1 // Copyright 2018 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 "sherlock.h"
6
7 #include <ddk/debug.h>
8 #include <ddk/device.h>
9 #include <ddk/platform-defs.h>
10
11 #include <soc/aml-s905d2/s905d2-hiu.h>
12 #include <soc/aml-t931/t931-gpio.h>
13 #include <soc/aml-t931/t931-hw.h>
14
15 namespace sherlock {
16
AudioInit()17 zx_status_t Sherlock::AudioInit() {
18
19 static constexpr pbus_gpio_t audio_gpios[] = {
20 {
21 // AUDIO_SOC_FAULT_L
22 .gpio = T931_GPIOZ(8),
23 },
24 {
25 // SOC_AUDIO_EN
26 .gpio = T931_GPIOH(7),
27 },
28 };
29
30 static constexpr pbus_mmio_t audio_mmios[] = {
31 {
32 .base = T931_EE_AUDIO_BASE,
33 .length = T931_EE_AUDIO_LENGTH
34 },
35 {
36 .base = T931_GPIO_BASE,
37 .length = T931_GPIO_LENGTH,
38 },
39 {
40 .base = T931_GPIO_A0_BASE,
41 .length = T931_GPIO_AO_LENGTH,
42 },
43 };
44
45 static constexpr pbus_bti_t tdm_btis[] = {
46 {
47 .iommu_index = 0,
48 .bti_id = BTI_AUDIO_OUT,
49 },
50 };
51
52 static constexpr pbus_i2c_channel_t codecs_i2cs[] = {
53 {
54 .bus_id = SHERLOCK_I2C_A0_0,
55 .address = 0x6c, // Tweeters.
56 },
57 {
58 .bus_id = SHERLOCK_I2C_A0_0,
59 .address = 0x6f, // Woofer.
60 },
61 };
62
63 pbus_dev_t tdm_dev = {};
64 tdm_dev.name = "SherlockAudio";
65 tdm_dev.vid = PDEV_VID_AMLOGIC;
66 tdm_dev.pid = PDEV_PID_AMLOGIC_T931;
67 tdm_dev.did = PDEV_DID_AMLOGIC_TDM;
68 tdm_dev.gpio_list = audio_gpios;
69 tdm_dev.gpio_count = countof(audio_gpios);
70 tdm_dev.i2c_channel_list = codecs_i2cs;
71 tdm_dev.i2c_channel_count = countof(codecs_i2cs);
72 tdm_dev.mmio_list = audio_mmios;
73 tdm_dev.mmio_count = countof(audio_mmios);
74 tdm_dev.bti_list = tdm_btis;
75 tdm_dev.bti_count = countof(tdm_btis);
76
77
78 static constexpr pbus_mmio_t pdm_mmios[] = {
79 {
80 .base = T931_EE_PDM_BASE,
81 .length = T931_EE_PDM_LENGTH
82 },
83 {
84 .base = T931_EE_AUDIO_BASE,
85 .length = T931_EE_AUDIO_LENGTH
86 },
87 };
88
89 static constexpr pbus_bti_t pdm_btis[] = {
90 {
91 .iommu_index = 0,
92 .bti_id = BTI_AUDIO_IN,
93 },
94 };
95
96 pbus_dev_t pdm_dev;
97 pdm_dev.name = "SherlockAudioIn";
98 pdm_dev.vid = PDEV_VID_AMLOGIC;
99 pdm_dev.pid = PDEV_PID_AMLOGIC_T931;
100 pdm_dev.did = PDEV_DID_SHERLOCK_PDM;
101 pdm_dev.mmio_list = pdm_mmios;
102 pdm_dev.mmio_count = countof(pdm_mmios);
103 pdm_dev.bti_list = pdm_btis;
104 pdm_dev.bti_count = countof(pdm_btis);
105
106
107 aml_hiu_dev_t hiu;
108 zx_status_t status = s905d2_hiu_init(&hiu);
109 if (status != ZX_OK) {
110 zxlogf(ERROR, "hiu_init: failed: %d\n", status);
111 return status;
112 }
113
114 aml_pll_dev_t hifi_pll;
115 s905d2_pll_init(&hiu, &hifi_pll, HIFI_PLL);
116 status = s905d2_pll_set_rate(&hifi_pll, T931_HIFI_PLL_RATE);
117 if (status != ZX_OK) {
118 zxlogf(ERROR, "Invalid rate selected for hifipll\n");
119 return status;
120 }
121
122 s905d2_pll_ena(&hifi_pll);
123
124 // TDM pin assignments.
125 gpio_impl_.SetAltFunction(T931_GPIOZ(7), T931_GPIOZ_7_TDMC_SCLK_FN);
126 gpio_impl_.SetAltFunction(T931_GPIOZ(6), T931_GPIOZ_6_TDMC_FS_FN);
127 gpio_impl_.SetAltFunction(T931_GPIOZ(2), T931_GPIOZ_2_TDMC_D0_FN);
128 gpio_impl_.SetAltFunction(T931_GPIOZ(3), T931_GPIOZ_3_TDMC_D1_FN);
129 gpio_impl_.SetAltFunction(T931_GPIOAO(9), T931_GPIOAO_9_MCLK_FN);
130
131 // PDM pin assignments.
132 gpio_impl_.SetAltFunction(T931_GPIOA(7), T931_GPIOA_7_PDM_DCLK_FN);
133 gpio_impl_.SetAltFunction(T931_GPIOA(8), T931_GPIOA_8_PDM_DIN0_FN);
134 gpio_impl_.SetAltFunction(T931_GPIOA(9), T931_GPIOA_9_PDM_DIN1_FN);
135
136 gpio_impl_.ConfigOut(T931_GPIOH(7), 1); // SOC_AUDIO_EN.
137
138 status = pbus_.DeviceAdd(&tdm_dev);
139 if (status != ZX_OK) {
140 zxlogf(ERROR, "%s pbus_.DeviceAdd failed %d\n", __FUNCTION__, status);
141 return status;
142 }
143 status = pbus_.DeviceAdd(&pdm_dev);
144 if (status != ZX_OK) {
145 zxlogf(ERROR, "%s pbus_.DeviceAdd failed %d\n", __FUNCTION__, status);
146 return status;
147 }
148 return ZX_OK;
149 }
150
151 } // namespace sherlock
152