hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/sound/soc/codecs/pcm3168a.c
....@@ -1,18 +1,17 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * PCM3168A codec driver
34 *
45 * Copyright (C) 2015 Imagination Technologies Ltd.
56 *
67 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify it
9
- * under the terms and conditions of the GNU General Public License,
10
- * version 2, as published by the Free Software Foundation.
118 */
129
1310 #include <linux/clk.h>
1411 #include <linux/delay.h>
12
+#include <linux/gpio/consumer.h>
1513 #include <linux/module.h>
14
+#include <linux/of_gpio.h>
1615 #include <linux/pm_runtime.h>
1716 #include <linux/regulator/consumer.h>
1817
....@@ -32,6 +31,8 @@
3231 #define PCM3168A_FMT_RIGHT_J_16 0x3
3332 #define PCM3168A_FMT_DSP_A 0x4
3433 #define PCM3168A_FMT_DSP_B 0x5
34
+#define PCM3168A_FMT_I2S_TDM 0x6
35
+#define PCM3168A_FMT_LEFT_J_TDM 0x7
3536 #define PCM3168A_FMT_DSP_MASK 0x4
3637
3738 #define PCM3168A_NUM_SUPPLIES 6
....@@ -44,15 +45,27 @@
4445 "VCCDA2"
4546 };
4647
48
+#define PCM3168A_DAI_DAC 0
49
+#define PCM3168A_DAI_ADC 1
50
+
51
+/* ADC/DAC side parameters */
52
+struct pcm3168a_io_params {
53
+ bool master_mode;
54
+ unsigned int fmt;
55
+ int tdm_slots;
56
+ u32 tdm_mask;
57
+ int slot_width;
58
+};
59
+
4760 struct pcm3168a_priv {
4861 struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES];
4962 struct regmap *regmap;
5063 struct clk *scki;
51
- bool adc_master_mode;
52
- bool dac_master_mode;
64
+ struct gpio_desc *gpio_rst;
5365 unsigned long sysclk;
54
- unsigned int adc_fmt;
55
- unsigned int dac_fmt;
66
+
67
+ struct pcm3168a_io_params io_params[2];
68
+ struct snd_soc_dai_driver dai_drv[2];
5669 };
5770
5871 static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" };
....@@ -130,10 +143,6 @@
130143 SOC_DOUBLE("DAC2 Invert Switch", PCM3168A_DAC_INV, 2, 3, 1, 0),
131144 SOC_DOUBLE("DAC3 Invert Switch", PCM3168A_DAC_INV, 4, 5, 1, 0),
132145 SOC_DOUBLE("DAC4 Invert Switch", PCM3168A_DAC_INV, 6, 7, 1, 0),
133
- SOC_DOUBLE_STS("DAC1 Zero Flag", PCM3168A_DAC_ZERO, 0, 1, 1, 0),
134
- SOC_DOUBLE_STS("DAC2 Zero Flag", PCM3168A_DAC_ZERO, 2, 3, 1, 0),
135
- SOC_DOUBLE_STS("DAC3 Zero Flag", PCM3168A_DAC_ZERO, 4, 5, 1, 0),
136
- SOC_DOUBLE_STS("DAC4 Zero Flag", PCM3168A_DAC_ZERO, 6, 7, 1, 0),
137146 SOC_ENUM("DAC Volume Control Type", pcm3168a_dac_volume_type),
138147 SOC_ENUM("DAC Volume Rate Multiplier", pcm3168a_dac_att_mult),
139148 SOC_ENUM("DAC De-Emphasis", pcm3168a_dac_demp),
....@@ -173,9 +182,6 @@
173182 SOC_DOUBLE("ADC1 Mute Switch", PCM3168A_ADC_MUTE, 0, 1, 1, 0),
174183 SOC_DOUBLE("ADC2 Mute Switch", PCM3168A_ADC_MUTE, 2, 3, 1, 0),
175184 SOC_DOUBLE("ADC3 Mute Switch", PCM3168A_ADC_MUTE, 4, 5, 1, 0),
176
- SOC_DOUBLE_STS("ADC1 Overflow Flag", PCM3168A_ADC_OV, 0, 1, 1, 0),
177
- SOC_DOUBLE_STS("ADC2 Overflow Flag", PCM3168A_ADC_OV, 2, 3, 1, 0),
178
- SOC_DOUBLE_STS("ADC3 Overflow Flag", PCM3168A_ADC_OV, 4, 5, 1, 0),
179185 SOC_ENUM("ADC Volume Control Type", pcm3168a_adc_volume_type),
180186 SOC_ENUM("ADC Volume Rate Multiplier", pcm3168a_adc_att_mult),
181187 SOC_ENUM("ADC Overflow Flag Polarity", pcm3168a_adc_ov_pol),
....@@ -267,7 +273,7 @@
267273 #define PCM3168A_NUM_SCKI_RATIOS_DAC ARRAY_SIZE(pcm3168a_scki_ratios)
268274 #define PCM3168A_NUM_SCKI_RATIOS_ADC (ARRAY_SIZE(pcm3168a_scki_ratios) - 2)
269275
270
-#define PCM1368A_MAX_SYSCLK 36864000
276
+#define PCM3168A_MAX_SYSCLK 36864000
271277
272278 static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a)
273279 {
....@@ -284,7 +290,7 @@
284290 PCM3168A_MRST_MASK | PCM3168A_SRST_MASK);
285291 }
286292
287
-static int pcm3168a_digital_mute(struct snd_soc_dai *dai, int mute)
293
+static int pcm3168a_mute(struct snd_soc_dai *dai, int mute, int direction)
288294 {
289295 struct snd_soc_component *component = dai->component;
290296 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
....@@ -300,7 +306,14 @@
300306 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component);
301307 int ret;
302308
303
- if (freq > PCM1368A_MAX_SYSCLK)
309
+ /*
310
+ * Some sound card sets 0 Hz as reset,
311
+ * but it is impossible to set. Ignore it here
312
+ */
313
+ if (freq == 0)
314
+ return 0;
315
+
316
+ if (freq > PCM3168A_MAX_SYSCLK)
304317 return -EINVAL;
305318
306319 ret = clk_set_rate(pcm3168a->scki, freq);
....@@ -312,8 +325,35 @@
312325 return 0;
313326 }
314327
315
-static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
316
- unsigned int format, bool dac)
328
+static void pcm3168a_update_fixup_pcm_stream(struct snd_soc_dai *dai)
329
+{
330
+ struct snd_soc_component *component = dai->component;
331
+ struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
332
+ u64 formats = SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE;
333
+ unsigned int channel_max = dai->id == PCM3168A_DAI_DAC ? 8 : 6;
334
+
335
+ if (pcm3168a->io_params[dai->id].fmt == PCM3168A_FMT_RIGHT_J) {
336
+ /* S16_LE is only supported in RIGHT_J mode */
337
+ formats |= SNDRV_PCM_FMTBIT_S16_LE;
338
+
339
+ /*
340
+ * If multi DIN/DOUT is not selected, RIGHT_J can only support
341
+ * two channels (no TDM support)
342
+ */
343
+ if (pcm3168a->io_params[dai->id].tdm_slots != 2)
344
+ channel_max = 2;
345
+ }
346
+
347
+ if (dai->id == PCM3168A_DAI_DAC) {
348
+ dai->driver->playback.channels_max = channel_max;
349
+ dai->driver->playback.formats = formats;
350
+ } else {
351
+ dai->driver->capture.channels_max = channel_max;
352
+ dai->driver->capture.formats = formats;
353
+ }
354
+}
355
+
356
+static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
317357 {
318358 struct snd_soc_component *component = dai->component;
319359 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
....@@ -360,35 +400,59 @@
360400 return -EINVAL;
361401 }
362402
363
- if (dac) {
403
+ if (dai->id == PCM3168A_DAI_DAC) {
364404 reg = PCM3168A_DAC_PWR_MST_FMT;
365405 mask = PCM3168A_DAC_FMT_MASK;
366406 shift = PCM3168A_DAC_FMT_SHIFT;
367
- pcm3168a->dac_master_mode = master_mode;
368
- pcm3168a->dac_fmt = fmt;
369407 } else {
370408 reg = PCM3168A_ADC_MST_FMT;
371409 mask = PCM3168A_ADC_FMTAD_MASK;
372410 shift = PCM3168A_ADC_FMTAD_SHIFT;
373
- pcm3168a->adc_master_mode = master_mode;
374
- pcm3168a->adc_fmt = fmt;
375411 }
376412
413
+ pcm3168a->io_params[dai->id].master_mode = master_mode;
414
+ pcm3168a->io_params[dai->id].fmt = fmt;
415
+
377416 regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
417
+
418
+ pcm3168a_update_fixup_pcm_stream(dai);
378419
379420 return 0;
380421 }
381422
382
-static int pcm3168a_set_dai_fmt_dac(struct snd_soc_dai *dai,
383
- unsigned int format)
423
+static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
424
+ unsigned int rx_mask, int slots,
425
+ int slot_width)
384426 {
385
- return pcm3168a_set_dai_fmt(dai, format, true);
386
-}
427
+ struct snd_soc_component *component = dai->component;
428
+ struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
429
+ struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id];
387430
388
-static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
389
- unsigned int format)
390
-{
391
- return pcm3168a_set_dai_fmt(dai, format, false);
431
+ if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
432
+ dev_err(component->dev,
433
+ "Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n",
434
+ tx_mask, rx_mask, slots);
435
+ return -EINVAL;
436
+ }
437
+
438
+ if (slot_width &&
439
+ (slot_width != 16 && slot_width != 24 && slot_width != 32 )) {
440
+ dev_err(component->dev, "Unsupported slot_width %d\n",
441
+ slot_width);
442
+ return -EINVAL;
443
+ }
444
+
445
+ io_params->tdm_slots = slots;
446
+ io_params->slot_width = slot_width;
447
+ /* Ignore the not relevant mask for the DAI/direction */
448
+ if (dai->id == PCM3168A_DAI_DAC)
449
+ io_params->tdm_mask = tx_mask;
450
+ else
451
+ io_params->tdm_mask = rx_mask;
452
+
453
+ pcm3168a_update_fixup_pcm_stream(dai);
454
+
455
+ return 0;
392456 }
393457
394458 static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
....@@ -397,31 +461,31 @@
397461 {
398462 struct snd_soc_component *component = dai->component;
399463 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
400
- bool tx, master_mode;
464
+ struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id];
465
+ bool master_mode;
401466 u32 val, mask, shift, reg;
402467 unsigned int rate, fmt, ratio, max_ratio;
403
- int i, min_frame_size;
468
+ unsigned int tdm_slots;
469
+ int i, slot_width;
404470
405471 rate = params_rate(params);
406472
407473 ratio = pcm3168a->sysclk / rate;
408474
409
- tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
410
- if (tx) {
475
+ if (dai->id == PCM3168A_DAI_DAC) {
411476 max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC;
412477 reg = PCM3168A_DAC_PWR_MST_FMT;
413478 mask = PCM3168A_DAC_MSDA_MASK;
414479 shift = PCM3168A_DAC_MSDA_SHIFT;
415
- master_mode = pcm3168a->dac_master_mode;
416
- fmt = pcm3168a->dac_fmt;
417480 } else {
418481 max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC;
419482 reg = PCM3168A_ADC_MST_FMT;
420483 mask = PCM3168A_ADC_MSAD_MASK;
421484 shift = PCM3168A_ADC_MSAD_SHIFT;
422
- master_mode = pcm3168a->adc_master_mode;
423
- fmt = pcm3168a->adc_fmt;
424485 }
486
+
487
+ master_mode = io_params->master_mode;
488
+ fmt = io_params->fmt;
425489
426490 for (i = 0; i < max_ratio; i++) {
427491 if (pcm3168a_scki_ratios[i] == ratio)
....@@ -433,26 +497,60 @@
433497 return -EINVAL;
434498 }
435499
436
- min_frame_size = params_width(params) * 2;
437
- switch (min_frame_size) {
438
- case 32:
500
+ if (io_params->slot_width)
501
+ slot_width = io_params->slot_width;
502
+ else
503
+ slot_width = params_width(params);
504
+
505
+ switch (slot_width) {
506
+ case 16:
439507 if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
440
- dev_err(component->dev, "32-bit frames are supported only for slave mode using right justified\n");
508
+ dev_err(component->dev, "16-bit slots are supported only for slave mode using right justified\n");
441509 return -EINVAL;
442510 }
443511 fmt = PCM3168A_FMT_RIGHT_J_16;
444512 break;
445
- case 48:
513
+ case 24:
446514 if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
447
- dev_err(component->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
515
+ dev_err(component->dev, "24-bit slots not supported in master mode, or slave mode using DSP\n");
448516 return -EINVAL;
449517 }
450518 break;
451
- case 64:
519
+ case 32:
452520 break;
453521 default:
454
- dev_err(component->dev, "unsupported frame size: %d\n", min_frame_size);
522
+ dev_err(component->dev, "unsupported frame size: %d\n", slot_width);
455523 return -EINVAL;
524
+ }
525
+
526
+ if (io_params->tdm_slots)
527
+ tdm_slots = io_params->tdm_slots;
528
+ else
529
+ tdm_slots = params_channels(params);
530
+
531
+ /*
532
+ * Switch the codec to TDM mode when more than 2 TDM slots are needed
533
+ * for the stream.
534
+ * If pcm3168a->tdm_slots is not set or set to more than 2 (8/6 usually)
535
+ * then DIN1/DOUT1 is used in TDM mode.
536
+ * If pcm3168a->tdm_slots is set to 2 then DIN1/2/3/4 and DOUT1/2/3 is
537
+ * used in normal mode, no need to switch to TDM modes.
538
+ */
539
+ if (tdm_slots > 2) {
540
+ switch (fmt) {
541
+ case PCM3168A_FMT_I2S:
542
+ case PCM3168A_FMT_DSP_A:
543
+ fmt = PCM3168A_FMT_I2S_TDM;
544
+ break;
545
+ case PCM3168A_FMT_LEFT_J:
546
+ case PCM3168A_FMT_DSP_B:
547
+ fmt = PCM3168A_FMT_LEFT_J_TDM;
548
+ break;
549
+ default:
550
+ dev_err(component->dev,
551
+ "TDM is supported under DSP/I2S/Left_J only\n");
552
+ return -EINVAL;
553
+ }
456554 }
457555
458556 if (master_mode)
....@@ -462,7 +560,7 @@
462560
463561 regmap_update_bits(pcm3168a->regmap, reg, mask, val);
464562
465
- if (tx) {
563
+ if (dai->id == PCM3168A_DAI_DAC) {
466564 mask = PCM3168A_DAC_FMT_MASK;
467565 shift = PCM3168A_DAC_FMT_SHIFT;
468566 } else {
....@@ -475,22 +573,19 @@
475573 return 0;
476574 }
477575
478
-static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = {
479
- .set_fmt = pcm3168a_set_dai_fmt_dac,
576
+static const struct snd_soc_dai_ops pcm3168a_dai_ops = {
577
+ .set_fmt = pcm3168a_set_dai_fmt,
480578 .set_sysclk = pcm3168a_set_dai_sysclk,
481579 .hw_params = pcm3168a_hw_params,
482
- .digital_mute = pcm3168a_digital_mute
483
-};
484
-
485
-static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
486
- .set_fmt = pcm3168a_set_dai_fmt_adc,
487
- .set_sysclk = pcm3168a_set_dai_sysclk,
488
- .hw_params = pcm3168a_hw_params
580
+ .mute_stream = pcm3168a_mute,
581
+ .set_tdm_slot = pcm3168a_set_tdm_slot,
582
+ .no_capture_mute = 1,
489583 };
490584
491585 static struct snd_soc_dai_driver pcm3168a_dais[] = {
492586 {
493587 .name = "pcm3168a-dac",
588
+ .id = PCM3168A_DAI_DAC,
494589 .playback = {
495590 .stream_name = "Playback",
496591 .channels_min = 1,
....@@ -498,10 +593,11 @@
498593 .rates = SNDRV_PCM_RATE_8000_192000,
499594 .formats = PCM3168A_FORMATS
500595 },
501
- .ops = &pcm3168a_dac_dai_ops
596
+ .ops = &pcm3168a_dai_ops
502597 },
503598 {
504599 .name = "pcm3168a-adc",
600
+ .id = PCM3168A_DAI_ADC,
505601 .capture = {
506602 .stream_name = "Capture",
507603 .channels_min = 1,
....@@ -509,7 +605,7 @@
509605 .rates = SNDRV_PCM_RATE_8000_96000,
510606 .formats = PCM3168A_FORMATS
511607 },
512
- .ops = &pcm3168a_adc_dai_ops
608
+ .ops = &pcm3168a_dai_ops
513609 },
514610 };
515611
....@@ -558,6 +654,7 @@
558654 static bool pcm3168a_volatile_register(struct device *dev, unsigned int reg)
559655 {
560656 switch (reg) {
657
+ case PCM3168A_RST_SMODE:
561658 case PCM3168A_DAC_ZERO:
562659 case PCM3168A_ADC_OV:
563660 return true;
....@@ -617,6 +714,25 @@
617714
618715 dev_set_drvdata(dev, pcm3168a);
619716
717
+ /*
718
+ * Request the reset (connected to RST pin) gpio line as non exclusive
719
+ * as the same reset line might be connected to multiple pcm3168a codec
720
+ *
721
+ * The RST is low active, we want the GPIO line to be high initially, so
722
+ * request the initial level to LOW which in practice means DEASSERTED:
723
+ * The deasserted level of GPIO_ACTIVE_LOW is HIGH.
724
+ */
725
+ pcm3168a->gpio_rst = devm_gpiod_get_optional(dev, "reset",
726
+ GPIOD_OUT_LOW |
727
+ GPIOD_FLAGS_BIT_NONEXCLUSIVE);
728
+ if (IS_ERR(pcm3168a->gpio_rst)) {
729
+ ret = PTR_ERR(pcm3168a->gpio_rst);
730
+ if (ret != -EPROBE_DEFER )
731
+ dev_err(dev, "failed to acquire RST gpio: %d\n", ret);
732
+
733
+ return ret;
734
+ }
735
+
620736 pcm3168a->scki = devm_clk_get(dev, "scki");
621737 if (IS_ERR(pcm3168a->scki)) {
622738 ret = PTR_ERR(pcm3168a->scki);
....@@ -658,18 +774,28 @@
658774 goto err_regulator;
659775 }
660776
661
- ret = pcm3168a_reset(pcm3168a);
662
- if (ret) {
663
- dev_err(dev, "Failed to reset device: %d\n", ret);
664
- goto err_regulator;
777
+ if (pcm3168a->gpio_rst) {
778
+ /*
779
+ * The device is taken out from reset via GPIO line, wait for
780
+ * 3846 SCKI clock cycles for the internal reset de-assertion
781
+ */
782
+ msleep(DIV_ROUND_UP(3846 * 1000, pcm3168a->sysclk));
783
+ } else {
784
+ ret = pcm3168a_reset(pcm3168a);
785
+ if (ret) {
786
+ dev_err(dev, "Failed to reset device: %d\n", ret);
787
+ goto err_regulator;
788
+ }
665789 }
666790
667791 pm_runtime_set_active(dev);
668792 pm_runtime_enable(dev);
669793 pm_runtime_idle(dev);
670794
671
- ret = devm_snd_soc_register_component(dev, &pcm3168a_driver, pcm3168a_dais,
672
- ARRAY_SIZE(pcm3168a_dais));
795
+ memcpy(pcm3168a->dai_drv, pcm3168a_dais, sizeof(pcm3168a->dai_drv));
796
+ ret = devm_snd_soc_register_component(dev, &pcm3168a_driver,
797
+ pcm3168a->dai_drv,
798
+ ARRAY_SIZE(pcm3168a->dai_drv));
673799 if (ret) {
674800 dev_err(dev, "failed to register component: %d\n", ret);
675801 goto err_regulator;
....@@ -698,6 +824,15 @@
698824
699825 void pcm3168a_remove(struct device *dev)
700826 {
827
+ struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
828
+
829
+ /*
830
+ * The RST is low active, we want the GPIO line to be low when the
831
+ * driver is removed, so set level to 1 which in practice means
832
+ * ASSERTED:
833
+ * The asserted level of GPIO_ACTIVE_LOW is LOW.
834
+ */
835
+ gpiod_set_value_cansleep(pcm3168a->gpio_rst, 1);
701836 pm_runtime_disable(dev);
702837 #ifndef CONFIG_PM
703838 pcm3168a_disable(dev);