Commit | Line | Data |
---|---|---|
a61f3b4f SK |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (c) 2019, Linaro Limited | |
3 | ||
4 | #include <linux/clk.h> | |
5 | #include <linux/clk-provider.h> | |
a61f3b4f SK |
6 | #include <linux/interrupt.h> |
7 | #include <linux/kernel.h> | |
8 | #include <linux/mfd/wcd934x/registers.h> | |
9 | #include <linux/mfd/wcd934x/wcd934x.h> | |
10 | #include <linux/module.h> | |
11 | #include <linux/mutex.h> | |
12 | #include <linux/of_clk.h> | |
a61f3b4f | 13 | #include <linux/of.h> |
a61f3b4f SK |
14 | #include <linux/platform_device.h> |
15 | #include <linux/regmap.h> | |
16 | #include <linux/regulator/consumer.h> | |
17 | #include <linux/slab.h> | |
18 | #include <linux/slimbus.h> | |
19 | #include <sound/pcm_params.h> | |
20 | #include <sound/soc.h> | |
21 | #include <sound/soc-dapm.h> | |
22 | #include <sound/tlv.h> | |
23 | #include "wcd-clsh-v2.h" | |
24 | ||
25 | #define WCD934X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ | |
26 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ | |
27 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) | |
28 | /* Fractional Rates */ | |
29 | #define WCD934X_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ | |
30 | SNDRV_PCM_RATE_176400) | |
31 | #define WCD934X_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \ | |
32 | SNDRV_PCM_FMTBIT_S24_LE) | |
33 | ||
34 | /* slave port water mark level | |
35 | * (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes) | |
36 | */ | |
37 | #define SLAVE_PORT_WATER_MARK_6BYTES 0 | |
38 | #define SLAVE_PORT_WATER_MARK_9BYTES 1 | |
39 | #define SLAVE_PORT_WATER_MARK_12BYTES 2 | |
40 | #define SLAVE_PORT_WATER_MARK_15BYTES 3 | |
41 | #define SLAVE_PORT_WATER_MARK_SHIFT 1 | |
42 | #define SLAVE_PORT_ENABLE 1 | |
43 | #define SLAVE_PORT_DISABLE 0 | |
44 | #define WCD934X_SLIM_WATER_MARK_VAL \ | |
45 | ((SLAVE_PORT_WATER_MARK_12BYTES << SLAVE_PORT_WATER_MARK_SHIFT) | \ | |
46 | (SLAVE_PORT_ENABLE)) | |
47 | ||
48 | #define WCD934X_SLIM_NUM_PORT_REG 3 | |
49 | #define WCD934X_SLIM_PGD_PORT_INT_TX_EN0 (WCD934X_SLIM_PGD_PORT_INT_EN0 + 2) | |
50 | #define WCD934X_SLIM_IRQ_OVERFLOW BIT(0) | |
51 | #define WCD934X_SLIM_IRQ_UNDERFLOW BIT(1) | |
52 | #define WCD934X_SLIM_IRQ_PORT_CLOSED BIT(2) | |
53 | ||
54 | #define WCD934X_MCLK_CLK_12P288MHZ 12288000 | |
55 | #define WCD934X_MCLK_CLK_9P6MHZ 9600000 | |
56 | ||
57 | /* Only valid for 9.6 MHz mclk */ | |
58 | #define WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ 2400000 | |
59 | #define WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ 4800000 | |
60 | ||
61 | /* Only valid for 12.288 MHz mclk */ | |
62 | #define WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ 4096000 | |
63 | ||
64 | #define WCD934X_DMIC_CLK_DIV_2 0x0 | |
65 | #define WCD934X_DMIC_CLK_DIV_3 0x1 | |
66 | #define WCD934X_DMIC_CLK_DIV_4 0x2 | |
67 | #define WCD934X_DMIC_CLK_DIV_6 0x3 | |
68 | #define WCD934X_DMIC_CLK_DIV_8 0x4 | |
69 | #define WCD934X_DMIC_CLK_DIV_16 0x5 | |
70 | #define WCD934X_DMIC_CLK_DRIVE_DEFAULT 0x02 | |
71 | ||
72 | #define TX_HPF_CUT_OFF_FREQ_MASK 0x60 | |
73 | #define CF_MIN_3DB_4HZ 0x0 | |
74 | #define CF_MIN_3DB_75HZ 0x1 | |
75 | #define CF_MIN_3DB_150HZ 0x2 | |
76 | ||
77 | #define WCD934X_RX_START 16 | |
78 | #define WCD934X_NUM_INTERPOLATORS 9 | |
79 | #define WCD934X_RX_PATH_CTL_OFFSET 20 | |
80 | #define WCD934X_MAX_VALID_ADC_MUX 13 | |
81 | #define WCD934X_INVALID_ADC_MUX 9 | |
82 | ||
83 | #define WCD934X_SLIM_RX_CH(p) \ | |
84 | {.port = p + WCD934X_RX_START, .shift = p,} | |
85 | ||
86 | #define WCD934X_SLIM_TX_CH(p) \ | |
87 | {.port = p, .shift = p,} | |
88 | ||
89 | /* Feature masks to distinguish codec version */ | |
90 | #define DSD_DISABLED_MASK 0 | |
91 | #define SLNQ_DISABLED_MASK 1 | |
92 | ||
93 | #define DSD_DISABLED BIT(DSD_DISABLED_MASK) | |
94 | #define SLNQ_DISABLED BIT(SLNQ_DISABLED_MASK) | |
95 | ||
96 | /* As fine version info cannot be retrieved before wcd probe. | |
97 | * Define three coarse versions for possible future use before wcd probe. | |
98 | */ | |
99 | #define WCD_VERSION_WCD9340_1_0 0x400 | |
100 | #define WCD_VERSION_WCD9341_1_0 0x410 | |
101 | #define WCD_VERSION_WCD9340_1_1 0x401 | |
102 | #define WCD_VERSION_WCD9341_1_1 0x411 | |
103 | #define WCD934X_AMIC_PWR_LEVEL_LP 0 | |
104 | #define WCD934X_AMIC_PWR_LEVEL_DEFAULT 1 | |
105 | #define WCD934X_AMIC_PWR_LEVEL_HP 2 | |
106 | #define WCD934X_AMIC_PWR_LEVEL_HYBRID 3 | |
107 | #define WCD934X_AMIC_PWR_LVL_MASK 0x60 | |
108 | #define WCD934X_AMIC_PWR_LVL_SHIFT 0x5 | |
109 | ||
110 | #define WCD934X_DEC_PWR_LVL_MASK 0x06 | |
111 | #define WCD934X_DEC_PWR_LVL_LP 0x02 | |
112 | #define WCD934X_DEC_PWR_LVL_HP 0x04 | |
113 | #define WCD934X_DEC_PWR_LVL_DF 0x00 | |
114 | #define WCD934X_DEC_PWR_LVL_HYBRID WCD934X_DEC_PWR_LVL_DF | |
115 | ||
116 | #define WCD934X_DEF_MICBIAS_MV 1800 | |
117 | #define WCD934X_MAX_MICBIAS_MV 2850 | |
118 | ||
1cde8b82 SK |
119 | #define WCD_IIR_FILTER_SIZE (sizeof(u32) * BAND_MAX) |
120 | ||
121 | #define WCD_IIR_FILTER_CTL(xname, iidx, bidx) \ | |
122 | { \ | |
123 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | |
124 | .info = wcd934x_iir_filter_info, \ | |
125 | .get = wcd934x_get_iir_band_audio_mixer, \ | |
126 | .put = wcd934x_put_iir_band_audio_mixer, \ | |
127 | .private_value = (unsigned long)&(struct wcd_iir_filter_ctl) { \ | |
128 | .iir_idx = iidx, \ | |
129 | .band_idx = bidx, \ | |
130 | .bytes_ext = {.max = WCD_IIR_FILTER_SIZE, }, \ | |
131 | } \ | |
132 | } | |
133 | ||
da3e83f8 SK |
134 | #define WCD934X_INTERPOLATOR_PATH(id) \ |
135 | {"RX INT" #id "_1 MIX1 INP0", "RX0", "SLIM RX0"}, \ | |
136 | {"RX INT" #id "_1 MIX1 INP0", "RX1", "SLIM RX1"}, \ | |
137 | {"RX INT" #id "_1 MIX1 INP0", "RX2", "SLIM RX2"}, \ | |
138 | {"RX INT" #id "_1 MIX1 INP0", "RX3", "SLIM RX3"}, \ | |
139 | {"RX INT" #id "_1 MIX1 INP0", "RX4", "SLIM RX4"}, \ | |
140 | {"RX INT" #id "_1 MIX1 INP0", "RX5", "SLIM RX5"}, \ | |
141 | {"RX INT" #id "_1 MIX1 INP0", "RX6", "SLIM RX6"}, \ | |
142 | {"RX INT" #id "_1 MIX1 INP0", "RX7", "SLIM RX7"}, \ | |
143 | {"RX INT" #id "_1 MIX1 INP0", "IIR0", "IIR0"}, \ | |
144 | {"RX INT" #id "_1 MIX1 INP0", "IIR1", "IIR1"}, \ | |
145 | {"RX INT" #id "_1 MIX1 INP1", "RX0", "SLIM RX0"}, \ | |
146 | {"RX INT" #id "_1 MIX1 INP1", "RX1", "SLIM RX1"}, \ | |
147 | {"RX INT" #id "_1 MIX1 INP1", "RX2", "SLIM RX2"}, \ | |
148 | {"RX INT" #id "_1 MIX1 INP1", "RX3", "SLIM RX3"}, \ | |
149 | {"RX INT" #id "_1 MIX1 INP1", "RX4", "SLIM RX4"}, \ | |
150 | {"RX INT" #id "_1 MIX1 INP1", "RX5", "SLIM RX5"}, \ | |
151 | {"RX INT" #id "_1 MIX1 INP1", "RX6", "SLIM RX6"}, \ | |
152 | {"RX INT" #id "_1 MIX1 INP1", "RX7", "SLIM RX7"}, \ | |
153 | {"RX INT" #id "_1 MIX1 INP1", "IIR0", "IIR0"}, \ | |
154 | {"RX INT" #id "_1 MIX1 INP1", "IIR1", "IIR1"}, \ | |
155 | {"RX INT" #id "_1 MIX1 INP2", "RX0", "SLIM RX0"}, \ | |
156 | {"RX INT" #id "_1 MIX1 INP2", "RX1", "SLIM RX1"}, \ | |
157 | {"RX INT" #id "_1 MIX1 INP2", "RX2", "SLIM RX2"}, \ | |
158 | {"RX INT" #id "_1 MIX1 INP2", "RX3", "SLIM RX3"}, \ | |
159 | {"RX INT" #id "_1 MIX1 INP2", "RX4", "SLIM RX4"}, \ | |
160 | {"RX INT" #id "_1 MIX1 INP2", "RX5", "SLIM RX5"}, \ | |
161 | {"RX INT" #id "_1 MIX1 INP2", "RX6", "SLIM RX6"}, \ | |
162 | {"RX INT" #id "_1 MIX1 INP2", "RX7", "SLIM RX7"}, \ | |
163 | {"RX INT" #id "_1 MIX1 INP2", "IIR0", "IIR0"}, \ | |
164 | {"RX INT" #id "_1 MIX1 INP2", "IIR1", "IIR1"}, \ | |
165 | {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP0"}, \ | |
166 | {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP1"}, \ | |
167 | {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP2"}, \ | |
168 | {"RX INT" #id "_2 MUX", "RX0", "SLIM RX0"}, \ | |
169 | {"RX INT" #id "_2 MUX", "RX1", "SLIM RX1"}, \ | |
170 | {"RX INT" #id "_2 MUX", "RX2", "SLIM RX2"}, \ | |
171 | {"RX INT" #id "_2 MUX", "RX3", "SLIM RX3"}, \ | |
172 | {"RX INT" #id "_2 MUX", "RX4", "SLIM RX4"}, \ | |
173 | {"RX INT" #id "_2 MUX", "RX5", "SLIM RX5"}, \ | |
174 | {"RX INT" #id "_2 MUX", "RX6", "SLIM RX6"}, \ | |
175 | {"RX INT" #id "_2 MUX", "RX7", "SLIM RX7"}, \ | |
176 | {"RX INT" #id "_2 MUX", NULL, "INT" #id "_CLK"}, \ | |
177 | {"RX INT" #id "_2 MUX", NULL, "DSMDEM" #id "_CLK"}, \ | |
178 | {"RX INT" #id "_2 INTERP", NULL, "RX INT" #id "_2 MUX"}, \ | |
179 | {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_2 INTERP"}, \ | |
180 | {"RX INT" #id "_1 INTERP", NULL, "RX INT" #id "_1 MIX1"}, \ | |
181 | {"RX INT" #id "_1 INTERP", NULL, "INT" #id "_CLK"}, \ | |
182 | {"RX INT" #id "_1 INTERP", NULL, "DSMDEM" #id "_CLK"}, \ | |
183 | {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_1 INTERP"} | |
184 | ||
185 | #define WCD934X_INTERPOLATOR_MIX2(id) \ | |
186 | {"RX INT" #id " MIX2", NULL, "RX INT" #id " SEC MIX"}, \ | |
187 | {"RX INT" #id " MIX2", NULL, "RX INT" #id " MIX2 INP"} | |
188 | ||
189 | #define WCD934X_SLIM_RX_AIF_PATH(id) \ | |
190 | {"SLIM RX"#id" MUX", "AIF1_PB", "AIF1 PB"}, \ | |
191 | {"SLIM RX"#id" MUX", "AIF2_PB", "AIF2 PB"}, \ | |
192 | {"SLIM RX"#id" MUX", "AIF3_PB", "AIF3 PB"}, \ | |
193 | {"SLIM RX"#id" MUX", "AIF4_PB", "AIF4 PB"}, \ | |
194 | {"SLIM RX"#id, NULL, "SLIM RX"#id" MUX"} | |
195 | ||
196 | #define WCD934X_ADC_MUX(id) \ | |
197 | {"ADC MUX" #id, "DMIC", "DMIC MUX" #id }, \ | |
198 | {"ADC MUX" #id, "AMIC", "AMIC MUX" #id }, \ | |
199 | {"DMIC MUX" #id, "DMIC0", "DMIC0"}, \ | |
200 | {"DMIC MUX" #id, "DMIC1", "DMIC1"}, \ | |
201 | {"DMIC MUX" #id, "DMIC2", "DMIC2"}, \ | |
202 | {"DMIC MUX" #id, "DMIC3", "DMIC3"}, \ | |
203 | {"DMIC MUX" #id, "DMIC4", "DMIC4"}, \ | |
204 | {"DMIC MUX" #id, "DMIC5", "DMIC5"}, \ | |
205 | {"AMIC MUX" #id, "ADC1", "ADC1"}, \ | |
206 | {"AMIC MUX" #id, "ADC2", "ADC2"}, \ | |
207 | {"AMIC MUX" #id, "ADC3", "ADC3"}, \ | |
208 | {"AMIC MUX" #id, "ADC4", "ADC4"} | |
209 | ||
210 | #define WCD934X_IIR_INP_MUX(id) \ | |
211 | {"IIR" #id, NULL, "IIR" #id " INP0 MUX"}, \ | |
212 | {"IIR" #id " INP0 MUX", "DEC0", "ADC MUX0"}, \ | |
213 | {"IIR" #id " INP0 MUX", "DEC1", "ADC MUX1"}, \ | |
214 | {"IIR" #id " INP0 MUX", "DEC2", "ADC MUX2"}, \ | |
215 | {"IIR" #id " INP0 MUX", "DEC3", "ADC MUX3"}, \ | |
216 | {"IIR" #id " INP0 MUX", "DEC4", "ADC MUX4"}, \ | |
217 | {"IIR" #id " INP0 MUX", "DEC5", "ADC MUX5"}, \ | |
218 | {"IIR" #id " INP0 MUX", "DEC6", "ADC MUX6"}, \ | |
219 | {"IIR" #id " INP0 MUX", "DEC7", "ADC MUX7"}, \ | |
220 | {"IIR" #id " INP0 MUX", "DEC8", "ADC MUX8"}, \ | |
221 | {"IIR" #id " INP0 MUX", "RX0", "SLIM RX0"}, \ | |
222 | {"IIR" #id " INP0 MUX", "RX1", "SLIM RX1"}, \ | |
223 | {"IIR" #id " INP0 MUX", "RX2", "SLIM RX2"}, \ | |
224 | {"IIR" #id " INP0 MUX", "RX3", "SLIM RX3"}, \ | |
225 | {"IIR" #id " INP0 MUX", "RX4", "SLIM RX4"}, \ | |
226 | {"IIR" #id " INP0 MUX", "RX5", "SLIM RX5"}, \ | |
227 | {"IIR" #id " INP0 MUX", "RX6", "SLIM RX6"}, \ | |
228 | {"IIR" #id " INP0 MUX", "RX7", "SLIM RX7"}, \ | |
229 | {"IIR" #id, NULL, "IIR" #id " INP1 MUX"}, \ | |
230 | {"IIR" #id " INP1 MUX", "DEC0", "ADC MUX0"}, \ | |
231 | {"IIR" #id " INP1 MUX", "DEC1", "ADC MUX1"}, \ | |
232 | {"IIR" #id " INP1 MUX", "DEC2", "ADC MUX2"}, \ | |
233 | {"IIR" #id " INP1 MUX", "DEC3", "ADC MUX3"}, \ | |
234 | {"IIR" #id " INP1 MUX", "DEC4", "ADC MUX4"}, \ | |
235 | {"IIR" #id " INP1 MUX", "DEC5", "ADC MUX5"}, \ | |
236 | {"IIR" #id " INP1 MUX", "DEC6", "ADC MUX6"}, \ | |
237 | {"IIR" #id " INP1 MUX", "DEC7", "ADC MUX7"}, \ | |
238 | {"IIR" #id " INP1 MUX", "DEC8", "ADC MUX8"}, \ | |
239 | {"IIR" #id " INP1 MUX", "RX0", "SLIM RX0"}, \ | |
240 | {"IIR" #id " INP1 MUX", "RX1", "SLIM RX1"}, \ | |
241 | {"IIR" #id " INP1 MUX", "RX2", "SLIM RX2"}, \ | |
242 | {"IIR" #id " INP1 MUX", "RX3", "SLIM RX3"}, \ | |
243 | {"IIR" #id " INP1 MUX", "RX4", "SLIM RX4"}, \ | |
244 | {"IIR" #id " INP1 MUX", "RX5", "SLIM RX5"}, \ | |
245 | {"IIR" #id " INP1 MUX", "RX6", "SLIM RX6"}, \ | |
246 | {"IIR" #id " INP1 MUX", "RX7", "SLIM RX7"}, \ | |
247 | {"IIR" #id, NULL, "IIR" #id " INP2 MUX"}, \ | |
248 | {"IIR" #id " INP2 MUX", "DEC0", "ADC MUX0"}, \ | |
249 | {"IIR" #id " INP2 MUX", "DEC1", "ADC MUX1"}, \ | |
250 | {"IIR" #id " INP2 MUX", "DEC2", "ADC MUX2"}, \ | |
251 | {"IIR" #id " INP2 MUX", "DEC3", "ADC MUX3"}, \ | |
252 | {"IIR" #id " INP2 MUX", "DEC4", "ADC MUX4"}, \ | |
253 | {"IIR" #id " INP2 MUX", "DEC5", "ADC MUX5"}, \ | |
254 | {"IIR" #id " INP2 MUX", "DEC6", "ADC MUX6"}, \ | |
255 | {"IIR" #id " INP2 MUX", "DEC7", "ADC MUX7"}, \ | |
256 | {"IIR" #id " INP2 MUX", "DEC8", "ADC MUX8"}, \ | |
257 | {"IIR" #id " INP2 MUX", "RX0", "SLIM RX0"}, \ | |
258 | {"IIR" #id " INP2 MUX", "RX1", "SLIM RX1"}, \ | |
259 | {"IIR" #id " INP2 MUX", "RX2", "SLIM RX2"}, \ | |
260 | {"IIR" #id " INP2 MUX", "RX3", "SLIM RX3"}, \ | |
261 | {"IIR" #id " INP2 MUX", "RX4", "SLIM RX4"}, \ | |
262 | {"IIR" #id " INP2 MUX", "RX5", "SLIM RX5"}, \ | |
263 | {"IIR" #id " INP2 MUX", "RX6", "SLIM RX6"}, \ | |
264 | {"IIR" #id " INP2 MUX", "RX7", "SLIM RX7"}, \ | |
265 | {"IIR" #id, NULL, "IIR" #id " INP3 MUX"}, \ | |
266 | {"IIR" #id " INP3 MUX", "DEC0", "ADC MUX0"}, \ | |
267 | {"IIR" #id " INP3 MUX", "DEC1", "ADC MUX1"}, \ | |
268 | {"IIR" #id " INP3 MUX", "DEC2", "ADC MUX2"}, \ | |
269 | {"IIR" #id " INP3 MUX", "DEC3", "ADC MUX3"}, \ | |
270 | {"IIR" #id " INP3 MUX", "DEC4", "ADC MUX4"}, \ | |
271 | {"IIR" #id " INP3 MUX", "DEC5", "ADC MUX5"}, \ | |
272 | {"IIR" #id " INP3 MUX", "DEC6", "ADC MUX6"}, \ | |
273 | {"IIR" #id " INP3 MUX", "DEC7", "ADC MUX7"}, \ | |
274 | {"IIR" #id " INP3 MUX", "DEC8", "ADC MUX8"}, \ | |
275 | {"IIR" #id " INP3 MUX", "RX0", "SLIM RX0"}, \ | |
276 | {"IIR" #id " INP3 MUX", "RX1", "SLIM RX1"}, \ | |
277 | {"IIR" #id " INP3 MUX", "RX2", "SLIM RX2"}, \ | |
278 | {"IIR" #id " INP3 MUX", "RX3", "SLIM RX3"}, \ | |
279 | {"IIR" #id " INP3 MUX", "RX4", "SLIM RX4"}, \ | |
280 | {"IIR" #id " INP3 MUX", "RX5", "SLIM RX5"}, \ | |
281 | {"IIR" #id " INP3 MUX", "RX6", "SLIM RX6"}, \ | |
282 | {"IIR" #id " INP3 MUX", "RX7", "SLIM RX7"} | |
283 | ||
284 | #define WCD934X_SLIM_TX_AIF_PATH(id) \ | |
285 | {"AIF1_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id }, \ | |
286 | {"AIF2_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id }, \ | |
287 | {"AIF3_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id }, \ | |
288 | {"SLIM TX" #id, NULL, "CDC_IF TX" #id " MUX"} | |
289 | ||
a70d9245 SK |
290 | enum { |
291 | MIC_BIAS_1 = 1, | |
292 | MIC_BIAS_2, | |
293 | MIC_BIAS_3, | |
294 | MIC_BIAS_4 | |
295 | }; | |
296 | ||
a61f3b4f SK |
297 | enum { |
298 | SIDO_SOURCE_INTERNAL, | |
299 | SIDO_SOURCE_RCO_BG, | |
300 | }; | |
301 | ||
302 | enum { | |
303 | INTERP_EAR = 0, | |
304 | INTERP_HPHL, | |
305 | INTERP_HPHR, | |
306 | INTERP_LO1, | |
307 | INTERP_LO2, | |
308 | INTERP_LO3_NA, /* LO3 not avalible in Tavil */ | |
309 | INTERP_LO4_NA, | |
310 | INTERP_SPKR1, /*INT7 WSA Speakers via soundwire */ | |
311 | INTERP_SPKR2, /*INT8 WSA Speakers via soundwire */ | |
312 | INTERP_MAX, | |
313 | }; | |
314 | ||
315 | enum { | |
316 | WCD934X_RX0 = 0, | |
317 | WCD934X_RX1, | |
318 | WCD934X_RX2, | |
319 | WCD934X_RX3, | |
320 | WCD934X_RX4, | |
321 | WCD934X_RX5, | |
322 | WCD934X_RX6, | |
323 | WCD934X_RX7, | |
324 | WCD934X_RX8, | |
325 | WCD934X_RX9, | |
326 | WCD934X_RX10, | |
327 | WCD934X_RX11, | |
328 | WCD934X_RX12, | |
329 | WCD934X_RX_MAX, | |
330 | }; | |
331 | ||
332 | enum { | |
333 | WCD934X_TX0 = 0, | |
334 | WCD934X_TX1, | |
335 | WCD934X_TX2, | |
336 | WCD934X_TX3, | |
337 | WCD934X_TX4, | |
338 | WCD934X_TX5, | |
339 | WCD934X_TX6, | |
340 | WCD934X_TX7, | |
341 | WCD934X_TX8, | |
342 | WCD934X_TX9, | |
343 | WCD934X_TX10, | |
344 | WCD934X_TX11, | |
345 | WCD934X_TX12, | |
346 | WCD934X_TX13, | |
347 | WCD934X_TX14, | |
348 | WCD934X_TX15, | |
349 | WCD934X_TX_MAX, | |
350 | }; | |
351 | ||
352 | struct wcd934x_slim_ch { | |
353 | u32 ch_num; | |
354 | u16 port; | |
355 | u16 shift; | |
356 | struct list_head list; | |
357 | }; | |
358 | ||
359 | static const struct wcd934x_slim_ch wcd934x_tx_chs[WCD934X_TX_MAX] = { | |
360 | WCD934X_SLIM_TX_CH(0), | |
361 | WCD934X_SLIM_TX_CH(1), | |
362 | WCD934X_SLIM_TX_CH(2), | |
363 | WCD934X_SLIM_TX_CH(3), | |
364 | WCD934X_SLIM_TX_CH(4), | |
365 | WCD934X_SLIM_TX_CH(5), | |
366 | WCD934X_SLIM_TX_CH(6), | |
367 | WCD934X_SLIM_TX_CH(7), | |
368 | WCD934X_SLIM_TX_CH(8), | |
369 | WCD934X_SLIM_TX_CH(9), | |
370 | WCD934X_SLIM_TX_CH(10), | |
371 | WCD934X_SLIM_TX_CH(11), | |
372 | WCD934X_SLIM_TX_CH(12), | |
373 | WCD934X_SLIM_TX_CH(13), | |
374 | WCD934X_SLIM_TX_CH(14), | |
375 | WCD934X_SLIM_TX_CH(15), | |
376 | }; | |
377 | ||
378 | static const struct wcd934x_slim_ch wcd934x_rx_chs[WCD934X_RX_MAX] = { | |
379 | WCD934X_SLIM_RX_CH(0), /* 16 */ | |
380 | WCD934X_SLIM_RX_CH(1), /* 17 */ | |
381 | WCD934X_SLIM_RX_CH(2), | |
382 | WCD934X_SLIM_RX_CH(3), | |
383 | WCD934X_SLIM_RX_CH(4), | |
384 | WCD934X_SLIM_RX_CH(5), | |
385 | WCD934X_SLIM_RX_CH(6), | |
386 | WCD934X_SLIM_RX_CH(7), | |
387 | WCD934X_SLIM_RX_CH(8), | |
388 | WCD934X_SLIM_RX_CH(9), | |
389 | WCD934X_SLIM_RX_CH(10), | |
390 | WCD934X_SLIM_RX_CH(11), | |
391 | WCD934X_SLIM_RX_CH(12), | |
392 | }; | |
393 | ||
1cde8b82 SK |
394 | /* Codec supports 2 IIR filters */ |
395 | enum { | |
396 | IIR0 = 0, | |
397 | IIR1, | |
398 | IIR_MAX, | |
399 | }; | |
400 | ||
401 | /* Each IIR has 5 Filter Stages */ | |
402 | enum { | |
403 | BAND1 = 0, | |
404 | BAND2, | |
405 | BAND3, | |
406 | BAND4, | |
407 | BAND5, | |
408 | BAND_MAX, | |
409 | }; | |
410 | ||
411 | enum { | |
412 | COMPANDER_1, /* HPH_L */ | |
413 | COMPANDER_2, /* HPH_R */ | |
414 | COMPANDER_3, /* LO1_DIFF */ | |
415 | COMPANDER_4, /* LO2_DIFF */ | |
416 | COMPANDER_5, /* LO3_SE - not used in Tavil */ | |
417 | COMPANDER_6, /* LO4_SE - not used in Tavil */ | |
418 | COMPANDER_7, /* SWR SPK CH1 */ | |
419 | COMPANDER_8, /* SWR SPK CH2 */ | |
420 | COMPANDER_MAX, | |
421 | }; | |
422 | ||
a61f3b4f SK |
423 | enum { |
424 | AIF1_PB = 0, | |
425 | AIF1_CAP, | |
426 | AIF2_PB, | |
427 | AIF2_CAP, | |
428 | AIF3_PB, | |
429 | AIF3_CAP, | |
430 | AIF4_PB, | |
431 | AIF4_VIFEED, | |
432 | AIF4_MAD_TX, | |
433 | NUM_CODEC_DAIS, | |
434 | }; | |
435 | ||
436 | enum { | |
437 | INTn_1_INP_SEL_ZERO = 0, | |
438 | INTn_1_INP_SEL_DEC0, | |
439 | INTn_1_INP_SEL_DEC1, | |
440 | INTn_1_INP_SEL_IIR0, | |
441 | INTn_1_INP_SEL_IIR1, | |
442 | INTn_1_INP_SEL_RX0, | |
443 | INTn_1_INP_SEL_RX1, | |
444 | INTn_1_INP_SEL_RX2, | |
445 | INTn_1_INP_SEL_RX3, | |
446 | INTn_1_INP_SEL_RX4, | |
447 | INTn_1_INP_SEL_RX5, | |
448 | INTn_1_INP_SEL_RX6, | |
449 | INTn_1_INP_SEL_RX7, | |
450 | }; | |
451 | ||
452 | enum { | |
453 | INTn_2_INP_SEL_ZERO = 0, | |
454 | INTn_2_INP_SEL_RX0, | |
455 | INTn_2_INP_SEL_RX1, | |
456 | INTn_2_INP_SEL_RX2, | |
457 | INTn_2_INP_SEL_RX3, | |
458 | INTn_2_INP_SEL_RX4, | |
459 | INTn_2_INP_SEL_RX5, | |
460 | INTn_2_INP_SEL_RX6, | |
461 | INTn_2_INP_SEL_RX7, | |
462 | INTn_2_INP_SEL_PROXIMITY, | |
463 | }; | |
464 | ||
465 | enum { | |
466 | INTERP_MAIN_PATH, | |
467 | INTERP_MIX_PATH, | |
468 | }; | |
469 | ||
470 | struct interp_sample_rate { | |
471 | int sample_rate; | |
472 | int rate_val; | |
473 | }; | |
474 | ||
475 | static struct interp_sample_rate sr_val_tbl[] = { | |
476 | {8000, 0x0}, | |
477 | {16000, 0x1}, | |
478 | {32000, 0x3}, | |
479 | {48000, 0x4}, | |
480 | {96000, 0x5}, | |
481 | {192000, 0x6}, | |
482 | {384000, 0x7}, | |
483 | {44100, 0x9}, | |
484 | {88200, 0xA}, | |
485 | {176400, 0xB}, | |
486 | {352800, 0xC}, | |
487 | }; | |
488 | ||
489 | struct wcd_slim_codec_dai_data { | |
490 | struct list_head slim_ch_list; | |
491 | struct slim_stream_config sconfig; | |
492 | struct slim_stream_runtime *sruntime; | |
493 | }; | |
494 | ||
495 | static const struct regmap_range_cfg wcd934x_ifc_ranges[] = { | |
496 | { | |
497 | .name = "WCD9335-IFC-DEV", | |
498 | .range_min = 0x0, | |
499 | .range_max = 0xffff, | |
500 | .selector_reg = 0x800, | |
501 | .selector_mask = 0xfff, | |
502 | .selector_shift = 0, | |
503 | .window_start = 0x800, | |
504 | .window_len = 0x400, | |
505 | }, | |
506 | }; | |
507 | ||
508 | static struct regmap_config wcd934x_ifc_regmap_config = { | |
509 | .reg_bits = 16, | |
510 | .val_bits = 8, | |
511 | .max_register = 0xffff, | |
512 | .ranges = wcd934x_ifc_ranges, | |
513 | .num_ranges = ARRAY_SIZE(wcd934x_ifc_ranges), | |
514 | }; | |
515 | ||
516 | struct wcd934x_codec { | |
517 | struct device *dev; | |
518 | struct clk_hw hw; | |
519 | struct clk *extclk; | |
520 | struct regmap *regmap; | |
521 | struct regmap *if_regmap; | |
522 | struct slim_device *sdev; | |
523 | struct slim_device *sidev; | |
524 | struct wcd_clsh_ctrl *clsh_ctrl; | |
525 | struct snd_soc_component *component; | |
526 | struct wcd934x_slim_ch rx_chs[WCD934X_RX_MAX]; | |
527 | struct wcd934x_slim_ch tx_chs[WCD934X_TX_MAX]; | |
528 | struct wcd_slim_codec_dai_data dai[NUM_CODEC_DAIS]; | |
529 | int rate; | |
530 | u32 version; | |
531 | u32 hph_mode; | |
532 | int num_rx_port; | |
533 | int num_tx_port; | |
534 | u32 tx_port_value[WCD934X_TX_MAX]; | |
535 | u32 rx_port_value[WCD934X_RX_MAX]; | |
536 | int sido_input_src; | |
537 | int dmic_0_1_clk_cnt; | |
538 | int dmic_2_3_clk_cnt; | |
539 | int dmic_4_5_clk_cnt; | |
540 | int dmic_sample_rate; | |
1cde8b82 | 541 | int comp_enabled[COMPANDER_MAX]; |
a61f3b4f SK |
542 | int sysclk_users; |
543 | struct mutex sysclk_mutex; | |
544 | }; | |
545 | ||
546 | #define to_wcd934x_codec(_hw) container_of(_hw, struct wcd934x_codec, hw) | |
547 | ||
1cde8b82 SK |
548 | struct wcd_iir_filter_ctl { |
549 | unsigned int iir_idx; | |
550 | unsigned int band_idx; | |
551 | struct soc_bytes_ext bytes_ext; | |
552 | }; | |
553 | ||
fc0522bb | 554 | static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); |
1cde8b82 SK |
555 | static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); |
556 | static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); | |
557 | static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0); | |
558 | ||
559 | /* Cutoff frequency for high pass filter */ | |
560 | static const char * const cf_text[] = { | |
561 | "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" | |
562 | }; | |
563 | ||
564 | static const char * const rx_cf_text[] = { | |
565 | "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ", | |
566 | "CF_NEG_3DB_0P48HZ" | |
567 | }; | |
568 | ||
569 | static const char * const rx_hph_mode_mux_text[] = { | |
570 | "Class H Invalid", "Class-H Hi-Fi", "Class-H Low Power", "Class-AB", | |
571 | "Class-H Hi-Fi Low Power" | |
572 | }; | |
573 | ||
dd9eb19b SK |
574 | static const char *const slim_rx_mux_text[] = { |
575 | "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB", | |
576 | }; | |
577 | ||
578 | static const char * const rx_int0_7_mix_mux_text[] = { | |
579 | "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", | |
580 | "RX6", "RX7", "PROXIMITY" | |
581 | }; | |
582 | ||
583 | static const char * const rx_int_mix_mux_text[] = { | |
584 | "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", | |
585 | "RX6", "RX7" | |
586 | }; | |
587 | ||
588 | static const char * const rx_prim_mix_text[] = { | |
589 | "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2", | |
590 | "RX3", "RX4", "RX5", "RX6", "RX7" | |
591 | }; | |
592 | ||
593 | static const char * const rx_sidetone_mix_text[] = { | |
594 | "ZERO", "SRC0", "SRC1", "SRC_SUM" | |
595 | }; | |
596 | ||
597 | static const char * const iir_inp_mux_text[] = { | |
598 | "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", | |
599 | "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7" | |
600 | }; | |
601 | ||
602 | static const char * const rx_int_dem_inp_mux_text[] = { | |
603 | "NORMAL_DSM_OUT", "CLSH_DSM_OUT", | |
604 | }; | |
605 | ||
606 | static const char * const rx_int0_1_interp_mux_text[] = { | |
607 | "ZERO", "RX INT0_1 MIX1", | |
608 | }; | |
609 | ||
610 | static const char * const rx_int1_1_interp_mux_text[] = { | |
611 | "ZERO", "RX INT1_1 MIX1", | |
612 | }; | |
613 | ||
614 | static const char * const rx_int2_1_interp_mux_text[] = { | |
615 | "ZERO", "RX INT2_1 MIX1", | |
616 | }; | |
617 | ||
618 | static const char * const rx_int3_1_interp_mux_text[] = { | |
619 | "ZERO", "RX INT3_1 MIX1", | |
620 | }; | |
621 | ||
622 | static const char * const rx_int4_1_interp_mux_text[] = { | |
623 | "ZERO", "RX INT4_1 MIX1", | |
624 | }; | |
625 | ||
626 | static const char * const rx_int7_1_interp_mux_text[] = { | |
627 | "ZERO", "RX INT7_1 MIX1", | |
628 | }; | |
629 | ||
630 | static const char * const rx_int8_1_interp_mux_text[] = { | |
631 | "ZERO", "RX INT8_1 MIX1", | |
632 | }; | |
633 | ||
634 | static const char * const rx_int0_2_interp_mux_text[] = { | |
635 | "ZERO", "RX INT0_2 MUX", | |
636 | }; | |
637 | ||
638 | static const char * const rx_int1_2_interp_mux_text[] = { | |
639 | "ZERO", "RX INT1_2 MUX", | |
640 | }; | |
641 | ||
642 | static const char * const rx_int2_2_interp_mux_text[] = { | |
643 | "ZERO", "RX INT2_2 MUX", | |
644 | }; | |
645 | ||
646 | static const char * const rx_int3_2_interp_mux_text[] = { | |
647 | "ZERO", "RX INT3_2 MUX", | |
648 | }; | |
649 | ||
650 | static const char * const rx_int4_2_interp_mux_text[] = { | |
651 | "ZERO", "RX INT4_2 MUX", | |
652 | }; | |
653 | ||
654 | static const char * const rx_int7_2_interp_mux_text[] = { | |
655 | "ZERO", "RX INT7_2 MUX", | |
656 | }; | |
657 | ||
658 | static const char * const rx_int8_2_interp_mux_text[] = { | |
659 | "ZERO", "RX INT8_2 MUX", | |
660 | }; | |
661 | ||
a70d9245 SK |
662 | static const char * const dmic_mux_text[] = { |
663 | "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5" | |
664 | }; | |
665 | ||
666 | static const char * const amic_mux_text[] = { | |
667 | "ZERO", "ADC1", "ADC2", "ADC3", "ADC4" | |
668 | }; | |
669 | ||
670 | static const char * const amic4_5_sel_text[] = { | |
671 | "AMIC4", "AMIC5" | |
672 | }; | |
673 | ||
674 | static const char * const adc_mux_text[] = { | |
675 | "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2" | |
676 | }; | |
677 | ||
678 | static const char * const cdc_if_tx0_mux_text[] = { | |
679 | "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192" | |
680 | }; | |
681 | ||
682 | static const char * const cdc_if_tx1_mux_text[] = { | |
683 | "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192" | |
684 | }; | |
685 | ||
686 | static const char * const cdc_if_tx2_mux_text[] = { | |
687 | "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192" | |
688 | }; | |
689 | ||
690 | static const char * const cdc_if_tx3_mux_text[] = { | |
691 | "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192" | |
692 | }; | |
693 | ||
694 | static const char * const cdc_if_tx4_mux_text[] = { | |
695 | "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192" | |
696 | }; | |
697 | ||
698 | static const char * const cdc_if_tx5_mux_text[] = { | |
699 | "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192" | |
700 | }; | |
701 | ||
702 | static const char * const cdc_if_tx6_mux_text[] = { | |
703 | "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192" | |
704 | }; | |
705 | ||
706 | static const char * const cdc_if_tx7_mux_text[] = { | |
707 | "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192" | |
708 | }; | |
709 | ||
710 | static const char * const cdc_if_tx8_mux_text[] = { | |
711 | "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192" | |
712 | }; | |
713 | ||
714 | static const char * const cdc_if_tx9_mux_text[] = { | |
715 | "ZERO", "DEC7", "DEC7_192" | |
716 | }; | |
717 | ||
718 | static const char * const cdc_if_tx10_mux_text[] = { | |
719 | "ZERO", "DEC6", "DEC6_192" | |
720 | }; | |
721 | ||
722 | static const char * const cdc_if_tx11_mux_text[] = { | |
723 | "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST" | |
724 | }; | |
725 | ||
726 | static const char * const cdc_if_tx11_inp1_mux_text[] = { | |
727 | "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", | |
728 | "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12" | |
729 | }; | |
730 | ||
731 | static const char * const cdc_if_tx13_mux_text[] = { | |
732 | "CDC_DEC_5", "MAD_BRDCST" | |
733 | }; | |
734 | ||
735 | static const char * const cdc_if_tx13_inp1_mux_text[] = { | |
736 | "ZERO", "DEC5", "DEC5_192" | |
737 | }; | |
738 | ||
1cde8b82 SK |
739 | static const struct soc_enum cf_dec0_enum = |
740 | SOC_ENUM_SINGLE(WCD934X_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text); | |
741 | ||
742 | static const struct soc_enum cf_dec1_enum = | |
743 | SOC_ENUM_SINGLE(WCD934X_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text); | |
744 | ||
745 | static const struct soc_enum cf_dec2_enum = | |
746 | SOC_ENUM_SINGLE(WCD934X_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text); | |
747 | ||
748 | static const struct soc_enum cf_dec3_enum = | |
749 | SOC_ENUM_SINGLE(WCD934X_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text); | |
750 | ||
751 | static const struct soc_enum cf_dec4_enum = | |
752 | SOC_ENUM_SINGLE(WCD934X_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text); | |
753 | ||
754 | static const struct soc_enum cf_dec5_enum = | |
755 | SOC_ENUM_SINGLE(WCD934X_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text); | |
756 | ||
757 | static const struct soc_enum cf_dec6_enum = | |
758 | SOC_ENUM_SINGLE(WCD934X_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text); | |
759 | ||
760 | static const struct soc_enum cf_dec7_enum = | |
761 | SOC_ENUM_SINGLE(WCD934X_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text); | |
762 | ||
763 | static const struct soc_enum cf_dec8_enum = | |
764 | SOC_ENUM_SINGLE(WCD934X_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text); | |
765 | ||
766 | static const struct soc_enum cf_int0_1_enum = | |
767 | SOC_ENUM_SINGLE(WCD934X_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text); | |
768 | ||
769 | static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD934X_CDC_RX0_RX_PATH_MIX_CFG, 2, | |
770 | rx_cf_text); | |
771 | ||
772 | static const struct soc_enum cf_int1_1_enum = | |
773 | SOC_ENUM_SINGLE(WCD934X_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text); | |
774 | ||
775 | static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD934X_CDC_RX1_RX_PATH_MIX_CFG, 2, | |
776 | rx_cf_text); | |
777 | ||
778 | static const struct soc_enum cf_int2_1_enum = | |
779 | SOC_ENUM_SINGLE(WCD934X_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text); | |
780 | ||
781 | static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD934X_CDC_RX2_RX_PATH_MIX_CFG, 2, | |
782 | rx_cf_text); | |
783 | ||
784 | static const struct soc_enum cf_int3_1_enum = | |
785 | SOC_ENUM_SINGLE(WCD934X_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text); | |
786 | ||
787 | static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD934X_CDC_RX3_RX_PATH_MIX_CFG, 2, | |
788 | rx_cf_text); | |
789 | ||
790 | static const struct soc_enum cf_int4_1_enum = | |
791 | SOC_ENUM_SINGLE(WCD934X_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text); | |
792 | ||
793 | static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD934X_CDC_RX4_RX_PATH_MIX_CFG, 2, | |
794 | rx_cf_text); | |
795 | ||
796 | static const struct soc_enum cf_int7_1_enum = | |
797 | SOC_ENUM_SINGLE(WCD934X_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text); | |
798 | ||
799 | static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD934X_CDC_RX7_RX_PATH_MIX_CFG, 2, | |
800 | rx_cf_text); | |
801 | ||
802 | static const struct soc_enum cf_int8_1_enum = | |
803 | SOC_ENUM_SINGLE(WCD934X_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text); | |
804 | ||
805 | static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD934X_CDC_RX8_RX_PATH_MIX_CFG, 2, | |
806 | rx_cf_text); | |
807 | ||
808 | static const struct soc_enum rx_hph_mode_mux_enum = | |
809 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), | |
810 | rx_hph_mode_mux_text); | |
811 | ||
dd9eb19b SK |
812 | static const struct soc_enum slim_rx_mux_enum = |
813 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text); | |
814 | ||
815 | static const struct soc_enum rx_int0_2_mux_chain_enum = | |
816 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10, | |
817 | rx_int0_7_mix_mux_text); | |
818 | ||
819 | static const struct soc_enum rx_int1_2_mux_chain_enum = | |
820 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9, | |
821 | rx_int_mix_mux_text); | |
822 | ||
823 | static const struct soc_enum rx_int2_2_mux_chain_enum = | |
824 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9, | |
825 | rx_int_mix_mux_text); | |
826 | ||
827 | static const struct soc_enum rx_int3_2_mux_chain_enum = | |
828 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9, | |
829 | rx_int_mix_mux_text); | |
830 | ||
831 | static const struct soc_enum rx_int4_2_mux_chain_enum = | |
832 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9, | |
833 | rx_int_mix_mux_text); | |
834 | ||
835 | static const struct soc_enum rx_int7_2_mux_chain_enum = | |
836 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10, | |
837 | rx_int0_7_mix_mux_text); | |
838 | ||
839 | static const struct soc_enum rx_int8_2_mux_chain_enum = | |
840 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9, | |
841 | rx_int_mix_mux_text); | |
842 | ||
843 | static const struct soc_enum rx_int0_1_mix_inp0_chain_enum = | |
844 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13, | |
845 | rx_prim_mix_text); | |
846 | ||
847 | static const struct soc_enum rx_int0_1_mix_inp1_chain_enum = | |
848 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13, | |
849 | rx_prim_mix_text); | |
850 | ||
851 | static const struct soc_enum rx_int0_1_mix_inp2_chain_enum = | |
852 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13, | |
853 | rx_prim_mix_text); | |
854 | ||
855 | static const struct soc_enum rx_int1_1_mix_inp0_chain_enum = | |
856 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13, | |
857 | rx_prim_mix_text); | |
858 | ||
859 | static const struct soc_enum rx_int1_1_mix_inp1_chain_enum = | |
860 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13, | |
861 | rx_prim_mix_text); | |
862 | ||
863 | static const struct soc_enum rx_int1_1_mix_inp2_chain_enum = | |
864 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13, | |
865 | rx_prim_mix_text); | |
866 | ||
867 | static const struct soc_enum rx_int2_1_mix_inp0_chain_enum = | |
868 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13, | |
869 | rx_prim_mix_text); | |
870 | ||
871 | static const struct soc_enum rx_int2_1_mix_inp1_chain_enum = | |
872 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13, | |
873 | rx_prim_mix_text); | |
874 | ||
875 | static const struct soc_enum rx_int2_1_mix_inp2_chain_enum = | |
876 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13, | |
877 | rx_prim_mix_text); | |
878 | ||
879 | static const struct soc_enum rx_int3_1_mix_inp0_chain_enum = | |
880 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13, | |
881 | rx_prim_mix_text); | |
882 | ||
883 | static const struct soc_enum rx_int3_1_mix_inp1_chain_enum = | |
884 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13, | |
885 | rx_prim_mix_text); | |
886 | ||
887 | static const struct soc_enum rx_int3_1_mix_inp2_chain_enum = | |
888 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13, | |
889 | rx_prim_mix_text); | |
890 | ||
891 | static const struct soc_enum rx_int4_1_mix_inp0_chain_enum = | |
892 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13, | |
893 | rx_prim_mix_text); | |
894 | ||
895 | static const struct soc_enum rx_int4_1_mix_inp1_chain_enum = | |
896 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13, | |
897 | rx_prim_mix_text); | |
898 | ||
899 | static const struct soc_enum rx_int4_1_mix_inp2_chain_enum = | |
900 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13, | |
901 | rx_prim_mix_text); | |
902 | ||
903 | static const struct soc_enum rx_int7_1_mix_inp0_chain_enum = | |
904 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13, | |
905 | rx_prim_mix_text); | |
906 | ||
907 | static const struct soc_enum rx_int7_1_mix_inp1_chain_enum = | |
908 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13, | |
909 | rx_prim_mix_text); | |
910 | ||
911 | static const struct soc_enum rx_int7_1_mix_inp2_chain_enum = | |
912 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13, | |
913 | rx_prim_mix_text); | |
914 | ||
915 | static const struct soc_enum rx_int8_1_mix_inp0_chain_enum = | |
916 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13, | |
917 | rx_prim_mix_text); | |
918 | ||
919 | static const struct soc_enum rx_int8_1_mix_inp1_chain_enum = | |
920 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13, | |
921 | rx_prim_mix_text); | |
922 | ||
923 | static const struct soc_enum rx_int8_1_mix_inp2_chain_enum = | |
924 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13, | |
925 | rx_prim_mix_text); | |
926 | ||
927 | static const struct soc_enum rx_int0_mix2_inp_mux_enum = | |
928 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0, 4, | |
929 | rx_sidetone_mix_text); | |
930 | ||
931 | static const struct soc_enum rx_int1_mix2_inp_mux_enum = | |
932 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 4, | |
933 | rx_sidetone_mix_text); | |
934 | ||
935 | static const struct soc_enum rx_int2_mix2_inp_mux_enum = | |
936 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, 4, | |
937 | rx_sidetone_mix_text); | |
938 | ||
939 | static const struct soc_enum rx_int3_mix2_inp_mux_enum = | |
940 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, 4, | |
941 | rx_sidetone_mix_text); | |
942 | ||
943 | static const struct soc_enum rx_int4_mix2_inp_mux_enum = | |
944 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0, 4, | |
945 | rx_sidetone_mix_text); | |
946 | ||
947 | static const struct soc_enum rx_int7_mix2_inp_mux_enum = | |
948 | SOC_ENUM_SINGLE(WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2, 4, | |
949 | rx_sidetone_mix_text); | |
950 | ||
951 | static const struct soc_enum iir0_inp0_mux_enum = | |
952 | SOC_ENUM_SINGLE(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, | |
953 | 0, 18, iir_inp_mux_text); | |
954 | ||
955 | static const struct soc_enum iir0_inp1_mux_enum = | |
956 | SOC_ENUM_SINGLE(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, | |
957 | 0, 18, iir_inp_mux_text); | |
958 | ||
959 | static const struct soc_enum iir0_inp2_mux_enum = | |
960 | SOC_ENUM_SINGLE(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, | |
961 | 0, 18, iir_inp_mux_text); | |
962 | ||
963 | static const struct soc_enum iir0_inp3_mux_enum = | |
964 | SOC_ENUM_SINGLE(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, | |
965 | 0, 18, iir_inp_mux_text); | |
966 | ||
967 | static const struct soc_enum iir1_inp0_mux_enum = | |
968 | SOC_ENUM_SINGLE(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0, | |
969 | 0, 18, iir_inp_mux_text); | |
970 | ||
971 | static const struct soc_enum iir1_inp1_mux_enum = | |
972 | SOC_ENUM_SINGLE(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1, | |
973 | 0, 18, iir_inp_mux_text); | |
974 | ||
975 | static const struct soc_enum iir1_inp2_mux_enum = | |
976 | SOC_ENUM_SINGLE(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2, | |
977 | 0, 18, iir_inp_mux_text); | |
978 | ||
979 | static const struct soc_enum iir1_inp3_mux_enum = | |
980 | SOC_ENUM_SINGLE(WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3, | |
981 | 0, 18, iir_inp_mux_text); | |
982 | ||
983 | static const struct soc_enum rx_int0_dem_inp_mux_enum = | |
984 | SOC_ENUM_SINGLE(WCD934X_CDC_RX0_RX_PATH_SEC0, 0, | |
985 | ARRAY_SIZE(rx_int_dem_inp_mux_text), | |
986 | rx_int_dem_inp_mux_text); | |
987 | ||
988 | static const struct soc_enum rx_int1_dem_inp_mux_enum = | |
989 | SOC_ENUM_SINGLE(WCD934X_CDC_RX1_RX_PATH_SEC0, 0, | |
990 | ARRAY_SIZE(rx_int_dem_inp_mux_text), | |
991 | rx_int_dem_inp_mux_text); | |
992 | ||
993 | static const struct soc_enum rx_int2_dem_inp_mux_enum = | |
994 | SOC_ENUM_SINGLE(WCD934X_CDC_RX2_RX_PATH_SEC0, 0, | |
995 | ARRAY_SIZE(rx_int_dem_inp_mux_text), | |
996 | rx_int_dem_inp_mux_text); | |
a70d9245 SK |
997 | |
998 | static const struct soc_enum tx_adc_mux0_enum = | |
999 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, | |
1000 | ARRAY_SIZE(adc_mux_text), adc_mux_text); | |
1001 | static const struct soc_enum tx_adc_mux1_enum = | |
1002 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, | |
1003 | ARRAY_SIZE(adc_mux_text), adc_mux_text); | |
1004 | static const struct soc_enum tx_adc_mux2_enum = | |
1005 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, | |
1006 | ARRAY_SIZE(adc_mux_text), adc_mux_text); | |
1007 | static const struct soc_enum tx_adc_mux3_enum = | |
1008 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, | |
1009 | ARRAY_SIZE(adc_mux_text), adc_mux_text); | |
1010 | static const struct soc_enum tx_adc_mux4_enum = | |
1011 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 2, | |
1012 | ARRAY_SIZE(adc_mux_text), adc_mux_text); | |
1013 | static const struct soc_enum tx_adc_mux5_enum = | |
1014 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 2, | |
1015 | ARRAY_SIZE(adc_mux_text), adc_mux_text); | |
1016 | static const struct soc_enum tx_adc_mux6_enum = | |
1017 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 2, | |
1018 | ARRAY_SIZE(adc_mux_text), adc_mux_text); | |
1019 | static const struct soc_enum tx_adc_mux7_enum = | |
1020 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 2, | |
1021 | ARRAY_SIZE(adc_mux_text), adc_mux_text); | |
1022 | static const struct soc_enum tx_adc_mux8_enum = | |
1023 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 4, | |
1024 | ARRAY_SIZE(adc_mux_text), adc_mux_text); | |
1025 | ||
dd9eb19b SK |
1026 | static const struct soc_enum rx_int0_1_interp_mux_enum = |
1027 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, | |
1028 | rx_int0_1_interp_mux_text); | |
1029 | ||
1030 | static const struct soc_enum rx_int1_1_interp_mux_enum = | |
1031 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, | |
1032 | rx_int1_1_interp_mux_text); | |
1033 | ||
1034 | static const struct soc_enum rx_int2_1_interp_mux_enum = | |
1035 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, | |
1036 | rx_int2_1_interp_mux_text); | |
1037 | ||
1038 | static const struct soc_enum rx_int3_1_interp_mux_enum = | |
1039 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int3_1_interp_mux_text); | |
1040 | ||
1041 | static const struct soc_enum rx_int4_1_interp_mux_enum = | |
1042 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int4_1_interp_mux_text); | |
1043 | ||
1044 | static const struct soc_enum rx_int7_1_interp_mux_enum = | |
1045 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int7_1_interp_mux_text); | |
1046 | ||
1047 | static const struct soc_enum rx_int8_1_interp_mux_enum = | |
1048 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int8_1_interp_mux_text); | |
1049 | ||
1050 | static const struct soc_enum rx_int0_2_interp_mux_enum = | |
1051 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int0_2_interp_mux_text); | |
1052 | ||
1053 | static const struct soc_enum rx_int1_2_interp_mux_enum = | |
1054 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int1_2_interp_mux_text); | |
1055 | ||
1056 | static const struct soc_enum rx_int2_2_interp_mux_enum = | |
1057 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int2_2_interp_mux_text); | |
1058 | ||
1059 | static const struct soc_enum rx_int3_2_interp_mux_enum = | |
1060 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int3_2_interp_mux_text); | |
1061 | ||
1062 | static const struct soc_enum rx_int4_2_interp_mux_enum = | |
1063 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int4_2_interp_mux_text); | |
1064 | ||
1065 | static const struct soc_enum rx_int7_2_interp_mux_enum = | |
1066 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int7_2_interp_mux_text); | |
1067 | ||
1068 | static const struct soc_enum rx_int8_2_interp_mux_enum = | |
1069 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_int8_2_interp_mux_text); | |
1070 | ||
a70d9245 SK |
1071 | static const struct soc_enum tx_dmic_mux0_enum = |
1072 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 7, | |
1073 | dmic_mux_text); | |
1074 | ||
1075 | static const struct soc_enum tx_dmic_mux1_enum = | |
1076 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 7, | |
1077 | dmic_mux_text); | |
1078 | ||
1079 | static const struct soc_enum tx_dmic_mux2_enum = | |
1080 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 7, | |
1081 | dmic_mux_text); | |
1082 | ||
1083 | static const struct soc_enum tx_dmic_mux3_enum = | |
1084 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 7, | |
1085 | dmic_mux_text); | |
1086 | ||
1087 | static const struct soc_enum tx_dmic_mux4_enum = | |
1088 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7, | |
1089 | dmic_mux_text); | |
1090 | ||
1091 | static const struct soc_enum tx_dmic_mux5_enum = | |
1092 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7, | |
1093 | dmic_mux_text); | |
1094 | ||
1095 | static const struct soc_enum tx_dmic_mux6_enum = | |
1096 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7, | |
1097 | dmic_mux_text); | |
1098 | ||
1099 | static const struct soc_enum tx_dmic_mux7_enum = | |
1100 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7, | |
1101 | dmic_mux_text); | |
1102 | ||
1103 | static const struct soc_enum tx_dmic_mux8_enum = | |
1104 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7, | |
1105 | dmic_mux_text); | |
1106 | ||
1107 | static const struct soc_enum tx_amic_mux0_enum = | |
1108 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 5, | |
1109 | amic_mux_text); | |
1110 | static const struct soc_enum tx_amic_mux1_enum = | |
1111 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 5, | |
1112 | amic_mux_text); | |
1113 | static const struct soc_enum tx_amic_mux2_enum = | |
1114 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 5, | |
1115 | amic_mux_text); | |
1116 | static const struct soc_enum tx_amic_mux3_enum = | |
1117 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 5, | |
1118 | amic_mux_text); | |
1119 | static const struct soc_enum tx_amic_mux4_enum = | |
1120 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 5, | |
1121 | amic_mux_text); | |
1122 | static const struct soc_enum tx_amic_mux5_enum = | |
1123 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 5, | |
1124 | amic_mux_text); | |
1125 | static const struct soc_enum tx_amic_mux6_enum = | |
1126 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 5, | |
1127 | amic_mux_text); | |
1128 | static const struct soc_enum tx_amic_mux7_enum = | |
1129 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 5, | |
1130 | amic_mux_text); | |
1131 | static const struct soc_enum tx_amic_mux8_enum = | |
1132 | SOC_ENUM_SINGLE(WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 5, | |
1133 | amic_mux_text); | |
1134 | ||
1135 | static const struct soc_enum tx_amic4_5_enum = | |
1136 | SOC_ENUM_SINGLE(WCD934X_TX_NEW_AMIC_4_5_SEL, 7, 2, amic4_5_sel_text); | |
1137 | ||
1138 | static const struct soc_enum cdc_if_tx0_mux_enum = | |
1139 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0, 0, | |
1140 | ARRAY_SIZE(cdc_if_tx0_mux_text), cdc_if_tx0_mux_text); | |
1141 | static const struct soc_enum cdc_if_tx1_mux_enum = | |
1142 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0, 2, | |
1143 | ARRAY_SIZE(cdc_if_tx1_mux_text), cdc_if_tx1_mux_text); | |
1144 | static const struct soc_enum cdc_if_tx2_mux_enum = | |
1145 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0, 4, | |
1146 | ARRAY_SIZE(cdc_if_tx2_mux_text), cdc_if_tx2_mux_text); | |
1147 | static const struct soc_enum cdc_if_tx3_mux_enum = | |
1148 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0, 6, | |
1149 | ARRAY_SIZE(cdc_if_tx3_mux_text), cdc_if_tx3_mux_text); | |
1150 | static const struct soc_enum cdc_if_tx4_mux_enum = | |
1151 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1, 0, | |
1152 | ARRAY_SIZE(cdc_if_tx4_mux_text), cdc_if_tx4_mux_text); | |
1153 | static const struct soc_enum cdc_if_tx5_mux_enum = | |
1154 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1, 2, | |
1155 | ARRAY_SIZE(cdc_if_tx5_mux_text), cdc_if_tx5_mux_text); | |
1156 | static const struct soc_enum cdc_if_tx6_mux_enum = | |
1157 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1, 4, | |
1158 | ARRAY_SIZE(cdc_if_tx6_mux_text), cdc_if_tx6_mux_text); | |
1159 | static const struct soc_enum cdc_if_tx7_mux_enum = | |
1160 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1, 6, | |
1161 | ARRAY_SIZE(cdc_if_tx7_mux_text), cdc_if_tx7_mux_text); | |
1162 | static const struct soc_enum cdc_if_tx8_mux_enum = | |
1163 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2, 0, | |
1164 | ARRAY_SIZE(cdc_if_tx8_mux_text), cdc_if_tx8_mux_text); | |
1165 | static const struct soc_enum cdc_if_tx9_mux_enum = | |
1166 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2, 2, | |
1167 | ARRAY_SIZE(cdc_if_tx9_mux_text), cdc_if_tx9_mux_text); | |
1168 | static const struct soc_enum cdc_if_tx10_mux_enum = | |
1169 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2, 4, | |
1170 | ARRAY_SIZE(cdc_if_tx10_mux_text), cdc_if_tx10_mux_text); | |
1171 | static const struct soc_enum cdc_if_tx11_inp1_mux_enum = | |
1172 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3, 0, | |
1173 | ARRAY_SIZE(cdc_if_tx11_inp1_mux_text), | |
1174 | cdc_if_tx11_inp1_mux_text); | |
1175 | static const struct soc_enum cdc_if_tx11_mux_enum = | |
1176 | SOC_ENUM_SINGLE(WCD934X_DATA_HUB_SB_TX11_INP_CFG, 0, | |
1177 | ARRAY_SIZE(cdc_if_tx11_mux_text), cdc_if_tx11_mux_text); | |
1178 | static const struct soc_enum cdc_if_tx13_inp1_mux_enum = | |
1179 | SOC_ENUM_SINGLE(WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3, 4, | |
1180 | ARRAY_SIZE(cdc_if_tx13_inp1_mux_text), | |
1181 | cdc_if_tx13_inp1_mux_text); | |
1182 | static const struct soc_enum cdc_if_tx13_mux_enum = | |
1183 | SOC_ENUM_SINGLE(WCD934X_DATA_HUB_SB_TX13_INP_CFG, 0, | |
1184 | ARRAY_SIZE(cdc_if_tx13_mux_text), cdc_if_tx13_mux_text); | |
1185 | ||
1186 | static int wcd934x_set_sido_input_src(struct wcd934x_codec *wcd, int sido_src) | |
a61f3b4f SK |
1187 | { |
1188 | if (sido_src == wcd->sido_input_src) | |
1189 | return 0; | |
1190 | ||
1191 | if (sido_src == SIDO_SOURCE_INTERNAL) { | |
1192 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL, | |
1193 | WCD934X_ANA_BUCK_HI_ACCU_EN_MASK, 0); | |
1194 | usleep_range(100, 110); | |
1195 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL, | |
1196 | WCD934X_ANA_BUCK_HI_ACCU_PRE_ENX_MASK, 0x0); | |
1197 | usleep_range(100, 110); | |
1198 | regmap_update_bits(wcd->regmap, WCD934X_ANA_RCO, | |
1199 | WCD934X_ANA_RCO_BG_EN_MASK, 0); | |
1200 | usleep_range(100, 110); | |
a61f3b4f SK |
1201 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL, |
1202 | WCD934X_ANA_BUCK_PRE_EN1_MASK, | |
1203 | WCD934X_ANA_BUCK_PRE_EN1_ENABLE); | |
1204 | usleep_range(100, 110); | |
1205 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL, | |
1206 | WCD934X_ANA_BUCK_PRE_EN2_MASK, | |
1207 | WCD934X_ANA_BUCK_PRE_EN2_ENABLE); | |
1208 | usleep_range(100, 110); | |
1209 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL, | |
1210 | WCD934X_ANA_BUCK_HI_ACCU_EN_MASK, | |
1211 | WCD934X_ANA_BUCK_HI_ACCU_ENABLE); | |
1212 | usleep_range(100, 110); | |
820766c1 SK |
1213 | } else if (sido_src == SIDO_SOURCE_RCO_BG) { |
1214 | regmap_update_bits(wcd->regmap, WCD934X_ANA_RCO, | |
1215 | WCD934X_ANA_RCO_BG_EN_MASK, | |
1216 | WCD934X_ANA_RCO_BG_ENABLE); | |
1217 | usleep_range(100, 110); | |
a61f3b4f SK |
1218 | } |
1219 | wcd->sido_input_src = sido_src; | |
1220 | ||
1221 | return 0; | |
1222 | } | |
1223 | ||
1224 | static int wcd934x_enable_ana_bias_and_sysclk(struct wcd934x_codec *wcd) | |
1225 | { | |
1226 | mutex_lock(&wcd->sysclk_mutex); | |
1227 | ||
1228 | if (++wcd->sysclk_users != 1) { | |
1229 | mutex_unlock(&wcd->sysclk_mutex); | |
1230 | return 0; | |
1231 | } | |
1232 | mutex_unlock(&wcd->sysclk_mutex); | |
1233 | ||
1234 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS, | |
1235 | WCD934X_ANA_BIAS_EN_MASK, | |
1236 | WCD934X_ANA_BIAS_EN); | |
1237 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS, | |
1238 | WCD934X_ANA_PRECHRG_EN_MASK, | |
1239 | WCD934X_ANA_PRECHRG_EN); | |
1240 | /* | |
1241 | * 1ms delay is required after pre-charge is enabled | |
1242 | * as per HW requirement | |
1243 | */ | |
1244 | usleep_range(1000, 1100); | |
1245 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS, | |
1246 | WCD934X_ANA_PRECHRG_EN_MASK, 0); | |
1247 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS, | |
1248 | WCD934X_ANA_PRECHRG_MODE_MASK, 0); | |
1249 | ||
1250 | /* | |
1251 | * In data clock contrl register is changed | |
1252 | * to CLK_SYS_MCLK_PRG | |
1253 | */ | |
1254 | ||
1255 | regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG, | |
1256 | WCD934X_EXT_CLK_BUF_EN_MASK, | |
1257 | WCD934X_EXT_CLK_BUF_EN); | |
1258 | regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG, | |
1259 | WCD934X_EXT_CLK_DIV_RATIO_MASK, | |
1260 | WCD934X_EXT_CLK_DIV_BY_2); | |
1261 | regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG, | |
1262 | WCD934X_MCLK_SRC_MASK, | |
1263 | WCD934X_MCLK_SRC_EXT_CLK); | |
1264 | regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG, | |
1265 | WCD934X_MCLK_EN_MASK, WCD934X_MCLK_EN); | |
1266 | regmap_update_bits(wcd->regmap, | |
1267 | WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, | |
1268 | WCD934X_CDC_FS_MCLK_CNT_EN_MASK, | |
1269 | WCD934X_CDC_FS_MCLK_CNT_ENABLE); | |
1270 | regmap_update_bits(wcd->regmap, | |
1271 | WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL, | |
1272 | WCD934X_MCLK_EN_MASK, | |
1273 | WCD934X_MCLK_EN); | |
1274 | regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_GATE, | |
1275 | WCD934X_CODEC_RPM_CLK_GATE_MASK, 0x0); | |
1276 | /* | |
1277 | * 10us sleep is required after clock is enabled | |
1278 | * as per HW requirement | |
1279 | */ | |
1280 | usleep_range(10, 15); | |
1281 | ||
1282 | wcd934x_set_sido_input_src(wcd, SIDO_SOURCE_RCO_BG); | |
1283 | ||
1284 | return 0; | |
1285 | } | |
1286 | ||
1287 | static int wcd934x_disable_ana_bias_and_syclk(struct wcd934x_codec *wcd) | |
1288 | { | |
1289 | mutex_lock(&wcd->sysclk_mutex); | |
1290 | if (--wcd->sysclk_users != 0) { | |
1291 | mutex_unlock(&wcd->sysclk_mutex); | |
1292 | return 0; | |
1293 | } | |
1294 | mutex_unlock(&wcd->sysclk_mutex); | |
1295 | ||
1296 | regmap_update_bits(wcd->regmap, WCD934X_CLK_SYS_MCLK_PRG, | |
1297 | WCD934X_EXT_CLK_BUF_EN_MASK | | |
1298 | WCD934X_MCLK_EN_MASK, 0x0); | |
1299 | wcd934x_set_sido_input_src(wcd, SIDO_SOURCE_INTERNAL); | |
1300 | ||
1301 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS, | |
1302 | WCD934X_ANA_BIAS_EN_MASK, 0); | |
1303 | regmap_update_bits(wcd->regmap, WCD934X_ANA_BIAS, | |
1304 | WCD934X_ANA_PRECHRG_EN_MASK, 0); | |
1305 | ||
1306 | return 0; | |
1307 | } | |
1308 | ||
1309 | static int __wcd934x_cdc_mclk_enable(struct wcd934x_codec *wcd, bool enable) | |
1310 | { | |
1311 | int ret = 0; | |
1312 | ||
1313 | if (enable) { | |
1314 | ret = clk_prepare_enable(wcd->extclk); | |
1315 | ||
1316 | if (ret) { | |
1317 | dev_err(wcd->dev, "%s: ext clk enable failed\n", | |
1318 | __func__); | |
1319 | return ret; | |
1320 | } | |
1321 | ret = wcd934x_enable_ana_bias_and_sysclk(wcd); | |
1322 | } else { | |
1323 | int val; | |
1324 | ||
1325 | regmap_read(wcd->regmap, WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL, | |
1326 | &val); | |
1327 | ||
1328 | /* Don't disable clock if soundwire using it.*/ | |
1329 | if (val & WCD934X_CDC_SWR_CLK_EN_MASK) | |
1330 | return 0; | |
1331 | ||
1332 | wcd934x_disable_ana_bias_and_syclk(wcd); | |
1333 | clk_disable_unprepare(wcd->extclk); | |
1334 | } | |
1335 | ||
1336 | return ret; | |
1337 | } | |
1338 | ||
dd9eb19b SK |
1339 | static int wcd934x_codec_enable_mclk(struct snd_soc_dapm_widget *w, |
1340 | struct snd_kcontrol *kc, int event) | |
1341 | { | |
1342 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
1343 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
1344 | ||
1345 | switch (event) { | |
1346 | case SND_SOC_DAPM_PRE_PMU: | |
1347 | return __wcd934x_cdc_mclk_enable(wcd, true); | |
1348 | case SND_SOC_DAPM_POST_PMD: | |
1349 | return __wcd934x_cdc_mclk_enable(wcd, false); | |
1350 | } | |
1351 | ||
1352 | return 0; | |
1353 | } | |
1354 | ||
a61f3b4f SK |
1355 | static int wcd934x_get_version(struct wcd934x_codec *wcd) |
1356 | { | |
1357 | int val1, val2, ver, ret; | |
1358 | struct regmap *regmap; | |
1359 | u16 id_minor; | |
1360 | u32 version_mask = 0; | |
1361 | ||
1362 | regmap = wcd->regmap; | |
1363 | ver = 0; | |
1364 | ||
1365 | ret = regmap_bulk_read(regmap, WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0, | |
1366 | (u8 *)&id_minor, sizeof(u16)); | |
1367 | ||
1368 | if (ret) | |
1369 | return ret; | |
1370 | ||
1371 | regmap_read(regmap, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14, &val1); | |
1372 | regmap_read(regmap, WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT15, &val2); | |
1373 | ||
1374 | version_mask |= (!!((u8)val1 & 0x80)) << DSD_DISABLED_MASK; | |
1375 | version_mask |= (!!((u8)val2 & 0x01)) << SLNQ_DISABLED_MASK; | |
1376 | ||
1377 | switch (version_mask) { | |
1378 | case DSD_DISABLED | SLNQ_DISABLED: | |
1379 | if (id_minor == 0) | |
1380 | ver = WCD_VERSION_WCD9340_1_0; | |
1381 | else if (id_minor == 0x01) | |
1382 | ver = WCD_VERSION_WCD9340_1_1; | |
1383 | break; | |
1384 | case SLNQ_DISABLED: | |
1385 | if (id_minor == 0) | |
1386 | ver = WCD_VERSION_WCD9341_1_0; | |
1387 | else if (id_minor == 0x01) | |
1388 | ver = WCD_VERSION_WCD9341_1_1; | |
1389 | break; | |
1390 | } | |
1391 | ||
1392 | wcd->version = ver; | |
1393 | dev_info(wcd->dev, "WCD934X Minor:0x%x Version:0x%x\n", id_minor, ver); | |
1394 | ||
1395 | return 0; | |
1396 | } | |
1397 | ||
1398 | static void wcd934x_enable_efuse_sensing(struct wcd934x_codec *wcd) | |
1399 | { | |
1400 | int rc, val; | |
1401 | ||
1402 | __wcd934x_cdc_mclk_enable(wcd, true); | |
1403 | ||
1404 | regmap_update_bits(wcd->regmap, | |
1405 | WCD934X_CHIP_TIER_CTRL_EFUSE_CTL, | |
1406 | WCD934X_EFUSE_SENSE_STATE_MASK, | |
1407 | WCD934X_EFUSE_SENSE_STATE_DEF); | |
1408 | regmap_update_bits(wcd->regmap, | |
1409 | WCD934X_CHIP_TIER_CTRL_EFUSE_CTL, | |
1410 | WCD934X_EFUSE_SENSE_EN_MASK, | |
1411 | WCD934X_EFUSE_SENSE_ENABLE); | |
1412 | /* | |
1413 | * 5ms sleep required after enabling efuse control | |
1414 | * before checking the status. | |
1415 | */ | |
1416 | usleep_range(5000, 5500); | |
1417 | wcd934x_set_sido_input_src(wcd, SIDO_SOURCE_RCO_BG); | |
1418 | ||
1419 | rc = regmap_read(wcd->regmap, | |
1420 | WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS, &val); | |
1421 | if (rc || (!(val & 0x01))) | |
1422 | WARN(1, "%s: Efuse sense is not complete val=%x, ret=%d\n", | |
1423 | __func__, val, rc); | |
1424 | ||
1425 | __wcd934x_cdc_mclk_enable(wcd, false); | |
1426 | } | |
1427 | ||
1428 | static int wcd934x_swrm_clock(struct wcd934x_codec *wcd, bool enable) | |
1429 | { | |
1430 | if (enable) { | |
1431 | __wcd934x_cdc_mclk_enable(wcd, true); | |
1432 | regmap_update_bits(wcd->regmap, | |
1433 | WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL, | |
1434 | WCD934X_CDC_SWR_CLK_EN_MASK, | |
1435 | WCD934X_CDC_SWR_CLK_ENABLE); | |
1436 | } else { | |
1437 | regmap_update_bits(wcd->regmap, | |
1438 | WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL, | |
1439 | WCD934X_CDC_SWR_CLK_EN_MASK, 0); | |
1440 | __wcd934x_cdc_mclk_enable(wcd, false); | |
1441 | } | |
1442 | ||
1443 | return 0; | |
1444 | } | |
1445 | ||
1446 | static int wcd934x_set_prim_interpolator_rate(struct snd_soc_dai *dai, | |
1447 | u8 rate_val, u32 rate) | |
1448 | { | |
1449 | struct snd_soc_component *comp = dai->component; | |
1450 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
1451 | struct wcd934x_slim_ch *ch; | |
1452 | u8 cfg0, cfg1, inp0_sel, inp1_sel, inp2_sel; | |
1453 | int inp, j; | |
1454 | ||
1455 | list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) { | |
1456 | inp = ch->shift + INTn_1_INP_SEL_RX0; | |
1457 | /* | |
1458 | * Loop through all interpolator MUX inputs and find out | |
1459 | * to which interpolator input, the slim rx port | |
1460 | * is connected | |
1461 | */ | |
1462 | for (j = 0; j < WCD934X_NUM_INTERPOLATORS; j++) { | |
1463 | /* Interpolators 5 and 6 are not aviliable in Tavil */ | |
1464 | if (j == INTERP_LO3_NA || j == INTERP_LO4_NA) | |
1465 | continue; | |
1466 | ||
eaf2767c | 1467 | cfg0 = snd_soc_component_read(comp, |
a61f3b4f | 1468 | WCD934X_CDC_RX_INP_MUX_RX_INT_CFG0(j)); |
eaf2767c | 1469 | cfg1 = snd_soc_component_read(comp, |
a61f3b4f SK |
1470 | WCD934X_CDC_RX_INP_MUX_RX_INT_CFG1(j)); |
1471 | ||
1472 | inp0_sel = cfg0 & | |
1473 | WCD934X_CDC_RX_INP_MUX_RX_INT_SEL_MASK; | |
1474 | inp1_sel = (cfg0 >> 4) & | |
1475 | WCD934X_CDC_RX_INP_MUX_RX_INT_SEL_MASK; | |
1476 | inp2_sel = (cfg1 >> 4) & | |
1477 | WCD934X_CDC_RX_INP_MUX_RX_INT_SEL_MASK; | |
1478 | ||
1479 | if ((inp0_sel == inp) || (inp1_sel == inp) || | |
1480 | (inp2_sel == inp)) { | |
1481 | /* rate is in Hz */ | |
1482 | /* | |
1483 | * Ear and speaker primary path does not support | |
1484 | * native sample rates | |
1485 | */ | |
1486 | if ((j == INTERP_EAR || j == INTERP_SPKR1 || | |
1487 | j == INTERP_SPKR2) && rate == 44100) | |
1488 | dev_err(wcd->dev, | |
1489 | "Cannot set 44.1KHz on INT%d\n", | |
1490 | j); | |
1491 | else | |
1492 | snd_soc_component_update_bits(comp, | |
1493 | WCD934X_CDC_RX_PATH_CTL(j), | |
1494 | WCD934X_CDC_MIX_PCM_RATE_MASK, | |
1495 | rate_val); | |
1496 | } | |
1497 | } | |
1498 | } | |
1499 | ||
1500 | return 0; | |
1501 | } | |
1502 | ||
1503 | static int wcd934x_set_mix_interpolator_rate(struct snd_soc_dai *dai, | |
1504 | int rate_val, u32 rate) | |
1505 | { | |
1506 | struct snd_soc_component *component = dai->component; | |
1507 | struct wcd934x_codec *wcd = dev_get_drvdata(component->dev); | |
1508 | struct wcd934x_slim_ch *ch; | |
1509 | int val, j; | |
1510 | ||
1511 | list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) { | |
1512 | for (j = 0; j < WCD934X_NUM_INTERPOLATORS; j++) { | |
1513 | /* Interpolators 5 and 6 are not aviliable in Tavil */ | |
1514 | if (j == INTERP_LO3_NA || j == INTERP_LO4_NA) | |
1515 | continue; | |
eaf2767c | 1516 | val = snd_soc_component_read(component, |
a61f3b4f SK |
1517 | WCD934X_CDC_RX_INP_MUX_RX_INT_CFG1(j)) & |
1518 | WCD934X_CDC_RX_INP_MUX_RX_INT_SEL_MASK; | |
1519 | ||
1520 | if (val == (ch->shift + INTn_2_INP_SEL_RX0)) { | |
1521 | /* | |
1522 | * Ear mix path supports only 48, 96, 192, | |
1523 | * 384KHz only | |
1524 | */ | |
1525 | if ((j == INTERP_EAR) && | |
1526 | (rate_val < 0x4 || | |
1527 | rate_val > 0x7)) { | |
1528 | dev_err(component->dev, | |
1529 | "Invalid rate for AIF_PB DAI(%d)\n", | |
1530 | dai->id); | |
1531 | return -EINVAL; | |
1532 | } | |
1533 | ||
1534 | snd_soc_component_update_bits(component, | |
1535 | WCD934X_CDC_RX_PATH_MIX_CTL(j), | |
1536 | WCD934X_CDC_MIX_PCM_RATE_MASK, | |
1537 | rate_val); | |
1538 | } | |
1539 | } | |
1540 | } | |
1541 | ||
1542 | return 0; | |
1543 | } | |
1544 | ||
1545 | static int wcd934x_set_interpolator_rate(struct snd_soc_dai *dai, | |
1546 | u32 sample_rate) | |
1547 | { | |
1548 | int rate_val = 0; | |
1549 | int i, ret; | |
1550 | ||
1551 | for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) { | |
1552 | if (sample_rate == sr_val_tbl[i].sample_rate) { | |
1553 | rate_val = sr_val_tbl[i].rate_val; | |
1554 | break; | |
1555 | } | |
1556 | } | |
1557 | if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) { | |
1558 | dev_err(dai->dev, "Unsupported sample rate: %d\n", sample_rate); | |
1559 | return -EINVAL; | |
1560 | } | |
1561 | ||
1562 | ret = wcd934x_set_prim_interpolator_rate(dai, (u8)rate_val, | |
1563 | sample_rate); | |
1564 | if (ret) | |
1565 | return ret; | |
1566 | ret = wcd934x_set_mix_interpolator_rate(dai, (u8)rate_val, | |
1567 | sample_rate); | |
a61f3b4f SK |
1568 | |
1569 | return ret; | |
1570 | } | |
1571 | ||
1572 | static int wcd934x_set_decimator_rate(struct snd_soc_dai *dai, | |
1573 | u8 rate_val, u32 rate) | |
1574 | { | |
1575 | struct snd_soc_component *comp = dai->component; | |
1576 | struct wcd934x_codec *wcd = snd_soc_component_get_drvdata(comp); | |
1577 | u8 shift = 0, shift_val = 0, tx_mux_sel; | |
1578 | struct wcd934x_slim_ch *ch; | |
1579 | int tx_port, tx_port_reg; | |
1580 | int decimator = -1; | |
1581 | ||
1582 | list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) { | |
1583 | tx_port = ch->port; | |
1584 | /* Find the SB TX MUX input - which decimator is connected */ | |
1585 | switch (tx_port) { | |
1586 | case 0 ... 3: | |
1587 | tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0; | |
1588 | shift = (tx_port << 1); | |
1589 | shift_val = 0x03; | |
1590 | break; | |
1591 | case 4 ... 7: | |
1592 | tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1; | |
1593 | shift = ((tx_port - 4) << 1); | |
1594 | shift_val = 0x03; | |
1595 | break; | |
1596 | case 8 ... 10: | |
1597 | tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2; | |
1598 | shift = ((tx_port - 8) << 1); | |
1599 | shift_val = 0x03; | |
1600 | break; | |
1601 | case 11: | |
1602 | tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3; | |
1603 | shift = 0; | |
1604 | shift_val = 0x0F; | |
1605 | break; | |
1606 | case 13: | |
1607 | tx_port_reg = WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3; | |
1608 | shift = 4; | |
1609 | shift_val = 0x03; | |
1610 | break; | |
1611 | default: | |
1612 | dev_err(wcd->dev, "Invalid SLIM TX%u port DAI ID:%d\n", | |
1613 | tx_port, dai->id); | |
1614 | return -EINVAL; | |
1615 | } | |
1616 | ||
eaf2767c | 1617 | tx_mux_sel = snd_soc_component_read(comp, tx_port_reg) & |
a61f3b4f SK |
1618 | (shift_val << shift); |
1619 | ||
1620 | tx_mux_sel = tx_mux_sel >> shift; | |
1621 | switch (tx_port) { | |
1622 | case 0 ... 8: | |
1623 | if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3)) | |
1624 | decimator = tx_port; | |
1625 | break; | |
1626 | case 9 ... 10: | |
1627 | if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) | |
1628 | decimator = ((tx_port == 9) ? 7 : 6); | |
1629 | break; | |
1630 | case 11: | |
1631 | if ((tx_mux_sel >= 1) && (tx_mux_sel < 7)) | |
1632 | decimator = tx_mux_sel - 1; | |
1633 | break; | |
1634 | case 13: | |
1635 | if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) | |
1636 | decimator = 5; | |
1637 | break; | |
1638 | default: | |
1639 | dev_err(wcd->dev, "ERROR: Invalid tx_port: %d\n", | |
1640 | tx_port); | |
1641 | return -EINVAL; | |
1642 | } | |
1643 | ||
1644 | snd_soc_component_update_bits(comp, | |
1645 | WCD934X_CDC_TX_PATH_CTL(decimator), | |
1646 | WCD934X_CDC_TX_PATH_CTL_PCM_RATE_MASK, | |
1647 | rate_val); | |
1648 | } | |
1649 | ||
1650 | return 0; | |
1651 | } | |
1652 | ||
1653 | static int wcd934x_slim_set_hw_params(struct wcd934x_codec *wcd, | |
1654 | struct wcd_slim_codec_dai_data *dai_data, | |
1655 | int direction) | |
1656 | { | |
1657 | struct list_head *slim_ch_list = &dai_data->slim_ch_list; | |
1658 | struct slim_stream_config *cfg = &dai_data->sconfig; | |
1659 | struct wcd934x_slim_ch *ch; | |
1660 | u16 payload = 0; | |
1661 | int ret, i; | |
1662 | ||
1663 | cfg->ch_count = 0; | |
1664 | cfg->direction = direction; | |
1665 | cfg->port_mask = 0; | |
1666 | ||
1667 | /* Configure slave interface device */ | |
1668 | list_for_each_entry(ch, slim_ch_list, list) { | |
1669 | cfg->ch_count++; | |
1670 | payload |= 1 << ch->shift; | |
1671 | cfg->port_mask |= BIT(ch->port); | |
1672 | } | |
1673 | ||
1674 | cfg->chs = kcalloc(cfg->ch_count, sizeof(unsigned int), GFP_KERNEL); | |
1675 | if (!cfg->chs) | |
1676 | return -ENOMEM; | |
1677 | ||
1678 | i = 0; | |
1679 | list_for_each_entry(ch, slim_ch_list, list) { | |
1680 | cfg->chs[i++] = ch->ch_num; | |
1681 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) { | |
1682 | /* write to interface device */ | |
1683 | ret = regmap_write(wcd->if_regmap, | |
1684 | WCD934X_SLIM_PGD_RX_PORT_MULTI_CHNL_0(ch->port), | |
1685 | payload); | |
1686 | ||
1687 | if (ret < 0) | |
1688 | goto err; | |
1689 | ||
1690 | /* configure the slave port for water mark and enable*/ | |
1691 | ret = regmap_write(wcd->if_regmap, | |
1692 | WCD934X_SLIM_PGD_RX_PORT_CFG(ch->port), | |
1693 | WCD934X_SLIM_WATER_MARK_VAL); | |
1694 | if (ret < 0) | |
1695 | goto err; | |
1696 | } else { | |
1697 | ret = regmap_write(wcd->if_regmap, | |
1698 | WCD934X_SLIM_PGD_TX_PORT_MULTI_CHNL_0(ch->port), | |
1699 | payload & 0x00FF); | |
1700 | if (ret < 0) | |
1701 | goto err; | |
1702 | ||
1703 | /* ports 8,9 */ | |
1704 | ret = regmap_write(wcd->if_regmap, | |
1705 | WCD934X_SLIM_PGD_TX_PORT_MULTI_CHNL_1(ch->port), | |
1706 | (payload & 0xFF00) >> 8); | |
1707 | if (ret < 0) | |
1708 | goto err; | |
1709 | ||
1710 | /* configure the slave port for water mark and enable*/ | |
1711 | ret = regmap_write(wcd->if_regmap, | |
1712 | WCD934X_SLIM_PGD_TX_PORT_CFG(ch->port), | |
1713 | WCD934X_SLIM_WATER_MARK_VAL); | |
1714 | ||
1715 | if (ret < 0) | |
1716 | goto err; | |
1717 | } | |
1718 | } | |
1719 | ||
1720 | dai_data->sruntime = slim_stream_allocate(wcd->sdev, "WCD934x-SLIM"); | |
1721 | ||
1722 | return 0; | |
1723 | ||
1724 | err: | |
1725 | dev_err(wcd->dev, "Error Setting slim hw params\n"); | |
1726 | kfree(cfg->chs); | |
1727 | cfg->chs = NULL; | |
1728 | ||
1729 | return ret; | |
1730 | } | |
1731 | ||
1732 | static int wcd934x_hw_params(struct snd_pcm_substream *substream, | |
1733 | struct snd_pcm_hw_params *params, | |
1734 | struct snd_soc_dai *dai) | |
1735 | { | |
1736 | struct wcd934x_codec *wcd; | |
1737 | int ret, tx_fs_rate = 0; | |
1738 | ||
1739 | wcd = snd_soc_component_get_drvdata(dai->component); | |
1740 | ||
1741 | switch (substream->stream) { | |
1742 | case SNDRV_PCM_STREAM_PLAYBACK: | |
1743 | ret = wcd934x_set_interpolator_rate(dai, params_rate(params)); | |
1744 | if (ret) { | |
1745 | dev_err(wcd->dev, "cannot set sample rate: %u\n", | |
1746 | params_rate(params)); | |
1747 | return ret; | |
1748 | } | |
1749 | switch (params_width(params)) { | |
1750 | case 16 ... 24: | |
1751 | wcd->dai[dai->id].sconfig.bps = params_width(params); | |
1752 | break; | |
1753 | default: | |
1754 | dev_err(wcd->dev, "Invalid format 0x%x\n", | |
1755 | params_width(params)); | |
1756 | return -EINVAL; | |
1757 | } | |
1758 | break; | |
1759 | ||
1760 | case SNDRV_PCM_STREAM_CAPTURE: | |
1761 | switch (params_rate(params)) { | |
1762 | case 8000: | |
1763 | tx_fs_rate = 0; | |
1764 | break; | |
1765 | case 16000: | |
1766 | tx_fs_rate = 1; | |
1767 | break; | |
1768 | case 32000: | |
1769 | tx_fs_rate = 3; | |
1770 | break; | |
1771 | case 48000: | |
1772 | tx_fs_rate = 4; | |
1773 | break; | |
1774 | case 96000: | |
1775 | tx_fs_rate = 5; | |
1776 | break; | |
1777 | case 192000: | |
1778 | tx_fs_rate = 6; | |
1779 | break; | |
1780 | case 384000: | |
1781 | tx_fs_rate = 7; | |
1782 | break; | |
1783 | default: | |
1784 | dev_err(wcd->dev, "Invalid TX sample rate: %d\n", | |
1785 | params_rate(params)); | |
1786 | return -EINVAL; | |
1787 | ||
e48e83d1 | 1788 | } |
a61f3b4f SK |
1789 | |
1790 | ret = wcd934x_set_decimator_rate(dai, tx_fs_rate, | |
1791 | params_rate(params)); | |
1792 | if (ret < 0) { | |
1793 | dev_err(wcd->dev, "Cannot set TX Decimator rate\n"); | |
1794 | return ret; | |
1795 | } | |
1796 | switch (params_width(params)) { | |
1797 | case 16 ... 32: | |
1798 | wcd->dai[dai->id].sconfig.bps = params_width(params); | |
1799 | break; | |
1800 | default: | |
1801 | dev_err(wcd->dev, "Invalid format 0x%x\n", | |
1802 | params_width(params)); | |
1803 | return -EINVAL; | |
e48e83d1 | 1804 | } |
a61f3b4f SK |
1805 | break; |
1806 | default: | |
1807 | dev_err(wcd->dev, "Invalid stream type %d\n", | |
1808 | substream->stream); | |
1809 | return -EINVAL; | |
e48e83d1 | 1810 | } |
a61f3b4f SK |
1811 | |
1812 | wcd->dai[dai->id].sconfig.rate = params_rate(params); | |
1813 | wcd934x_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream); | |
1814 | ||
1815 | return 0; | |
1816 | } | |
1817 | ||
1818 | static int wcd934x_hw_free(struct snd_pcm_substream *substream, | |
1819 | struct snd_soc_dai *dai) | |
1820 | { | |
1821 | struct wcd_slim_codec_dai_data *dai_data; | |
1822 | struct wcd934x_codec *wcd; | |
1823 | ||
1824 | wcd = snd_soc_component_get_drvdata(dai->component); | |
1825 | ||
1826 | dai_data = &wcd->dai[dai->id]; | |
1827 | ||
1828 | kfree(dai_data->sconfig.chs); | |
1829 | ||
1830 | return 0; | |
1831 | } | |
1832 | ||
1833 | static int wcd934x_trigger(struct snd_pcm_substream *substream, int cmd, | |
1834 | struct snd_soc_dai *dai) | |
1835 | { | |
1836 | struct wcd_slim_codec_dai_data *dai_data; | |
1837 | struct wcd934x_codec *wcd; | |
1838 | struct slim_stream_config *cfg; | |
1839 | ||
1840 | wcd = snd_soc_component_get_drvdata(dai->component); | |
1841 | ||
1842 | dai_data = &wcd->dai[dai->id]; | |
1843 | ||
1844 | switch (cmd) { | |
1845 | case SNDRV_PCM_TRIGGER_START: | |
1846 | case SNDRV_PCM_TRIGGER_RESUME: | |
1847 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | |
1848 | cfg = &dai_data->sconfig; | |
1849 | slim_stream_prepare(dai_data->sruntime, cfg); | |
1850 | slim_stream_enable(dai_data->sruntime); | |
1851 | break; | |
1852 | case SNDRV_PCM_TRIGGER_STOP: | |
1853 | case SNDRV_PCM_TRIGGER_SUSPEND: | |
1854 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | |
1855 | slim_stream_unprepare(dai_data->sruntime); | |
1856 | slim_stream_disable(dai_data->sruntime); | |
1857 | break; | |
1858 | default: | |
1859 | break; | |
1860 | } | |
1861 | ||
1862 | return 0; | |
1863 | } | |
1864 | ||
1865 | static int wcd934x_set_channel_map(struct snd_soc_dai *dai, | |
1866 | unsigned int tx_num, unsigned int *tx_slot, | |
1867 | unsigned int rx_num, unsigned int *rx_slot) | |
1868 | { | |
1869 | struct wcd934x_codec *wcd; | |
1870 | int i; | |
1871 | ||
1872 | wcd = snd_soc_component_get_drvdata(dai->component); | |
1873 | ||
3bb4852d SK |
1874 | if (tx_num > WCD934X_TX_MAX || rx_num > WCD934X_RX_MAX) { |
1875 | dev_err(wcd->dev, "Invalid tx %d or rx %d channel count\n", | |
1876 | tx_num, rx_num); | |
1877 | return -EINVAL; | |
1878 | } | |
1879 | ||
a61f3b4f SK |
1880 | if (!tx_slot || !rx_slot) { |
1881 | dev_err(wcd->dev, "Invalid tx_slot=%p, rx_slot=%p\n", | |
1882 | tx_slot, rx_slot); | |
1883 | return -EINVAL; | |
1884 | } | |
1885 | ||
918d0aba NC |
1886 | wcd->num_rx_port = rx_num; |
1887 | for (i = 0; i < rx_num; i++) { | |
1888 | wcd->rx_chs[i].ch_num = rx_slot[i]; | |
1889 | INIT_LIST_HEAD(&wcd->rx_chs[i].list); | |
a61f3b4f SK |
1890 | } |
1891 | ||
918d0aba NC |
1892 | wcd->num_tx_port = tx_num; |
1893 | for (i = 0; i < tx_num; i++) { | |
1894 | wcd->tx_chs[i].ch_num = tx_slot[i]; | |
1895 | INIT_LIST_HEAD(&wcd->tx_chs[i].list); | |
a61f3b4f SK |
1896 | } |
1897 | ||
1898 | return 0; | |
1899 | } | |
1900 | ||
1901 | static int wcd934x_get_channel_map(struct snd_soc_dai *dai, | |
1902 | unsigned int *tx_num, unsigned int *tx_slot, | |
1903 | unsigned int *rx_num, unsigned int *rx_slot) | |
1904 | { | |
1905 | struct wcd934x_slim_ch *ch; | |
1906 | struct wcd934x_codec *wcd; | |
1907 | int i = 0; | |
1908 | ||
1909 | wcd = snd_soc_component_get_drvdata(dai->component); | |
1910 | ||
1911 | switch (dai->id) { | |
1912 | case AIF1_PB: | |
1913 | case AIF2_PB: | |
1914 | case AIF3_PB: | |
1915 | case AIF4_PB: | |
1916 | if (!rx_slot || !rx_num) { | |
1917 | dev_err(wcd->dev, "Invalid rx_slot %p or rx_num %p\n", | |
1918 | rx_slot, rx_num); | |
1919 | return -EINVAL; | |
1920 | } | |
1921 | ||
1922 | list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) | |
1923 | rx_slot[i++] = ch->ch_num; | |
1924 | ||
1925 | *rx_num = i; | |
1926 | break; | |
1927 | case AIF1_CAP: | |
1928 | case AIF2_CAP: | |
1929 | case AIF3_CAP: | |
1930 | if (!tx_slot || !tx_num) { | |
1931 | dev_err(wcd->dev, "Invalid tx_slot %p or tx_num %p\n", | |
1932 | tx_slot, tx_num); | |
1933 | return -EINVAL; | |
1934 | } | |
1935 | ||
1936 | list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) | |
1937 | tx_slot[i++] = ch->ch_num; | |
1938 | ||
1939 | *tx_num = i; | |
1940 | break; | |
1941 | default: | |
1942 | dev_err(wcd->dev, "Invalid DAI ID %x\n", dai->id); | |
1943 | break; | |
1944 | } | |
1945 | ||
1946 | return 0; | |
1947 | } | |
1948 | ||
e994cf82 | 1949 | static const struct snd_soc_dai_ops wcd934x_dai_ops = { |
a61f3b4f SK |
1950 | .hw_params = wcd934x_hw_params, |
1951 | .hw_free = wcd934x_hw_free, | |
1952 | .trigger = wcd934x_trigger, | |
1953 | .set_channel_map = wcd934x_set_channel_map, | |
1954 | .get_channel_map = wcd934x_get_channel_map, | |
1955 | }; | |
1956 | ||
1957 | static struct snd_soc_dai_driver wcd934x_slim_dais[] = { | |
1958 | [0] = { | |
1959 | .name = "wcd934x_rx1", | |
1960 | .id = AIF1_PB, | |
1961 | .playback = { | |
1962 | .stream_name = "AIF1 Playback", | |
1963 | .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK, | |
1964 | .formats = WCD934X_FORMATS_S16_S24_LE, | |
1965 | .rate_max = 192000, | |
1966 | .rate_min = 8000, | |
1967 | .channels_min = 1, | |
1968 | .channels_max = 2, | |
1969 | }, | |
1970 | .ops = &wcd934x_dai_ops, | |
1971 | }, | |
1972 | [1] = { | |
1973 | .name = "wcd934x_tx1", | |
1974 | .id = AIF1_CAP, | |
1975 | .capture = { | |
1976 | .stream_name = "AIF1 Capture", | |
1977 | .rates = WCD934X_RATES_MASK, | |
1978 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
1979 | .rate_min = 8000, | |
1980 | .rate_max = 192000, | |
1981 | .channels_min = 1, | |
1982 | .channels_max = 4, | |
1983 | }, | |
1984 | .ops = &wcd934x_dai_ops, | |
1985 | }, | |
1986 | [2] = { | |
1987 | .name = "wcd934x_rx2", | |
1988 | .id = AIF2_PB, | |
1989 | .playback = { | |
1990 | .stream_name = "AIF2 Playback", | |
1991 | .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK, | |
1992 | .formats = WCD934X_FORMATS_S16_S24_LE, | |
1993 | .rate_min = 8000, | |
1994 | .rate_max = 192000, | |
1995 | .channels_min = 1, | |
1996 | .channels_max = 2, | |
1997 | }, | |
1998 | .ops = &wcd934x_dai_ops, | |
1999 | }, | |
2000 | [3] = { | |
2001 | .name = "wcd934x_tx2", | |
2002 | .id = AIF2_CAP, | |
2003 | .capture = { | |
2004 | .stream_name = "AIF2 Capture", | |
2005 | .rates = WCD934X_RATES_MASK, | |
2006 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
2007 | .rate_min = 8000, | |
2008 | .rate_max = 192000, | |
2009 | .channels_min = 1, | |
2010 | .channels_max = 4, | |
2011 | }, | |
2012 | .ops = &wcd934x_dai_ops, | |
2013 | }, | |
2014 | [4] = { | |
2015 | .name = "wcd934x_rx3", | |
2016 | .id = AIF3_PB, | |
2017 | .playback = { | |
2018 | .stream_name = "AIF3 Playback", | |
2019 | .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK, | |
2020 | .formats = WCD934X_FORMATS_S16_S24_LE, | |
2021 | .rate_min = 8000, | |
2022 | .rate_max = 192000, | |
2023 | .channels_min = 1, | |
2024 | .channels_max = 2, | |
2025 | }, | |
2026 | .ops = &wcd934x_dai_ops, | |
2027 | }, | |
2028 | [5] = { | |
2029 | .name = "wcd934x_tx3", | |
2030 | .id = AIF3_CAP, | |
2031 | .capture = { | |
2032 | .stream_name = "AIF3 Capture", | |
2033 | .rates = WCD934X_RATES_MASK, | |
2034 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | |
2035 | .rate_min = 8000, | |
2036 | .rate_max = 192000, | |
2037 | .channels_min = 1, | |
2038 | .channels_max = 4, | |
2039 | }, | |
2040 | .ops = &wcd934x_dai_ops, | |
2041 | }, | |
2042 | [6] = { | |
2043 | .name = "wcd934x_rx4", | |
2044 | .id = AIF4_PB, | |
2045 | .playback = { | |
2046 | .stream_name = "AIF4 Playback", | |
2047 | .rates = WCD934X_RATES_MASK | WCD934X_FRAC_RATES_MASK, | |
2048 | .formats = WCD934X_FORMATS_S16_S24_LE, | |
2049 | .rate_min = 8000, | |
2050 | .rate_max = 192000, | |
2051 | .channels_min = 1, | |
2052 | .channels_max = 2, | |
2053 | }, | |
2054 | .ops = &wcd934x_dai_ops, | |
2055 | }, | |
2056 | }; | |
2057 | ||
2058 | static int swclk_gate_enable(struct clk_hw *hw) | |
2059 | { | |
2060 | return wcd934x_swrm_clock(to_wcd934x_codec(hw), true); | |
2061 | } | |
2062 | ||
2063 | static void swclk_gate_disable(struct clk_hw *hw) | |
2064 | { | |
2065 | wcd934x_swrm_clock(to_wcd934x_codec(hw), false); | |
2066 | } | |
2067 | ||
2068 | static int swclk_gate_is_enabled(struct clk_hw *hw) | |
2069 | { | |
2070 | struct wcd934x_codec *wcd = to_wcd934x_codec(hw); | |
2071 | int ret, val; | |
2072 | ||
2073 | regmap_read(wcd->regmap, WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL, &val); | |
2074 | ret = val & WCD934X_CDC_SWR_CLK_EN_MASK; | |
2075 | ||
2076 | return ret; | |
2077 | } | |
2078 | ||
2079 | static unsigned long swclk_recalc_rate(struct clk_hw *hw, | |
2080 | unsigned long parent_rate) | |
2081 | { | |
2082 | return parent_rate / 2; | |
2083 | } | |
2084 | ||
2085 | static const struct clk_ops swclk_gate_ops = { | |
2086 | .prepare = swclk_gate_enable, | |
2087 | .unprepare = swclk_gate_disable, | |
2088 | .is_enabled = swclk_gate_is_enabled, | |
2089 | .recalc_rate = swclk_recalc_rate, | |
2090 | ||
2091 | }; | |
2092 | ||
2093 | static struct clk *wcd934x_register_mclk_output(struct wcd934x_codec *wcd) | |
2094 | { | |
2095 | struct clk *parent = wcd->extclk; | |
2096 | struct device *dev = wcd->dev; | |
2097 | struct device_node *np = dev->parent->of_node; | |
2098 | const char *parent_clk_name = NULL; | |
2099 | const char *clk_name = "mclk"; | |
2100 | struct clk_hw *hw; | |
2101 | struct clk_init_data init; | |
2102 | int ret; | |
2103 | ||
2104 | if (of_property_read_u32(np, "clock-frequency", &wcd->rate)) | |
2105 | return NULL; | |
2106 | ||
2107 | parent_clk_name = __clk_get_name(parent); | |
2108 | ||
2109 | of_property_read_string(np, "clock-output-names", &clk_name); | |
2110 | ||
2111 | init.name = clk_name; | |
2112 | init.ops = &swclk_gate_ops; | |
2113 | init.flags = 0; | |
2114 | init.parent_names = &parent_clk_name; | |
2115 | init.num_parents = 1; | |
2116 | wcd->hw.init = &init; | |
2117 | ||
2118 | hw = &wcd->hw; | |
2119 | ret = clk_hw_register(wcd->dev->parent, hw); | |
2120 | if (ret) | |
2121 | return ERR_PTR(ret); | |
2122 | ||
2123 | of_clk_add_provider(np, of_clk_src_simple_get, hw->clk); | |
2124 | ||
2125 | return NULL; | |
2126 | } | |
2127 | ||
2128 | static int wcd934x_get_micbias_val(struct device *dev, const char *micbias) | |
2129 | { | |
2130 | int mv; | |
2131 | ||
2132 | if (of_property_read_u32(dev->parent->of_node, micbias, &mv)) { | |
2133 | dev_err(dev, "%s value not found, using default\n", micbias); | |
2134 | mv = WCD934X_DEF_MICBIAS_MV; | |
2135 | } else { | |
2136 | /* convert it to milli volts */ | |
2137 | mv = mv/1000; | |
2138 | } | |
2139 | ||
2140 | if (mv < 1000 || mv > 2850) { | |
2141 | dev_err(dev, "%s value not in valid range, using default\n", | |
2142 | micbias); | |
2143 | mv = WCD934X_DEF_MICBIAS_MV; | |
2144 | } | |
2145 | ||
2146 | return (mv - 1000) / 50; | |
2147 | } | |
2148 | ||
2149 | static int wcd934x_init_dmic(struct snd_soc_component *comp) | |
2150 | { | |
2151 | int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4; | |
2152 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
2153 | u32 def_dmic_rate, dmic_clk_drv; | |
2154 | ||
2155 | vout_ctl_1 = wcd934x_get_micbias_val(comp->dev, | |
2156 | "qcom,micbias1-microvolt"); | |
2157 | vout_ctl_2 = wcd934x_get_micbias_val(comp->dev, | |
2158 | "qcom,micbias2-microvolt"); | |
2159 | vout_ctl_3 = wcd934x_get_micbias_val(comp->dev, | |
2160 | "qcom,micbias3-microvolt"); | |
2161 | vout_ctl_4 = wcd934x_get_micbias_val(comp->dev, | |
2162 | "qcom,micbias4-microvolt"); | |
2163 | ||
2164 | snd_soc_component_update_bits(comp, WCD934X_ANA_MICB1, | |
2165 | WCD934X_MICB_VAL_MASK, vout_ctl_1); | |
2166 | snd_soc_component_update_bits(comp, WCD934X_ANA_MICB2, | |
2167 | WCD934X_MICB_VAL_MASK, vout_ctl_2); | |
2168 | snd_soc_component_update_bits(comp, WCD934X_ANA_MICB3, | |
2169 | WCD934X_MICB_VAL_MASK, vout_ctl_3); | |
2170 | snd_soc_component_update_bits(comp, WCD934X_ANA_MICB4, | |
2171 | WCD934X_MICB_VAL_MASK, vout_ctl_4); | |
2172 | ||
2173 | if (wcd->rate == WCD934X_MCLK_CLK_9P6MHZ) | |
2174 | def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; | |
2175 | else | |
2176 | def_dmic_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ; | |
2177 | ||
2178 | wcd->dmic_sample_rate = def_dmic_rate; | |
2179 | ||
2180 | dmic_clk_drv = 0; | |
2181 | snd_soc_component_update_bits(comp, WCD934X_TEST_DEBUG_PAD_DRVCTL_0, | |
2182 | 0x0C, dmic_clk_drv << 2); | |
2183 | ||
2184 | return 0; | |
2185 | } | |
2186 | ||
2187 | static void wcd934x_hw_init(struct wcd934x_codec *wcd) | |
2188 | { | |
2189 | struct regmap *rm = wcd->regmap; | |
2190 | ||
2191 | /* set SPKR rate to FS_2P4_3P072 */ | |
2192 | regmap_update_bits(rm, WCD934X_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08); | |
2193 | regmap_update_bits(rm, WCD934X_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08); | |
2194 | ||
2195 | /* Take DMICs out of reset */ | |
2196 | regmap_update_bits(rm, WCD934X_CPE_SS_DMIC_CFG, 0x80, 0x00); | |
2197 | } | |
2198 | ||
2199 | static int wcd934x_comp_init(struct snd_soc_component *component) | |
2200 | { | |
2201 | struct wcd934x_codec *wcd = dev_get_drvdata(component->dev); | |
2202 | ||
2203 | wcd934x_hw_init(wcd); | |
2204 | wcd934x_enable_efuse_sensing(wcd); | |
2205 | wcd934x_get_version(wcd); | |
2206 | ||
2207 | return 0; | |
2208 | } | |
2209 | ||
2210 | static irqreturn_t wcd934x_slim_irq_handler(int irq, void *data) | |
2211 | { | |
2212 | struct wcd934x_codec *wcd = data; | |
2213 | unsigned long status = 0; | |
2214 | int i, j, port_id; | |
2215 | unsigned int val, int_val = 0; | |
2216 | irqreturn_t ret = IRQ_NONE; | |
2217 | bool tx; | |
2218 | unsigned short reg = 0; | |
2219 | ||
2220 | for (i = WCD934X_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0; | |
2221 | i <= WCD934X_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) { | |
2222 | regmap_read(wcd->if_regmap, i, &val); | |
2223 | status |= ((u32)val << (8 * j)); | |
2224 | } | |
2225 | ||
2226 | for_each_set_bit(j, &status, 32) { | |
2227 | tx = false; | |
2228 | port_id = j; | |
2229 | ||
2230 | if (j >= 16) { | |
2231 | tx = true; | |
2232 | port_id = j - 16; | |
2233 | } | |
2234 | ||
2235 | regmap_read(wcd->if_regmap, | |
2236 | WCD934X_SLIM_PGD_PORT_INT_RX_SOURCE0 + j, &val); | |
2237 | if (val) { | |
2238 | if (!tx) | |
2239 | reg = WCD934X_SLIM_PGD_PORT_INT_EN0 + | |
2240 | (port_id / 8); | |
2241 | else | |
2242 | reg = WCD934X_SLIM_PGD_PORT_INT_TX_EN0 + | |
2243 | (port_id / 8); | |
2244 | regmap_read(wcd->if_regmap, reg, &int_val); | |
2245 | } | |
2246 | ||
2247 | if (val & WCD934X_SLIM_IRQ_OVERFLOW) | |
2248 | dev_err_ratelimited(wcd->dev, | |
2249 | "overflow error on %s port %d, value %x\n", | |
2250 | (tx ? "TX" : "RX"), port_id, val); | |
2251 | ||
2252 | if (val & WCD934X_SLIM_IRQ_UNDERFLOW) | |
2253 | dev_err_ratelimited(wcd->dev, | |
2254 | "underflow error on %s port %d, value %x\n", | |
2255 | (tx ? "TX" : "RX"), port_id, val); | |
2256 | ||
2257 | if ((val & WCD934X_SLIM_IRQ_OVERFLOW) || | |
2258 | (val & WCD934X_SLIM_IRQ_UNDERFLOW)) { | |
2259 | if (!tx) | |
2260 | reg = WCD934X_SLIM_PGD_PORT_INT_EN0 + | |
2261 | (port_id / 8); | |
2262 | else | |
2263 | reg = WCD934X_SLIM_PGD_PORT_INT_TX_EN0 + | |
2264 | (port_id / 8); | |
2265 | regmap_read( | |
2266 | wcd->if_regmap, reg, &int_val); | |
2267 | if (int_val & (1 << (port_id % 8))) { | |
2268 | int_val = int_val ^ (1 << (port_id % 8)); | |
2269 | regmap_write(wcd->if_regmap, | |
2270 | reg, int_val); | |
2271 | } | |
2272 | } | |
2273 | ||
2274 | if (val & WCD934X_SLIM_IRQ_PORT_CLOSED) | |
2275 | dev_err_ratelimited(wcd->dev, | |
2276 | "Port Closed %s port %d, value %x\n", | |
2277 | (tx ? "TX" : "RX"), port_id, val); | |
2278 | ||
2279 | regmap_write(wcd->if_regmap, | |
2280 | WCD934X_SLIM_PGD_PORT_INT_CLR_RX_0 + (j / 8), | |
2281 | BIT(j % 8)); | |
2282 | ret = IRQ_HANDLED; | |
2283 | } | |
2284 | ||
2285 | return ret; | |
2286 | } | |
2287 | ||
2288 | static int wcd934x_comp_probe(struct snd_soc_component *component) | |
2289 | { | |
2290 | struct wcd934x_codec *wcd = dev_get_drvdata(component->dev); | |
2291 | int i; | |
2292 | ||
2293 | snd_soc_component_init_regmap(component, wcd->regmap); | |
2294 | wcd->component = component; | |
2295 | ||
2296 | /* Class-H Init*/ | |
2297 | wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, wcd->version); | |
2298 | if (IS_ERR(wcd->clsh_ctrl)) | |
2299 | return PTR_ERR(wcd->clsh_ctrl); | |
2300 | ||
2301 | /* Default HPH Mode to Class-H Low HiFi */ | |
2302 | wcd->hph_mode = CLS_H_LOHIFI; | |
2303 | ||
2304 | wcd934x_comp_init(component); | |
2305 | ||
2306 | for (i = 0; i < NUM_CODEC_DAIS; i++) | |
2307 | INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list); | |
2308 | ||
2309 | wcd934x_init_dmic(component); | |
2310 | return 0; | |
2311 | } | |
2312 | ||
2313 | static void wcd934x_comp_remove(struct snd_soc_component *comp) | |
2314 | { | |
2315 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
2316 | ||
2317 | wcd_clsh_ctrl_free(wcd->clsh_ctrl); | |
2318 | } | |
2319 | ||
2320 | static int wcd934x_comp_set_sysclk(struct snd_soc_component *comp, | |
2321 | int clk_id, int source, | |
2322 | unsigned int freq, int dir) | |
2323 | { | |
2324 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
2325 | int val = WCD934X_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ; | |
2326 | ||
2327 | wcd->rate = freq; | |
2328 | ||
2329 | if (wcd->rate == WCD934X_MCLK_CLK_12P288MHZ) | |
2330 | val = WCD934X_CODEC_RPM_CLK_MCLK_CFG_12P288MHZ; | |
2331 | ||
2332 | snd_soc_component_update_bits(comp, WCD934X_CODEC_RPM_CLK_MCLK_CFG, | |
2333 | WCD934X_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK, | |
2334 | val); | |
2335 | ||
2336 | return clk_set_rate(wcd->extclk, freq); | |
2337 | } | |
2338 | ||
1cde8b82 SK |
2339 | static uint32_t get_iir_band_coeff(struct snd_soc_component *component, |
2340 | int iir_idx, int band_idx, int coeff_idx) | |
2341 | { | |
2342 | u32 value = 0; | |
2343 | int reg, b2_reg; | |
2344 | ||
2345 | /* Address does not automatically update if reading */ | |
2346 | reg = WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx; | |
2347 | b2_reg = WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; | |
2348 | ||
2349 | snd_soc_component_write(component, reg, | |
2350 | ((band_idx * BAND_MAX + coeff_idx) * | |
2351 | sizeof(uint32_t)) & 0x7F); | |
2352 | ||
eaf2767c | 2353 | value |= snd_soc_component_read(component, b2_reg); |
1cde8b82 SK |
2354 | snd_soc_component_write(component, reg, |
2355 | ((band_idx * BAND_MAX + coeff_idx) | |
2356 | * sizeof(uint32_t) + 1) & 0x7F); | |
2357 | ||
eaf2767c | 2358 | value |= (snd_soc_component_read(component, b2_reg) << 8); |
1cde8b82 SK |
2359 | snd_soc_component_write(component, reg, |
2360 | ((band_idx * BAND_MAX + coeff_idx) | |
2361 | * sizeof(uint32_t) + 2) & 0x7F); | |
2362 | ||
eaf2767c | 2363 | value |= (snd_soc_component_read(component, b2_reg) << 16); |
1cde8b82 SK |
2364 | snd_soc_component_write(component, reg, |
2365 | ((band_idx * BAND_MAX + coeff_idx) | |
2366 | * sizeof(uint32_t) + 3) & 0x7F); | |
2367 | ||
2368 | /* Mask bits top 2 bits since they are reserved */ | |
eaf2767c | 2369 | value |= (snd_soc_component_read(component, b2_reg) << 24); |
1cde8b82 SK |
2370 | return value; |
2371 | } | |
2372 | ||
2373 | static void set_iir_band_coeff(struct snd_soc_component *component, | |
2374 | int iir_idx, int band_idx, uint32_t value) | |
2375 | { | |
2376 | int reg = WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; | |
2377 | ||
2378 | snd_soc_component_write(component, reg, (value & 0xFF)); | |
2379 | snd_soc_component_write(component, reg, (value >> 8) & 0xFF); | |
2380 | snd_soc_component_write(component, reg, (value >> 16) & 0xFF); | |
2381 | /* Mask top 2 bits, 7-8 are reserved */ | |
2382 | snd_soc_component_write(component, reg, (value >> 24) & 0x3F); | |
2383 | } | |
2384 | ||
2385 | static int wcd934x_put_iir_band_audio_mixer( | |
2386 | struct snd_kcontrol *kcontrol, | |
2387 | struct snd_ctl_elem_value *ucontrol) | |
2388 | { | |
2389 | struct snd_soc_component *component = | |
2390 | snd_soc_kcontrol_component(kcontrol); | |
2391 | struct wcd_iir_filter_ctl *ctl = | |
2392 | (struct wcd_iir_filter_ctl *)kcontrol->private_value; | |
2393 | struct soc_bytes_ext *params = &ctl->bytes_ext; | |
2394 | int iir_idx = ctl->iir_idx; | |
2395 | int band_idx = ctl->band_idx; | |
2396 | u32 coeff[BAND_MAX]; | |
2397 | int reg = WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx; | |
2398 | ||
2399 | memcpy(&coeff[0], ucontrol->value.bytes.data, params->max); | |
2400 | ||
2401 | /* Mask top bit it is reserved */ | |
2402 | /* Updates addr automatically for each B2 write */ | |
2403 | snd_soc_component_write(component, reg, (band_idx * BAND_MAX * | |
2404 | sizeof(uint32_t)) & 0x7F); | |
2405 | ||
2406 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[0]); | |
2407 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[1]); | |
2408 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[2]); | |
2409 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[3]); | |
2410 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[4]); | |
2411 | ||
2412 | return 0; | |
2413 | } | |
2414 | ||
2415 | static int wcd934x_get_iir_band_audio_mixer(struct snd_kcontrol *kcontrol, | |
2416 | struct snd_ctl_elem_value *ucontrol) | |
2417 | { | |
2418 | struct snd_soc_component *component = | |
2419 | snd_soc_kcontrol_component(kcontrol); | |
2420 | struct wcd_iir_filter_ctl *ctl = | |
2421 | (struct wcd_iir_filter_ctl *)kcontrol->private_value; | |
2422 | struct soc_bytes_ext *params = &ctl->bytes_ext; | |
2423 | int iir_idx = ctl->iir_idx; | |
2424 | int band_idx = ctl->band_idx; | |
2425 | u32 coeff[BAND_MAX]; | |
2426 | ||
2427 | coeff[0] = get_iir_band_coeff(component, iir_idx, band_idx, 0); | |
2428 | coeff[1] = get_iir_band_coeff(component, iir_idx, band_idx, 1); | |
2429 | coeff[2] = get_iir_band_coeff(component, iir_idx, band_idx, 2); | |
2430 | coeff[3] = get_iir_band_coeff(component, iir_idx, band_idx, 3); | |
2431 | coeff[4] = get_iir_band_coeff(component, iir_idx, band_idx, 4); | |
2432 | ||
2433 | memcpy(ucontrol->value.bytes.data, &coeff[0], params->max); | |
2434 | ||
2435 | return 0; | |
2436 | } | |
2437 | ||
2438 | static int wcd934x_iir_filter_info(struct snd_kcontrol *kcontrol, | |
2439 | struct snd_ctl_elem_info *ucontrol) | |
2440 | { | |
2441 | struct wcd_iir_filter_ctl *ctl = | |
2442 | (struct wcd_iir_filter_ctl *)kcontrol->private_value; | |
2443 | struct soc_bytes_ext *params = &ctl->bytes_ext; | |
2444 | ||
2445 | ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; | |
2446 | ucontrol->count = params->max; | |
2447 | ||
2448 | return 0; | |
2449 | } | |
2450 | ||
2451 | static int wcd934x_compander_get(struct snd_kcontrol *kc, | |
2452 | struct snd_ctl_elem_value *ucontrol) | |
2453 | { | |
2454 | struct snd_soc_component *component = snd_soc_kcontrol_component(kc); | |
2455 | int comp = ((struct soc_mixer_control *)kc->private_value)->shift; | |
2456 | struct wcd934x_codec *wcd = dev_get_drvdata(component->dev); | |
2457 | ||
2458 | ucontrol->value.integer.value[0] = wcd->comp_enabled[comp]; | |
2459 | ||
2460 | return 0; | |
2461 | } | |
2462 | ||
2463 | static int wcd934x_compander_set(struct snd_kcontrol *kc, | |
2464 | struct snd_ctl_elem_value *ucontrol) | |
2465 | { | |
2466 | struct snd_soc_component *component = snd_soc_kcontrol_component(kc); | |
2467 | struct wcd934x_codec *wcd = dev_get_drvdata(component->dev); | |
2468 | int comp = ((struct soc_mixer_control *)kc->private_value)->shift; | |
2469 | int value = ucontrol->value.integer.value[0]; | |
2470 | int sel; | |
2471 | ||
2472 | wcd->comp_enabled[comp] = value; | |
2473 | sel = value ? WCD934X_HPH_GAIN_SRC_SEL_COMPANDER : | |
2474 | WCD934X_HPH_GAIN_SRC_SEL_REGISTER; | |
2475 | ||
2476 | /* Any specific register configuration for compander */ | |
2477 | switch (comp) { | |
2478 | case COMPANDER_1: | |
2479 | /* Set Gain Source Select based on compander enable/disable */ | |
2480 | snd_soc_component_update_bits(component, WCD934X_HPH_L_EN, | |
2481 | WCD934X_HPH_GAIN_SRC_SEL_MASK, | |
2482 | sel); | |
2483 | break; | |
2484 | case COMPANDER_2: | |
2485 | snd_soc_component_update_bits(component, WCD934X_HPH_R_EN, | |
2486 | WCD934X_HPH_GAIN_SRC_SEL_MASK, | |
2487 | sel); | |
2488 | break; | |
2489 | case COMPANDER_3: | |
2490 | case COMPANDER_4: | |
2491 | case COMPANDER_7: | |
2492 | case COMPANDER_8: | |
2493 | break; | |
2494 | default: | |
2495 | break; | |
e48e83d1 | 2496 | } |
1cde8b82 SK |
2497 | |
2498 | return 0; | |
2499 | } | |
2500 | ||
2501 | static int wcd934x_rx_hph_mode_get(struct snd_kcontrol *kc, | |
2502 | struct snd_ctl_elem_value *ucontrol) | |
2503 | { | |
2504 | struct snd_soc_component *component = snd_soc_kcontrol_component(kc); | |
2505 | struct wcd934x_codec *wcd = dev_get_drvdata(component->dev); | |
2506 | ||
2507 | ucontrol->value.enumerated.item[0] = wcd->hph_mode; | |
2508 | ||
2509 | return 0; | |
2510 | } | |
2511 | ||
2512 | static int wcd934x_rx_hph_mode_put(struct snd_kcontrol *kc, | |
2513 | struct snd_ctl_elem_value *ucontrol) | |
2514 | { | |
2515 | struct snd_soc_component *component = snd_soc_kcontrol_component(kc); | |
2516 | struct wcd934x_codec *wcd = dev_get_drvdata(component->dev); | |
2517 | u32 mode_val; | |
2518 | ||
2519 | mode_val = ucontrol->value.enumerated.item[0]; | |
2520 | ||
2521 | if (mode_val == 0) { | |
2522 | dev_err(wcd->dev, "Invalid HPH Mode, default to ClSH HiFi\n"); | |
2523 | mode_val = CLS_H_LOHIFI; | |
2524 | } | |
2525 | wcd->hph_mode = mode_val; | |
2526 | ||
2527 | return 0; | |
2528 | } | |
2529 | ||
dd9eb19b SK |
2530 | static int slim_rx_mux_get(struct snd_kcontrol *kc, |
2531 | struct snd_ctl_elem_value *ucontrol) | |
2532 | { | |
2533 | struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); | |
2534 | struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); | |
2535 | struct wcd934x_codec *wcd = dev_get_drvdata(dapm->dev); | |
2536 | ||
2537 | ucontrol->value.enumerated.item[0] = wcd->rx_port_value[w->shift]; | |
2538 | ||
2539 | return 0; | |
2540 | } | |
2541 | ||
2542 | static int slim_rx_mux_put(struct snd_kcontrol *kc, | |
2543 | struct snd_ctl_elem_value *ucontrol) | |
2544 | { | |
2545 | struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); | |
2546 | struct wcd934x_codec *wcd = dev_get_drvdata(w->dapm->dev); | |
2547 | struct soc_enum *e = (struct soc_enum *)kc->private_value; | |
2548 | struct snd_soc_dapm_update *update = NULL; | |
2549 | u32 port_id = w->shift; | |
2550 | ||
2551 | if (wcd->rx_port_value[port_id] == ucontrol->value.enumerated.item[0]) | |
2552 | return 0; | |
2553 | ||
2554 | wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; | |
2555 | ||
2556 | switch (wcd->rx_port_value[port_id]) { | |
2557 | case 0: | |
2558 | list_del_init(&wcd->rx_chs[port_id].list); | |
2559 | break; | |
2560 | case 1: | |
2561 | list_add_tail(&wcd->rx_chs[port_id].list, | |
2562 | &wcd->dai[AIF1_PB].slim_ch_list); | |
2563 | break; | |
2564 | case 2: | |
2565 | list_add_tail(&wcd->rx_chs[port_id].list, | |
2566 | &wcd->dai[AIF2_PB].slim_ch_list); | |
2567 | break; | |
2568 | case 3: | |
2569 | list_add_tail(&wcd->rx_chs[port_id].list, | |
2570 | &wcd->dai[AIF3_PB].slim_ch_list); | |
2571 | break; | |
2572 | case 4: | |
2573 | list_add_tail(&wcd->rx_chs[port_id].list, | |
2574 | &wcd->dai[AIF4_PB].slim_ch_list); | |
2575 | break; | |
2576 | default: | |
2577 | dev_err(wcd->dev, "Unknown AIF %d\n", | |
2578 | wcd->rx_port_value[port_id]); | |
2579 | goto err; | |
2580 | } | |
2581 | ||
2582 | snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id], | |
2583 | e, update); | |
2584 | ||
2585 | return 0; | |
2586 | err: | |
2587 | return -EINVAL; | |
2588 | } | |
2589 | ||
2590 | static int wcd934x_int_dem_inp_mux_put(struct snd_kcontrol *kc, | |
2591 | struct snd_ctl_elem_value *ucontrol) | |
2592 | { | |
2593 | struct soc_enum *e = (struct soc_enum *)kc->private_value; | |
2594 | struct snd_soc_component *component; | |
2595 | int reg, val, ret; | |
2596 | ||
2597 | component = snd_soc_dapm_kcontrol_component(kc); | |
2598 | val = ucontrol->value.enumerated.item[0]; | |
2599 | if (e->reg == WCD934X_CDC_RX0_RX_PATH_SEC0) | |
2600 | reg = WCD934X_CDC_RX0_RX_PATH_CFG0; | |
2601 | else if (e->reg == WCD934X_CDC_RX1_RX_PATH_SEC0) | |
2602 | reg = WCD934X_CDC_RX1_RX_PATH_CFG0; | |
2603 | else if (e->reg == WCD934X_CDC_RX2_RX_PATH_SEC0) | |
2604 | reg = WCD934X_CDC_RX2_RX_PATH_CFG0; | |
2605 | else | |
2606 | return -EINVAL; | |
2607 | ||
2608 | /* Set Look Ahead Delay */ | |
2609 | if (val) | |
2610 | snd_soc_component_update_bits(component, reg, | |
2611 | WCD934X_RX_DLY_ZN_EN_MASK, | |
2612 | WCD934X_RX_DLY_ZN_ENABLE); | |
2613 | else | |
2614 | snd_soc_component_update_bits(component, reg, | |
2615 | WCD934X_RX_DLY_ZN_EN_MASK, | |
2616 | WCD934X_RX_DLY_ZN_DISABLE); | |
2617 | ||
2618 | ret = snd_soc_dapm_put_enum_double(kc, ucontrol); | |
2619 | ||
2620 | return ret; | |
2621 | } | |
2622 | ||
a70d9245 SK |
2623 | static int wcd934x_dec_enum_put(struct snd_kcontrol *kcontrol, |
2624 | struct snd_ctl_elem_value *ucontrol) | |
2625 | { | |
2626 | struct snd_soc_component *comp; | |
2627 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | |
2628 | unsigned int val; | |
2629 | u16 mic_sel_reg = 0; | |
2630 | u8 mic_sel; | |
2631 | ||
2632 | comp = snd_soc_dapm_kcontrol_component(kcontrol); | |
2633 | ||
2634 | val = ucontrol->value.enumerated.item[0]; | |
2635 | if (val > e->items - 1) | |
2636 | return -EINVAL; | |
2637 | ||
2638 | switch (e->reg) { | |
2639 | case WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1: | |
2640 | if (e->shift_l == 0) | |
2641 | mic_sel_reg = WCD934X_CDC_TX0_TX_PATH_CFG0; | |
2642 | else if (e->shift_l == 2) | |
2643 | mic_sel_reg = WCD934X_CDC_TX4_TX_PATH_CFG0; | |
2644 | else if (e->shift_l == 4) | |
2645 | mic_sel_reg = WCD934X_CDC_TX8_TX_PATH_CFG0; | |
2646 | break; | |
2647 | case WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1: | |
2648 | if (e->shift_l == 0) | |
2649 | mic_sel_reg = WCD934X_CDC_TX1_TX_PATH_CFG0; | |
2650 | else if (e->shift_l == 2) | |
2651 | mic_sel_reg = WCD934X_CDC_TX5_TX_PATH_CFG0; | |
2652 | break; | |
2653 | case WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1: | |
2654 | if (e->shift_l == 0) | |
2655 | mic_sel_reg = WCD934X_CDC_TX2_TX_PATH_CFG0; | |
2656 | else if (e->shift_l == 2) | |
2657 | mic_sel_reg = WCD934X_CDC_TX6_TX_PATH_CFG0; | |
2658 | break; | |
2659 | case WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1: | |
2660 | if (e->shift_l == 0) | |
2661 | mic_sel_reg = WCD934X_CDC_TX3_TX_PATH_CFG0; | |
2662 | else if (e->shift_l == 2) | |
2663 | mic_sel_reg = WCD934X_CDC_TX7_TX_PATH_CFG0; | |
2664 | break; | |
2665 | default: | |
2666 | dev_err(comp->dev, "%s: e->reg: 0x%x not expected\n", | |
2667 | __func__, e->reg); | |
2668 | return -EINVAL; | |
2669 | } | |
2670 | ||
2671 | /* ADC: 0, DMIC: 1 */ | |
2672 | mic_sel = val ? 0x0 : 0x1; | |
2673 | if (mic_sel_reg) | |
2674 | snd_soc_component_update_bits(comp, mic_sel_reg, BIT(7), | |
2675 | mic_sel << 7); | |
2676 | ||
2677 | return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); | |
2678 | } | |
2679 | ||
dd9eb19b SK |
2680 | static const struct snd_kcontrol_new rx_int0_2_mux = |
2681 | SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum); | |
2682 | ||
2683 | static const struct snd_kcontrol_new rx_int1_2_mux = | |
2684 | SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum); | |
2685 | ||
2686 | static const struct snd_kcontrol_new rx_int2_2_mux = | |
2687 | SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum); | |
2688 | ||
2689 | static const struct snd_kcontrol_new rx_int3_2_mux = | |
2690 | SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum); | |
2691 | ||
2692 | static const struct snd_kcontrol_new rx_int4_2_mux = | |
2693 | SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum); | |
2694 | ||
2695 | static const struct snd_kcontrol_new rx_int7_2_mux = | |
2696 | SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum); | |
2697 | ||
2698 | static const struct snd_kcontrol_new rx_int8_2_mux = | |
2699 | SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum); | |
2700 | ||
2701 | static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux = | |
2702 | SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum); | |
2703 | ||
2704 | static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux = | |
2705 | SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum); | |
2706 | ||
2707 | static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux = | |
2708 | SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum); | |
2709 | ||
2710 | static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux = | |
2711 | SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum); | |
2712 | ||
2713 | static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux = | |
2714 | SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum); | |
2715 | ||
2716 | static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux = | |
2717 | SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum); | |
2718 | ||
2719 | static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux = | |
2720 | SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum); | |
2721 | ||
2722 | static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux = | |
2723 | SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum); | |
2724 | ||
2725 | static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux = | |
2726 | SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum); | |
2727 | ||
2728 | static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux = | |
2729 | SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum); | |
2730 | ||
2731 | static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux = | |
2732 | SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum); | |
2733 | ||
2734 | static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux = | |
2735 | SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum); | |
2736 | ||
2737 | static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux = | |
2738 | SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum); | |
2739 | ||
2740 | static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux = | |
2741 | SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum); | |
2742 | ||
2743 | static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux = | |
2744 | SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum); | |
2745 | ||
2746 | static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux = | |
2747 | SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum); | |
2748 | ||
2749 | static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux = | |
2750 | SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum); | |
2751 | ||
2752 | static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux = | |
2753 | SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum); | |
2754 | ||
2755 | static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux = | |
2756 | SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum); | |
2757 | ||
2758 | static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux = | |
2759 | SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum); | |
2760 | ||
2761 | static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux = | |
2762 | SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum); | |
2763 | ||
2764 | static const struct snd_kcontrol_new rx_int0_mix2_inp_mux = | |
2765 | SOC_DAPM_ENUM("RX INT0 MIX2 INP Mux", rx_int0_mix2_inp_mux_enum); | |
2766 | ||
2767 | static const struct snd_kcontrol_new rx_int1_mix2_inp_mux = | |
2768 | SOC_DAPM_ENUM("RX INT1 MIX2 INP Mux", rx_int1_mix2_inp_mux_enum); | |
2769 | ||
2770 | static const struct snd_kcontrol_new rx_int2_mix2_inp_mux = | |
2771 | SOC_DAPM_ENUM("RX INT2 MIX2 INP Mux", rx_int2_mix2_inp_mux_enum); | |
2772 | ||
2773 | static const struct snd_kcontrol_new rx_int3_mix2_inp_mux = | |
2774 | SOC_DAPM_ENUM("RX INT3 MIX2 INP Mux", rx_int3_mix2_inp_mux_enum); | |
2775 | ||
2776 | static const struct snd_kcontrol_new rx_int4_mix2_inp_mux = | |
2777 | SOC_DAPM_ENUM("RX INT4 MIX2 INP Mux", rx_int4_mix2_inp_mux_enum); | |
2778 | ||
2779 | static const struct snd_kcontrol_new rx_int7_mix2_inp_mux = | |
2780 | SOC_DAPM_ENUM("RX INT7 MIX2 INP Mux", rx_int7_mix2_inp_mux_enum); | |
2781 | ||
2782 | static const struct snd_kcontrol_new iir0_inp0_mux = | |
2783 | SOC_DAPM_ENUM("IIR0 INP0 Mux", iir0_inp0_mux_enum); | |
2784 | static const struct snd_kcontrol_new iir0_inp1_mux = | |
2785 | SOC_DAPM_ENUM("IIR0 INP1 Mux", iir0_inp1_mux_enum); | |
2786 | static const struct snd_kcontrol_new iir0_inp2_mux = | |
2787 | SOC_DAPM_ENUM("IIR0 INP2 Mux", iir0_inp2_mux_enum); | |
2788 | static const struct snd_kcontrol_new iir0_inp3_mux = | |
2789 | SOC_DAPM_ENUM("IIR0 INP3 Mux", iir0_inp3_mux_enum); | |
2790 | ||
2791 | static const struct snd_kcontrol_new iir1_inp0_mux = | |
2792 | SOC_DAPM_ENUM("IIR1 INP0 Mux", iir1_inp0_mux_enum); | |
2793 | static const struct snd_kcontrol_new iir1_inp1_mux = | |
2794 | SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum); | |
2795 | static const struct snd_kcontrol_new iir1_inp2_mux = | |
2796 | SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum); | |
2797 | static const struct snd_kcontrol_new iir1_inp3_mux = | |
2798 | SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum); | |
2799 | ||
2800 | static const struct snd_kcontrol_new slim_rx_mux[WCD934X_RX_MAX] = { | |
2801 | SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum, | |
2802 | slim_rx_mux_get, slim_rx_mux_put), | |
2803 | SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum, | |
2804 | slim_rx_mux_get, slim_rx_mux_put), | |
2805 | SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum, | |
2806 | slim_rx_mux_get, slim_rx_mux_put), | |
2807 | SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum, | |
2808 | slim_rx_mux_get, slim_rx_mux_put), | |
2809 | SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum, | |
2810 | slim_rx_mux_get, slim_rx_mux_put), | |
2811 | SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum, | |
2812 | slim_rx_mux_get, slim_rx_mux_put), | |
2813 | SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum, | |
2814 | slim_rx_mux_get, slim_rx_mux_put), | |
2815 | SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum, | |
2816 | slim_rx_mux_get, slim_rx_mux_put), | |
2817 | }; | |
2818 | ||
2819 | static const struct snd_kcontrol_new rx_int1_asrc_switch[] = { | |
2820 | SOC_DAPM_SINGLE("HPHL Switch", SND_SOC_NOPM, 0, 1, 0), | |
2821 | }; | |
2822 | ||
2823 | static const struct snd_kcontrol_new rx_int2_asrc_switch[] = { | |
2824 | SOC_DAPM_SINGLE("HPHR Switch", SND_SOC_NOPM, 0, 1, 0), | |
2825 | }; | |
2826 | ||
2827 | static const struct snd_kcontrol_new rx_int3_asrc_switch[] = { | |
2828 | SOC_DAPM_SINGLE("LO1 Switch", SND_SOC_NOPM, 0, 1, 0), | |
2829 | }; | |
2830 | ||
2831 | static const struct snd_kcontrol_new rx_int4_asrc_switch[] = { | |
2832 | SOC_DAPM_SINGLE("LO2 Switch", SND_SOC_NOPM, 0, 1, 0), | |
2833 | }; | |
2834 | ||
2835 | static const struct snd_kcontrol_new rx_int0_dem_inp_mux = | |
2836 | SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum, | |
2837 | snd_soc_dapm_get_enum_double, | |
2838 | wcd934x_int_dem_inp_mux_put); | |
2839 | ||
2840 | static const struct snd_kcontrol_new rx_int1_dem_inp_mux = | |
2841 | SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum, | |
2842 | snd_soc_dapm_get_enum_double, | |
2843 | wcd934x_int_dem_inp_mux_put); | |
2844 | ||
2845 | static const struct snd_kcontrol_new rx_int2_dem_inp_mux = | |
2846 | SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum, | |
2847 | snd_soc_dapm_get_enum_double, | |
2848 | wcd934x_int_dem_inp_mux_put); | |
2849 | ||
2850 | static const struct snd_kcontrol_new rx_int0_1_interp_mux = | |
2851 | SOC_DAPM_ENUM("RX INT0_1 INTERP Mux", rx_int0_1_interp_mux_enum); | |
2852 | ||
2853 | static const struct snd_kcontrol_new rx_int1_1_interp_mux = | |
2854 | SOC_DAPM_ENUM("RX INT1_1 INTERP Mux", rx_int1_1_interp_mux_enum); | |
2855 | ||
2856 | static const struct snd_kcontrol_new rx_int2_1_interp_mux = | |
2857 | SOC_DAPM_ENUM("RX INT2_1 INTERP Mux", rx_int2_1_interp_mux_enum); | |
2858 | ||
2859 | static const struct snd_kcontrol_new rx_int3_1_interp_mux = | |
2860 | SOC_DAPM_ENUM("RX INT3_1 INTERP Mux", rx_int3_1_interp_mux_enum); | |
2861 | ||
2862 | static const struct snd_kcontrol_new rx_int4_1_interp_mux = | |
2863 | SOC_DAPM_ENUM("RX INT4_1 INTERP Mux", rx_int4_1_interp_mux_enum); | |
2864 | ||
2865 | static const struct snd_kcontrol_new rx_int7_1_interp_mux = | |
2866 | SOC_DAPM_ENUM("RX INT7_1 INTERP Mux", rx_int7_1_interp_mux_enum); | |
2867 | ||
2868 | static const struct snd_kcontrol_new rx_int8_1_interp_mux = | |
2869 | SOC_DAPM_ENUM("RX INT8_1 INTERP Mux", rx_int8_1_interp_mux_enum); | |
2870 | ||
2871 | static const struct snd_kcontrol_new rx_int0_2_interp_mux = | |
2872 | SOC_DAPM_ENUM("RX INT0_2 INTERP Mux", rx_int0_2_interp_mux_enum); | |
2873 | ||
2874 | static const struct snd_kcontrol_new rx_int1_2_interp_mux = | |
2875 | SOC_DAPM_ENUM("RX INT1_2 INTERP Mux", rx_int1_2_interp_mux_enum); | |
2876 | ||
2877 | static const struct snd_kcontrol_new rx_int2_2_interp_mux = | |
2878 | SOC_DAPM_ENUM("RX INT2_2 INTERP Mux", rx_int2_2_interp_mux_enum); | |
2879 | ||
2880 | static const struct snd_kcontrol_new rx_int3_2_interp_mux = | |
2881 | SOC_DAPM_ENUM("RX INT3_2 INTERP Mux", rx_int3_2_interp_mux_enum); | |
2882 | ||
2883 | static const struct snd_kcontrol_new rx_int4_2_interp_mux = | |
2884 | SOC_DAPM_ENUM("RX INT4_2 INTERP Mux", rx_int4_2_interp_mux_enum); | |
2885 | ||
2886 | static const struct snd_kcontrol_new rx_int7_2_interp_mux = | |
2887 | SOC_DAPM_ENUM("RX INT7_2 INTERP Mux", rx_int7_2_interp_mux_enum); | |
2888 | ||
2889 | static const struct snd_kcontrol_new rx_int8_2_interp_mux = | |
2890 | SOC_DAPM_ENUM("RX INT8_2 INTERP Mux", rx_int8_2_interp_mux_enum); | |
2891 | ||
a70d9245 SK |
2892 | static const struct snd_kcontrol_new tx_dmic_mux0 = |
2893 | SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum); | |
2894 | ||
2895 | static const struct snd_kcontrol_new tx_dmic_mux1 = | |
2896 | SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum); | |
2897 | ||
2898 | static const struct snd_kcontrol_new tx_dmic_mux2 = | |
2899 | SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum); | |
2900 | ||
2901 | static const struct snd_kcontrol_new tx_dmic_mux3 = | |
2902 | SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum); | |
2903 | ||
2904 | static const struct snd_kcontrol_new tx_dmic_mux4 = | |
2905 | SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum); | |
2906 | ||
2907 | static const struct snd_kcontrol_new tx_dmic_mux5 = | |
2908 | SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum); | |
2909 | ||
2910 | static const struct snd_kcontrol_new tx_dmic_mux6 = | |
2911 | SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum); | |
2912 | ||
2913 | static const struct snd_kcontrol_new tx_dmic_mux7 = | |
2914 | SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum); | |
2915 | ||
2916 | static const struct snd_kcontrol_new tx_dmic_mux8 = | |
2917 | SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum); | |
2918 | ||
2919 | static const struct snd_kcontrol_new tx_amic_mux0 = | |
2920 | SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum); | |
2921 | ||
2922 | static const struct snd_kcontrol_new tx_amic_mux1 = | |
2923 | SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum); | |
2924 | ||
2925 | static const struct snd_kcontrol_new tx_amic_mux2 = | |
2926 | SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum); | |
2927 | ||
2928 | static const struct snd_kcontrol_new tx_amic_mux3 = | |
2929 | SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum); | |
2930 | ||
2931 | static const struct snd_kcontrol_new tx_amic_mux4 = | |
2932 | SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum); | |
2933 | ||
2934 | static const struct snd_kcontrol_new tx_amic_mux5 = | |
2935 | SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum); | |
2936 | ||
2937 | static const struct snd_kcontrol_new tx_amic_mux6 = | |
2938 | SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum); | |
2939 | ||
2940 | static const struct snd_kcontrol_new tx_amic_mux7 = | |
2941 | SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum); | |
2942 | ||
2943 | static const struct snd_kcontrol_new tx_amic_mux8 = | |
2944 | SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum); | |
2945 | ||
2946 | static const struct snd_kcontrol_new tx_amic4_5 = | |
2947 | SOC_DAPM_ENUM("AMIC4_5 SEL Mux", tx_amic4_5_enum); | |
2948 | ||
2949 | static const struct snd_kcontrol_new tx_adc_mux0_mux = | |
2950 | SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_enum, | |
2951 | snd_soc_dapm_get_enum_double, wcd934x_dec_enum_put); | |
2952 | static const struct snd_kcontrol_new tx_adc_mux1_mux = | |
2953 | SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_enum, | |
2954 | snd_soc_dapm_get_enum_double, wcd934x_dec_enum_put); | |
2955 | static const struct snd_kcontrol_new tx_adc_mux2_mux = | |
2956 | SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_enum, | |
2957 | snd_soc_dapm_get_enum_double, wcd934x_dec_enum_put); | |
2958 | static const struct snd_kcontrol_new tx_adc_mux3_mux = | |
2959 | SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_enum, | |
2960 | snd_soc_dapm_get_enum_double, wcd934x_dec_enum_put); | |
2961 | static const struct snd_kcontrol_new tx_adc_mux4_mux = | |
2962 | SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_enum, | |
2963 | snd_soc_dapm_get_enum_double, wcd934x_dec_enum_put); | |
2964 | static const struct snd_kcontrol_new tx_adc_mux5_mux = | |
2965 | SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_enum, | |
2966 | snd_soc_dapm_get_enum_double, wcd934x_dec_enum_put); | |
2967 | static const struct snd_kcontrol_new tx_adc_mux6_mux = | |
2968 | SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_enum, | |
2969 | snd_soc_dapm_get_enum_double, wcd934x_dec_enum_put); | |
2970 | static const struct snd_kcontrol_new tx_adc_mux7_mux = | |
2971 | SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_enum, | |
2972 | snd_soc_dapm_get_enum_double, wcd934x_dec_enum_put); | |
2973 | static const struct snd_kcontrol_new tx_adc_mux8_mux = | |
2974 | SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_enum, | |
2975 | snd_soc_dapm_get_enum_double, wcd934x_dec_enum_put); | |
2976 | ||
2977 | static const struct snd_kcontrol_new cdc_if_tx0_mux = | |
2978 | SOC_DAPM_ENUM("CDC_IF TX0 MUX Mux", cdc_if_tx0_mux_enum); | |
2979 | static const struct snd_kcontrol_new cdc_if_tx1_mux = | |
2980 | SOC_DAPM_ENUM("CDC_IF TX1 MUX Mux", cdc_if_tx1_mux_enum); | |
2981 | static const struct snd_kcontrol_new cdc_if_tx2_mux = | |
2982 | SOC_DAPM_ENUM("CDC_IF TX2 MUX Mux", cdc_if_tx2_mux_enum); | |
2983 | static const struct snd_kcontrol_new cdc_if_tx3_mux = | |
2984 | SOC_DAPM_ENUM("CDC_IF TX3 MUX Mux", cdc_if_tx3_mux_enum); | |
2985 | static const struct snd_kcontrol_new cdc_if_tx4_mux = | |
2986 | SOC_DAPM_ENUM("CDC_IF TX4 MUX Mux", cdc_if_tx4_mux_enum); | |
2987 | static const struct snd_kcontrol_new cdc_if_tx5_mux = | |
2988 | SOC_DAPM_ENUM("CDC_IF TX5 MUX Mux", cdc_if_tx5_mux_enum); | |
2989 | static const struct snd_kcontrol_new cdc_if_tx6_mux = | |
2990 | SOC_DAPM_ENUM("CDC_IF TX6 MUX Mux", cdc_if_tx6_mux_enum); | |
2991 | static const struct snd_kcontrol_new cdc_if_tx7_mux = | |
2992 | SOC_DAPM_ENUM("CDC_IF TX7 MUX Mux", cdc_if_tx7_mux_enum); | |
2993 | static const struct snd_kcontrol_new cdc_if_tx8_mux = | |
2994 | SOC_DAPM_ENUM("CDC_IF TX8 MUX Mux", cdc_if_tx8_mux_enum); | |
2995 | static const struct snd_kcontrol_new cdc_if_tx9_mux = | |
2996 | SOC_DAPM_ENUM("CDC_IF TX9 MUX Mux", cdc_if_tx9_mux_enum); | |
2997 | static const struct snd_kcontrol_new cdc_if_tx10_mux = | |
2998 | SOC_DAPM_ENUM("CDC_IF TX10 MUX Mux", cdc_if_tx10_mux_enum); | |
2999 | static const struct snd_kcontrol_new cdc_if_tx11_mux = | |
3000 | SOC_DAPM_ENUM("CDC_IF TX11 MUX Mux", cdc_if_tx11_mux_enum); | |
3001 | static const struct snd_kcontrol_new cdc_if_tx11_inp1_mux = | |
3002 | SOC_DAPM_ENUM("CDC_IF TX11 INP1 MUX Mux", cdc_if_tx11_inp1_mux_enum); | |
3003 | static const struct snd_kcontrol_new cdc_if_tx13_mux = | |
3004 | SOC_DAPM_ENUM("CDC_IF TX13 MUX Mux", cdc_if_tx13_mux_enum); | |
3005 | static const struct snd_kcontrol_new cdc_if_tx13_inp1_mux = | |
3006 | SOC_DAPM_ENUM("CDC_IF TX13 INP1 MUX Mux", cdc_if_tx13_inp1_mux_enum); | |
3007 | ||
3008 | static int slim_tx_mixer_get(struct snd_kcontrol *kc, | |
3009 | struct snd_ctl_elem_value *ucontrol) | |
3010 | { | |
3011 | struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); | |
3012 | struct wcd934x_codec *wcd = dev_get_drvdata(dapm->dev); | |
3013 | struct soc_mixer_control *mixer = | |
3014 | (struct soc_mixer_control *)kc->private_value; | |
3015 | int port_id = mixer->shift; | |
3016 | ||
3017 | ucontrol->value.integer.value[0] = wcd->tx_port_value[port_id]; | |
3018 | ||
3019 | return 0; | |
3020 | } | |
3021 | ||
3022 | static int slim_tx_mixer_put(struct snd_kcontrol *kc, | |
3023 | struct snd_ctl_elem_value *ucontrol) | |
3024 | { | |
3025 | struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc); | |
3026 | struct wcd934x_codec *wcd = dev_get_drvdata(widget->dapm->dev); | |
3027 | struct snd_soc_dapm_update *update = NULL; | |
3028 | struct soc_mixer_control *mixer = | |
3029 | (struct soc_mixer_control *)kc->private_value; | |
3030 | int enable = ucontrol->value.integer.value[0]; | |
3031 | int dai_id = widget->shift; | |
3032 | int port_id = mixer->shift; | |
3033 | ||
3034 | /* only add to the list if value not set */ | |
3035 | if (enable == wcd->tx_port_value[port_id]) | |
3036 | return 0; | |
3037 | ||
3038 | wcd->tx_port_value[port_id] = enable; | |
3039 | ||
3040 | if (enable) | |
3041 | list_add_tail(&wcd->tx_chs[port_id].list, | |
3042 | &wcd->dai[dai_id].slim_ch_list); | |
3043 | else | |
3044 | list_del_init(&wcd->tx_chs[port_id].list); | |
3045 | ||
3046 | snd_soc_dapm_mixer_update_power(widget->dapm, kc, enable, update); | |
3047 | ||
3048 | return 0; | |
3049 | } | |
3050 | ||
3051 | static const struct snd_kcontrol_new aif1_slim_cap_mixer[] = { | |
3052 | SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, | |
3053 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3054 | SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, | |
3055 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3056 | SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD934X_TX2, 1, 0, | |
3057 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3058 | SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD934X_TX3, 1, 0, | |
3059 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3060 | SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD934X_TX4, 1, 0, | |
3061 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3062 | SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD934X_TX5, 1, 0, | |
3063 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3064 | SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD934X_TX6, 1, 0, | |
3065 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3066 | SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD934X_TX7, 1, 0, | |
3067 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3068 | SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD934X_TX8, 1, 0, | |
3069 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3070 | SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD934X_TX9, 1, 0, | |
3071 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3072 | SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD934X_TX10, 1, 0, | |
3073 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3074 | SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD934X_TX11, 1, 0, | |
3075 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3076 | SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD934X_TX13, 1, 0, | |
3077 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3078 | }; | |
3079 | ||
3080 | static const struct snd_kcontrol_new aif2_slim_cap_mixer[] = { | |
3081 | SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, | |
3082 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3083 | SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, | |
3084 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3085 | SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD934X_TX2, 1, 0, | |
3086 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3087 | SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD934X_TX3, 1, 0, | |
3088 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3089 | SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD934X_TX4, 1, 0, | |
3090 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3091 | SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD934X_TX5, 1, 0, | |
3092 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3093 | SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD934X_TX6, 1, 0, | |
3094 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3095 | SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD934X_TX7, 1, 0, | |
3096 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3097 | SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD934X_TX8, 1, 0, | |
3098 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3099 | SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD934X_TX9, 1, 0, | |
3100 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3101 | SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD934X_TX10, 1, 0, | |
3102 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3103 | SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD934X_TX11, 1, 0, | |
3104 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3105 | SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD934X_TX13, 1, 0, | |
3106 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3107 | }; | |
3108 | ||
3109 | static const struct snd_kcontrol_new aif3_slim_cap_mixer[] = { | |
3110 | SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0, | |
3111 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3112 | SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0, | |
3113 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3114 | SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD934X_TX2, 1, 0, | |
3115 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3116 | SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD934X_TX3, 1, 0, | |
3117 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3118 | SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD934X_TX4, 1, 0, | |
3119 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3120 | SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD934X_TX5, 1, 0, | |
3121 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3122 | SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD934X_TX6, 1, 0, | |
3123 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3124 | SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD934X_TX7, 1, 0, | |
3125 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3126 | SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD934X_TX8, 1, 0, | |
3127 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3128 | SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD934X_TX9, 1, 0, | |
3129 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3130 | SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD934X_TX10, 1, 0, | |
3131 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3132 | SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD934X_TX11, 1, 0, | |
3133 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3134 | SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD934X_TX13, 1, 0, | |
3135 | slim_tx_mixer_get, slim_tx_mixer_put), | |
3136 | }; | |
3137 | ||
1cde8b82 SK |
3138 | static const struct snd_kcontrol_new wcd934x_snd_controls[] = { |
3139 | /* Gain Controls */ | |
3140 | SOC_SINGLE_TLV("EAR PA Volume", WCD934X_ANA_EAR, 4, 4, 1, ear_pa_gain), | |
3141 | SOC_SINGLE_TLV("HPHL Volume", WCD934X_HPH_L_EN, 0, 24, 1, line_gain), | |
3142 | SOC_SINGLE_TLV("HPHR Volume", WCD934X_HPH_R_EN, 0, 24, 1, line_gain), | |
3143 | SOC_SINGLE_TLV("LINEOUT1 Volume", WCD934X_DIFF_LO_LO1_COMPANDER, | |
3144 | 3, 16, 1, line_gain), | |
3145 | SOC_SINGLE_TLV("LINEOUT2 Volume", WCD934X_DIFF_LO_LO2_COMPANDER, | |
3146 | 3, 16, 1, line_gain), | |
3147 | ||
3148 | SOC_SINGLE_TLV("ADC1 Volume", WCD934X_ANA_AMIC1, 0, 20, 0, analog_gain), | |
3149 | SOC_SINGLE_TLV("ADC2 Volume", WCD934X_ANA_AMIC2, 0, 20, 0, analog_gain), | |
3150 | SOC_SINGLE_TLV("ADC3 Volume", WCD934X_ANA_AMIC3, 0, 20, 0, analog_gain), | |
3151 | SOC_SINGLE_TLV("ADC4 Volume", WCD934X_ANA_AMIC4, 0, 20, 0, analog_gain), | |
3152 | ||
3153 | SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD934X_CDC_RX0_RX_VOL_CTL, | |
3154 | -84, 40, digital_gain), /* -84dB min - 40dB max */ | |
3155 | SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD934X_CDC_RX1_RX_VOL_CTL, | |
3156 | -84, 40, digital_gain), | |
3157 | SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD934X_CDC_RX2_RX_VOL_CTL, | |
3158 | -84, 40, digital_gain), | |
3159 | SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD934X_CDC_RX3_RX_VOL_CTL, | |
3160 | -84, 40, digital_gain), | |
3161 | SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD934X_CDC_RX4_RX_VOL_CTL, | |
3162 | -84, 40, digital_gain), | |
3163 | SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD934X_CDC_RX7_RX_VOL_CTL, | |
3164 | -84, 40, digital_gain), | |
3165 | SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD934X_CDC_RX8_RX_VOL_CTL, | |
3166 | -84, 40, digital_gain), | |
3167 | SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", | |
3168 | WCD934X_CDC_RX0_RX_VOL_MIX_CTL, | |
3169 | -84, 40, digital_gain), | |
3170 | SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", | |
3171 | WCD934X_CDC_RX1_RX_VOL_MIX_CTL, | |
3172 | -84, 40, digital_gain), | |
3173 | SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", | |
3174 | WCD934X_CDC_RX2_RX_VOL_MIX_CTL, | |
3175 | -84, 40, digital_gain), | |
3176 | SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", | |
3177 | WCD934X_CDC_RX3_RX_VOL_MIX_CTL, | |
3178 | -84, 40, digital_gain), | |
3179 | SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", | |
3180 | WCD934X_CDC_RX4_RX_VOL_MIX_CTL, | |
3181 | -84, 40, digital_gain), | |
3182 | SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", | |
3183 | WCD934X_CDC_RX7_RX_VOL_MIX_CTL, | |
3184 | -84, 40, digital_gain), | |
3185 | SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", | |
3186 | WCD934X_CDC_RX8_RX_VOL_MIX_CTL, | |
3187 | -84, 40, digital_gain), | |
3188 | ||
3189 | SOC_SINGLE_S8_TLV("DEC0 Volume", WCD934X_CDC_TX0_TX_VOL_CTL, | |
3190 | -84, 40, digital_gain), | |
3191 | SOC_SINGLE_S8_TLV("DEC1 Volume", WCD934X_CDC_TX1_TX_VOL_CTL, | |
3192 | -84, 40, digital_gain), | |
3193 | SOC_SINGLE_S8_TLV("DEC2 Volume", WCD934X_CDC_TX2_TX_VOL_CTL, | |
3194 | -84, 40, digital_gain), | |
3195 | SOC_SINGLE_S8_TLV("DEC3 Volume", WCD934X_CDC_TX3_TX_VOL_CTL, | |
3196 | -84, 40, digital_gain), | |
3197 | SOC_SINGLE_S8_TLV("DEC4 Volume", WCD934X_CDC_TX4_TX_VOL_CTL, | |
3198 | -84, 40, digital_gain), | |
3199 | SOC_SINGLE_S8_TLV("DEC5 Volume", WCD934X_CDC_TX5_TX_VOL_CTL, | |
3200 | -84, 40, digital_gain), | |
3201 | SOC_SINGLE_S8_TLV("DEC6 Volume", WCD934X_CDC_TX6_TX_VOL_CTL, | |
3202 | -84, 40, digital_gain), | |
3203 | SOC_SINGLE_S8_TLV("DEC7 Volume", WCD934X_CDC_TX7_TX_VOL_CTL, | |
3204 | -84, 40, digital_gain), | |
3205 | SOC_SINGLE_S8_TLV("DEC8 Volume", WCD934X_CDC_TX8_TX_VOL_CTL, | |
3206 | -84, 40, digital_gain), | |
3207 | ||
3208 | SOC_SINGLE_S8_TLV("IIR0 INP0 Volume", | |
3209 | WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, -84, 40, | |
3210 | digital_gain), | |
3211 | SOC_SINGLE_S8_TLV("IIR0 INP1 Volume", | |
3212 | WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, -84, 40, | |
3213 | digital_gain), | |
3214 | SOC_SINGLE_S8_TLV("IIR0 INP2 Volume", | |
3215 | WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, -84, 40, | |
3216 | digital_gain), | |
3217 | SOC_SINGLE_S8_TLV("IIR0 INP3 Volume", | |
3218 | WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, -84, 40, | |
3219 | digital_gain), | |
3220 | SOC_SINGLE_S8_TLV("IIR1 INP0 Volume", | |
3221 | WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, -84, 40, | |
3222 | digital_gain), | |
3223 | SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", | |
3224 | WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL, -84, 40, | |
3225 | digital_gain), | |
3226 | SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", | |
3227 | WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL, -84, 40, | |
3228 | digital_gain), | |
3229 | SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", | |
3230 | WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, -84, 40, | |
3231 | digital_gain), | |
3232 | ||
3233 | SOC_ENUM("TX0 HPF cut off", cf_dec0_enum), | |
3234 | SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), | |
3235 | SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), | |
3236 | SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), | |
3237 | SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), | |
3238 | SOC_ENUM("TX5 HPF cut off", cf_dec5_enum), | |
3239 | SOC_ENUM("TX6 HPF cut off", cf_dec6_enum), | |
3240 | SOC_ENUM("TX7 HPF cut off", cf_dec7_enum), | |
3241 | SOC_ENUM("TX8 HPF cut off", cf_dec8_enum), | |
3242 | ||
3243 | SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), | |
3244 | SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), | |
3245 | SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum), | |
3246 | SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum), | |
3247 | SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum), | |
3248 | SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum), | |
3249 | SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum), | |
3250 | SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum), | |
3251 | SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum), | |
3252 | SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum), | |
3253 | SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum), | |
3254 | SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum), | |
3255 | SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum), | |
3256 | SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum), | |
3257 | ||
3258 | SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, | |
3259 | wcd934x_rx_hph_mode_get, wcd934x_rx_hph_mode_put), | |
3260 | ||
3261 | SOC_SINGLE("IIR1 Band1 Switch", WCD934X_CDC_SIDETONE_IIR0_IIR_CTL, | |
3262 | 0, 1, 0), | |
3263 | SOC_SINGLE("IIR1 Band2 Switch", WCD934X_CDC_SIDETONE_IIR0_IIR_CTL, | |
3264 | 1, 1, 0), | |
3265 | SOC_SINGLE("IIR1 Band3 Switch", WCD934X_CDC_SIDETONE_IIR0_IIR_CTL, | |
3266 | 2, 1, 0), | |
3267 | SOC_SINGLE("IIR1 Band4 Switch", WCD934X_CDC_SIDETONE_IIR0_IIR_CTL, | |
3268 | 3, 1, 0), | |
3269 | SOC_SINGLE("IIR1 Band5 Switch", WCD934X_CDC_SIDETONE_IIR0_IIR_CTL, | |
3270 | 4, 1, 0), | |
3271 | SOC_SINGLE("IIR2 Band1 Switch", WCD934X_CDC_SIDETONE_IIR1_IIR_CTL, | |
3272 | 0, 1, 0), | |
3273 | SOC_SINGLE("IIR2 Band2 Switch", WCD934X_CDC_SIDETONE_IIR1_IIR_CTL, | |
3274 | 1, 1, 0), | |
3275 | SOC_SINGLE("IIR2 Band3 Switch", WCD934X_CDC_SIDETONE_IIR1_IIR_CTL, | |
3276 | 2, 1, 0), | |
3277 | SOC_SINGLE("IIR2 Band4 Switch", WCD934X_CDC_SIDETONE_IIR1_IIR_CTL, | |
3278 | 3, 1, 0), | |
3279 | SOC_SINGLE("IIR2 Band5 Switch", WCD934X_CDC_SIDETONE_IIR1_IIR_CTL, | |
3280 | 4, 1, 0), | |
3281 | WCD_IIR_FILTER_CTL("IIR0 Band1", IIR0, BAND1), | |
3282 | WCD_IIR_FILTER_CTL("IIR0 Band2", IIR0, BAND2), | |
3283 | WCD_IIR_FILTER_CTL("IIR0 Band3", IIR0, BAND3), | |
3284 | WCD_IIR_FILTER_CTL("IIR0 Band4", IIR0, BAND4), | |
3285 | WCD_IIR_FILTER_CTL("IIR0 Band5", IIR0, BAND5), | |
3286 | ||
3287 | WCD_IIR_FILTER_CTL("IIR1 Band1", IIR1, BAND1), | |
3288 | WCD_IIR_FILTER_CTL("IIR1 Band2", IIR1, BAND2), | |
3289 | WCD_IIR_FILTER_CTL("IIR1 Band3", IIR1, BAND3), | |
3290 | WCD_IIR_FILTER_CTL("IIR1 Band4", IIR1, BAND4), | |
3291 | WCD_IIR_FILTER_CTL("IIR1 Band5", IIR1, BAND5), | |
3292 | ||
3293 | SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0, | |
3294 | wcd934x_compander_get, wcd934x_compander_set), | |
3295 | SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0, | |
3296 | wcd934x_compander_get, wcd934x_compander_set), | |
3297 | SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0, | |
3298 | wcd934x_compander_get, wcd934x_compander_set), | |
3299 | SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0, | |
3300 | wcd934x_compander_get, wcd934x_compander_set), | |
3301 | SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0, | |
3302 | wcd934x_compander_get, wcd934x_compander_set), | |
3303 | SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0, | |
3304 | wcd934x_compander_get, wcd934x_compander_set), | |
3305 | }; | |
3306 | ||
dd9eb19b SK |
3307 | static void wcd934x_codec_enable_int_port(struct wcd_slim_codec_dai_data *dai, |
3308 | struct snd_soc_component *component) | |
3309 | { | |
3310 | int port_num = 0; | |
3311 | unsigned short reg = 0; | |
3312 | unsigned int val = 0; | |
3313 | struct wcd934x_codec *wcd = dev_get_drvdata(component->dev); | |
3314 | struct wcd934x_slim_ch *ch; | |
3315 | ||
3316 | list_for_each_entry(ch, &dai->slim_ch_list, list) { | |
3317 | if (ch->port >= WCD934X_RX_START) { | |
3318 | port_num = ch->port - WCD934X_RX_START; | |
3319 | reg = WCD934X_SLIM_PGD_PORT_INT_EN0 + (port_num / 8); | |
3320 | } else { | |
3321 | port_num = ch->port; | |
3322 | reg = WCD934X_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8); | |
3323 | } | |
3324 | ||
3325 | regmap_read(wcd->if_regmap, reg, &val); | |
3326 | if (!(val & BIT(port_num % 8))) | |
3327 | regmap_write(wcd->if_regmap, reg, | |
3328 | val | BIT(port_num % 8)); | |
3329 | } | |
3330 | } | |
3331 | ||
3332 | static int wcd934x_codec_enable_slim(struct snd_soc_dapm_widget *w, | |
3333 | struct snd_kcontrol *kc, int event) | |
3334 | { | |
3335 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3336 | struct wcd934x_codec *wcd = snd_soc_component_get_drvdata(comp); | |
3337 | struct wcd_slim_codec_dai_data *dai = &wcd->dai[w->shift]; | |
3338 | ||
3339 | switch (event) { | |
3340 | case SND_SOC_DAPM_POST_PMU: | |
3341 | wcd934x_codec_enable_int_port(dai, comp); | |
3342 | break; | |
3343 | } | |
3344 | ||
3345 | return 0; | |
3346 | } | |
3347 | ||
3348 | static void wcd934x_codec_hd2_control(struct snd_soc_component *component, | |
3349 | u16 interp_idx, int event) | |
3350 | { | |
3351 | u16 hd2_scale_reg; | |
3352 | u16 hd2_enable_reg = 0; | |
3353 | ||
3354 | switch (interp_idx) { | |
3355 | case INTERP_HPHL: | |
3356 | hd2_scale_reg = WCD934X_CDC_RX1_RX_PATH_SEC3; | |
3357 | hd2_enable_reg = WCD934X_CDC_RX1_RX_PATH_CFG0; | |
3358 | break; | |
3359 | case INTERP_HPHR: | |
3360 | hd2_scale_reg = WCD934X_CDC_RX2_RX_PATH_SEC3; | |
3361 | hd2_enable_reg = WCD934X_CDC_RX2_RX_PATH_CFG0; | |
3362 | break; | |
3363 | default: | |
3364 | return; | |
3365 | } | |
3366 | ||
3367 | if (SND_SOC_DAPM_EVENT_ON(event)) { | |
3368 | snd_soc_component_update_bits(component, hd2_scale_reg, | |
3369 | WCD934X_CDC_RX_PATH_SEC_HD2_ALPHA_MASK, | |
3370 | WCD934X_CDC_RX_PATH_SEC_HD2_ALPHA_0P3125); | |
3371 | snd_soc_component_update_bits(component, hd2_enable_reg, | |
3372 | WCD934X_CDC_RX_PATH_CFG_HD2_EN_MASK, | |
3373 | WCD934X_CDC_RX_PATH_CFG_HD2_ENABLE); | |
3374 | } | |
3375 | ||
3376 | if (SND_SOC_DAPM_EVENT_OFF(event)) { | |
3377 | snd_soc_component_update_bits(component, hd2_enable_reg, | |
3378 | WCD934X_CDC_RX_PATH_CFG_HD2_EN_MASK, | |
3379 | WCD934X_CDC_RX_PATH_CFG_HD2_DISABLE); | |
3380 | snd_soc_component_update_bits(component, hd2_scale_reg, | |
3381 | WCD934X_CDC_RX_PATH_SEC_HD2_ALPHA_MASK, | |
3382 | WCD934X_CDC_RX_PATH_SEC_HD2_ALPHA_0P0000); | |
3383 | } | |
3384 | } | |
3385 | ||
3386 | static void wcd934x_codec_hphdelay_lutbypass(struct snd_soc_component *comp, | |
3387 | u16 interp_idx, int event) | |
3388 | { | |
3389 | u8 hph_dly_mask; | |
3390 | u16 hph_lut_bypass_reg = 0; | |
dd9eb19b SK |
3391 | |
3392 | switch (interp_idx) { | |
3393 | case INTERP_HPHL: | |
3394 | hph_dly_mask = 1; | |
3395 | hph_lut_bypass_reg = WCD934X_CDC_TOP_HPHL_COMP_LUT; | |
dd9eb19b SK |
3396 | break; |
3397 | case INTERP_HPHR: | |
3398 | hph_dly_mask = 2; | |
3399 | hph_lut_bypass_reg = WCD934X_CDC_TOP_HPHR_COMP_LUT; | |
dd9eb19b SK |
3400 | break; |
3401 | default: | |
3402 | return; | |
3403 | } | |
3404 | ||
3405 | if (SND_SOC_DAPM_EVENT_ON(event)) { | |
3406 | snd_soc_component_update_bits(comp, WCD934X_CDC_CLSH_TEST0, | |
3407 | hph_dly_mask, 0x0); | |
3408 | snd_soc_component_update_bits(comp, hph_lut_bypass_reg, | |
3409 | WCD934X_HPH_LUT_BYPASS_MASK, | |
3410 | WCD934X_HPH_LUT_BYPASS_ENABLE); | |
3411 | } | |
3412 | ||
3413 | if (SND_SOC_DAPM_EVENT_OFF(event)) { | |
3414 | snd_soc_component_update_bits(comp, WCD934X_CDC_CLSH_TEST0, | |
3415 | hph_dly_mask, hph_dly_mask); | |
3416 | snd_soc_component_update_bits(comp, hph_lut_bypass_reg, | |
3417 | WCD934X_HPH_LUT_BYPASS_MASK, | |
3418 | WCD934X_HPH_LUT_BYPASS_DISABLE); | |
3419 | } | |
3420 | } | |
3421 | ||
3422 | static int wcd934x_config_compander(struct snd_soc_component *comp, | |
3423 | int interp_n, int event) | |
3424 | { | |
3425 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
3426 | int compander; | |
3427 | u16 comp_ctl0_reg, rx_path_cfg0_reg; | |
3428 | ||
3429 | /* EAR does not have compander */ | |
3430 | if (!interp_n) | |
3431 | return 0; | |
3432 | ||
3433 | compander = interp_n - 1; | |
3434 | if (!wcd->comp_enabled[compander]) | |
3435 | return 0; | |
3436 | ||
3437 | comp_ctl0_reg = WCD934X_CDC_COMPANDER1_CTL0 + (compander * 8); | |
3438 | rx_path_cfg0_reg = WCD934X_CDC_RX1_RX_PATH_CFG0 + (compander * 20); | |
3439 | ||
3440 | switch (event) { | |
3441 | case SND_SOC_DAPM_PRE_PMU: | |
3442 | /* Enable Compander Clock */ | |
3443 | snd_soc_component_update_bits(comp, comp_ctl0_reg, | |
3444 | WCD934X_COMP_CLK_EN_MASK, | |
3445 | WCD934X_COMP_CLK_ENABLE); | |
3446 | snd_soc_component_update_bits(comp, comp_ctl0_reg, | |
3447 | WCD934X_COMP_SOFT_RST_MASK, | |
3448 | WCD934X_COMP_SOFT_RST_ENABLE); | |
3449 | snd_soc_component_update_bits(comp, comp_ctl0_reg, | |
3450 | WCD934X_COMP_SOFT_RST_MASK, | |
3451 | WCD934X_COMP_SOFT_RST_DISABLE); | |
3452 | snd_soc_component_update_bits(comp, rx_path_cfg0_reg, | |
3453 | WCD934X_HPH_CMP_EN_MASK, | |
3454 | WCD934X_HPH_CMP_ENABLE); | |
3455 | break; | |
3456 | case SND_SOC_DAPM_POST_PMD: | |
3457 | snd_soc_component_update_bits(comp, rx_path_cfg0_reg, | |
3458 | WCD934X_HPH_CMP_EN_MASK, | |
3459 | WCD934X_HPH_CMP_DISABLE); | |
3460 | snd_soc_component_update_bits(comp, comp_ctl0_reg, | |
3461 | WCD934X_COMP_HALT_MASK, | |
3462 | WCD934X_COMP_HALT); | |
3463 | snd_soc_component_update_bits(comp, comp_ctl0_reg, | |
3464 | WCD934X_COMP_SOFT_RST_MASK, | |
3465 | WCD934X_COMP_SOFT_RST_ENABLE); | |
3466 | snd_soc_component_update_bits(comp, comp_ctl0_reg, | |
3467 | WCD934X_COMP_SOFT_RST_MASK, | |
3468 | WCD934X_COMP_SOFT_RST_DISABLE); | |
3469 | snd_soc_component_update_bits(comp, comp_ctl0_reg, | |
3470 | WCD934X_COMP_CLK_EN_MASK, 0x0); | |
3471 | snd_soc_component_update_bits(comp, comp_ctl0_reg, | |
3472 | WCD934X_COMP_SOFT_RST_MASK, 0x0); | |
3473 | break; | |
3474 | } | |
3475 | ||
3476 | return 0; | |
3477 | } | |
3478 | ||
3479 | static int wcd934x_codec_enable_interp_clk(struct snd_soc_dapm_widget *w, | |
3480 | struct snd_kcontrol *kc, int event) | |
3481 | { | |
3482 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3483 | int interp_idx = w->shift; | |
3484 | u16 main_reg = WCD934X_CDC_RX0_RX_PATH_CTL + (interp_idx * 20); | |
3485 | ||
3486 | switch (event) { | |
3487 | case SND_SOC_DAPM_PRE_PMU: | |
3488 | /* Clk enable */ | |
3489 | snd_soc_component_update_bits(comp, main_reg, | |
3490 | WCD934X_RX_CLK_EN_MASK, | |
3491 | WCD934X_RX_CLK_ENABLE); | |
3492 | wcd934x_codec_hd2_control(comp, interp_idx, event); | |
3493 | wcd934x_codec_hphdelay_lutbypass(comp, interp_idx, event); | |
3494 | wcd934x_config_compander(comp, interp_idx, event); | |
3495 | break; | |
3496 | case SND_SOC_DAPM_POST_PMD: | |
3497 | wcd934x_config_compander(comp, interp_idx, event); | |
3498 | wcd934x_codec_hphdelay_lutbypass(comp, interp_idx, event); | |
3499 | wcd934x_codec_hd2_control(comp, interp_idx, event); | |
3500 | /* Clk Disable */ | |
3501 | snd_soc_component_update_bits(comp, main_reg, | |
3502 | WCD934X_RX_CLK_EN_MASK, 0); | |
3503 | /* Reset enable and disable */ | |
3504 | snd_soc_component_update_bits(comp, main_reg, | |
3505 | WCD934X_RX_RESET_MASK, | |
3506 | WCD934X_RX_RESET_ENABLE); | |
3507 | snd_soc_component_update_bits(comp, main_reg, | |
3508 | WCD934X_RX_RESET_MASK, | |
3509 | WCD934X_RX_RESET_DISABLE); | |
3510 | /* Reset rate to 48K*/ | |
3511 | snd_soc_component_update_bits(comp, main_reg, | |
3512 | WCD934X_RX_PCM_RATE_MASK, | |
3513 | WCD934X_RX_PCM_RATE_F_48K); | |
3514 | break; | |
3515 | } | |
3516 | ||
3517 | return 0; | |
3518 | } | |
3519 | ||
3520 | static int wcd934x_codec_enable_mix_path(struct snd_soc_dapm_widget *w, | |
3521 | struct snd_kcontrol *kc, int event) | |
3522 | { | |
3523 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3524 | int offset_val = 0; | |
3525 | u16 gain_reg, mix_reg; | |
3526 | int val = 0; | |
3527 | ||
3528 | gain_reg = WCD934X_CDC_RX0_RX_VOL_MIX_CTL + | |
3529 | (w->shift * WCD934X_RX_PATH_CTL_OFFSET); | |
3530 | mix_reg = WCD934X_CDC_RX0_RX_PATH_MIX_CTL + | |
3531 | (w->shift * WCD934X_RX_PATH_CTL_OFFSET); | |
3532 | ||
3533 | switch (event) { | |
3534 | case SND_SOC_DAPM_PRE_PMU: | |
3535 | /* Clk enable */ | |
3536 | snd_soc_component_update_bits(comp, mix_reg, | |
3537 | WCD934X_CDC_RX_MIX_CLK_EN_MASK, | |
3538 | WCD934X_CDC_RX_MIX_CLK_ENABLE); | |
3539 | break; | |
3540 | ||
3541 | case SND_SOC_DAPM_POST_PMU: | |
eaf2767c | 3542 | val = snd_soc_component_read(comp, gain_reg); |
dd9eb19b SK |
3543 | val += offset_val; |
3544 | snd_soc_component_write(comp, gain_reg, val); | |
3545 | break; | |
e48e83d1 | 3546 | } |
dd9eb19b SK |
3547 | |
3548 | return 0; | |
3549 | } | |
3550 | ||
3551 | static int wcd934x_codec_set_iir_gain(struct snd_soc_dapm_widget *w, | |
3552 | struct snd_kcontrol *kcontrol, int event) | |
3553 | { | |
3554 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3555 | int reg = w->reg; | |
3556 | ||
3557 | switch (event) { | |
3558 | case SND_SOC_DAPM_POST_PMU: | |
3559 | /* B1 GAIN */ | |
3560 | snd_soc_component_write(comp, reg, | |
eaf2767c | 3561 | snd_soc_component_read(comp, reg)); |
dd9eb19b SK |
3562 | /* B2 GAIN */ |
3563 | reg++; | |
3564 | snd_soc_component_write(comp, reg, | |
eaf2767c | 3565 | snd_soc_component_read(comp, reg)); |
dd9eb19b SK |
3566 | /* B3 GAIN */ |
3567 | reg++; | |
3568 | snd_soc_component_write(comp, reg, | |
eaf2767c | 3569 | snd_soc_component_read(comp, reg)); |
dd9eb19b SK |
3570 | /* B4 GAIN */ |
3571 | reg++; | |
3572 | snd_soc_component_write(comp, reg, | |
eaf2767c | 3573 | snd_soc_component_read(comp, reg)); |
dd9eb19b SK |
3574 | /* B5 GAIN */ |
3575 | reg++; | |
3576 | snd_soc_component_write(comp, reg, | |
eaf2767c | 3577 | snd_soc_component_read(comp, reg)); |
dd9eb19b SK |
3578 | break; |
3579 | default: | |
3580 | break; | |
3581 | } | |
3582 | return 0; | |
3583 | } | |
3584 | ||
3585 | static int wcd934x_codec_enable_main_path(struct snd_soc_dapm_widget *w, | |
3586 | struct snd_kcontrol *kcontrol, | |
3587 | int event) | |
3588 | { | |
3589 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3590 | u16 gain_reg; | |
3591 | ||
3592 | gain_reg = WCD934X_CDC_RX0_RX_VOL_CTL + (w->shift * | |
3593 | WCD934X_RX_PATH_CTL_OFFSET); | |
3594 | ||
3595 | switch (event) { | |
3596 | case SND_SOC_DAPM_POST_PMU: | |
3597 | snd_soc_component_write(comp, gain_reg, | |
eaf2767c | 3598 | snd_soc_component_read(comp, gain_reg)); |
dd9eb19b | 3599 | break; |
e48e83d1 | 3600 | } |
dd9eb19b SK |
3601 | |
3602 | return 0; | |
3603 | } | |
3604 | ||
3605 | static int wcd934x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, | |
3606 | struct snd_kcontrol *kc, int event) | |
3607 | { | |
3608 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3609 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
3610 | ||
3611 | switch (event) { | |
3612 | case SND_SOC_DAPM_PRE_PMU: | |
3613 | /* Disable AutoChop timer during power up */ | |
3614 | snd_soc_component_update_bits(comp, | |
3615 | WCD934X_HPH_NEW_INT_HPH_TIMER1, | |
3616 | WCD934X_HPH_AUTOCHOP_TIMER_EN_MASK, 0x0); | |
3617 | wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, | |
3618 | WCD_CLSH_STATE_EAR, CLS_H_NORMAL); | |
3619 | ||
3620 | break; | |
3621 | case SND_SOC_DAPM_POST_PMD: | |
3622 | wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, | |
3623 | WCD_CLSH_STATE_EAR, CLS_H_NORMAL); | |
3624 | break; | |
e48e83d1 | 3625 | } |
dd9eb19b SK |
3626 | |
3627 | return 0; | |
3628 | } | |
3629 | ||
3630 | static int wcd934x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, | |
3631 | struct snd_kcontrol *kcontrol, | |
3632 | int event) | |
3633 | { | |
3634 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3635 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
3636 | int hph_mode = wcd->hph_mode; | |
3637 | u8 dem_inp; | |
3638 | ||
3639 | switch (event) { | |
3640 | case SND_SOC_DAPM_PRE_PMU: | |
3641 | /* Read DEM INP Select */ | |
eaf2767c | 3642 | dem_inp = snd_soc_component_read(comp, |
dd9eb19b SK |
3643 | WCD934X_CDC_RX1_RX_PATH_SEC0) & 0x03; |
3644 | ||
3645 | if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || | |
3646 | (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { | |
3647 | return -EINVAL; | |
3648 | } | |
3649 | if (hph_mode != CLS_H_LP) | |
3650 | /* Ripple freq control enable */ | |
3651 | snd_soc_component_update_bits(comp, | |
3652 | WCD934X_SIDO_NEW_VOUT_D_FREQ2, | |
3653 | WCD934X_SIDO_RIPPLE_FREQ_EN_MASK, | |
3654 | WCD934X_SIDO_RIPPLE_FREQ_ENABLE); | |
3655 | /* Disable AutoChop timer during power up */ | |
3656 | snd_soc_component_update_bits(comp, | |
3657 | WCD934X_HPH_NEW_INT_HPH_TIMER1, | |
3658 | WCD934X_HPH_AUTOCHOP_TIMER_EN_MASK, 0x0); | |
3659 | wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, | |
3660 | WCD_CLSH_STATE_HPHL, hph_mode); | |
3661 | ||
3662 | break; | |
3663 | case SND_SOC_DAPM_POST_PMD: | |
3664 | /* 1000us required as per HW requirement */ | |
3665 | usleep_range(1000, 1100); | |
3666 | wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, | |
3667 | WCD_CLSH_STATE_HPHL, hph_mode); | |
3668 | if (hph_mode != CLS_H_LP) | |
3669 | /* Ripple freq control disable */ | |
3670 | snd_soc_component_update_bits(comp, | |
3671 | WCD934X_SIDO_NEW_VOUT_D_FREQ2, | |
3672 | WCD934X_SIDO_RIPPLE_FREQ_EN_MASK, 0x0); | |
3673 | ||
3674 | break; | |
3675 | default: | |
3676 | break; | |
e48e83d1 | 3677 | } |
dd9eb19b SK |
3678 | |
3679 | return 0; | |
3680 | } | |
3681 | ||
3682 | static int wcd934x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, | |
3683 | struct snd_kcontrol *kcontrol, | |
3684 | int event) | |
3685 | { | |
3686 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3687 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
3688 | int hph_mode = wcd->hph_mode; | |
3689 | u8 dem_inp; | |
3690 | ||
3691 | switch (event) { | |
3692 | case SND_SOC_DAPM_PRE_PMU: | |
eaf2767c | 3693 | dem_inp = snd_soc_component_read(comp, |
dd9eb19b SK |
3694 | WCD934X_CDC_RX2_RX_PATH_SEC0) & 0x03; |
3695 | if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || | |
3696 | (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { | |
3697 | return -EINVAL; | |
3698 | } | |
3699 | if (hph_mode != CLS_H_LP) | |
3700 | /* Ripple freq control enable */ | |
3701 | snd_soc_component_update_bits(comp, | |
3702 | WCD934X_SIDO_NEW_VOUT_D_FREQ2, | |
3703 | WCD934X_SIDO_RIPPLE_FREQ_EN_MASK, | |
3704 | WCD934X_SIDO_RIPPLE_FREQ_ENABLE); | |
3705 | /* Disable AutoChop timer during power up */ | |
3706 | snd_soc_component_update_bits(comp, | |
3707 | WCD934X_HPH_NEW_INT_HPH_TIMER1, | |
3708 | WCD934X_HPH_AUTOCHOP_TIMER_EN_MASK, 0x0); | |
3709 | wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, | |
3710 | WCD_CLSH_STATE_HPHR, | |
3711 | hph_mode); | |
3712 | break; | |
3713 | case SND_SOC_DAPM_POST_PMD: | |
3714 | /* 1000us required as per HW requirement */ | |
3715 | usleep_range(1000, 1100); | |
3716 | ||
3717 | wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, | |
3718 | WCD_CLSH_STATE_HPHR, hph_mode); | |
3719 | if (hph_mode != CLS_H_LP) | |
3720 | /* Ripple freq control disable */ | |
3721 | snd_soc_component_update_bits(comp, | |
3722 | WCD934X_SIDO_NEW_VOUT_D_FREQ2, | |
3723 | WCD934X_SIDO_RIPPLE_FREQ_EN_MASK, 0x0); | |
3724 | break; | |
3725 | default: | |
3726 | break; | |
e48e83d1 | 3727 | } |
dd9eb19b SK |
3728 | |
3729 | return 0; | |
3730 | } | |
3731 | ||
3732 | static int wcd934x_codec_lineout_dac_event(struct snd_soc_dapm_widget *w, | |
3733 | struct snd_kcontrol *kc, int event) | |
3734 | { | |
3735 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3736 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
3737 | ||
3738 | switch (event) { | |
3739 | case SND_SOC_DAPM_PRE_PMU: | |
3740 | wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, | |
3741 | WCD_CLSH_STATE_LO, CLS_AB); | |
3742 | break; | |
3743 | case SND_SOC_DAPM_POST_PMD: | |
3744 | wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, | |
3745 | WCD_CLSH_STATE_LO, CLS_AB); | |
3746 | break; | |
3747 | } | |
3748 | ||
3749 | return 0; | |
3750 | } | |
3751 | ||
3752 | static int wcd934x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, | |
3753 | struct snd_kcontrol *kcontrol, | |
3754 | int event) | |
3755 | { | |
3756 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3757 | ||
3758 | switch (event) { | |
3759 | case SND_SOC_DAPM_POST_PMU: | |
3760 | /* | |
3761 | * 7ms sleep is required after PA is enabled as per | |
3762 | * HW requirement. If compander is disabled, then | |
3763 | * 20ms delay is needed. | |
3764 | */ | |
3765 | usleep_range(20000, 20100); | |
3766 | ||
3767 | snd_soc_component_update_bits(comp, WCD934X_HPH_L_TEST, | |
3768 | WCD934X_HPH_OCP_DET_MASK, | |
3769 | WCD934X_HPH_OCP_DET_ENABLE); | |
3770 | /* Remove Mute on primary path */ | |
3771 | snd_soc_component_update_bits(comp, WCD934X_CDC_RX1_RX_PATH_CTL, | |
3772 | WCD934X_RX_PATH_PGA_MUTE_EN_MASK, | |
3773 | 0); | |
3774 | /* Enable GM3 boost */ | |
3775 | snd_soc_component_update_bits(comp, WCD934X_HPH_CNP_WG_CTL, | |
3776 | WCD934X_HPH_GM3_BOOST_EN_MASK, | |
3777 | WCD934X_HPH_GM3_BOOST_ENABLE); | |
3778 | /* Enable AutoChop timer at the end of power up */ | |
3779 | snd_soc_component_update_bits(comp, | |
3780 | WCD934X_HPH_NEW_INT_HPH_TIMER1, | |
3781 | WCD934X_HPH_AUTOCHOP_TIMER_EN_MASK, | |
3782 | WCD934X_HPH_AUTOCHOP_TIMER_ENABLE); | |
3783 | /* Remove mix path mute */ | |
3784 | snd_soc_component_update_bits(comp, | |
3785 | WCD934X_CDC_RX1_RX_PATH_MIX_CTL, | |
3786 | WCD934X_CDC_RX_PGA_MUTE_EN_MASK, 0x00); | |
3787 | break; | |
3788 | case SND_SOC_DAPM_PRE_PMD: | |
3789 | /* Enable DSD Mute before PA disable */ | |
3790 | snd_soc_component_update_bits(comp, WCD934X_HPH_L_TEST, | |
3791 | WCD934X_HPH_OCP_DET_MASK, | |
3792 | WCD934X_HPH_OCP_DET_DISABLE); | |
3793 | snd_soc_component_update_bits(comp, WCD934X_CDC_RX1_RX_PATH_CTL, | |
3794 | WCD934X_RX_PATH_PGA_MUTE_EN_MASK, | |
3795 | WCD934X_RX_PATH_PGA_MUTE_ENABLE); | |
3796 | snd_soc_component_update_bits(comp, | |
3797 | WCD934X_CDC_RX1_RX_PATH_MIX_CTL, | |
3798 | WCD934X_RX_PATH_PGA_MUTE_EN_MASK, | |
3799 | WCD934X_RX_PATH_PGA_MUTE_ENABLE); | |
3800 | break; | |
3801 | case SND_SOC_DAPM_POST_PMD: | |
3802 | /* | |
3803 | * 5ms sleep is required after PA disable. If compander is | |
3804 | * disabled, then 20ms delay is needed after PA disable. | |
3805 | */ | |
3806 | usleep_range(20000, 20100); | |
3807 | break; | |
e48e83d1 | 3808 | } |
dd9eb19b SK |
3809 | |
3810 | return 0; | |
3811 | } | |
3812 | ||
3813 | static int wcd934x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, | |
3814 | struct snd_kcontrol *kcontrol, | |
3815 | int event) | |
3816 | { | |
3817 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3818 | ||
3819 | switch (event) { | |
3820 | case SND_SOC_DAPM_POST_PMU: | |
3821 | /* | |
3822 | * 7ms sleep is required after PA is enabled as per | |
3823 | * HW requirement. If compander is disabled, then | |
3824 | * 20ms delay is needed. | |
3825 | */ | |
3826 | usleep_range(20000, 20100); | |
3827 | snd_soc_component_update_bits(comp, WCD934X_HPH_R_TEST, | |
3828 | WCD934X_HPH_OCP_DET_MASK, | |
3829 | WCD934X_HPH_OCP_DET_ENABLE); | |
3830 | /* Remove mute */ | |
3831 | snd_soc_component_update_bits(comp, WCD934X_CDC_RX2_RX_PATH_CTL, | |
3832 | WCD934X_RX_PATH_PGA_MUTE_EN_MASK, | |
3833 | 0); | |
3834 | /* Enable GM3 boost */ | |
3835 | snd_soc_component_update_bits(comp, WCD934X_HPH_CNP_WG_CTL, | |
3836 | WCD934X_HPH_GM3_BOOST_EN_MASK, | |
3837 | WCD934X_HPH_GM3_BOOST_ENABLE); | |
3838 | /* Enable AutoChop timer at the end of power up */ | |
3839 | snd_soc_component_update_bits(comp, | |
3840 | WCD934X_HPH_NEW_INT_HPH_TIMER1, | |
3841 | WCD934X_HPH_AUTOCHOP_TIMER_EN_MASK, | |
3842 | WCD934X_HPH_AUTOCHOP_TIMER_ENABLE); | |
3843 | /* Remove mix path mute if it is enabled */ | |
eaf2767c | 3844 | if ((snd_soc_component_read(comp, |
dd9eb19b SK |
3845 | WCD934X_CDC_RX2_RX_PATH_MIX_CTL)) & 0x10) |
3846 | snd_soc_component_update_bits(comp, | |
3847 | WCD934X_CDC_RX2_RX_PATH_MIX_CTL, | |
3848 | WCD934X_CDC_RX_PGA_MUTE_EN_MASK, | |
3849 | WCD934X_CDC_RX_PGA_MUTE_DISABLE); | |
3850 | break; | |
3851 | case SND_SOC_DAPM_PRE_PMD: | |
3852 | snd_soc_component_update_bits(comp, WCD934X_HPH_R_TEST, | |
3853 | WCD934X_HPH_OCP_DET_MASK, | |
3854 | WCD934X_HPH_OCP_DET_DISABLE); | |
3855 | snd_soc_component_update_bits(comp, WCD934X_CDC_RX2_RX_PATH_CTL, | |
3856 | WCD934X_RX_PATH_PGA_MUTE_EN_MASK, | |
3857 | WCD934X_RX_PATH_PGA_MUTE_ENABLE); | |
3858 | snd_soc_component_update_bits(comp, | |
3859 | WCD934X_CDC_RX2_RX_PATH_MIX_CTL, | |
3860 | WCD934X_CDC_RX_PGA_MUTE_EN_MASK, | |
3861 | WCD934X_CDC_RX_PGA_MUTE_ENABLE); | |
3862 | break; | |
3863 | case SND_SOC_DAPM_POST_PMD: | |
3864 | /* | |
3865 | * 5ms sleep is required after PA disable. If compander is | |
3866 | * disabled, then 20ms delay is needed after PA disable. | |
3867 | */ | |
3868 | usleep_range(20000, 20100); | |
3869 | break; | |
e48e83d1 | 3870 | } |
dd9eb19b SK |
3871 | |
3872 | return 0; | |
3873 | } | |
3874 | ||
a70d9245 SK |
3875 | static u32 wcd934x_get_dmic_sample_rate(struct snd_soc_component *comp, |
3876 | unsigned int dmic, | |
3877 | struct wcd934x_codec *wcd) | |
3878 | { | |
3879 | u8 tx_stream_fs; | |
3880 | u8 adc_mux_index = 0, adc_mux_sel = 0; | |
3881 | bool dec_found = false; | |
3882 | u16 adc_mux_ctl_reg, tx_fs_reg; | |
3883 | u32 dmic_fs; | |
3884 | ||
4f05b5c6 | 3885 | while (!dec_found && adc_mux_index < WCD934X_MAX_VALID_ADC_MUX) { |
a70d9245 SK |
3886 | if (adc_mux_index < 4) { |
3887 | adc_mux_ctl_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + | |
3888 | (adc_mux_index * 2); | |
3889 | } else if (adc_mux_index < WCD934X_INVALID_ADC_MUX) { | |
3890 | adc_mux_ctl_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + | |
3891 | adc_mux_index - 4; | |
3892 | } else if (adc_mux_index == WCD934X_INVALID_ADC_MUX) { | |
3893 | ++adc_mux_index; | |
3894 | continue; | |
3895 | } | |
eaf2767c | 3896 | adc_mux_sel = ((snd_soc_component_read(comp, adc_mux_ctl_reg) |
a70d9245 SK |
3897 | & 0xF8) >> 3) - 1; |
3898 | ||
3899 | if (adc_mux_sel == dmic) { | |
3900 | dec_found = true; | |
3901 | break; | |
3902 | } | |
3903 | ||
3904 | ++adc_mux_index; | |
3905 | } | |
3906 | ||
3907 | if (dec_found && adc_mux_index <= 8) { | |
3908 | tx_fs_reg = WCD934X_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index); | |
eaf2767c | 3909 | tx_stream_fs = snd_soc_component_read(comp, tx_fs_reg) & 0x0F; |
a70d9245 SK |
3910 | if (tx_stream_fs <= 4) { |
3911 | if (wcd->dmic_sample_rate <= | |
3912 | WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ) | |
3913 | dmic_fs = wcd->dmic_sample_rate; | |
3914 | else | |
3915 | dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ; | |
3916 | } else | |
3917 | dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; | |
3918 | } else { | |
3919 | dmic_fs = wcd->dmic_sample_rate; | |
3920 | } | |
3921 | ||
3922 | return dmic_fs; | |
3923 | } | |
3924 | ||
3925 | static u8 wcd934x_get_dmic_clk_val(struct snd_soc_component *comp, | |
3926 | u32 mclk_rate, u32 dmic_clk_rate) | |
3927 | { | |
3928 | u32 div_factor; | |
3929 | u8 dmic_ctl_val; | |
3930 | ||
3931 | /* Default value to return in case of error */ | |
3932 | if (mclk_rate == WCD934X_MCLK_CLK_9P6MHZ) | |
3933 | dmic_ctl_val = WCD934X_DMIC_CLK_DIV_2; | |
3934 | else | |
3935 | dmic_ctl_val = WCD934X_DMIC_CLK_DIV_3; | |
3936 | ||
3937 | if (dmic_clk_rate == 0) { | |
3938 | dev_err(comp->dev, | |
3939 | "%s: dmic_sample_rate cannot be 0\n", | |
3940 | __func__); | |
3941 | goto done; | |
3942 | } | |
3943 | ||
3944 | div_factor = mclk_rate / dmic_clk_rate; | |
3945 | switch (div_factor) { | |
3946 | case 2: | |
3947 | dmic_ctl_val = WCD934X_DMIC_CLK_DIV_2; | |
3948 | break; | |
3949 | case 3: | |
3950 | dmic_ctl_val = WCD934X_DMIC_CLK_DIV_3; | |
3951 | break; | |
3952 | case 4: | |
3953 | dmic_ctl_val = WCD934X_DMIC_CLK_DIV_4; | |
3954 | break; | |
3955 | case 6: | |
3956 | dmic_ctl_val = WCD934X_DMIC_CLK_DIV_6; | |
3957 | break; | |
3958 | case 8: | |
3959 | dmic_ctl_val = WCD934X_DMIC_CLK_DIV_8; | |
3960 | break; | |
3961 | case 16: | |
3962 | dmic_ctl_val = WCD934X_DMIC_CLK_DIV_16; | |
3963 | break; | |
3964 | default: | |
3965 | dev_err(comp->dev, | |
3966 | "%s: Invalid div_factor %u, clk_rate(%u), dmic_rate(%u)\n", | |
3967 | __func__, div_factor, mclk_rate, dmic_clk_rate); | |
3968 | break; | |
3969 | } | |
3970 | ||
3971 | done: | |
3972 | return dmic_ctl_val; | |
3973 | } | |
3974 | ||
3975 | static int wcd934x_codec_enable_dmic(struct snd_soc_dapm_widget *w, | |
3976 | struct snd_kcontrol *kcontrol, int event) | |
3977 | { | |
3978 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
3979 | struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev); | |
3980 | u8 dmic_clk_en = 0x01; | |
3981 | u16 dmic_clk_reg; | |
3982 | s32 *dmic_clk_cnt; | |
3983 | u8 dmic_rate_val, dmic_rate_shift = 1; | |
3984 | unsigned int dmic; | |
3985 | u32 dmic_sample_rate; | |
3986 | int ret; | |
3987 | char *wname; | |
3988 | ||
3989 | wname = strpbrk(w->name, "012345"); | |
3990 | if (!wname) { | |
3991 | dev_err(comp->dev, "%s: widget not found\n", __func__); | |
3992 | return -EINVAL; | |
3993 | } | |
3994 | ||
3995 | ret = kstrtouint(wname, 10, &dmic); | |
3996 | if (ret < 0) { | |
3997 | dev_err(comp->dev, "%s: Invalid DMIC line on the codec\n", | |
3998 | __func__); | |
3999 | return -EINVAL; | |
4000 | } | |
4001 | ||
4002 | switch (dmic) { | |
4003 | case 0: | |
4004 | case 1: | |
4005 | dmic_clk_cnt = &wcd->dmic_0_1_clk_cnt; | |
4006 | dmic_clk_reg = WCD934X_CPE_SS_DMIC0_CTL; | |
4007 | break; | |
4008 | case 2: | |
4009 | case 3: | |
4010 | dmic_clk_cnt = &wcd->dmic_2_3_clk_cnt; | |
4011 | dmic_clk_reg = WCD934X_CPE_SS_DMIC1_CTL; | |
4012 | break; | |
4013 | case 4: | |
4014 | case 5: | |
4015 | dmic_clk_cnt = &wcd->dmic_4_5_clk_cnt; | |
4016 | dmic_clk_reg = WCD934X_CPE_SS_DMIC2_CTL; | |
4017 | break; | |
4018 | default: | |
4019 | dev_err(comp->dev, "%s: Invalid DMIC Selection\n", | |
4020 | __func__); | |
4021 | return -EINVAL; | |
e48e83d1 | 4022 | } |
a70d9245 SK |
4023 | |
4024 | switch (event) { | |
4025 | case SND_SOC_DAPM_PRE_PMU: | |
4026 | dmic_sample_rate = wcd934x_get_dmic_sample_rate(comp, dmic, | |
4027 | wcd); | |
4028 | dmic_rate_val = wcd934x_get_dmic_clk_val(comp, wcd->rate, | |
4029 | dmic_sample_rate); | |
4030 | (*dmic_clk_cnt)++; | |
4031 | if (*dmic_clk_cnt == 1) { | |
4032 | dmic_rate_val = dmic_rate_val << dmic_rate_shift; | |
4033 | snd_soc_component_update_bits(comp, dmic_clk_reg, | |
4034 | WCD934X_DMIC_RATE_MASK, | |
4035 | dmic_rate_val); | |
4036 | snd_soc_component_update_bits(comp, dmic_clk_reg, | |
4037 | dmic_clk_en, dmic_clk_en); | |
4038 | } | |
4039 | ||
4040 | break; | |
4041 | case SND_SOC_DAPM_POST_PMD: | |
4042 | (*dmic_clk_cnt)--; | |
4043 | if (*dmic_clk_cnt == 0) | |
4044 | snd_soc_component_update_bits(comp, dmic_clk_reg, | |
4045 | dmic_clk_en, 0); | |
4046 | break; | |
e48e83d1 | 4047 | } |
a70d9245 SK |
4048 | |
4049 | return 0; | |
4050 | } | |
4051 | ||
4052 | static int wcd934x_codec_find_amic_input(struct snd_soc_component *comp, | |
4053 | int adc_mux_n) | |
4054 | { | |
4055 | u16 mask, shift, adc_mux_in_reg; | |
4056 | u16 amic_mux_sel_reg; | |
4057 | bool is_amic; | |
4058 | ||
4059 | if (adc_mux_n < 0 || adc_mux_n > WCD934X_MAX_VALID_ADC_MUX || | |
4060 | adc_mux_n == WCD934X_INVALID_ADC_MUX) | |
4061 | return 0; | |
4062 | ||
4063 | if (adc_mux_n < 3) { | |
4064 | adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + | |
4065 | adc_mux_n; | |
4066 | mask = 0x03; | |
4067 | shift = 0; | |
4068 | amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + | |
4069 | 2 * adc_mux_n; | |
4070 | } else if (adc_mux_n < 4) { | |
4071 | adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1; | |
4072 | mask = 0x03; | |
4073 | shift = 0; | |
4074 | amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + | |
4075 | 2 * adc_mux_n; | |
4076 | } else if (adc_mux_n < 7) { | |
4077 | adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + | |
4078 | (adc_mux_n - 4); | |
4079 | mask = 0x0C; | |
4080 | shift = 2; | |
4081 | amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + | |
4082 | adc_mux_n - 4; | |
4083 | } else if (adc_mux_n < 8) { | |
4084 | adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1; | |
4085 | mask = 0x0C; | |
4086 | shift = 2; | |
4087 | amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + | |
4088 | adc_mux_n - 4; | |
4089 | } else if (adc_mux_n < 12) { | |
4090 | adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + | |
4091 | ((adc_mux_n == 8) ? (adc_mux_n - 8) : | |
4092 | (adc_mux_n - 9)); | |
4093 | mask = 0x30; | |
4094 | shift = 4; | |
4095 | amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + | |
4096 | adc_mux_n - 4; | |
4097 | } else if (adc_mux_n < 13) { | |
4098 | adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1; | |
4099 | mask = 0x30; | |
4100 | shift = 4; | |
4101 | amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + | |
4102 | adc_mux_n - 4; | |
4103 | } else { | |
4104 | adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1; | |
4105 | mask = 0xC0; | |
4106 | shift = 6; | |
4107 | amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + | |
4108 | adc_mux_n - 4; | |
4109 | } | |
4110 | ||
eaf2767c | 4111 | is_amic = (((snd_soc_component_read(comp, adc_mux_in_reg) |
a70d9245 SK |
4112 | & mask) >> shift) == 1); |
4113 | if (!is_amic) | |
4114 | return 0; | |
4115 | ||
eaf2767c | 4116 | return snd_soc_component_read(comp, amic_mux_sel_reg) & 0x07; |
a70d9245 SK |
4117 | } |
4118 | ||
4119 | static u16 wcd934x_codec_get_amic_pwlvl_reg(struct snd_soc_component *comp, | |
4120 | int amic) | |
4121 | { | |
4122 | u16 pwr_level_reg = 0; | |
4123 | ||
4124 | switch (amic) { | |
4125 | case 1: | |
4126 | case 2: | |
4127 | pwr_level_reg = WCD934X_ANA_AMIC1; | |
4128 | break; | |
4129 | ||
4130 | case 3: | |
4131 | case 4: | |
4132 | pwr_level_reg = WCD934X_ANA_AMIC3; | |
4133 | break; | |
4134 | default: | |
4135 | break; | |
4136 | } | |
4137 | ||
4138 | return pwr_level_reg; | |
4139 | } | |
4140 | ||
4141 | static int wcd934x_codec_enable_dec(struct snd_soc_dapm_widget *w, | |
4142 | struct snd_kcontrol *kcontrol, int event) | |
4143 | { | |
4144 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
4145 | unsigned int decimator; | |
4146 | char *dec_adc_mux_name = NULL; | |
4147 | char *widget_name = NULL; | |
4148 | char *wname; | |
4149 | int ret = 0, amic_n; | |
4150 | u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg; | |
4151 | u16 tx_gain_ctl_reg; | |
4152 | char *dec; | |
4153 | u8 hpf_coff_freq; | |
4154 | ||
4155 | widget_name = kstrndup(w->name, 15, GFP_KERNEL); | |
4156 | if (!widget_name) | |
4157 | return -ENOMEM; | |
4158 | ||
4159 | wname = widget_name; | |
4160 | dec_adc_mux_name = strsep(&widget_name, " "); | |
4161 | if (!dec_adc_mux_name) { | |
4162 | dev_err(comp->dev, "%s: Invalid decimator = %s\n", | |
4163 | __func__, w->name); | |
4164 | ret = -EINVAL; | |
4165 | goto out; | |
4166 | } | |
4167 | dec_adc_mux_name = widget_name; | |
4168 | ||
4169 | dec = strpbrk(dec_adc_mux_name, "012345678"); | |
4170 | if (!dec) { | |
4171 | dev_err(comp->dev, "%s: decimator index not found\n", | |
4172 | __func__); | |
4173 | ret = -EINVAL; | |
4174 | goto out; | |
4175 | } | |
4176 | ||
4177 | ret = kstrtouint(dec, 10, &decimator); | |
4178 | if (ret < 0) { | |
4179 | dev_err(comp->dev, "%s: Invalid decimator = %s\n", | |
4180 | __func__, wname); | |
4181 | ret = -EINVAL; | |
4182 | goto out; | |
4183 | } | |
4184 | ||
4185 | tx_vol_ctl_reg = WCD934X_CDC_TX0_TX_PATH_CTL + 16 * decimator; | |
4186 | hpf_gate_reg = WCD934X_CDC_TX0_TX_PATH_SEC2 + 16 * decimator; | |
4187 | dec_cfg_reg = WCD934X_CDC_TX0_TX_PATH_CFG0 + 16 * decimator; | |
4188 | tx_gain_ctl_reg = WCD934X_CDC_TX0_TX_VOL_CTL + 16 * decimator; | |
4189 | ||
4190 | switch (event) { | |
4191 | case SND_SOC_DAPM_PRE_PMU: | |
4192 | amic_n = wcd934x_codec_find_amic_input(comp, decimator); | |
4193 | if (amic_n) | |
4194 | pwr_level_reg = wcd934x_codec_get_amic_pwlvl_reg(comp, | |
4195 | amic_n); | |
4196 | ||
4197 | if (!pwr_level_reg) | |
4198 | break; | |
4199 | ||
eaf2767c | 4200 | switch ((snd_soc_component_read(comp, pwr_level_reg) & |
a70d9245 SK |
4201 | WCD934X_AMIC_PWR_LVL_MASK) >> |
4202 | WCD934X_AMIC_PWR_LVL_SHIFT) { | |
4203 | case WCD934X_AMIC_PWR_LEVEL_LP: | |
4204 | snd_soc_component_update_bits(comp, dec_cfg_reg, | |
4205 | WCD934X_DEC_PWR_LVL_MASK, | |
4206 | WCD934X_DEC_PWR_LVL_LP); | |
4207 | break; | |
4208 | case WCD934X_AMIC_PWR_LEVEL_HP: | |
4209 | snd_soc_component_update_bits(comp, dec_cfg_reg, | |
4210 | WCD934X_DEC_PWR_LVL_MASK, | |
4211 | WCD934X_DEC_PWR_LVL_HP); | |
4212 | break; | |
4213 | case WCD934X_AMIC_PWR_LEVEL_DEFAULT: | |
4214 | case WCD934X_AMIC_PWR_LEVEL_HYBRID: | |
4215 | default: | |
4216 | snd_soc_component_update_bits(comp, dec_cfg_reg, | |
4217 | WCD934X_DEC_PWR_LVL_MASK, | |
4218 | WCD934X_DEC_PWR_LVL_DF); | |
4219 | break; | |
4220 | } | |
4221 | break; | |
4222 | case SND_SOC_DAPM_POST_PMU: | |
eaf2767c | 4223 | hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) & |
a70d9245 SK |
4224 | TX_HPF_CUT_OFF_FREQ_MASK) >> 5; |
4225 | if (hpf_coff_freq != CF_MIN_3DB_150HZ) { | |
4226 | snd_soc_component_update_bits(comp, dec_cfg_reg, | |
4227 | TX_HPF_CUT_OFF_FREQ_MASK, | |
4228 | CF_MIN_3DB_150HZ << 5); | |
4229 | snd_soc_component_update_bits(comp, hpf_gate_reg, | |
4230 | WCD934X_HPH_CUTOFF_FREQ_CHANGE_REQ_MASK, | |
4231 | WCD934X_HPH_CUTOFF_FREQ_CHANGE_REQ); | |
4232 | /* | |
4233 | * Minimum 1 clk cycle delay is required as per | |
4234 | * HW spec. | |
4235 | */ | |
4236 | usleep_range(1000, 1010); | |
4237 | snd_soc_component_update_bits(comp, hpf_gate_reg, | |
4238 | WCD934X_HPH_CUTOFF_FREQ_CHANGE_REQ_MASK, | |
4239 | 0); | |
4240 | } | |
4241 | /* apply gain after decimator is enabled */ | |
4242 | snd_soc_component_write(comp, tx_gain_ctl_reg, | |
eaf2767c | 4243 | snd_soc_component_read(comp, |
a70d9245 SK |
4244 | tx_gain_ctl_reg)); |
4245 | break; | |
4246 | case SND_SOC_DAPM_PRE_PMD: | |
eaf2767c | 4247 | hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) & |
a70d9245 SK |
4248 | TX_HPF_CUT_OFF_FREQ_MASK) >> 5; |
4249 | ||
4250 | if (hpf_coff_freq != CF_MIN_3DB_150HZ) { | |
4251 | snd_soc_component_update_bits(comp, dec_cfg_reg, | |
4252 | TX_HPF_CUT_OFF_FREQ_MASK, | |
4253 | hpf_coff_freq << 5); | |
4254 | snd_soc_component_update_bits(comp, hpf_gate_reg, | |
4255 | WCD934X_HPH_CUTOFF_FREQ_CHANGE_REQ_MASK, | |
4256 | WCD934X_HPH_CUTOFF_FREQ_CHANGE_REQ); | |
4257 | /* | |
4258 | * Minimum 1 clk cycle delay is required as per | |
4259 | * HW spec. | |
4260 | */ | |
4261 | usleep_range(1000, 1010); | |
4262 | snd_soc_component_update_bits(comp, hpf_gate_reg, | |
4263 | WCD934X_HPH_CUTOFF_FREQ_CHANGE_REQ_MASK, | |
4264 | 0); | |
4265 | } | |
4266 | break; | |
4267 | case SND_SOC_DAPM_POST_PMD: | |
4268 | snd_soc_component_update_bits(comp, tx_vol_ctl_reg, | |
4269 | 0x10, 0x00); | |
4270 | snd_soc_component_update_bits(comp, dec_cfg_reg, | |
4271 | WCD934X_DEC_PWR_LVL_MASK, | |
4272 | WCD934X_DEC_PWR_LVL_DF); | |
4273 | break; | |
e48e83d1 | 4274 | } |
a70d9245 SK |
4275 | out: |
4276 | kfree(wname); | |
4277 | return ret; | |
4278 | } | |
4279 | ||
4280 | static void wcd934x_codec_set_tx_hold(struct snd_soc_component *comp, | |
4281 | u16 amic_reg, bool set) | |
4282 | { | |
4283 | u8 mask = 0x20; | |
4284 | u8 val; | |
4285 | ||
4286 | if (amic_reg == WCD934X_ANA_AMIC1 || | |
4287 | amic_reg == WCD934X_ANA_AMIC3) | |
4288 | mask = 0x40; | |
4289 | ||
4290 | val = set ? mask : 0x00; | |
4291 | ||
4292 | switch (amic_reg) { | |
4293 | case WCD934X_ANA_AMIC1: | |
4294 | case WCD934X_ANA_AMIC2: | |
4295 | snd_soc_component_update_bits(comp, WCD934X_ANA_AMIC2, | |
4296 | mask, val); | |
4297 | break; | |
4298 | case WCD934X_ANA_AMIC3: | |
4299 | case WCD934X_ANA_AMIC4: | |
4300 | snd_soc_component_update_bits(comp, WCD934X_ANA_AMIC4, | |
4301 | mask, val); | |
4302 | break; | |
4303 | default: | |
4304 | break; | |
4305 | } | |
4306 | } | |
4307 | ||
4308 | static int wcd934x_codec_enable_adc(struct snd_soc_dapm_widget *w, | |
4309 | struct snd_kcontrol *kcontrol, int event) | |
4310 | { | |
4311 | struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); | |
4312 | ||
4313 | switch (event) { | |
4314 | case SND_SOC_DAPM_PRE_PMU: | |
4315 | wcd934x_codec_set_tx_hold(comp, w->reg, true); | |
4316 | break; | |
4317 | default: | |
4318 | break; | |
4319 | } | |
4320 | ||
4321 | return 0; | |
4322 | } | |
4323 | ||
dd9eb19b SK |
4324 | static const struct snd_soc_dapm_widget wcd934x_dapm_widgets[] = { |
4325 | /* Analog Outputs */ | |
4326 | SND_SOC_DAPM_OUTPUT("EAR"), | |
4327 | SND_SOC_DAPM_OUTPUT("HPHL"), | |
4328 | SND_SOC_DAPM_OUTPUT("HPHR"), | |
4329 | SND_SOC_DAPM_OUTPUT("LINEOUT1"), | |
4330 | SND_SOC_DAPM_OUTPUT("LINEOUT2"), | |
4331 | SND_SOC_DAPM_OUTPUT("SPK1 OUT"), | |
4332 | SND_SOC_DAPM_OUTPUT("SPK2 OUT"), | |
4333 | SND_SOC_DAPM_OUTPUT("ANC EAR"), | |
4334 | SND_SOC_DAPM_OUTPUT("ANC HPHL"), | |
4335 | SND_SOC_DAPM_OUTPUT("ANC HPHR"), | |
4336 | SND_SOC_DAPM_OUTPUT("WDMA3_OUT"), | |
4337 | SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT1"), | |
4338 | SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT2"), | |
4339 | SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, | |
4340 | AIF1_PB, 0, wcd934x_codec_enable_slim, | |
4341 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4342 | SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM, | |
4343 | AIF2_PB, 0, wcd934x_codec_enable_slim, | |
4344 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4345 | SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM, | |
4346 | AIF3_PB, 0, wcd934x_codec_enable_slim, | |
4347 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4348 | SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM, | |
4349 | AIF4_PB, 0, wcd934x_codec_enable_slim, | |
4350 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4351 | ||
4352 | SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, WCD934X_RX0, 0, | |
4353 | &slim_rx_mux[WCD934X_RX0]), | |
4354 | SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, WCD934X_RX1, 0, | |
4355 | &slim_rx_mux[WCD934X_RX1]), | |
4356 | SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, WCD934X_RX2, 0, | |
4357 | &slim_rx_mux[WCD934X_RX2]), | |
4358 | SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, WCD934X_RX3, 0, | |
4359 | &slim_rx_mux[WCD934X_RX3]), | |
4360 | SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, WCD934X_RX4, 0, | |
4361 | &slim_rx_mux[WCD934X_RX4]), | |
4362 | SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, WCD934X_RX5, 0, | |
4363 | &slim_rx_mux[WCD934X_RX5]), | |
4364 | SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, WCD934X_RX6, 0, | |
4365 | &slim_rx_mux[WCD934X_RX6]), | |
4366 | SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, WCD934X_RX7, 0, | |
4367 | &slim_rx_mux[WCD934X_RX7]), | |
4368 | ||
4369 | SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4370 | SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4371 | SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4372 | SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4373 | SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4374 | SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4375 | SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4376 | SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4377 | ||
4378 | SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_EAR, 0, | |
4379 | &rx_int0_2_mux, wcd934x_codec_enable_mix_path, | |
4380 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4381 | SND_SOC_DAPM_POST_PMD), | |
4382 | SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, | |
4383 | &rx_int1_2_mux, wcd934x_codec_enable_mix_path, | |
4384 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4385 | SND_SOC_DAPM_POST_PMD), | |
4386 | SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, | |
4387 | &rx_int2_2_mux, wcd934x_codec_enable_mix_path, | |
4388 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4389 | SND_SOC_DAPM_POST_PMD), | |
4390 | SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", SND_SOC_NOPM, INTERP_LO1, 0, | |
4391 | &rx_int3_2_mux, wcd934x_codec_enable_mix_path, | |
4392 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4393 | SND_SOC_DAPM_POST_PMD), | |
4394 | SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", SND_SOC_NOPM, INTERP_LO2, 0, | |
4395 | &rx_int4_2_mux, wcd934x_codec_enable_mix_path, | |
4396 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4397 | SND_SOC_DAPM_POST_PMD), | |
4398 | SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", SND_SOC_NOPM, INTERP_SPKR1, 0, | |
4399 | &rx_int7_2_mux, wcd934x_codec_enable_mix_path, | |
4400 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4401 | SND_SOC_DAPM_POST_PMD), | |
4402 | SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", SND_SOC_NOPM, INTERP_SPKR2, 0, | |
4403 | &rx_int8_2_mux, wcd934x_codec_enable_mix_path, | |
4404 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4405 | SND_SOC_DAPM_POST_PMD), | |
4406 | ||
4407 | SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, | |
4408 | &rx_int0_1_mix_inp0_mux), | |
4409 | SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, | |
4410 | &rx_int0_1_mix_inp1_mux), | |
4411 | SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, | |
4412 | &rx_int0_1_mix_inp2_mux), | |
4413 | SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, | |
4414 | &rx_int1_1_mix_inp0_mux), | |
4415 | SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, | |
4416 | &rx_int1_1_mix_inp1_mux), | |
4417 | SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, | |
4418 | &rx_int1_1_mix_inp2_mux), | |
4419 | SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, | |
4420 | &rx_int2_1_mix_inp0_mux), | |
4421 | SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, | |
4422 | &rx_int2_1_mix_inp1_mux), | |
4423 | SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, | |
4424 | &rx_int2_1_mix_inp2_mux), | |
4425 | SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, | |
4426 | &rx_int3_1_mix_inp0_mux), | |
4427 | SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, | |
4428 | &rx_int3_1_mix_inp1_mux), | |
4429 | SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, | |
4430 | &rx_int3_1_mix_inp2_mux), | |
4431 | SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, | |
4432 | &rx_int4_1_mix_inp0_mux), | |
4433 | SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, | |
4434 | &rx_int4_1_mix_inp1_mux), | |
4435 | SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, | |
4436 | &rx_int4_1_mix_inp2_mux), | |
4437 | SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, | |
4438 | &rx_int7_1_mix_inp0_mux), | |
4439 | SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, | |
4440 | &rx_int7_1_mix_inp1_mux), | |
4441 | SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, | |
4442 | &rx_int7_1_mix_inp2_mux), | |
4443 | SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, | |
4444 | &rx_int8_1_mix_inp0_mux), | |
4445 | SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, | |
4446 | &rx_int8_1_mix_inp1_mux), | |
4447 | SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, | |
4448 | &rx_int8_1_mix_inp2_mux), | |
4449 | SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4450 | SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4451 | SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4452 | SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, | |
4453 | rx_int1_asrc_switch, | |
4454 | ARRAY_SIZE(rx_int1_asrc_switch)), | |
4455 | SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4456 | SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, | |
4457 | rx_int2_asrc_switch, | |
4458 | ARRAY_SIZE(rx_int2_asrc_switch)), | |
4459 | SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4460 | SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, | |
4461 | rx_int3_asrc_switch, | |
4462 | ARRAY_SIZE(rx_int3_asrc_switch)), | |
4463 | SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4464 | SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, | |
4465 | rx_int4_asrc_switch, | |
4466 | ARRAY_SIZE(rx_int4_asrc_switch)), | |
4467 | SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4468 | SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4469 | SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4470 | SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4471 | SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4472 | SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4473 | SND_SOC_DAPM_MIXER("RX INT1 MIX3", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4474 | SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4475 | SND_SOC_DAPM_MIXER("RX INT2 MIX3", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4476 | SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4477 | SND_SOC_DAPM_MIXER("RX INT3 MIX3", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4478 | SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4479 | SND_SOC_DAPM_MIXER("RX INT4 MIX3", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4480 | ||
4481 | SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4482 | SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0, | |
4483 | NULL, 0, NULL, 0), | |
4484 | SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0, | |
4485 | NULL, 0, NULL, 0), | |
4486 | SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", WCD934X_CDC_RX0_RX_PATH_CFG0, 4, | |
4487 | 0, &rx_int0_mix2_inp_mux, NULL, | |
4488 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4489 | SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", WCD934X_CDC_RX1_RX_PATH_CFG0, 4, | |
4490 | 0, &rx_int1_mix2_inp_mux, NULL, | |
4491 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4492 | SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", WCD934X_CDC_RX2_RX_PATH_CFG0, 4, | |
4493 | 0, &rx_int2_mix2_inp_mux, NULL, | |
4494 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4495 | SND_SOC_DAPM_MUX_E("RX INT3 MIX2 INP", WCD934X_CDC_RX3_RX_PATH_CFG0, 4, | |
4496 | 0, &rx_int3_mix2_inp_mux, NULL, | |
4497 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4498 | SND_SOC_DAPM_MUX_E("RX INT4 MIX2 INP", WCD934X_CDC_RX4_RX_PATH_CFG0, 4, | |
4499 | 0, &rx_int4_mix2_inp_mux, NULL, | |
4500 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4501 | SND_SOC_DAPM_MUX_E("RX INT7 MIX2 INP", WCD934X_CDC_RX7_RX_PATH_CFG0, 4, | |
4502 | 0, &rx_int7_mix2_inp_mux, NULL, | |
4503 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4504 | ||
4505 | SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux), | |
4506 | SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux), | |
4507 | SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux), | |
4508 | SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux), | |
4509 | SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux), | |
4510 | SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux), | |
4511 | SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux), | |
4512 | SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux), | |
4513 | ||
4514 | SND_SOC_DAPM_PGA_E("IIR0", WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, | |
4515 | 0, 0, NULL, 0, wcd934x_codec_set_iir_gain, | |
4516 | SND_SOC_DAPM_POST_PMU), | |
4517 | SND_SOC_DAPM_PGA_E("IIR1", WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL, | |
4518 | 1, 0, NULL, 0, wcd934x_codec_set_iir_gain, | |
4519 | SND_SOC_DAPM_POST_PMU), | |
4520 | SND_SOC_DAPM_MIXER("SRC0", WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, | |
4521 | 4, 0, NULL, 0), | |
4522 | SND_SOC_DAPM_MIXER("SRC1", WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL, | |
4523 | 4, 0, NULL, 0), | |
4524 | SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0, | |
4525 | &rx_int0_dem_inp_mux), | |
4526 | SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0, | |
4527 | &rx_int1_dem_inp_mux), | |
4528 | SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0, | |
4529 | &rx_int2_dem_inp_mux), | |
4530 | ||
4531 | SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_EAR, 0, | |
4532 | &rx_int0_1_interp_mux, | |
4533 | wcd934x_codec_enable_main_path, | |
4534 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4535 | SND_SOC_DAPM_POST_PMD), | |
4536 | SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0, | |
4537 | &rx_int1_1_interp_mux, | |
4538 | wcd934x_codec_enable_main_path, | |
4539 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4540 | SND_SOC_DAPM_POST_PMD), | |
4541 | SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0, | |
4542 | &rx_int2_1_interp_mux, | |
4543 | wcd934x_codec_enable_main_path, | |
4544 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4545 | SND_SOC_DAPM_POST_PMD), | |
4546 | SND_SOC_DAPM_MUX_E("RX INT3_1 INTERP", SND_SOC_NOPM, INTERP_LO1, 0, | |
4547 | &rx_int3_1_interp_mux, | |
4548 | wcd934x_codec_enable_main_path, | |
4549 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4550 | SND_SOC_DAPM_POST_PMD), | |
4551 | SND_SOC_DAPM_MUX_E("RX INT4_1 INTERP", SND_SOC_NOPM, INTERP_LO2, 0, | |
4552 | &rx_int4_1_interp_mux, | |
4553 | wcd934x_codec_enable_main_path, | |
4554 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4555 | SND_SOC_DAPM_POST_PMD), | |
4556 | SND_SOC_DAPM_MUX_E("RX INT7_1 INTERP", SND_SOC_NOPM, INTERP_SPKR1, 0, | |
4557 | &rx_int7_1_interp_mux, | |
4558 | wcd934x_codec_enable_main_path, | |
4559 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4560 | SND_SOC_DAPM_POST_PMD), | |
4561 | SND_SOC_DAPM_MUX_E("RX INT8_1 INTERP", SND_SOC_NOPM, INTERP_SPKR2, 0, | |
4562 | &rx_int8_1_interp_mux, | |
4563 | wcd934x_codec_enable_main_path, | |
4564 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4565 | SND_SOC_DAPM_POST_PMD), | |
4566 | ||
4567 | SND_SOC_DAPM_MUX("RX INT0_2 INTERP", SND_SOC_NOPM, 0, 0, | |
4568 | &rx_int0_2_interp_mux), | |
4569 | SND_SOC_DAPM_MUX("RX INT1_2 INTERP", SND_SOC_NOPM, 0, 0, | |
4570 | &rx_int1_2_interp_mux), | |
4571 | SND_SOC_DAPM_MUX("RX INT2_2 INTERP", SND_SOC_NOPM, 0, 0, | |
4572 | &rx_int2_2_interp_mux), | |
4573 | SND_SOC_DAPM_MUX("RX INT3_2 INTERP", SND_SOC_NOPM, 0, 0, | |
4574 | &rx_int3_2_interp_mux), | |
4575 | SND_SOC_DAPM_MUX("RX INT4_2 INTERP", SND_SOC_NOPM, 0, 0, | |
4576 | &rx_int4_2_interp_mux), | |
4577 | SND_SOC_DAPM_MUX("RX INT7_2 INTERP", SND_SOC_NOPM, 0, 0, | |
4578 | &rx_int7_2_interp_mux), | |
4579 | SND_SOC_DAPM_MUX("RX INT8_2 INTERP", SND_SOC_NOPM, 0, 0, | |
4580 | &rx_int8_2_interp_mux), | |
4581 | SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM, | |
4582 | 0, 0, wcd934x_codec_ear_dac_event, | |
4583 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4584 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4585 | SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD934X_ANA_HPH, | |
4586 | 5, 0, wcd934x_codec_hphl_dac_event, | |
4587 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4588 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4589 | SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD934X_ANA_HPH, | |
4590 | 4, 0, wcd934x_codec_hphr_dac_event, | |
4591 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4592 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4593 | SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM, | |
4594 | 0, 0, wcd934x_codec_lineout_dac_event, | |
4595 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4596 | SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM, | |
4597 | 0, 0, wcd934x_codec_lineout_dac_event, | |
4598 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4599 | SND_SOC_DAPM_PGA_E("EAR PA", WCD934X_ANA_EAR, 7, 0, NULL, 0, NULL, 0), | |
4600 | SND_SOC_DAPM_PGA_E("HPHL PA", WCD934X_ANA_HPH, 7, 0, NULL, 0, | |
4601 | wcd934x_codec_enable_hphl_pa, | |
4602 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4603 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4604 | SND_SOC_DAPM_PGA_E("HPHR PA", WCD934X_ANA_HPH, 6, 0, NULL, 0, | |
4605 | wcd934x_codec_enable_hphr_pa, | |
4606 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4607 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4608 | SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD934X_ANA_LO_1_2, 7, 0, NULL, 0, | |
4609 | NULL, 0), | |
4610 | SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD934X_ANA_LO_1_2, 6, 0, NULL, 0, | |
4611 | NULL, 0), | |
4612 | SND_SOC_DAPM_SUPPLY("RX_BIAS", WCD934X_ANA_RX_SUPPLIES, 0, 0, NULL, | |
4613 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4614 | SND_SOC_DAPM_SUPPLY("SBOOST0", WCD934X_CDC_RX7_RX_PATH_CFG1, | |
4615 | 0, 0, NULL, 0), | |
4616 | SND_SOC_DAPM_SUPPLY("SBOOST0_CLK", WCD934X_CDC_BOOST0_BOOST_PATH_CTL, | |
4617 | 0, 0, NULL, 0), | |
4618 | SND_SOC_DAPM_SUPPLY("SBOOST1", WCD934X_CDC_RX8_RX_PATH_CFG1, | |
4619 | 0, 0, NULL, 0), | |
4620 | SND_SOC_DAPM_SUPPLY("SBOOST1_CLK", WCD934X_CDC_BOOST1_BOOST_PATH_CTL, | |
4621 | 0, 0, NULL, 0), | |
4622 | SND_SOC_DAPM_SUPPLY("INT0_CLK", SND_SOC_NOPM, INTERP_EAR, 0, | |
4623 | wcd934x_codec_enable_interp_clk, | |
4624 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4625 | SND_SOC_DAPM_SUPPLY("INT1_CLK", SND_SOC_NOPM, INTERP_HPHL, 0, | |
4626 | wcd934x_codec_enable_interp_clk, | |
4627 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4628 | SND_SOC_DAPM_SUPPLY("INT2_CLK", SND_SOC_NOPM, INTERP_HPHR, 0, | |
4629 | wcd934x_codec_enable_interp_clk, | |
4630 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4631 | SND_SOC_DAPM_SUPPLY("INT3_CLK", SND_SOC_NOPM, INTERP_LO1, 0, | |
4632 | wcd934x_codec_enable_interp_clk, | |
4633 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4634 | SND_SOC_DAPM_SUPPLY("INT4_CLK", SND_SOC_NOPM, INTERP_LO2, 0, | |
4635 | wcd934x_codec_enable_interp_clk, | |
4636 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4637 | SND_SOC_DAPM_SUPPLY("INT7_CLK", SND_SOC_NOPM, INTERP_SPKR1, 0, | |
4638 | wcd934x_codec_enable_interp_clk, | |
4639 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4640 | SND_SOC_DAPM_SUPPLY("INT8_CLK", SND_SOC_NOPM, INTERP_SPKR2, 0, | |
4641 | wcd934x_codec_enable_interp_clk, | |
4642 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4643 | SND_SOC_DAPM_SUPPLY("DSMDEM0_CLK", WCD934X_CDC_RX0_RX_PATH_DSMDEM_CTL, | |
4644 | 0, 0, NULL, 0), | |
4645 | SND_SOC_DAPM_SUPPLY("DSMDEM1_CLK", WCD934X_CDC_RX1_RX_PATH_DSMDEM_CTL, | |
4646 | 0, 0, NULL, 0), | |
4647 | SND_SOC_DAPM_SUPPLY("DSMDEM2_CLK", WCD934X_CDC_RX2_RX_PATH_DSMDEM_CTL, | |
4648 | 0, 0, NULL, 0), | |
4649 | SND_SOC_DAPM_SUPPLY("DSMDEM3_CLK", WCD934X_CDC_RX3_RX_PATH_DSMDEM_CTL, | |
4650 | 0, 0, NULL, 0), | |
4651 | SND_SOC_DAPM_SUPPLY("DSMDEM4_CLK", WCD934X_CDC_RX4_RX_PATH_DSMDEM_CTL, | |
4652 | 0, 0, NULL, 0), | |
4653 | SND_SOC_DAPM_SUPPLY("DSMDEM7_CLK", WCD934X_CDC_RX7_RX_PATH_DSMDEM_CTL, | |
4654 | 0, 0, NULL, 0), | |
4655 | SND_SOC_DAPM_SUPPLY("DSMDEM8_CLK", WCD934X_CDC_RX8_RX_PATH_DSMDEM_CTL, | |
4656 | 0, 0, NULL, 0), | |
4657 | SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, | |
4658 | wcd934x_codec_enable_mclk, | |
4659 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
a70d9245 SK |
4660 | |
4661 | /* TX */ | |
4662 | SND_SOC_DAPM_INPUT("AMIC1"), | |
4663 | SND_SOC_DAPM_INPUT("AMIC2"), | |
4664 | SND_SOC_DAPM_INPUT("AMIC3"), | |
4665 | SND_SOC_DAPM_INPUT("AMIC4"), | |
4666 | SND_SOC_DAPM_INPUT("AMIC5"), | |
4667 | SND_SOC_DAPM_INPUT("DMIC0 Pin"), | |
4668 | SND_SOC_DAPM_INPUT("DMIC1 Pin"), | |
4669 | SND_SOC_DAPM_INPUT("DMIC2 Pin"), | |
4670 | SND_SOC_DAPM_INPUT("DMIC3 Pin"), | |
4671 | SND_SOC_DAPM_INPUT("DMIC4 Pin"), | |
4672 | SND_SOC_DAPM_INPUT("DMIC5 Pin"), | |
4673 | ||
4674 | SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM, | |
4675 | AIF1_CAP, 0, wcd934x_codec_enable_slim, | |
4676 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4677 | SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM, | |
4678 | AIF2_CAP, 0, wcd934x_codec_enable_slim, | |
4679 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4680 | SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM, | |
4681 | AIF3_CAP, 0, wcd934x_codec_enable_slim, | |
4682 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4683 | ||
4684 | SND_SOC_DAPM_MIXER("SLIM TX0", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4685 | SND_SOC_DAPM_MIXER("SLIM TX1", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4686 | SND_SOC_DAPM_MIXER("SLIM TX2", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4687 | SND_SOC_DAPM_MIXER("SLIM TX3", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4688 | SND_SOC_DAPM_MIXER("SLIM TX4", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4689 | SND_SOC_DAPM_MIXER("SLIM TX5", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4690 | SND_SOC_DAPM_MIXER("SLIM TX6", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4691 | SND_SOC_DAPM_MIXER("SLIM TX7", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4692 | SND_SOC_DAPM_MIXER("SLIM TX8", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4693 | SND_SOC_DAPM_MIXER("SLIM TX9", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4694 | SND_SOC_DAPM_MIXER("SLIM TX10", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4695 | SND_SOC_DAPM_MIXER("SLIM TX11", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4696 | SND_SOC_DAPM_MIXER("SLIM TX13", SND_SOC_NOPM, 0, 0, NULL, 0), | |
4697 | ||
4698 | /* Digital Mic Inputs */ | |
4699 | SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0, | |
4700 | wcd934x_codec_enable_dmic, | |
4701 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4702 | SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, | |
4703 | wcd934x_codec_enable_dmic, | |
4704 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4705 | SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, | |
4706 | wcd934x_codec_enable_dmic, | |
4707 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4708 | SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0, | |
4709 | wcd934x_codec_enable_dmic, | |
4710 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4711 | SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0, | |
4712 | wcd934x_codec_enable_dmic, | |
4713 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4714 | SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0, | |
4715 | wcd934x_codec_enable_dmic, | |
4716 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | |
4717 | SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0, &tx_dmic_mux0), | |
4718 | SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0, &tx_dmic_mux1), | |
4719 | SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0, &tx_dmic_mux2), | |
4720 | SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0, &tx_dmic_mux3), | |
4721 | SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0, &tx_dmic_mux4), | |
4722 | SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0, &tx_dmic_mux5), | |
4723 | SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0, &tx_dmic_mux6), | |
4724 | SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0, &tx_dmic_mux7), | |
4725 | SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0, &tx_dmic_mux8), | |
4726 | SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0, &tx_amic_mux0), | |
4727 | SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0, &tx_amic_mux1), | |
4728 | SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0, &tx_amic_mux2), | |
4729 | SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0, &tx_amic_mux3), | |
4730 | SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0, &tx_amic_mux4), | |
4731 | SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0, &tx_amic_mux5), | |
4732 | SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0, &tx_amic_mux6), | |
4733 | SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0, &tx_amic_mux7), | |
4734 | SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0, &tx_amic_mux8), | |
4735 | SND_SOC_DAPM_MUX_E("ADC MUX0", WCD934X_CDC_TX0_TX_PATH_CTL, 5, 0, | |
4736 | &tx_adc_mux0_mux, wcd934x_codec_enable_dec, | |
4737 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4738 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4739 | SND_SOC_DAPM_MUX_E("ADC MUX1", WCD934X_CDC_TX1_TX_PATH_CTL, 5, 0, | |
4740 | &tx_adc_mux1_mux, wcd934x_codec_enable_dec, | |
4741 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4742 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4743 | SND_SOC_DAPM_MUX_E("ADC MUX2", WCD934X_CDC_TX2_TX_PATH_CTL, 5, 0, | |
4744 | &tx_adc_mux2_mux, wcd934x_codec_enable_dec, | |
4745 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4746 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4747 | SND_SOC_DAPM_MUX_E("ADC MUX3", WCD934X_CDC_TX3_TX_PATH_CTL, 5, 0, | |
4748 | &tx_adc_mux3_mux, wcd934x_codec_enable_dec, | |
4749 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4750 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4751 | SND_SOC_DAPM_MUX_E("ADC MUX4", WCD934X_CDC_TX4_TX_PATH_CTL, 5, 0, | |
4752 | &tx_adc_mux4_mux, wcd934x_codec_enable_dec, | |
4753 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4754 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4755 | SND_SOC_DAPM_MUX_E("ADC MUX5", WCD934X_CDC_TX5_TX_PATH_CTL, 5, 0, | |
4756 | &tx_adc_mux5_mux, wcd934x_codec_enable_dec, | |
4757 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4758 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4759 | SND_SOC_DAPM_MUX_E("ADC MUX6", WCD934X_CDC_TX6_TX_PATH_CTL, 5, 0, | |
4760 | &tx_adc_mux6_mux, wcd934x_codec_enable_dec, | |
4761 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4762 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4763 | SND_SOC_DAPM_MUX_E("ADC MUX7", WCD934X_CDC_TX7_TX_PATH_CTL, 5, 0, | |
4764 | &tx_adc_mux7_mux, wcd934x_codec_enable_dec, | |
4765 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4766 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4767 | SND_SOC_DAPM_MUX_E("ADC MUX8", WCD934X_CDC_TX8_TX_PATH_CTL, 5, 0, | |
4768 | &tx_adc_mux8_mux, wcd934x_codec_enable_dec, | |
4769 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
4770 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | |
4771 | SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD934X_ANA_AMIC1, 7, 0, | |
4772 | wcd934x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), | |
4773 | SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD934X_ANA_AMIC2, 7, 0, | |
4774 | wcd934x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), | |
4775 | SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD934X_ANA_AMIC3, 7, 0, | |
4776 | wcd934x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), | |
4777 | SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD934X_ANA_AMIC4, 7, 0, | |
4778 | wcd934x_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), | |
4779 | SND_SOC_DAPM_SUPPLY("MIC BIAS1", WCD934X_ANA_MICB1, 6, 0, NULL, | |
4780 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4781 | SND_SOC_DAPM_SUPPLY("MIC BIAS2", WCD934X_ANA_MICB2, 6, 0, NULL, | |
4782 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4783 | SND_SOC_DAPM_SUPPLY("MIC BIAS3", WCD934X_ANA_MICB3, 6, 0, NULL, | |
4784 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4785 | SND_SOC_DAPM_SUPPLY("MIC BIAS4", WCD934X_ANA_MICB4, 6, 0, NULL, | |
4786 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | |
4787 | ||
4788 | SND_SOC_DAPM_MUX("AMIC4_5 SEL", SND_SOC_NOPM, 0, 0, &tx_amic4_5), | |
4789 | SND_SOC_DAPM_MUX("CDC_IF TX0 MUX", SND_SOC_NOPM, WCD934X_TX0, 0, | |
4790 | &cdc_if_tx0_mux), | |
4791 | SND_SOC_DAPM_MUX("CDC_IF TX1 MUX", SND_SOC_NOPM, WCD934X_TX1, 0, | |
4792 | &cdc_if_tx1_mux), | |
4793 | SND_SOC_DAPM_MUX("CDC_IF TX2 MUX", SND_SOC_NOPM, WCD934X_TX2, 0, | |
4794 | &cdc_if_tx2_mux), | |
4795 | SND_SOC_DAPM_MUX("CDC_IF TX3 MUX", SND_SOC_NOPM, WCD934X_TX3, 0, | |
4796 | &cdc_if_tx3_mux), | |
4797 | SND_SOC_DAPM_MUX("CDC_IF TX4 MUX", SND_SOC_NOPM, WCD934X_TX4, 0, | |
4798 | &cdc_if_tx4_mux), | |
4799 | SND_SOC_DAPM_MUX("CDC_IF TX5 MUX", SND_SOC_NOPM, WCD934X_TX5, 0, | |
4800 | &cdc_if_tx5_mux), | |
4801 | SND_SOC_DAPM_MUX("CDC_IF TX6 MUX", SND_SOC_NOPM, WCD934X_TX6, 0, | |
4802 | &cdc_if_tx6_mux), | |
4803 | SND_SOC_DAPM_MUX("CDC_IF TX7 MUX", SND_SOC_NOPM, WCD934X_TX7, 0, | |
4804 | &cdc_if_tx7_mux), | |
4805 | SND_SOC_DAPM_MUX("CDC_IF TX8 MUX", SND_SOC_NOPM, WCD934X_TX8, 0, | |
4806 | &cdc_if_tx8_mux), | |
4807 | SND_SOC_DAPM_MUX("CDC_IF TX9 MUX", SND_SOC_NOPM, WCD934X_TX9, 0, | |
4808 | &cdc_if_tx9_mux), | |
4809 | SND_SOC_DAPM_MUX("CDC_IF TX10 MUX", SND_SOC_NOPM, WCD934X_TX10, 0, | |
4810 | &cdc_if_tx10_mux), | |
4811 | SND_SOC_DAPM_MUX("CDC_IF TX11 MUX", SND_SOC_NOPM, WCD934X_TX11, 0, | |
4812 | &cdc_if_tx11_mux), | |
4813 | SND_SOC_DAPM_MUX("CDC_IF TX11 INP1 MUX", SND_SOC_NOPM, WCD934X_TX11, 0, | |
4814 | &cdc_if_tx11_inp1_mux), | |
4815 | SND_SOC_DAPM_MUX("CDC_IF TX13 MUX", SND_SOC_NOPM, WCD934X_TX13, 0, | |
4816 | &cdc_if_tx13_mux), | |
4817 | SND_SOC_DAPM_MUX("CDC_IF TX13 INP1 MUX", SND_SOC_NOPM, WCD934X_TX13, 0, | |
4818 | &cdc_if_tx13_inp1_mux), | |
4819 | SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, | |
4820 | aif1_slim_cap_mixer, | |
4821 | ARRAY_SIZE(aif1_slim_cap_mixer)), | |
4822 | SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, | |
4823 | aif2_slim_cap_mixer, | |
4824 | ARRAY_SIZE(aif2_slim_cap_mixer)), | |
4825 | SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0, | |
4826 | aif3_slim_cap_mixer, | |
4827 | ARRAY_SIZE(aif3_slim_cap_mixer)), | |
dd9eb19b SK |
4828 | }; |
4829 | ||
da3e83f8 SK |
4830 | static const struct snd_soc_dapm_route wcd934x_audio_map[] = { |
4831 | /* RX0-RX7 */ | |
4832 | WCD934X_SLIM_RX_AIF_PATH(0), | |
4833 | WCD934X_SLIM_RX_AIF_PATH(1), | |
4834 | WCD934X_SLIM_RX_AIF_PATH(2), | |
4835 | WCD934X_SLIM_RX_AIF_PATH(3), | |
4836 | WCD934X_SLIM_RX_AIF_PATH(4), | |
4837 | WCD934X_SLIM_RX_AIF_PATH(5), | |
4838 | WCD934X_SLIM_RX_AIF_PATH(6), | |
4839 | WCD934X_SLIM_RX_AIF_PATH(7), | |
4840 | ||
4841 | /* RX0 Ear out */ | |
4842 | WCD934X_INTERPOLATOR_PATH(0), | |
4843 | WCD934X_INTERPOLATOR_MIX2(0), | |
4844 | {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"}, | |
4845 | {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"}, | |
4846 | {"RX INT0 DAC", NULL, "RX_BIAS"}, | |
4847 | {"EAR PA", NULL, "RX INT0 DAC"}, | |
4848 | {"EAR", NULL, "EAR PA"}, | |
4849 | ||
4850 | /* RX1 Headphone left */ | |
4851 | WCD934X_INTERPOLATOR_PATH(1), | |
4852 | WCD934X_INTERPOLATOR_MIX2(1), | |
4853 | {"RX INT1 MIX3", NULL, "RX INT1 MIX2"}, | |
4854 | {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX3"}, | |
4855 | {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"}, | |
4856 | {"RX INT1 DAC", NULL, "RX_BIAS"}, | |
4857 | {"HPHL PA", NULL, "RX INT1 DAC"}, | |
4858 | {"HPHL", NULL, "HPHL PA"}, | |
4859 | ||
4860 | /* RX2 Headphone right */ | |
4861 | WCD934X_INTERPOLATOR_PATH(2), | |
4862 | WCD934X_INTERPOLATOR_MIX2(2), | |
4863 | {"RX INT2 MIX3", NULL, "RX INT2 MIX2"}, | |
4864 | {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 MIX3"}, | |
4865 | {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"}, | |
4866 | {"RX INT2 DAC", NULL, "RX_BIAS"}, | |
4867 | {"HPHR PA", NULL, "RX INT2 DAC"}, | |
4868 | {"HPHR", NULL, "HPHR PA"}, | |
4869 | ||
4870 | /* RX3 HIFi LineOut1 */ | |
4871 | WCD934X_INTERPOLATOR_PATH(3), | |
4872 | WCD934X_INTERPOLATOR_MIX2(3), | |
4873 | {"RX INT3 MIX3", NULL, "RX INT3 MIX2"}, | |
4874 | {"RX INT3 DAC", NULL, "RX INT3 MIX3"}, | |
4875 | {"RX INT3 DAC", NULL, "RX_BIAS"}, | |
4876 | {"LINEOUT1 PA", NULL, "RX INT3 DAC"}, | |
4877 | {"LINEOUT1", NULL, "LINEOUT1 PA"}, | |
4878 | ||
4879 | /* RX4 HIFi LineOut2 */ | |
4880 | WCD934X_INTERPOLATOR_PATH(4), | |
4881 | WCD934X_INTERPOLATOR_MIX2(4), | |
4882 | {"RX INT4 MIX3", NULL, "RX INT4 MIX2"}, | |
4883 | {"RX INT4 DAC", NULL, "RX INT4 MIX3"}, | |
4884 | {"RX INT4 DAC", NULL, "RX_BIAS"}, | |
4885 | {"LINEOUT2 PA", NULL, "RX INT4 DAC"}, | |
4886 | {"LINEOUT2", NULL, "LINEOUT2 PA"}, | |
4887 | ||
4888 | /* RX7 Speaker Left Out PA */ | |
4889 | WCD934X_INTERPOLATOR_PATH(7), | |
4890 | WCD934X_INTERPOLATOR_MIX2(7), | |
4891 | {"RX INT7 CHAIN", NULL, "RX INT7 MIX2"}, | |
4892 | {"RX INT7 CHAIN", NULL, "RX_BIAS"}, | |
4893 | {"RX INT7 CHAIN", NULL, "SBOOST0"}, | |
4894 | {"RX INT7 CHAIN", NULL, "SBOOST0_CLK"}, | |
4895 | {"SPK1 OUT", NULL, "RX INT7 CHAIN"}, | |
4896 | ||
4897 | /* RX8 Speaker Right Out PA */ | |
4898 | WCD934X_INTERPOLATOR_PATH(8), | |
4899 | {"RX INT8 CHAIN", NULL, "RX INT8 SEC MIX"}, | |
4900 | {"RX INT8 CHAIN", NULL, "RX_BIAS"}, | |
4901 | {"RX INT8 CHAIN", NULL, "SBOOST1"}, | |
4902 | {"RX INT8 CHAIN", NULL, "SBOOST1_CLK"}, | |
4903 | {"SPK2 OUT", NULL, "RX INT8 CHAIN"}, | |
4904 | ||
4905 | /* Tx */ | |
4906 | {"AIF1 CAP", NULL, "AIF1_CAP Mixer"}, | |
4907 | {"AIF2 CAP", NULL, "AIF2_CAP Mixer"}, | |
4908 | {"AIF3 CAP", NULL, "AIF3_CAP Mixer"}, | |
4909 | ||
4910 | WCD934X_SLIM_TX_AIF_PATH(0), | |
4911 | WCD934X_SLIM_TX_AIF_PATH(1), | |
4912 | WCD934X_SLIM_TX_AIF_PATH(2), | |
4913 | WCD934X_SLIM_TX_AIF_PATH(3), | |
4914 | WCD934X_SLIM_TX_AIF_PATH(4), | |
4915 | WCD934X_SLIM_TX_AIF_PATH(5), | |
4916 | WCD934X_SLIM_TX_AIF_PATH(6), | |
4917 | WCD934X_SLIM_TX_AIF_PATH(7), | |
4918 | WCD934X_SLIM_TX_AIF_PATH(8), | |
4919 | ||
4920 | WCD934X_ADC_MUX(0), | |
4921 | WCD934X_ADC_MUX(1), | |
4922 | WCD934X_ADC_MUX(2), | |
4923 | WCD934X_ADC_MUX(3), | |
4924 | WCD934X_ADC_MUX(4), | |
4925 | WCD934X_ADC_MUX(5), | |
4926 | WCD934X_ADC_MUX(6), | |
4927 | WCD934X_ADC_MUX(7), | |
4928 | WCD934X_ADC_MUX(8), | |
4929 | ||
4930 | {"CDC_IF TX0 MUX", "DEC0", "ADC MUX0"}, | |
4931 | {"CDC_IF TX1 MUX", "DEC1", "ADC MUX1"}, | |
4932 | {"CDC_IF TX2 MUX", "DEC2", "ADC MUX2"}, | |
4933 | {"CDC_IF TX3 MUX", "DEC3", "ADC MUX3"}, | |
4934 | {"CDC_IF TX4 MUX", "DEC4", "ADC MUX4"}, | |
4935 | {"CDC_IF TX5 MUX", "DEC5", "ADC MUX5"}, | |
4936 | {"CDC_IF TX6 MUX", "DEC6", "ADC MUX6"}, | |
4937 | {"CDC_IF TX7 MUX", "DEC7", "ADC MUX7"}, | |
4938 | {"CDC_IF TX8 MUX", "DEC8", "ADC MUX8"}, | |
4939 | ||
4940 | {"AMIC4_5 SEL", "AMIC4", "AMIC4"}, | |
4941 | {"AMIC4_5 SEL", "AMIC5", "AMIC5"}, | |
4942 | ||
4943 | { "DMIC0", NULL, "DMIC0 Pin" }, | |
4944 | { "DMIC1", NULL, "DMIC1 Pin" }, | |
4945 | { "DMIC2", NULL, "DMIC2 Pin" }, | |
4946 | { "DMIC3", NULL, "DMIC3 Pin" }, | |
4947 | { "DMIC4", NULL, "DMIC4 Pin" }, | |
4948 | { "DMIC5", NULL, "DMIC5 Pin" }, | |
4949 | ||
4950 | {"ADC1", NULL, "AMIC1"}, | |
4951 | {"ADC2", NULL, "AMIC2"}, | |
4952 | {"ADC3", NULL, "AMIC3"}, | |
4953 | {"ADC4", NULL, "AMIC4_5 SEL"}, | |
4954 | ||
4955 | WCD934X_IIR_INP_MUX(0), | |
4956 | WCD934X_IIR_INP_MUX(1), | |
4957 | ||
4958 | {"SRC0", NULL, "IIR0"}, | |
4959 | {"SRC1", NULL, "IIR1"}, | |
4960 | }; | |
4961 | ||
a61f3b4f SK |
4962 | static const struct snd_soc_component_driver wcd934x_component_drv = { |
4963 | .probe = wcd934x_comp_probe, | |
4964 | .remove = wcd934x_comp_remove, | |
4965 | .set_sysclk = wcd934x_comp_set_sysclk, | |
1cde8b82 SK |
4966 | .controls = wcd934x_snd_controls, |
4967 | .num_controls = ARRAY_SIZE(wcd934x_snd_controls), | |
dd9eb19b SK |
4968 | .dapm_widgets = wcd934x_dapm_widgets, |
4969 | .num_dapm_widgets = ARRAY_SIZE(wcd934x_dapm_widgets), | |
da3e83f8 SK |
4970 | .dapm_routes = wcd934x_audio_map, |
4971 | .num_dapm_routes = ARRAY_SIZE(wcd934x_audio_map), | |
a61f3b4f SK |
4972 | }; |
4973 | ||
4974 | static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd) | |
4975 | { | |
4976 | struct device *dev = &wcd->sdev->dev; | |
4977 | struct device_node *ifc_dev_np; | |
4978 | ||
4979 | ifc_dev_np = of_parse_phandle(dev->of_node, "slim-ifc-dev", 0); | |
4980 | if (!ifc_dev_np) { | |
4981 | dev_err(dev, "No Interface device found\n"); | |
4982 | return -EINVAL; | |
4983 | } | |
4984 | ||
4985 | wcd->sidev = of_slim_get_device(wcd->sdev->ctrl, ifc_dev_np); | |
4986 | if (!wcd->sidev) { | |
4987 | dev_err(dev, "Unable to get SLIM Interface device\n"); | |
4988 | return -EINVAL; | |
4989 | } | |
4990 | ||
4991 | slim_get_logical_addr(wcd->sidev); | |
4992 | wcd->if_regmap = regmap_init_slimbus(wcd->sidev, | |
4993 | &wcd934x_ifc_regmap_config); | |
4994 | if (IS_ERR(wcd->if_regmap)) { | |
4995 | dev_err(dev, "Failed to allocate ifc register map\n"); | |
4996 | return PTR_ERR(wcd->if_regmap); | |
4997 | } | |
4998 | ||
4999 | of_property_read_u32(dev->parent->of_node, "qcom,dmic-sample-rate", | |
5000 | &wcd->dmic_sample_rate); | |
5001 | ||
5002 | return 0; | |
5003 | } | |
5004 | ||
5005 | static int wcd934x_codec_probe(struct platform_device *pdev) | |
5006 | { | |
5007 | struct wcd934x_ddata *data = dev_get_drvdata(pdev->dev.parent); | |
5008 | struct wcd934x_codec *wcd; | |
5009 | struct device *dev = &pdev->dev; | |
5010 | int ret, irq; | |
5011 | ||
5012 | wcd = devm_kzalloc(&pdev->dev, sizeof(*wcd), GFP_KERNEL); | |
5013 | if (!wcd) | |
5014 | return -ENOMEM; | |
5015 | ||
5016 | wcd->dev = dev; | |
5017 | wcd->regmap = data->regmap; | |
5018 | wcd->extclk = data->extclk; | |
5019 | wcd->sdev = to_slim_device(data->dev); | |
5020 | mutex_init(&wcd->sysclk_mutex); | |
5021 | ||
5022 | ret = wcd934x_codec_parse_data(wcd); | |
5023 | if (ret) { | |
5024 | dev_err(wcd->dev, "Failed to get SLIM IRQ\n"); | |
5025 | return ret; | |
5026 | } | |
5027 | ||
5028 | /* set default rate 9P6MHz */ | |
5029 | regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_MCLK_CFG, | |
5030 | WCD934X_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK, | |
5031 | WCD934X_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ); | |
5032 | memcpy(wcd->rx_chs, wcd934x_rx_chs, sizeof(wcd934x_rx_chs)); | |
5033 | memcpy(wcd->tx_chs, wcd934x_tx_chs, sizeof(wcd934x_tx_chs)); | |
5034 | ||
5035 | irq = regmap_irq_get_virq(data->irq_data, WCD934X_IRQ_SLIMBUS); | |
5036 | if (irq < 0) { | |
5037 | dev_err(wcd->dev, "Failed to get SLIM IRQ\n"); | |
5038 | return irq; | |
5039 | } | |
5040 | ||
5041 | ret = devm_request_threaded_irq(dev, irq, NULL, | |
5042 | wcd934x_slim_irq_handler, | |
5043 | IRQF_TRIGGER_RISING, | |
5044 | "slim", wcd); | |
5045 | if (ret) { | |
5046 | dev_err(dev, "Failed to request slimbus irq\n"); | |
5047 | return ret; | |
5048 | } | |
5049 | ||
5050 | wcd934x_register_mclk_output(wcd); | |
5051 | platform_set_drvdata(pdev, wcd); | |
5052 | ||
5053 | return devm_snd_soc_register_component(dev, &wcd934x_component_drv, | |
5054 | wcd934x_slim_dais, | |
5055 | ARRAY_SIZE(wcd934x_slim_dais)); | |
5056 | } | |
5057 | ||
5058 | static const struct platform_device_id wcd934x_driver_id[] = { | |
5059 | { | |
5060 | .name = "wcd934x-codec", | |
5061 | }, | |
5062 | {}, | |
5063 | }; | |
5064 | MODULE_DEVICE_TABLE(platform, wcd934x_driver_id); | |
5065 | ||
5066 | static struct platform_driver wcd934x_codec_driver = { | |
5067 | .probe = &wcd934x_codec_probe, | |
5068 | .id_table = wcd934x_driver_id, | |
5069 | .driver = { | |
5070 | .name = "wcd934x-codec", | |
5071 | } | |
5072 | }; | |
5073 | ||
5074 | MODULE_ALIAS("platform:wcd934x-codec"); | |
5075 | module_platform_driver(wcd934x_codec_driver); | |
5076 | MODULE_DESCRIPTION("WCD934x codec driver"); | |
5077 | MODULE_LICENSE("GPL v2"); |