hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
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,
....@@ -796,7 +776,7 @@
796776 /* Wait for DC servo to complete */
797777 dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
798778 do {
799
- val = snd_soc_component_read32(component, WM8904_DC_SERVO_READBACK_0);
779
+ val = snd_soc_component_read(component, WM8904_DC_SERVO_READBACK_0);
800780 if ((val & dcs_mask) == dcs_mask)
801781 break;
802782
....@@ -834,8 +814,8 @@
834814 case SND_SOC_DAPM_POST_PMD:
835815 /* Cache the DC servo configuration; this will be
836816 * 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);
817
+ wm8904->dcs_state[dcs_l] = snd_soc_component_read(component, dcs_l_reg);
818
+ wm8904->dcs_state[dcs_r] = snd_soc_component_read(component, dcs_r_reg);
839819
840820 snd_soc_component_update_bits(component, WM8904_DC_SERVO_0,
841821 dcs_mask, 0);
....@@ -857,6 +837,10 @@
857837 return 0;
858838 }
859839
840
+static const char *input_mode_text[] = {
841
+ "Single-Ended", "Differential Line", "Differential Mic"
842
+};
843
+
860844 static const char *lin_text[] = {
861845 "IN1L", "IN2L", "IN3L"
862846 };
....@@ -871,7 +855,14 @@
871855 lin_text);
872856
873857 static const struct snd_kcontrol_new lin_inv_mux =
874
- SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
858
+ SOC_DAPM_ENUM("Left Capture Inverting Mux", lin_inv_enum);
859
+
860
+static SOC_ENUM_SINGLE_DECL(lin_mode_enum,
861
+ WM8904_ANALOGUE_LEFT_INPUT_1, 0,
862
+ input_mode_text);
863
+
864
+static const struct snd_kcontrol_new lin_mode =
865
+ SOC_DAPM_ENUM("Left Capture Mode", lin_mode_enum);
875866
876867 static const char *rin_text[] = {
877868 "IN1R", "IN2R", "IN3R"
....@@ -887,7 +878,14 @@
887878 rin_text);
888879
889880 static const struct snd_kcontrol_new rin_inv_mux =
890
- SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
881
+ SOC_DAPM_ENUM("Right Capture Inverting Mux", rin_inv_enum);
882
+
883
+static SOC_ENUM_SINGLE_DECL(rin_mode_enum,
884
+ WM8904_ANALOGUE_RIGHT_INPUT_1, 0,
885
+ input_mode_text);
886
+
887
+static const struct snd_kcontrol_new rin_mode =
888
+ SOC_DAPM_ENUM("Right Capture Mode", rin_mode_enum);
891889
892890 static const char *aif_text[] = {
893891 "Left", "Right"
....@@ -937,9 +935,11 @@
937935 SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
938936 SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
939937 &lin_inv_mux),
938
+SND_SOC_DAPM_MUX("Left Capture Mode", SND_SOC_NOPM, 0, 0, &lin_mode),
940939 SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
941940 SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
942941 &rin_inv_mux),
942
+SND_SOC_DAPM_MUX("Right Capture Mode", SND_SOC_NOPM, 0, 0, &rin_mode),
943943
944944 SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
945945 NULL, 0),
....@@ -1062,6 +1062,12 @@
10621062 { "Left Capture Inverting Mux", "IN2L", "IN2L" },
10631063 { "Left Capture Inverting Mux", "IN3L", "IN3L" },
10641064
1065
+ { "Left Capture Mode", "Single-Ended", "Left Capture Inverting Mux" },
1066
+ { "Left Capture Mode", "Differential Line", "Left Capture Mux" },
1067
+ { "Left Capture Mode", "Differential Line", "Left Capture Inverting Mux" },
1068
+ { "Left Capture Mode", "Differential Mic", "Left Capture Mux" },
1069
+ { "Left Capture Mode", "Differential Mic", "Left Capture Inverting Mux" },
1070
+
10651071 { "Right Capture Mux", "IN1R", "IN1R" },
10661072 { "Right Capture Mux", "IN2R", "IN2R" },
10671073 { "Right Capture Mux", "IN3R", "IN3R" },
....@@ -1070,11 +1076,14 @@
10701076 { "Right Capture Inverting Mux", "IN2R", "IN2R" },
10711077 { "Right Capture Inverting Mux", "IN3R", "IN3R" },
10721078
1073
- { "Left Capture PGA", NULL, "Left Capture Mux" },
1074
- { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
1079
+ { "Right Capture Mode", "Single-Ended", "Right Capture Inverting Mux" },
1080
+ { "Right Capture Mode", "Differential Line", "Right Capture Mux" },
1081
+ { "Right Capture Mode", "Differential Line", "Right Capture Inverting Mux" },
1082
+ { "Right Capture Mode", "Differential Mic", "Right Capture Mux" },
1083
+ { "Right Capture Mode", "Differential Mic", "Right Capture Inverting Mux" },
10751084
1076
- { "Right Capture PGA", NULL, "Right Capture Mux" },
1077
- { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
1085
+ { "Left Capture PGA", NULL, "Left Capture Mode" },
1086
+ { "Right Capture PGA", NULL, "Right Capture Mode" },
10781087
10791088 { "AIFOUTL Mux", "Left", "ADCL" },
10801089 { "AIFOUTL Mux", "Right", "ADCR" },
....@@ -1401,34 +1410,6 @@
14011410 return 0;
14021411 }
14031412
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
-
14321413 static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
14331414 {
14341415 struct snd_soc_component *component = dai->component;
....@@ -1455,7 +1436,7 @@
14551436 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
14561437 case SND_SOC_DAIFMT_DSP_B:
14571438 aif1 |= 0x3 | WM8904_AIF_LRCLK_INV;
1458
- /* fall through */
1439
+ fallthrough;
14591440 case SND_SOC_DAIFMT_DSP_A:
14601441 aif1 |= 0x3;
14611442 break;
....@@ -1690,7 +1671,7 @@
16901671 Fout == wm8904->fll_fout)
16911672 return 0;
16921673
1693
- clock2 = snd_soc_component_read32(component, WM8904_CLOCK_RATES_2);
1674
+ clock2 = snd_soc_component_read(component, WM8904_CLOCK_RATES_2);
16941675
16951676 if (Fout == 0) {
16961677 dev_dbg(component->dev, "FLL disabled\n");
....@@ -1735,7 +1716,7 @@
17351716
17361717 /* Save current state then disable the FLL and SYSCLK to avoid
17371718 * misclocking */
1738
- fll1 = snd_soc_component_read32(component, WM8904_FLL_CONTROL_1);
1719
+ fll1 = snd_soc_component_read(component, WM8904_FLL_CONTROL_1);
17391720 snd_soc_component_update_bits(component, WM8904_CLOCK_RATES_2,
17401721 WM8904_CLK_SYS_ENA, 0);
17411722 snd_soc_component_update_bits(component, WM8904_FLL_CONTROL_1,
....@@ -1815,7 +1796,57 @@
18151796 return 0;
18161797 }
18171798
1818
-static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1799
+static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1800
+ unsigned int freq, int dir)
1801
+{
1802
+ struct snd_soc_component *component = dai->component;
1803
+ struct wm8904_priv *priv = snd_soc_component_get_drvdata(component);
1804
+ unsigned long mclk_freq;
1805
+ int ret;
1806
+
1807
+ switch (clk_id) {
1808
+ case WM8904_CLK_AUTO:
1809
+ /* We don't have any rate constraints, so just ignore the
1810
+ * request to disable constraining.
1811
+ */
1812
+ if (!freq)
1813
+ return 0;
1814
+
1815
+ mclk_freq = clk_get_rate(priv->mclk);
1816
+ /* enable FLL if a different sysclk is desired */
1817
+ if (mclk_freq != freq) {
1818
+ priv->sysclk_src = WM8904_CLK_FLL;
1819
+ ret = wm8904_set_fll(dai, WM8904_FLL_MCLK,
1820
+ WM8904_FLL_MCLK,
1821
+ mclk_freq, freq);
1822
+ if (ret)
1823
+ return ret;
1824
+ break;
1825
+ }
1826
+ clk_id = WM8904_CLK_MCLK;
1827
+ fallthrough;
1828
+
1829
+ case WM8904_CLK_MCLK:
1830
+ priv->sysclk_src = clk_id;
1831
+ priv->mclk_rate = freq;
1832
+ break;
1833
+
1834
+ case WM8904_CLK_FLL:
1835
+ priv->sysclk_src = clk_id;
1836
+ break;
1837
+
1838
+ default:
1839
+ return -EINVAL;
1840
+ }
1841
+
1842
+ dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1843
+
1844
+ wm8904_configure_clocking(component);
1845
+
1846
+ return 0;
1847
+}
1848
+
1849
+static int wm8904_mute(struct snd_soc_dai *codec_dai, int mute, int direction)
18191850 {
18201851 struct snd_soc_component *component = codec_dai->component;
18211852 int val;
....@@ -1838,9 +1869,6 @@
18381869
18391870 switch (level) {
18401871 case SND_SOC_BIAS_ON:
1841
- ret = clk_prepare_enable(wm8904->mclk);
1842
- if (ret)
1843
- return ret;
18441872 break;
18451873
18461874 case SND_SOC_BIAS_PREPARE:
....@@ -1862,6 +1890,15 @@
18621890 dev_err(component->dev,
18631891 "Failed to enable supplies: %d\n",
18641892 ret);
1893
+ return ret;
1894
+ }
1895
+
1896
+ ret = clk_prepare_enable(wm8904->mclk);
1897
+ if (ret) {
1898
+ dev_err(component->dev,
1899
+ "Failed to enable MCLK: %d\n", ret);
1900
+ regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
1901
+ wm8904->supplies);
18651902 return ret;
18661903 }
18671904
....@@ -1925,7 +1962,8 @@
19251962 .set_tdm_slot = wm8904_set_tdm_slot,
19261963 .set_pll = wm8904_set_fll,
19271964 .hw_params = wm8904_hw_params,
1928
- .digital_mute = wm8904_digital_mute,
1965
+ .mute_stream = wm8904_mute,
1966
+ .no_capture_mute = 1,
19291967 };
19301968
19311969 static struct snd_soc_dai_driver wm8904_dai = {
....@@ -2110,16 +2148,13 @@
21102148 };
21112149
21122150 #ifdef CONFIG_OF
2113
-static enum wm8904_type wm8904_data = WM8904;
2114
-static enum wm8904_type wm8912_data = WM8912;
2115
-
21162151 static const struct of_device_id wm8904_of_match[] = {
21172152 {
21182153 .compatible = "wlf,wm8904",
2119
- .data = &wm8904_data,
2154
+ .data = (void *)WM8904,
21202155 }, {
21212156 .compatible = "wlf,wm8912",
2122
- .data = &wm8912_data,
2157
+ .data = (void *)WM8912,
21232158 }, {
21242159 /* sentinel */
21252160 }
....@@ -2160,7 +2195,7 @@
21602195 match = of_match_node(wm8904_of_match, i2c->dev.of_node);
21612196 if (match == NULL)
21622197 return -EINVAL;
2163
- wm8904->devtype = *((enum wm8904_type *)match->data);
2198
+ wm8904->devtype = (enum wm8904_type)match->data;
21642199 } else {
21652200 wm8904->devtype = id->driver_data;
21662201 }