xref: /linux/sound/soc/codecs/pcm6240.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // ALSA SoC Texas Instruments PCM6240 Family Audio ADC/DAC Device
4 //
5 // Copyright (C) 2022 - 2024 Texas Instruments Incorporated
6 // https://www.ti.com
7 //
8 // The PCM6240 driver implements a flexible and configurable
9 // algo coefficient setting for one, two, or even multiple
10 // PCM6240 Family chips.
11 //
12 // Author: Shenghao Ding <shenghao-ding@ti.com>
13 //
14 
15 #include <linux/cleanup.h>
16 #include <linux/unaligned.h>
17 #include <linux/firmware.h>
18 #include <linux/gpio/consumer.h>
19 #include <linux/i2c.h>
20 #include <linux/module.h>
21 #include <linux/of_irq.h>
22 #include <linux/of_address.h>
23 #include <linux/regmap.h>
24 #include <sound/pcm_params.h>
25 #include <sound/soc.h>
26 #include <sound/tlv.h>
27 
28 #include "pcm6240.h"
29 
30 static const struct i2c_device_id pcmdevice_i2c_id[] = {
31 	{ .name = "adc3120", .driver_data = ADC3120 },
32 	{ .name = "adc5120", .driver_data = ADC5120 },
33 	{ .name = "adc6120", .driver_data = ADC6120 },
34 	{ .name = "dix4192", .driver_data = DIX4192 },
35 	{ .name = "pcm1690", .driver_data = PCM1690 },
36 	{ .name = "pcm3120", .driver_data = PCM3120 },
37 	{ .name = "pcm3140", .driver_data = PCM3140 },
38 	{ .name = "pcm5120", .driver_data = PCM5120 },
39 	{ .name = "pcm5140", .driver_data = PCM5140 },
40 	{ .name = "pcm6120", .driver_data = PCM6120 },
41 	{ .name = "pcm6140", .driver_data = PCM6140 },
42 	{ .name = "pcm6240", .driver_data = PCM6240 },
43 	{ .name = "pcm6260", .driver_data = PCM6260 },
44 	{ .name = "pcm9211", .driver_data = PCM9211 },
45 	{ .name = "pcmd3140", .driver_data = PCMD3140 },
46 	{ .name = "pcmd3180", .driver_data = PCMD3180 },
47 	{ .name = "pcmd512x", .driver_data = PCMD512X },
48 	{ .name = "taa5212", .driver_data = TAA5212 },
49 	{ .name = "taa5412", .driver_data = TAA5412 },
50 	{ .name = "tad5212", .driver_data = TAD5212 },
51 	{ .name = "tad5412", .driver_data = TAD5412 },
52 	{ }
53 };
54 MODULE_DEVICE_TABLE(i2c, pcmdevice_i2c_id);
55 
56 static const char *const pcmdev_ctrl_name[] = {
57 	"%s i2c%d Dev%d Ch%d Ana Volume",
58 	"%s i2c%d Dev%d Ch%d Digi Volume",
59 	"%s i2c%d Dev%d Ch%d Fine Volume",
60 };
61 
62 static const struct pcmdevice_mixer_control adc5120_analog_gain_ctl[] = {
63 	{
64 		.shift = 1,
65 		.reg = ADC5120_REG_CH1_ANALOG_GAIN,
66 		.max = 0x54,
67 		.invert = 0,
68 	},
69 	{
70 		.shift = 1,
71 		.reg = ADC5120_REG_CH2_ANALOG_GAIN,
72 		.max = 0x54,
73 		.invert = 0,
74 	}
75 };
76 
77 static const struct pcmdevice_mixer_control adc5120_digi_gain_ctl[] = {
78 	{
79 		.shift = 0,
80 		.reg = ADC5120_REG_CH1_DIGITAL_GAIN,
81 		.max = 0xff,
82 		.invert = 0,
83 	},
84 	{
85 		.shift = 0,
86 		.reg = ADC5120_REG_CH2_DIGITAL_GAIN,
87 		.max = 0xff,
88 		.invert = 0,
89 	}
90 };
91 
92 static const struct pcmdevice_mixer_control pcm1690_digi_gain_ctl[] = {
93 	{
94 		.shift = 0,
95 		.reg = PCM1690_REG_CH1_DIGITAL_GAIN,
96 		.max = 0xff,
97 		.invert = 0,
98 	},
99 	{
100 		.shift = 0,
101 		.reg = PCM1690_REG_CH2_DIGITAL_GAIN,
102 		.max = 0xff,
103 		.invert = 0,
104 	},
105 	{
106 		.shift = 0,
107 		.reg = PCM1690_REG_CH3_DIGITAL_GAIN,
108 		.max = 0xff,
109 		.invert = 0,
110 	},
111 	{
112 		.shift = 0,
113 		.reg = PCM1690_REG_CH4_DIGITAL_GAIN,
114 		.max = 0xff,
115 		.invert = 0,
116 	},
117 	{
118 		.shift = 0,
119 		.reg = PCM1690_REG_CH5_DIGITAL_GAIN,
120 		.max = 0xff,
121 		.invert = 0,
122 	},
123 	{
124 		.shift = 0,
125 		.reg = PCM1690_REG_CH6_DIGITAL_GAIN,
126 		.max = 0xff,
127 		.invert = 0,
128 	},
129 	{
130 		.shift = 0,
131 		.reg = PCM1690_REG_CH7_DIGITAL_GAIN,
132 		.max = 0xff,
133 		.invert = 0,
134 	},
135 	{
136 		.shift = 0,
137 		.reg = PCM1690_REG_CH8_DIGITAL_GAIN,
138 		.max = 0xff,
139 		.invert = 0,
140 	}
141 };
142 
143 static const struct pcmdevice_mixer_control pcm6240_analog_gain_ctl[] = {
144 	{
145 		.shift = 2,
146 		.reg = PCM6240_REG_CH1_ANALOG_GAIN,
147 		.max = 0x42,
148 		.invert = 0,
149 	},
150 	{
151 		.shift = 2,
152 		.reg = PCM6240_REG_CH2_ANALOG_GAIN,
153 		.max = 0x42,
154 		.invert = 0,
155 	},
156 	{
157 		.shift = 2,
158 		.reg = PCM6240_REG_CH3_ANALOG_GAIN,
159 		.max = 0x42,
160 		.invert = 0,
161 	},
162 	{
163 		.shift = 2,
164 		.reg = PCM6240_REG_CH4_ANALOG_GAIN,
165 		.max = 0x42,
166 		.invert = 0,
167 	}
168 };
169 
170 static const struct pcmdevice_mixer_control pcm6240_digi_gain_ctl[] = {
171 	{
172 		.shift = 0,
173 		.reg = PCM6240_REG_CH1_DIGITAL_GAIN,
174 		.max = 0xff,
175 		.invert = 0,
176 	},
177 	{
178 		.shift = 0,
179 		.reg = PCM6240_REG_CH2_DIGITAL_GAIN,
180 		.max = 0xff,
181 		.invert = 0,
182 	},
183 	{
184 		.shift = 0,
185 		.reg = PCM6240_REG_CH3_DIGITAL_GAIN,
186 		.max = 0xff,
187 		.invert = 0,
188 	},
189 	{
190 		.shift = 0,
191 		.reg = PCM6240_REG_CH4_DIGITAL_GAIN,
192 		.max = 0xff,
193 		.invert = 0,
194 	}
195 };
196 
197 static const struct pcmdevice_mixer_control pcm6260_analog_gain_ctl[] = {
198 	{
199 		.shift = 2,
200 		.reg = PCM6260_REG_CH1_ANALOG_GAIN,
201 		.max = 0x42,
202 		.invert = 0,
203 	},
204 	{
205 		.shift = 2,
206 		.reg = PCM6260_REG_CH2_ANALOG_GAIN,
207 		.max = 0x42,
208 		.invert = 0,
209 	},
210 	{
211 		.shift = 2,
212 		.reg = PCM6260_REG_CH3_ANALOG_GAIN,
213 		.max = 0x42,
214 		.invert = 0,
215 	},
216 	{
217 		.shift = 2,
218 		.reg = PCM6260_REG_CH4_ANALOG_GAIN,
219 		.max = 0x42,
220 		.invert = 0,
221 	},
222 	{
223 		.shift = 2,
224 		.reg = PCM6260_REG_CH5_ANALOG_GAIN,
225 		.max = 0x42,
226 		.invert = 0,
227 	},
228 	{
229 		.shift = 2,
230 		.reg = PCM6260_REG_CH6_ANALOG_GAIN,
231 		.max = 0x42,
232 		.invert = 0,
233 	}
234 };
235 
236 static const struct pcmdevice_mixer_control pcm6260_digi_gain_ctl[] = {
237 	{
238 		.shift = 0,
239 		.reg = PCM6260_REG_CH1_DIGITAL_GAIN,
240 		.max = 0xff,
241 		.invert = 0,
242 	},
243 	{
244 		.shift = 0,
245 		.reg = PCM6260_REG_CH2_DIGITAL_GAIN,
246 		.max = 0xff,
247 		.invert = 0,
248 	},
249 	{
250 		.shift = 0,
251 		.reg = PCM6260_REG_CH3_DIGITAL_GAIN,
252 		.max = 0xff,
253 		.invert = 0,
254 	},
255 	{
256 		.shift = 0,
257 		.reg = PCM6260_REG_CH4_DIGITAL_GAIN,
258 		.max = 0xff,
259 		.invert = 0,
260 	},
261 	{
262 		.shift = 0,
263 		.reg = PCM6260_REG_CH5_DIGITAL_GAIN,
264 		.max = 0xff,
265 		.invert = 0,
266 	},
267 	{
268 		.shift = 0,
269 		.reg = PCM6260_REG_CH6_DIGITAL_GAIN,
270 		.max = 0xff,
271 		.invert = 0,
272 	}
273 };
274 
275 static const struct pcmdevice_mixer_control pcm9211_digi_gain_ctl[] = {
276 	{
277 		.shift = 0,
278 		.reg = PCM9211_REG_CH1_DIGITAL_GAIN,
279 		.max = 0xff,
280 		.invert = 0,
281 	},
282 	{
283 		.shift = 0,
284 		.reg = PCM9211_REG_CH2_DIGITAL_GAIN,
285 		.max = 0xff,
286 		.invert = 0,
287 	}
288 };
289 
290 static const struct pcmdevice_mixer_control pcmd3140_digi_gain_ctl[] = {
291 	{
292 		.shift = 0,
293 		.reg = PCMD3140_REG_CH1_DIGITAL_GAIN,
294 		.max = 0xff,
295 		.invert = 0,
296 	},
297 	{
298 		.shift = 0,
299 		.reg = PCMD3140_REG_CH2_DIGITAL_GAIN,
300 		.max = 0xff,
301 		.invert = 0,
302 	},
303 	{
304 		.shift = 0,
305 		.reg = PCMD3140_REG_CH3_DIGITAL_GAIN,
306 		.max = 0xff,
307 		.invert = 0,
308 	},
309 	{
310 		.shift = 0,
311 		.reg = PCMD3140_REG_CH4_DIGITAL_GAIN,
312 		.max = 0xff,
313 		.invert = 0,
314 	}
315 };
316 
317 static const struct pcmdevice_mixer_control pcmd3140_fine_gain_ctl[] = {
318 	{
319 		.shift = 4,
320 		.reg = PCMD3140_REG_CH1_FINE_GAIN,
321 		.max = 0xf,
322 		.invert = 0,
323 	},
324 	{
325 		.shift = 4,
326 		.reg = PCMD3140_REG_CH2_FINE_GAIN,
327 		.max = 0xf,
328 		.invert = 0,
329 	},
330 	{
331 		.shift = 4,
332 		.reg = PCMD3140_REG_CH3_FINE_GAIN,
333 		.max = 0xf,
334 		.invert = 0,
335 	},
336 	{
337 		.shift = 4,
338 		.reg = PCMD3140_REG_CH4_FINE_GAIN,
339 		.max = 0xf,
340 		.invert = 0,
341 	}
342 };
343 
344 static const struct pcmdevice_mixer_control pcmd3180_digi_gain_ctl[] = {
345 	{
346 		.shift = 0,
347 		.reg = PCMD3180_REG_CH1_DIGITAL_GAIN,
348 		.max = 0xff,
349 		.invert = 0,
350 	},
351 	{
352 		.shift = 0,
353 		.reg = PCMD3180_REG_CH2_DIGITAL_GAIN,
354 		.max = 0xff,
355 		.invert = 0,
356 	},
357 	{
358 		.shift = 0,
359 		.reg = PCMD3180_REG_CH3_DIGITAL_GAIN,
360 		.max = 0xff,
361 		.invert = 0,
362 	},
363 	{
364 		.shift = 0,
365 		.reg = PCMD3180_REG_CH4_DIGITAL_GAIN,
366 		.max = 0xff,
367 		.invert = 0,
368 	},
369 	{
370 		.shift = 0,
371 		.reg = PCMD3180_REG_CH5_DIGITAL_GAIN,
372 		.max = 0xff,
373 		.invert = 0,
374 	},
375 	{
376 		.shift = 0,
377 		.reg = PCMD3180_REG_CH6_DIGITAL_GAIN,
378 		.max = 0xff,
379 		.invert = 0,
380 	},
381 	{
382 		.shift = 0,
383 		.reg = PCMD3180_REG_CH7_DIGITAL_GAIN,
384 		.max = 0xff,
385 		.invert = 0,
386 	},
387 	{
388 		.shift = 0,
389 		.reg = PCMD3180_REG_CH8_DIGITAL_GAIN,
390 		.max = 0xff,
391 		.invert = 0,
392 	}
393 };
394 
395 static const struct pcmdevice_mixer_control pcmd3180_fine_gain_ctl[] = {
396 	{
397 		.shift = 4,
398 		.reg = PCMD3180_REG_CH1_FINE_GAIN,
399 		.max = 0xf,
400 		.invert = 0,
401 	},
402 	{
403 		.shift = 4,
404 		.reg = PCMD3180_REG_CH2_FINE_GAIN,
405 		.max = 0xf,
406 		.invert = 0,
407 	},
408 	{
409 		.shift = 4,
410 		.reg = PCMD3180_REG_CH3_FINE_GAIN,
411 		.max = 0xf,
412 		.invert = 0,
413 	},
414 	{
415 		.shift = 4,
416 		.reg = PCMD3180_REG_CH4_FINE_GAIN,
417 		.max = 0xf,
418 		.invert = 0,
419 	},
420 	{
421 		.shift = 4,
422 		.reg = PCMD3180_REG_CH5_FINE_GAIN,
423 		.max = 0xf,
424 		.invert = 0,
425 	},
426 	{
427 		.shift = 4,
428 		.reg = PCMD3180_REG_CH6_FINE_GAIN,
429 		.max = 0xf,
430 		.invert = 0,
431 	},
432 	{
433 		.shift = 4,
434 		.reg = PCMD3180_REG_CH7_FINE_GAIN,
435 		.max = 0xf,
436 		.invert = 0,
437 	},
438 	{
439 		.shift = 4,
440 		.reg = PCMD3180_REG_CH8_FINE_GAIN,
441 		.max = 0xf,
442 		.invert = 0,
443 	}
444 };
445 
446 static const struct pcmdevice_mixer_control taa5412_digi_vol_ctl[] = {
447 	{
448 		.shift = 0,
449 		.reg = TAA5412_REG_CH1_DIGITAL_VOLUME,
450 		.max = 0xff,
451 		.invert = 0,
452 	},
453 	{
454 		.shift = 0,
455 		.reg = TAA5412_REG_CH2_DIGITAL_VOLUME,
456 		.max = 0xff,
457 		.invert = 0,
458 	},
459 	{
460 		.shift = 0,
461 		.reg = TAA5412_REG_CH3_DIGITAL_VOLUME,
462 		.max = 0xff,
463 		.invert = 0,
464 	},
465 	{
466 		.shift = 0,
467 		.reg = TAA5412_REG_CH4_DIGITAL_VOLUME,
468 		.max = 0xff,
469 		.invert = 0,
470 	}
471 };
472 
473 static const struct pcmdevice_mixer_control taa5412_fine_gain_ctl[] = {
474 	{
475 		.shift = 4,
476 		.reg = TAA5412_REG_CH1_FINE_GAIN,
477 		.max = 0xf,
478 		.invert = 0,
479 	},
480 	{
481 		.shift = 4,
482 		.reg = TAA5412_REG_CH2_FINE_GAIN,
483 		.max = 0xf,
484 		.invert = 0,
485 	},
486 	{
487 		.shift = 4,
488 		.reg = TAA5412_REG_CH3_FINE_GAIN,
489 		.max = 0xf,
490 		.invert = 4,
491 	},
492 	{
493 		.shift = 0,
494 		.reg = TAA5412_REG_CH4_FINE_GAIN,
495 		.max = 0xf,
496 		.invert = 4,
497 	}
498 };
499 
500 static const DECLARE_TLV_DB_MINMAX_MUTE(pcmd3140_dig_gain_tlv,
501 	-10000, 2700);
502 static const DECLARE_TLV_DB_MINMAX_MUTE(pcm1690_fine_dig_gain_tlv,
503 	-12750, 0);
504 static const DECLARE_TLV_DB_MINMAX_MUTE(pcm1690_dig_gain_tlv,
505 	-25500, 0);
506 static const DECLARE_TLV_DB_MINMAX_MUTE(pcm9211_dig_gain_tlv,
507 	-11450, 2000);
508 static const DECLARE_TLV_DB_MINMAX_MUTE(adc5120_fgain_tlv,
509 	-10050, 2700);
510 static const DECLARE_TLV_DB_LINEAR(adc5120_chgain_tlv, 0, 4200);
511 static const DECLARE_TLV_DB_MINMAX_MUTE(pcm6260_fgain_tlv,
512 	-10000, 2700);
513 static const DECLARE_TLV_DB_LINEAR(pcm6260_chgain_tlv, 0, 4200);
514 static const DECLARE_TLV_DB_MINMAX_MUTE(taa5412_dig_vol_tlv,
515 	-8050, 4700);
516 static const DECLARE_TLV_DB_LINEAR(taa5412_fine_gain_tlv,
517 	-80, 70);
518 
519 static int pcmdev_change_dev(struct pcmdevice_priv *pcm_priv,
520 	unsigned short dev_no)
521 {
522 	struct i2c_client *client = (struct i2c_client *)pcm_priv->client;
523 	struct regmap *map = pcm_priv->regmap;
524 	int ret;
525 
526 	if (client->addr == pcm_priv->addr[dev_no])
527 		return 0;
528 
529 	client->addr = pcm_priv->addr[dev_no];
530 	/* All pcmdevices share the same regmap, clear the page
531 	 * inside regmap once switching to another pcmdevice.
532 	 * Register 0 at any pages inside pcmdevice is the same
533 	 * one for page-switching.
534 	 */
535 	ret = regmap_write(map, PCMDEVICE_PAGE_SELECT, 0);
536 	if (ret < 0)
537 		dev_err(pcm_priv->dev, "%s: err = %d\n", __func__, ret);
538 
539 	return ret;
540 }
541 
542 static int pcmdev_dev_read(struct pcmdevice_priv *pcm_dev,
543 	unsigned int dev_no, unsigned int reg, unsigned int *val)
544 {
545 	struct regmap *map = pcm_dev->regmap;
546 	int ret;
547 
548 	if (dev_no >= pcm_dev->ndev) {
549 		dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__,
550 			dev_no);
551 		return -EINVAL;
552 	}
553 
554 	ret = pcmdev_change_dev(pcm_dev, dev_no);
555 	if (ret < 0) {
556 		dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret);
557 		return ret;
558 	}
559 
560 	ret = regmap_read(map, reg, val);
561 	if (ret < 0)
562 		dev_err(pcm_dev->dev, "%s: err = %d\n", __func__, ret);
563 
564 	return ret;
565 }
566 
567 static int pcmdev_dev_update_bits(struct pcmdevice_priv *pcm_dev,
568 	unsigned int dev_no, unsigned int reg, unsigned int mask,
569 	unsigned int value)
570 {
571 	struct regmap *map = pcm_dev->regmap;
572 	int ret;
573 
574 	if (dev_no >= pcm_dev->ndev) {
575 		dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__,
576 			dev_no);
577 		return -EINVAL;
578 	}
579 
580 	ret = pcmdev_change_dev(pcm_dev, dev_no);
581 	if (ret < 0) {
582 		dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret);
583 		return ret;
584 	}
585 
586 	ret = regmap_update_bits(map, reg, mask, value);
587 	if (ret < 0)
588 		dev_err(pcm_dev->dev, "%s: update_bits err=%d\n",
589 			__func__, ret);
590 
591 	return ret;
592 }
593 
594 static int pcmdev_get_volsw(struct snd_kcontrol *kcontrol,
595 	struct snd_ctl_elem_value *ucontrol, int vol_ctrl_type)
596 {
597 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
598 	struct pcmdevice_priv *pcm_dev =
599 		snd_soc_component_get_drvdata(component);
600 	struct pcmdevice_mixer_control *mc =
601 		(struct pcmdevice_mixer_control *)kcontrol->private_value;
602 	int max = mc->max, ret;
603 	unsigned int mask = BIT(fls(max)) - 1;
604 	unsigned int dev_no = mc->dev_no;
605 	unsigned int shift = mc->shift;
606 	unsigned int reg = mc->reg;
607 	unsigned int val;
608 
609 	guard(mutex)(&pcm_dev->codec_lock);
610 
611 	if (pcm_dev->chip_id == PCM1690) {
612 		ret = pcmdev_dev_read(pcm_dev, dev_no, PCM1690_REG_MODE_CTRL,
613 			&val);
614 		if (ret) {
615 			dev_err(pcm_dev->dev, "%s: read mode err=%d\n",
616 				__func__, ret);
617 			return ret;
618 		}
619 		val &= PCM1690_REG_MODE_CTRL_DAMS_MSK;
620 		/* Set to wide-range mode, before using vol ctrl. */
621 		if (!val && vol_ctrl_type == PCMDEV_PCM1690_VOL_CTRL) {
622 			ucontrol->value.integer.value[0] = -25500;
623 			return ret;
624 		}
625 		/* Set to fine mode, before using fine vol ctrl. */
626 		if (val && vol_ctrl_type == PCMDEV_PCM1690_FINE_VOL_CTRL) {
627 			ucontrol->value.integer.value[0] = -12750;
628 			return ret;
629 		}
630 	}
631 
632 	ret = pcmdev_dev_read(pcm_dev, dev_no, reg, &val);
633 	if (ret) {
634 		dev_err(pcm_dev->dev, "%s: read err=%d\n",
635 			__func__, ret);
636 		return ret;
637 	}
638 
639 	val = (val >> shift) & mask;
640 	val = (val > max) ? max : val;
641 	val = mc->invert ? max - val : val;
642 	ucontrol->value.integer.value[0] = val;
643 
644 	return ret;
645 }
646 
647 static int pcmdevice_get_volsw(struct snd_kcontrol *kcontrol,
648 	struct snd_ctl_elem_value *ucontrol)
649 {
650 	return pcmdev_get_volsw(kcontrol, ucontrol, PCMDEV_GENERIC_VOL_CTRL);
651 }
652 
653 static int pcm1690_get_volsw(struct snd_kcontrol *kcontrol,
654 	struct snd_ctl_elem_value *ucontrol)
655 {
656 	return pcmdev_get_volsw(kcontrol, ucontrol, PCMDEV_PCM1690_VOL_CTRL);
657 }
658 
659 static int pcm1690_get_finevolsw(struct snd_kcontrol *kcontrol,
660 		struct snd_ctl_elem_value *ucontrol)
661 {
662 	return pcmdev_get_volsw(kcontrol, ucontrol,
663 		PCMDEV_PCM1690_FINE_VOL_CTRL);
664 }
665 
666 static int pcmdev_put_volsw(struct snd_kcontrol *kcontrol,
667 	struct snd_ctl_elem_value *ucontrol, int vol_ctrl_type)
668 {
669 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
670 	struct pcmdevice_priv *pcm_dev =
671 		snd_soc_component_get_drvdata(component);
672 	struct pcmdevice_mixer_control *mc =
673 		(struct pcmdevice_mixer_control *)kcontrol->private_value;
674 	int max = mc->max, rc;
675 	unsigned int mask = BIT(fls(max)) - 1;
676 	unsigned int dev_no = mc->dev_no;
677 	unsigned int shift = mc->shift;
678 	unsigned int val, val_mask;
679 	unsigned int reg = mc->reg;
680 
681 	guard(mutex)(&pcm_dev->codec_lock);
682 	val = ucontrol->value.integer.value[0] & mask;
683 	val = (val > max) ? max : val;
684 	val = mc->invert ? max - val : val;
685 	val_mask = mask << shift;
686 	val = val << shift;
687 
688 	switch (vol_ctrl_type) {
689 	case PCMDEV_PCM1690_VOL_CTRL:
690 		val_mask |= PCM1690_REG_MODE_CTRL_DAMS_MSK;
691 		val |= PCM1690_REG_MODE_CTRL_DAMS_WIDE_RANGE;
692 		break;
693 	case PCMDEV_PCM1690_FINE_VOL_CTRL:
694 		val_mask |= PCM1690_REG_MODE_CTRL_DAMS_MSK;
695 		val |= PCM1690_REG_MODE_CTRL_DAMS_FINE_STEP;
696 		break;
697 	}
698 
699 	rc = pcmdev_dev_update_bits(pcm_dev, dev_no, reg, val_mask, val);
700 	if (rc < 0)
701 		dev_err(pcm_dev->dev, "%s: update_bits err = %d\n",
702 			__func__, rc);
703 	else
704 		rc = 1;
705 
706 	return rc;
707 }
708 
709 static int pcmdevice_put_volsw(struct snd_kcontrol *kcontrol,
710 	struct snd_ctl_elem_value *ucontrol)
711 {
712 	return pcmdev_put_volsw(kcontrol, ucontrol, PCMDEV_GENERIC_VOL_CTRL);
713 }
714 
715 static int pcm1690_put_volsw(struct snd_kcontrol *kcontrol,
716 	struct snd_ctl_elem_value *ucontrol)
717 {
718 	return pcmdev_put_volsw(kcontrol, ucontrol, PCMDEV_PCM1690_VOL_CTRL);
719 }
720 
721 static int pcm1690_put_finevolsw(struct snd_kcontrol *kcontrol,
722 	struct snd_ctl_elem_value *ucontrol)
723 {
724 	return pcmdev_put_volsw(kcontrol, ucontrol,
725 		PCMDEV_PCM1690_FINE_VOL_CTRL);
726 }
727 
728 static const struct pcmdev_ctrl_info pcmdev_gain_ctl_info[][2] = {
729 	// ADC3120
730 	{
731 		{
732 			.gain = adc5120_chgain_tlv,
733 			.pcmdev_ctrl = adc5120_analog_gain_ctl,
734 			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
735 			.get = pcmdevice_get_volsw,
736 			.put = pcmdevice_put_volsw,
737 			.pcmdev_ctrl_name_id = 0,
738 		},
739 		{
740 			.gain = adc5120_fgain_tlv,
741 			.pcmdev_ctrl = adc5120_digi_gain_ctl,
742 			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
743 			.get = pcmdevice_get_volsw,
744 			.put = pcmdevice_put_volsw,
745 			.pcmdev_ctrl_name_id = 1,
746 		},
747 	},
748 	// ADC5120
749 	{
750 		{
751 			.gain = adc5120_chgain_tlv,
752 			.pcmdev_ctrl = adc5120_analog_gain_ctl,
753 			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
754 			.get = pcmdevice_get_volsw,
755 			.put = pcmdevice_put_volsw,
756 			.pcmdev_ctrl_name_id = 0,
757 		},
758 		{
759 			.gain = adc5120_fgain_tlv,
760 			.pcmdev_ctrl = adc5120_digi_gain_ctl,
761 			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
762 			.get = pcmdevice_get_volsw,
763 			.put = pcmdevice_put_volsw,
764 			.pcmdev_ctrl_name_id = 1,
765 		},
766 	},
767 	// ADC6120
768 	{
769 		{
770 			.gain = adc5120_chgain_tlv,
771 			.pcmdev_ctrl = adc5120_analog_gain_ctl,
772 			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
773 			.get = pcmdevice_get_volsw,
774 			.put = pcmdevice_put_volsw,
775 			.pcmdev_ctrl_name_id = 0,
776 		},
777 		{
778 			.gain = adc5120_fgain_tlv,
779 			.pcmdev_ctrl = adc5120_digi_gain_ctl,
780 			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
781 			.get = pcmdevice_get_volsw,
782 			.put = pcmdevice_put_volsw,
783 			.pcmdev_ctrl_name_id = 1,
784 		},
785 	},
786 	// DIX4192
787 	{
788 		{
789 			.ctrl_array_size = 0,
790 		},
791 		{
792 			.ctrl_array_size = 0,
793 		},
794 	},
795 	// PCM1690
796 	{
797 		{
798 			.gain = pcm1690_fine_dig_gain_tlv,
799 			.pcmdev_ctrl = pcm1690_digi_gain_ctl,
800 			.ctrl_array_size = ARRAY_SIZE(pcm1690_digi_gain_ctl),
801 			.get = pcm1690_get_volsw,
802 			.put = pcm1690_put_volsw,
803 			.pcmdev_ctrl_name_id = 1,
804 		},
805 		{
806 			.gain = pcm1690_dig_gain_tlv,
807 			.pcmdev_ctrl = pcm1690_digi_gain_ctl,
808 			.ctrl_array_size = ARRAY_SIZE(pcm1690_digi_gain_ctl),
809 			.get = pcm1690_get_finevolsw,
810 			.put = pcm1690_put_finevolsw,
811 			.pcmdev_ctrl_name_id = 2,
812 		},
813 	},
814 	// PCM3120
815 	{
816 		{
817 			.gain = adc5120_chgain_tlv,
818 			.pcmdev_ctrl = adc5120_analog_gain_ctl,
819 			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
820 			.get = pcmdevice_get_volsw,
821 			.put = pcmdevice_put_volsw,
822 			.pcmdev_ctrl_name_id = 0,
823 		},
824 		{
825 			.gain = adc5120_fgain_tlv,
826 			.pcmdev_ctrl = adc5120_digi_gain_ctl,
827 			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
828 			.get = pcmdevice_get_volsw,
829 			.put = pcmdevice_put_volsw,
830 			.pcmdev_ctrl_name_id = 1,
831 		},
832 	},
833 	// PCM3140
834 	{
835 		{
836 			.gain = pcm6260_chgain_tlv,
837 			.pcmdev_ctrl = pcm6240_analog_gain_ctl,
838 			.ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl),
839 			.get = pcmdevice_get_volsw,
840 			.put = pcmdevice_put_volsw,
841 			.pcmdev_ctrl_name_id = 0,
842 		},
843 		{
844 			.gain = pcm6260_fgain_tlv,
845 			.pcmdev_ctrl = pcm6240_digi_gain_ctl,
846 			.ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl),
847 			.get = pcmdevice_get_volsw,
848 			.put = pcmdevice_put_volsw,
849 			.pcmdev_ctrl_name_id = 1,
850 		},
851 	},
852 	// PCM5120
853 	{
854 		{
855 			.gain = adc5120_chgain_tlv,
856 			.pcmdev_ctrl = adc5120_analog_gain_ctl,
857 			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
858 			.get = pcmdevice_get_volsw,
859 			.put = pcmdevice_put_volsw,
860 			.pcmdev_ctrl_name_id = 0,
861 		},
862 		{
863 			.gain = adc5120_fgain_tlv,
864 			.pcmdev_ctrl = adc5120_digi_gain_ctl,
865 			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
866 			.get = pcmdevice_get_volsw,
867 			.put = pcmdevice_put_volsw,
868 			.pcmdev_ctrl_name_id = 1,
869 		},
870 	},
871 	// PCM5140
872 	{
873 		{
874 			.gain = pcm6260_chgain_tlv,
875 			.pcmdev_ctrl = pcm6240_analog_gain_ctl,
876 			.ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl),
877 			.get = pcmdevice_get_volsw,
878 			.put = pcmdevice_put_volsw,
879 			.pcmdev_ctrl_name_id = 0,
880 		},
881 		{
882 			.gain = pcm6260_fgain_tlv,
883 			.pcmdev_ctrl = pcm6240_digi_gain_ctl,
884 			.ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl),
885 			.get = pcmdevice_get_volsw,
886 			.put = pcmdevice_put_volsw,
887 			.pcmdev_ctrl_name_id = 1,
888 		},
889 	},
890 	// PCM6120
891 	{
892 		{
893 			.gain = adc5120_chgain_tlv,
894 			.pcmdev_ctrl = adc5120_analog_gain_ctl,
895 			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
896 			.get = pcmdevice_get_volsw,
897 			.put = pcmdevice_put_volsw,
898 			.pcmdev_ctrl_name_id = 0,
899 		},
900 		{
901 			.gain = adc5120_fgain_tlv,
902 			.pcmdev_ctrl = adc5120_digi_gain_ctl,
903 			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
904 			.get = pcmdevice_get_volsw,
905 			.put = pcmdevice_put_volsw,
906 			.pcmdev_ctrl_name_id = 1,
907 		},
908 	},
909 	// PCM6140
910 	{
911 		{
912 			.gain = pcm6260_chgain_tlv,
913 			.pcmdev_ctrl = pcm6240_analog_gain_ctl,
914 			.ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl),
915 			.get = pcmdevice_get_volsw,
916 			.put = pcmdevice_put_volsw,
917 			.pcmdev_ctrl_name_id = 0,
918 		},
919 		{
920 			.gain = pcm6260_fgain_tlv,
921 			.pcmdev_ctrl = pcm6240_digi_gain_ctl,
922 			.ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl),
923 			.get = pcmdevice_get_volsw,
924 			.put = pcmdevice_put_volsw,
925 			.pcmdev_ctrl_name_id = 1,
926 		},
927 	},
928 	// PCM6240
929 	{
930 		{
931 			.gain = pcm6260_chgain_tlv,
932 			.pcmdev_ctrl = pcm6240_analog_gain_ctl,
933 			.ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl),
934 			.get = pcmdevice_get_volsw,
935 			.put = pcmdevice_put_volsw,
936 			.pcmdev_ctrl_name_id = 0,
937 		},
938 		{
939 			.gain = pcm6260_fgain_tlv,
940 			.pcmdev_ctrl = pcm6240_digi_gain_ctl,
941 			.ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl),
942 			.get = pcmdevice_get_volsw,
943 			.put = pcmdevice_put_volsw,
944 			.pcmdev_ctrl_name_id = 1,
945 		},
946 	},
947 	// PCM6260
948 	{
949 		{
950 			.gain = pcm6260_chgain_tlv,
951 			.pcmdev_ctrl = pcm6260_analog_gain_ctl,
952 			.ctrl_array_size = ARRAY_SIZE(pcm6260_analog_gain_ctl),
953 			.get = pcmdevice_get_volsw,
954 			.put = pcmdevice_put_volsw,
955 			.pcmdev_ctrl_name_id = 0,
956 		},
957 		{
958 			.gain = pcm6260_fgain_tlv,
959 			.pcmdev_ctrl = pcm6260_digi_gain_ctl,
960 			.ctrl_array_size = ARRAY_SIZE(pcm6260_digi_gain_ctl),
961 			.get = pcmdevice_get_volsw,
962 			.put = pcmdevice_put_volsw,
963 			.pcmdev_ctrl_name_id = 1,
964 		},
965 	},
966 	// PCM9211
967 	{
968 		{
969 			.ctrl_array_size = 0,
970 		},
971 		{
972 			.gain = pcm9211_dig_gain_tlv,
973 			.pcmdev_ctrl = pcm9211_digi_gain_ctl,
974 			.ctrl_array_size = ARRAY_SIZE(pcm9211_digi_gain_ctl),
975 			.get = pcmdevice_get_volsw,
976 			.put = pcmdevice_put_volsw,
977 			.pcmdev_ctrl_name_id = 1,
978 		},
979 
980 	},
981 	// PCMD3140
982 	{
983 		{
984 			.gain = taa5412_fine_gain_tlv,
985 			.pcmdev_ctrl = pcmd3140_fine_gain_ctl,
986 			.ctrl_array_size = ARRAY_SIZE(pcmd3140_fine_gain_ctl),
987 			.get = pcmdevice_get_volsw,
988 			.put = pcmdevice_put_volsw,
989 			.pcmdev_ctrl_name_id = 2,
990 		},
991 		{
992 			.gain = pcmd3140_dig_gain_tlv,
993 			.pcmdev_ctrl = pcmd3140_digi_gain_ctl,
994 			.ctrl_array_size = ARRAY_SIZE(pcmd3140_digi_gain_ctl),
995 			.get = pcmdevice_get_volsw,
996 			.put = pcmdevice_put_volsw,
997 			.pcmdev_ctrl_name_id = 1,
998 		},
999 	},
1000 	// PCMD3180
1001 	{
1002 		{
1003 			.gain = taa5412_fine_gain_tlv,
1004 			.pcmdev_ctrl = pcmd3180_fine_gain_ctl,
1005 			.ctrl_array_size = ARRAY_SIZE(pcmd3180_fine_gain_ctl),
1006 			.get = pcmdevice_get_volsw,
1007 			.put = pcmdevice_put_volsw,
1008 			.pcmdev_ctrl_name_id = 2,
1009 		},
1010 		{
1011 			.gain = pcmd3140_dig_gain_tlv,
1012 			.pcmdev_ctrl = pcmd3180_digi_gain_ctl,
1013 			.ctrl_array_size = ARRAY_SIZE(pcmd3180_digi_gain_ctl),
1014 			.get = pcmdevice_get_volsw,
1015 			.put = pcmdevice_put_volsw,
1016 			.pcmdev_ctrl_name_id = 1,
1017 		},
1018 	},
1019 	// PCMD512X
1020 	{
1021 		{
1022 			.ctrl_array_size = 0,
1023 		},
1024 		{
1025 			.ctrl_array_size = 0,
1026 		},
1027 	},
1028 	// TAA5212
1029 	{
1030 		{
1031 			.gain = taa5412_fine_gain_tlv,
1032 			.pcmdev_ctrl = taa5412_fine_gain_ctl,
1033 			.ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl),
1034 			.get = pcmdevice_get_volsw,
1035 			.put = pcmdevice_put_volsw,
1036 			.pcmdev_ctrl_name_id = 2,
1037 		},
1038 		{
1039 			.gain = taa5412_dig_vol_tlv,
1040 			.pcmdev_ctrl = taa5412_digi_vol_ctl,
1041 			.ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl),
1042 			.get = pcmdevice_get_volsw,
1043 			.put = pcmdevice_put_volsw,
1044 			.pcmdev_ctrl_name_id = 1,
1045 		},
1046 	},
1047 	// TAA5412
1048 	{
1049 		{
1050 			.gain = taa5412_fine_gain_tlv,
1051 			.pcmdev_ctrl = taa5412_fine_gain_ctl,
1052 			.ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl),
1053 			.get = pcmdevice_get_volsw,
1054 			.put = pcmdevice_put_volsw,
1055 			.pcmdev_ctrl_name_id = 2,
1056 		},
1057 		{
1058 			.gain = taa5412_dig_vol_tlv,
1059 			.pcmdev_ctrl = taa5412_digi_vol_ctl,
1060 			.ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl),
1061 			.get = pcmdevice_get_volsw,
1062 			.put = pcmdevice_put_volsw,
1063 			.pcmdev_ctrl_name_id = 1,
1064 		},
1065 	},
1066 	// TAD5212
1067 	{
1068 		{
1069 			.ctrl_array_size = 0,
1070 		},
1071 		{
1072 			.ctrl_array_size = 0,
1073 		},
1074 	},
1075 	// TAD5412
1076 	{
1077 		{
1078 			.ctrl_array_size = 0,
1079 		},
1080 		{
1081 			.ctrl_array_size = 0,
1082 		},
1083 	},
1084 };
1085 
1086 static int pcmdev_dev_bulk_write(struct pcmdevice_priv *pcm_dev,
1087 	unsigned int dev_no, unsigned int reg, unsigned char *data,
1088 	unsigned int len)
1089 {
1090 	struct regmap *map = pcm_dev->regmap;
1091 	int ret;
1092 
1093 	if (dev_no >= pcm_dev->ndev) {
1094 		dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__,
1095 			dev_no);
1096 		return -EINVAL;
1097 	}
1098 
1099 	ret = pcmdev_change_dev(pcm_dev, dev_no);
1100 	if (ret < 0) {
1101 		dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret);
1102 		return ret;
1103 	}
1104 
1105 	ret = regmap_bulk_write(map, reg, data, len);
1106 	if (ret < 0)
1107 		dev_err(pcm_dev->dev, "%s: bulk_write err = %d\n", __func__,
1108 			ret);
1109 
1110 	return ret;
1111 }
1112 
1113 static int pcmdev_dev_write(struct pcmdevice_priv *pcm_dev,
1114 	unsigned int dev_no, unsigned int reg, unsigned int value)
1115 {
1116 	struct regmap *map = pcm_dev->regmap;
1117 	int ret;
1118 
1119 	if (dev_no >= pcm_dev->ndev) {
1120 		dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__,
1121 			dev_no);
1122 		return -EINVAL;
1123 	}
1124 
1125 	ret = pcmdev_change_dev(pcm_dev, dev_no);
1126 	if (ret < 0) {
1127 		dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret);
1128 		return ret;
1129 	}
1130 
1131 	ret = regmap_write(map, reg, value);
1132 	if (ret < 0)
1133 		dev_err(pcm_dev->dev, "%s: err = %d\n", __func__, ret);
1134 
1135 	return ret;
1136 }
1137 
1138 static int pcmdevice_info_profile(
1139 	struct snd_kcontrol *kcontrol,
1140 	struct snd_ctl_elem_info *uinfo)
1141 {
1142 	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
1143 	struct pcmdevice_priv *pcm_dev =
1144 		snd_soc_component_get_drvdata(codec);
1145 
1146 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1147 	uinfo->count = 1;
1148 	uinfo->value.integer.min = 0;
1149 	uinfo->value.integer.max = max(0, pcm_dev->regbin.ncfgs - 1);
1150 
1151 	return 0;
1152 }
1153 
1154 static int pcmdevice_get_profile_id(
1155 	struct snd_kcontrol *kcontrol,
1156 	struct snd_ctl_elem_value *ucontrol)
1157 {
1158 	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
1159 	struct pcmdevice_priv *pcm_dev =
1160 		snd_soc_component_get_drvdata(codec);
1161 
1162 	ucontrol->value.integer.value[0] = pcm_dev->cur_conf;
1163 
1164 	return 0;
1165 }
1166 
1167 static int pcmdevice_set_profile_id(
1168 	struct snd_kcontrol *kcontrol,
1169 	struct snd_ctl_elem_value *ucontrol)
1170 {
1171 	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
1172 	struct pcmdevice_priv *pcm_dev =
1173 		snd_soc_component_get_drvdata(codec);
1174 	int nr_profile = ucontrol->value.integer.value[0];
1175 	int max = pcm_dev->regbin.ncfgs - 1;
1176 	int ret = 0;
1177 
1178 	nr_profile = clamp(nr_profile, 0, max);
1179 
1180 	if (pcm_dev->cur_conf != nr_profile) {
1181 		pcm_dev->cur_conf = nr_profile;
1182 		ret = 1;
1183 	}
1184 
1185 	return ret;
1186 }
1187 
1188 static int pcmdevice_info_volsw(struct snd_kcontrol *kcontrol,
1189 	struct snd_ctl_elem_info *uinfo)
1190 {
1191 	struct pcmdevice_mixer_control *mc =
1192 		(struct pcmdevice_mixer_control *)kcontrol->private_value;
1193 
1194 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1195 	uinfo->count = 1;
1196 	uinfo->value.integer.min = 0;
1197 	uinfo->value.integer.max = mc->max;
1198 	return 0;
1199 }
1200 
1201 static void pcm9211_sw_rst(struct pcmdevice_priv *pcm_dev)
1202 {
1203 	int ret, i;
1204 
1205 	for (i = 0; i < pcm_dev->ndev; i++) {
1206 		ret = pcmdev_dev_update_bits(pcm_dev, i,
1207 			PCM9211_REG_SW_CTRL, PCM9211_REG_SW_CTRL_MRST_MSK,
1208 			PCM9211_REG_SW_CTRL_MRST);
1209 		if (ret < 0)
1210 			dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n",
1211 				__func__, i, ret);
1212 	}
1213 }
1214 
1215 static void pcmdevice_sw_rst(struct pcmdevice_priv *pcm_dev)
1216 {
1217 	int ret, i;
1218 
1219 	for (i = 0; i < pcm_dev->ndev; i++) {
1220 		ret = pcmdev_dev_write(pcm_dev, i, PCMDEVICE_REG_SWRESET,
1221 			PCMDEVICE_REG_SWRESET_RESET);
1222 		if (ret < 0)
1223 			dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n",
1224 				__func__, i, ret);
1225 	}
1226 }
1227 
1228 static struct pcmdevice_config_info *pcmdevice_add_config(void *ctxt,
1229 	const unsigned char *config_data, unsigned int config_size,
1230 	int *status)
1231 {
1232 	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1233 	struct pcmdevice_config_info *cfg_info = NULL;
1234 	struct pcmdevice_block_data **bk_da;
1235 	char cfg_name[64] = {};
1236 	unsigned int config_offset = 0, i;
1237 	unsigned int nblocks;
1238 
1239 	if (pcm_dev->regbin.fw_hdr.binary_version_num >= 0x105) {
1240 		if (config_offset + 64 > (int)config_size) {
1241 			*status = -EINVAL;
1242 			dev_err(pcm_dev->dev,
1243 				"%s: cfg_name out of boundary\n", __func__);
1244 			goto out;
1245 		}
1246 		memcpy(cfg_name, &config_data[config_offset], 64);
1247 		config_offset += 64;
1248 	}
1249 
1250 	if (config_offset + 4 > config_size) {
1251 		*status = -EINVAL;
1252 		dev_err(pcm_dev->dev, "%s: nblocks out of boundary\n",
1253 			__func__);
1254 		goto out;
1255 	}
1256 	nblocks = get_unaligned_be32(&config_data[config_offset]);
1257 	config_offset += 4;
1258 
1259 	cfg_info = kzalloc_flex(*cfg_info, blk_data, nblocks);
1260 	if (!cfg_info) {
1261 		*status = -ENOMEM;
1262 		goto out;
1263 	}
1264 	cfg_info->nblocks = nblocks;
1265 	memcpy(cfg_info->cfg_name, cfg_name, sizeof(cfg_info->cfg_name));
1266 	bk_da = cfg_info->blk_data;
1267 	cfg_info->real_nblocks = 0;
1268 	for (i = 0; i < cfg_info->nblocks; i++) {
1269 		if (config_offset + 12 > config_size) {
1270 			*status = -EINVAL;
1271 			dev_err(pcm_dev->dev,
1272 				"%s: out of boundary i = %d nblocks = %u\n",
1273 				__func__, i, cfg_info->nblocks);
1274 			break;
1275 		}
1276 		bk_da[i] = kzalloc_obj(struct pcmdevice_block_data);
1277 		if (!bk_da[i]) {
1278 			*status = -ENOMEM;
1279 			break;
1280 		}
1281 		bk_da[i]->dev_idx = config_data[config_offset];
1282 		config_offset++;
1283 
1284 		bk_da[i]->block_type = config_data[config_offset];
1285 		config_offset++;
1286 
1287 		if (bk_da[i]->block_type == PCMDEVICE_BIN_BLK_PRE_POWER_UP) {
1288 			if (bk_da[i]->dev_idx == 0)
1289 				cfg_info->active_dev =
1290 					(1 << pcm_dev->ndev) - 1;
1291 			else
1292 				cfg_info->active_dev =
1293 					1 << (bk_da[i]->dev_idx - 1);
1294 		}
1295 
1296 		bk_da[i]->yram_checksum =
1297 			get_unaligned_be16(&config_data[config_offset]);
1298 		config_offset += 2;
1299 		bk_da[i]->block_size =
1300 			get_unaligned_be32(&config_data[config_offset]);
1301 		config_offset += 4;
1302 
1303 		bk_da[i]->n_subblks =
1304 			get_unaligned_be32(&config_data[config_offset]);
1305 
1306 		config_offset += 4;
1307 
1308 		if (config_offset + bk_da[i]->block_size > config_size) {
1309 			*status = -EINVAL;
1310 			dev_err(pcm_dev->dev,
1311 				"%s: out of boundary: i = %d blks = %u\n",
1312 				__func__, i, cfg_info->nblocks);
1313 			break;
1314 		}
1315 
1316 		bk_da[i]->regdata = kmemdup(&config_data[config_offset],
1317 			bk_da[i]->block_size, GFP_KERNEL);
1318 		if (!bk_da[i]->regdata) {
1319 			*status = -ENOMEM;
1320 			goto out;
1321 		}
1322 		config_offset += bk_da[i]->block_size;
1323 		cfg_info->real_nblocks += 1;
1324 	}
1325 out:
1326 	return cfg_info;
1327 }
1328 
1329 static int pcmdev_gain_ctrl_add(struct pcmdevice_priv *pcm_dev,
1330 	int dev_no, int ctl_id)
1331 {
1332 	struct i2c_adapter *adap = pcm_dev->client->adapter;
1333 	struct snd_soc_component *comp = pcm_dev->component;
1334 	struct pcmdevice_mixer_control *pcmdev_ctrl;
1335 	struct snd_kcontrol_new *pcmdev_controls;
1336 	int ret, mix_index = 0, name_id, chn;
1337 	unsigned int id = pcm_dev->chip_id;
1338 	const int nr_chn =
1339 		pcmdev_gain_ctl_info[id][ctl_id].ctrl_array_size;
1340 	const char *ctrl_name;
1341 	char *name;
1342 
1343 	if (!nr_chn) {
1344 		dev_dbg(pcm_dev->dev, "%s: no gain ctrl for %s\n", __func__,
1345 			pcm_dev->dev_name);
1346 		return 0;
1347 	}
1348 
1349 	pcmdev_controls = devm_kcalloc(pcm_dev->dev, nr_chn,
1350 				       sizeof(struct snd_kcontrol_new), GFP_KERNEL);
1351 	if (!pcmdev_controls)
1352 		return -ENOMEM;
1353 
1354 	name_id = pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl_name_id;
1355 
1356 	ctrl_name = pcmdev_ctrl_name[name_id];
1357 
1358 	for (chn = 1; chn <= nr_chn; chn++) {
1359 		name = devm_kzalloc(pcm_dev->dev,
1360 			SNDRV_CTL_ELEM_ID_NAME_MAXLEN, GFP_KERNEL);
1361 		if (!name) {
1362 			ret = -ENOMEM;
1363 			goto out;
1364 		}
1365 		scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1366 			ctrl_name, pcm_dev->upper_dev_name, adap->nr,
1367 			dev_no, chn);
1368 		pcmdev_controls[mix_index].tlv.p =
1369 			pcmdev_gain_ctl_info[id][ctl_id].gain;
1370 		pcmdev_ctrl = devm_kmemdup(pcm_dev->dev,
1371 			&pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl[chn - 1],
1372 			sizeof(*pcmdev_ctrl), GFP_KERNEL);
1373 		if (!pcmdev_ctrl) {
1374 			ret = -ENOMEM;
1375 			goto out;
1376 		}
1377 		pcmdev_ctrl->dev_no = dev_no;
1378 		pcmdev_controls[mix_index].private_value =
1379 			(unsigned long)pcmdev_ctrl;
1380 		pcmdev_controls[mix_index].name = name;
1381 		pcmdev_controls[mix_index].access =
1382 			SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1383 			SNDRV_CTL_ELEM_ACCESS_READWRITE;
1384 		pcmdev_controls[mix_index].iface =
1385 			SNDRV_CTL_ELEM_IFACE_MIXER;
1386 		pcmdev_controls[mix_index].info = pcmdevice_info_volsw;
1387 		pcmdev_controls[mix_index].get =
1388 			pcmdev_gain_ctl_info[id][ctl_id].get;
1389 		pcmdev_controls[mix_index].put =
1390 			pcmdev_gain_ctl_info[id][ctl_id].put;
1391 		mix_index++;
1392 	}
1393 
1394 	ret = snd_soc_add_component_controls(comp, pcmdev_controls, mix_index);
1395 	if (ret)
1396 		dev_err(pcm_dev->dev, "%s: add_controls err = %d\n",
1397 			__func__, ret);
1398 out:
1399 	return ret;
1400 }
1401 
1402 static int pcmdev_profile_ctrl_add(struct pcmdevice_priv *pcm_dev)
1403 {
1404 	struct snd_soc_component *comp = pcm_dev->component;
1405 	struct i2c_adapter *adap = pcm_dev->client->adapter;
1406 	struct snd_kcontrol_new *pcmdev_ctrl;
1407 	char *name;
1408 	int ret;
1409 
1410 	pcmdev_ctrl = devm_kzalloc(pcm_dev->dev,
1411 		sizeof(struct snd_kcontrol_new), GFP_KERNEL);
1412 	if (!pcmdev_ctrl)
1413 		return -ENOMEM;
1414 
1415 	/* Create a mixer item for selecting the active profile */
1416 	name = devm_kzalloc(pcm_dev->dev, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1417 		GFP_KERNEL);
1418 	if (!name)
1419 		return -ENOMEM;
1420 
1421 	scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1422 		"%s i2c%d Profile id", pcm_dev->upper_dev_name, adap->nr);
1423 	pcmdev_ctrl->name = name;
1424 	pcmdev_ctrl->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1425 	pcmdev_ctrl->info = pcmdevice_info_profile;
1426 	pcmdev_ctrl->get = pcmdevice_get_profile_id;
1427 	pcmdev_ctrl->put = pcmdevice_set_profile_id;
1428 
1429 	ret = snd_soc_add_component_controls(comp, pcmdev_ctrl, 1);
1430 	if (ret)
1431 		dev_err(pcm_dev->dev, "%s: add_controls err = %d\n",
1432 			__func__, ret);
1433 
1434 	return ret;
1435 }
1436 
1437 static void pcmdevice_config_info_remove(void *ctxt)
1438 {
1439 	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *) ctxt;
1440 	struct pcmdevice_regbin *regbin = &(pcm_dev->regbin);
1441 	struct pcmdevice_config_info **cfg_info = regbin->cfg_info;
1442 	int i, j;
1443 
1444 	if (!cfg_info)
1445 		return;
1446 	for (i = 0; i < regbin->ncfgs; i++) {
1447 		if (!cfg_info[i])
1448 			continue;
1449 		for (j = 0; j < (int)cfg_info[i]->real_nblocks; j++) {
1450 			if (!cfg_info[i]->blk_data[j])
1451 				continue;
1452 			kfree(cfg_info[i]->blk_data[j]->regdata);
1453 			kfree(cfg_info[i]->blk_data[j]);
1454 		}
1455 		kfree(cfg_info[i]);
1456 	}
1457 	kfree(cfg_info);
1458 }
1459 
1460 static int pcmdev_regbin_ready(const struct firmware *fmw, void *ctxt)
1461 {
1462 	struct pcmdevice_config_info **cfg_info;
1463 	struct pcmdevice_priv *pcm_dev = ctxt;
1464 	struct pcmdevice_regbin_hdr *fw_hdr;
1465 	struct pcmdevice_regbin *regbin;
1466 	unsigned int total_config_sz = 0;
1467 	int offset = 0, ret = 0, i;
1468 	unsigned char *buf;
1469 
1470 	regbin = &(pcm_dev->regbin);
1471 	fw_hdr = &(regbin->fw_hdr);
1472 	if (!fmw || !fmw->data) {
1473 		dev_err(pcm_dev->dev, "%s: failed to read %s\n",
1474 			__func__, pcm_dev->bin_name);
1475 		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1476 		ret = -EINVAL;
1477 		goto out;
1478 	}
1479 	buf = (unsigned char *)fmw->data;
1480 
1481 	fw_hdr->img_sz = get_unaligned_be32(&buf[offset]);
1482 	offset += 4;
1483 	if (fw_hdr->img_sz != fmw->size) {
1484 		dev_err(pcm_dev->dev, "%s: file size(%d) not match %u",
1485 			__func__, (int)fmw->size, fw_hdr->img_sz);
1486 		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1487 		ret = -EINVAL;
1488 		goto out;
1489 	}
1490 
1491 	fw_hdr->checksum = get_unaligned_be32(&buf[offset]);
1492 	offset += 4;
1493 	fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]);
1494 	if (fw_hdr->binary_version_num < 0x103) {
1495 		dev_err(pcm_dev->dev, "%s: bin version 0x%04x is out of date",
1496 			__func__, fw_hdr->binary_version_num);
1497 		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1498 		ret = -EINVAL;
1499 		goto out;
1500 	}
1501 	offset += 4;
1502 	fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]);
1503 	offset += 8;
1504 	fw_hdr->plat_type = buf[offset];
1505 	offset += 1;
1506 	fw_hdr->dev_family = buf[offset];
1507 	offset += 1;
1508 	fw_hdr->reserve = buf[offset];
1509 	offset += 1;
1510 	fw_hdr->ndev = buf[offset];
1511 	offset += 1;
1512 	if (fw_hdr->ndev != pcm_dev->ndev) {
1513 		dev_err(pcm_dev->dev, "%s: invalid ndev(%u)\n", __func__,
1514 			fw_hdr->ndev);
1515 		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1516 		ret = -EINVAL;
1517 		goto out;
1518 	}
1519 
1520 	if (offset + PCMDEVICE_MAX_REGBIN_DEVICES > fw_hdr->img_sz) {
1521 		dev_err(pcm_dev->dev, "%s: devs out of boundary!\n", __func__);
1522 		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1523 		ret = -EINVAL;
1524 		goto out;
1525 	}
1526 
1527 	for (i = 0; i < PCMDEVICE_MAX_REGBIN_DEVICES; i++, offset++)
1528 		fw_hdr->devs[i] = buf[offset];
1529 
1530 	fw_hdr->nconfig = get_unaligned_be32(&buf[offset]);
1531 	offset += 4;
1532 
1533 	for (i = 0; i < PCMDEVICE_CONFIG_SUM; i++) {
1534 		fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]);
1535 		offset += 4;
1536 		total_config_sz += fw_hdr->config_size[i];
1537 	}
1538 
1539 	if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) {
1540 		dev_err(pcm_dev->dev, "%s: bin file error!\n", __func__);
1541 		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1542 		ret = -EINVAL;
1543 		goto out;
1544 	}
1545 	cfg_info = kzalloc_objs(*cfg_info, fw_hdr->nconfig);
1546 	if (!cfg_info) {
1547 		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1548 		ret = -ENOMEM;
1549 		goto out;
1550 	}
1551 	regbin->cfg_info = cfg_info;
1552 	regbin->ncfgs = 0;
1553 	for (i = 0; i < (int)fw_hdr->nconfig; i++) {
1554 		cfg_info[i] = pcmdevice_add_config(ctxt, &buf[offset],
1555 				fw_hdr->config_size[i], &ret);
1556 		if (ret) {
1557 			/* In case the bin file is partially destroyed. */
1558 			if (regbin->ncfgs == 0)
1559 				pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1560 			break;
1561 		}
1562 		offset += (int)fw_hdr->config_size[i];
1563 		regbin->ncfgs += 1;
1564 	}
1565 
1566 out:
1567 	if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) {
1568 		dev_err(pcm_dev->dev,
1569 			"%s: remove config due to fw load error!\n", __func__);
1570 		pcmdevice_config_info_remove(pcm_dev);
1571 	}
1572 
1573 	return ret;
1574 }
1575 
1576 static int pcmdevice_comp_probe(struct snd_soc_component *comp)
1577 {
1578 	struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(comp);
1579 	struct i2c_adapter *adap = pcm_dev->client->adapter;
1580 	const struct firmware *fw_entry __free(firmware) = NULL;
1581 	int ret, i, j;
1582 
1583 	guard(mutex)(&pcm_dev->codec_lock);
1584 
1585 	pcm_dev->component = comp;
1586 
1587 	for (i = 0; i < pcm_dev->ndev; i++) {
1588 		for (j = 0; j < 2; j++) {
1589 			ret = pcmdev_gain_ctrl_add(pcm_dev, i, j);
1590 			if (ret < 0)
1591 				return ret;
1592 		}
1593 	}
1594 
1595 	if (comp->name_prefix) {
1596 		/* There's name_prefix defined in DTS. Bin file name will be
1597 		 * name_prefix.bin stores the firmware including register
1598 		 * setting and params for different filters inside chips, it
1599 		 * must be copied into firmware folder. The same types of
1600 		 * pcmdevices sitting on the same i2c bus will be aggregated as
1601 		 * one single codec, all of them share the same bin file.
1602 		 */
1603 		scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN,
1604 			"%s.bin", comp->name_prefix);
1605 	} else {
1606 		/* There's NO name_prefix defined in DTS. Bin file name will be
1607 		 * device-name[defined in pcmdevice_i2c_id]-i2c-bus_id
1608 		 * [0,1,...,N]-sum[1,...,4]dev.bin stores the firmware
1609 		 * including register setting and params for different filters
1610 		 * inside chips, it must be copied into firmware folder. The
1611 		 * same types of pcmdevices sitting on the same i2c bus will be
1612 		 * aggregated as one single codec, all of them share the same
1613 		 * bin file.
1614 		 */
1615 		scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN,
1616 			"%s-i2c-%d-%udev.bin", pcm_dev->dev_name, adap->nr,
1617 			pcm_dev->ndev);
1618 	}
1619 
1620 	ret = request_firmware(&fw_entry, pcm_dev->bin_name, pcm_dev->dev);
1621 	if (ret) {
1622 		dev_err(pcm_dev->dev, "%s: request %s err = %d\n", __func__,
1623 			pcm_dev->bin_name, ret);
1624 		return ret;
1625 	}
1626 
1627 	ret = pcmdev_regbin_ready(fw_entry, pcm_dev);
1628 	if (ret) {
1629 		dev_err(pcm_dev->dev, "%s: %s parse err = %d\n", __func__,
1630 			pcm_dev->bin_name, ret);
1631 		return ret;
1632 	}
1633 
1634 	return pcmdev_profile_ctrl_add(pcm_dev);
1635 }
1636 
1637 
1638 static void pcmdevice_comp_remove(struct snd_soc_component *codec)
1639 {
1640 	struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec);
1641 
1642 	if (!pcm_dev)
1643 		return;
1644 	guard(mutex)(&pcm_dev->codec_lock);
1645 	pcmdevice_config_info_remove(pcm_dev);
1646 }
1647 
1648 static const struct snd_soc_dapm_widget pcmdevice_dapm_widgets[] = {
1649 	SND_SOC_DAPM_AIF_IN("ASI", "ASI Playback", 0, SND_SOC_NOPM, 0, 0),
1650 	SND_SOC_DAPM_AIF_OUT("ASI1 OUT", "ASI1 Capture",
1651 		0, SND_SOC_NOPM, 0, 0),
1652 	SND_SOC_DAPM_OUTPUT("OUT"),
1653 	SND_SOC_DAPM_INPUT("MIC"),
1654 };
1655 
1656 static const struct snd_soc_dapm_route pcmdevice_audio_map[] = {
1657 	{"OUT", NULL, "ASI"},
1658 	{"ASI1 OUT", NULL, "MIC"},
1659 };
1660 
1661 static const struct snd_soc_component_driver
1662 	soc_codec_driver_pcmdevice = {
1663 	.probe			= pcmdevice_comp_probe,
1664 	.remove			= pcmdevice_comp_remove,
1665 	.dapm_widgets		= pcmdevice_dapm_widgets,
1666 	.num_dapm_widgets	= ARRAY_SIZE(pcmdevice_dapm_widgets),
1667 	.dapm_routes		= pcmdevice_audio_map,
1668 	.num_dapm_routes	= ARRAY_SIZE(pcmdevice_audio_map),
1669 	.suspend_bias_off	= 1,
1670 	.idle_bias_on		= 0,
1671 	.use_pmdown_time	= 1,
1672 	.endianness		= 1,
1673 };
1674 
1675 static int pcmdev_single_byte_wr(struct pcmdevice_priv *pcm_dev,
1676 	unsigned char *data, int devn, int sublocksize)
1677 {
1678 	unsigned short len = get_unaligned_be16(&data[2]);
1679 	int offset = 2;
1680 	int i, ret;
1681 
1682 	offset += 2;
1683 	if (offset + 4 * len > sublocksize) {
1684 		dev_err(pcm_dev->dev, "%s: dev-%d byt wr out of boundary\n",
1685 			__func__, devn);
1686 		return -EINVAL;
1687 	}
1688 
1689 	for (i = 0; i < len; i++) {
1690 		ret = pcmdev_dev_write(pcm_dev, devn,
1691 			PCMDEVICE_REG(data[offset + 1], data[offset + 2]),
1692 			data[offset + 3]);
1693 		/* skip this error for next operation or next devices */
1694 		if (ret < 0)
1695 			dev_err(pcm_dev->dev, "%s: dev-%d single write err\n",
1696 				__func__, devn);
1697 
1698 		offset += 4;
1699 	}
1700 
1701 	return offset;
1702 }
1703 
1704 static int pcmdev_burst_wr(struct pcmdevice_priv *pcm_dev,
1705 	unsigned char *data, int devn, int sublocksize)
1706 {
1707 	unsigned short len = get_unaligned_be16(&data[2]);
1708 	int offset = 2;
1709 	int ret;
1710 
1711 	offset += 2;
1712 	if (offset + 4 + len > sublocksize) {
1713 		dev_err(pcm_dev->dev, "%s: dev-%d burst Out of boundary\n",
1714 			__func__, devn);
1715 		return -EINVAL;
1716 	}
1717 	if (len % 4) {
1718 		dev_err(pcm_dev->dev, "%s: dev-%d bst-len(%u) not div by 4\n",
1719 			__func__, devn, len);
1720 		return -EINVAL;
1721 	}
1722 	ret = pcmdev_dev_bulk_write(pcm_dev, devn,
1723 		PCMDEVICE_REG(data[offset + 1], data[offset + 2]),
1724 		&(data[offset + 4]), len);
1725 	/* skip this error for next devices */
1726 	if (ret < 0)
1727 		dev_err(pcm_dev->dev, "%s: dev-%d bulk_write err = %d\n",
1728 			__func__, devn, ret);
1729 
1730 	offset += (len + 4);
1731 
1732 	return offset;
1733 }
1734 
1735 static int pcmdev_delay(struct pcmdevice_priv *pcm_dev,
1736 	unsigned char *data, int devn, int sublocksize)
1737 {
1738 	unsigned int delay_time = 0;
1739 	int offset = 2;
1740 
1741 	if (offset + 2 > sublocksize) {
1742 		dev_err(pcm_dev->dev, "%s: dev-%d delay out of boundary\n",
1743 			__func__, devn);
1744 		return -EINVAL;
1745 	}
1746 	delay_time = get_unaligned_be16(&data[2]) * 1000;
1747 	usleep_range(delay_time, delay_time + 50);
1748 	offset += 2;
1749 
1750 	return offset;
1751 }
1752 
1753 static int pcmdev_bits_wr(struct pcmdevice_priv *pcm_dev,
1754 	unsigned char *data, int devn, int sublocksize)
1755 {
1756 	int offset = 2;
1757 	int ret;
1758 
1759 	if (offset + 6 > sublocksize) {
1760 		dev_err(pcm_dev->dev, "%s: dev-%d bit write out of memory\n",
1761 			__func__, devn);
1762 		return -EINVAL;
1763 	}
1764 	ret = pcmdev_dev_update_bits(pcm_dev, devn,
1765 		PCMDEVICE_REG(data[offset + 3], data[offset + 4]),
1766 		data[offset + 1], data[offset + 5]);
1767 	/* skip this error for next devices */
1768 	if (ret < 0)
1769 		dev_err(pcm_dev->dev, "%s: dev-%d update_bits err = %d\n",
1770 			__func__, devn, ret);
1771 
1772 	offset += 6;
1773 
1774 	return offset;
1775 }
1776 
1777 static int pcmdevice_process_block(void *ctxt, unsigned char *data,
1778 	unsigned char dev_idx, int sublocksize)
1779 {
1780 	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1781 	int devn, dev_end, ret = 0;
1782 	unsigned char subblk_typ = data[1];
1783 
1784 	if (dev_idx) {
1785 		devn = dev_idx - 1;
1786 		dev_end = dev_idx;
1787 	} else {
1788 		devn = 0;
1789 		dev_end = pcm_dev->ndev;
1790 	}
1791 
1792 	/* loop in case of several devices sharing the same sub-block */
1793 	for (; devn < dev_end; devn++) {
1794 		switch (subblk_typ) {
1795 		case PCMDEVICE_CMD_SING_W:
1796 		ret = pcmdev_single_byte_wr(pcm_dev, data, devn, sublocksize);
1797 			break;
1798 		case PCMDEVICE_CMD_BURST:
1799 		ret = pcmdev_burst_wr(pcm_dev, data, devn, sublocksize);
1800 			break;
1801 		case PCMDEVICE_CMD_DELAY:
1802 		ret = pcmdev_delay(pcm_dev, data, devn, sublocksize);
1803 			break;
1804 		case PCMDEVICE_CMD_FIELD_W:
1805 		ret = pcmdev_bits_wr(pcm_dev, data, devn, sublocksize);
1806 			break;
1807 		default:
1808 			break;
1809 		}
1810 		/*
1811 		 * In case of sub-block error, break the loop for the rest of
1812 		 * devices.
1813 		 */
1814 		if (ret < 0)
1815 			break;
1816 	}
1817 
1818 	return ret;
1819 }
1820 
1821 static void pcmdevice_select_cfg_blk(void *ctxt, int conf_no,
1822 	unsigned char block_type)
1823 {
1824 	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1825 	struct pcmdevice_regbin *regbin = &(pcm_dev->regbin);
1826 	struct pcmdevice_config_info **cfg_info = regbin->cfg_info;
1827 	struct pcmdevice_block_data **blk_data;
1828 	int j, k;
1829 
1830 	if (conf_no >= regbin->ncfgs || conf_no < 0 || NULL == cfg_info) {
1831 		dev_err(pcm_dev->dev, "%s: conf_no should be less than %u\n",
1832 			__func__, regbin->ncfgs);
1833 		goto out;
1834 	}
1835 	blk_data = cfg_info[conf_no]->blk_data;
1836 
1837 	for (j = 0; j < (int)cfg_info[conf_no]->real_nblocks; j++) {
1838 		unsigned int length = 0, ret;
1839 
1840 		if (block_type > 5 || block_type < 2) {
1841 			dev_err(pcm_dev->dev,
1842 				"%s: block_type should be out of range\n",
1843 				__func__);
1844 			goto out;
1845 		}
1846 		if (block_type != blk_data[j]->block_type)
1847 			continue;
1848 
1849 		for (k = 0; k < (int)blk_data[j]->n_subblks; k++) {
1850 			ret = pcmdevice_process_block(pcm_dev,
1851 				blk_data[j]->regdata + length,
1852 				blk_data[j]->dev_idx,
1853 				blk_data[j]->block_size - length);
1854 			length += ret;
1855 			if (blk_data[j]->block_size < length) {
1856 				dev_err(pcm_dev->dev,
1857 					"%s: %u %u out of boundary\n",
1858 					__func__, length,
1859 					blk_data[j]->block_size);
1860 				break;
1861 			}
1862 		}
1863 		if (length != blk_data[j]->block_size)
1864 			dev_err(pcm_dev->dev, "%s: %u %u size is not same\n",
1865 				__func__, length, blk_data[j]->block_size);
1866 	}
1867 
1868 out:
1869 	return;
1870 }
1871 
1872 static int pcmdevice_mute(struct snd_soc_dai *dai, int mute, int stream)
1873 {
1874 	struct snd_soc_component *codec = dai->component;
1875 	struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec);
1876 	unsigned char block_type;
1877 
1878 	if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) {
1879 		dev_err(pcm_dev->dev, "%s: bin file not loaded\n", __func__);
1880 		return -EINVAL;
1881 	}
1882 
1883 	if (mute)
1884 		block_type = PCMDEVICE_BIN_BLK_PRE_SHUTDOWN;
1885 	else
1886 		block_type = PCMDEVICE_BIN_BLK_PRE_POWER_UP;
1887 
1888 	guard(mutex)(&pcm_dev->codec_lock);
1889 	pcmdevice_select_cfg_blk(pcm_dev, pcm_dev->cur_conf, block_type);
1890 
1891 	return 0;
1892 }
1893 
1894 static int pcmdevice_hw_params(struct snd_pcm_substream *substream,
1895 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1896 {
1897 	struct pcmdevice_priv *pcm_dev = snd_soc_dai_get_drvdata(dai);
1898 	unsigned int fsrate;
1899 	unsigned int slot_width;
1900 	int bclk_rate;
1901 	int ret = 0;
1902 
1903 	fsrate = params_rate(params);
1904 	switch (fsrate) {
1905 	case 48000:
1906 		break;
1907 	case 44100:
1908 		break;
1909 	default:
1910 		dev_err(pcm_dev->dev, "%s: incorrect sample rate = %u\n",
1911 			__func__, fsrate);
1912 		ret = -EINVAL;
1913 		goto out;
1914 	}
1915 
1916 	slot_width = params_width(params);
1917 	switch (slot_width) {
1918 	case 16:
1919 		break;
1920 	case 20:
1921 		break;
1922 	case 24:
1923 		break;
1924 	case 32:
1925 		break;
1926 	default:
1927 		dev_err(pcm_dev->dev, "%s: incorrect slot width = %u\n",
1928 			__func__, slot_width);
1929 		ret = -EINVAL;
1930 		goto out;
1931 	}
1932 
1933 	bclk_rate = snd_soc_params_to_bclk(params);
1934 	if (bclk_rate < 0) {
1935 		dev_err(pcm_dev->dev, "%s: incorrect bclk rate = %d\n",
1936 			__func__, bclk_rate);
1937 		ret = bclk_rate;
1938 	}
1939 
1940 out:
1941 	return ret;
1942 }
1943 
1944 static const struct snd_soc_dai_ops pcmdevice_dai_ops = {
1945 	.mute_stream = pcmdevice_mute,
1946 	.hw_params = pcmdevice_hw_params,
1947 };
1948 
1949 static struct snd_soc_dai_driver pcmdevice_dai_driver[] = {
1950 	{
1951 		.name = "pcmdevice-codec",
1952 		.capture = {
1953 			.stream_name	 = "Capture",
1954 			.channels_min	 = 2,
1955 			.channels_max	 = PCMDEVICE_MAX_CHANNELS,
1956 			.rates		 = PCMDEVICE_RATES,
1957 			.formats	 = PCMDEVICE_FORMATS,
1958 		},
1959 		.playback = {
1960 			.stream_name	 = "Playback",
1961 			.channels_min	 = 2,
1962 			.channels_max	 = PCMDEVICE_MAX_CHANNELS,
1963 			.rates		 = PCMDEVICE_RATES,
1964 			.formats	 = PCMDEVICE_FORMATS,
1965 		},
1966 		.ops = &pcmdevice_dai_ops,
1967 		.symmetric_rate = 1,
1968 	}
1969 };
1970 
1971 #ifdef CONFIG_OF
1972 static const struct of_device_id pcmdevice_of_match[] = {
1973 	{ .compatible = "ti,adc3120"  },
1974 	{ .compatible = "ti,adc5120"  },
1975 	{ .compatible = "ti,adc6120"  },
1976 	{ .compatible = "ti,dix4192"  },
1977 	{ .compatible = "ti,pcm1690"  },
1978 	{ .compatible = "ti,pcm3120"  },
1979 	{ .compatible = "ti,pcm3140"  },
1980 	{ .compatible = "ti,pcm5120"  },
1981 	{ .compatible = "ti,pcm5140"  },
1982 	{ .compatible = "ti,pcm6120"  },
1983 	{ .compatible = "ti,pcm6140"  },
1984 	{ .compatible = "ti,pcm6240"  },
1985 	{ .compatible = "ti,pcm6260"  },
1986 	{ .compatible = "ti,pcm9211"  },
1987 	{ .compatible = "ti,pcmd3140" },
1988 	{ .compatible = "ti,pcmd3180" },
1989 	{ .compatible = "ti,pcmd512x" },
1990 	{ .compatible = "ti,taa5212"  },
1991 	{ .compatible = "ti,taa5412"  },
1992 	{ .compatible = "ti,tad5212"  },
1993 	{ .compatible = "ti,tad5412"  },
1994 	{},
1995 };
1996 MODULE_DEVICE_TABLE(of, pcmdevice_of_match);
1997 #endif
1998 
1999 static const struct regmap_range_cfg pcmdevice_ranges[] = {
2000 	{
2001 		.range_min = 0,
2002 		.range_max = 256 * 128,
2003 		.selector_reg = PCMDEVICE_PAGE_SELECT,
2004 		.selector_mask = 0xff,
2005 		.selector_shift = 0,
2006 		.window_start = 0,
2007 		.window_len = 128,
2008 	},
2009 };
2010 
2011 static const struct regmap_config pcmdevice_i2c_regmap = {
2012 	.reg_bits = 8,
2013 	.val_bits = 8,
2014 	.cache_type = REGCACHE_MAPLE,
2015 	.ranges = pcmdevice_ranges,
2016 	.num_ranges = ARRAY_SIZE(pcmdevice_ranges),
2017 	.max_register = 256 * 128,
2018 };
2019 
2020 static void pcmdevice_remove(struct pcmdevice_priv *pcm_dev)
2021 {
2022 	if (pcm_dev->irq)
2023 		free_irq(pcm_dev->irq, pcm_dev);
2024 	mutex_destroy(&pcm_dev->codec_lock);
2025 }
2026 
2027 static char *str_to_upper(char *str)
2028 {
2029 	char *orig = str;
2030 
2031 	if (!str)
2032 		return NULL;
2033 
2034 	while (*str) {
2035 		*str = toupper(*str);
2036 		str++;
2037 	}
2038 
2039 	return orig;
2040 }
2041 
2042 static int pcmdevice_i2c_probe(struct i2c_client *i2c)
2043 {
2044 	struct pcmdevice_priv *pcm_dev;
2045 	struct device_node *np;
2046 	unsigned int dev_addrs[PCMDEVICE_MAX_I2C_DEVICES];
2047 	int ret = 0, i = 0, ndev = 0;
2048 
2049 	pcm_dev = devm_kzalloc(&i2c->dev, sizeof(*pcm_dev), GFP_KERNEL);
2050 	if (!pcm_dev)
2051 		return -ENOMEM;
2052 
2053 	pcm_dev->chip_id = (uintptr_t)i2c_get_match_data(i2c);
2054 
2055 	pcm_dev->dev = &i2c->dev;
2056 	pcm_dev->client = i2c;
2057 
2058 	if (pcm_dev->chip_id >= MAX_DEVICE)
2059 		pcm_dev->chip_id = 0;
2060 
2061 	strscpy(pcm_dev->dev_name, pcmdevice_i2c_id[pcm_dev->chip_id].name,
2062 		sizeof(pcm_dev->dev_name));
2063 
2064 	strscpy(pcm_dev->upper_dev_name,
2065 		pcmdevice_i2c_id[pcm_dev->chip_id].name,
2066 		sizeof(pcm_dev->upper_dev_name));
2067 
2068 	str_to_upper(pcm_dev->upper_dev_name);
2069 
2070 	pcm_dev->regmap = devm_regmap_init_i2c(i2c, &pcmdevice_i2c_regmap);
2071 	if (IS_ERR(pcm_dev->regmap)) {
2072 		ret = PTR_ERR(pcm_dev->regmap);
2073 		dev_err(&i2c->dev, "%s: failed to allocate register map: %d\n",
2074 			__func__, ret);
2075 		goto out;
2076 	}
2077 
2078 	i2c_set_clientdata(i2c, pcm_dev);
2079 	mutex_init(&pcm_dev->codec_lock);
2080 	np = pcm_dev->dev->of_node;
2081 
2082 	if (IS_ENABLED(CONFIG_OF)) {
2083 		u64 addr;
2084 
2085 		for (i = 0; i < PCMDEVICE_MAX_I2C_DEVICES; i++) {
2086 			if (of_property_read_reg(np, i, &addr, NULL))
2087 				break;
2088 			dev_addrs[ndev++] = addr;
2089 		}
2090 	} else {
2091 		ndev = 1;
2092 		dev_addrs[0] = i2c->addr;
2093 	}
2094 	pcm_dev->irq = of_irq_get(np, 0);
2095 
2096 	for (i = 0; i < ndev; i++)
2097 		pcm_dev->addr[i] = dev_addrs[i];
2098 
2099 	pcm_dev->ndev = ndev;
2100 
2101 	pcm_dev->hw_rst = devm_gpiod_get_optional(&i2c->dev,
2102 			"reset-gpios", GPIOD_OUT_HIGH);
2103 	/* No reset GPIO, no side-effect */
2104 	if (IS_ERR(pcm_dev->hw_rst)) {
2105 		if (pcm_dev->chip_id == PCM9211 || pcm_dev->chip_id == PCM1690)
2106 			pcm9211_sw_rst(pcm_dev);
2107 		else
2108 			pcmdevice_sw_rst(pcm_dev);
2109 	} else {
2110 		gpiod_set_value_cansleep(pcm_dev->hw_rst, 0);
2111 		usleep_range(500, 1000);
2112 		gpiod_set_value_cansleep(pcm_dev->hw_rst, 1);
2113 	}
2114 
2115 	if (pcm_dev->chip_id == PCM1690)
2116 		goto skip_interrupt;
2117 	if (pcm_dev->irq) {
2118 		dev_dbg(pcm_dev->dev, "irq = %d", pcm_dev->irq);
2119 	} else
2120 		dev_err(pcm_dev->dev, "No irq provided\n");
2121 
2122 skip_interrupt:
2123 	ret = devm_snd_soc_register_component(&i2c->dev,
2124 		&soc_codec_driver_pcmdevice, pcmdevice_dai_driver,
2125 		ARRAY_SIZE(pcmdevice_dai_driver));
2126 	if (ret < 0)
2127 		dev_err(&i2c->dev, "probe register comp failed %d\n", ret);
2128 
2129 out:
2130 	if (ret < 0)
2131 		pcmdevice_remove(pcm_dev);
2132 	return ret;
2133 }
2134 
2135 static void pcmdevice_i2c_remove(struct i2c_client *i2c)
2136 {
2137 	struct pcmdevice_priv *pcm_dev = i2c_get_clientdata(i2c);
2138 
2139 	pcmdevice_remove(pcm_dev);
2140 }
2141 
2142 static struct i2c_driver pcmdevice_i2c_driver = {
2143 	.driver = {
2144 		.name = "pcmdevice-codec",
2145 		.of_match_table = of_match_ptr(pcmdevice_of_match),
2146 	},
2147 	.probe	= pcmdevice_i2c_probe,
2148 	.remove = pcmdevice_i2c_remove,
2149 	.id_table = pcmdevice_i2c_id,
2150 };
2151 module_i2c_driver(pcmdevice_i2c_driver);
2152 
2153 MODULE_AUTHOR("Shenghao Ding <shenghao-ding@ti.com>");
2154 MODULE_DESCRIPTION("ASoC PCM6240 Family Audio ADC/DAC Driver");
2155 MODULE_LICENSE("GPL");
2156