1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // CS530x CODEC driver
4 //
5 // Copyright (C) 2024 Cirrus Logic, Inc. and
6 // Cirrus Logic International Semiconductor Ltd.
7
8 #include <sound/core.h>
9 #include <linux/delay.h>
10 #include <linux/i2c.h>
11 #include <linux/init.h>
12 #include <sound/initval.h>
13 #include <linux/module.h>
14 #include <sound/pcm.h>
15 #include <sound/pcm_params.h>
16 #include <linux/pm.h>
17 #include <linux/property.h>
18 #include <linux/slab.h>
19 #include <sound/soc.h>
20 #include <sound/tlv.h>
21
22 #include "cs530x.h"
23
24 #define CS530X_MAX_ADC_CH 8
25 #define CS530X_MIN_ADC_CH 2
26
27 static const char *cs530x_supply_names[CS530X_NUM_SUPPLIES] = {
28 "vdd-a",
29 "vdd-io",
30 };
31
32 static const struct reg_default cs530x_reg_defaults[] = {
33 { CS530X_CLK_CFG_0, 0x30 },
34 { CS530X_CLK_CFG_1, 0x0001 },
35 { CS530X_CHIP_ENABLE, 0 },
36 { CS530X_ASP_CFG, 0 },
37 { CS530X_SIGNAL_PATH_CFG, 0 },
38 { CS530X_IN_ENABLES, 0 },
39 { CS530X_IN_RAMP_SUM, 0x0022 },
40 { CS530X_IN_FILTER, 0 },
41 { CS530X_IN_HIZ, 0 },
42 { CS530X_IN_INV, 0 },
43 { CS530X_IN_VOL_CTRL1_0, 0x8000 },
44 { CS530X_IN_VOL_CTRL1_1, 0x8000 },
45 { CS530X_IN_VOL_CTRL2_0, 0x8000 },
46 { CS530X_IN_VOL_CTRL2_1, 0x8000 },
47 { CS530X_IN_VOL_CTRL3_0, 0x8000 },
48 { CS530X_IN_VOL_CTRL3_1, 0x8000 },
49 { CS530X_IN_VOL_CTRL4_0, 0x8000 },
50 { CS530X_IN_VOL_CTRL4_1, 0x8000 },
51 { CS530X_PAD_FN, 0 },
52 { CS530X_PAD_LVL, 0 },
53 };
54
cs530x_read_and_write_regs(unsigned int reg)55 static bool cs530x_read_and_write_regs(unsigned int reg)
56 {
57 switch (reg) {
58 case CS530X_CLK_CFG_0:
59 case CS530X_CLK_CFG_1:
60 case CS530X_CHIP_ENABLE:
61 case CS530X_ASP_CFG:
62 case CS530X_SIGNAL_PATH_CFG:
63 case CS530X_IN_ENABLES:
64 case CS530X_IN_RAMP_SUM:
65 case CS530X_IN_FILTER:
66 case CS530X_IN_HIZ:
67 case CS530X_IN_INV:
68 case CS530X_IN_VOL_CTRL1_0:
69 case CS530X_IN_VOL_CTRL1_1:
70 case CS530X_IN_VOL_CTRL2_0:
71 case CS530X_IN_VOL_CTRL2_1:
72 case CS530X_IN_VOL_CTRL3_0:
73 case CS530X_IN_VOL_CTRL3_1:
74 case CS530X_IN_VOL_CTRL4_0:
75 case CS530X_IN_VOL_CTRL4_1:
76 case CS530X_PAD_FN:
77 case CS530X_PAD_LVL:
78 return true;
79 default:
80 return false;
81 }
82 }
83
cs530x_readable_register(struct device * dev,unsigned int reg)84 static bool cs530x_readable_register(struct device *dev, unsigned int reg)
85 {
86 switch (reg) {
87 case CS530X_DEVID:
88 case CS530X_REVID:
89 return true;
90 default:
91 return cs530x_read_and_write_regs(reg);
92 }
93 }
94
cs530x_writeable_register(struct device * dev,unsigned int reg)95 static bool cs530x_writeable_register(struct device *dev, unsigned int reg)
96 {
97 switch (reg) {
98 case CS530X_SW_RESET:
99 case CS530X_IN_VOL_CTRL5:
100 return true;
101 default:
102 return cs530x_read_and_write_regs(reg);
103 }
104 }
105
cs530x_put_volsw_vu(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)106 static int cs530x_put_volsw_vu(struct snd_kcontrol *kcontrol,
107 struct snd_ctl_elem_value *ucontrol)
108 {
109 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
110 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
111 struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
112 struct regmap *regmap = cs530x->regmap;
113 int ret;
114
115 snd_soc_dapm_mutex_lock(dapm);
116
117 ret = snd_soc_put_volsw(kcontrol, ucontrol);
118 if (ret)
119 goto volsw_err;
120
121 /* Write IN_VU bit for the volume change to take effect */
122 regmap_write(regmap, CS530X_IN_VOL_CTRL5, CS530X_IN_VU);
123
124 volsw_err:
125 snd_soc_dapm_mutex_unlock(dapm);
126
127 return ret;
128 }
129
130 static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1270, 50, 0);
131
132 static const char * const cs530x_in_filter_text[] = {
133 "Min Phase Slow Roll-off",
134 "Min Phase Fast Roll-off",
135 "Linear Phase Slow Roll-off",
136 "Linear Phase Fast Roll-off",
137 };
138
139 static SOC_ENUM_SINGLE_DECL(cs530x_in_filter_enum, CS530X_IN_FILTER,
140 CS530X_IN_FILTER_SHIFT,
141 cs530x_in_filter_text);
142
143 static const char * const cs530x_in_4ch_sum_text[] = {
144 "None",
145 "Groups of 2",
146 "Groups of 4",
147 };
148
149 static SOC_ENUM_SINGLE_DECL(cs530x_in_sum_ch4_enum, CS530X_IN_RAMP_SUM,
150 CS530X_IN_SUM_MODE_SHIFT,
151 cs530x_in_4ch_sum_text);
152
153 static const struct snd_kcontrol_new cs530x_in_sum_4ch_controls[] = {
154 SOC_ENUM("IN Sum Select", cs530x_in_sum_ch4_enum),
155 };
156
157 static const char * const cs530x_in_8ch_sum_text[] = {
158 "None",
159 "Groups of 2",
160 "Groups of 4",
161 "Groups of 8",
162 };
163
164 static SOC_ENUM_SINGLE_DECL(cs530x_in_sum_ch8_enum, CS530X_IN_RAMP_SUM,
165 CS530X_IN_SUM_MODE_SHIFT,
166 cs530x_in_8ch_sum_text);
167
168 static const struct snd_kcontrol_new cs530x_in_sum_8ch_controls[] = {
169 SOC_ENUM("IN Sum Select", cs530x_in_sum_ch8_enum),
170 };
171
172
173 static const char * const cs530x_vol_ramp_text[] = {
174 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
175 "15ms/6dB", "30ms/6dB",
176 };
177
178 static SOC_ENUM_SINGLE_DECL(cs530x_ramp_inc_enum, CS530X_IN_RAMP_SUM,
179 CS530X_RAMP_RATE_INC_SHIFT,
180 cs530x_vol_ramp_text);
181
182 static SOC_ENUM_SINGLE_DECL(cs530x_ramp_dec_enum, CS530X_IN_RAMP_SUM,
183 CS530X_RAMP_RATE_DEC_SHIFT,
184 cs530x_vol_ramp_text);
185
186 static const struct snd_kcontrol_new cs530x_in_1_to_2_controls[] = {
187 SOC_SINGLE_EXT_TLV("IN1 Volume", CS530X_IN_VOL_CTRL1_0, 0, 255, 1,
188 snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
189 SOC_SINGLE_EXT_TLV("IN2 Volume", CS530X_IN_VOL_CTRL1_1, 0, 255, 1,
190 snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
191
192 SOC_ENUM("IN DEC Filter Select", cs530x_in_filter_enum),
193 SOC_ENUM("Input Ramp Up", cs530x_ramp_inc_enum),
194 SOC_ENUM("Input Ramp Down", cs530x_ramp_dec_enum),
195
196 SOC_SINGLE("ADC1 Invert Switch", CS530X_IN_INV, CS530X_IN1_INV_SHIFT, 1, 0),
197 SOC_SINGLE("ADC2 Invert Switch", CS530X_IN_INV, CS530X_IN2_INV_SHIFT, 1, 0),
198 };
199
200 static const struct snd_kcontrol_new cs530x_in_3_to_4_controls[] = {
201 SOC_SINGLE_EXT_TLV("IN3 Volume", CS530X_IN_VOL_CTRL2_0, 0, 255, 1,
202 snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
203 SOC_SINGLE_EXT_TLV("IN4 Volume", CS530X_IN_VOL_CTRL2_1, 0, 255, 1,
204 snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
205
206 SOC_SINGLE("ADC3 Invert Switch", CS530X_IN_INV, CS530X_IN3_INV_SHIFT, 1, 0),
207 SOC_SINGLE("ADC4 Invert Switch", CS530X_IN_INV, CS530X_IN4_INV_SHIFT, 1, 0),
208 };
209
210 static const struct snd_kcontrol_new cs530x_in_5_to_8_controls[] = {
211 SOC_SINGLE_EXT_TLV("IN5 Volume", CS530X_IN_VOL_CTRL3_0, 0, 255, 1,
212 snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
213 SOC_SINGLE_EXT_TLV("IN6 Volume", CS530X_IN_VOL_CTRL3_1, 0, 255, 1,
214 snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
215 SOC_SINGLE_EXT_TLV("IN7 Volume", CS530X_IN_VOL_CTRL4_0, 0, 255, 1,
216 snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
217 SOC_SINGLE_EXT_TLV("IN8 Volume", CS530X_IN_VOL_CTRL4_1, 0, 255, 1,
218 snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
219
220 SOC_SINGLE("ADC5 Invert Switch", CS530X_IN_INV, CS530X_IN5_INV_SHIFT, 1, 0),
221 SOC_SINGLE("ADC6 Invert Switch", CS530X_IN_INV, CS530X_IN6_INV_SHIFT, 1, 0),
222 SOC_SINGLE("ADC7 Invert Switch", CS530X_IN_INV, CS530X_IN7_INV_SHIFT, 1, 0),
223 SOC_SINGLE("ADC8 Invert Switch", CS530X_IN_INV, CS530X_IN8_INV_SHIFT, 1, 0),
224 };
225
cs530x_adc_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)226 static int cs530x_adc_event(struct snd_soc_dapm_widget *w,
227 struct snd_kcontrol *kcontrol, int event)
228 {
229 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
230 struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
231 struct regmap *regmap = cs530x->regmap;
232
233 switch (event) {
234 case SND_SOC_DAPM_PRE_PMU:
235 cs530x->adc_pairs_count++;
236 break;
237 case SND_SOC_DAPM_POST_PMU:
238 regmap_clear_bits(regmap, CS530X_IN_VOL_CTRL1_0 +
239 (w->shift * 2), CS530X_IN_MUTE);
240 regmap_clear_bits(regmap, CS530X_IN_VOL_CTRL1_0 +
241 ((w->shift+1) * 2), CS530X_IN_MUTE);
242
243 cs530x->adc_pairs_count--;
244 if (!cs530x->adc_pairs_count) {
245 usleep_range(1000, 1100);
246 return regmap_write(regmap, CS530X_IN_VOL_CTRL5,
247 CS530X_IN_VU);
248 }
249 break;
250 case SND_SOC_DAPM_PRE_PMD:
251 regmap_set_bits(regmap, CS530X_IN_VOL_CTRL1_0 +
252 (w->shift * 2), CS530X_IN_MUTE);
253 regmap_set_bits(regmap, CS530X_IN_VOL_CTRL1_0 +
254 ((w->shift+1) * 2), CS530X_IN_MUTE);
255 return regmap_write(regmap, CS530X_IN_VOL_CTRL5,
256 CS530X_IN_VU);
257 default:
258 return -EINVAL;
259 }
260
261 return 0;
262 }
263
264 static const struct snd_kcontrol_new adc12_ctrl =
265 SOC_DAPM_SINGLE_VIRT("Switch", 1);
266
267 static const struct snd_kcontrol_new adc34_ctrl =
268 SOC_DAPM_SINGLE_VIRT("Switch", 1);
269
270 static const struct snd_kcontrol_new adc56_ctrl =
271 SOC_DAPM_SINGLE_VIRT("Switch", 1);
272
273 static const struct snd_kcontrol_new adc78_ctrl =
274 SOC_DAPM_SINGLE_VIRT("Switch", 1);
275
276 static const struct snd_kcontrol_new in_hpf_ctrl =
277 SOC_DAPM_SINGLE_VIRT("Switch", 1);
278
279 /* General DAPM widgets for all devices */
280 static const struct snd_soc_dapm_widget cs530x_gen_dapm_widgets[] = {
281 SND_SOC_DAPM_SUPPLY("Global Enable", CS530X_CHIP_ENABLE, 0, 0, NULL, 0),
282 };
283
284 /* ADC's Channels 1 and 2 plus generic ADC DAPM events */
285 static const struct snd_soc_dapm_widget cs530x_adc_ch12_dapm_widgets[] = {
286 SND_SOC_DAPM_INPUT("IN1"),
287 SND_SOC_DAPM_INPUT("IN2"),
288 SND_SOC_DAPM_ADC_E("ADC1", NULL, CS530X_IN_ENABLES, 0, 0,
289 cs530x_adc_event,
290 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
291 SND_SOC_DAPM_PRE_PMU),
292 SND_SOC_DAPM_ADC("ADC2", NULL, CS530X_IN_ENABLES, 1, 0),
293 SND_SOC_DAPM_SWITCH("ADC12 Enable", SND_SOC_NOPM, 0, 0, &adc12_ctrl),
294 SND_SOC_DAPM_SWITCH("IN HPF", CS530X_IN_FILTER, CS530X_IN_HPF_EN_SHIFT,
295 0, &in_hpf_ctrl),
296 };
297
298 /* ADC's Channels 3 and 4 */
299 static const struct snd_soc_dapm_widget cs530x_adc_ch34_dapm_widgets[] = {
300 SND_SOC_DAPM_INPUT("IN3"),
301 SND_SOC_DAPM_INPUT("IN4"),
302 SND_SOC_DAPM_ADC_E("ADC3", NULL, CS530X_IN_ENABLES, 2, 0,
303 cs530x_adc_event,
304 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
305 SND_SOC_DAPM_PRE_PMU),
306 SND_SOC_DAPM_ADC("ADC4", NULL, CS530X_IN_ENABLES, 3, 0),
307 SND_SOC_DAPM_SWITCH("ADC34 Enable", SND_SOC_NOPM, 0, 0, &adc34_ctrl),
308 };
309
310 /* ADC's Channels 5 to 8 */
311 static const struct snd_soc_dapm_widget cs530x_adc_ch58_dapm_widgets[] = {
312 SND_SOC_DAPM_INPUT("IN5"),
313 SND_SOC_DAPM_INPUT("IN6"),
314 SND_SOC_DAPM_INPUT("IN7"),
315 SND_SOC_DAPM_INPUT("IN8"),
316 SND_SOC_DAPM_ADC_E("ADC5", NULL, CS530X_IN_ENABLES, 4, 0,
317 cs530x_adc_event,
318 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
319 SND_SOC_DAPM_PRE_PMU),
320 SND_SOC_DAPM_ADC("ADC6", NULL, CS530X_IN_ENABLES, 5, 0),
321 SND_SOC_DAPM_SWITCH("ADC56 Enable", SND_SOC_NOPM, 0, 0, &adc56_ctrl),
322 SND_SOC_DAPM_ADC_E("ADC7", NULL, CS530X_IN_ENABLES, 6, 0,
323 cs530x_adc_event,
324 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
325 SND_SOC_DAPM_PRE_PMU),
326 SND_SOC_DAPM_ADC("ADC8", NULL, CS530X_IN_ENABLES, 7, 0),
327 SND_SOC_DAPM_SWITCH("ADC78 Enable", SND_SOC_NOPM, 0, 0, &adc78_ctrl),
328 };
329
330 static const struct snd_soc_dapm_route adc_ch1_2_routes[] = {
331 { "ADC1", NULL, "Global Enable" },
332 { "ADC2", NULL, "Global Enable" },
333
334 { "ADC12 Enable", "Switch", "IN1" },
335 { "ADC12 Enable", "Switch", "IN2" },
336 { "ADC1", NULL, "ADC12 Enable" },
337 { "ADC2", NULL, "ADC12 Enable" },
338 { "IN HPF", "Switch", "ADC1" },
339 { "IN HPF", "Switch", "ADC2" },
340
341 { "AIF Capture", NULL, "IN HPF" },
342 { "AIF Capture", NULL, "ADC1" },
343 { "AIF Capture", NULL, "ADC2" },
344 };
345
346 static const struct snd_soc_dapm_route adc_ch3_4_routes[] = {
347 { "ADC3", NULL, "Global Enable" },
348 { "ADC4", NULL, "Global Enable" },
349
350 { "ADC34 Enable", "Switch", "IN3" },
351 { "ADC34 Enable", "Switch", "IN4" },
352 { "ADC3", NULL, "ADC34 Enable" },
353 { "ADC4", NULL, "ADC34 Enable" },
354 { "IN HPF", "Switch", "ADC3" },
355 { "IN HPF", "Switch", "ADC4" },
356
357 { "AIF Capture", NULL, "ADC3" },
358 { "AIF Capture", NULL, "ADC4" },
359 };
360
361 static const struct snd_soc_dapm_route adc_ch5_8_routes[] = {
362 { "ADC5", NULL, "Global Enable" },
363 { "ADC6", NULL, "Global Enable" },
364 { "ADC7", NULL, "Global Enable" },
365 { "ADC8", NULL, "Global Enable" },
366
367 { "ADC56 Enable", "Switch", "IN5" },
368 { "ADC56 Enable", "Switch", "IN6" },
369 { "ADC5", NULL, "ADC56 Enable" },
370 { "ADC6", NULL, "ADC56 Enable" },
371 { "IN HPF", "Switch", "ADC5" },
372 { "IN HPF", "Switch", "ADC6" },
373
374 { "AIF Capture", NULL, "ADC5" },
375 { "AIF Capture", NULL, "ADC6" },
376
377 { "ADC78 Enable", "Switch", "IN7" },
378 { "ADC78 Enable", "Switch", "IN8" },
379 { "ADC7", NULL, "ADC78 Enable" },
380 { "ADC8", NULL, "ADC78 Enable" },
381 { "IN HPF", "Switch", "ADC7" },
382 { "IN HPF", "Switch", "ADC8" },
383
384 { "AIF Capture", NULL, "ADC7" },
385 { "AIF Capture", NULL, "ADC8" },
386 };
387
cs530x_add_12_adc_widgets(struct snd_soc_component * component)388 static void cs530x_add_12_adc_widgets(struct snd_soc_component *component)
389 {
390 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
391
392 snd_soc_add_component_controls(component,
393 cs530x_in_1_to_2_controls,
394 ARRAY_SIZE(cs530x_in_1_to_2_controls));
395
396 snd_soc_dapm_new_controls(dapm, cs530x_adc_ch12_dapm_widgets,
397 ARRAY_SIZE(cs530x_adc_ch12_dapm_widgets));
398
399 snd_soc_dapm_add_routes(dapm, adc_ch1_2_routes,
400 ARRAY_SIZE(adc_ch1_2_routes));
401 }
402
cs530x_add_34_adc_widgets(struct snd_soc_component * component)403 static void cs530x_add_34_adc_widgets(struct snd_soc_component *component)
404 {
405 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
406
407 snd_soc_add_component_controls(component,
408 cs530x_in_3_to_4_controls,
409 ARRAY_SIZE(cs530x_in_3_to_4_controls));
410
411 snd_soc_dapm_new_controls(dapm, cs530x_adc_ch34_dapm_widgets,
412 ARRAY_SIZE(cs530x_adc_ch34_dapm_widgets));
413
414 snd_soc_dapm_add_routes(dapm, adc_ch3_4_routes,
415 ARRAY_SIZE(adc_ch3_4_routes));
416 }
417
cs530x_set_bclk(struct snd_soc_component * component,const int freq)418 static int cs530x_set_bclk(struct snd_soc_component *component, const int freq)
419 {
420 struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
421 struct regmap *regmap = cs530x->regmap;
422 unsigned int bclk_val;
423
424 switch (freq) {
425 case 2822400:
426 case 3072000:
427 bclk_val = CS530X_BCLK_2P822_3P072;
428 break;
429 case 5644800:
430 case 6144000:
431 bclk_val = CS530X_BCLK_5P6448_6P144;
432 break;
433 case 11289600:
434 case 12288000:
435 bclk_val = CS530X_BCLK_11P2896_12P288;
436 break;
437 case 22579200:
438 case 24576000:
439 bclk_val = CS530X_BCLK_24P5792_24P576;
440 break;
441 default:
442 dev_err(component->dev, "Invalid BCLK frequency %d\n", freq);
443 return -EINVAL;
444 }
445
446 dev_dbg(component->dev, "BCLK frequency is %d\n", freq);
447
448 return regmap_update_bits(regmap, CS530X_ASP_CFG,
449 CS530X_ASP_BCLK_FREQ_MASK, bclk_val);
450 }
451
cs530x_set_pll_refclk(struct snd_soc_component * component,const unsigned int freq)452 static int cs530x_set_pll_refclk(struct snd_soc_component *component,
453 const unsigned int freq)
454 {
455 struct cs530x_priv *priv = snd_soc_component_get_drvdata(component);
456 struct regmap *regmap = priv->regmap;
457 unsigned int refclk;
458
459 switch (freq) {
460 case 2822400:
461 case 3072000:
462 refclk = CS530X_REFCLK_2P822_3P072;
463 break;
464 case 5644800:
465 case 6144000:
466 refclk = CS530X_REFCLK_5P6448_6P144;
467 break;
468 case 11289600:
469 case 12288000:
470 refclk = CS530X_REFCLK_11P2896_12P288;
471 break;
472 case 22579200:
473 case 24576000:
474 refclk = CS530X_REFCLK_24P5792_24P576;
475 break;
476 default:
477 dev_err(component->dev, "Invalid PLL refclk %d\n", freq);
478 return -EINVAL;
479 }
480
481 return regmap_update_bits(regmap, CS530X_CLK_CFG_0,
482 CS530X_PLL_REFCLK_FREQ_MASK, refclk);
483 }
484
cs530x_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)485 static int cs530x_hw_params(struct snd_pcm_substream *substream,
486 struct snd_pcm_hw_params *params,
487 struct snd_soc_dai *dai)
488 {
489 struct snd_soc_component *component = dai->component;
490 struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
491 struct regmap *regmap = cs530x->regmap;
492 int ret = 0, fs = params_rate(params), bclk;
493 unsigned int fs_val;
494
495
496 switch (fs) {
497 case 32000:
498 fs_val = CS530X_FS_32K;
499 break;
500 case 44100:
501 case 48000:
502 fs_val = CS530X_FS_48K_44P1K;
503 break;
504 case 88200:
505 case 96000:
506 fs_val = CS530X_FS_96K_88P2K;
507 break;
508 case 176400:
509 case 192000:
510 fs_val = CS530X_FS_192K_176P4K;
511 break;
512 case 356800:
513 case 384000:
514 fs_val = CS530X_FS_384K_356P8K;
515 break;
516 case 705600:
517 case 768000:
518 fs_val = CS530X_FS_768K_705P6K;
519 break;
520 default:
521 dev_err(component->dev, "Invalid sample rate %d\n", fs);
522 return -EINVAL;
523 }
524
525 cs530x->fs = fs;
526 regmap_update_bits(regmap, CS530X_CLK_CFG_1,
527 CS530X_SAMPLE_RATE_MASK, fs_val);
528
529
530 if (regmap_test_bits(regmap, CS530X_SIGNAL_PATH_CFG,
531 CS530X_TDM_EN_MASK)) {
532 dev_dbg(component->dev, "Configuring for %d %d bit TDM slots\n",
533 cs530x->tdm_slots, cs530x->tdm_width);
534 bclk = snd_soc_tdm_params_to_bclk(params,
535 cs530x->tdm_width,
536 cs530x->tdm_slots,
537 1);
538 } else {
539 bclk = snd_soc_params_to_bclk(params);
540 }
541
542 if (!regmap_test_bits(regmap, CS530X_CLK_CFG_0,
543 CS530X_PLL_REFCLK_SRC_MASK)) {
544 ret = cs530x_set_pll_refclk(component, bclk);
545 if (ret)
546 return ret;
547 }
548
549 return cs530x_set_bclk(component, bclk);
550 }
551
cs530x_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)552 static int cs530x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
553 {
554 struct snd_soc_component *component = dai->component;
555 struct cs530x_priv *priv = snd_soc_component_get_drvdata(component);
556 struct regmap *regmap = priv->regmap;
557 unsigned int asp_fmt, asp_cfg = 0;
558
559 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
560 case SND_SOC_DAIFMT_CBS_CFS:
561 break;
562 case SND_SOC_DAIFMT_CBM_CFM:
563 asp_cfg = CS530X_ASP_PRIMARY;
564 break;
565 default:
566 return -EINVAL;
567 }
568
569 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
570 case SND_SOC_DAIFMT_DSP_A:
571 asp_fmt = CS530X_ASP_FMT_DSP_A;
572 break;
573 case SND_SOC_DAIFMT_I2S:
574 asp_fmt = CS530X_ASP_FMT_I2S;
575 break;
576 case SND_SOC_DAIFMT_LEFT_J:
577 asp_fmt = CS530X_ASP_FMT_LJ;
578 break;
579 default:
580 return -EINVAL;
581 }
582
583 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
584 case SND_SOC_DAIFMT_NB_NF:
585 break;
586 case SND_SOC_DAIFMT_IB_IF:
587 asp_cfg |= CS530X_ASP_BCLK_INV;
588 break;
589 default:
590 return -EINVAL;
591 }
592
593 regmap_update_bits(regmap, CS530X_ASP_CFG,
594 CS530X_ASP_PRIMARY | CS530X_ASP_BCLK_INV,
595 asp_cfg);
596
597 return regmap_update_bits(regmap, CS530X_SIGNAL_PATH_CFG,
598 CS530X_ASP_FMT_MASK, asp_fmt);
599 }
600
cs530x_check_mclk_freq(struct snd_soc_component * component,const unsigned int freq)601 static bool cs530x_check_mclk_freq(struct snd_soc_component *component,
602 const unsigned int freq)
603 {
604 switch (freq) {
605 case 24576000:
606 case 22579200:
607 case 12288000:
608 case 11289600:
609 return true;
610 default:
611 dev_err(component->dev, "Invalid MCLK %d\n", freq);
612 return false;
613 }
614 }
615
cs530x_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)616 static int cs530x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
617 unsigned int rx_mask, int slots, int slot_width)
618 {
619 struct snd_soc_component *component = dai->component;
620 struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
621 struct regmap *regmap = cs530x->regmap;
622 unsigned int val;
623
624 switch (tx_mask) {
625 case CS530X_0_1_TDM_SLOT_MASK:
626 case CS530X_0_3_TDM_SLOT_MASK:
627 case CS530X_0_7_TDM_SLOT_MASK:
628 val = CS530X_0_7_TDM_SLOT_VAL;
629 break;
630 case CS530X_2_3_TDM_SLOT_MASK:
631 val = CS530X_2_3_TDM_SLOT_VAL;
632 break;
633 case CS530X_4_5_TDM_SLOT_MASK:
634 case CS530X_4_7_TDM_SLOT_MASK:
635 val = CS530X_4_7_TDM_SLOT_VAL;
636 break;
637 case CS530X_6_7_TDM_SLOT_MASK:
638 val = CS530X_6_7_TDM_SLOT_VAL;
639 break;
640 case CS530X_8_9_TDM_SLOT_MASK:
641 case CS530X_8_11_TDM_SLOT_MASK:
642 case CS530X_8_15_TDM_SLOT_MASK:
643 val = CS530X_8_15_TDM_SLOT_VAL;
644 break;
645 case CS530X_10_11_TDM_SLOT_MASK:
646 val = CS530X_10_11_TDM_SLOT_VAL;
647 break;
648 case CS530X_12_13_TDM_SLOT_MASK:
649 case CS530X_12_15_TDM_SLOT_MASK:
650 val = CS530X_12_15_TDM_SLOT_VAL;
651 break;
652 case CS530X_14_15_TDM_SLOT_MASK:
653 val = CS530X_14_15_TDM_SLOT_VAL;
654 break;
655 default:
656 dev_err(component->dev, "Invalid TX slot(s) 0x%x\n", tx_mask);
657 return -EINVAL;
658 }
659
660 cs530x->tdm_width = slot_width;
661 cs530x->tdm_slots = slots;
662
663 return regmap_update_bits(regmap, CS530X_SIGNAL_PATH_CFG,
664 CS530X_ASP_TDM_SLOT_MASK,
665 val << CS530X_ASP_TDM_SLOT_SHIFT);
666 }
667
668 static const struct snd_soc_dai_ops cs530x_dai_ops = {
669 .set_fmt = cs530x_set_fmt,
670 .hw_params = cs530x_hw_params,
671 .set_tdm_slot = cs530x_set_tdm_slot,
672 };
673
674 static const struct snd_soc_dai_driver cs530x_dai = {
675 .name = "cs530x-dai",
676 .capture = {
677 .stream_name = "AIF Capture",
678 .channels_min = 2,
679 .channels_max = 8,
680 .rates = SNDRV_PCM_RATE_KNOT,
681 .formats = SNDRV_PCM_FMTBIT_S32_LE,
682 },
683 .ops = &cs530x_dai_ops,
684 .symmetric_rate = 1,
685 .symmetric_sample_bits = 1,
686 };
687
cs530x_set_pll(struct snd_soc_component * component,int pll_id,int source,unsigned int freq_in,unsigned int freq_out)688 static int cs530x_set_pll(struct snd_soc_component *component, int pll_id,
689 int source, unsigned int freq_in,
690 unsigned int freq_out)
691 {
692 struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
693 struct regmap *regmap = cs530x->regmap;
694 unsigned int sysclk_src;
695 int ret;
696
697 regmap_read(regmap, CS530X_CLK_CFG_0, &sysclk_src);
698
699 /* Check if the source is the PLL */
700 if ((sysclk_src & CS530X_SYSCLK_SRC_MASK) == 0)
701 return 0;
702
703 switch (source) {
704 case CS530X_PLL_SRC_MCLK:
705 if (!cs530x_check_mclk_freq(component, freq_in))
706 return -EINVAL;
707
708 ret = cs530x_set_pll_refclk(component, freq_in);
709 if (ret)
710 return ret;
711
712 break;
713 case CS530X_PLL_SRC_BCLK:
714 break;
715 default:
716 dev_err(component->dev, "Invalid PLL source %d\n", source);
717 return -EINVAL;
718 }
719
720 return regmap_update_bits(regmap, CS530X_CLK_CFG_0,
721 CS530X_PLL_REFCLK_SRC_MASK, source);
722 }
723
cs530x_component_probe(struct snd_soc_component * component)724 static int cs530x_component_probe(struct snd_soc_component *component)
725 {
726 struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
727 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
728 int num_widgets;
729
730 snd_soc_dapm_new_controls(dapm, cs530x_gen_dapm_widgets,
731 ARRAY_SIZE(cs530x_gen_dapm_widgets));
732
733 switch (cs530x->devtype) {
734 case CS5302:
735 cs530x_add_12_adc_widgets(component);
736 break;
737 case CS5304:
738 cs530x_add_12_adc_widgets(component);
739 cs530x_add_34_adc_widgets(component);
740
741 num_widgets = ARRAY_SIZE(cs530x_in_sum_4ch_controls);
742 snd_soc_add_component_controls(component,
743 cs530x_in_sum_4ch_controls,
744 num_widgets);
745 break;
746
747 case CS5308:
748 cs530x_add_12_adc_widgets(component);
749 cs530x_add_34_adc_widgets(component);
750
751 num_widgets = ARRAY_SIZE(cs530x_in_5_to_8_controls);
752 snd_soc_add_component_controls(component,
753 cs530x_in_5_to_8_controls,
754 num_widgets);
755
756 num_widgets = ARRAY_SIZE(cs530x_in_sum_8ch_controls);
757 snd_soc_add_component_controls(component,
758 cs530x_in_sum_8ch_controls,
759 num_widgets);
760
761 num_widgets = ARRAY_SIZE(cs530x_adc_ch58_dapm_widgets);
762 snd_soc_dapm_new_controls(dapm, cs530x_adc_ch58_dapm_widgets,
763 num_widgets);
764
765 snd_soc_dapm_add_routes(dapm, adc_ch5_8_routes,
766 ARRAY_SIZE(adc_ch5_8_routes));
767 break;
768 default:
769 dev_err(component->dev, "Invalid device type %d\n",
770 cs530x->devtype);
771 return -EINVAL;
772 }
773
774 return 0;
775 }
776
cs530x_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)777 static int cs530x_set_sysclk(struct snd_soc_component *component, int clk_id,
778 int source, unsigned int freq, int dir)
779 {
780 struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
781 struct regmap *regmap = cs530x->regmap;
782
783 switch (source) {
784 case CS530X_SYSCLK_SRC_MCLK:
785 if (freq != 24560000 && freq != 22572000) {
786 dev_err(component->dev, "Invalid MCLK source rate %d\n",
787 freq);
788 return -EINVAL;
789 }
790
791 cs530x->mclk_rate = freq;
792 break;
793 case CS530X_SYSCLK_SRC_PLL:
794 break;
795 default:
796 dev_err(component->dev, "Invalid clock id %d\n", clk_id);
797 return -EINVAL;
798 }
799
800 return regmap_update_bits(regmap, CS530X_CLK_CFG_0,
801 CS530X_SYSCLK_SRC_MASK,
802 source << CS530X_SYSCLK_SRC_SHIFT);
803 }
804
805 static const struct snd_soc_component_driver soc_component_dev_cs530x = {
806 .probe = cs530x_component_probe,
807 .set_sysclk = cs530x_set_sysclk,
808 .set_pll = cs530x_set_pll,
809 .endianness = 1,
810 };
811
812 const struct regmap_config cs530x_regmap = {
813 .reg_bits = 16,
814 .val_bits = 16,
815
816 .max_register = CS530X_MAX_REGISTER,
817 .readable_reg = cs530x_readable_register,
818 .writeable_reg = cs530x_writeable_register,
819
820 .cache_type = REGCACHE_MAPLE,
821 .reg_defaults = cs530x_reg_defaults,
822 .num_reg_defaults = ARRAY_SIZE(cs530x_reg_defaults),
823 };
824 EXPORT_SYMBOL_NS_GPL(cs530x_regmap, SND_SOC_CS530X);
825
cs530x_check_device_id(struct cs530x_priv * cs530x)826 static int cs530x_check_device_id(struct cs530x_priv *cs530x)
827 {
828 struct device *dev = cs530x->dev;
829 unsigned int dev_id, rev;
830 int ret;
831
832 ret = regmap_read(cs530x->regmap, CS530X_DEVID, &dev_id);
833 if (ret)
834 return dev_err_probe(dev, ret, "Can't read device ID\n");
835
836 ret = regmap_read(cs530x->regmap, CS530X_REVID, &rev);
837 if (ret)
838 return dev_err_probe(dev, ret, "Can't read REV ID\n");
839
840 dev_dbg(dev, "Device ID 0x%x Rev ID 0x%x\n", dev_id, rev);
841
842 switch (dev_id) {
843 case CS530X_2CH_ADC_DEV_ID:
844 cs530x->num_adcs = 2;
845 break;
846 case CS530X_4CH_ADC_DEV_ID:
847 cs530x->num_adcs = 4;
848 break;
849 case CS530X_8CH_ADC_DEV_ID:
850 cs530x->num_adcs = 8;
851 break;
852 default:
853 return dev_err_probe(dev, -EINVAL, "Invalid device ID 0x%x\n",
854 dev_id);
855 }
856
857 return 0;
858 }
859
cs530x_parse_device_properties(struct cs530x_priv * cs530x)860 static int cs530x_parse_device_properties(struct cs530x_priv *cs530x)
861 {
862 struct regmap *regmap = cs530x->regmap;
863 struct device *dev = cs530x->dev;
864 unsigned int val = 0;
865
866 switch (cs530x->num_adcs) {
867 case 8:
868 if (device_property_read_bool(dev, "cirrus,in-hiz-pin78"))
869 val = CS530X_IN78_HIZ;
870
871 if (device_property_read_bool(dev, "cirrus,in-hiz-pin56"))
872 val |= CS530X_IN56_HIZ;
873
874 fallthrough;
875 case 4:
876 if (device_property_read_bool(dev, "cirrus,in-hiz-pin34"))
877 val |= CS530X_IN34_HIZ;
878
879 fallthrough;
880 case 2:
881 if (device_property_read_bool(dev, "cirrus,in-hiz-pin12"))
882 val |= CS530X_IN12_HIZ;
883
884 return regmap_set_bits(regmap, CS530X_IN_HIZ, val);
885 default:
886 return dev_err_probe(dev, -EINVAL,
887 "Invalid number of adcs %d\n",
888 cs530x->num_adcs);
889 }
890 }
891
cs530x_probe(struct cs530x_priv * cs530x)892 int cs530x_probe(struct cs530x_priv *cs530x)
893 {
894 struct device *dev = cs530x->dev;
895 int ret, i;
896
897 cs530x->dev_dai = devm_kmemdup(dev, &cs530x_dai,
898 sizeof(*(cs530x->dev_dai)),
899 GFP_KERNEL);
900 if (!cs530x->dev_dai)
901 return -ENOMEM;
902
903 for (i = 0; i < ARRAY_SIZE(cs530x->supplies); i++)
904 cs530x->supplies[i].supply = cs530x_supply_names[i];
905
906 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs530x->supplies),
907 cs530x->supplies);
908 if (ret != 0)
909 return dev_err_probe(dev, ret, "Failed to request supplies");
910
911 ret = regulator_bulk_enable(ARRAY_SIZE(cs530x->supplies),
912 cs530x->supplies);
913 if (ret != 0)
914 return dev_err_probe(dev, ret, "Failed to enable supplies");
915
916 cs530x->reset_gpio = devm_gpiod_get_optional(dev, "reset",
917 GPIOD_OUT_HIGH);
918 if (IS_ERR(cs530x->reset_gpio)) {
919 ret = dev_err_probe(dev, PTR_ERR(cs530x->reset_gpio),
920 "Reset gpio not available\n");
921 goto err_regulator;
922 }
923
924 if (cs530x->reset_gpio) {
925 usleep_range(2000, 2100);
926 gpiod_set_value_cansleep(cs530x->reset_gpio, 0);
927 }
928
929 usleep_range(5000, 5100);
930 ret = cs530x_check_device_id(cs530x);
931 if (ret)
932 goto err_reset;
933
934 if (!cs530x->reset_gpio) {
935 ret = regmap_write(cs530x->regmap, CS530X_SW_RESET,
936 CS530X_SW_RST_VAL);
937 if (ret) {
938 dev_err_probe(dev, ret, "Soft Reset Failed\n");
939 goto err_reset;
940 }
941 }
942
943 ret = cs530x_parse_device_properties(cs530x);
944 if (ret)
945 goto err_reset;
946
947 cs530x->dev_dai->capture.channels_max = cs530x->num_adcs;
948
949 ret = devm_snd_soc_register_component(dev,
950 &soc_component_dev_cs530x, cs530x->dev_dai, 1);
951 if (ret) {
952 dev_err_probe(dev, ret, "Can't register cs530x component\n");
953 goto err_reset;
954 }
955
956 return 0;
957
958 err_reset:
959 gpiod_set_value_cansleep(cs530x->reset_gpio, 1);
960
961 err_regulator:
962 regulator_bulk_disable(ARRAY_SIZE(cs530x->supplies),
963 cs530x->supplies);
964
965 return ret;
966 }
967 EXPORT_SYMBOL_NS_GPL(cs530x_probe, SND_SOC_CS530X);
968
969 MODULE_DESCRIPTION("CS530X CODEC Driver");
970 MODULE_AUTHOR("Paul Handrigan <paulha@opensource.cirrus.com>");
971 MODULE_LICENSE("GPL");
972