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
pcmdev_change_dev(struct pcmdevice_priv * pcm_priv,unsigned short dev_no)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
pcmdev_dev_read(struct pcmdevice_priv * pcm_dev,unsigned int dev_no,unsigned int reg,unsigned int * val)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
pcmdev_dev_update_bits(struct pcmdevice_priv * pcm_dev,unsigned int dev_no,unsigned int reg,unsigned int mask,unsigned int value)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
pcmdev_get_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol,int vol_ctrl_type)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
pcmdevice_get_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcm1690_get_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcm1690_get_finevolsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcmdev_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol,int vol_ctrl_type)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
pcmdevice_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcm1690_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcm1690_put_finevolsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcmdev_dev_bulk_write(struct pcmdevice_priv * pcm_dev,unsigned int dev_no,unsigned int reg,unsigned char * data,unsigned int len)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
pcmdev_dev_write(struct pcmdevice_priv * pcm_dev,unsigned int dev_no,unsigned int reg,unsigned int value)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
pcmdevice_info_profile(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)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
pcmdevice_get_profile_id(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcmdevice_set_profile_id(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcmdevice_info_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)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
pcm9211_sw_rst(struct pcmdevice_priv * pcm_dev)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
pcmdevice_sw_rst(struct pcmdevice_priv * pcm_dev)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
pcmdevice_add_config(void * ctxt,const unsigned char * config_data,unsigned int config_size,int * status)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
pcmdev_gain_ctrl_add(struct pcmdevice_priv * pcm_dev,int dev_no,int ctl_id)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
pcmdev_profile_ctrl_add(struct pcmdevice_priv * pcm_dev)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
pcmdevice_config_info_remove(void * ctxt)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
pcmdev_regbin_ready(const struct firmware * fmw,void * ctxt)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
pcmdevice_comp_probe(struct snd_soc_component * comp)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
pcmdevice_comp_remove(struct snd_soc_component * codec)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
pcmdev_single_byte_wr(struct pcmdevice_priv * pcm_dev,unsigned char * data,int devn,int sublocksize)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
pcmdev_burst_wr(struct pcmdevice_priv * pcm_dev,unsigned char * data,int devn,int sublocksize)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
pcmdev_delay(struct pcmdevice_priv * pcm_dev,unsigned char * data,int devn,int sublocksize)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
pcmdev_bits_wr(struct pcmdevice_priv * pcm_dev,unsigned char * data,int devn,int sublocksize)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
pcmdevice_process_block(void * ctxt,unsigned char * data,unsigned char dev_idx,int sublocksize)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
pcmdevice_select_cfg_blk(void * ctxt,int conf_no,unsigned char block_type)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
pcmdevice_mute(struct snd_soc_dai * dai,int mute,int stream)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
pcmdevice_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)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
pcmdevice_remove(struct pcmdevice_priv * pcm_dev)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
str_to_upper(char * str)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
pcmdevice_i2c_probe(struct i2c_client * i2c)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
pcmdevice_i2c_remove(struct i2c_client * i2c)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