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