1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * This driver supports the digital controls for the internal codec
4 * found in Allwinner's A33 SoCs.
5 *
6 * (C) Copyright 2010-2016
7 * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
8 * huangxin <huangxin@Reuuimllatech.com>
9 * Mylène Josserand <mylene.josserand@free-electrons.com>
10 */
11
12 #include <linux/module.h>
13 #include <linux/delay.h>
14 #include <linux/clk.h>
15 #include <linux/input.h>
16 #include <linux/io.h>
17 #include <linux/irq.h>
18 #include <linux/mutex.h>
19 #include <linux/of.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/regmap.h>
22 #include <linux/log2.h>
23
24 #include <sound/jack.h>
25 #include <sound/pcm_params.h>
26 #include <sound/soc.h>
27 #include <sound/soc-dapm.h>
28 #include <sound/tlv.h>
29
30 #define SUN8I_SYSCLK_CTL 0x00c
31 #define SUN8I_SYSCLK_CTL_AIF1CLK_ENA 11
32 #define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL (0x2 << 8)
33 #define SUN8I_SYSCLK_CTL_AIF2CLK_ENA 7
34 #define SUN8I_SYSCLK_CTL_AIF2CLK_SRC_PLL (0x2 << 4)
35 #define SUN8I_SYSCLK_CTL_SYSCLK_ENA 3
36 #define SUN8I_SYSCLK_CTL_SYSCLK_SRC 0
37 #define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK (0x0 << 0)
38 #define SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF2CLK (0x1 << 0)
39 #define SUN8I_MOD_CLK_ENA 0x010
40 #define SUN8I_MOD_CLK_ENA_AIF1 15
41 #define SUN8I_MOD_CLK_ENA_AIF2 14
42 #define SUN8I_MOD_CLK_ENA_AIF3 13
43 #define SUN8I_MOD_CLK_ENA_ADC 3
44 #define SUN8I_MOD_CLK_ENA_DAC 2
45 #define SUN8I_MOD_RST_CTL 0x014
46 #define SUN8I_MOD_RST_CTL_AIF1 15
47 #define SUN8I_MOD_RST_CTL_AIF2 14
48 #define SUN8I_MOD_RST_CTL_AIF3 13
49 #define SUN8I_MOD_RST_CTL_ADC 3
50 #define SUN8I_MOD_RST_CTL_DAC 2
51 #define SUN8I_SYS_SR_CTRL 0x018
52 #define SUN8I_SYS_SR_CTRL_AIF1_FS 12
53 #define SUN8I_SYS_SR_CTRL_AIF2_FS 8
54 #define SUN8I_AIF_CLK_CTRL(n) (0x040 * (1 + (n)))
55 #define SUN8I_AIF_CLK_CTRL_MSTR_MOD 15
56 #define SUN8I_AIF_CLK_CTRL_CLK_INV 13
57 #define SUN8I_AIF_CLK_CTRL_BCLK_DIV 9
58 #define SUN8I_AIF_CLK_CTRL_LRCK_DIV 6
59 #define SUN8I_AIF_CLK_CTRL_WORD_SIZ 4
60 #define SUN8I_AIF_CLK_CTRL_DATA_FMT 2
61 #define SUN8I_AIF1_ADCDAT_CTRL 0x044
62 #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA 15
63 #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA 14
64 #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC 10
65 #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC 8
66 #define SUN8I_AIF1_DACDAT_CTRL 0x048
67 #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA 15
68 #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA 14
69 #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC 10
70 #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC 8
71 #define SUN8I_AIF1_MXR_SRC 0x04c
72 #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L 15
73 #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL 14
74 #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_ADCL 13
75 #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACR 12
76 #define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R 11
77 #define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR 10
78 #define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR 9
79 #define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL 8
80 #define SUN8I_AIF1_VOL_CTRL1 0x050
81 #define SUN8I_AIF1_VOL_CTRL1_AD0L_VOL 8
82 #define SUN8I_AIF1_VOL_CTRL1_AD0R_VOL 0
83 #define SUN8I_AIF1_VOL_CTRL3 0x058
84 #define SUN8I_AIF1_VOL_CTRL3_DA0L_VOL 8
85 #define SUN8I_AIF1_VOL_CTRL3_DA0R_VOL 0
86 #define SUN8I_AIF2_ADCDAT_CTRL 0x084
87 #define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_ENA 15
88 #define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_ENA 14
89 #define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_SRC 10
90 #define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_SRC 8
91 #define SUN8I_AIF2_DACDAT_CTRL 0x088
92 #define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_ENA 15
93 #define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_ENA 14
94 #define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_SRC 10
95 #define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_SRC 8
96 #define SUN8I_AIF2_MXR_SRC 0x08c
97 #define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA0L 15
98 #define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA1L 14
99 #define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF2DACR 13
100 #define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_ADCL 12
101 #define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA0R 11
102 #define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA1R 10
103 #define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF2DACL 9
104 #define SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_ADCR 8
105 #define SUN8I_AIF2_VOL_CTRL1 0x090
106 #define SUN8I_AIF2_VOL_CTRL1_ADCL_VOL 8
107 #define SUN8I_AIF2_VOL_CTRL1_ADCR_VOL 0
108 #define SUN8I_AIF2_VOL_CTRL2 0x098
109 #define SUN8I_AIF2_VOL_CTRL2_DACL_VOL 8
110 #define SUN8I_AIF2_VOL_CTRL2_DACR_VOL 0
111 #define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF1 (0x0 << 0)
112 #define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF2 (0x1 << 0)
113 #define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF1CLK (0x2 << 0)
114 #define SUN8I_AIF3_PATH_CTRL 0x0cc
115 #define SUN8I_AIF3_PATH_CTRL_AIF3_ADC_SRC 10
116 #define SUN8I_AIF3_PATH_CTRL_AIF2_DAC_SRC 8
117 #define SUN8I_AIF3_PATH_CTRL_AIF3_PINS_TRI 7
118 #define SUN8I_ADC_DIG_CTRL 0x100
119 #define SUN8I_ADC_DIG_CTRL_ENAD 15
120 #define SUN8I_ADC_DIG_CTRL_ADOUT_DTS 2
121 #define SUN8I_ADC_DIG_CTRL_ADOUT_DLY 1
122 #define SUN8I_ADC_VOL_CTRL 0x104
123 #define SUN8I_ADC_VOL_CTRL_ADCL_VOL 8
124 #define SUN8I_ADC_VOL_CTRL_ADCR_VOL 0
125 #define SUN8I_HMIC_CTRL1 0x110
126 #define SUN8I_HMIC_CTRL1_HMIC_M 12
127 #define SUN8I_HMIC_CTRL1_HMIC_N 8
128 #define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB 5
129 #define SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN 4
130 #define SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN 3
131 #define SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN 0
132 #define SUN8I_HMIC_CTRL2 0x114
133 #define SUN8I_HMIC_CTRL2_HMIC_SAMPLE 14
134 #define SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD 8
135 #define SUN8I_HMIC_CTRL2_HMIC_SF 6
136 #define SUN8I_HMIC_STS 0x118
137 #define SUN8I_HMIC_STS_MDATA_DISCARD 13
138 #define SUN8I_HMIC_STS_HMIC_DATA 8
139 #define SUN8I_HMIC_STS_JACK_OUT_IRQ_ST 4
140 #define SUN8I_HMIC_STS_JACK_IN_IRQ_ST 3
141 #define SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST 0
142 #define SUN8I_DAC_DIG_CTRL 0x120
143 #define SUN8I_DAC_DIG_CTRL_ENDA 15
144 #define SUN8I_DAC_VOL_CTRL 0x124
145 #define SUN8I_DAC_VOL_CTRL_DACL_VOL 8
146 #define SUN8I_DAC_VOL_CTRL_DACR_VOL 0
147 #define SUN8I_DAC_MXR_SRC 0x130
148 #define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L 15
149 #define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L 14
150 #define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL 13
151 #define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL 12
152 #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R 11
153 #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R 10
154 #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR 9
155 #define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR 8
156
157 #define SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK GENMASK(9, 8)
158 #define SUN8I_SYSCLK_CTL_AIF2CLK_SRC_MASK GENMASK(5, 4)
159 #define SUN8I_SYS_SR_CTRL_AIF1_FS_MASK GENMASK(15, 12)
160 #define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK GENMASK(11, 8)
161 #define SUN8I_AIF_CLK_CTRL_CLK_INV_MASK GENMASK(14, 13)
162 #define SUN8I_AIF_CLK_CTRL_BCLK_DIV_MASK GENMASK(12, 9)
163 #define SUN8I_AIF_CLK_CTRL_LRCK_DIV_MASK GENMASK(8, 6)
164 #define SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK GENMASK(5, 4)
165 #define SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK GENMASK(3, 2)
166 #define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK GENMASK(1, 0)
167 #define SUN8I_HMIC_CTRL1_HMIC_M_MASK GENMASK(15, 12)
168 #define SUN8I_HMIC_CTRL1_HMIC_N_MASK GENMASK(11, 8)
169 #define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB_MASK GENMASK(6, 5)
170 #define SUN8I_HMIC_CTRL2_HMIC_SAMPLE_MASK GENMASK(15, 14)
171 #define SUN8I_HMIC_CTRL2_HMIC_SF_MASK GENMASK(7, 6)
172 #define SUN8I_HMIC_STS_HMIC_DATA_MASK GENMASK(12, 8)
173
174 #define SUN8I_CODEC_BUTTONS (SND_JACK_BTN_0|\
175 SND_JACK_BTN_1|\
176 SND_JACK_BTN_2|\
177 SND_JACK_BTN_3)
178
179 #define SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE 48000
180
181 #define SUN8I_CODEC_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 |\
182 SNDRV_PCM_FMTBIT_S16_LE |\
183 SNDRV_PCM_FMTBIT_S20_LE |\
184 SNDRV_PCM_FMTBIT_S24_LE |\
185 SNDRV_PCM_FMTBIT_S20_3LE|\
186 SNDRV_PCM_FMTBIT_S24_3LE)
187
188 #define SUN8I_CODEC_PCM_RATES (SNDRV_PCM_RATE_8000_48000|\
189 SNDRV_PCM_RATE_88200 |\
190 SNDRV_PCM_RATE_96000 |\
191 SNDRV_PCM_RATE_176400 |\
192 SNDRV_PCM_RATE_192000 |\
193 SNDRV_PCM_RATE_KNOT)
194
195 enum {
196 SUN8I_CODEC_AIF1,
197 SUN8I_CODEC_AIF2,
198 SUN8I_CODEC_AIF3,
199 SUN8I_CODEC_NAIFS
200 };
201
202 struct sun8i_codec_aif {
203 unsigned int lrck_div_order;
204 unsigned int sample_rate;
205 unsigned int slots;
206 unsigned int slot_width;
207 unsigned int active_streams : 2;
208 unsigned int open_streams : 2;
209 };
210
211 struct sun8i_codec_quirks {
212 bool bus_clock : 1;
213 bool jack_detection : 1;
214 bool legacy_widgets : 1;
215 bool lrck_inversion : 1;
216 };
217
218 enum {
219 SUN8I_JACK_STATUS_DISCONNECTED,
220 SUN8I_JACK_STATUS_WAITING_HBIAS,
221 SUN8I_JACK_STATUS_CONNECTED,
222 };
223
224 struct sun8i_codec {
225 struct snd_soc_component *component;
226 struct regmap *regmap;
227 struct clk *clk_bus;
228 struct clk *clk_module;
229 const struct sun8i_codec_quirks *quirks;
230 struct sun8i_codec_aif aifs[SUN8I_CODEC_NAIFS];
231 struct snd_soc_jack *jack;
232 struct delayed_work jack_work;
233 int jack_irq;
234 int jack_status;
235 int jack_type;
236 int jack_last_sample;
237 ktime_t jack_hbias_ready;
238 struct mutex jack_mutex;
239 int last_hmic_irq;
240 unsigned int sysclk_rate;
241 int sysclk_refcnt;
242 };
243
244 static struct snd_soc_dai_driver sun8i_codec_dais[];
245
sun8i_codec_runtime_resume(struct device * dev)246 static int sun8i_codec_runtime_resume(struct device *dev)
247 {
248 struct sun8i_codec *scodec = dev_get_drvdata(dev);
249 int ret;
250
251 ret = clk_prepare_enable(scodec->clk_bus);
252 if (ret) {
253 dev_err(dev, "Failed to enable the bus clock\n");
254 return ret;
255 }
256
257 regcache_cache_only(scodec->regmap, false);
258
259 ret = regcache_sync(scodec->regmap);
260 if (ret) {
261 dev_err(dev, "Failed to sync regmap cache\n");
262 return ret;
263 }
264
265 return 0;
266 }
267
sun8i_codec_runtime_suspend(struct device * dev)268 static int sun8i_codec_runtime_suspend(struct device *dev)
269 {
270 struct sun8i_codec *scodec = dev_get_drvdata(dev);
271
272 regcache_cache_only(scodec->regmap, true);
273 regcache_mark_dirty(scodec->regmap);
274
275 clk_disable_unprepare(scodec->clk_bus);
276
277 return 0;
278 }
279
sun8i_codec_get_hw_rate(unsigned int sample_rate)280 static int sun8i_codec_get_hw_rate(unsigned int sample_rate)
281 {
282 switch (sample_rate) {
283 case 7350:
284 case 8000:
285 return 0x0;
286 case 11025:
287 return 0x1;
288 case 12000:
289 return 0x2;
290 case 14700:
291 case 16000:
292 return 0x3;
293 case 22050:
294 return 0x4;
295 case 24000:
296 return 0x5;
297 case 29400:
298 case 32000:
299 return 0x6;
300 case 44100:
301 return 0x7;
302 case 48000:
303 return 0x8;
304 case 88200:
305 case 96000:
306 return 0x9;
307 case 176400:
308 case 192000:
309 return 0xa;
310 default:
311 return -EINVAL;
312 }
313 }
314
sun8i_codec_update_sample_rate(struct sun8i_codec * scodec)315 static int sun8i_codec_update_sample_rate(struct sun8i_codec *scodec)
316 {
317 unsigned int max_rate = 0;
318 int hw_rate, i;
319
320 for (i = SUN8I_CODEC_AIF1; i < SUN8I_CODEC_NAIFS; ++i) {
321 struct sun8i_codec_aif *aif = &scodec->aifs[i];
322
323 if (aif->active_streams)
324 max_rate = max(max_rate, aif->sample_rate);
325 }
326
327 /* Set the sample rate for ADC->DAC passthrough when no AIF is active. */
328 if (!max_rate)
329 max_rate = SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE;
330
331 hw_rate = sun8i_codec_get_hw_rate(max_rate);
332 if (hw_rate < 0)
333 return hw_rate;
334
335 regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
336 SUN8I_SYS_SR_CTRL_AIF1_FS_MASK,
337 hw_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
338
339 return 0;
340 }
341
sun8i_codec_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)342 static int sun8i_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
343 {
344 struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
345 u32 dsp_format, format, invert, value;
346
347 /* clock masters */
348 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
349 case SND_SOC_DAIFMT_CBC_CFC: /* Codec slave, DAI master */
350 value = 0x1;
351 break;
352 case SND_SOC_DAIFMT_CBP_CFP: /* Codec Master, DAI slave */
353 value = 0x0;
354 break;
355 default:
356 return -EINVAL;
357 }
358
359 if (dai->id == SUN8I_CODEC_AIF3) {
360 /* AIF3 only supports master mode. */
361 if (value)
362 return -EINVAL;
363
364 /* Use the AIF2 BCLK and LRCK for AIF3. */
365 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
366 SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK,
367 SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_AIF2);
368 } else {
369 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
370 BIT(SUN8I_AIF_CLK_CTRL_MSTR_MOD),
371 value << SUN8I_AIF_CLK_CTRL_MSTR_MOD);
372 }
373
374 /* DAI format */
375 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
376 case SND_SOC_DAIFMT_I2S:
377 format = 0x0;
378 break;
379 case SND_SOC_DAIFMT_LEFT_J:
380 format = 0x1;
381 break;
382 case SND_SOC_DAIFMT_RIGHT_J:
383 format = 0x2;
384 break;
385 case SND_SOC_DAIFMT_DSP_A:
386 format = 0x3;
387 dsp_format = 0x0; /* Set LRCK_INV to 0 */
388 break;
389 case SND_SOC_DAIFMT_DSP_B:
390 format = 0x3;
391 dsp_format = 0x1; /* Set LRCK_INV to 1 */
392 break;
393 default:
394 return -EINVAL;
395 }
396
397 if (dai->id == SUN8I_CODEC_AIF3) {
398 /* AIF3 only supports DSP mode. */
399 if (format != 3)
400 return -EINVAL;
401 } else {
402 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
403 SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK,
404 format << SUN8I_AIF_CLK_CTRL_DATA_FMT);
405 }
406
407 /* clock inversion */
408 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
409 case SND_SOC_DAIFMT_NB_NF: /* Normal */
410 invert = 0x0;
411 break;
412 case SND_SOC_DAIFMT_NB_IF: /* Inverted LRCK */
413 invert = 0x1;
414 break;
415 case SND_SOC_DAIFMT_IB_NF: /* Inverted BCLK */
416 invert = 0x2;
417 break;
418 case SND_SOC_DAIFMT_IB_IF: /* Both inverted */
419 invert = 0x3;
420 break;
421 default:
422 return -EINVAL;
423 }
424
425 if (format == 0x3) {
426 /* Inverted LRCK is not available in DSP mode. */
427 if (invert & BIT(0))
428 return -EINVAL;
429
430 /* Instead, the bit selects between DSP A/B formats. */
431 invert |= dsp_format;
432 } else {
433 /*
434 * It appears that the DAI and the codec in the A33 SoC don't
435 * share the same polarity for the LRCK signal when they mean
436 * 'normal' and 'inverted' in the datasheet.
437 *
438 * Since the DAI here is our regular i2s driver that have been
439 * tested with way more codecs than just this one, it means
440 * that the codec probably gets it backward, and we have to
441 * invert the value here.
442 */
443 invert ^= scodec->quirks->lrck_inversion;
444 }
445
446 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
447 SUN8I_AIF_CLK_CTRL_CLK_INV_MASK,
448 invert << SUN8I_AIF_CLK_CTRL_CLK_INV);
449
450 return 0;
451 }
452
sun8i_codec_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)453 static int sun8i_codec_set_tdm_slot(struct snd_soc_dai *dai,
454 unsigned int tx_mask, unsigned int rx_mask,
455 int slots, int slot_width)
456 {
457 struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
458 struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
459
460 if (slot_width && !is_power_of_2(slot_width))
461 return -EINVAL;
462
463 aif->slots = slots;
464 aif->slot_width = slot_width;
465
466 return 0;
467 }
468
469 static const unsigned int sun8i_codec_rates[] = {
470 7350, 8000, 11025, 12000, 14700, 16000, 22050, 24000,
471 29400, 32000, 44100, 48000, 88200, 96000, 176400, 192000,
472 };
473
474 static const struct snd_pcm_hw_constraint_list sun8i_codec_all_rates = {
475 .list = sun8i_codec_rates,
476 .count = ARRAY_SIZE(sun8i_codec_rates),
477 };
478
479 static const struct snd_pcm_hw_constraint_list sun8i_codec_22M_rates = {
480 .list = sun8i_codec_rates,
481 .count = ARRAY_SIZE(sun8i_codec_rates),
482 .mask = 0x5555,
483 };
484
485 static const struct snd_pcm_hw_constraint_list sun8i_codec_24M_rates = {
486 .list = sun8i_codec_rates,
487 .count = ARRAY_SIZE(sun8i_codec_rates),
488 .mask = 0xaaaa,
489 };
490
sun8i_codec_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)491 static int sun8i_codec_startup(struct snd_pcm_substream *substream,
492 struct snd_soc_dai *dai)
493 {
494 struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
495 const struct snd_pcm_hw_constraint_list *list;
496
497 /* hw_constraints is not relevant for codec2codec DAIs. */
498 if (dai->id != SUN8I_CODEC_AIF1)
499 return 0;
500
501 if (!scodec->sysclk_refcnt)
502 list = &sun8i_codec_all_rates;
503 else if (scodec->sysclk_rate == 22579200)
504 list = &sun8i_codec_22M_rates;
505 else if (scodec->sysclk_rate == 24576000)
506 list = &sun8i_codec_24M_rates;
507 else
508 return -EINVAL;
509
510 return snd_pcm_hw_constraint_list(substream->runtime, 0,
511 SNDRV_PCM_HW_PARAM_RATE, list);
512 }
513
514 struct sun8i_codec_clk_div {
515 u8 div;
516 u8 val;
517 };
518
519 static const struct sun8i_codec_clk_div sun8i_codec_bclk_div[] = {
520 { .div = 1, .val = 0 },
521 { .div = 2, .val = 1 },
522 { .div = 4, .val = 2 },
523 { .div = 6, .val = 3 },
524 { .div = 8, .val = 4 },
525 { .div = 12, .val = 5 },
526 { .div = 16, .val = 6 },
527 { .div = 24, .val = 7 },
528 { .div = 32, .val = 8 },
529 { .div = 48, .val = 9 },
530 { .div = 64, .val = 10 },
531 { .div = 96, .val = 11 },
532 { .div = 128, .val = 12 },
533 { .div = 192, .val = 13 },
534 };
535
sun8i_codec_get_bclk_div(unsigned int sysclk_rate,unsigned int lrck_div_order,unsigned int sample_rate)536 static int sun8i_codec_get_bclk_div(unsigned int sysclk_rate,
537 unsigned int lrck_div_order,
538 unsigned int sample_rate)
539 {
540 unsigned int div = sysclk_rate / sample_rate >> lrck_div_order;
541 int i;
542
543 for (i = 0; i < ARRAY_SIZE(sun8i_codec_bclk_div); i++) {
544 const struct sun8i_codec_clk_div *bdiv = &sun8i_codec_bclk_div[i];
545
546 if (bdiv->div == div)
547 return bdiv->val;
548 }
549
550 return -EINVAL;
551 }
552
sun8i_codec_get_lrck_div_order(unsigned int slots,unsigned int slot_width)553 static int sun8i_codec_get_lrck_div_order(unsigned int slots,
554 unsigned int slot_width)
555 {
556 unsigned int div = slots * slot_width;
557
558 if (div < 16 || div > 256)
559 return -EINVAL;
560
561 return order_base_2(div);
562 }
563
sun8i_codec_get_sysclk_rate(unsigned int sample_rate)564 static unsigned int sun8i_codec_get_sysclk_rate(unsigned int sample_rate)
565 {
566 return (sample_rate % 4000) ? 22579200 : 24576000;
567 }
568
sun8i_codec_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)569 static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
570 struct snd_pcm_hw_params *params,
571 struct snd_soc_dai *dai)
572 {
573 struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
574 struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
575 unsigned int sample_rate = params_rate(params);
576 unsigned int slots = aif->slots ?: params_channels(params);
577 unsigned int slot_width = aif->slot_width ?: params_width(params);
578 unsigned int sysclk_rate = sun8i_codec_get_sysclk_rate(sample_rate);
579 int bclk_div, lrck_div_order, ret, word_size;
580 u32 clk_reg;
581
582 /* word size */
583 switch (params_width(params)) {
584 case 8:
585 word_size = 0x0;
586 break;
587 case 16:
588 word_size = 0x1;
589 break;
590 case 20:
591 word_size = 0x2;
592 break;
593 case 24:
594 word_size = 0x3;
595 break;
596 default:
597 return -EINVAL;
598 }
599
600 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id),
601 SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK,
602 word_size << SUN8I_AIF_CLK_CTRL_WORD_SIZ);
603
604 /* LRCK divider (BCLK/LRCK ratio) */
605 lrck_div_order = sun8i_codec_get_lrck_div_order(slots, slot_width);
606 if (lrck_div_order < 0)
607 return lrck_div_order;
608
609 if (dai->id == SUN8I_CODEC_AIF2 || dai->id == SUN8I_CODEC_AIF3) {
610 /* AIF2 and AIF3 share AIF2's BCLK and LRCK generation circuitry. */
611 int partner = (SUN8I_CODEC_AIF2 + SUN8I_CODEC_AIF3) - dai->id;
612 const struct sun8i_codec_aif *partner_aif = &scodec->aifs[partner];
613 const char *partner_name = sun8i_codec_dais[partner].name;
614
615 if (partner_aif->open_streams &&
616 (lrck_div_order != partner_aif->lrck_div_order ||
617 sample_rate != partner_aif->sample_rate)) {
618 dev_err(dai->dev,
619 "%s sample and bit rates must match %s when both are used\n",
620 dai->name, partner_name);
621 return -EBUSY;
622 }
623
624 clk_reg = SUN8I_AIF_CLK_CTRL(SUN8I_CODEC_AIF2);
625 } else {
626 clk_reg = SUN8I_AIF_CLK_CTRL(dai->id);
627 }
628
629 regmap_update_bits(scodec->regmap, clk_reg,
630 SUN8I_AIF_CLK_CTRL_LRCK_DIV_MASK,
631 (lrck_div_order - 4) << SUN8I_AIF_CLK_CTRL_LRCK_DIV);
632
633 /* BCLK divider (SYSCLK/BCLK ratio) */
634 bclk_div = sun8i_codec_get_bclk_div(sysclk_rate, lrck_div_order, sample_rate);
635 if (bclk_div < 0)
636 return bclk_div;
637
638 regmap_update_bits(scodec->regmap, clk_reg,
639 SUN8I_AIF_CLK_CTRL_BCLK_DIV_MASK,
640 bclk_div << SUN8I_AIF_CLK_CTRL_BCLK_DIV);
641
642 /*
643 * SYSCLK rate
644 *
645 * Clock rate protection is reference counted; but hw_params may be
646 * called many times per substream, without matching calls to hw_free.
647 * Protect the clock rate once per AIF, on the first hw_params call
648 * for the first substream. clk_set_rate() will allow clock rate
649 * changes on subsequent calls if only one AIF has open streams.
650 */
651 ret = (aif->open_streams ? clk_set_rate : clk_set_rate_exclusive)(scodec->clk_module,
652 sysclk_rate);
653 if (ret == -EBUSY)
654 dev_err(dai->dev,
655 "%s sample rate (%u Hz) conflicts with other audio streams\n",
656 dai->name, sample_rate);
657 if (ret < 0)
658 return ret;
659
660 if (!aif->open_streams)
661 scodec->sysclk_refcnt++;
662 scodec->sysclk_rate = sysclk_rate;
663
664 aif->lrck_div_order = lrck_div_order;
665 aif->sample_rate = sample_rate;
666 aif->open_streams |= BIT(substream->stream);
667
668 return sun8i_codec_update_sample_rate(scodec);
669 }
670
sun8i_codec_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)671 static int sun8i_codec_hw_free(struct snd_pcm_substream *substream,
672 struct snd_soc_dai *dai)
673 {
674 struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
675 struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
676
677 /* Drop references when the last substream for the AIF is freed. */
678 if (aif->open_streams != BIT(substream->stream))
679 goto done;
680
681 clk_rate_exclusive_put(scodec->clk_module);
682 scodec->sysclk_refcnt--;
683 aif->lrck_div_order = 0;
684 aif->sample_rate = 0;
685
686 done:
687 aif->open_streams &= ~BIT(substream->stream);
688 return 0;
689 }
690
691 static const struct snd_soc_dai_ops sun8i_codec_dai_ops = {
692 .set_fmt = sun8i_codec_set_fmt,
693 .set_tdm_slot = sun8i_codec_set_tdm_slot,
694 .startup = sun8i_codec_startup,
695 .hw_params = sun8i_codec_hw_params,
696 .hw_free = sun8i_codec_hw_free,
697 };
698
699 static struct snd_soc_dai_driver sun8i_codec_dais[] = {
700 {
701 .name = "sun8i-codec-aif1",
702 .id = SUN8I_CODEC_AIF1,
703 .ops = &sun8i_codec_dai_ops,
704 /* capture capabilities */
705 .capture = {
706 .stream_name = "AIF1 Capture",
707 .channels_min = 1,
708 .channels_max = 2,
709 .rates = SUN8I_CODEC_PCM_RATES,
710 .formats = SUN8I_CODEC_PCM_FORMATS,
711 .sig_bits = 24,
712 },
713 /* playback capabilities */
714 .playback = {
715 .stream_name = "AIF1 Playback",
716 .channels_min = 1,
717 .channels_max = 2,
718 .rates = SUN8I_CODEC_PCM_RATES,
719 .formats = SUN8I_CODEC_PCM_FORMATS,
720 },
721 .symmetric_rate = true,
722 .symmetric_channels = true,
723 .symmetric_sample_bits = true,
724 },
725 {
726 .name = "sun8i-codec-aif2",
727 .id = SUN8I_CODEC_AIF2,
728 .ops = &sun8i_codec_dai_ops,
729 /* capture capabilities */
730 .capture = {
731 .stream_name = "AIF2 Capture",
732 .channels_min = 1,
733 .channels_max = 2,
734 .rates = SUN8I_CODEC_PCM_RATES,
735 .formats = SUN8I_CODEC_PCM_FORMATS,
736 .sig_bits = 24,
737 },
738 /* playback capabilities */
739 .playback = {
740 .stream_name = "AIF2 Playback",
741 .channels_min = 1,
742 .channels_max = 2,
743 .rates = SUN8I_CODEC_PCM_RATES,
744 .formats = SUN8I_CODEC_PCM_FORMATS,
745 },
746 .symmetric_rate = true,
747 .symmetric_channels = true,
748 .symmetric_sample_bits = true,
749 },
750 {
751 .name = "sun8i-codec-aif3",
752 .id = SUN8I_CODEC_AIF3,
753 .ops = &sun8i_codec_dai_ops,
754 /* capture capabilities */
755 .capture = {
756 .stream_name = "AIF3 Capture",
757 .channels_min = 1,
758 .channels_max = 1,
759 .rates = SUN8I_CODEC_PCM_RATES,
760 .formats = SUN8I_CODEC_PCM_FORMATS,
761 .sig_bits = 24,
762 },
763 /* playback capabilities */
764 .playback = {
765 .stream_name = "AIF3 Playback",
766 .channels_min = 1,
767 .channels_max = 1,
768 .rates = SUN8I_CODEC_PCM_RATES,
769 .formats = SUN8I_CODEC_PCM_FORMATS,
770 },
771 .symmetric_rate = true,
772 .symmetric_channels = true,
773 .symmetric_sample_bits = true,
774 },
775 };
776
777 static const DECLARE_TLV_DB_SCALE(sun8i_codec_vol_scale, -12000, 75, 1);
778
779 static const struct snd_kcontrol_new sun8i_codec_controls[] = {
780 SOC_DOUBLE_TLV("AIF1 AD0 Capture Volume",
781 SUN8I_AIF1_VOL_CTRL1,
782 SUN8I_AIF1_VOL_CTRL1_AD0L_VOL,
783 SUN8I_AIF1_VOL_CTRL1_AD0R_VOL,
784 0xc0, 0, sun8i_codec_vol_scale),
785 SOC_DOUBLE_TLV("AIF1 DA0 Playback Volume",
786 SUN8I_AIF1_VOL_CTRL3,
787 SUN8I_AIF1_VOL_CTRL3_DA0L_VOL,
788 SUN8I_AIF1_VOL_CTRL3_DA0R_VOL,
789 0xc0, 0, sun8i_codec_vol_scale),
790 SOC_DOUBLE_TLV("AIF2 ADC Capture Volume",
791 SUN8I_AIF2_VOL_CTRL1,
792 SUN8I_AIF2_VOL_CTRL1_ADCL_VOL,
793 SUN8I_AIF2_VOL_CTRL1_ADCR_VOL,
794 0xc0, 0, sun8i_codec_vol_scale),
795 SOC_DOUBLE_TLV("AIF2 DAC Playback Volume",
796 SUN8I_AIF2_VOL_CTRL2,
797 SUN8I_AIF2_VOL_CTRL2_DACL_VOL,
798 SUN8I_AIF2_VOL_CTRL2_DACR_VOL,
799 0xc0, 0, sun8i_codec_vol_scale),
800 SOC_DOUBLE_TLV("ADC Capture Volume",
801 SUN8I_ADC_VOL_CTRL,
802 SUN8I_ADC_VOL_CTRL_ADCL_VOL,
803 SUN8I_ADC_VOL_CTRL_ADCR_VOL,
804 0xc0, 0, sun8i_codec_vol_scale),
805 SOC_DOUBLE_TLV("DAC Playback Volume",
806 SUN8I_DAC_VOL_CTRL,
807 SUN8I_DAC_VOL_CTRL_DACL_VOL,
808 SUN8I_DAC_VOL_CTRL_DACR_VOL,
809 0xc0, 0, sun8i_codec_vol_scale),
810 };
811
sun8i_codec_aif_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)812 static int sun8i_codec_aif_event(struct snd_soc_dapm_widget *w,
813 struct snd_kcontrol *kcontrol, int event)
814 {
815 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
816 struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
817 struct sun8i_codec_aif *aif = &scodec->aifs[w->sname[3] - '1'];
818 int stream = w->id == snd_soc_dapm_aif_out;
819
820 if (SND_SOC_DAPM_EVENT_ON(event))
821 aif->active_streams |= BIT(stream);
822 else
823 aif->active_streams &= ~BIT(stream);
824
825 return sun8i_codec_update_sample_rate(scodec);
826 }
827
828 static const char *const sun8i_aif_stereo_mux_enum_values[] = {
829 "Stereo", "Reverse Stereo", "Sum Mono", "Mix Mono"
830 };
831
832 static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_ad0_stereo_mux_enum,
833 SUN8I_AIF1_ADCDAT_CTRL,
834 SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC,
835 SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC,
836 sun8i_aif_stereo_mux_enum_values);
837
838 static const struct snd_kcontrol_new sun8i_aif1_ad0_stereo_mux_control =
839 SOC_DAPM_ENUM("AIF1 AD0 Stereo Capture Route",
840 sun8i_aif1_ad0_stereo_mux_enum);
841
842 static SOC_ENUM_DOUBLE_DECL(sun8i_aif2_adc_stereo_mux_enum,
843 SUN8I_AIF2_ADCDAT_CTRL,
844 SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_SRC,
845 SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_SRC,
846 sun8i_aif_stereo_mux_enum_values);
847
848 static const struct snd_kcontrol_new sun8i_aif2_adc_stereo_mux_control =
849 SOC_DAPM_ENUM("AIF2 ADC Stereo Capture Route",
850 sun8i_aif2_adc_stereo_mux_enum);
851
852 static const char *const sun8i_aif3_adc_mux_enum_values[] = {
853 "None", "AIF2 ADCL", "AIF2 ADCR"
854 };
855
856 static SOC_ENUM_SINGLE_DECL(sun8i_aif3_adc_mux_enum,
857 SUN8I_AIF3_PATH_CTRL,
858 SUN8I_AIF3_PATH_CTRL_AIF3_ADC_SRC,
859 sun8i_aif3_adc_mux_enum_values);
860
861 static const struct snd_kcontrol_new sun8i_aif3_adc_mux_control =
862 SOC_DAPM_ENUM("AIF3 ADC Source Capture Route",
863 sun8i_aif3_adc_mux_enum);
864
865 static const struct snd_kcontrol_new sun8i_aif1_ad0_mixer_controls[] = {
866 SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital ADC Capture Switch",
867 SUN8I_AIF1_MXR_SRC,
868 SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L,
869 SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R, 1, 0),
870 SOC_DAPM_DOUBLE("AIF2 Digital ADC Capture Switch",
871 SUN8I_AIF1_MXR_SRC,
872 SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL,
873 SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR, 1, 0),
874 SOC_DAPM_DOUBLE("AIF1 Data Digital ADC Capture Switch",
875 SUN8I_AIF1_MXR_SRC,
876 SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_ADCL,
877 SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR, 1, 0),
878 SOC_DAPM_DOUBLE("AIF2 Inv Digital ADC Capture Switch",
879 SUN8I_AIF1_MXR_SRC,
880 SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACR,
881 SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL, 1, 0),
882 };
883
884 static const struct snd_kcontrol_new sun8i_aif2_adc_mixer_controls[] = {
885 SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF1 DA0 Capture Switch",
886 SUN8I_AIF2_MXR_SRC,
887 SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA0L,
888 SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA0R, 1, 0),
889 SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF1 DA1 Capture Switch",
890 SUN8I_AIF2_MXR_SRC,
891 SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA1L,
892 SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF1DA1R, 1, 0),
893 SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF2 DAC Rev Capture Switch",
894 SUN8I_AIF2_MXR_SRC,
895 SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF2DACR,
896 SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_AIF2DACL, 1, 0),
897 SOC_DAPM_DOUBLE("AIF2 ADC Mixer ADC Capture Switch",
898 SUN8I_AIF2_MXR_SRC,
899 SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_ADCL,
900 SUN8I_AIF2_MXR_SRC_ADCR_MXR_SRC_ADCR, 1, 0),
901 };
902
903 static const char *const sun8i_aif2_dac_mux_enum_values[] = {
904 "AIF2", "AIF3+2", "AIF2+3"
905 };
906
907 static SOC_ENUM_SINGLE_DECL(sun8i_aif2_dac_mux_enum,
908 SUN8I_AIF3_PATH_CTRL,
909 SUN8I_AIF3_PATH_CTRL_AIF2_DAC_SRC,
910 sun8i_aif2_dac_mux_enum_values);
911
912 static const struct snd_kcontrol_new sun8i_aif2_dac_mux_control =
913 SOC_DAPM_ENUM("AIF2 DAC Source Playback Route",
914 sun8i_aif2_dac_mux_enum);
915
916 static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_da0_stereo_mux_enum,
917 SUN8I_AIF1_DACDAT_CTRL,
918 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC,
919 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC,
920 sun8i_aif_stereo_mux_enum_values);
921
922 static const struct snd_kcontrol_new sun8i_aif1_da0_stereo_mux_control =
923 SOC_DAPM_ENUM("AIF1 DA0 Stereo Playback Route",
924 sun8i_aif1_da0_stereo_mux_enum);
925
926 static SOC_ENUM_DOUBLE_DECL(sun8i_aif2_dac_stereo_mux_enum,
927 SUN8I_AIF2_DACDAT_CTRL,
928 SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_SRC,
929 SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_SRC,
930 sun8i_aif_stereo_mux_enum_values);
931
932 static const struct snd_kcontrol_new sun8i_aif2_dac_stereo_mux_control =
933 SOC_DAPM_ENUM("AIF2 DAC Stereo Playback Route",
934 sun8i_aif2_dac_stereo_mux_enum);
935
936 static const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = {
937 SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital DAC Playback Switch",
938 SUN8I_DAC_MXR_SRC,
939 SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L,
940 SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
941 SOC_DAPM_DOUBLE("AIF1 Slot 1 Digital DAC Playback Switch",
942 SUN8I_DAC_MXR_SRC,
943 SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L,
944 SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
945 SOC_DAPM_DOUBLE("AIF2 Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
946 SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL,
947 SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
948 SOC_DAPM_DOUBLE("ADC Digital DAC Playback Switch", SUN8I_DAC_MXR_SRC,
949 SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL,
950 SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
951 };
952
953 static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
954 /* System Clocks */
955 SND_SOC_DAPM_CLOCK_SUPPLY("mod"),
956
957 SND_SOC_DAPM_SUPPLY("AIF1CLK",
958 SUN8I_SYSCLK_CTL,
959 SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
960 SND_SOC_DAPM_SUPPLY("AIF2CLK",
961 SUN8I_SYSCLK_CTL,
962 SUN8I_SYSCLK_CTL_AIF2CLK_ENA, 0, NULL, 0),
963 SND_SOC_DAPM_SUPPLY("SYSCLK",
964 SUN8I_SYSCLK_CTL,
965 SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
966
967 /* Module Clocks */
968 SND_SOC_DAPM_SUPPLY("CLK AIF1",
969 SUN8I_MOD_CLK_ENA,
970 SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
971 SND_SOC_DAPM_SUPPLY("CLK AIF2",
972 SUN8I_MOD_CLK_ENA,
973 SUN8I_MOD_CLK_ENA_AIF2, 0, NULL, 0),
974 SND_SOC_DAPM_SUPPLY("CLK AIF3",
975 SUN8I_MOD_CLK_ENA,
976 SUN8I_MOD_CLK_ENA_AIF3, 0, NULL, 0),
977 SND_SOC_DAPM_SUPPLY("CLK ADC",
978 SUN8I_MOD_CLK_ENA,
979 SUN8I_MOD_CLK_ENA_ADC, 0, NULL, 0),
980 SND_SOC_DAPM_SUPPLY("CLK DAC",
981 SUN8I_MOD_CLK_ENA,
982 SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
983
984 /* Module Resets */
985 SND_SOC_DAPM_SUPPLY("RST AIF1",
986 SUN8I_MOD_RST_CTL,
987 SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
988 SND_SOC_DAPM_SUPPLY("RST AIF2",
989 SUN8I_MOD_RST_CTL,
990 SUN8I_MOD_RST_CTL_AIF2, 0, NULL, 0),
991 SND_SOC_DAPM_SUPPLY("RST AIF3",
992 SUN8I_MOD_RST_CTL,
993 SUN8I_MOD_RST_CTL_AIF3, 0, NULL, 0),
994 SND_SOC_DAPM_SUPPLY("RST ADC",
995 SUN8I_MOD_RST_CTL,
996 SUN8I_MOD_RST_CTL_ADC, 0, NULL, 0),
997 SND_SOC_DAPM_SUPPLY("RST DAC",
998 SUN8I_MOD_RST_CTL,
999 SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
1000
1001 /* Module Supplies */
1002 SND_SOC_DAPM_SUPPLY("ADC",
1003 SUN8I_ADC_DIG_CTRL,
1004 SUN8I_ADC_DIG_CTRL_ENAD, 0, NULL, 0),
1005 SND_SOC_DAPM_SUPPLY("DAC",
1006 SUN8I_DAC_DIG_CTRL,
1007 SUN8I_DAC_DIG_CTRL_ENDA, 0, NULL, 0),
1008
1009 /* AIF "ADC" Outputs */
1010 SND_SOC_DAPM_AIF_OUT_E("AIF1 AD0L", "AIF1 Capture", 0,
1011 SUN8I_AIF1_ADCDAT_CTRL,
1012 SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA, 0,
1013 sun8i_codec_aif_event,
1014 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1015 SND_SOC_DAPM_AIF_OUT("AIF1 AD0R", "AIF1 Capture", 1,
1016 SUN8I_AIF1_ADCDAT_CTRL,
1017 SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA, 0),
1018
1019 SND_SOC_DAPM_AIF_OUT_E("AIF2 ADCL", "AIF2 Capture", 0,
1020 SUN8I_AIF2_ADCDAT_CTRL,
1021 SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_ENA, 0,
1022 sun8i_codec_aif_event,
1023 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1024 SND_SOC_DAPM_AIF_OUT("AIF2 ADCR", "AIF2 Capture", 1,
1025 SUN8I_AIF2_ADCDAT_CTRL,
1026 SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_ENA, 0),
1027
1028 SND_SOC_DAPM_AIF_OUT_E("AIF3 ADC", "AIF3 Capture", 0,
1029 SND_SOC_NOPM, 0, 0,
1030 sun8i_codec_aif_event,
1031 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1032
1033 /* AIF "ADC" Mono/Stereo Muxes */
1034 SND_SOC_DAPM_MUX("AIF1 AD0L Stereo Mux", SND_SOC_NOPM, 0, 0,
1035 &sun8i_aif1_ad0_stereo_mux_control),
1036 SND_SOC_DAPM_MUX("AIF1 AD0R Stereo Mux", SND_SOC_NOPM, 0, 0,
1037 &sun8i_aif1_ad0_stereo_mux_control),
1038
1039 SND_SOC_DAPM_MUX("AIF2 ADCL Stereo Mux", SND_SOC_NOPM, 0, 0,
1040 &sun8i_aif2_adc_stereo_mux_control),
1041 SND_SOC_DAPM_MUX("AIF2 ADCR Stereo Mux", SND_SOC_NOPM, 0, 0,
1042 &sun8i_aif2_adc_stereo_mux_control),
1043
1044 /* AIF "ADC" Output Muxes */
1045 SND_SOC_DAPM_MUX("AIF3 ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
1046 &sun8i_aif3_adc_mux_control),
1047
1048 /* AIF "ADC" Mixers */
1049 SOC_MIXER_ARRAY("AIF1 AD0L Mixer", SND_SOC_NOPM, 0, 0,
1050 sun8i_aif1_ad0_mixer_controls),
1051 SOC_MIXER_ARRAY("AIF1 AD0R Mixer", SND_SOC_NOPM, 0, 0,
1052 sun8i_aif1_ad0_mixer_controls),
1053
1054 SOC_MIXER_ARRAY("AIF2 ADCL Mixer", SND_SOC_NOPM, 0, 0,
1055 sun8i_aif2_adc_mixer_controls),
1056 SOC_MIXER_ARRAY("AIF2 ADCR Mixer", SND_SOC_NOPM, 0, 0,
1057 sun8i_aif2_adc_mixer_controls),
1058
1059 /* AIF "DAC" Input Muxes */
1060 SND_SOC_DAPM_MUX("AIF2 DACL Source", SND_SOC_NOPM, 0, 0,
1061 &sun8i_aif2_dac_mux_control),
1062 SND_SOC_DAPM_MUX("AIF2 DACR Source", SND_SOC_NOPM, 0, 0,
1063 &sun8i_aif2_dac_mux_control),
1064
1065 /* AIF "DAC" Mono/Stereo Muxes */
1066 SND_SOC_DAPM_MUX("AIF1 DA0L Stereo Mux", SND_SOC_NOPM, 0, 0,
1067 &sun8i_aif1_da0_stereo_mux_control),
1068 SND_SOC_DAPM_MUX("AIF1 DA0R Stereo Mux", SND_SOC_NOPM, 0, 0,
1069 &sun8i_aif1_da0_stereo_mux_control),
1070
1071 SND_SOC_DAPM_MUX("AIF2 DACL Stereo Mux", SND_SOC_NOPM, 0, 0,
1072 &sun8i_aif2_dac_stereo_mux_control),
1073 SND_SOC_DAPM_MUX("AIF2 DACR Stereo Mux", SND_SOC_NOPM, 0, 0,
1074 &sun8i_aif2_dac_stereo_mux_control),
1075
1076 /* AIF "DAC" Inputs */
1077 SND_SOC_DAPM_AIF_IN_E("AIF1 DA0L", "AIF1 Playback", 0,
1078 SUN8I_AIF1_DACDAT_CTRL,
1079 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0,
1080 sun8i_codec_aif_event,
1081 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1082 SND_SOC_DAPM_AIF_IN("AIF1 DA0R", "AIF1 Playback", 1,
1083 SUN8I_AIF1_DACDAT_CTRL,
1084 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
1085
1086 SND_SOC_DAPM_AIF_IN_E("AIF2 DACL", "AIF2 Playback", 0,
1087 SUN8I_AIF2_DACDAT_CTRL,
1088 SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_ENA, 0,
1089 sun8i_codec_aif_event,
1090 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1091 SND_SOC_DAPM_AIF_IN("AIF2 DACR", "AIF2 Playback", 1,
1092 SUN8I_AIF2_DACDAT_CTRL,
1093 SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_ENA, 0),
1094
1095 SND_SOC_DAPM_AIF_IN_E("AIF3 DAC", "AIF3 Playback", 0,
1096 SND_SOC_NOPM, 0, 0,
1097 sun8i_codec_aif_event,
1098 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1099
1100 /* ADC Inputs (connected to analog codec DAPM context) */
1101 SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 0, 0),
1102 SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
1103
1104 /* DAC Outputs (connected to analog codec DAPM context) */
1105 SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
1106 SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
1107
1108 /* DAC Mixers */
1109 SOC_MIXER_ARRAY("DACL Mixer", SND_SOC_NOPM, 0, 0,
1110 sun8i_dac_mixer_controls),
1111 SOC_MIXER_ARRAY("DACR Mixer", SND_SOC_NOPM, 0, 0,
1112 sun8i_dac_mixer_controls),
1113 };
1114
1115 static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
1116 /* Clock Routes */
1117 { "AIF1CLK", NULL, "mod" },
1118
1119 { "SYSCLK", NULL, "AIF1CLK" },
1120
1121 { "CLK AIF1", NULL, "AIF1CLK" },
1122 { "CLK AIF1", NULL, "SYSCLK" },
1123 { "RST AIF1", NULL, "CLK AIF1" },
1124 { "AIF1 AD0L", NULL, "RST AIF1" },
1125 { "AIF1 AD0R", NULL, "RST AIF1" },
1126 { "AIF1 DA0L", NULL, "RST AIF1" },
1127 { "AIF1 DA0R", NULL, "RST AIF1" },
1128
1129 { "CLK AIF2", NULL, "AIF2CLK" },
1130 { "CLK AIF2", NULL, "SYSCLK" },
1131 { "RST AIF2", NULL, "CLK AIF2" },
1132 { "AIF2 ADCL", NULL, "RST AIF2" },
1133 { "AIF2 ADCR", NULL, "RST AIF2" },
1134 { "AIF2 DACL", NULL, "RST AIF2" },
1135 { "AIF2 DACR", NULL, "RST AIF2" },
1136
1137 { "CLK AIF3", NULL, "AIF1CLK" },
1138 { "CLK AIF3", NULL, "SYSCLK" },
1139 { "RST AIF3", NULL, "CLK AIF3" },
1140 { "AIF3 ADC", NULL, "RST AIF3" },
1141 { "AIF3 DAC", NULL, "RST AIF3" },
1142
1143 { "CLK ADC", NULL, "SYSCLK" },
1144 { "RST ADC", NULL, "CLK ADC" },
1145 { "ADC", NULL, "RST ADC" },
1146 { "ADCL", NULL, "ADC" },
1147 { "ADCR", NULL, "ADC" },
1148
1149 { "CLK DAC", NULL, "SYSCLK" },
1150 { "RST DAC", NULL, "CLK DAC" },
1151 { "DAC", NULL, "RST DAC" },
1152 { "DACL", NULL, "DAC" },
1153 { "DACR", NULL, "DAC" },
1154
1155 /* AIF "ADC" Output Routes */
1156 { "AIF1 AD0L", NULL, "AIF1 AD0L Stereo Mux" },
1157 { "AIF1 AD0R", NULL, "AIF1 AD0R Stereo Mux" },
1158
1159 { "AIF2 ADCL", NULL, "AIF2 ADCL Stereo Mux" },
1160 { "AIF2 ADCR", NULL, "AIF2 ADCR Stereo Mux" },
1161
1162 { "AIF3 ADC", NULL, "AIF3 ADC Source Capture Route" },
1163
1164 /* AIF "ADC" Mono/Stereo Mux Routes */
1165 { "AIF1 AD0L Stereo Mux", "Stereo", "AIF1 AD0L Mixer" },
1166 { "AIF1 AD0L Stereo Mux", "Reverse Stereo", "AIF1 AD0R Mixer" },
1167 { "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
1168 { "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
1169 { "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
1170 { "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
1171
1172 { "AIF1 AD0R Stereo Mux", "Stereo", "AIF1 AD0R Mixer" },
1173 { "AIF1 AD0R Stereo Mux", "Reverse Stereo", "AIF1 AD0L Mixer" },
1174 { "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
1175 { "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
1176 { "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
1177 { "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
1178
1179 { "AIF2 ADCL Stereo Mux", "Stereo", "AIF2 ADCL Mixer" },
1180 { "AIF2 ADCL Stereo Mux", "Reverse Stereo", "AIF2 ADCR Mixer" },
1181 { "AIF2 ADCL Stereo Mux", "Sum Mono", "AIF2 ADCL Mixer" },
1182 { "AIF2 ADCL Stereo Mux", "Sum Mono", "AIF2 ADCR Mixer" },
1183 { "AIF2 ADCL Stereo Mux", "Mix Mono", "AIF2 ADCL Mixer" },
1184 { "AIF2 ADCL Stereo Mux", "Mix Mono", "AIF2 ADCR Mixer" },
1185
1186 { "AIF2 ADCR Stereo Mux", "Stereo", "AIF2 ADCR Mixer" },
1187 { "AIF2 ADCR Stereo Mux", "Reverse Stereo", "AIF2 ADCL Mixer" },
1188 { "AIF2 ADCR Stereo Mux", "Sum Mono", "AIF2 ADCL Mixer" },
1189 { "AIF2 ADCR Stereo Mux", "Sum Mono", "AIF2 ADCR Mixer" },
1190 { "AIF2 ADCR Stereo Mux", "Mix Mono", "AIF2 ADCL Mixer" },
1191 { "AIF2 ADCR Stereo Mux", "Mix Mono", "AIF2 ADCR Mixer" },
1192
1193 /* AIF "ADC" Output Mux Routes */
1194 { "AIF3 ADC Source Capture Route", "AIF2 ADCL", "AIF2 ADCL Mixer" },
1195 { "AIF3 ADC Source Capture Route", "AIF2 ADCR", "AIF2 ADCR Mixer" },
1196
1197 /* AIF "ADC" Mixer Routes */
1198 { "AIF1 AD0L Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0L Stereo Mux" },
1199 { "AIF1 AD0L Mixer", "AIF2 Digital ADC Capture Switch", "AIF2 DACL Source" },
1200 { "AIF1 AD0L Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCL" },
1201 { "AIF1 AD0L Mixer", "AIF2 Inv Digital ADC Capture Switch", "AIF2 DACR Source" },
1202
1203 { "AIF1 AD0R Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0R Stereo Mux" },
1204 { "AIF1 AD0R Mixer", "AIF2 Digital ADC Capture Switch", "AIF2 DACR Source" },
1205 { "AIF1 AD0R Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCR" },
1206 { "AIF1 AD0R Mixer", "AIF2 Inv Digital ADC Capture Switch", "AIF2 DACL Source" },
1207
1208 { "AIF2 ADCL Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0L Stereo Mux" },
1209 { "AIF2 ADCL Mixer", "AIF2 ADC Mixer AIF2 DAC Rev Capture Switch", "AIF2 DACR Source" },
1210 { "AIF2 ADCL Mixer", "AIF2 ADC Mixer ADC Capture Switch", "ADCL" },
1211
1212 { "AIF2 ADCR Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0R Stereo Mux" },
1213 { "AIF2 ADCR Mixer", "AIF2 ADC Mixer AIF2 DAC Rev Capture Switch", "AIF2 DACL Source" },
1214 { "AIF2 ADCR Mixer", "AIF2 ADC Mixer ADC Capture Switch", "ADCR" },
1215
1216 /* AIF "DAC" Input Mux Routes */
1217 { "AIF2 DACL Source", "AIF2", "AIF2 DACL Stereo Mux" },
1218 { "AIF2 DACL Source", "AIF3+2", "AIF3 DAC" },
1219 { "AIF2 DACL Source", "AIF2+3", "AIF2 DACL Stereo Mux" },
1220
1221 { "AIF2 DACR Source", "AIF2", "AIF2 DACR Stereo Mux" },
1222 { "AIF2 DACR Source", "AIF3+2", "AIF2 DACR Stereo Mux" },
1223 { "AIF2 DACR Source", "AIF2+3", "AIF3 DAC" },
1224
1225 /* AIF "DAC" Mono/Stereo Mux Routes */
1226 { "AIF1 DA0L Stereo Mux", "Stereo", "AIF1 DA0L" },
1227 { "AIF1 DA0L Stereo Mux", "Reverse Stereo", "AIF1 DA0R" },
1228 { "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0L" },
1229 { "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0R" },
1230 { "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0L" },
1231 { "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0R" },
1232
1233 { "AIF1 DA0R Stereo Mux", "Stereo", "AIF1 DA0R" },
1234 { "AIF1 DA0R Stereo Mux", "Reverse Stereo", "AIF1 DA0L" },
1235 { "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0L" },
1236 { "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0R" },
1237 { "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0L" },
1238 { "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0R" },
1239
1240 { "AIF2 DACL Stereo Mux", "Stereo", "AIF2 DACL" },
1241 { "AIF2 DACL Stereo Mux", "Reverse Stereo", "AIF2 DACR" },
1242 { "AIF2 DACL Stereo Mux", "Sum Mono", "AIF2 DACL" },
1243 { "AIF2 DACL Stereo Mux", "Sum Mono", "AIF2 DACR" },
1244 { "AIF2 DACL Stereo Mux", "Mix Mono", "AIF2 DACL" },
1245 { "AIF2 DACL Stereo Mux", "Mix Mono", "AIF2 DACR" },
1246
1247 { "AIF2 DACR Stereo Mux", "Stereo", "AIF2 DACR" },
1248 { "AIF2 DACR Stereo Mux", "Reverse Stereo", "AIF2 DACL" },
1249 { "AIF2 DACR Stereo Mux", "Sum Mono", "AIF2 DACL" },
1250 { "AIF2 DACR Stereo Mux", "Sum Mono", "AIF2 DACR" },
1251 { "AIF2 DACR Stereo Mux", "Mix Mono", "AIF2 DACL" },
1252 { "AIF2 DACR Stereo Mux", "Mix Mono", "AIF2 DACR" },
1253
1254 /* DAC Output Routes */
1255 { "DACL", NULL, "DACL Mixer" },
1256 { "DACR", NULL, "DACR Mixer" },
1257
1258 /* DAC Mixer Routes */
1259 { "DACL Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0L Stereo Mux" },
1260 { "DACL Mixer", "AIF2 Digital DAC Playback Switch", "AIF2 DACL Source" },
1261 { "DACL Mixer", "ADC Digital DAC Playback Switch", "ADCL" },
1262
1263 { "DACR Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0R Stereo Mux" },
1264 { "DACR Mixer", "AIF2 Digital DAC Playback Switch", "AIF2 DACR Source" },
1265 { "DACR Mixer", "ADC Digital DAC Playback Switch", "ADCR" },
1266 };
1267
1268 static const struct snd_soc_dapm_widget sun8i_codec_legacy_widgets[] = {
1269 /* Legacy ADC Inputs (connected to analog codec DAPM context) */
1270 SND_SOC_DAPM_ADC("AIF1 Slot 0 Left ADC", NULL, SND_SOC_NOPM, 0, 0),
1271 SND_SOC_DAPM_ADC("AIF1 Slot 0 Right ADC", NULL, SND_SOC_NOPM, 0, 0),
1272
1273 /* Legacy DAC Outputs (connected to analog codec DAPM context) */
1274 SND_SOC_DAPM_DAC("AIF1 Slot 0 Left", NULL, SND_SOC_NOPM, 0, 0),
1275 SND_SOC_DAPM_DAC("AIF1 Slot 0 Right", NULL, SND_SOC_NOPM, 0, 0),
1276 };
1277
1278 static const struct snd_soc_dapm_route sun8i_codec_legacy_routes[] = {
1279 /* Legacy ADC Routes */
1280 { "ADCL", NULL, "AIF1 Slot 0 Left ADC" },
1281 { "ADCR", NULL, "AIF1 Slot 0 Right ADC" },
1282
1283 /* Legacy DAC Routes */
1284 { "AIF1 Slot 0 Left", NULL, "DACL" },
1285 { "AIF1 Slot 0 Right", NULL, "DACR" },
1286 };
1287
sun8i_codec_component_probe(struct snd_soc_component * component)1288 static int sun8i_codec_component_probe(struct snd_soc_component *component)
1289 {
1290 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1291 struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
1292 int ret;
1293
1294 scodec->component = component;
1295
1296 /* Add widgets for backward compatibility with old device trees. */
1297 if (scodec->quirks->legacy_widgets) {
1298 ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_legacy_widgets,
1299 ARRAY_SIZE(sun8i_codec_legacy_widgets));
1300 if (ret)
1301 return ret;
1302
1303 ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_legacy_routes,
1304 ARRAY_SIZE(sun8i_codec_legacy_routes));
1305 if (ret)
1306 return ret;
1307 }
1308
1309 /*
1310 * AIF1CLK and AIF2CLK share a pair of clock parents: PLL_AUDIO ("mod")
1311 * and MCLK (from the CPU DAI connected to AIF1). MCLK's parent is also
1312 * PLL_AUDIO, so using it adds no additional flexibility. Use PLL_AUDIO
1313 * directly to simplify the clock tree.
1314 */
1315 regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
1316 SUN8I_SYSCLK_CTL_AIF1CLK_SRC_MASK |
1317 SUN8I_SYSCLK_CTL_AIF2CLK_SRC_MASK,
1318 SUN8I_SYSCLK_CTL_AIF1CLK_SRC_PLL |
1319 SUN8I_SYSCLK_CTL_AIF2CLK_SRC_PLL);
1320
1321 /* Use AIF1CLK as the SYSCLK parent since AIF1 is used most often. */
1322 regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL,
1323 BIT(SUN8I_SYSCLK_CTL_SYSCLK_SRC),
1324 SUN8I_SYSCLK_CTL_SYSCLK_SRC_AIF1CLK);
1325
1326 /* Program the default sample rate. */
1327 sun8i_codec_update_sample_rate(scodec);
1328
1329 return 0;
1330 }
1331
sun8i_codec_set_hmic_bias(struct sun8i_codec * scodec,bool enable)1332 static void sun8i_codec_set_hmic_bias(struct sun8i_codec *scodec, bool enable)
1333 {
1334 struct snd_soc_dapm_context *dapm = &scodec->component->card->dapm;
1335 int irq_mask = BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN);
1336
1337 if (enable)
1338 snd_soc_dapm_force_enable_pin(dapm, "HBIAS");
1339 else
1340 snd_soc_dapm_disable_pin(dapm, "HBIAS");
1341
1342 snd_soc_dapm_sync(dapm);
1343
1344 regmap_update_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
1345 irq_mask, enable ? irq_mask : 0);
1346 }
1347
sun8i_codec_jack_work(struct work_struct * work)1348 static void sun8i_codec_jack_work(struct work_struct *work)
1349 {
1350 struct sun8i_codec *scodec = container_of(work, struct sun8i_codec,
1351 jack_work.work);
1352 unsigned int mdata;
1353 int type;
1354
1355 guard(mutex)(&scodec->jack_mutex);
1356
1357 if (scodec->jack_status == SUN8I_JACK_STATUS_DISCONNECTED) {
1358 if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_IN_IRQ_ST)
1359 return;
1360
1361 scodec->jack_last_sample = -1;
1362
1363 if (scodec->jack_type & SND_JACK_MICROPHONE) {
1364 /*
1365 * If we were in disconnected state, we enable HBIAS and
1366 * wait 600ms before reading initial HDATA value.
1367 */
1368 scodec->jack_hbias_ready = ktime_add_ms(ktime_get(), 600);
1369 sun8i_codec_set_hmic_bias(scodec, true);
1370 queue_delayed_work(system_power_efficient_wq,
1371 &scodec->jack_work,
1372 msecs_to_jiffies(610));
1373 scodec->jack_status = SUN8I_JACK_STATUS_WAITING_HBIAS;
1374 } else {
1375 snd_soc_jack_report(scodec->jack, SND_JACK_HEADPHONE,
1376 scodec->jack_type);
1377 scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED;
1378 }
1379 } else if (scodec->jack_status == SUN8I_JACK_STATUS_WAITING_HBIAS) {
1380 /*
1381 * If we're waiting for HBIAS to stabilize, and we get plug-out
1382 * interrupt and nothing more for > 100ms, just cancel the
1383 * initialization.
1384 */
1385 if (scodec->last_hmic_irq == SUN8I_HMIC_STS_JACK_OUT_IRQ_ST) {
1386 scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED;
1387 sun8i_codec_set_hmic_bias(scodec, false);
1388 return;
1389 }
1390
1391 /*
1392 * If we're not done waiting for HBIAS to stabilize, wait more.
1393 */
1394 if (!ktime_after(ktime_get(), scodec->jack_hbias_ready)) {
1395 s64 msecs = ktime_ms_delta(scodec->jack_hbias_ready,
1396 ktime_get());
1397
1398 queue_delayed_work(system_power_efficient_wq,
1399 &scodec->jack_work,
1400 msecs_to_jiffies(msecs + 10));
1401 return;
1402 }
1403
1404 /*
1405 * Everything is stabilized, determine jack type and report it.
1406 */
1407 regmap_read(scodec->regmap, SUN8I_HMIC_STS, &mdata);
1408 mdata &= SUN8I_HMIC_STS_HMIC_DATA_MASK;
1409 mdata >>= SUN8I_HMIC_STS_HMIC_DATA;
1410
1411 regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0);
1412
1413 type = mdata < 16 ? SND_JACK_HEADPHONE : SND_JACK_HEADSET;
1414 if (type == SND_JACK_HEADPHONE)
1415 sun8i_codec_set_hmic_bias(scodec, false);
1416
1417 snd_soc_jack_report(scodec->jack, type, scodec->jack_type);
1418 scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED;
1419 } else if (scodec->jack_status == SUN8I_JACK_STATUS_CONNECTED) {
1420 if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_OUT_IRQ_ST)
1421 return;
1422
1423 scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED;
1424 if (scodec->jack_type & SND_JACK_MICROPHONE)
1425 sun8i_codec_set_hmic_bias(scodec, false);
1426
1427 snd_soc_jack_report(scodec->jack, 0, scodec->jack_type);
1428 }
1429 }
1430
sun8i_codec_jack_irq(int irq,void * dev_id)1431 static irqreturn_t sun8i_codec_jack_irq(int irq, void *dev_id)
1432 {
1433 struct sun8i_codec *scodec = dev_id;
1434 int type = SND_JACK_HEADSET;
1435 unsigned int status, value;
1436
1437 guard(mutex)(&scodec->jack_mutex);
1438
1439 regmap_read(scodec->regmap, SUN8I_HMIC_STS, &status);
1440 regmap_write(scodec->regmap, SUN8I_HMIC_STS, status);
1441
1442 /*
1443 * De-bounce in/out interrupts via a delayed work re-scheduling to
1444 * 100ms after each interrupt..
1445 */
1446 if (status & BIT(SUN8I_HMIC_STS_JACK_OUT_IRQ_ST)) {
1447 /*
1448 * Out interrupt has priority over in interrupt so that if
1449 * we get both, we assume the disconnected state, which is
1450 * safer.
1451 */
1452 scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_OUT_IRQ_ST;
1453 mod_delayed_work(system_power_efficient_wq, &scodec->jack_work,
1454 msecs_to_jiffies(100));
1455 } else if (status & BIT(SUN8I_HMIC_STS_JACK_IN_IRQ_ST)) {
1456 scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_IN_IRQ_ST;
1457 mod_delayed_work(system_power_efficient_wq, &scodec->jack_work,
1458 msecs_to_jiffies(100));
1459 } else if (status & BIT(SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST)) {
1460 /*
1461 * Ignore data interrupts until jack status turns to connected
1462 * state, which is after HMIC enable stabilization is completed.
1463 * Until then tha data are bogus.
1464 */
1465 if (scodec->jack_status != SUN8I_JACK_STATUS_CONNECTED)
1466 return IRQ_HANDLED;
1467
1468 value = (status & SUN8I_HMIC_STS_HMIC_DATA_MASK) >>
1469 SUN8I_HMIC_STS_HMIC_DATA;
1470
1471 /*
1472 * Assumes 60 mV per ADC LSB increment, 2V bias voltage, 2.2kOhm
1473 * bias resistor.
1474 */
1475 if (value == 0)
1476 type |= SND_JACK_BTN_0;
1477 else if (value == 1)
1478 type |= SND_JACK_BTN_3;
1479 else if (value <= 3)
1480 type |= SND_JACK_BTN_1;
1481 else if (value <= 8)
1482 type |= SND_JACK_BTN_2;
1483
1484 /*
1485 * De-bounce. Only report button after two consecutive A/D
1486 * samples are identical.
1487 */
1488 if (scodec->jack_last_sample >= 0 &&
1489 scodec->jack_last_sample == value)
1490 snd_soc_jack_report(scodec->jack, type,
1491 scodec->jack_type);
1492
1493 scodec->jack_last_sample = value;
1494 }
1495
1496 return IRQ_HANDLED;
1497 }
1498
sun8i_codec_enable_jack_detect(struct snd_soc_component * component,struct snd_soc_jack * jack,void * data)1499 static int sun8i_codec_enable_jack_detect(struct snd_soc_component *component,
1500 struct snd_soc_jack *jack, void *data)
1501 {
1502 struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
1503 struct platform_device *pdev = to_platform_device(component->dev);
1504 int ret;
1505
1506 if (!scodec->quirks->jack_detection)
1507 return 0;
1508
1509 scodec->jack = jack;
1510
1511 scodec->jack_irq = platform_get_irq(pdev, 0);
1512 if (scodec->jack_irq < 0)
1513 return scodec->jack_irq;
1514
1515 /* Reserved value required for jack IRQs to trigger. */
1516 regmap_write(scodec->regmap, SUN8I_HMIC_CTRL1,
1517 0xf << SUN8I_HMIC_CTRL1_HMIC_N |
1518 0x0 << SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB |
1519 0x4 << SUN8I_HMIC_CTRL1_HMIC_M);
1520
1521 /* Sample the ADC at 128 Hz; bypass smooth filter. */
1522 regmap_write(scodec->regmap, SUN8I_HMIC_CTRL2,
1523 0x0 << SUN8I_HMIC_CTRL2_HMIC_SAMPLE |
1524 0x17 << SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD |
1525 0x0 << SUN8I_HMIC_CTRL2_HMIC_SF);
1526
1527 /* Do not discard any MDATA, enable user written MDATA threshold. */
1528 regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0);
1529
1530 regmap_set_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
1531 BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) |
1532 BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN));
1533
1534 ret = devm_request_threaded_irq(&pdev->dev, scodec->jack_irq,
1535 NULL, sun8i_codec_jack_irq,
1536 IRQF_ONESHOT,
1537 dev_name(&pdev->dev), scodec);
1538 if (ret)
1539 return ret;
1540
1541 return 0;
1542 }
1543
sun8i_codec_disable_jack_detect(struct snd_soc_component * component)1544 static void sun8i_codec_disable_jack_detect(struct snd_soc_component *component)
1545 {
1546 struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component);
1547
1548 if (!scodec->quirks->jack_detection)
1549 return;
1550
1551 devm_free_irq(component->dev, scodec->jack_irq, scodec);
1552
1553 cancel_delayed_work_sync(&scodec->jack_work);
1554
1555 regmap_clear_bits(scodec->regmap, SUN8I_HMIC_CTRL1,
1556 BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) |
1557 BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN) |
1558 BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN));
1559
1560 scodec->jack = NULL;
1561 }
1562
sun8i_codec_component_set_jack(struct snd_soc_component * component,struct snd_soc_jack * jack,void * data)1563 static int sun8i_codec_component_set_jack(struct snd_soc_component *component,
1564 struct snd_soc_jack *jack, void *data)
1565 {
1566 int ret = 0;
1567
1568 if (jack)
1569 ret = sun8i_codec_enable_jack_detect(component, jack, data);
1570 else
1571 sun8i_codec_disable_jack_detect(component);
1572
1573 return ret;
1574 }
1575
1576 static const struct snd_soc_component_driver sun8i_soc_component = {
1577 .controls = sun8i_codec_controls,
1578 .num_controls = ARRAY_SIZE(sun8i_codec_controls),
1579 .dapm_widgets = sun8i_codec_dapm_widgets,
1580 .num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets),
1581 .dapm_routes = sun8i_codec_dapm_routes,
1582 .num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes),
1583 .set_jack = sun8i_codec_component_set_jack,
1584 .probe = sun8i_codec_component_probe,
1585 .idle_bias_on = 1,
1586 .suspend_bias_off = 1,
1587 .endianness = 1,
1588 };
1589
sun8i_codec_volatile_reg(struct device * dev,unsigned int reg)1590 static bool sun8i_codec_volatile_reg(struct device *dev, unsigned int reg)
1591 {
1592 return reg == SUN8I_HMIC_STS;
1593 }
1594
1595 static const struct regmap_config sun8i_codec_regmap_config = {
1596 .reg_bits = 32,
1597 .reg_stride = 4,
1598 .val_bits = 32,
1599 .volatile_reg = sun8i_codec_volatile_reg,
1600 .max_register = SUN8I_DAC_MXR_SRC,
1601
1602 .cache_type = REGCACHE_FLAT,
1603 };
1604
sun8i_codec_probe(struct platform_device * pdev)1605 static int sun8i_codec_probe(struct platform_device *pdev)
1606 {
1607 struct sun8i_codec *scodec;
1608 void __iomem *base;
1609 int ret;
1610
1611 scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
1612 if (!scodec)
1613 return -ENOMEM;
1614
1615 scodec->quirks = of_device_get_match_data(&pdev->dev);
1616 INIT_DELAYED_WORK(&scodec->jack_work, sun8i_codec_jack_work);
1617 mutex_init(&scodec->jack_mutex);
1618
1619 platform_set_drvdata(pdev, scodec);
1620
1621 if (scodec->quirks->bus_clock) {
1622 scodec->clk_bus = devm_clk_get(&pdev->dev, "bus");
1623 if (IS_ERR(scodec->clk_bus)) {
1624 dev_err(&pdev->dev, "Failed to get the bus clock\n");
1625 return PTR_ERR(scodec->clk_bus);
1626 }
1627 }
1628
1629 scodec->clk_module = devm_clk_get(&pdev->dev, "mod");
1630 if (IS_ERR(scodec->clk_module)) {
1631 dev_err(&pdev->dev, "Failed to get the module clock\n");
1632 return PTR_ERR(scodec->clk_module);
1633 }
1634
1635 base = devm_platform_ioremap_resource(pdev, 0);
1636 if (IS_ERR(base)) {
1637 dev_err(&pdev->dev, "Failed to map the registers\n");
1638 return PTR_ERR(base);
1639 }
1640
1641 scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
1642 &sun8i_codec_regmap_config);
1643 if (IS_ERR(scodec->regmap)) {
1644 dev_err(&pdev->dev, "Failed to create our regmap\n");
1645 return PTR_ERR(scodec->regmap);
1646 }
1647
1648 regcache_cache_only(scodec->regmap, true);
1649 pm_runtime_enable(&pdev->dev);
1650 if (!pm_runtime_enabled(&pdev->dev)) {
1651 ret = sun8i_codec_runtime_resume(&pdev->dev);
1652 if (ret)
1653 goto err_pm_disable;
1654 }
1655
1656 ret = devm_snd_soc_register_component(&pdev->dev, &sun8i_soc_component,
1657 sun8i_codec_dais,
1658 ARRAY_SIZE(sun8i_codec_dais));
1659 if (ret) {
1660 dev_err(&pdev->dev, "Failed to register codec\n");
1661 goto err_suspend;
1662 }
1663
1664 return ret;
1665
1666 err_suspend:
1667 if (!pm_runtime_status_suspended(&pdev->dev))
1668 sun8i_codec_runtime_suspend(&pdev->dev);
1669
1670 err_pm_disable:
1671 pm_runtime_disable(&pdev->dev);
1672
1673 return ret;
1674 }
1675
sun8i_codec_remove(struct platform_device * pdev)1676 static void sun8i_codec_remove(struct platform_device *pdev)
1677 {
1678 pm_runtime_disable(&pdev->dev);
1679 if (!pm_runtime_status_suspended(&pdev->dev))
1680 sun8i_codec_runtime_suspend(&pdev->dev);
1681 }
1682
1683 static const struct sun8i_codec_quirks sun8i_a33_quirks = {
1684 .bus_clock = true,
1685 .legacy_widgets = true,
1686 .lrck_inversion = true,
1687 };
1688
1689 static const struct sun8i_codec_quirks sun50i_a64_quirks = {
1690 .bus_clock = true,
1691 .jack_detection = true,
1692 };
1693
1694 static const struct of_device_id sun8i_codec_of_match[] = {
1695 { .compatible = "allwinner,sun8i-a33-codec", .data = &sun8i_a33_quirks },
1696 { .compatible = "allwinner,sun50i-a64-codec", .data = &sun50i_a64_quirks },
1697 {}
1698 };
1699 MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
1700
1701 static const struct dev_pm_ops sun8i_codec_pm_ops = {
1702 RUNTIME_PM_OPS(sun8i_codec_runtime_suspend,
1703 sun8i_codec_runtime_resume, NULL)
1704 };
1705
1706 static struct platform_driver sun8i_codec_driver = {
1707 .driver = {
1708 .name = "sun8i-codec",
1709 .of_match_table = sun8i_codec_of_match,
1710 .pm = pm_ptr(&sun8i_codec_pm_ops),
1711 },
1712 .probe = sun8i_codec_probe,
1713 .remove = sun8i_codec_remove,
1714 };
1715 module_platform_driver(sun8i_codec_driver);
1716
1717 MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
1718 MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
1719 MODULE_LICENSE("GPL");
1720 MODULE_ALIAS("platform:sun8i-codec");
1721