xref: /linux/sound/soc/codecs/cs530x.c (revision 377773dd6be500d17b94de08271ff9ed643554f1)
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