1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Analog Devices ADAU1372 Audio Codec driver |
4 | * |
5 | * Copyright 2016 Analog Devices Inc. |
6 | * Author: Lars-Peter Clausen <lars@metafoo.de> |
7 | */ |
8 | |
9 | #include <linux/clk.h> |
10 | #include <linux/delay.h> |
11 | #include <linux/gpio/consumer.h> |
12 | #include <linux/init.h> |
13 | #include <linux/module.h> |
14 | #include <linux/pm.h> |
15 | #include <linux/slab.h> |
16 | |
17 | #include <sound/core.h> |
18 | #include <sound/pcm.h> |
19 | #include <sound/pcm_params.h> |
20 | #include <sound/tlv.h> |
21 | #include <sound/soc.h> |
22 | |
23 | #include "adau1372.h" |
24 | #include "adau-utils.h" |
25 | |
26 | struct adau1372 { |
27 | struct regmap *regmap; |
28 | void (*switch_mode)(struct device *dev); |
29 | bool use_pll; |
30 | bool enabled; |
31 | bool clock_provider; |
32 | |
33 | struct snd_pcm_hw_constraint_list rate_constraints; |
34 | unsigned int slot_width; |
35 | |
36 | struct clk *mclk; |
37 | struct gpio_desc *pd_gpio; |
38 | struct device *dev; |
39 | }; |
40 | |
41 | #define ADAU1372_REG_CLK_CTRL 0x00 |
42 | #define ADAU1372_REG_PLL(x) (0x01 + (x)) |
43 | #define ADAU1372_REG_DAC_SOURCE 0x11 |
44 | #define ADAU1372_REG_SOUT_SOURCE_0_1 0x13 |
45 | #define ADAU1372_REG_SOUT_SOURCE_2_3 0x14 |
46 | #define ADAU1372_REG_SOUT_SOURCE_4_5 0x15 |
47 | #define ADAU1372_REG_SOUT_SOURCE_6_7 0x16 |
48 | #define ADAU1372_REG_ADC_SDATA_CH 0x17 |
49 | #define ADAU1372_REG_ASRCO_SOURCE_0_1 0x18 |
50 | #define ADAU1372_REG_ASRCO_SOURCE_2_3 0x19 |
51 | #define ADAU1372_REG_ASRC_MODE 0x1a |
52 | #define ADAU1372_REG_ADC_CTRL0 0x1b |
53 | #define ADAU1372_REG_ADC_CTRL1 0x1c |
54 | #define ADAU1372_REG_ADC_CTRL2 0x1d |
55 | #define ADAU1372_REG_ADC_CTRL3 0x1e |
56 | #define ADAU1372_REG_ADC_VOL(x) (0x1f + (x)) |
57 | #define ADAU1372_REG_PGA_CTRL(x) (0x23 + (x)) |
58 | #define ADAU1372_REG_PGA_BOOST 0x28 |
59 | #define ADAU1372_REG_MICBIAS 0x2d |
60 | #define ADAU1372_REG_DAC_CTRL 0x2e |
61 | #define ADAU1372_REG_DAC_VOL(x) (0x2f + (x)) |
62 | #define ADAU1372_REG_OP_STAGE_MUTE 0x31 |
63 | #define ADAU1372_REG_SAI0 0x32 |
64 | #define ADAU1372_REG_SAI1 0x33 |
65 | #define ADAU1372_REG_SOUT_CTRL 0x34 |
66 | #define ADAU1372_REG_MODE_MP(x) (0x38 + (x)) |
67 | #define ADAU1372_REG_OP_STAGE_CTRL 0x43 |
68 | #define ADAU1372_REG_DECIM_PWR 0x44 |
69 | #define ADAU1372_REG_INTERP_PWR 0x45 |
70 | #define ADAU1372_REG_BIAS_CTRL0 0x46 |
71 | #define ADAU1372_REG_BIAS_CTRL1 0x47 |
72 | |
73 | #define ADAU1372_CLK_CTRL_PLL_EN BIT(7) |
74 | #define ADAU1372_CLK_CTRL_XTAL_DIS BIT(4) |
75 | #define ADAU1372_CLK_CTRL_CLKSRC BIT(3) |
76 | #define ADAU1372_CLK_CTRL_CC_MDIV BIT(1) |
77 | #define ADAU1372_CLK_CTRL_MCLK_EN BIT(0) |
78 | |
79 | #define ADAU1372_SAI0_DELAY1 (0x0 << 6) |
80 | #define ADAU1372_SAI0_DELAY0 (0x1 << 6) |
81 | #define ADAU1372_SAI0_DELAY_MASK (0x3 << 6) |
82 | #define ADAU1372_SAI0_SAI_I2S (0x0 << 4) |
83 | #define ADAU1372_SAI0_SAI_TDM2 (0x1 << 4) |
84 | #define ADAU1372_SAI0_SAI_TDM4 (0x2 << 4) |
85 | #define ADAU1372_SAI0_SAI_TDM8 (0x3 << 4) |
86 | #define ADAU1372_SAI0_SAI_MASK (0x3 << 4) |
87 | #define ADAU1372_SAI0_FS_48 0x0 |
88 | #define ADAU1372_SAI0_FS_8 0x1 |
89 | #define ADAU1372_SAI0_FS_12 0x2 |
90 | #define ADAU1372_SAI0_FS_16 0x3 |
91 | #define ADAU1372_SAI0_FS_24 0x4 |
92 | #define ADAU1372_SAI0_FS_32 0x5 |
93 | #define ADAU1372_SAI0_FS_96 0x6 |
94 | #define ADAU1372_SAI0_FS_192 0x7 |
95 | #define ADAU1372_SAI0_FS_MASK 0xf |
96 | |
97 | #define ADAU1372_SAI1_TDM_TS BIT(7) |
98 | #define ADAU1372_SAI1_BCLK_TDMC BIT(6) |
99 | #define ADAU1372_SAI1_LR_MODE BIT(5) |
100 | #define ADAU1372_SAI1_LR_POL BIT(4) |
101 | #define ADAU1372_SAI1_BCLKRATE BIT(2) |
102 | #define ADAU1372_SAI1_BCLKEDGE BIT(1) |
103 | #define ADAU1372_SAI1_MS BIT(0) |
104 | |
105 | static const unsigned int adau1372_rates[] = { |
106 | [ADAU1372_SAI0_FS_8] = 8000, |
107 | [ADAU1372_SAI0_FS_12] = 12000, |
108 | [ADAU1372_SAI0_FS_16] = 16000, |
109 | [ADAU1372_SAI0_FS_24] = 24000, |
110 | [ADAU1372_SAI0_FS_32] = 32000, |
111 | [ADAU1372_SAI0_FS_48] = 48000, |
112 | [ADAU1372_SAI0_FS_96] = 96000, |
113 | [ADAU1372_SAI0_FS_192] = 192000, |
114 | }; |
115 | |
116 | /* 8k, 12k, 24k, 48k */ |
117 | #define ADAU1372_RATE_MASK_TDM8 0x17 |
118 | /* + 16k, 96k */ |
119 | #define ADAU1372_RATE_MASK_TDM4_MASTER (ADAU1372_RATE_MASK_TDM8 | 0x48 | 0x20) |
120 | /* +32k */ |
121 | #define ADAU1372_RATE_MASK_TDM4 (ADAU1372_RATE_MASK_TDM4_MASTER | 0x20) |
122 | /* + 192k */ |
123 | #define ADAU1372_RATE_MASK_TDM2 (ADAU1372_RATE_MASK_TDM4 | 0x80) |
124 | |
125 | static const DECLARE_TLV_DB_MINMAX(adau1372_digital_tlv, -9563, 0); |
126 | static const DECLARE_TLV_DB_SCALE(adau1372_pga_tlv, -1200, 75, 0); |
127 | static const DECLARE_TLV_DB_SCALE(adau1372_pga_boost_tlv, 0, 1000, 0); |
128 | |
129 | static const char * const adau1372_bias_text[] = { |
130 | "Normal operation" , "Extreme power saving" , "Enhanced performance" , |
131 | "Power saving" , |
132 | }; |
133 | |
134 | static const unsigned int adau1372_bias_adc_values[] = { |
135 | 0, 2, 3, |
136 | }; |
137 | |
138 | static const char * const adau1372_bias_adc_text[] = { |
139 | "Normal operation" , "Enhanced performance" , "Power saving" , |
140 | }; |
141 | |
142 | static const char * const adau1372_bias_dac_text[] = { |
143 | "Normal operation" , "Power saving" , "Superior performance" , |
144 | "Enhanced performance" , |
145 | }; |
146 | |
147 | static SOC_ENUM_SINGLE_DECL(adau1372_bias_hp_enum, |
148 | ADAU1372_REG_BIAS_CTRL0, 6, adau1372_bias_text); |
149 | static SOC_ENUM_SINGLE_DECL(adau1372_bias_afe0_1_enum, |
150 | ADAU1372_REG_BIAS_CTRL0, 4, adau1372_bias_text); |
151 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_bias_adc2_3_enum, |
152 | ADAU1372_REG_BIAS_CTRL0, 2, 0x3, adau1372_bias_adc_text, |
153 | adau1372_bias_adc_values); |
154 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_bias_adc0_1_enum, |
155 | ADAU1372_REG_BIAS_CTRL0, 0, 0x3, adau1372_bias_adc_text, |
156 | adau1372_bias_adc_values); |
157 | static SOC_ENUM_SINGLE_DECL(adau1372_bias_afe2_3_enum, |
158 | ADAU1372_REG_BIAS_CTRL1, 4, adau1372_bias_text); |
159 | static SOC_ENUM_SINGLE_DECL(adau1372_bias_mic_enum, |
160 | ADAU1372_REG_BIAS_CTRL1, 2, adau1372_bias_text); |
161 | static SOC_ENUM_SINGLE_DECL(adau1372_bias_dac_enum, |
162 | ADAU1372_REG_BIAS_CTRL1, 0, adau1372_bias_dac_text); |
163 | |
164 | static const char * const adau1372_hpf_text[] = { |
165 | "Off" , |
166 | "1 Hz" , |
167 | "4 Hz" , |
168 | "8 Hz" , |
169 | }; |
170 | |
171 | static SOC_ENUM_SINGLE_DECL(adau1372_hpf0_1_enum, ADAU1372_REG_ADC_CTRL2, 5, |
172 | adau1372_hpf_text); |
173 | static SOC_ENUM_SINGLE_DECL(adau1372_hpf2_3_enum, ADAU1372_REG_ADC_CTRL3, 5, |
174 | adau1372_hpf_text); |
175 | static const struct snd_kcontrol_new adau1372_controls[] = { |
176 | SOC_SINGLE_TLV("ADC 0 Capture Volume" , ADAU1372_REG_ADC_VOL(0), |
177 | 0, 0xff, 1, adau1372_digital_tlv), |
178 | SOC_SINGLE_TLV("ADC 1 Capture Volume" , ADAU1372_REG_ADC_VOL(1), |
179 | 0, 0xff, 1, adau1372_digital_tlv), |
180 | SOC_SINGLE_TLV("ADC 2 Capture Volume" , ADAU1372_REG_ADC_VOL(2), |
181 | 0, 0xff, 1, adau1372_digital_tlv), |
182 | SOC_SINGLE_TLV("ADC 3 Capture Volume" , ADAU1372_REG_ADC_VOL(3), |
183 | 0, 0xff, 1, adau1372_digital_tlv), |
184 | SOC_SINGLE("ADC 0 Capture Switch" , ADAU1372_REG_ADC_CTRL0, 3, 1, 1), |
185 | SOC_SINGLE("ADC 1 Capture Switch" , ADAU1372_REG_ADC_CTRL0, 4, 1, 1), |
186 | SOC_SINGLE("ADC 2 Capture Switch" , ADAU1372_REG_ADC_CTRL1, 3, 1, 1), |
187 | SOC_SINGLE("ADC 3 Capture Switch" , ADAU1372_REG_ADC_CTRL1, 4, 1, 1), |
188 | |
189 | SOC_ENUM("ADC 0+1 High-Pass-Filter" , adau1372_hpf0_1_enum), |
190 | SOC_ENUM("ADC 2+3 High-Pass-Filter" , adau1372_hpf2_3_enum), |
191 | |
192 | SOC_SINGLE_TLV("PGA 0 Capture Volume" , ADAU1372_REG_PGA_CTRL(0), |
193 | 0, 0x3f, 0, adau1372_pga_tlv), |
194 | SOC_SINGLE_TLV("PGA 1 Capture Volume" , ADAU1372_REG_PGA_CTRL(1), |
195 | 0, 0x3f, 0, adau1372_pga_tlv), |
196 | SOC_SINGLE_TLV("PGA 2 Capture Volume" , ADAU1372_REG_PGA_CTRL(2), |
197 | 0, 0x3f, 0, adau1372_pga_tlv), |
198 | SOC_SINGLE_TLV("PGA 3 Capture Volume" , ADAU1372_REG_PGA_CTRL(3), |
199 | 0, 0x3f, 0, adau1372_pga_tlv), |
200 | SOC_SINGLE_TLV("PGA 0 Boost Capture Volume" , ADAU1372_REG_PGA_BOOST, |
201 | 0, 1, 0, adau1372_pga_boost_tlv), |
202 | SOC_SINGLE_TLV("PGA 1 Boost Capture Volume" , ADAU1372_REG_PGA_BOOST, |
203 | 1, 1, 0, adau1372_pga_boost_tlv), |
204 | SOC_SINGLE_TLV("PGA 2 Boost Capture Volume" , ADAU1372_REG_PGA_BOOST, |
205 | 2, 1, 0, adau1372_pga_boost_tlv), |
206 | SOC_SINGLE_TLV("PGA 3 Boost Capture Volume" , ADAU1372_REG_PGA_BOOST, |
207 | 3, 1, 0, adau1372_pga_boost_tlv), |
208 | SOC_SINGLE("PGA 0 Capture Switch" , ADAU1372_REG_PGA_CTRL(0), 7, 1, 0), |
209 | SOC_SINGLE("PGA 1 Capture Switch" , ADAU1372_REG_PGA_CTRL(1), 7, 1, 0), |
210 | SOC_SINGLE("PGA 2 Capture Switch" , ADAU1372_REG_PGA_CTRL(2), 7, 1, 0), |
211 | SOC_SINGLE("PGA 3 Capture Switch" , ADAU1372_REG_PGA_CTRL(3), 7, 1, 0), |
212 | |
213 | SOC_SINGLE_TLV("DAC 0 Playback Volume" , ADAU1372_REG_DAC_VOL(0), |
214 | 0, 0xff, 1, adau1372_digital_tlv), |
215 | SOC_SINGLE_TLV("DAC 1 Playback Volume" , ADAU1372_REG_DAC_VOL(1), |
216 | 0, 0xff, 1, adau1372_digital_tlv), |
217 | SOC_SINGLE("DAC 0 Playback Switch" , ADAU1372_REG_DAC_CTRL, 3, 1, 1), |
218 | SOC_SINGLE("DAC 1 Playback Switch" , ADAU1372_REG_DAC_CTRL, 4, 1, 1), |
219 | |
220 | SOC_ENUM("Headphone Bias" , adau1372_bias_hp_enum), |
221 | SOC_ENUM("Microphone Bias" , adau1372_bias_mic_enum), |
222 | SOC_ENUM("AFE 0+1 Bias" , adau1372_bias_afe0_1_enum), |
223 | SOC_ENUM("AFE 2+3 Bias" , adau1372_bias_afe2_3_enum), |
224 | SOC_ENUM("ADC 0+1 Bias" , adau1372_bias_adc0_1_enum), |
225 | SOC_ENUM("ADC 2+3 Bias" , adau1372_bias_adc2_3_enum), |
226 | SOC_ENUM("DAC 0+1 Bias" , adau1372_bias_dac_enum), |
227 | }; |
228 | |
229 | static const char * const adau1372_decimator_mux_text[] = { |
230 | "ADC" , |
231 | "DMIC" , |
232 | }; |
233 | |
234 | static SOC_ENUM_SINGLE_DECL(adau1372_decimator0_1_mux_enum, ADAU1372_REG_ADC_CTRL2, |
235 | 2, adau1372_decimator_mux_text); |
236 | |
237 | static const struct snd_kcontrol_new adau1372_decimator0_1_mux_control = |
238 | SOC_DAPM_ENUM("Decimator 0+1 Capture Mux" , adau1372_decimator0_1_mux_enum); |
239 | |
240 | static SOC_ENUM_SINGLE_DECL(adau1372_decimator2_3_mux_enum, ADAU1372_REG_ADC_CTRL3, |
241 | 2, adau1372_decimator_mux_text); |
242 | |
243 | static const struct snd_kcontrol_new adau1372_decimator2_3_mux_control = |
244 | SOC_DAPM_ENUM("Decimator 2+3 Capture Mux" , adau1372_decimator2_3_mux_enum); |
245 | |
246 | static const unsigned int adau1372_asrco_mux_values[] = { |
247 | 4, 5, 6, 7, |
248 | }; |
249 | |
250 | static const char * const adau1372_asrco_mux_text[] = { |
251 | "Decimator0" , |
252 | "Decimator1" , |
253 | "Decimator2" , |
254 | "Decimator3" , |
255 | }; |
256 | |
257 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_asrco0_mux_enum, ADAU1372_REG_ASRCO_SOURCE_0_1, |
258 | 0, 0xf, adau1372_asrco_mux_text, adau1372_asrco_mux_values); |
259 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_asrco1_mux_enum, ADAU1372_REG_ASRCO_SOURCE_0_1, |
260 | 4, 0xf, adau1372_asrco_mux_text, adau1372_asrco_mux_values); |
261 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_asrco2_mux_enum, ADAU1372_REG_ASRCO_SOURCE_2_3, |
262 | 0, 0xf, adau1372_asrco_mux_text, adau1372_asrco_mux_values); |
263 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_asrco3_mux_enum, ADAU1372_REG_ASRCO_SOURCE_2_3, |
264 | 4, 0xf, adau1372_asrco_mux_text, adau1372_asrco_mux_values); |
265 | |
266 | static const struct snd_kcontrol_new adau1372_asrco0_mux_control = |
267 | SOC_DAPM_ENUM("Output ASRC0 Capture Mux" , adau1372_asrco0_mux_enum); |
268 | static const struct snd_kcontrol_new adau1372_asrco1_mux_control = |
269 | SOC_DAPM_ENUM("Output ASRC1 Capture Mux" , adau1372_asrco1_mux_enum); |
270 | static const struct snd_kcontrol_new adau1372_asrco2_mux_control = |
271 | SOC_DAPM_ENUM("Output ASRC2 Capture Mux" , adau1372_asrco2_mux_enum); |
272 | static const struct snd_kcontrol_new adau1372_asrco3_mux_control = |
273 | SOC_DAPM_ENUM("Output ASRC3 Capture Mux" , adau1372_asrco3_mux_enum); |
274 | |
275 | static const unsigned int adau1372_sout_mux_values[] = { |
276 | 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 |
277 | }; |
278 | |
279 | static const char * const adau1372_sout_mux_text[] = { |
280 | "Output ASRC0" , |
281 | "Output ASRC1" , |
282 | "Output ASRC2" , |
283 | "Output ASRC3" , |
284 | "Serial Input 0" , |
285 | "Serial Input 1" , |
286 | "Serial Input 2" , |
287 | "Serial Input 3" , |
288 | "Serial Input 4" , |
289 | "Serial Input 5" , |
290 | "Serial Input 6" , |
291 | "Serial Input 7" , |
292 | }; |
293 | |
294 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_sout0_mux_enum, ADAU1372_REG_SOUT_SOURCE_0_1, |
295 | 0, 0xf, adau1372_sout_mux_text, adau1372_sout_mux_values); |
296 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_sout1_mux_enum, ADAU1372_REG_SOUT_SOURCE_0_1, |
297 | 4, 0xf, adau1372_sout_mux_text, adau1372_sout_mux_values); |
298 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_sout2_mux_enum, ADAU1372_REG_SOUT_SOURCE_2_3, |
299 | 0, 0xf, adau1372_sout_mux_text, adau1372_sout_mux_values); |
300 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_sout3_mux_enum, ADAU1372_REG_SOUT_SOURCE_2_3, |
301 | 4, 0xf, adau1372_sout_mux_text, adau1372_sout_mux_values); |
302 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_sout4_mux_enum, ADAU1372_REG_SOUT_SOURCE_4_5, |
303 | 0, 0xf, adau1372_sout_mux_text, adau1372_sout_mux_values); |
304 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_sout5_mux_enum, ADAU1372_REG_SOUT_SOURCE_4_5, |
305 | 4, 0xf, adau1372_sout_mux_text, adau1372_sout_mux_values); |
306 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_sout6_mux_enum, ADAU1372_REG_SOUT_SOURCE_6_7, |
307 | 0, 0xf, adau1372_sout_mux_text, adau1372_sout_mux_values); |
308 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_sout7_mux_enum, ADAU1372_REG_SOUT_SOURCE_6_7, |
309 | 4, 0xf, adau1372_sout_mux_text, adau1372_sout_mux_values); |
310 | |
311 | static const struct snd_kcontrol_new adau1372_sout0_mux_control = |
312 | SOC_DAPM_ENUM("Serial Output 0 Capture Mux" , adau1372_sout0_mux_enum); |
313 | static const struct snd_kcontrol_new adau1372_sout1_mux_control = |
314 | SOC_DAPM_ENUM("Serial Output 1 Capture Mux" , adau1372_sout1_mux_enum); |
315 | static const struct snd_kcontrol_new adau1372_sout2_mux_control = |
316 | SOC_DAPM_ENUM("Serial Output 2 Capture Mux" , adau1372_sout2_mux_enum); |
317 | static const struct snd_kcontrol_new adau1372_sout3_mux_control = |
318 | SOC_DAPM_ENUM("Serial Output 3 Capture Mux" , adau1372_sout3_mux_enum); |
319 | static const struct snd_kcontrol_new adau1372_sout4_mux_control = |
320 | SOC_DAPM_ENUM("Serial Output 4 Capture Mux" , adau1372_sout4_mux_enum); |
321 | static const struct snd_kcontrol_new adau1372_sout5_mux_control = |
322 | SOC_DAPM_ENUM("Serial Output 5 Capture Mux" , adau1372_sout5_mux_enum); |
323 | static const struct snd_kcontrol_new adau1372_sout6_mux_control = |
324 | SOC_DAPM_ENUM("Serial Output 6 Capture Mux" , adau1372_sout6_mux_enum); |
325 | static const struct snd_kcontrol_new adau1372_sout7_mux_control = |
326 | SOC_DAPM_ENUM("Serial Output 7 Capture Mux" , adau1372_sout7_mux_enum); |
327 | |
328 | static const char * const adau1372_asrci_mux_text[] = { |
329 | "Serial Input 0+1" , |
330 | "Serial Input 2+3" , |
331 | "Serial Input 4+5" , |
332 | "Serial Input 6+7" , |
333 | }; |
334 | |
335 | static SOC_ENUM_SINGLE_DECL(adau1372_asrci_mux_enum, |
336 | ADAU1372_REG_ASRC_MODE, 2, adau1372_asrci_mux_text); |
337 | |
338 | static const struct snd_kcontrol_new adau1372_asrci_mux_control = |
339 | SOC_DAPM_ENUM("Input ASRC Playback Mux" , adau1372_asrci_mux_enum); |
340 | |
341 | static const unsigned int adau1372_dac_mux_values[] = { |
342 | 12, 13 |
343 | }; |
344 | |
345 | static const char * const adau1372_dac_mux_text[] = { |
346 | "Input ASRC0" , |
347 | "Input ASRC1" , |
348 | }; |
349 | |
350 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_dac0_mux_enum, ADAU1372_REG_DAC_SOURCE, |
351 | 0, 0xf, adau1372_dac_mux_text, adau1372_dac_mux_values); |
352 | static SOC_VALUE_ENUM_SINGLE_DECL(adau1372_dac1_mux_enum, ADAU1372_REG_DAC_SOURCE, |
353 | 4, 0xf, adau1372_dac_mux_text, adau1372_dac_mux_values); |
354 | |
355 | static const struct snd_kcontrol_new adau1372_dac0_mux_control = |
356 | SOC_DAPM_ENUM("DAC 0 Playback Mux" , adau1372_dac0_mux_enum); |
357 | static const struct snd_kcontrol_new adau1372_dac1_mux_control = |
358 | SOC_DAPM_ENUM("DAC 1 Playback Mux" , adau1372_dac1_mux_enum); |
359 | |
360 | static const struct snd_soc_dapm_widget adau1372_dapm_widgets[] = { |
361 | SND_SOC_DAPM_INPUT("AIN0" ), |
362 | SND_SOC_DAPM_INPUT("AIN1" ), |
363 | SND_SOC_DAPM_INPUT("AIN2" ), |
364 | SND_SOC_DAPM_INPUT("AIN3" ), |
365 | SND_SOC_DAPM_INPUT("DMIC0_1" ), |
366 | SND_SOC_DAPM_INPUT("DMIC2_3" ), |
367 | |
368 | SND_SOC_DAPM_SUPPLY("MICBIAS0" , ADAU1372_REG_MICBIAS, 4, 0, NULL, 0), |
369 | SND_SOC_DAPM_SUPPLY("MICBIAS1" , ADAU1372_REG_MICBIAS, 5, 0, NULL, 0), |
370 | |
371 | SND_SOC_DAPM_PGA("PGA0" , ADAU1372_REG_PGA_CTRL(0), 6, 1, NULL, 0), |
372 | SND_SOC_DAPM_PGA("PGA1" , ADAU1372_REG_PGA_CTRL(1), 6, 1, NULL, 0), |
373 | SND_SOC_DAPM_PGA("PGA2" , ADAU1372_REG_PGA_CTRL(2), 6, 1, NULL, 0), |
374 | SND_SOC_DAPM_PGA("PGA3" , ADAU1372_REG_PGA_CTRL(3), 6, 1, NULL, 0), |
375 | SND_SOC_DAPM_ADC("ADC0" , NULL, ADAU1372_REG_ADC_CTRL2, 0, 0), |
376 | SND_SOC_DAPM_ADC("ADC1" , NULL, ADAU1372_REG_ADC_CTRL2, 1, 0), |
377 | SND_SOC_DAPM_ADC("ADC2" , NULL, ADAU1372_REG_ADC_CTRL3, 0, 0), |
378 | SND_SOC_DAPM_ADC("ADC3" , NULL, ADAU1372_REG_ADC_CTRL3, 1, 0), |
379 | |
380 | SND_SOC_DAPM_SUPPLY("ADC0 Filter" , ADAU1372_REG_DECIM_PWR, 0, 0, NULL, 0), |
381 | SND_SOC_DAPM_SUPPLY("ADC1 Filter" , ADAU1372_REG_DECIM_PWR, 1, 0, NULL, 0), |
382 | SND_SOC_DAPM_SUPPLY("ADC2 Filter" , ADAU1372_REG_DECIM_PWR, 2, 0, NULL, 0), |
383 | SND_SOC_DAPM_SUPPLY("ADC3 Filter" , ADAU1372_REG_DECIM_PWR, 3, 0, NULL, 0), |
384 | SND_SOC_DAPM_SUPPLY("Output ASRC0 Decimator" , ADAU1372_REG_DECIM_PWR, 4, 0, NULL, 0), |
385 | SND_SOC_DAPM_SUPPLY("Output ASRC1 Decimator" , ADAU1372_REG_DECIM_PWR, 5, 0, NULL, 0), |
386 | SND_SOC_DAPM_SUPPLY("Output ASRC2 Decimator" , ADAU1372_REG_DECIM_PWR, 6, 0, NULL, 0), |
387 | SND_SOC_DAPM_SUPPLY("Output ASRC3 Decimator" , ADAU1372_REG_DECIM_PWR, 7, 0, NULL, 0), |
388 | |
389 | SND_SOC_DAPM_MUX("Decimator0 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_decimator0_1_mux_control), |
390 | SND_SOC_DAPM_MUX("Decimator1 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_decimator0_1_mux_control), |
391 | SND_SOC_DAPM_MUX("Decimator2 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_decimator2_3_mux_control), |
392 | SND_SOC_DAPM_MUX("Decimator3 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_decimator2_3_mux_control), |
393 | |
394 | SND_SOC_DAPM_MUX("Output ASRC0 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_asrco0_mux_control), |
395 | SND_SOC_DAPM_MUX("Output ASRC1 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_asrco1_mux_control), |
396 | SND_SOC_DAPM_MUX("Output ASRC2 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_asrco2_mux_control), |
397 | SND_SOC_DAPM_MUX("Output ASRC3 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_asrco3_mux_control), |
398 | SND_SOC_DAPM_MUX("Serial Output 0 Capture Mux" , SND_SOC_NOPM, 0, 0, |
399 | &adau1372_sout0_mux_control), |
400 | SND_SOC_DAPM_MUX("Serial Output 1 Capture Mux" , SND_SOC_NOPM, 0, 0, |
401 | &adau1372_sout1_mux_control), |
402 | SND_SOC_DAPM_MUX("Serial Output 2 Capture Mux" , SND_SOC_NOPM, 0, 0, |
403 | &adau1372_sout2_mux_control), |
404 | SND_SOC_DAPM_MUX("Serial Output 3 Capture Mux" , SND_SOC_NOPM, 0, 0, |
405 | &adau1372_sout3_mux_control), |
406 | SND_SOC_DAPM_MUX("Serial Output 4 Capture Mux" , SND_SOC_NOPM, 0, 0, |
407 | &adau1372_sout4_mux_control), |
408 | SND_SOC_DAPM_MUX("Serial Output 5 Capture Mux" , SND_SOC_NOPM, 0, 0, |
409 | &adau1372_sout5_mux_control), |
410 | SND_SOC_DAPM_MUX("Serial Output 6 Capture Mux" , SND_SOC_NOPM, 0, 0, |
411 | &adau1372_sout6_mux_control), |
412 | SND_SOC_DAPM_MUX("Serial Output 7 Capture Mux" , SND_SOC_NOPM, 0, 0, |
413 | &adau1372_sout7_mux_control), |
414 | |
415 | SND_SOC_DAPM_AIF_IN("Serial Input 0" , NULL, 0, SND_SOC_NOPM, 0, 0), |
416 | SND_SOC_DAPM_AIF_IN("Serial Input 1" , NULL, 1, SND_SOC_NOPM, 0, 0), |
417 | SND_SOC_DAPM_AIF_IN("Serial Input 2" , NULL, 2, SND_SOC_NOPM, 0, 0), |
418 | SND_SOC_DAPM_AIF_IN("Serial Input 3" , NULL, 3, SND_SOC_NOPM, 0, 0), |
419 | SND_SOC_DAPM_AIF_IN("Serial Input 4" , NULL, 4, SND_SOC_NOPM, 0, 0), |
420 | SND_SOC_DAPM_AIF_IN("Serial Input 5" , NULL, 5, SND_SOC_NOPM, 0, 0), |
421 | SND_SOC_DAPM_AIF_IN("Serial Input 6" , NULL, 6, SND_SOC_NOPM, 0, 0), |
422 | SND_SOC_DAPM_AIF_IN("Serial Input 7" , NULL, 7, SND_SOC_NOPM, 0, 0), |
423 | |
424 | SND_SOC_DAPM_AIF_OUT("Serial Output 0" , NULL, 0, SND_SOC_NOPM, 0, 0), |
425 | SND_SOC_DAPM_AIF_OUT("Serial Output 1" , NULL, 1, SND_SOC_NOPM, 0, 0), |
426 | SND_SOC_DAPM_AIF_OUT("Serial Output 2" , NULL, 2, SND_SOC_NOPM, 0, 0), |
427 | SND_SOC_DAPM_AIF_OUT("Serial Output 3" , NULL, 3, SND_SOC_NOPM, 0, 0), |
428 | SND_SOC_DAPM_AIF_OUT("Serial Output 4" , NULL, 4, SND_SOC_NOPM, 0, 0), |
429 | SND_SOC_DAPM_AIF_OUT("Serial Output 5" , NULL, 5, SND_SOC_NOPM, 0, 0), |
430 | SND_SOC_DAPM_AIF_OUT("Serial Output 6" , NULL, 6, SND_SOC_NOPM, 0, 0), |
431 | SND_SOC_DAPM_AIF_OUT("Serial Output 7" , NULL, 7, SND_SOC_NOPM, 0, 0), |
432 | |
433 | SND_SOC_DAPM_SUPPLY("Output ASRC Supply" , ADAU1372_REG_ASRC_MODE, 1, 0, NULL, 0), |
434 | SND_SOC_DAPM_SUPPLY("Input ASRC Supply" , ADAU1372_REG_ASRC_MODE, 0, 0, NULL, 0), |
435 | |
436 | SND_SOC_DAPM_SUPPLY("DAC1 Modulator" , ADAU1372_REG_INTERP_PWR, 3, 0, NULL, 0), |
437 | SND_SOC_DAPM_SUPPLY("DAC0 Modulator" , ADAU1372_REG_INTERP_PWR, 2, 0, NULL, 0), |
438 | SND_SOC_DAPM_SUPPLY("Input ASRC1 Interpolator" , ADAU1372_REG_INTERP_PWR, 1, 0, NULL, 0), |
439 | SND_SOC_DAPM_SUPPLY("Input ASRC0 Interpolator" , ADAU1372_REG_INTERP_PWR, 0, 0, NULL, 0), |
440 | |
441 | SND_SOC_DAPM_MUX("Input ASRC0 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_asrci_mux_control), |
442 | SND_SOC_DAPM_MUX("Input ASRC1 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_asrci_mux_control), |
443 | |
444 | SND_SOC_DAPM_MUX("DAC 0 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_dac0_mux_control), |
445 | SND_SOC_DAPM_MUX("DAC 1 Mux" , SND_SOC_NOPM, 0, 0, &adau1372_dac1_mux_control), |
446 | |
447 | SND_SOC_DAPM_DAC("DAC0" , NULL, ADAU1372_REG_DAC_CTRL, 0, 0), |
448 | SND_SOC_DAPM_DAC("DAC1" , NULL, ADAU1372_REG_DAC_CTRL, 1, 0), |
449 | |
450 | SND_SOC_DAPM_OUT_DRV("OP_STAGE_LP" , ADAU1372_REG_OP_STAGE_CTRL, 0, 1, NULL, 0), |
451 | SND_SOC_DAPM_OUT_DRV("OP_STAGE_LN" , ADAU1372_REG_OP_STAGE_CTRL, 1, 1, NULL, 0), |
452 | SND_SOC_DAPM_OUT_DRV("OP_STAGE_RP" , ADAU1372_REG_OP_STAGE_CTRL, 2, 1, NULL, 0), |
453 | SND_SOC_DAPM_OUT_DRV("OP_STAGE_RN" , ADAU1372_REG_OP_STAGE_CTRL, 3, 1, NULL, 0), |
454 | |
455 | SND_SOC_DAPM_OUTPUT("HPOUTL" ), |
456 | SND_SOC_DAPM_OUTPUT("HPOUTR" ), |
457 | }; |
458 | |
459 | #define ADAU1372_SOUT_ROUTES(x) \ |
460 | { "Serial Output " #x " Capture Mux", "Output ASRC0", "Output ASRC0 Mux" }, \ |
461 | { "Serial Output " #x " Capture Mux", "Output ASRC1", "Output ASRC1 Mux" }, \ |
462 | { "Serial Output " #x " Capture Mux", "Output ASRC2", "Output ASRC2 Mux" }, \ |
463 | { "Serial Output " #x " Capture Mux", "Output ASRC3", "Output ASRC3 Mux" }, \ |
464 | { "Serial Output " #x " Capture Mux", "Serial Input 0", "Serial Input 0" }, \ |
465 | { "Serial Output " #x " Capture Mux", "Serial Input 1", "Serial Input 1" }, \ |
466 | { "Serial Output " #x " Capture Mux", "Serial Input 2", "Serial Input 2" }, \ |
467 | { "Serial Output " #x " Capture Mux", "Serial Input 3", "Serial Input 3" }, \ |
468 | { "Serial Output " #x " Capture Mux", "Serial Input 4", "Serial Input 4" }, \ |
469 | { "Serial Output " #x " Capture Mux", "Serial Input 5", "Serial Input 5" }, \ |
470 | { "Serial Output " #x " Capture Mux", "Serial Input 6", "Serial Input 6" }, \ |
471 | { "Serial Output " #x " Capture Mux", "Serial Input 7", "Serial Input 7" }, \ |
472 | { "Serial Output " #x, NULL, "Serial Output " #x " Capture Mux" }, \ |
473 | { "Capture", NULL, "Serial Output " #x } |
474 | |
475 | #define ADAU1372_ASRCO_ROUTES(x) \ |
476 | { "Output ASRC" #x " Mux", "Decimator0", "Decimator0 Mux" }, \ |
477 | { "Output ASRC" #x " Mux", "Decimator1", "Decimator1 Mux" }, \ |
478 | { "Output ASRC" #x " Mux", "Decimator2", "Decimator2 Mux" }, \ |
479 | { "Output ASRC" #x " Mux", "Decimator3", "Decimator3 Mux" } |
480 | |
481 | static const struct snd_soc_dapm_route adau1372_dapm_routes[] = { |
482 | { "PGA0" , NULL, "AIN0" }, |
483 | { "PGA1" , NULL, "AIN1" }, |
484 | { "PGA2" , NULL, "AIN2" }, |
485 | { "PGA3" , NULL, "AIN3" }, |
486 | |
487 | { "ADC0" , NULL, "PGA0" }, |
488 | { "ADC1" , NULL, "PGA1" }, |
489 | { "ADC2" , NULL, "PGA2" }, |
490 | { "ADC3" , NULL, "PGA3" }, |
491 | |
492 | { "Decimator0 Mux" , "ADC" , "ADC0" }, |
493 | { "Decimator1 Mux" , "ADC" , "ADC1" }, |
494 | { "Decimator2 Mux" , "ADC" , "ADC2" }, |
495 | { "Decimator3 Mux" , "ADC" , "ADC3" }, |
496 | |
497 | { "Decimator0 Mux" , "DMIC" , "DMIC0_1" }, |
498 | { "Decimator1 Mux" , "DMIC" , "DMIC0_1" }, |
499 | { "Decimator2 Mux" , "DMIC" , "DMIC2_3" }, |
500 | { "Decimator3 Mux" , "DMIC" , "DMIC2_3" }, |
501 | |
502 | { "Decimator0 Mux" , NULL, "ADC0 Filter" }, |
503 | { "Decimator1 Mux" , NULL, "ADC1 Filter" }, |
504 | { "Decimator2 Mux" , NULL, "ADC2 Filter" }, |
505 | { "Decimator3 Mux" , NULL, "ADC3 Filter" }, |
506 | |
507 | { "Output ASRC0 Mux" , NULL, "Output ASRC Supply" }, |
508 | { "Output ASRC1 Mux" , NULL, "Output ASRC Supply" }, |
509 | { "Output ASRC2 Mux" , NULL, "Output ASRC Supply" }, |
510 | { "Output ASRC3 Mux" , NULL, "Output ASRC Supply" }, |
511 | { "Output ASRC0 Mux" , NULL, "Output ASRC0 Decimator" }, |
512 | { "Output ASRC1 Mux" , NULL, "Output ASRC1 Decimator" }, |
513 | { "Output ASRC2 Mux" , NULL, "Output ASRC2 Decimator" }, |
514 | { "Output ASRC3 Mux" , NULL, "Output ASRC3 Decimator" }, |
515 | |
516 | ADAU1372_ASRCO_ROUTES(0), |
517 | ADAU1372_ASRCO_ROUTES(1), |
518 | ADAU1372_ASRCO_ROUTES(2), |
519 | ADAU1372_ASRCO_ROUTES(3), |
520 | |
521 | ADAU1372_SOUT_ROUTES(0), |
522 | ADAU1372_SOUT_ROUTES(1), |
523 | ADAU1372_SOUT_ROUTES(2), |
524 | ADAU1372_SOUT_ROUTES(3), |
525 | ADAU1372_SOUT_ROUTES(4), |
526 | ADAU1372_SOUT_ROUTES(5), |
527 | ADAU1372_SOUT_ROUTES(6), |
528 | ADAU1372_SOUT_ROUTES(7), |
529 | |
530 | { "Serial Input 0" , NULL, "Playback" }, |
531 | { "Serial Input 1" , NULL, "Playback" }, |
532 | { "Serial Input 2" , NULL, "Playback" }, |
533 | { "Serial Input 3" , NULL, "Playback" }, |
534 | { "Serial Input 4" , NULL, "Playback" }, |
535 | { "Serial Input 5" , NULL, "Playback" }, |
536 | { "Serial Input 6" , NULL, "Playback" }, |
537 | { "Serial Input 7" , NULL, "Playback" }, |
538 | |
539 | { "Input ASRC0 Mux" , "Serial Input 0+1" , "Serial Input 0" }, |
540 | { "Input ASRC1 Mux" , "Serial Input 0+1" , "Serial Input 1" }, |
541 | { "Input ASRC0 Mux" , "Serial Input 2+3" , "Serial Input 2" }, |
542 | { "Input ASRC1 Mux" , "Serial Input 2+3" , "Serial Input 3" }, |
543 | { "Input ASRC0 Mux" , "Serial Input 4+5" , "Serial Input 4" }, |
544 | { "Input ASRC1 Mux" , "Serial Input 4+5" , "Serial Input 5" }, |
545 | { "Input ASRC0 Mux" , "Serial Input 6+7" , "Serial Input 6" }, |
546 | { "Input ASRC1 Mux" , "Serial Input 6+7" , "Serial Input 7" }, |
547 | { "Input ASRC0 Mux" , NULL, "Input ASRC Supply" }, |
548 | { "Input ASRC1 Mux" , NULL, "Input ASRC Supply" }, |
549 | { "Input ASRC0 Mux" , NULL, "Input ASRC0 Interpolator" }, |
550 | { "Input ASRC1 Mux" , NULL, "Input ASRC1 Interpolator" }, |
551 | |
552 | { "DAC 0 Mux" , "Input ASRC0" , "Input ASRC0 Mux" }, |
553 | { "DAC 0 Mux" , "Input ASRC1" , "Input ASRC1 Mux" }, |
554 | { "DAC 1 Mux" , "Input ASRC0" , "Input ASRC0 Mux" }, |
555 | { "DAC 1 Mux" , "Input ASRC1" , "Input ASRC1 Mux" }, |
556 | |
557 | { "DAC0" , NULL, "DAC 0 Mux" }, |
558 | { "DAC1" , NULL, "DAC 1 Mux" }, |
559 | { "DAC0" , NULL, "DAC0 Modulator" }, |
560 | { "DAC1" , NULL, "DAC1 Modulator" }, |
561 | |
562 | { "OP_STAGE_LP" , NULL, "DAC0" }, |
563 | { "OP_STAGE_LN" , NULL, "DAC0" }, |
564 | { "OP_STAGE_RP" , NULL, "DAC1" }, |
565 | { "OP_STAGE_RN" , NULL, "DAC1" }, |
566 | |
567 | { "HPOUTL" , NULL, "OP_STAGE_LP" }, |
568 | { "HPOUTL" , NULL, "OP_STAGE_LN" }, |
569 | { "HPOUTR" , NULL, "OP_STAGE_RP" }, |
570 | { "HPOUTR" , NULL, "OP_STAGE_RN" }, |
571 | }; |
572 | |
573 | static int adau1372_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
574 | { |
575 | struct adau1372 *adau1372 = snd_soc_dai_get_drvdata(dai); |
576 | unsigned int sai0 = 0, sai1 = 0; |
577 | bool invert_lrclk = false; |
578 | |
579 | switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { |
580 | case SND_SOC_DAIFMT_CBP_CFP: |
581 | adau1372->clock_provider = true; |
582 | sai1 |= ADAU1372_SAI1_MS; |
583 | break; |
584 | case SND_SOC_DAIFMT_CBC_CFC: |
585 | adau1372->clock_provider = false; |
586 | break; |
587 | default: |
588 | return -EINVAL; |
589 | } |
590 | |
591 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
592 | case SND_SOC_DAIFMT_NB_NF: |
593 | invert_lrclk = false; |
594 | break; |
595 | case SND_SOC_DAIFMT_NB_IF: |
596 | invert_lrclk = true; |
597 | break; |
598 | case SND_SOC_DAIFMT_IB_NF: |
599 | invert_lrclk = false; |
600 | sai1 |= ADAU1372_SAI1_BCLKEDGE; |
601 | break; |
602 | case SND_SOC_DAIFMT_IB_IF: |
603 | invert_lrclk = true; |
604 | sai1 |= ADAU1372_SAI1_BCLKEDGE; |
605 | break; |
606 | } |
607 | |
608 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
609 | case SND_SOC_DAIFMT_I2S: |
610 | sai0 |= ADAU1372_SAI0_DELAY1; |
611 | break; |
612 | case SND_SOC_DAIFMT_LEFT_J: |
613 | sai0 |= ADAU1372_SAI0_DELAY0; |
614 | invert_lrclk = !invert_lrclk; |
615 | break; |
616 | case SND_SOC_DAIFMT_DSP_A: |
617 | sai0 |= ADAU1372_SAI0_DELAY1; |
618 | sai1 |= ADAU1372_SAI1_LR_MODE; |
619 | break; |
620 | case SND_SOC_DAIFMT_DSP_B: |
621 | sai0 |= ADAU1372_SAI0_DELAY0; |
622 | sai1 |= ADAU1372_SAI1_LR_MODE; |
623 | break; |
624 | } |
625 | |
626 | if (invert_lrclk) |
627 | sai1 |= ADAU1372_SAI1_LR_POL; |
628 | |
629 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_SAI0, ADAU1372_SAI0_DELAY_MASK, val: sai0); |
630 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_SAI1, |
631 | ADAU1372_SAI1_MS | ADAU1372_SAI1_BCLKEDGE | |
632 | ADAU1372_SAI1_LR_MODE | ADAU1372_SAI1_LR_POL, val: sai1); |
633 | |
634 | return 0; |
635 | } |
636 | |
637 | static int adau1372_hw_params(struct snd_pcm_substream *substream, |
638 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
639 | { |
640 | struct adau1372 *adau1372 = snd_soc_dai_get_drvdata(dai); |
641 | unsigned int rate = params_rate(p: params); |
642 | unsigned int slot_width; |
643 | unsigned int sai0, sai1; |
644 | unsigned int i; |
645 | |
646 | for (i = 0; i < ARRAY_SIZE(adau1372_rates); i++) { |
647 | if (rate == adau1372_rates[i]) |
648 | break; |
649 | } |
650 | |
651 | if (i == ARRAY_SIZE(adau1372_rates)) |
652 | return -EINVAL; |
653 | |
654 | sai0 = i; |
655 | |
656 | slot_width = adau1372->slot_width; |
657 | if (slot_width == 0) |
658 | slot_width = params_width(p: params); |
659 | |
660 | switch (slot_width) { |
661 | case 16: |
662 | sai1 = ADAU1372_SAI1_BCLKRATE; |
663 | break; |
664 | case 24: |
665 | case 32: |
666 | sai1 = 0; |
667 | break; |
668 | default: |
669 | return -EINVAL; |
670 | } |
671 | |
672 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_SAI0, ADAU1372_SAI0_FS_MASK, val: sai0); |
673 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_SAI1, ADAU1372_SAI1_BCLKRATE, val: sai1); |
674 | |
675 | return 0; |
676 | } |
677 | |
678 | static int adau1372_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, |
679 | unsigned int rx_mask, int slots, int width) |
680 | { |
681 | struct adau1372 *adau1372 = snd_soc_dai_get_drvdata(dai); |
682 | unsigned int sai0, sai1; |
683 | |
684 | /* I2S mode */ |
685 | if (slots == 0) { |
686 | /* The other settings dont matter in I2S mode */ |
687 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_SAI0, |
688 | ADAU1372_SAI0_SAI_MASK, ADAU1372_SAI0_SAI_I2S); |
689 | adau1372->rate_constraints.mask = ADAU1372_RATE_MASK_TDM2; |
690 | adau1372->slot_width = 0; |
691 | return 0; |
692 | } |
693 | |
694 | /* We have 8 channels anything outside that is not supported */ |
695 | if ((tx_mask & ~0xff) != 0 || (rx_mask & ~0xff) != 0) |
696 | return -EINVAL; |
697 | |
698 | switch (width) { |
699 | case 16: |
700 | sai1 = ADAU1372_SAI1_BCLK_TDMC; |
701 | break; |
702 | case 24: |
703 | case 32: |
704 | sai1 = 0; |
705 | break; |
706 | default: |
707 | return -EINVAL; |
708 | } |
709 | |
710 | switch (slots) { |
711 | case 2: |
712 | sai0 = ADAU1372_SAI0_SAI_TDM2; |
713 | adau1372->rate_constraints.mask = ADAU1372_RATE_MASK_TDM2; |
714 | break; |
715 | case 4: |
716 | sai0 = ADAU1372_SAI0_SAI_TDM4; |
717 | if (adau1372->clock_provider) |
718 | adau1372->rate_constraints.mask = ADAU1372_RATE_MASK_TDM4_MASTER; |
719 | else |
720 | adau1372->rate_constraints.mask = ADAU1372_RATE_MASK_TDM4; |
721 | break; |
722 | case 8: |
723 | sai0 = ADAU1372_SAI0_SAI_TDM8; |
724 | adau1372->rate_constraints.mask = ADAU1372_RATE_MASK_TDM8; |
725 | break; |
726 | default: |
727 | return -EINVAL; |
728 | } |
729 | |
730 | adau1372->slot_width = width; |
731 | |
732 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_SAI0, ADAU1372_SAI0_SAI_MASK, val: sai0); |
733 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_SAI1, ADAU1372_SAI1_BCLK_TDMC, val: sai1); |
734 | |
735 | /* Mask is inverted in hardware */ |
736 | regmap_write(map: adau1372->regmap, ADAU1372_REG_SOUT_CTRL, val: ~tx_mask); |
737 | |
738 | return 0; |
739 | } |
740 | |
741 | static int adau1372_set_tristate(struct snd_soc_dai *dai, int tristate) |
742 | { |
743 | struct adau1372 *adau1372 = snd_soc_dai_get_drvdata(dai); |
744 | unsigned int sai1; |
745 | |
746 | if (tristate) |
747 | sai1 = ADAU1372_SAI1_TDM_TS; |
748 | else |
749 | sai1 = 0; |
750 | |
751 | return regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_SAI1, ADAU1372_SAI1_TDM_TS, val: sai1); |
752 | } |
753 | |
754 | static int adau1372_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) |
755 | { |
756 | struct adau1372 *adau1372 = snd_soc_dai_get_drvdata(dai); |
757 | |
758 | snd_pcm_hw_constraint_list(runtime: substream->runtime, cond: 0, SNDRV_PCM_HW_PARAM_RATE, |
759 | l: &adau1372->rate_constraints); |
760 | |
761 | return 0; |
762 | } |
763 | |
764 | static void adau1372_enable_pll(struct adau1372 *adau1372) |
765 | { |
766 | unsigned int val, timeout = 0; |
767 | int ret; |
768 | |
769 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_CLK_CTRL, |
770 | ADAU1372_CLK_CTRL_PLL_EN, ADAU1372_CLK_CTRL_PLL_EN); |
771 | do { |
772 | /* Takes about 1ms to lock */ |
773 | usleep_range(min: 1000, max: 2000); |
774 | ret = regmap_read(map: adau1372->regmap, ADAU1372_REG_PLL(5), val: &val); |
775 | if (ret) |
776 | break; |
777 | timeout++; |
778 | } while (!(val & 1) && timeout < 3); |
779 | |
780 | if (ret < 0 || !(val & 1)) |
781 | dev_err(adau1372->dev, "Failed to lock PLL\n" ); |
782 | } |
783 | |
784 | static void adau1372_set_power(struct adau1372 *adau1372, bool enable) |
785 | { |
786 | if (adau1372->enabled == enable) |
787 | return; |
788 | |
789 | if (enable) { |
790 | unsigned int clk_ctrl = ADAU1372_CLK_CTRL_MCLK_EN; |
791 | |
792 | clk_prepare_enable(clk: adau1372->mclk); |
793 | if (adau1372->pd_gpio) |
794 | gpiod_set_value(desc: adau1372->pd_gpio, value: 0); |
795 | |
796 | if (adau1372->switch_mode) |
797 | adau1372->switch_mode(adau1372->dev); |
798 | |
799 | regcache_cache_only(map: adau1372->regmap, enable: false); |
800 | |
801 | /* |
802 | * Clocks needs to be enabled before any other register can be |
803 | * accessed. |
804 | */ |
805 | if (adau1372->use_pll) { |
806 | adau1372_enable_pll(adau1372); |
807 | clk_ctrl |= ADAU1372_CLK_CTRL_CLKSRC; |
808 | } |
809 | |
810 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_CLK_CTRL, |
811 | ADAU1372_CLK_CTRL_MCLK_EN | ADAU1372_CLK_CTRL_CLKSRC, val: clk_ctrl); |
812 | regcache_sync(map: adau1372->regmap); |
813 | } else { |
814 | if (adau1372->pd_gpio) { |
815 | /* |
816 | * This will turn everything off and reset the register |
817 | * map. No need to do any register writes to manually |
818 | * turn things off. |
819 | */ |
820 | gpiod_set_value(desc: adau1372->pd_gpio, value: 1); |
821 | regcache_mark_dirty(map: adau1372->regmap); |
822 | } else { |
823 | regmap_update_bits(map: adau1372->regmap, ADAU1372_REG_CLK_CTRL, |
824 | ADAU1372_CLK_CTRL_MCLK_EN | ADAU1372_CLK_CTRL_PLL_EN, val: 0); |
825 | } |
826 | clk_disable_unprepare(clk: adau1372->mclk); |
827 | regcache_cache_only(map: adau1372->regmap, enable: true); |
828 | } |
829 | |
830 | adau1372->enabled = enable; |
831 | } |
832 | |
833 | static int adau1372_set_bias_level(struct snd_soc_component *component, |
834 | enum snd_soc_bias_level level) |
835 | { |
836 | struct adau1372 *adau1372 = snd_soc_component_get_drvdata(c: component); |
837 | |
838 | switch (level) { |
839 | case SND_SOC_BIAS_ON: |
840 | break; |
841 | case SND_SOC_BIAS_PREPARE: |
842 | break; |
843 | case SND_SOC_BIAS_STANDBY: |
844 | adau1372_set_power(adau1372, enable: true); |
845 | break; |
846 | case SND_SOC_BIAS_OFF: |
847 | adau1372_set_power(adau1372, enable: false); |
848 | break; |
849 | } |
850 | |
851 | return 0; |
852 | } |
853 | |
854 | static const struct snd_soc_component_driver adau1372_driver = { |
855 | .set_bias_level = adau1372_set_bias_level, |
856 | .controls = adau1372_controls, |
857 | .num_controls = ARRAY_SIZE(adau1372_controls), |
858 | .dapm_widgets = adau1372_dapm_widgets, |
859 | .num_dapm_widgets = ARRAY_SIZE(adau1372_dapm_widgets), |
860 | .dapm_routes = adau1372_dapm_routes, |
861 | .num_dapm_routes = ARRAY_SIZE(adau1372_dapm_routes), |
862 | .endianness = 1, |
863 | }; |
864 | |
865 | static const struct snd_soc_dai_ops adau1372_dai_ops = { |
866 | .set_fmt = adau1372_set_dai_fmt, |
867 | .set_tdm_slot = adau1372_set_tdm_slot, |
868 | .set_tristate = adau1372_set_tristate, |
869 | .hw_params = adau1372_hw_params, |
870 | .startup = adau1372_startup, |
871 | }; |
872 | |
873 | #define ADAU1372_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ |
874 | SNDRV_PCM_FMTBIT_S24_LE | \ |
875 | SNDRV_PCM_FMTBIT_S32_LE) |
876 | |
877 | static struct snd_soc_dai_driver adau1372_dai_driver = { |
878 | .name = "adau1372" , |
879 | .playback = { |
880 | .stream_name = "Playback" , |
881 | .channels_min = 2, |
882 | .channels_max = 8, |
883 | .rates = SNDRV_PCM_RATE_KNOT, |
884 | .formats = ADAU1372_FORMATS, |
885 | .sig_bits = 24, |
886 | }, |
887 | .capture = { |
888 | .stream_name = "Capture" , |
889 | .channels_min = 2, |
890 | .channels_max = 8, |
891 | .rates = SNDRV_PCM_RATE_KNOT, |
892 | .formats = ADAU1372_FORMATS, |
893 | .sig_bits = 24, |
894 | }, |
895 | .ops = &adau1372_dai_ops, |
896 | .symmetric_rate = 1, |
897 | }; |
898 | |
899 | static int adau1372_setup_pll(struct adau1372 *adau1372, unsigned int rate) |
900 | { |
901 | u8 regs[5]; |
902 | unsigned int i; |
903 | int ret; |
904 | |
905 | ret = adau_calc_pll_cfg(freq_in: rate, freq_out: 49152000, regs); |
906 | if (ret < 0) |
907 | return ret; |
908 | |
909 | for (i = 0; i < ARRAY_SIZE(regs); i++) |
910 | regmap_write(map: adau1372->regmap, ADAU1372_REG_PLL(i), val: regs[i]); |
911 | |
912 | return 0; |
913 | } |
914 | |
915 | int adau1372_probe(struct device *dev, struct regmap *regmap, |
916 | void (*switch_mode)(struct device *dev)) |
917 | { |
918 | struct adau1372 *adau1372; |
919 | unsigned int clk_ctrl; |
920 | unsigned long rate; |
921 | int ret; |
922 | |
923 | if (IS_ERR(ptr: regmap)) |
924 | return PTR_ERR(ptr: regmap); |
925 | |
926 | adau1372 = devm_kzalloc(dev, size: sizeof(*adau1372), GFP_KERNEL); |
927 | if (!adau1372) |
928 | return -ENOMEM; |
929 | |
930 | adau1372->mclk = devm_clk_get(dev, id: "mclk" ); |
931 | if (IS_ERR(ptr: adau1372->mclk)) |
932 | return PTR_ERR(ptr: adau1372->mclk); |
933 | |
934 | adau1372->pd_gpio = devm_gpiod_get_optional(dev, con_id: "powerdown" , flags: GPIOD_OUT_HIGH); |
935 | if (IS_ERR(ptr: adau1372->pd_gpio)) |
936 | return PTR_ERR(ptr: adau1372->pd_gpio); |
937 | |
938 | adau1372->regmap = regmap; |
939 | adau1372->switch_mode = switch_mode; |
940 | adau1372->dev = dev; |
941 | adau1372->rate_constraints.list = adau1372_rates; |
942 | adau1372->rate_constraints.count = ARRAY_SIZE(adau1372_rates); |
943 | adau1372->rate_constraints.mask = ADAU1372_RATE_MASK_TDM2; |
944 | |
945 | dev_set_drvdata(dev, data: adau1372); |
946 | |
947 | /* |
948 | * The datasheet says that the internal MCLK always needs to run at |
949 | * 12.288MHz. Automatically choose a valid configuration from the |
950 | * external clock. |
951 | */ |
952 | rate = clk_get_rate(clk: adau1372->mclk); |
953 | |
954 | switch (rate) { |
955 | case 12288000: |
956 | clk_ctrl = ADAU1372_CLK_CTRL_CC_MDIV; |
957 | break; |
958 | case 24576000: |
959 | clk_ctrl = 0; |
960 | break; |
961 | default: |
962 | clk_ctrl = 0; |
963 | ret = adau1372_setup_pll(adau1372, rate); |
964 | if (ret < 0) |
965 | return ret; |
966 | adau1372->use_pll = true; |
967 | break; |
968 | } |
969 | |
970 | /* |
971 | * Most of the registers are inaccessible unless the internal clock is |
972 | * enabled. |
973 | */ |
974 | regcache_cache_only(map: regmap, enable: true); |
975 | |
976 | regmap_update_bits(map: regmap, ADAU1372_REG_CLK_CTRL, ADAU1372_CLK_CTRL_CC_MDIV, val: clk_ctrl); |
977 | |
978 | /* |
979 | * No pinctrl support yet, put the multi-purpose pins in the most |
980 | * sensible mode for general purpose CODEC operation. |
981 | */ |
982 | regmap_write(map: regmap, ADAU1372_REG_MODE_MP(1), val: 0x00); /* SDATA OUT */ |
983 | regmap_write(map: regmap, ADAU1372_REG_MODE_MP(6), val: 0x12); /* CLOCKOUT */ |
984 | |
985 | regmap_write(map: regmap, ADAU1372_REG_OP_STAGE_MUTE, val: 0x0); |
986 | |
987 | regmap_write(map: regmap, reg: 0x7, val: 0x01); /* CLOCK OUT */ |
988 | |
989 | return devm_snd_soc_register_component(dev, component_driver: &adau1372_driver, dai_drv: &adau1372_dai_driver, num_dai: 1); |
990 | } |
991 | EXPORT_SYMBOL(adau1372_probe); |
992 | |
993 | static const struct reg_default adau1372_reg_defaults[] = { |
994 | { ADAU1372_REG_CLK_CTRL, 0x00 }, |
995 | { ADAU1372_REG_PLL(0), 0x00 }, |
996 | { ADAU1372_REG_PLL(1), 0x00 }, |
997 | { ADAU1372_REG_PLL(2), 0x00 }, |
998 | { ADAU1372_REG_PLL(3), 0x00 }, |
999 | { ADAU1372_REG_PLL(4), 0x00 }, |
1000 | { ADAU1372_REG_PLL(5), 0x00 }, |
1001 | { ADAU1372_REG_DAC_SOURCE, 0x10 }, |
1002 | { ADAU1372_REG_SOUT_SOURCE_0_1, 0x54 }, |
1003 | { ADAU1372_REG_SOUT_SOURCE_2_3, 0x76 }, |
1004 | { ADAU1372_REG_SOUT_SOURCE_4_5, 0x54 }, |
1005 | { ADAU1372_REG_SOUT_SOURCE_6_7, 0x76 }, |
1006 | { ADAU1372_REG_ADC_SDATA_CH, 0x04 }, |
1007 | { ADAU1372_REG_ASRCO_SOURCE_0_1, 0x10 }, |
1008 | { ADAU1372_REG_ASRCO_SOURCE_2_3, 0x32 }, |
1009 | { ADAU1372_REG_ASRC_MODE, 0x00 }, |
1010 | { ADAU1372_REG_ADC_CTRL0, 0x19 }, |
1011 | { ADAU1372_REG_ADC_CTRL1, 0x19 }, |
1012 | { ADAU1372_REG_ADC_CTRL2, 0x00 }, |
1013 | { ADAU1372_REG_ADC_CTRL3, 0x00 }, |
1014 | { ADAU1372_REG_ADC_VOL(0), 0x00 }, |
1015 | { ADAU1372_REG_ADC_VOL(1), 0x00 }, |
1016 | { ADAU1372_REG_ADC_VOL(2), 0x00 }, |
1017 | { ADAU1372_REG_ADC_VOL(3), 0x00 }, |
1018 | { ADAU1372_REG_PGA_CTRL(0), 0x40 }, |
1019 | { ADAU1372_REG_PGA_CTRL(1), 0x40 }, |
1020 | { ADAU1372_REG_PGA_CTRL(2), 0x40 }, |
1021 | { ADAU1372_REG_PGA_CTRL(3), 0x40 }, |
1022 | { ADAU1372_REG_PGA_BOOST, 0x00 }, |
1023 | { ADAU1372_REG_MICBIAS, 0x00 }, |
1024 | { ADAU1372_REG_DAC_CTRL, 0x18 }, |
1025 | { ADAU1372_REG_DAC_VOL(0), 0x00 }, |
1026 | { ADAU1372_REG_DAC_VOL(1), 0x00 }, |
1027 | { ADAU1372_REG_OP_STAGE_MUTE, 0x0f }, |
1028 | { ADAU1372_REG_SAI0, 0x00 }, |
1029 | { ADAU1372_REG_SAI1, 0x00 }, |
1030 | { ADAU1372_REG_SOUT_CTRL, 0x00 }, |
1031 | { ADAU1372_REG_MODE_MP(0), 0x00 }, |
1032 | { ADAU1372_REG_MODE_MP(1), 0x10 }, |
1033 | { ADAU1372_REG_MODE_MP(4), 0x00 }, |
1034 | { ADAU1372_REG_MODE_MP(5), 0x00 }, |
1035 | { ADAU1372_REG_MODE_MP(6), 0x11 }, |
1036 | { ADAU1372_REG_OP_STAGE_CTRL, 0x0f }, |
1037 | { ADAU1372_REG_DECIM_PWR, 0x00 }, |
1038 | { ADAU1372_REG_INTERP_PWR, 0x00 }, |
1039 | { ADAU1372_REG_BIAS_CTRL0, 0x00 }, |
1040 | { ADAU1372_REG_BIAS_CTRL1, 0x00 }, |
1041 | }; |
1042 | |
1043 | static bool adau1372_volatile_register(struct device *dev, unsigned int reg) |
1044 | { |
1045 | if (reg == ADAU1372_REG_PLL(5)) |
1046 | return true; |
1047 | |
1048 | return false; |
1049 | } |
1050 | |
1051 | const struct regmap_config adau1372_regmap_config = { |
1052 | .val_bits = 8, |
1053 | .reg_bits = 16, |
1054 | .max_register = 0x4d, |
1055 | |
1056 | .reg_defaults = adau1372_reg_defaults, |
1057 | .num_reg_defaults = ARRAY_SIZE(adau1372_reg_defaults), |
1058 | .volatile_reg = adau1372_volatile_register, |
1059 | .cache_type = REGCACHE_MAPLE, |
1060 | }; |
1061 | EXPORT_SYMBOL_GPL(adau1372_regmap_config); |
1062 | |
1063 | MODULE_DESCRIPTION("ASoC ADAU1372 CODEC driver" ); |
1064 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>" ); |
1065 | MODULE_LICENSE("GPL v2" ); |
1066 | |