hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/sound/soc/codecs/ad193x.c
....@@ -1,9 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * AD193X Audio Codec driver supporting AD1936/7/8/9
34 *
45 * Copyright 2010 Analog Devices Inc.
5
- *
6
- * Licensed under the GPL-2 or later.
76 */
87
98 #include <linux/module.h>
....@@ -36,6 +35,13 @@
3635 ad193x_deemp);
3736
3837 static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
38
+
39
+static const unsigned int ad193x_sb[] = {32};
40
+
41
+static struct snd_pcm_hw_constraint_list constr = {
42
+ .list = ad193x_sb,
43
+ .count = ARRAY_SIZE(ad193x_sb),
44
+};
3945
4046 static const struct snd_kcontrol_new ad193x_snd_controls[] = {
4147 /* DAC volume control */
....@@ -93,6 +99,15 @@
9399 SND_SOC_DAPM_INPUT("ADC2IN"),
94100 };
95101
102
+static int ad193x_check_pll(struct snd_soc_dapm_widget *source,
103
+ struct snd_soc_dapm_widget *sink)
104
+{
105
+ struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
106
+ struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
107
+
108
+ return !!ad193x->sysclk;
109
+}
110
+
96111 static const struct snd_soc_dapm_route audio_paths[] = {
97112 { "DAC", NULL, "SYSCLK" },
98113 { "DAC Output", NULL, "DAC" },
....@@ -101,7 +116,7 @@
101116 { "DAC2OUT", NULL, "DAC Output" },
102117 { "DAC3OUT", NULL, "DAC Output" },
103118 { "DAC4OUT", NULL, "DAC Output" },
104
- { "SYSCLK", NULL, "PLL_PWR" },
119
+ { "SYSCLK", NULL, "PLL_PWR", &ad193x_check_pll },
105120 };
106121
107122 static const struct snd_soc_dapm_route ad193x_adc_audio_paths[] = {
....@@ -128,7 +143,7 @@
128143 * DAI ops entries
129144 */
130145
131
-static int ad193x_mute(struct snd_soc_dai *dai, int mute)
146
+static int ad193x_mute(struct snd_soc_dai *dai, int mute, int direction)
132147 {
133148 struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(dai->component);
134149
....@@ -181,23 +196,26 @@
181196 {
182197 struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(codec_dai->component);
183198 unsigned int adc_serfmt = 0;
199
+ unsigned int dac_serfmt = 0;
184200 unsigned int adc_fmt = 0;
185201 unsigned int dac_fmt = 0;
186202
187203 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
188
- * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
204
+ * with TDM), ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) and DAC I2S mode
205
+ * (SND_SOC_DAIFMT_I2S)
189206 */
190207 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
191208 case SND_SOC_DAIFMT_I2S:
192209 adc_serfmt |= AD193X_ADC_SERFMT_TDM;
210
+ dac_serfmt |= AD193X_DAC_SERFMT_STEREO;
193211 break;
194212 case SND_SOC_DAIFMT_DSP_A:
195213 adc_serfmt |= AD193X_ADC_SERFMT_AUX;
214
+ dac_serfmt |= AD193X_DAC_SERFMT_TDM;
196215 break;
197216 default:
198217 if (ad193x_has_adc(ad193x))
199218 return -EINVAL;
200
- break;
201219 }
202220
203221 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
....@@ -220,6 +238,10 @@
220238 default:
221239 return -EINVAL;
222240 }
241
+
242
+ /* For DSP_*, LRCLK's polarity must be inverted */
243
+ if (fmt & SND_SOC_DAIFMT_DSP_A)
244
+ dac_fmt ^= AD193X_DAC_LEFT_HIGH;
223245
224246 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
225247 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
....@@ -248,6 +270,8 @@
248270 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
249271 AD193X_ADC_FMT_MASK, adc_fmt);
250272 }
273
+ regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0,
274
+ AD193X_DAC_SERFMT_MASK, dac_serfmt);
251275 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
252276 AD193X_DAC_FMT_MASK, dac_fmt);
253277
....@@ -258,7 +282,22 @@
258282 int clk_id, unsigned int freq, int dir)
259283 {
260284 struct snd_soc_component *component = codec_dai->component;
285
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
261286 struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
287
+
288
+ if (clk_id == AD193X_SYSCLK_MCLK) {
289
+ /* MCLK must be 512 x fs */
290
+ if (dir == SND_SOC_CLOCK_OUT || freq != 24576000)
291
+ return -EINVAL;
292
+
293
+ regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL1,
294
+ AD193X_PLL_SRC_MASK,
295
+ AD193X_PLL_DAC_SRC_MCLK |
296
+ AD193X_PLL_CLK_SRC_MCLK);
297
+
298
+ snd_soc_dapm_sync(dapm);
299
+ return 0;
300
+ }
262301 switch (freq) {
263302 case 12288000:
264303 case 18432000:
....@@ -321,12 +360,22 @@
321360 return 0;
322361 }
323362
363
+static int ad193x_startup(struct snd_pcm_substream *substream,
364
+ struct snd_soc_dai *dai)
365
+{
366
+ return snd_pcm_hw_constraint_list(substream->runtime, 0,
367
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
368
+ &constr);
369
+}
370
+
324371 static const struct snd_soc_dai_ops ad193x_dai_ops = {
372
+ .startup = ad193x_startup,
325373 .hw_params = ad193x_hw_params,
326
- .digital_mute = ad193x_mute,
374
+ .mute_stream = ad193x_mute,
327375 .set_tdm_slot = ad193x_set_tdm_slot,
328376 .set_sysclk = ad193x_set_dai_sysclk,
329377 .set_fmt = ad193x_set_dai_fmt,
378
+ .no_capture_mute = 1,
330379 };
331380
332381 /* codec DAI instance */
....@@ -351,6 +400,53 @@
351400 .ops = &ad193x_dai_ops,
352401 };
353402
403
+/* codec DAI instance for DAC only */
404
+static struct snd_soc_dai_driver ad193x_no_adc_dai = {
405
+ .name = "ad193x-hifi",
406
+ .playback = {
407
+ .stream_name = "Playback",
408
+ .channels_min = 2,
409
+ .channels_max = 8,
410
+ .rates = SNDRV_PCM_RATE_48000,
411
+ .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
412
+ SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
413
+ },
414
+ .ops = &ad193x_dai_ops,
415
+};
416
+
417
+/* codec register values to set after reset */
418
+static void ad193x_reg_default_init(struct ad193x_priv *ad193x)
419
+{
420
+ static const struct reg_sequence reg_init[] = {
421
+ { 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */
422
+ { 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */
423
+ { 2, 0x40 }, /* DAC_CTRL0: TDM mode */
424
+ { 3, 0x00 }, /* DAC_CTRL1: reset */
425
+ { 4, 0x1A }, /* DAC_CTRL2: 48kHz de-emphasis, unmute dac */
426
+ { 5, 0x00 }, /* DAC_CHNL_MUTE: unmute DAC channels */
427
+ { 6, 0x00 }, /* DAC_L1_VOL: no attenuation */
428
+ { 7, 0x00 }, /* DAC_R1_VOL: no attenuation */
429
+ { 8, 0x00 }, /* DAC_L2_VOL: no attenuation */
430
+ { 9, 0x00 }, /* DAC_R2_VOL: no attenuation */
431
+ { 10, 0x00 }, /* DAC_L3_VOL: no attenuation */
432
+ { 11, 0x00 }, /* DAC_R3_VOL: no attenuation */
433
+ { 12, 0x00 }, /* DAC_L4_VOL: no attenuation */
434
+ { 13, 0x00 }, /* DAC_R4_VOL: no attenuation */
435
+ };
436
+ static const struct reg_sequence reg_adc_init[] = {
437
+ { 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */
438
+ { 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */
439
+ { 16, 0x00 }, /* ADC_CTRL2: reset */
440
+ };
441
+
442
+ regmap_multi_reg_write(ad193x->regmap, reg_init, ARRAY_SIZE(reg_init));
443
+
444
+ if (ad193x_has_adc(ad193x)) {
445
+ regmap_multi_reg_write(ad193x->regmap, reg_adc_init,
446
+ ARRAY_SIZE(reg_adc_init));
447
+ }
448
+}
449
+
354450 static int ad193x_component_probe(struct snd_soc_component *component)
355451 {
356452 struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
....@@ -358,25 +454,7 @@
358454 int num, ret;
359455
360456 /* default setting for ad193x */
361
-
362
- /* unmute dac channels */
363
- regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0);
364
- /* de-emphasis: 48kHz, powedown dac */
365
- regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
366
- /* dac in tdm mode */
367
- regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40);
368
-
369
- /* adc only */
370
- if (ad193x_has_adc(ad193x)) {
371
- /* high-pass filter enable */
372
- regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
373
- /* sata delay=1, adc aux mode */
374
- regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43);
375
- }
376
-
377
- /* pll input: mclki/xi */
378
- regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
379
- regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
457
+ ad193x_reg_default_init(ad193x);
380458
381459 /* adc only */
382460 if (ad193x_has_adc(ad193x)) {
....@@ -444,8 +522,11 @@
444522
445523 dev_set_drvdata(dev, ad193x);
446524
525
+ if (ad193x_has_adc(ad193x))
526
+ return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
527
+ &ad193x_dai, 1);
447528 return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
448
- &ad193x_dai, 1);
529
+ &ad193x_no_adc_dai, 1);
449530 }
450531 EXPORT_SYMBOL_GPL(ad193x_probe);
451532