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