1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <ddk/debug.h>
6#include <ddk/device.h>
7#include <ddk/protocol/platform-defs.h>
8#include <hw/reg.h>
9#include <soc/aml-a113/a113-hw.h>
10#include <soc/aml-a113/aml-tdm.h>
11#include <zircon/assert.h>
12#include <limits.h>
13
14#include "gauss.h"
15
16#define PDM_MMIO_BASE 0xff632000
17#define EE_AUDIO_MMIO_BASE 0xff642000
18#define PDM_IRQ (85 + 32)
19
20static const pbus_mmio_t audio_in_mmios[] = {
21    {
22        .base = EE_AUDIO_MMIO_BASE, .length = PAGE_SIZE,
23    },
24    {
25        .base = PDM_MMIO_BASE, .length = PAGE_SIZE,
26    },
27};
28
29static const pbus_irq_t audio_in_irqs[] = {
30    {
31        .irq = PDM_IRQ,
32        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
33    },
34};
35
36static const pbus_bti_t audio_in_btis[] = {
37    {
38        .iommu_index = 0,
39        .bti_id = BTI_AUDIO_IN,
40    },
41};
42
43static const pbus_dev_t gauss_audio_in_dev = {
44    .name = "gauss-audio-in",
45    .vid = PDEV_VID_GOOGLE,
46    .pid = PDEV_PID_GAUSS,
47    .did = PDEV_DID_GAUSS_AUDIO_IN,
48    .mmios = audio_in_mmios,
49    .mmio_count = countof(audio_in_mmios),
50    .irqs = audio_in_irqs,
51    .irq_count = countof(audio_in_irqs),
52    .btis = audio_in_btis,
53    .bti_count = countof(audio_in_btis),
54};
55
56static const pbus_mmio_t tdm_audio_mmios[] = {
57    {
58        .base = A113_TDM_PHYS_BASE,
59        .length = 4096
60    },
61};
62
63static const pbus_i2c_channel_t tdm_i2cs[] = {
64    {
65        .bus_id = AML_I2C_B,
66        .address = 0x4C
67    },
68    {
69        .bus_id = AML_I2C_B,
70        .address = 0x4D
71    },
72    {
73        .bus_id = AML_I2C_B,
74        .address = 0x4E
75    },
76};
77
78static const pbus_irq_t tdm_irqs[] = {
79    {
80        .irq = (90 + 32),
81        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
82    },
83};
84
85static const pbus_bti_t tdm_btis[] = {
86    {
87        .iommu_index = 0,
88        .bti_id = BTI_AUDIO_OUT,
89    },
90};
91
92static const pbus_dev_t gauss_tdm_audio_dev = {
93    .name = "gauss-tdm-audio",
94    .vid = PDEV_VID_GOOGLE,
95    .pid = PDEV_PID_GAUSS,
96    .did = PDEV_DID_GAUSS_AUDIO_OUT,
97    .irqs = tdm_irqs,
98    .irq_count = countof(tdm_irqs),
99    .mmios = tdm_audio_mmios,
100    .mmio_count = countof(tdm_audio_mmios),
101    .i2c_channels = tdm_i2cs,
102    .i2c_channel_count = countof(tdm_i2cs),
103    .btis = tdm_btis,
104    .bti_count = countof(tdm_btis),
105};
106
107zx_status_t gauss_audio_init(gauss_bus_t* bus) {
108
109    ZX_DEBUG_ASSERT(bus);
110    zx_status_t status;
111
112    // Add audio in and out devices.
113    if ((status = pbus_device_add(&bus->pbus, &gauss_audio_in_dev)) != ZX_OK) {
114        zxlogf(ERROR, "a113_audio_init could not add gauss_audio_in_dev: %d\n", status);
115        return status;
116    }
117
118    printf("Adding the tdm device\n");
119    if ((status = pbus_device_add(&bus->pbus, &gauss_tdm_audio_dev)) != ZX_OK) {
120        zxlogf(ERROR, "a113_audio_init could not add gauss_tdm_audio_dev: %d\n", status);
121    }
122
123    return ZX_OK;
124}
125