xref: /linux/sound/soc/codecs/cs530x.c (revision 3f1c07fc21c68bd3bd2df9d2c9441f6485e934d9)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // CS530x CODEC driver
4 //
5 // Copyright (C) 2024-2025 Cirrus Logic, Inc. and
6 //                         Cirrus Logic International Semiconductor Ltd.
7 
8 #include <linux/delay.h>
9 #include <linux/i2c.h>
10 #include <linux/init.h>
11 #include <linux/module.h>
12 #include <linux/pm.h>
13 #include <linux/property.h>
14 #include <linux/slab.h>
15 #include <linux/spi/spi.h>
16 #include <sound/core.h>
17 #include <sound/initval.h>
18 #include <sound/pcm.h>
19 #include <sound/pcm_params.h>
20 #include <sound/soc.h>
21 #include <sound/tlv.h>
22 
23 #include "cs530x.h"
24 
25 static const char *cs530x_supply_names[CS530X_NUM_SUPPLIES] = {
26 	"vdd-a",
27 	"vdd-io",
28 };
29 
30 static const struct reg_default cs530x_reg_defaults[] = {
31 	{ CS530X_CLK_CFG_0, 0x30 },
32 	{ CS530X_CLK_CFG_1, 0x0001 },
33 	{ CS530X_CHIP_ENABLE, 0 },
34 	{ CS530X_ASP_CFG, 0 },
35 	{ CS530X_SIGNAL_PATH_CFG, 0 },
36 	{ CS530X_IN_ENABLES, 0 },
37 	{ CS530X_IN_RAMP_SUM, 0x0022 },
38 	{ CS530X_IN_FILTER, 0 },
39 	{ CS530X_IN_HIZ, 0 },
40 	{ CS530X_IN_INV, 0 },
41 	{ CS530X_IN_VOL_CTRL1_0, 0x8000 },
42 	{ CS530X_IN_VOL_CTRL1_1, 0x8000 },
43 	{ CS530X_IN_VOL_CTRL2_0, 0x8000 },
44 	{ CS530X_IN_VOL_CTRL2_1, 0x8000 },
45 	{ CS530X_IN_VOL_CTRL3_0, 0x8000 },
46 	{ CS530X_IN_VOL_CTRL3_1, 0x8000 },
47 	{ CS530X_IN_VOL_CTRL4_0, 0x8000 },
48 	{ CS530X_IN_VOL_CTRL4_1, 0x8000 },
49 	{ CS530X_OUT_ENABLES, 0 },
50 	{ CS530X_OUT_RAMP_SUM, 0x0022 },
51 	{ CS530X_OUT_FILTER, 0 },
52 	{ CS530X_OUT_INV, 0 },
53 	{ CS530X_OUT_VOL_CTRL1_0, 0x8000 },
54 	{ CS530X_OUT_VOL_CTRL1_1, 0x8000 },
55 	{ CS530X_OUT_VOL_CTRL2_0, 0x8000 },
56 	{ CS530X_OUT_VOL_CTRL2_1, 0x8000 },
57 	{ CS530X_OUT_VOL_CTRL3_0, 0x8000 },
58 	{ CS530X_OUT_VOL_CTRL3_1, 0x8000 },
59 	{ CS530X_OUT_VOL_CTRL4_0, 0x8000 },
60 	{ CS530X_OUT_VOL_CTRL4_1, 0x8000 },
61 	{ CS530X_PAD_FN, 0 },
62 	{ CS530X_PAD_LVL, 0 },
63 };
64 
cs530x_read_and_write_regs(unsigned int reg)65 static bool cs530x_read_and_write_regs(unsigned int reg)
66 {
67 	switch (reg) {
68 	case CS530X_CLK_CFG_0:
69 	case CS530X_CLK_CFG_1:
70 	case CS530X_CHIP_ENABLE:
71 	case CS530X_ASP_CFG:
72 	case CS530X_SIGNAL_PATH_CFG:
73 	case CS530X_IN_ENABLES:
74 	case CS530X_IN_RAMP_SUM:
75 	case CS530X_IN_FILTER:
76 	case CS530X_IN_HIZ:
77 	case CS530X_IN_INV:
78 	case CS530X_IN_VOL_CTRL1_0:
79 	case CS530X_IN_VOL_CTRL1_1:
80 	case CS530X_IN_VOL_CTRL2_0:
81 	case CS530X_IN_VOL_CTRL2_1:
82 	case CS530X_IN_VOL_CTRL3_0:
83 	case CS530X_IN_VOL_CTRL3_1:
84 	case CS530X_IN_VOL_CTRL4_0:
85 	case CS530X_IN_VOL_CTRL4_1:
86 	case CS530X_OUT_ENABLES:
87 	case CS530X_OUT_RAMP_SUM:
88 	case CS530X_OUT_DEEMPH:
89 	case CS530X_OUT_FILTER:
90 	case CS530X_OUT_INV:
91 	case CS530X_OUT_VOL_CTRL1_0:
92 	case CS530X_OUT_VOL_CTRL1_1:
93 	case CS530X_OUT_VOL_CTRL2_0:
94 	case CS530X_OUT_VOL_CTRL2_1:
95 	case CS530X_OUT_VOL_CTRL3_0:
96 	case CS530X_OUT_VOL_CTRL3_1:
97 	case CS530X_OUT_VOL_CTRL4_0:
98 	case CS530X_OUT_VOL_CTRL4_1:
99 	case CS530X_PAD_FN:
100 	case CS530X_PAD_LVL:
101 		return true;
102 	default:
103 		return false;
104 	}
105 }
106 
cs530x_readable_register(struct device * dev,unsigned int reg)107 static bool cs530x_readable_register(struct device *dev, unsigned int reg)
108 {
109 	switch (reg) {
110 	case CS530X_DEVID:
111 	case CS530X_REVID:
112 		return true;
113 	default:
114 		return cs530x_read_and_write_regs(reg);
115 	}
116 }
117 
cs530x_writeable_register(struct device * dev,unsigned int reg)118 static bool cs530x_writeable_register(struct device *dev, unsigned int reg)
119 {
120 	switch (reg) {
121 	case CS530X_SW_RESET:
122 	case CS530X_IN_VOL_CTRL5:
123 	case CS530X_OUT_VOL_CTRL5:
124 		return true;
125 	default:
126 		return cs530x_read_and_write_regs(reg);
127 	}
128 }
129 
cs530x_put_volsw_vu(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)130 static int cs530x_put_volsw_vu(struct snd_kcontrol *kcontrol,
131 			       struct snd_ctl_elem_value *ucontrol)
132 {
133 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
134 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
135 	struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
136 	struct regmap *regmap = cs530x->regmap;
137 	int ret;
138 
139 	snd_soc_dapm_mutex_lock(dapm);
140 
141 	ret = snd_soc_put_volsw(kcontrol, ucontrol);
142 	if (ret)
143 		goto volsw_err;
144 
145 	/* Write INOUT_VU bit for the volume change to take effect */
146 	regmap_write(regmap, CS530X_IN_VOL_CTRL5, CS530X_INOUT_VU);
147 
148 volsw_err:
149 	snd_soc_dapm_mutex_unlock(dapm);
150 
151 	return ret;
152 }
153 
154 static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1270, 50, 0);
155 
156 static const char * const cs530x_inout_filter_text[] = {
157 	"Min Phase Slow Roll-off",
158 	"Min Phase Fast Roll-off",
159 	"Linear Phase Slow Roll-off",
160 	"Linear Phase Fast Roll-off",
161 };
162 
163 static SOC_ENUM_SINGLE_DECL(cs530x_in_filter_enum, CS530X_IN_FILTER,
164 			    CS530X_INOUT_FILTER_SHIFT,
165 			    cs530x_inout_filter_text);
166 
167 static SOC_ENUM_SINGLE_DECL(cs530x_out_filter_enum, CS530X_OUT_FILTER,
168 			    CS530X_INOUT_FILTER_SHIFT,
169 			    cs530x_inout_filter_text);
170 
171 static const char * const cs530x_4ch_sum_text[] = {
172 	"None",
173 	"Groups of 2",
174 	"Groups of 4",
175 };
176 
177 static SOC_ENUM_SINGLE_DECL(cs530x_in_sum_ch4_enum, CS530X_IN_RAMP_SUM,
178 			    CS530X_INOUT_SUM_MODE_SHIFT,
179 			    cs530x_4ch_sum_text);
180 
181 static const struct snd_kcontrol_new cs530x_in_sum_4ch_controls[] = {
182 SOC_ENUM("IN Sum Select", cs530x_in_sum_ch4_enum),
183 };
184 
185 static SOC_ENUM_SINGLE_DECL(cs530x_out_sum_ch4_enum, CS530X_OUT_RAMP_SUM,
186 			    CS530X_INOUT_SUM_MODE_SHIFT,
187 			    cs530x_4ch_sum_text);
188 
189 static const struct snd_kcontrol_new cs530x_out_sum_4ch_controls[] = {
190 SOC_ENUM("OUT Sum Select", cs530x_out_sum_ch4_enum),
191 };
192 
193 static const char * const cs530x_8ch_sum_text[] = {
194 	"None",
195 	"Groups of 2",
196 	"Groups of 4",
197 	"Groups of 8",
198 };
199 
200 static SOC_ENUM_SINGLE_DECL(cs530x_in_sum_ch8_enum, CS530X_IN_RAMP_SUM,
201 			    CS530X_INOUT_SUM_MODE_SHIFT,
202 			    cs530x_8ch_sum_text);
203 
204 static const struct snd_kcontrol_new cs530x_in_sum_8ch_controls[] = {
205 SOC_ENUM("IN Sum Select", cs530x_in_sum_ch8_enum),
206 };
207 
208 static SOC_ENUM_SINGLE_DECL(cs530x_out_sum_ch8_enum, CS530X_OUT_RAMP_SUM,
209 			    CS530X_INOUT_SUM_MODE_SHIFT,
210 			    cs530x_8ch_sum_text);
211 
212 static const struct snd_kcontrol_new cs530x_out_sum_8ch_controls[] = {
213 SOC_ENUM("OUT Sum Select", cs530x_out_sum_ch8_enum),
214 };
215 
216 static const char * const cs530x_vol_ramp_text[] = {
217 	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
218 	"15ms/6dB", "30ms/6dB",
219 };
220 
221 static SOC_ENUM_SINGLE_DECL(cs530x_ramp_inc_enum, CS530X_IN_RAMP_SUM,
222 			    CS530X_RAMP_RATE_INC_SHIFT,
223 			    cs530x_vol_ramp_text);
224 
225 static SOC_ENUM_SINGLE_DECL(cs530x_ramp_dec_enum, CS530X_IN_RAMP_SUM,
226 			    CS530X_RAMP_RATE_DEC_SHIFT,
227 			    cs530x_vol_ramp_text);
228 
229 static const struct snd_kcontrol_new cs530x_in_1_to_2_controls[] = {
230 SOC_SINGLE_EXT_TLV("IN1 Volume", CS530X_IN_VOL_CTRL1_0, 0, 255, 1,
231 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
232 SOC_SINGLE_EXT_TLV("IN2 Volume", CS530X_IN_VOL_CTRL1_1, 0, 255, 1,
233 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
234 
235 SOC_ENUM("IN DEC Filter Select", cs530x_in_filter_enum),
236 SOC_ENUM("Input Ramp Up", cs530x_ramp_inc_enum),
237 SOC_ENUM("Input Ramp Down", cs530x_ramp_dec_enum),
238 
239 SOC_SINGLE("ADC1 Invert Switch", CS530X_IN_INV, CS530X_INOUT1_INV_SHIFT, 1, 0),
240 SOC_SINGLE("ADC2 Invert Switch", CS530X_IN_INV, CS530X_INOUT2_INV_SHIFT, 1, 0),
241 };
242 
243 static const struct snd_kcontrol_new cs530x_in_3_to_4_controls[] = {
244 SOC_SINGLE_EXT_TLV("IN3 Volume", CS530X_IN_VOL_CTRL2_0, 0, 255, 1,
245 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
246 SOC_SINGLE_EXT_TLV("IN4 Volume", CS530X_IN_VOL_CTRL2_1, 0, 255, 1,
247 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
248 
249 SOC_SINGLE("ADC3 Invert Switch", CS530X_IN_INV, CS530X_INOUT3_INV_SHIFT, 1, 0),
250 SOC_SINGLE("ADC4 Invert Switch", CS530X_IN_INV, CS530X_INOUT4_INV_SHIFT, 1, 0),
251 };
252 
253 static const struct snd_kcontrol_new cs530x_in_5_to_8_controls[] = {
254 SOC_SINGLE_EXT_TLV("IN5 Volume", CS530X_IN_VOL_CTRL3_0, 0, 255, 1,
255 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
256 SOC_SINGLE_EXT_TLV("IN6 Volume", CS530X_IN_VOL_CTRL3_1, 0, 255, 1,
257 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
258 SOC_SINGLE_EXT_TLV("IN7 Volume", CS530X_IN_VOL_CTRL4_0, 0, 255, 1,
259 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
260 SOC_SINGLE_EXT_TLV("IN8 Volume", CS530X_IN_VOL_CTRL4_1, 0, 255, 1,
261 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
262 
263 SOC_SINGLE("ADC5 Invert Switch", CS530X_IN_INV, CS530X_INOUT5_INV_SHIFT, 1, 0),
264 SOC_SINGLE("ADC6 Invert Switch", CS530X_IN_INV, CS530X_INOUT6_INV_SHIFT, 1, 0),
265 SOC_SINGLE("ADC7 Invert Switch", CS530X_IN_INV, CS530X_INOUT7_INV_SHIFT, 1, 0),
266 SOC_SINGLE("ADC8 Invert Switch", CS530X_IN_INV, CS530X_INOUT8_INV_SHIFT, 1, 0),
267 };
268 
cs530x_adc_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)269 static int cs530x_adc_event(struct snd_soc_dapm_widget *w,
270 			    struct snd_kcontrol *kcontrol, int event)
271 {
272 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
273 	struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
274 	struct regmap *regmap = cs530x->regmap;
275 
276 	switch (event) {
277 	case SND_SOC_DAPM_PRE_PMU:
278 		cs530x->adc_pairs_count++;
279 		break;
280 	case SND_SOC_DAPM_POST_PMU:
281 		regmap_clear_bits(regmap, CS530X_IN_VOL_CTRL1_0 +
282 				  (w->shift * 2), CS530X_INOUT_MUTE);
283 		regmap_clear_bits(regmap, CS530X_IN_VOL_CTRL1_0 +
284 				  ((w->shift + 1) * 2), CS530X_INOUT_MUTE);
285 
286 		cs530x->adc_pairs_count--;
287 		if (!cs530x->adc_pairs_count) {
288 			usleep_range(1000, 1100);
289 			return regmap_write(regmap, CS530X_IN_VOL_CTRL5,
290 					    CS530X_INOUT_VU);
291 		}
292 		break;
293 	case SND_SOC_DAPM_PRE_PMD:
294 		regmap_set_bits(regmap, CS530X_IN_VOL_CTRL1_0 +
295 				(w->shift * 2), CS530X_INOUT_MUTE);
296 		regmap_set_bits(regmap, CS530X_IN_VOL_CTRL1_0 +
297 				((w->shift + 1) * 2), CS530X_INOUT_MUTE);
298 		return regmap_write(regmap, CS530X_IN_VOL_CTRL5,
299 				    CS530X_INOUT_VU);
300 	default:
301 		return -EINVAL;
302 	}
303 
304 	return 0;
305 }
306 
307 static SOC_ENUM_SINGLE_DECL(cs530x_ramp_out_inc_enum, CS530X_OUT_RAMP_SUM,
308 			    CS530X_RAMP_RATE_INC_SHIFT,
309 			    cs530x_vol_ramp_text);
310 
311 static SOC_ENUM_SINGLE_DECL(cs530x_ramp_out_dec_enum, CS530X_OUT_RAMP_SUM,
312 			    CS530X_RAMP_RATE_DEC_SHIFT,
313 			    cs530x_vol_ramp_text);
314 
315 static const struct snd_kcontrol_new cs530x_out_1_to_2_controls[] = {
316 SOC_SINGLE_EXT_TLV("OUT1 Volume", CS530X_OUT_VOL_CTRL1_0, 0, 255, 1,
317 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
318 SOC_SINGLE_EXT_TLV("OUT2 Volume", CS530X_OUT_VOL_CTRL1_1, 0, 255, 1,
319 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
320 
321 SOC_ENUM("OUT DEC Filter Select", cs530x_out_filter_enum),
322 SOC_ENUM("Output Ramp Up", cs530x_ramp_out_inc_enum),
323 SOC_ENUM("Output Ramp Down", cs530x_ramp_out_dec_enum),
324 
325 SOC_SINGLE("DAC1 Invert Switch", CS530X_OUT_INV, CS530X_INOUT1_INV_SHIFT, 1, 0),
326 SOC_SINGLE("DAC2 Invert Switch", CS530X_OUT_INV, CS530X_INOUT2_INV_SHIFT, 1, 0),
327 };
328 
329 static const struct snd_kcontrol_new cs530x_out_3_to_4_controls[] = {
330 SOC_SINGLE_EXT_TLV("OUT3 Volume", CS530X_OUT_VOL_CTRL2_0, 0, 255, 1,
331 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
332 SOC_SINGLE_EXT_TLV("OUT4 Volume", CS530X_OUT_VOL_CTRL2_1, 0, 255, 1,
333 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
334 
335 SOC_SINGLE("DAC3 Invert Switch", CS530X_OUT_INV, CS530X_INOUT3_INV_SHIFT, 1, 0),
336 SOC_SINGLE("DAC4 Invert Switch", CS530X_OUT_INV, CS530X_INOUT4_INV_SHIFT, 1, 0),
337 };
338 
339 static const struct snd_kcontrol_new cs530x_out_5_to_8_controls[] = {
340 SOC_SINGLE_EXT_TLV("OUT5 Volume", CS530X_OUT_VOL_CTRL3_0, 0, 255, 1,
341 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
342 SOC_SINGLE_EXT_TLV("OUT6 Volume", CS530X_OUT_VOL_CTRL3_1, 0, 255, 1,
343 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
344 SOC_SINGLE_EXT_TLV("OUT7 Volume", CS530X_OUT_VOL_CTRL4_0, 0, 255, 1,
345 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
346 SOC_SINGLE_EXT_TLV("OUT8 Volume", CS530X_OUT_VOL_CTRL4_1, 0, 255, 1,
347 		    snd_soc_get_volsw, cs530x_put_volsw_vu, in_vol_tlv),
348 
349 SOC_SINGLE("DAC5 Invert Switch", CS530X_OUT_INV, CS530X_INOUT5_INV_SHIFT, 1, 0),
350 SOC_SINGLE("DAC6 Invert Switch", CS530X_OUT_INV, CS530X_INOUT6_INV_SHIFT, 1, 0),
351 SOC_SINGLE("DAC7 Invert Switch", CS530X_OUT_INV, CS530X_INOUT7_INV_SHIFT, 1, 0),
352 SOC_SINGLE("DAC8 Invert Switch", CS530X_OUT_INV, CS530X_INOUT8_INV_SHIFT, 1, 0),
353 };
354 
cs530x_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)355 static int cs530x_dac_event(struct snd_soc_dapm_widget *w,
356 			    struct snd_kcontrol *kcontrol, int event)
357 {
358 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
359 	struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
360 	struct regmap *regmap = cs530x->regmap;
361 
362 	switch (event) {
363 	case SND_SOC_DAPM_PRE_PMU:
364 		cs530x->dac_pairs_count++;
365 		break;
366 	case SND_SOC_DAPM_POST_PMU:
367 		regmap_clear_bits(regmap, CS530X_OUT_VOL_CTRL1_0 +
368 				 (w->shift * 2), CS530X_INOUT_MUTE);
369 		regmap_clear_bits(regmap, CS530X_OUT_VOL_CTRL1_0 +
370 				 ((w->shift + 1) * 2), CS530X_INOUT_MUTE);
371 
372 		cs530x->dac_pairs_count--;
373 		if (!cs530x->dac_pairs_count) {
374 			usleep_range(1000, 1100);
375 			return regmap_write(regmap, CS530X_OUT_VOL_CTRL5,
376 					    CS530X_INOUT_VU);
377 		}
378 		break;
379 	case SND_SOC_DAPM_PRE_PMD:
380 		regmap_set_bits(regmap, CS530X_OUT_VOL_CTRL1_0 +
381 			       (w->shift * 2), CS530X_INOUT_MUTE);
382 		regmap_set_bits(regmap, CS530X_OUT_VOL_CTRL1_0 +
383 			       ((w->shift + 1) * 2), CS530X_INOUT_MUTE);
384 		return regmap_write(regmap, CS530X_OUT_VOL_CTRL5,
385 				    CS530X_INOUT_VU);
386 	default:
387 		return -EINVAL;
388 	}
389 
390 	return 0;
391 }
392 
393 static const struct snd_kcontrol_new adc12_ctrl =
394 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
395 static const struct snd_kcontrol_new adc34_ctrl =
396 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
397 static const struct snd_kcontrol_new adc56_ctrl =
398 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
399 static const struct snd_kcontrol_new adc78_ctrl =
400 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
401 static const struct snd_kcontrol_new dac12_ctrl =
402 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
403 static const struct snd_kcontrol_new dac34_ctrl =
404 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
405 static const struct snd_kcontrol_new dac56_ctrl =
406 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
407 static const struct snd_kcontrol_new dac78_ctrl =
408 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
409 static const struct snd_kcontrol_new in_hpf_ctrl =
410 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
411 static const struct snd_kcontrol_new out_hpf_ctrl =
412 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
413 
414 /* General DAPM widgets for all devices */
415 static const struct snd_soc_dapm_widget cs530x_gen_dapm_widgets[] = {
416 SND_SOC_DAPM_SUPPLY("Global Enable", CS530X_CHIP_ENABLE, 0, 0, NULL, 0),
417 };
418 
419 /* ADC's Channels 1 and 2 plus generic ADC DAPM events */
420 static const struct snd_soc_dapm_widget cs530x_adc_ch12_dapm_widgets[] = {
421 SND_SOC_DAPM_INPUT("IN1"),
422 SND_SOC_DAPM_INPUT("IN2"),
423 SND_SOC_DAPM_ADC_E("ADC1", NULL, CS530X_IN_ENABLES, 0, 0,
424 		   cs530x_adc_event,
425 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
426 		   SND_SOC_DAPM_PRE_PMU),
427 SND_SOC_DAPM_ADC("ADC2", NULL, CS530X_IN_ENABLES, 1, 0),
428 SND_SOC_DAPM_SWITCH("ADC12 Enable", SND_SOC_NOPM, 0, 0, &adc12_ctrl),
429 SND_SOC_DAPM_SWITCH("IN HPF", CS530X_IN_FILTER, CS530X_INOUT_HPF_EN_SHIFT,
430 		    0, &in_hpf_ctrl),
431 };
432 
433 /* ADC's Channels 3 and 4 */
434 static const struct snd_soc_dapm_widget cs530x_adc_ch34_dapm_widgets[] = {
435 SND_SOC_DAPM_INPUT("IN3"),
436 SND_SOC_DAPM_INPUT("IN4"),
437 SND_SOC_DAPM_ADC_E("ADC3", NULL, CS530X_IN_ENABLES, 2, 0,
438 		   cs530x_adc_event,
439 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
440 		   SND_SOC_DAPM_PRE_PMU),
441 SND_SOC_DAPM_ADC("ADC4", NULL, CS530X_IN_ENABLES, 3, 0),
442 SND_SOC_DAPM_SWITCH("ADC34 Enable", SND_SOC_NOPM, 0, 0, &adc34_ctrl),
443 };
444 
445 /* ADC's Channels 5 to 8 */
446 static const struct snd_soc_dapm_widget cs530x_adc_ch58_dapm_widgets[] = {
447 SND_SOC_DAPM_INPUT("IN5"),
448 SND_SOC_DAPM_INPUT("IN6"),
449 SND_SOC_DAPM_INPUT("IN7"),
450 SND_SOC_DAPM_INPUT("IN8"),
451 SND_SOC_DAPM_ADC_E("ADC5", NULL, CS530X_IN_ENABLES, 4, 0,
452 		   cs530x_adc_event,
453 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
454 		   SND_SOC_DAPM_PRE_PMU),
455 SND_SOC_DAPM_ADC("ADC6", NULL, CS530X_IN_ENABLES, 5, 0),
456 SND_SOC_DAPM_SWITCH("ADC56 Enable", SND_SOC_NOPM, 0, 0, &adc56_ctrl),
457 SND_SOC_DAPM_ADC_E("ADC7", NULL, CS530X_IN_ENABLES, 6, 0,
458 		   cs530x_adc_event,
459 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
460 		   SND_SOC_DAPM_PRE_PMU),
461 SND_SOC_DAPM_ADC("ADC8", NULL, CS530X_IN_ENABLES, 7, 0),
462 SND_SOC_DAPM_SWITCH("ADC78 Enable", SND_SOC_NOPM, 0, 0, &adc78_ctrl),
463 };
464 
465 static const struct snd_soc_dapm_route adc_ch1_2_routes[] = {
466 	{ "ADC1", NULL, "Global Enable" },
467 	{ "ADC2", NULL, "Global Enable" },
468 
469 	{ "ADC12 Enable", "Switch", "IN1" },
470 	{ "ADC12 Enable", "Switch", "IN2" },
471 	{ "ADC1", NULL, "ADC12 Enable" },
472 	{ "ADC2", NULL, "ADC12 Enable" },
473 	{ "IN HPF", "Switch", "ADC1" },
474 	{ "IN HPF", "Switch", "ADC2" },
475 
476 	{ "AIF Capture", NULL, "IN HPF" },
477 	{ "AIF Capture", NULL, "ADC1" },
478 	{ "AIF Capture", NULL, "ADC2" },
479 };
480 
481 static const struct snd_soc_dapm_route adc_ch3_4_routes[] = {
482 	{ "ADC3", NULL, "Global Enable" },
483 	{ "ADC4", NULL, "Global Enable" },
484 
485 	{ "ADC34 Enable", "Switch", "IN3" },
486 	{ "ADC34 Enable", "Switch", "IN4" },
487 	{ "ADC3", NULL, "ADC34 Enable" },
488 	{ "ADC4", NULL, "ADC34 Enable" },
489 	{ "IN HPF", "Switch", "ADC3" },
490 	{ "IN HPF", "Switch", "ADC4" },
491 
492 	{ "AIF Capture", NULL, "ADC3" },
493 	{ "AIF Capture", NULL, "ADC4" },
494 };
495 
496 static const struct snd_soc_dapm_route adc_ch5_8_routes[] = {
497 	{ "ADC5", NULL, "Global Enable" },
498 	{ "ADC6", NULL, "Global Enable" },
499 	{ "ADC7", NULL, "Global Enable" },
500 	{ "ADC8", NULL, "Global Enable" },
501 
502 	{ "ADC56 Enable", "Switch", "IN5" },
503 	{ "ADC56 Enable", "Switch", "IN6" },
504 	{ "ADC5", NULL, "ADC56 Enable" },
505 	{ "ADC6", NULL, "ADC56 Enable" },
506 	{ "IN HPF", "Switch", "ADC5" },
507 	{ "IN HPF", "Switch", "ADC6" },
508 
509 	{ "AIF Capture", NULL, "ADC5" },
510 	{ "AIF Capture", NULL, "ADC6" },
511 
512 	{ "ADC78 Enable", "Switch", "IN7" },
513 	{ "ADC78 Enable", "Switch", "IN8" },
514 	{ "ADC7", NULL, "ADC78 Enable" },
515 	{ "ADC8", NULL, "ADC78 Enable" },
516 	{ "IN HPF", "Switch", "ADC7" },
517 	{ "IN HPF", "Switch", "ADC8" },
518 
519 	{ "AIF Capture", NULL, "ADC7" },
520 	{ "AIF Capture", NULL, "ADC8" },
521 };
522 
cs530x_add_12_adc_widgets(struct snd_soc_component * component)523 static void cs530x_add_12_adc_widgets(struct snd_soc_component *component)
524 {
525 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
526 
527 	snd_soc_add_component_controls(component,
528 				       cs530x_in_1_to_2_controls,
529 				       ARRAY_SIZE(cs530x_in_1_to_2_controls));
530 
531 	snd_soc_dapm_new_controls(dapm, cs530x_adc_ch12_dapm_widgets,
532 				  ARRAY_SIZE(cs530x_adc_ch12_dapm_widgets));
533 
534 	snd_soc_dapm_add_routes(dapm, adc_ch1_2_routes,
535 				ARRAY_SIZE(adc_ch1_2_routes));
536 }
537 
cs530x_add_34_adc_widgets(struct snd_soc_component * component)538 static void cs530x_add_34_adc_widgets(struct snd_soc_component *component)
539 {
540 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
541 
542 	snd_soc_add_component_controls(component,
543 				       cs530x_in_3_to_4_controls,
544 				       ARRAY_SIZE(cs530x_in_3_to_4_controls));
545 
546 	snd_soc_dapm_new_controls(dapm, cs530x_adc_ch34_dapm_widgets,
547 				  ARRAY_SIZE(cs530x_adc_ch34_dapm_widgets));
548 
549 	snd_soc_dapm_add_routes(dapm, adc_ch3_4_routes,
550 				ARRAY_SIZE(adc_ch3_4_routes));
551 }
552 
553 /* DAC's Channels 1 and 2 plus generic DAC DAPM events */
554 static const struct snd_soc_dapm_widget cs530x_dac_ch12_dapm_widgets[] = {
555 SND_SOC_DAPM_OUTPUT("OUT1"),
556 SND_SOC_DAPM_OUTPUT("OUT2"),
557 SND_SOC_DAPM_DAC_E("DAC1", NULL, CS530X_OUT_ENABLES, 0, 0,
558 		   cs530x_dac_event,
559 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
560 		   SND_SOC_DAPM_PRE_PMU),
561 SND_SOC_DAPM_DAC("DAC2", NULL, CS530X_OUT_ENABLES, 1, 0),
562 SND_SOC_DAPM_SWITCH("DAC12 Enable", SND_SOC_NOPM, 0, 0, &dac12_ctrl),
563 SND_SOC_DAPM_SWITCH("OUT HPF", CS530X_OUT_FILTER, CS530X_INOUT_HPF_EN_SHIFT,
564 		    0, &out_hpf_ctrl),
565 };
566 
567 /* DAC's Channels 3 and 4 */
568 static const struct snd_soc_dapm_widget cs530x_dac_ch34_dapm_widgets[] = {
569 SND_SOC_DAPM_OUTPUT("OUT3"),
570 SND_SOC_DAPM_OUTPUT("OUT4"),
571 SND_SOC_DAPM_DAC_E("DAC3", NULL, CS530X_OUT_ENABLES, 2, 0,
572 		   cs530x_dac_event,
573 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
574 		   SND_SOC_DAPM_PRE_PMU),
575 SND_SOC_DAPM_DAC("DAC4", NULL, CS530X_OUT_ENABLES, 3, 0),
576 SND_SOC_DAPM_SWITCH("DAC34 Enable", SND_SOC_NOPM, 0, 0, &dac34_ctrl),
577 };
578 
579 /* DAC's Channels 5 to 8 */
580 static const struct snd_soc_dapm_widget cs530x_dac_ch58_dapm_widgets[] = {
581 SND_SOC_DAPM_OUTPUT("OUT5"),
582 SND_SOC_DAPM_OUTPUT("OUT6"),
583 SND_SOC_DAPM_OUTPUT("OUT7"),
584 SND_SOC_DAPM_OUTPUT("OUT8"),
585 SND_SOC_DAPM_DAC_E("DAC5", NULL, CS530X_OUT_ENABLES, 4, 0,
586 		   cs530x_dac_event,
587 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
588 		   SND_SOC_DAPM_PRE_PMU),
589 SND_SOC_DAPM_DAC("DAC6", NULL, CS530X_OUT_ENABLES, 5, 0),
590 SND_SOC_DAPM_SWITCH("DAC56 Enable", SND_SOC_NOPM, 0, 0, &dac56_ctrl),
591 SND_SOC_DAPM_DAC_E("DAC7", NULL, CS530X_OUT_ENABLES, 6, 0,
592 		   cs530x_dac_event,
593 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU |
594 		   SND_SOC_DAPM_PRE_PMU),
595 SND_SOC_DAPM_DAC("DAC8", NULL, CS530X_OUT_ENABLES, 7, 0),
596 SND_SOC_DAPM_SWITCH("DAC78 Enable", SND_SOC_NOPM, 0, 0, &dac78_ctrl),
597 };
598 
599 static const struct snd_soc_dapm_route dac_ch1_2_routes[] = {
600 	{ "DAC1", NULL, "Global Enable" },
601 	{ "DAC2", NULL, "Global Enable" },
602 
603 	{ "DAC12 Enable", "Switch", "OUT1" },
604 	{ "DAC12 Enable", "Switch", "OUT2" },
605 	{ "DAC1", NULL, "DAC12 Enable" },
606 	{ "DAC2", NULL, "DAC12 Enable" },
607 	{ "OUT HPF", "Switch", "DAC1" },
608 	{ "OUT HPF", "Switch", "DAC2" },
609 
610 	{ "OUT HPF", NULL, "AIF Playback" },
611 	{ "DAC1", NULL, "AIF Playback" },
612 	{ "DAC2", NULL, "AIF Playback" },
613 
614 	{ "OUT1", NULL, "DAC1" },
615 	{ "OUT2", NULL, "DAC2" },
616 };
617 
618 static const struct snd_soc_dapm_route dac_ch3_4_routes[] = {
619 	{ "DAC3", NULL, "Global Enable" },
620 	{ "DAC4", NULL, "Global Enable" },
621 
622 	{ "DAC34 Enable", "Switch", "OUT3" },
623 	{ "DAC34 Enable", "Switch", "OUT4" },
624 	{ "DAC3", NULL, "DAC34 Enable" },
625 	{ "DAC4", NULL, "DAC34 Enable" },
626 	{ "OUT HPF", "Switch", "DAC3" },
627 	{ "OUT HPF", "Switch", "DAC4" },
628 
629 	{ "DAC3", NULL, "AIF Playback" },
630 	{ "DAC4", NULL, "AIF Playback" },
631 
632 	{ "OUT3", NULL, "DAC3" },
633 	{ "OUT4", NULL, "DAC4" },
634 };
635 
636 static const struct snd_soc_dapm_route dac_ch5_8_routes[] = {
637 	{ "DAC5", NULL, "Global Enable" },
638 	{ "DAC6", NULL, "Global Enable" },
639 
640 	{ "DAC56 Enable", "Switch", "OUT5" },
641 	{ "DAC56 Enable", "Switch", "OUT6" },
642 	{ "DAC5", NULL, "DAC56 Enable" },
643 	{ "DAC6", NULL, "DAC56 Enable" },
644 	{ "OUT HPF", "Switch", "DAC5" },
645 	{ "OUT HPF", "Switch", "DAC6" },
646 
647 	{ "DAC5", NULL, "AIF Playback" },
648 	{ "DAC6", NULL, "AIF Playback" },
649 
650 	{ "OUT5", NULL, "DAC5" },
651 	{ "OUT6", NULL, "DAC6" },
652 
653 	{ "DAC7", NULL, "Global Enable" },
654 	{ "DAC8", NULL, "Global Enable" },
655 
656 	{ "DAC78 Enable", "Switch", "OUT7" },
657 	{ "DAC78 Enable", "Switch", "OUT8" },
658 	{ "DAC7", NULL, "DAC78 Enable" },
659 	{ "DAC8", NULL, "DAC78 Enable" },
660 	{ "OUT HPF", "Switch", "DAC7" },
661 	{ "OUT HPF", "Switch", "DAC8" },
662 
663 	{ "DAC7", NULL, "AIF Playback" },
664 	{ "DAC8", NULL, "AIF Playback" },
665 
666 	{ "OUT7", NULL, "DAC7" },
667 	{ "OUT8", NULL, "DAC8" },
668 };
669 
cs530x_add_12_dac_widgets(struct snd_soc_component * component)670 static void cs530x_add_12_dac_widgets(struct snd_soc_component *component)
671 {
672 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
673 
674 	snd_soc_add_component_controls(component,
675 				       cs530x_out_1_to_2_controls,
676 				       ARRAY_SIZE(cs530x_out_1_to_2_controls));
677 
678 	snd_soc_dapm_new_controls(dapm, cs530x_dac_ch12_dapm_widgets,
679 				  ARRAY_SIZE(cs530x_dac_ch12_dapm_widgets));
680 
681 	snd_soc_dapm_add_routes(dapm, dac_ch1_2_routes,
682 				ARRAY_SIZE(dac_ch1_2_routes));
683 }
684 
cs530x_add_34_dac_widgets(struct snd_soc_component * component)685 static void cs530x_add_34_dac_widgets(struct snd_soc_component *component)
686 {
687 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
688 
689 	snd_soc_add_component_controls(component,
690 				       cs530x_out_3_to_4_controls,
691 				       ARRAY_SIZE(cs530x_out_3_to_4_controls));
692 
693 	snd_soc_dapm_new_controls(dapm, cs530x_dac_ch34_dapm_widgets,
694 				  ARRAY_SIZE(cs530x_dac_ch34_dapm_widgets));
695 
696 	snd_soc_dapm_add_routes(dapm, dac_ch3_4_routes,
697 				ARRAY_SIZE(dac_ch3_4_routes));
698 }
699 
cs530x_set_bclk(struct snd_soc_component * component,const int freq)700 static int cs530x_set_bclk(struct snd_soc_component *component, const int freq)
701 {
702 	struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
703 	struct regmap *regmap = cs530x->regmap;
704 	unsigned int bclk_val;
705 
706 	switch (freq) {
707 	case 2822400:
708 	case 3072000:
709 		bclk_val = CS530X_BCLK_2P822_3P072;
710 		break;
711 	case 5644800:
712 	case 6144000:
713 		bclk_val = CS530X_BCLK_5P6448_6P144;
714 		break;
715 	case 11289600:
716 	case 12288000:
717 		bclk_val = CS530X_BCLK_11P2896_12P288;
718 		break;
719 	case 22579200:
720 	case 24576000:
721 		bclk_val = CS530X_BCLK_24P5792_24P576;
722 		break;
723 	default:
724 		dev_err(component->dev, "Invalid BCLK frequency %d\n", freq);
725 		return -EINVAL;
726 	}
727 
728 	dev_dbg(component->dev, "BCLK frequency is %d\n", freq);
729 
730 	return regmap_update_bits(regmap, CS530X_ASP_CFG,
731 				  CS530X_ASP_BCLK_FREQ_MASK, bclk_val);
732 }
733 
cs530x_set_pll_refclk(struct snd_soc_component * component,const unsigned int freq)734 static int cs530x_set_pll_refclk(struct snd_soc_component *component,
735 				 const unsigned int freq)
736 {
737 	struct cs530x_priv *priv = snd_soc_component_get_drvdata(component);
738 	struct regmap *regmap = priv->regmap;
739 	unsigned int refclk;
740 
741 	switch (freq) {
742 	case 2822400:
743 	case 3072000:
744 		refclk = CS530X_REFCLK_2P822_3P072;
745 		break;
746 	case 5644800:
747 	case 6144000:
748 		refclk = CS530X_REFCLK_5P6448_6P144;
749 		break;
750 	case 11289600:
751 	case 12288000:
752 		refclk = CS530X_REFCLK_11P2896_12P288;
753 		break;
754 	case 22579200:
755 	case 24576000:
756 		refclk = CS530X_REFCLK_24P5792_24P576;
757 		break;
758 	default:
759 		dev_err(component->dev, "Invalid PLL refclk %d\n", freq);
760 		return -EINVAL;
761 	}
762 
763 	return regmap_update_bits(regmap, CS530X_CLK_CFG_0,
764 				  CS530X_PLL_REFCLK_FREQ_MASK, refclk);
765 }
766 
cs530x_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)767 static int cs530x_hw_params(struct snd_pcm_substream *substream,
768 			    struct snd_pcm_hw_params *params,
769 			    struct snd_soc_dai *dai)
770 {
771 	struct snd_soc_component *component = dai->component;
772 	struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
773 	struct regmap *regmap = cs530x->regmap;
774 	int ret = 0, fs = params_rate(params), bclk;
775 	unsigned int fs_val;
776 
777 	switch (fs) {
778 	case 32000:
779 		fs_val = CS530X_FS_32K;
780 		break;
781 	case 44100:
782 	case 48000:
783 		fs_val = CS530X_FS_44P1K_48K;
784 		break;
785 	case 88200:
786 	case 96000:
787 		fs_val = CS530X_FS_88P2K_96K;
788 		break;
789 	case 176400:
790 	case 192000:
791 		fs_val = CS530X_FS_176P4K_192K;
792 		break;
793 	case 356800:
794 	case 384000:
795 		fs_val = CS530X_FS_356P8K_384K;
796 		break;
797 	case 705600:
798 	case 768000:
799 		fs_val = CS530X_FS_705P6K_768K;
800 		break;
801 	default:
802 		dev_err(component->dev, "Invalid sample rate %d\n", fs);
803 		return -EINVAL;
804 	}
805 
806 	regmap_update_bits(regmap, CS530X_CLK_CFG_1,
807 			   CS530X_SAMPLE_RATE_MASK, fs_val);
808 
809 
810 	if (regmap_test_bits(regmap, CS530X_SIGNAL_PATH_CFG,
811 			     CS530X_TDM_EN_MASK)) {
812 		dev_dbg(component->dev, "Configuring for %d %d bit TDM slots\n",
813 			cs530x->tdm_slots, cs530x->tdm_width);
814 		bclk = snd_soc_tdm_params_to_bclk(params,
815 						  cs530x->tdm_width,
816 						  cs530x->tdm_slots,
817 						  1);
818 	} else {
819 		bclk = snd_soc_params_to_bclk(params);
820 	}
821 
822 	if (!regmap_test_bits(regmap, CS530X_CLK_CFG_0,
823 			      CS530X_PLL_REFCLK_SRC_MASK)) {
824 		ret = cs530x_set_pll_refclk(component, bclk);
825 		if (ret)
826 			return ret;
827 	}
828 
829 	return cs530x_set_bclk(component, bclk);
830 }
831 
cs530x_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)832 static int cs530x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
833 {
834 	struct snd_soc_component *component = dai->component;
835 	struct cs530x_priv *priv = snd_soc_component_get_drvdata(component);
836 	struct regmap *regmap = priv->regmap;
837 	unsigned int asp_fmt, asp_cfg = 0;
838 
839 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
840 	case SND_SOC_DAIFMT_CBC_CFC:
841 		break;
842 	case SND_SOC_DAIFMT_CBP_CFP:
843 		asp_cfg = CS530X_ASP_PRIMARY;
844 		break;
845 	default:
846 		return -EINVAL;
847 	}
848 
849 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
850 	case SND_SOC_DAIFMT_DSP_A:
851 		asp_fmt = CS530X_ASP_FMT_DSP_A;
852 		break;
853 	case SND_SOC_DAIFMT_I2S:
854 		asp_fmt = CS530X_ASP_FMT_I2S;
855 		break;
856 	case SND_SOC_DAIFMT_LEFT_J:
857 		asp_fmt = CS530X_ASP_FMT_LJ;
858 		break;
859 	default:
860 		return -EINVAL;
861 	}
862 
863 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
864 	case SND_SOC_DAIFMT_NB_NF:
865 		break;
866 	case SND_SOC_DAIFMT_IB_IF:
867 		asp_cfg |= CS530X_ASP_BCLK_INV;
868 		break;
869 	default:
870 		return -EINVAL;
871 	}
872 
873 	regmap_update_bits(regmap, CS530X_ASP_CFG,
874 			   CS530X_ASP_PRIMARY | CS530X_ASP_BCLK_INV,
875 			   asp_cfg);
876 
877 	return regmap_update_bits(regmap, CS530X_SIGNAL_PATH_CFG,
878 				  CS530X_ASP_FMT_MASK, asp_fmt);
879 }
880 
cs530x_check_mclk_freq(struct snd_soc_component * component,const unsigned int freq)881 static bool cs530x_check_mclk_freq(struct snd_soc_component *component,
882 				   const unsigned int freq)
883 {
884 	switch (freq) {
885 	case 24576000:
886 	case 22579200:
887 	case 12288000:
888 	case 11289600:
889 		return true;
890 	default:
891 		dev_err(component->dev, "Invalid MCLK %d\n", freq);
892 		return false;
893 	}
894 }
895 
cs530x_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)896 static int cs530x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
897 			       unsigned int rx_mask, int slots, int slot_width)
898 {
899 	struct snd_soc_component *component = dai->component;
900 	struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
901 	struct regmap *regmap = cs530x->regmap;
902 	unsigned int val;
903 
904 	switch (tx_mask) {
905 	case CS530X_0_1_TDM_SLOT_MASK:
906 	case CS530X_0_3_TDM_SLOT_MASK:
907 	case CS530X_0_7_TDM_SLOT_MASK:
908 		val = CS530X_0_7_TDM_SLOT_VAL;
909 		break;
910 	case CS530X_2_3_TDM_SLOT_MASK:
911 		val = CS530X_2_3_TDM_SLOT_VAL;
912 		break;
913 	case CS530X_4_5_TDM_SLOT_MASK:
914 	case CS530X_4_7_TDM_SLOT_MASK:
915 		val = CS530X_4_7_TDM_SLOT_VAL;
916 		break;
917 	case CS530X_6_7_TDM_SLOT_MASK:
918 		val = CS530X_6_7_TDM_SLOT_VAL;
919 		break;
920 	case CS530X_8_9_TDM_SLOT_MASK:
921 	case CS530X_8_11_TDM_SLOT_MASK:
922 	case CS530X_8_15_TDM_SLOT_MASK:
923 		val = CS530X_8_15_TDM_SLOT_VAL;
924 		break;
925 	case CS530X_10_11_TDM_SLOT_MASK:
926 		val = CS530X_10_11_TDM_SLOT_VAL;
927 		break;
928 	case CS530X_12_13_TDM_SLOT_MASK:
929 	case CS530X_12_15_TDM_SLOT_MASK:
930 		val = CS530X_12_15_TDM_SLOT_VAL;
931 		break;
932 	case CS530X_14_15_TDM_SLOT_MASK:
933 		val = CS530X_14_15_TDM_SLOT_VAL;
934 		break;
935 	default:
936 		dev_err(component->dev, "Invalid TX slot(s) 0x%x\n", tx_mask);
937 		return -EINVAL;
938 	}
939 
940 	cs530x->tdm_width = slot_width;
941 	cs530x->tdm_slots = slots;
942 
943 	return regmap_update_bits(regmap, CS530X_SIGNAL_PATH_CFG,
944 				  CS530X_ASP_TDM_SLOT_MASK,
945 				  val << CS530X_ASP_TDM_SLOT_SHIFT);
946 }
947 
948 static const struct snd_soc_dai_ops cs530x_dai_ops = {
949 	.set_fmt = cs530x_set_fmt,
950 	.hw_params = cs530x_hw_params,
951 	.set_tdm_slot = cs530x_set_tdm_slot,
952 };
953 
954 static const struct snd_soc_dai_driver cs530x_dai = {
955 	.name = "cs530x-dai",
956 	.capture = {
957 		.stream_name = "AIF Capture",
958 		.rates = SNDRV_PCM_RATE_KNOT,
959 		.formats = SNDRV_PCM_FMTBIT_S32_LE,
960 	},
961 	.playback = {
962 		.stream_name = "AIF Playback",
963 		.rates = SNDRV_PCM_RATE_KNOT,
964 		.formats = SNDRV_PCM_FMTBIT_S32_LE,
965 	},
966 	.ops = &cs530x_dai_ops,
967 	.symmetric_rate = 1,
968 	.symmetric_sample_bits = 1,
969 };
970 
cs530x_set_pll(struct snd_soc_component * component,int pll_id,int source,unsigned int freq_in,unsigned int freq_out)971 static int cs530x_set_pll(struct snd_soc_component *component, int pll_id,
972 			  int source, unsigned int freq_in,
973 			  unsigned int freq_out)
974 {
975 	struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
976 	struct regmap *regmap = cs530x->regmap;
977 	unsigned int sysclk_src;
978 	int ret;
979 
980 	regmap_read(regmap, CS530X_CLK_CFG_0, &sysclk_src);
981 
982 	/* Check if the source is the PLL  */
983 	if ((sysclk_src & CS530X_SYSCLK_SRC_MASK) == 0)
984 		return 0;
985 
986 	switch (source) {
987 	case CS530X_PLL_SRC_MCLK:
988 		if (!cs530x_check_mclk_freq(component, freq_in))
989 			return -EINVAL;
990 
991 		ret = cs530x_set_pll_refclk(component, freq_in);
992 		if (ret)
993 			return ret;
994 
995 		break;
996 	case CS530X_PLL_SRC_BCLK:
997 		break;
998 	default:
999 		dev_err(component->dev, "Invalid PLL source %d\n", source);
1000 		return -EINVAL;
1001 	}
1002 
1003 	return regmap_update_bits(regmap, CS530X_CLK_CFG_0,
1004 				  CS530X_PLL_REFCLK_SRC_MASK, source);
1005 }
1006 
cs530x_component_probe(struct snd_soc_component * component)1007 static int cs530x_component_probe(struct snd_soc_component *component)
1008 {
1009 	struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
1010 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
1011 	int num_widgets;
1012 
1013 	snd_soc_dapm_new_controls(dapm, cs530x_gen_dapm_widgets,
1014 				  ARRAY_SIZE(cs530x_gen_dapm_widgets));
1015 
1016 	switch (cs530x->devtype) {
1017 	case CS4282:
1018 		cs530x_add_12_adc_widgets(component);
1019 		cs530x_add_12_dac_widgets(component);
1020 		break;
1021 	case CS4302:
1022 		cs530x_add_12_dac_widgets(component);
1023 		break;
1024 	case CS4304:
1025 		cs530x_add_12_dac_widgets(component);
1026 		cs530x_add_34_dac_widgets(component);
1027 
1028 		num_widgets = ARRAY_SIZE(cs530x_out_sum_4ch_controls);
1029 		snd_soc_add_component_controls(component,
1030 					       cs530x_out_sum_4ch_controls,
1031 					       num_widgets);
1032 		break;
1033 	case CS4308:
1034 		cs530x_add_12_dac_widgets(component);
1035 		cs530x_add_34_dac_widgets(component);
1036 
1037 		num_widgets = ARRAY_SIZE(cs530x_out_5_to_8_controls);
1038 		snd_soc_add_component_controls(component,
1039 					       cs530x_out_5_to_8_controls,
1040 					       num_widgets);
1041 
1042 		num_widgets = ARRAY_SIZE(cs530x_out_sum_8ch_controls);
1043 		snd_soc_add_component_controls(component,
1044 					       cs530x_out_sum_8ch_controls,
1045 					       num_widgets);
1046 
1047 		num_widgets = ARRAY_SIZE(cs530x_dac_ch58_dapm_widgets);
1048 		snd_soc_dapm_new_controls(dapm, cs530x_dac_ch58_dapm_widgets,
1049 					  num_widgets);
1050 
1051 		snd_soc_dapm_add_routes(dapm, dac_ch5_8_routes,
1052 					ARRAY_SIZE(dac_ch5_8_routes));
1053 		break;
1054 	case CS5302:
1055 		cs530x_add_12_adc_widgets(component);
1056 		break;
1057 	case CS5304:
1058 		cs530x_add_12_adc_widgets(component);
1059 		cs530x_add_34_adc_widgets(component);
1060 
1061 		num_widgets = ARRAY_SIZE(cs530x_in_sum_4ch_controls);
1062 		snd_soc_add_component_controls(component,
1063 					       cs530x_in_sum_4ch_controls,
1064 					       num_widgets);
1065 		break;
1066 	case CS5308:
1067 		cs530x_add_12_adc_widgets(component);
1068 		cs530x_add_34_adc_widgets(component);
1069 
1070 		num_widgets = ARRAY_SIZE(cs530x_in_5_to_8_controls);
1071 		snd_soc_add_component_controls(component,
1072 					       cs530x_in_5_to_8_controls,
1073 					       num_widgets);
1074 
1075 		num_widgets = ARRAY_SIZE(cs530x_in_sum_8ch_controls);
1076 		snd_soc_add_component_controls(component,
1077 					       cs530x_in_sum_8ch_controls,
1078 					       num_widgets);
1079 
1080 		num_widgets = ARRAY_SIZE(cs530x_adc_ch58_dapm_widgets);
1081 		snd_soc_dapm_new_controls(dapm, cs530x_adc_ch58_dapm_widgets,
1082 					  num_widgets);
1083 
1084 		snd_soc_dapm_add_routes(dapm, adc_ch5_8_routes,
1085 					ARRAY_SIZE(adc_ch5_8_routes));
1086 		break;
1087 	default:
1088 		dev_err(component->dev, "Invalid device type %d\n",
1089 			cs530x->devtype);
1090 		return -EINVAL;
1091 	}
1092 
1093 	return 0;
1094 }
1095 
cs530x_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)1096 static int cs530x_set_sysclk(struct snd_soc_component *component, int clk_id,
1097 			     int source, unsigned int freq, int dir)
1098 {
1099 	struct cs530x_priv *cs530x = snd_soc_component_get_drvdata(component);
1100 	struct regmap *regmap = cs530x->regmap;
1101 
1102 	switch (source) {
1103 	case CS530X_SYSCLK_SRC_MCLK:
1104 		switch (freq) {
1105 		case CS530X_SYSCLK_REF_45_1MHZ:
1106 		case CS530X_SYSCLK_REF_49_1MHZ:
1107 			break;
1108 		default:
1109 			dev_err(component->dev, "Invalid MCLK source rate %d\n", freq);
1110 			return -EINVAL;
1111 		}
1112 		break;
1113 	case CS530X_SYSCLK_SRC_PLL:
1114 		break;
1115 	default:
1116 		dev_err(component->dev, "Invalid sysclk source: %d\n", source);
1117 		return -EINVAL;
1118 	}
1119 
1120 	return regmap_update_bits(regmap, CS530X_CLK_CFG_0,
1121 				  CS530X_SYSCLK_SRC_MASK,
1122 				  source << CS530X_SYSCLK_SRC_SHIFT);
1123 }
1124 
1125 static const struct snd_soc_component_driver soc_component_dev_cs530x = {
1126 	.probe			= cs530x_component_probe,
1127 	.set_sysclk		= cs530x_set_sysclk,
1128 	.set_pll		= cs530x_set_pll,
1129 	.endianness		= 1,
1130 };
1131 
1132 const struct regmap_config cs530x_regmap_i2c = {
1133 	.reg_bits = 16,
1134 	.val_bits = 16,
1135 
1136 	.max_register = CS530X_MAX_REGISTER,
1137 	.readable_reg = cs530x_readable_register,
1138 	.writeable_reg = cs530x_writeable_register,
1139 
1140 	.cache_type = REGCACHE_MAPLE,
1141 	.reg_defaults = cs530x_reg_defaults,
1142 	.num_reg_defaults = ARRAY_SIZE(cs530x_reg_defaults),
1143 };
1144 EXPORT_SYMBOL_NS_GPL(cs530x_regmap_i2c, "SND_SOC_CS530X");
1145 
1146 const struct regmap_config cs530x_regmap_spi = {
1147 	.reg_bits = 16,
1148 	.pad_bits = 16,
1149 	.val_bits = 16,
1150 
1151 	.reg_stride = 2,
1152 
1153 	.reg_format_endian = REGMAP_ENDIAN_BIG,
1154 	.val_format_endian = REGMAP_ENDIAN_BIG,
1155 
1156 	.max_register = CS530X_MAX_REGISTER,
1157 	.writeable_reg = cs530x_writeable_register,
1158 	.readable_reg = cs530x_readable_register,
1159 
1160 	.cache_type = REGCACHE_MAPLE,
1161 	.reg_defaults = cs530x_reg_defaults,
1162 	.num_reg_defaults = ARRAY_SIZE(cs530x_reg_defaults),
1163 };
1164 EXPORT_SYMBOL_NS_GPL(cs530x_regmap_spi, "SND_SOC_CS530X");
1165 
cs530x_check_device_id(struct cs530x_priv * cs530x)1166 static int cs530x_check_device_id(struct cs530x_priv *cs530x)
1167 {
1168 	struct device *dev = cs530x->dev;
1169 	unsigned int dev_id, rev;
1170 	int ret;
1171 
1172 	ret = regmap_read(cs530x->regmap, CS530X_DEVID, &dev_id);
1173 	if (ret)
1174 		return dev_err_probe(dev, ret, "Can't read device ID\n");
1175 
1176 	ret = regmap_read(cs530x->regmap, CS530X_REVID, &rev);
1177 	if (ret)
1178 		return dev_err_probe(dev, ret, "Can't read REV ID\n");
1179 
1180 	switch (dev_id) {
1181 	case CS530X_2CH_CODEC_DEV_ID:
1182 		cs530x->num_dacs = 2;
1183 		cs530x->num_adcs = 2;
1184 		break;
1185 	case CS530X_2CH_DAC_DEV_ID:
1186 		cs530x->num_dacs = 2;
1187 		break;
1188 	case CS530X_4CH_DAC_DEV_ID:
1189 		cs530x->num_dacs = 4;
1190 		break;
1191 	case CS530X_8CH_DAC_DEV_ID:
1192 		cs530x->num_dacs = 8;
1193 		break;
1194 	case CS530X_2CH_ADC_DEV_ID:
1195 		cs530x->num_adcs = 2;
1196 		break;
1197 	case CS530X_4CH_ADC_DEV_ID:
1198 		cs530x->num_adcs = 4;
1199 		break;
1200 	case CS530X_8CH_ADC_DEV_ID:
1201 		cs530x->num_adcs = 8;
1202 		break;
1203 	default:
1204 		return dev_err_probe(dev, -EINVAL, "Invalid device ID 0x%x\n",
1205 				     dev_id);
1206 	}
1207 
1208 	if (cs530x->devtype != dev_id) {
1209 		dev_err(dev, "Read device ID 0x%x is not the expected devtype 0x%x\n",
1210 			dev_id, cs530x->devtype);
1211 		return -EINVAL;
1212 	}
1213 
1214 	dev_dbg(dev, "Device ID 0x%x Rev ID 0x%x (%d in %d out)\n", dev_id, rev,
1215 		cs530x->num_adcs, cs530x->num_dacs);
1216 
1217 	return 0;
1218 }
1219 
cs530x_parse_device_properties(struct cs530x_priv * cs530x)1220 static int cs530x_parse_device_properties(struct cs530x_priv *cs530x)
1221 {
1222 	struct regmap *regmap = cs530x->regmap;
1223 	struct device *dev = cs530x->dev;
1224 	unsigned int val = 0;
1225 
1226 	switch (cs530x->num_adcs) {
1227 	case 8:
1228 		if (device_property_read_bool(dev, "cirrus,in-hiz-pin78"))
1229 			val = CS530X_IN78_HIZ;
1230 
1231 		if (device_property_read_bool(dev, "cirrus,in-hiz-pin56"))
1232 			val |= CS530X_IN56_HIZ;
1233 
1234 		fallthrough;
1235 	case 4:
1236 		if (device_property_read_bool(dev, "cirrus,in-hiz-pin34"))
1237 			val |= CS530X_IN34_HIZ;
1238 
1239 		fallthrough;
1240 	case 2:
1241 		if (device_property_read_bool(dev, "cirrus,in-hiz-pin12"))
1242 			val |= CS530X_IN12_HIZ;
1243 
1244 		return regmap_set_bits(regmap, CS530X_IN_HIZ, val);
1245 	case 0:
1246 		/* No ADCs */
1247 		return 0;
1248 	default:
1249 		return dev_err_probe(dev, -EINVAL,
1250 				     "Invalid number of adcs %d\n",
1251 				     cs530x->num_adcs);
1252 	}
1253 }
1254 
cs530x_probe(struct cs530x_priv * cs530x)1255 int cs530x_probe(struct cs530x_priv *cs530x)
1256 {
1257 	struct device *dev = cs530x->dev;
1258 	int ret, i;
1259 
1260 	cs530x->dev_dai = devm_kmemdup(dev, &cs530x_dai,
1261 				       sizeof(*(cs530x->dev_dai)),
1262 				       GFP_KERNEL);
1263 	if (!cs530x->dev_dai)
1264 		return -ENOMEM;
1265 
1266 	for (i = 0; i < ARRAY_SIZE(cs530x->supplies); i++)
1267 		cs530x->supplies[i].supply = cs530x_supply_names[i];
1268 
1269 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs530x->supplies),
1270 				      cs530x->supplies);
1271 	if (ret != 0)
1272 		return dev_err_probe(dev, ret, "Failed to request supplies");
1273 
1274 	ret = regulator_bulk_enable(ARRAY_SIZE(cs530x->supplies),
1275 				    cs530x->supplies);
1276 	if (ret != 0)
1277 		return dev_err_probe(dev, ret, "Failed to enable supplies");
1278 
1279 	cs530x->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1280 						     GPIOD_OUT_HIGH);
1281 	if (IS_ERR(cs530x->reset_gpio)) {
1282 		ret = dev_err_probe(dev, PTR_ERR(cs530x->reset_gpio),
1283 				    "Reset gpio not available\n");
1284 		goto err_regulator;
1285 	}
1286 
1287 	if (cs530x->reset_gpio) {
1288 		usleep_range(2000, 2100);
1289 		gpiod_set_value_cansleep(cs530x->reset_gpio, 0);
1290 	}
1291 
1292 	usleep_range(5000, 5100);
1293 	ret = cs530x_check_device_id(cs530x);
1294 	if (ret)
1295 		goto err_reset;
1296 
1297 	if (!cs530x->reset_gpio) {
1298 		ret = regmap_write(cs530x->regmap, CS530X_SW_RESET,
1299 				   CS530X_SW_RST_VAL);
1300 		if (ret) {
1301 			dev_err_probe(dev, ret, "Soft Reset Failed\n");
1302 			goto err_reset;
1303 		}
1304 	}
1305 
1306 	ret = cs530x_parse_device_properties(cs530x);
1307 	if (ret)
1308 		goto err_reset;
1309 
1310 	if (cs530x->num_adcs) {
1311 		cs530x->dev_dai->capture.channels_min = 2;
1312 		cs530x->dev_dai->capture.channels_max = cs530x->num_adcs;
1313 	}
1314 
1315 	if (cs530x->num_dacs) {
1316 		cs530x->dev_dai->playback.channels_min = 2;
1317 		cs530x->dev_dai->playback.channels_max = cs530x->num_dacs;
1318 	}
1319 
1320 	ret = devm_snd_soc_register_component(dev,
1321 					      &soc_component_dev_cs530x,
1322 					      cs530x->dev_dai, 1);
1323 	if (ret) {
1324 		dev_err_probe(dev, ret, "Can't register cs530x component\n");
1325 		goto err_reset;
1326 	}
1327 
1328 	return 0;
1329 
1330 err_reset:
1331 	gpiod_set_value_cansleep(cs530x->reset_gpio, 1);
1332 
1333 err_regulator:
1334 	regulator_bulk_disable(ARRAY_SIZE(cs530x->supplies),
1335 			       cs530x->supplies);
1336 
1337 	return ret;
1338 }
1339 EXPORT_SYMBOL_NS_GPL(cs530x_probe, "SND_SOC_CS530X");
1340 
1341 MODULE_DESCRIPTION("CS530X CODEC Driver");
1342 MODULE_AUTHOR("Paul Handrigan <paulha@opensource.cirrus.com>");
1343 MODULE_LICENSE("GPL");
1344