hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/sound/soc/codecs/cs42l51.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * cs42l51.c
34 *
....@@ -7,20 +8,12 @@
78 *
89 * Based on cs4270.c - Copyright (c) Freescale Semiconductor
910 *
10
- * This program is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License version 2 as
12
- * published by the Free Software Foundation.
13
- *
14
- * This program is distributed in the hope that it will be useful,
15
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- * GNU General Public License for more details.
18
- *
1911 * For now:
2012 * - Only I2C is support. Not SPI
2113 * - master mode *NOT* supported
2214 */
2315
16
+#include <linux/clk.h>
2417 #include <linux/module.h>
2518 #include <linux/slab.h>
2619 #include <sound/core.h>
....@@ -29,7 +22,9 @@
2922 #include <sound/initval.h>
3023 #include <sound/pcm_params.h>
3124 #include <sound/pcm.h>
25
+#include <linux/gpio/consumer.h>
3226 #include <linux/regmap.h>
27
+#include <linux/regulator/consumer.h>
3328
3429 #include "cs42l51.h"
3530
....@@ -39,10 +34,21 @@
3934 MODE_MASTER,
4035 };
4136
37
+static const char * const cs42l51_supply_names[] = {
38
+ "VL",
39
+ "VD",
40
+ "VA",
41
+ "VAHP",
42
+};
43
+
4244 struct cs42l51_private {
4345 unsigned int mclk;
46
+ struct clk *mclk_handle;
4447 unsigned int audio_mode; /* The mode (I2S or left-justified) */
4548 enum master_slave_mode func;
49
+ struct regulator_bulk_data supplies[ARRAY_SIZE(cs42l51_supply_names)];
50
+ struct gpio_desc *reset_gpio;
51
+ struct regmap *regmap;
4652 };
4753
4854 #define CS42L51_FORMATS ( \
....@@ -55,7 +61,7 @@
5561 struct snd_ctl_elem_value *ucontrol)
5662 {
5763 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
58
- unsigned long value = snd_soc_component_read32(component, CS42L51_PCM_MIXER)&3;
64
+ unsigned long value = snd_soc_component_read(component, CS42L51_PCM_MIXER)&3;
5965
6066 switch (value) {
6167 default:
....@@ -109,11 +115,15 @@
109115 static const DECLARE_TLV_DB_SCALE(aout_tlv, -10200, 50, 0);
110116
111117 static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0);
118
+static const DECLARE_TLV_DB_SCALE(adc_boost_tlv, 2000, 2000, 0);
112119 static const char *chan_mix[] = {
113120 "L R",
114121 "L+R",
115122 "R L",
116123 };
124
+
125
+static const DECLARE_TLV_DB_SCALE(pga_tlv, -300, 50, 0);
126
+static const DECLARE_TLV_DB_SCALE(adc_att_tlv, -9600, 100, 0);
117127
118128 static SOC_ENUM_SINGLE_EXT_DECL(cs42l51_chan_mix, chan_mix);
119129
....@@ -131,12 +141,20 @@
131141 0, 0x19, 0x7F, adc_pcm_tlv),
132142 SOC_DOUBLE_R("ADC Mixer Switch",
133143 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
144
+ SOC_DOUBLE_R_SX_TLV("ADC Attenuator Volume",
145
+ CS42L51_ADCA_ATT, CS42L51_ADCB_ATT,
146
+ 0, 0xA0, 96, adc_att_tlv),
147
+ SOC_DOUBLE_R_SX_TLV("PGA Volume",
148
+ CS42L51_ALC_PGA_CTL, CS42L51_ALC_PGB_CTL,
149
+ 0, 0x1A, 30, pga_tlv),
134150 SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
135151 SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
136152 SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
137153 SOC_SINGLE("Zero Cross Switch", CS42L51_DAC_CTL, 0, 0, 0),
138154 SOC_DOUBLE_TLV("Mic Boost Volume",
139155 CS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv),
156
+ SOC_DOUBLE_TLV("ADC Boost Volume",
157
+ CS42L51_MIC_CTL, 5, 6, 1, 0, adc_boost_tlv),
140158 SOC_SINGLE_TLV("Bass Volume", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv),
141159 SOC_SINGLE_TLV("Treble Volume", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv),
142160 SOC_ENUM_EXT("PCM channel mixer",
....@@ -193,7 +211,8 @@
193211 SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum);
194212
195213 static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = {
196
- SND_SOC_DAPM_MICBIAS("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1),
214
+ SND_SOC_DAPM_SUPPLY("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1, NULL,
215
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
197216 SND_SOC_DAPM_PGA_E("Left PGA", CS42L51_POWER_CTL1, 3, 1, NULL, 0,
198217 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
199218 SND_SOC_DAPM_PGA_E("Right PGA", CS42L51_POWER_CTL1, 4, 1, NULL, 0,
....@@ -204,12 +223,10 @@
204223 SND_SOC_DAPM_ADC_E("Right ADC", "Right HiFi Capture",
205224 CS42L51_POWER_CTL1, 2, 1,
206225 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
207
- SND_SOC_DAPM_DAC_E("Left DAC", "Left HiFi Playback",
208
- CS42L51_POWER_CTL1, 5, 1,
209
- cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
210
- SND_SOC_DAPM_DAC_E("Right DAC", "Right HiFi Playback",
211
- CS42L51_POWER_CTL1, 6, 1,
212
- cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
226
+ SND_SOC_DAPM_DAC_E("Left DAC", NULL, CS42L51_POWER_CTL1, 5, 1,
227
+ cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
228
+ SND_SOC_DAPM_DAC_E("Right DAC", NULL, CS42L51_POWER_CTL1, 6, 1,
229
+ cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
213230
214231 /* analog/mic */
215232 SND_SOC_DAPM_INPUT("AIN1L"),
....@@ -237,9 +254,39 @@
237254 &cs42l51_adcr_mux_controls),
238255 };
239256
257
+static int mclk_event(struct snd_soc_dapm_widget *w,
258
+ struct snd_kcontrol *kcontrol, int event)
259
+{
260
+ struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
261
+ struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(comp);
262
+
263
+ switch (event) {
264
+ case SND_SOC_DAPM_PRE_PMU:
265
+ return clk_prepare_enable(cs42l51->mclk_handle);
266
+ case SND_SOC_DAPM_POST_PMD:
267
+ /* Delay mclk shutdown to fulfill power-down sequence requirements */
268
+ msleep(20);
269
+ clk_disable_unprepare(cs42l51->mclk_handle);
270
+ break;
271
+ }
272
+
273
+ return 0;
274
+}
275
+
276
+static const struct snd_soc_dapm_widget cs42l51_dapm_mclk_widgets[] = {
277
+ SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, mclk_event,
278
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
279
+};
280
+
240281 static const struct snd_soc_dapm_route cs42l51_routes[] = {
241282 {"HPL", NULL, "Left DAC"},
242283 {"HPR", NULL, "Right DAC"},
284
+
285
+ {"Right DAC", NULL, "DAC Mux"},
286
+ {"Left DAC", NULL, "DAC Mux"},
287
+
288
+ {"DAC Mux", "Direct PCM", "Playback"},
289
+ {"DAC Mux", "DSP PCM", "Playback"},
243290
244291 {"Left ADC", NULL, "Left PGA"},
245292 {"Right ADC", NULL, "Right PGA"},
....@@ -323,6 +370,19 @@
323370 { 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 },
324371 };
325372
373
+/*
374
+ * Master mode mclk/fs ratios.
375
+ * Recommended configurations are SSM for 4-50khz and DSM for 50-100kHz ranges
376
+ * The table below provides support of following ratios:
377
+ * 128: SSM (%128) with div2 disabled
378
+ * 256: SSM (%128) with div2 enabled
379
+ * In both cases, if sampling rate is above 50kHz, SSM is overridden
380
+ * with DSM (%128) configuration
381
+ */
382
+static struct cs42l51_ratios master_ratios[] = {
383
+ { 128, CS42L51_SSM_MODE, 0 }, { 256, CS42L51_SSM_MODE, 1 },
384
+};
385
+
326386 static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
327387 int clk_id, unsigned int freq, int dir)
328388 {
....@@ -345,11 +405,13 @@
345405 unsigned int ratio;
346406 struct cs42l51_ratios *ratios = NULL;
347407 int nr_ratios = 0;
348
- int intf_ctl, power_ctl, fmt;
408
+ int intf_ctl, power_ctl, fmt, mode;
349409
350410 switch (cs42l51->func) {
351411 case MODE_MASTER:
352
- return -EINVAL;
412
+ ratios = master_ratios;
413
+ nr_ratios = ARRAY_SIZE(master_ratios);
414
+ break;
353415 case MODE_SLAVE:
354416 ratios = slave_ratios;
355417 nr_ratios = ARRAY_SIZE(slave_ratios);
....@@ -374,8 +436,8 @@
374436 return -EINVAL;
375437 }
376438
377
- intf_ctl = snd_soc_component_read32(component, CS42L51_INTF_CTL);
378
- power_ctl = snd_soc_component_read32(component, CS42L51_MIC_POWER_CTL);
439
+ intf_ctl = snd_soc_component_read(component, CS42L51_INTF_CTL);
440
+ power_ctl = snd_soc_component_read(component, CS42L51_MIC_POWER_CTL);
379441
380442 intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S
381443 | CS42L51_INTF_CTL_DAC_FORMAT(7));
....@@ -385,7 +447,16 @@
385447 switch (cs42l51->func) {
386448 case MODE_MASTER:
387449 intf_ctl |= CS42L51_INTF_CTL_MASTER;
388
- power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
450
+ mode = ratios[i].speed_mode;
451
+ /* Force DSM mode if sampling rate is above 50kHz */
452
+ if (rate > 50000)
453
+ mode = CS42L51_DSM_MODE;
454
+ power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(mode);
455
+ /*
456
+ * Auto detect mode is not applicable for master mode and has to
457
+ * be disabled. Otherwise SPEED[1:0] bits will be ignored.
458
+ */
459
+ power_ctl &= ~CS42L51_MIC_POWER_CTL_AUTO;
389460 break;
390461 case MODE_SLAVE:
391462 power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
....@@ -442,13 +513,13 @@
442513 return 0;
443514 }
444515
445
-static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)
516
+static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute, int direction)
446517 {
447518 struct snd_soc_component *component = dai->component;
448519 int reg;
449520 int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;
450521
451
- reg = snd_soc_component_read32(component, CS42L51_DAC_OUT_CTL);
522
+ reg = snd_soc_component_read(component, CS42L51_DAC_OUT_CTL);
452523
453524 if (mute)
454525 reg |= mask;
....@@ -458,11 +529,19 @@
458529 return snd_soc_component_write(component, CS42L51_DAC_OUT_CTL, reg);
459530 }
460531
532
+static int cs42l51_of_xlate_dai_id(struct snd_soc_component *component,
533
+ struct device_node *endpoint)
534
+{
535
+ /* return dai id 0, whatever the endpoint index */
536
+ return 0;
537
+}
538
+
461539 static const struct snd_soc_dai_ops cs42l51_dai_ops = {
462540 .hw_params = cs42l51_hw_params,
463541 .set_sysclk = cs42l51_set_dai_sysclk,
464542 .set_fmt = cs42l51_set_dai_fmt,
465
- .digital_mute = cs42l51_dai_mute,
543
+ .mute_stream = cs42l51_dai_mute,
544
+ .no_capture_mute = 1,
466545 };
467546
468547 static struct snd_soc_dai_driver cs42l51_dai = {
....@@ -487,6 +566,14 @@
487566 static int cs42l51_component_probe(struct snd_soc_component *component)
488567 {
489568 int ret, reg;
569
+ struct snd_soc_dapm_context *dapm;
570
+ struct cs42l51_private *cs42l51;
571
+
572
+ cs42l51 = snd_soc_component_get_drvdata(component);
573
+ dapm = snd_soc_component_get_dapm(component);
574
+
575
+ if (cs42l51->mclk_handle)
576
+ snd_soc_dapm_new_controls(dapm, cs42l51_dapm_mclk_widgets, 1);
490577
491578 /*
492579 * DAC configuration
....@@ -512,13 +599,113 @@
512599 .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets),
513600 .dapm_routes = cs42l51_routes,
514601 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
602
+ .of_xlate_dai_id = cs42l51_of_xlate_dai_id,
515603 .idle_bias_on = 1,
516604 .use_pmdown_time = 1,
517605 .endianness = 1,
518606 .non_legacy_dai_naming = 1,
519607 };
520608
609
+static bool cs42l51_writeable_reg(struct device *dev, unsigned int reg)
610
+{
611
+ switch (reg) {
612
+ case CS42L51_POWER_CTL1:
613
+ case CS42L51_MIC_POWER_CTL:
614
+ case CS42L51_INTF_CTL:
615
+ case CS42L51_MIC_CTL:
616
+ case CS42L51_ADC_CTL:
617
+ case CS42L51_ADC_INPUT:
618
+ case CS42L51_DAC_OUT_CTL:
619
+ case CS42L51_DAC_CTL:
620
+ case CS42L51_ALC_PGA_CTL:
621
+ case CS42L51_ALC_PGB_CTL:
622
+ case CS42L51_ADCA_ATT:
623
+ case CS42L51_ADCB_ATT:
624
+ case CS42L51_ADCA_VOL:
625
+ case CS42L51_ADCB_VOL:
626
+ case CS42L51_PCMA_VOL:
627
+ case CS42L51_PCMB_VOL:
628
+ case CS42L51_BEEP_FREQ:
629
+ case CS42L51_BEEP_VOL:
630
+ case CS42L51_BEEP_CONF:
631
+ case CS42L51_TONE_CTL:
632
+ case CS42L51_AOUTA_VOL:
633
+ case CS42L51_AOUTB_VOL:
634
+ case CS42L51_PCM_MIXER:
635
+ case CS42L51_LIMIT_THRES_DIS:
636
+ case CS42L51_LIMIT_REL:
637
+ case CS42L51_LIMIT_ATT:
638
+ case CS42L51_ALC_EN:
639
+ case CS42L51_ALC_REL:
640
+ case CS42L51_ALC_THRES:
641
+ case CS42L51_NOISE_CONF:
642
+ case CS42L51_CHARGE_FREQ:
643
+ return true;
644
+ default:
645
+ return false;
646
+ }
647
+}
648
+
649
+static bool cs42l51_volatile_reg(struct device *dev, unsigned int reg)
650
+{
651
+ switch (reg) {
652
+ case CS42L51_STATUS:
653
+ return true;
654
+ default:
655
+ return false;
656
+ }
657
+}
658
+
659
+static bool cs42l51_readable_reg(struct device *dev, unsigned int reg)
660
+{
661
+ switch (reg) {
662
+ case CS42L51_CHIP_REV_ID:
663
+ case CS42L51_POWER_CTL1:
664
+ case CS42L51_MIC_POWER_CTL:
665
+ case CS42L51_INTF_CTL:
666
+ case CS42L51_MIC_CTL:
667
+ case CS42L51_ADC_CTL:
668
+ case CS42L51_ADC_INPUT:
669
+ case CS42L51_DAC_OUT_CTL:
670
+ case CS42L51_DAC_CTL:
671
+ case CS42L51_ALC_PGA_CTL:
672
+ case CS42L51_ALC_PGB_CTL:
673
+ case CS42L51_ADCA_ATT:
674
+ case CS42L51_ADCB_ATT:
675
+ case CS42L51_ADCA_VOL:
676
+ case CS42L51_ADCB_VOL:
677
+ case CS42L51_PCMA_VOL:
678
+ case CS42L51_PCMB_VOL:
679
+ case CS42L51_BEEP_FREQ:
680
+ case CS42L51_BEEP_VOL:
681
+ case CS42L51_BEEP_CONF:
682
+ case CS42L51_TONE_CTL:
683
+ case CS42L51_AOUTA_VOL:
684
+ case CS42L51_AOUTB_VOL:
685
+ case CS42L51_PCM_MIXER:
686
+ case CS42L51_LIMIT_THRES_DIS:
687
+ case CS42L51_LIMIT_REL:
688
+ case CS42L51_LIMIT_ATT:
689
+ case CS42L51_ALC_EN:
690
+ case CS42L51_ALC_REL:
691
+ case CS42L51_ALC_THRES:
692
+ case CS42L51_NOISE_CONF:
693
+ case CS42L51_STATUS:
694
+ case CS42L51_CHARGE_FREQ:
695
+ return true;
696
+ default:
697
+ return false;
698
+ }
699
+}
700
+
521701 const struct regmap_config cs42l51_regmap = {
702
+ .reg_bits = 8,
703
+ .reg_stride = 1,
704
+ .val_bits = 8,
705
+ .use_single_write = true,
706
+ .readable_reg = cs42l51_readable_reg,
707
+ .volatile_reg = cs42l51_volatile_reg,
708
+ .writeable_reg = cs42l51_writeable_reg,
522709 .max_register = CS42L51_CHARGE_FREQ,
523710 .cache_type = REGCACHE_RBTREE,
524711 };
....@@ -528,7 +715,7 @@
528715 {
529716 struct cs42l51_private *cs42l51;
530717 unsigned int val;
531
- int ret;
718
+ int ret, i;
532719
533720 if (IS_ERR(regmap))
534721 return PTR_ERR(regmap);
....@@ -539,6 +726,42 @@
539726 return -ENOMEM;
540727
541728 dev_set_drvdata(dev, cs42l51);
729
+ cs42l51->regmap = regmap;
730
+
731
+ cs42l51->mclk_handle = devm_clk_get(dev, "MCLK");
732
+ if (IS_ERR(cs42l51->mclk_handle)) {
733
+ if (PTR_ERR(cs42l51->mclk_handle) != -ENOENT)
734
+ return PTR_ERR(cs42l51->mclk_handle);
735
+ cs42l51->mclk_handle = NULL;
736
+ }
737
+
738
+ for (i = 0; i < ARRAY_SIZE(cs42l51->supplies); i++)
739
+ cs42l51->supplies[i].supply = cs42l51_supply_names[i];
740
+
741
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs42l51->supplies),
742
+ cs42l51->supplies);
743
+ if (ret != 0) {
744
+ dev_err(dev, "Failed to request supplies: %d\n", ret);
745
+ return ret;
746
+ }
747
+
748
+ ret = regulator_bulk_enable(ARRAY_SIZE(cs42l51->supplies),
749
+ cs42l51->supplies);
750
+ if (ret != 0) {
751
+ dev_err(dev, "Failed to enable supplies: %d\n", ret);
752
+ return ret;
753
+ }
754
+
755
+ cs42l51->reset_gpio = devm_gpiod_get_optional(dev, "reset",
756
+ GPIOD_OUT_LOW);
757
+ if (IS_ERR(cs42l51->reset_gpio))
758
+ return PTR_ERR(cs42l51->reset_gpio);
759
+
760
+ if (cs42l51->reset_gpio) {
761
+ dev_dbg(dev, "Release reset gpio\n");
762
+ gpiod_set_value_cansleep(cs42l51->reset_gpio, 0);
763
+ mdelay(2);
764
+ }
542765
543766 /* Verify that we have a CS42L51 */
544767 ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val);
....@@ -558,11 +781,50 @@
558781
559782 ret = devm_snd_soc_register_component(dev,
560783 &soc_component_device_cs42l51, &cs42l51_dai, 1);
784
+ if (ret < 0)
785
+ goto error;
786
+
787
+ return 0;
788
+
561789 error:
790
+ regulator_bulk_disable(ARRAY_SIZE(cs42l51->supplies),
791
+ cs42l51->supplies);
562792 return ret;
563793 }
564794 EXPORT_SYMBOL_GPL(cs42l51_probe);
565795
796
+int cs42l51_remove(struct device *dev)
797
+{
798
+ struct cs42l51_private *cs42l51 = dev_get_drvdata(dev);
799
+
800
+ gpiod_set_value_cansleep(cs42l51->reset_gpio, 1);
801
+
802
+ return regulator_bulk_disable(ARRAY_SIZE(cs42l51->supplies),
803
+ cs42l51->supplies);
804
+}
805
+EXPORT_SYMBOL_GPL(cs42l51_remove);
806
+
807
+int __maybe_unused cs42l51_suspend(struct device *dev)
808
+{
809
+ struct cs42l51_private *cs42l51 = dev_get_drvdata(dev);
810
+
811
+ regcache_cache_only(cs42l51->regmap, true);
812
+ regcache_mark_dirty(cs42l51->regmap);
813
+
814
+ return 0;
815
+}
816
+EXPORT_SYMBOL_GPL(cs42l51_suspend);
817
+
818
+int __maybe_unused cs42l51_resume(struct device *dev)
819
+{
820
+ struct cs42l51_private *cs42l51 = dev_get_drvdata(dev);
821
+
822
+ regcache_cache_only(cs42l51->regmap, false);
823
+
824
+ return regcache_sync(cs42l51->regmap);
825
+}
826
+EXPORT_SYMBOL_GPL(cs42l51_resume);
827
+
566828 const struct of_device_id cs42l51_of_match[] = {
567829 { .compatible = "cirrus,cs42l51", },
568830 { }