hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/sound/soc/codecs/wm8904.c
....@@ -1,19 +1,14 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * wm8904.c -- WM8904 ALSA SoC Audio driver
34 *
45 * Copyright 2009-12 Wolfson Microelectronics plc
56 *
67 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7
- *
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License version 2 as
11
- * published by the Free Software Foundation.
128 */
139
1410 #include <linux/clk.h>
1511 #include <linux/module.h>
16
-#include <linux/moduleparam.h>
1712 #include <linux/init.h>
1813 #include <linux/delay.h>
1914 #include <linux/pm.h>
....@@ -322,7 +317,7 @@
322317 unsigned int clock0, clock2, rate;
323318
324319 /* Gate the clock while we're updating to avoid misclocking */
325
- clock2 = snd_soc_component_read32(component, WM8904_CLOCK_RATES_2);
320
+ clock2 = snd_soc_component_read(component, WM8904_CLOCK_RATES_2);
326321 snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_2,
327322 WM8904_SYSCLK_SRC, 0);
328323
....@@ -379,7 +374,7 @@
379374 int save, i;
380375
381376 /* Save any enables; the configuration should clear them. */
382
- save = snd_soc_component_read32(component, WM8904_DRC_0);
377
+ save = snd_soc_component_read(component, WM8904_DRC_0);
383378
384379 for (i = 0; i < WM8904_DRC_REGS; i++)
385380 snd_soc_component_update_bits(component, WM8904_DRC_0 + i, 0xffff,
....@@ -452,7 +447,7 @@
452447 /* The EQ will be disabled while reconfiguring it, remember the
453448 * current configuration.
454449 */
455
- save = snd_soc_component_read32(component, WM8904_EQ1);
450
+ save = snd_soc_component_read(component, WM8904_EQ1);
456451
457452 for (i = 0; i < WM8904_EQ_REGS; i++)
458453 snd_soc_component_update_bits(component, WM8904_EQ1 + i, 0xffff,
....@@ -550,18 +545,6 @@
550545 static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
551546 static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
552547
553
-static const char *input_mode_text[] = {
554
- "Single-Ended", "Differential Line", "Differential Mic"
555
-};
556
-
557
-static SOC_ENUM_SINGLE_DECL(lin_mode,
558
- WM8904_ANALOGUE_LEFT_INPUT_1, 0,
559
- input_mode_text);
560
-
561
-static SOC_ENUM_SINGLE_DECL(rin_mode,
562
- WM8904_ANALOGUE_RIGHT_INPUT_1, 0,
563
- input_mode_text);
564
-
565548 static const char *hpf_mode_text[] = {
566549 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
567550 };
....@@ -595,9 +578,6 @@
595578 static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
596579 SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
597580 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
598
-
599
-SOC_ENUM("Left Capture Mode", lin_mode),
600
-SOC_ENUM("Right Capture Mode", rin_mode),
601581
602582 /* No TLV since it depends on mode */
603583 SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
....@@ -717,6 +697,7 @@
717697 int dcs_mask;
718698 int dcs_l, dcs_r;
719699 int dcs_l_reg, dcs_r_reg;
700
+ int an_out_reg;
720701 int timeout;
721702 int pwr_reg;
722703
....@@ -732,6 +713,7 @@
732713 dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
733714 dcs_r_reg = WM8904_DC_SERVO_8;
734715 dcs_l_reg = WM8904_DC_SERVO_9;
716
+ an_out_reg = WM8904_ANALOGUE_OUT1_LEFT;
735717 dcs_l = 0;
736718 dcs_r = 1;
737719 break;
....@@ -740,6 +722,7 @@
740722 dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
741723 dcs_r_reg = WM8904_DC_SERVO_6;
742724 dcs_l_reg = WM8904_DC_SERVO_7;
725
+ an_out_reg = WM8904_ANALOGUE_OUT2_LEFT;
743726 dcs_l = 2;
744727 dcs_r = 3;
745728 break;
....@@ -796,7 +779,7 @@
796779 /* Wait for DC servo to complete */
797780 dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
798781 do {
799
- val = snd_soc_component_read32(component, WM8904_DC_SERVO_READBACK_0);
782
+ val = snd_soc_component_read(component, WM8904_DC_SERVO_READBACK_0);
800783 if ((val & dcs_mask) == dcs_mask)
801784 break;
802785
....@@ -812,6 +795,10 @@
812795 snd_soc_component_update_bits(component, reg,
813796 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
814797 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
798
+
799
+ /* Update volume, requires PGA to be powered */
800
+ val = snd_soc_component_read(component, an_out_reg);
801
+ snd_soc_component_write(component, an_out_reg, val);
815802 break;
816803
817804 case SND_SOC_DAPM_POST_PMU:
....@@ -834,8 +821,8 @@
834821 case SND_SOC_DAPM_POST_PMD:
835822 /* Cache the DC servo configuration; this will be
836823 * invalidated if we change the configuration. */
837
- wm8904->dcs_state[dcs_l] = snd_soc_component_read32(component, dcs_l_reg);
838
- wm8904->dcs_state[dcs_r] = snd_soc_component_read32(component, dcs_r_reg);
824
+ wm8904->dcs_state[dcs_l] = snd_soc_component_read(component, dcs_l_reg);
825
+ wm8904->dcs_state[dcs_r] = snd_soc_component_read(component, dcs_r_reg);
839826
840827 snd_soc_component_update_bits(component, WM8904_DC_SERVO_0,
841828 dcs_mask, 0);
....@@ -857,6 +844,10 @@
857844 return 0;
858845 }
859846
847
+static const char *input_mode_text[] = {
848
+ "Single-Ended", "Differential Line", "Differential Mic"
849
+};
850
+
860851 static const char *lin_text[] = {
861852 "IN1L", "IN2L", "IN3L"
862853 };
....@@ -871,7 +862,14 @@
871862 lin_text);
872863
873864 static const struct snd_kcontrol_new lin_inv_mux =
874
- SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
865
+ SOC_DAPM_ENUM("Left Capture Inverting Mux", lin_inv_enum);
866
+
867
+static SOC_ENUM_SINGLE_DECL(lin_mode_enum,
868
+ WM8904_ANALOGUE_LEFT_INPUT_1, 0,
869
+ input_mode_text);
870
+
871
+static const struct snd_kcontrol_new lin_mode =
872
+ SOC_DAPM_ENUM("Left Capture Mode", lin_mode_enum);
875873
876874 static const char *rin_text[] = {
877875 "IN1R", "IN2R", "IN3R"
....@@ -887,7 +885,14 @@
887885 rin_text);
888886
889887 static const struct snd_kcontrol_new rin_inv_mux =
890
- SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
888
+ SOC_DAPM_ENUM("Right Capture Inverting Mux", rin_inv_enum);
889
+
890
+static SOC_ENUM_SINGLE_DECL(rin_mode_enum,
891
+ WM8904_ANALOGUE_RIGHT_INPUT_1, 0,
892
+ input_mode_text);
893
+
894
+static const struct snd_kcontrol_new rin_mode =
895
+ SOC_DAPM_ENUM("Right Capture Mode", rin_mode_enum);
891896
892897 static const char *aif_text[] = {
893898 "Left", "Right"
....@@ -937,9 +942,11 @@
937942 SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
938943 SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
939944 &lin_inv_mux),
945
+SND_SOC_DAPM_MUX("Left Capture Mode", SND_SOC_NOPM, 0, 0, &lin_mode),
940946 SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
941947 SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
942948 &rin_inv_mux),
949
+SND_SOC_DAPM_MUX("Right Capture Mode", SND_SOC_NOPM, 0, 0, &rin_mode),
943950
944951 SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
945952 NULL, 0),
....@@ -1062,6 +1069,12 @@
10621069 { "Left Capture Inverting Mux", "IN2L", "IN2L" },
10631070 { "Left Capture Inverting Mux", "IN3L", "IN3L" },
10641071
1072
+ { "Left Capture Mode", "Single-Ended", "Left Capture Inverting Mux" },
1073
+ { "Left Capture Mode", "Differential Line", "Left Capture Mux" },
1074
+ { "Left Capture Mode", "Differential Line", "Left Capture Inverting Mux" },
1075
+ { "Left Capture Mode", "Differential Mic", "Left Capture Mux" },
1076
+ { "Left Capture Mode", "Differential Mic", "Left Capture Inverting Mux" },
1077
+
10651078 { "Right Capture Mux", "IN1R", "IN1R" },
10661079 { "Right Capture Mux", "IN2R", "IN2R" },
10671080 { "Right Capture Mux", "IN3R", "IN3R" },
....@@ -1070,11 +1083,14 @@
10701083 { "Right Capture Inverting Mux", "IN2R", "IN2R" },
10711084 { "Right Capture Inverting Mux", "IN3R", "IN3R" },
10721085
1073
- { "Left Capture PGA", NULL, "Left Capture Mux" },
1074
- { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
1086
+ { "Right Capture Mode", "Single-Ended", "Right Capture Inverting Mux" },
1087
+ { "Right Capture Mode", "Differential Line", "Right Capture Mux" },
1088
+ { "Right Capture Mode", "Differential Line", "Right Capture Inverting Mux" },
1089
+ { "Right Capture Mode", "Differential Mic", "Right Capture Mux" },
1090
+ { "Right Capture Mode", "Differential Mic", "Right Capture Inverting Mux" },
10751091
1076
- { "Right Capture PGA", NULL, "Right Capture Mux" },
1077
- { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
1092
+ { "Left Capture PGA", NULL, "Left Capture Mode" },
1093
+ { "Right Capture PGA", NULL, "Right Capture Mode" },
10781094
10791095 { "AIFOUTL Mux", "Left", "ADCL" },
10801096 { "AIFOUTL Mux", "Right", "ADCR" },
....@@ -1401,34 +1417,6 @@
14011417 return 0;
14021418 }
14031419
1404
-
1405
-static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1406
- unsigned int freq, int dir)
1407
-{
1408
- struct snd_soc_component *component = dai->component;
1409
- struct wm8904_priv *priv = snd_soc_component_get_drvdata(component);
1410
-
1411
- switch (clk_id) {
1412
- case WM8904_CLK_MCLK:
1413
- priv->sysclk_src = clk_id;
1414
- priv->mclk_rate = freq;
1415
- break;
1416
-
1417
- case WM8904_CLK_FLL:
1418
- priv->sysclk_src = clk_id;
1419
- break;
1420
-
1421
- default:
1422
- return -EINVAL;
1423
- }
1424
-
1425
- dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1426
-
1427
- wm8904_configure_clocking(component);
1428
-
1429
- return 0;
1430
-}
1431
-
14321420 static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
14331421 {
14341422 struct snd_soc_component *component = dai->component;
....@@ -1455,7 +1443,7 @@
14551443 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
14561444 case SND_SOC_DAIFMT_DSP_B:
14571445 aif1 |= 0x3 | WM8904_AIF_LRCLK_INV;
1458
- /* fall through */
1446
+ fallthrough;
14591447 case SND_SOC_DAIFMT_DSP_A:
14601448 aif1 |= 0x3;
14611449 break;
....@@ -1690,7 +1678,7 @@
16901678 Fout == wm8904->fll_fout)
16911679 return 0;
16921680
1693
- clock2 = snd_soc_component_read32(component, WM8904_CLOCK_RATES_2);
1681
+ clock2 = snd_soc_component_read(component, WM8904_CLOCK_RATES_2);
16941682
16951683 if (Fout == 0) {
16961684 dev_dbg(component->dev, "FLL disabled\n");
....@@ -1735,7 +1723,7 @@
17351723
17361724 /* Save current state then disable the FLL and SYSCLK to avoid
17371725 * misclocking */
1738
- fll1 = snd_soc_component_read32(component, WM8904_FLL_CONTROL_1);
1726
+ fll1 = snd_soc_component_read(component, WM8904_FLL_CONTROL_1);
17391727 snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_2,
17401728 WM8904_CLK_SYS_ENA, 0);
17411729 snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
....@@ -1815,7 +1803,57 @@
18151803 return 0;
18161804 }
18171805
1818
-static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1806
+static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1807
+ unsigned int freq, int dir)
1808
+{
1809
+ struct snd_soc_component *component = dai->component;
1810
+ struct wm8904_priv *priv = snd_soc_component_get_drvdata(component);
1811
+ unsigned long mclk_freq;
1812
+ int ret;
1813
+
1814
+ switch (clk_id) {
1815
+ case WM8904_CLK_AUTO:
1816
+ /* We don't have any rate constraints, so just ignore the
1817
+ * request to disable constraining.
1818
+ */
1819
+ if (!freq)
1820
+ return 0;
1821
+
1822
+ mclk_freq = clk_get_rate(priv->mclk);
1823
+ /* enable FLL if a different sysclk is desired */
1824
+ if (mclk_freq != freq) {
1825
+ priv->sysclk_src = WM8904_CLK_FLL;
1826
+ ret = wm8904_set_fll(dai, WM8904_FLL_MCLK,
1827
+ WM8904_FLL_MCLK,
1828
+ mclk_freq, freq);
1829
+ if (ret)
1830
+ return ret;
1831
+ break;
1832
+ }
1833
+ clk_id = WM8904_CLK_MCLK;
1834
+ fallthrough;
1835
+
1836
+ case WM8904_CLK_MCLK:
1837
+ priv->sysclk_src = clk_id;
1838
+ priv->mclk_rate = freq;
1839
+ break;
1840
+
1841
+ case WM8904_CLK_FLL:
1842
+ priv->sysclk_src = clk_id;
1843
+ break;
1844
+
1845
+ default:
1846
+ return -EINVAL;
1847
+ }
1848
+
1849
+ dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1850
+
1851
+ wm8904_configure_clocking(component);
1852
+
1853
+ return 0;
1854
+}
1855
+
1856
+static int wm8904_mute(struct snd_soc_dai *codec_dai, int mute, int direction)
18191857 {
18201858 struct snd_soc_component *component = codec_dai->component;
18211859 int val;
....@@ -1838,9 +1876,6 @@
18381876
18391877 switch (level) {
18401878 case SND_SOC_BIAS_ON:
1841
- ret = clk_prepare_enable(wm8904->mclk);
1842
- if (ret)
1843
- return ret;
18441879 break;
18451880
18461881 case SND_SOC_BIAS_PREPARE:
....@@ -1862,6 +1897,15 @@
18621897 dev_err(component->dev,
18631898 "Failed to enable supplies: %d\n",
18641899 ret);
1900
+ return ret;
1901
+ }
1902
+
1903
+ ret = clk_prepare_enable(wm8904->mclk);
1904
+ if (ret) {
1905
+ dev_err(component->dev,
1906
+ "Failed to enable MCLK: %d\n", ret);
1907
+ regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
1908
+ wm8904->supplies);
18651909 return ret;
18661910 }
18671911
....@@ -1925,7 +1969,8 @@
19251969 .set_tdm_slot = wm8904_set_tdm_slot,
19261970 .set_pll = wm8904_set_fll,
19271971 .hw_params = wm8904_hw_params,
1928
- .digital_mute = wm8904_digital_mute,
1972
+ .mute_stream = wm8904_mute,
1973
+ .no_capture_mute = 1,
19291974 };
19301975
19311976 static struct snd_soc_dai_driver wm8904_dai = {
....@@ -2110,16 +2155,13 @@
21102155 };
21112156
21122157 #ifdef CONFIG_OF
2113
-static enum wm8904_type wm8904_data = WM8904;
2114
-static enum wm8904_type wm8912_data = WM8912;
2115
-
21162158 static const struct of_device_id wm8904_of_match[] = {
21172159 {
21182160 .compatible = "wlf,wm8904",
2119
- .data = &wm8904_data,
2161
+ .data = (void *)WM8904,
21202162 }, {
21212163 .compatible = "wlf,wm8912",
2122
- .data = &wm8912_data,
2164
+ .data = (void *)WM8912,
21232165 }, {
21242166 /* sentinel */
21252167 }
....@@ -2160,7 +2202,7 @@
21602202 match = of_match_node(wm8904_of_match, i2c->dev.of_node);
21612203 if (match == NULL)
21622204 return -EINVAL;
2163
- wm8904->devtype = *((enum wm8904_type *)match->data);
2205
+ wm8904->devtype = (enum wm8904_type)match->data;
21642206 } else {
21652207 wm8904->devtype = id->driver_data;
21662208 }
....@@ -2264,6 +2306,9 @@
22642306 regmap_update_bits(wm8904->regmap, WM8904_BIAS_CONTROL_0,
22652307 WM8904_POBCTRL, 0);
22662308
2309
+ /* Fill the cache for the ADC test register */
2310
+ regmap_read(wm8904->regmap, WM8904_ADC_TEST_0, &val);
2311
+
22672312 /* Can leave the device powered off until we need it */
22682313 regcache_cache_only(wm8904->regmap, true);
22692314 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);