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/consumer.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
pcmdev_change_dev(struct pcmdevice_priv * pcm_priv,unsigned short dev_no)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
pcmdev_dev_read(struct pcmdevice_priv * pcm_dev,unsigned int dev_no,unsigned int reg,unsigned int * val)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
pcmdev_dev_update_bits(struct pcmdevice_priv * pcm_dev,unsigned int dev_no,unsigned int reg,unsigned int mask,unsigned int value)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
pcmdev_get_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol,int vol_ctrl_type)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
pcmdevice_get_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcm1690_get_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcm1690_get_finevolsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcmdev_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol,int vol_ctrl_type)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
pcmdevice_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcm1690_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcm1690_put_finevolsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)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
pcmdev_dev_bulk_write(struct pcmdevice_priv * pcm_dev,unsigned int dev_no,unsigned int reg,unsigned char * data,unsigned int len)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
pcmdev_dev_write(struct pcmdevice_priv * pcm_dev,unsigned int dev_no,unsigned int reg,unsigned int value)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
pcmdevice_info_profile(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1138 static int pcmdevice_info_profile(
1139 struct snd_kcontrol *kcontrol,
1140 struct snd_ctl_elem_info *uinfo)
1141 {
1142 struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
1143 struct pcmdevice_priv *pcm_dev =
1144 snd_soc_component_get_drvdata(codec);
1145
1146 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1147 uinfo->count = 1;
1148 uinfo->value.integer.min = 0;
1149 uinfo->value.integer.max = max(0, pcm_dev->regbin.ncfgs - 1);
1150
1151 return 0;
1152 }
1153
pcmdevice_get_profile_id(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1154 static int pcmdevice_get_profile_id(
1155 struct snd_kcontrol *kcontrol,
1156 struct snd_ctl_elem_value *ucontrol)
1157 {
1158 struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
1159 struct pcmdevice_priv *pcm_dev =
1160 snd_soc_component_get_drvdata(codec);
1161
1162 ucontrol->value.integer.value[0] = pcm_dev->cur_conf;
1163
1164 return 0;
1165 }
1166
pcmdevice_set_profile_id(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1167 static int pcmdevice_set_profile_id(
1168 struct snd_kcontrol *kcontrol,
1169 struct snd_ctl_elem_value *ucontrol)
1170 {
1171 struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
1172 struct pcmdevice_priv *pcm_dev =
1173 snd_soc_component_get_drvdata(codec);
1174 int nr_profile = ucontrol->value.integer.value[0];
1175 int max = pcm_dev->regbin.ncfgs - 1;
1176 int ret = 0;
1177
1178 nr_profile = clamp(nr_profile, 0, max);
1179
1180 if (pcm_dev->cur_conf != nr_profile) {
1181 pcm_dev->cur_conf = nr_profile;
1182 ret = 1;
1183 }
1184
1185 return ret;
1186 }
1187
pcmdevice_info_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1188 static int pcmdevice_info_volsw(struct snd_kcontrol *kcontrol,
1189 struct snd_ctl_elem_info *uinfo)
1190 {
1191 struct pcmdevice_mixer_control *mc =
1192 (struct pcmdevice_mixer_control *)kcontrol->private_value;
1193
1194 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1195 uinfo->count = 1;
1196 uinfo->value.integer.min = 0;
1197 uinfo->value.integer.max = mc->max;
1198 return 0;
1199 }
1200
pcm9211_sw_rst(struct pcmdevice_priv * pcm_dev)1201 static void pcm9211_sw_rst(struct pcmdevice_priv *pcm_dev)
1202 {
1203 int ret, i;
1204
1205 for (i = 0; i < pcm_dev->ndev; i++) {
1206 ret = pcmdev_dev_update_bits(pcm_dev, i,
1207 PCM9211_REG_SW_CTRL, PCM9211_REG_SW_CTRL_MRST_MSK,
1208 PCM9211_REG_SW_CTRL_MRST);
1209 if (ret < 0)
1210 dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n",
1211 __func__, i, ret);
1212 }
1213 }
1214
pcmdevice_sw_rst(struct pcmdevice_priv * pcm_dev)1215 static void pcmdevice_sw_rst(struct pcmdevice_priv *pcm_dev)
1216 {
1217 int ret, i;
1218
1219 for (i = 0; i < pcm_dev->ndev; i++) {
1220 ret = pcmdev_dev_write(pcm_dev, i, PCMDEVICE_REG_SWRESET,
1221 PCMDEVICE_REG_SWRESET_RESET);
1222 if (ret < 0)
1223 dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n",
1224 __func__, i, ret);
1225 }
1226 }
1227
pcmdevice_add_config(void * ctxt,const unsigned char * config_data,unsigned int config_size,int * status)1228 static struct pcmdevice_config_info *pcmdevice_add_config(void *ctxt,
1229 const unsigned char *config_data, unsigned int config_size,
1230 int *status)
1231 {
1232 struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1233 struct pcmdevice_config_info *cfg_info;
1234 struct pcmdevice_block_data **bk_da;
1235 unsigned int config_offset = 0, i;
1236
1237 cfg_info = kzalloc_obj(struct pcmdevice_config_info);
1238 if (!cfg_info) {
1239 *status = -ENOMEM;
1240 goto out;
1241 }
1242
1243 if (pcm_dev->regbin.fw_hdr.binary_version_num >= 0x105) {
1244 if (config_offset + 64 > (int)config_size) {
1245 *status = -EINVAL;
1246 dev_err(pcm_dev->dev,
1247 "%s: cfg_name out of boundary\n", __func__);
1248 goto out;
1249 }
1250 memcpy(cfg_info->cfg_name, &config_data[config_offset], 64);
1251 config_offset += 64;
1252 }
1253
1254 if (config_offset + 4 > config_size) {
1255 *status = -EINVAL;
1256 dev_err(pcm_dev->dev, "%s: nblocks out of boundary\n",
1257 __func__);
1258 goto out;
1259 }
1260 cfg_info->nblocks =
1261 get_unaligned_be32(&config_data[config_offset]);
1262 config_offset += 4;
1263
1264 bk_da = cfg_info->blk_data = kzalloc_objs(struct pcmdevice_block_data *,
1265 cfg_info->nblocks);
1266 if (!bk_da) {
1267 *status = -ENOMEM;
1268 goto out;
1269 }
1270 cfg_info->real_nblocks = 0;
1271 for (i = 0; i < cfg_info->nblocks; i++) {
1272 if (config_offset + 12 > config_size) {
1273 *status = -EINVAL;
1274 dev_err(pcm_dev->dev,
1275 "%s: out of boundary i = %d nblocks = %u\n",
1276 __func__, i, cfg_info->nblocks);
1277 break;
1278 }
1279 bk_da[i] = kzalloc_obj(struct pcmdevice_block_data);
1280 if (!bk_da[i]) {
1281 *status = -ENOMEM;
1282 break;
1283 }
1284 bk_da[i]->dev_idx = config_data[config_offset];
1285 config_offset++;
1286
1287 bk_da[i]->block_type = config_data[config_offset];
1288 config_offset++;
1289
1290 if (bk_da[i]->block_type == PCMDEVICE_BIN_BLK_PRE_POWER_UP) {
1291 if (bk_da[i]->dev_idx == 0)
1292 cfg_info->active_dev =
1293 (1 << pcm_dev->ndev) - 1;
1294 else
1295 cfg_info->active_dev =
1296 1 << (bk_da[i]->dev_idx - 1);
1297 }
1298
1299 bk_da[i]->yram_checksum =
1300 get_unaligned_be16(&config_data[config_offset]);
1301 config_offset += 2;
1302 bk_da[i]->block_size =
1303 get_unaligned_be32(&config_data[config_offset]);
1304 config_offset += 4;
1305
1306 bk_da[i]->n_subblks =
1307 get_unaligned_be32(&config_data[config_offset]);
1308
1309 config_offset += 4;
1310
1311 if (config_offset + bk_da[i]->block_size > config_size) {
1312 *status = -EINVAL;
1313 dev_err(pcm_dev->dev,
1314 "%s: out of boundary: i = %d blks = %u\n",
1315 __func__, i, cfg_info->nblocks);
1316 break;
1317 }
1318
1319 bk_da[i]->regdata = kmemdup(&config_data[config_offset],
1320 bk_da[i]->block_size, GFP_KERNEL);
1321 if (!bk_da[i]->regdata) {
1322 *status = -ENOMEM;
1323 goto out;
1324 }
1325 config_offset += bk_da[i]->block_size;
1326 cfg_info->real_nblocks += 1;
1327 }
1328 out:
1329 return cfg_info;
1330 }
1331
pcmdev_gain_ctrl_add(struct pcmdevice_priv * pcm_dev,int dev_no,int ctl_id)1332 static int pcmdev_gain_ctrl_add(struct pcmdevice_priv *pcm_dev,
1333 int dev_no, int ctl_id)
1334 {
1335 struct i2c_adapter *adap = pcm_dev->client->adapter;
1336 struct snd_soc_component *comp = pcm_dev->component;
1337 struct pcmdevice_mixer_control *pcmdev_ctrl;
1338 struct snd_kcontrol_new *pcmdev_controls;
1339 int ret, mix_index = 0, name_id, chn;
1340 unsigned int id = pcm_dev->chip_id;
1341 const int nr_chn =
1342 pcmdev_gain_ctl_info[id][ctl_id].ctrl_array_size;
1343 const char *ctrl_name;
1344 char *name;
1345
1346 if (!nr_chn) {
1347 dev_dbg(pcm_dev->dev, "%s: no gain ctrl for %s\n", __func__,
1348 pcm_dev->dev_name);
1349 return 0;
1350 }
1351
1352 pcmdev_controls = devm_kcalloc(pcm_dev->dev, nr_chn,
1353 sizeof(struct snd_kcontrol_new), GFP_KERNEL);
1354 if (!pcmdev_controls)
1355 return -ENOMEM;
1356
1357 name_id = pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl_name_id;
1358
1359 ctrl_name = pcmdev_ctrl_name[name_id];
1360
1361 for (chn = 1; chn <= nr_chn; chn++) {
1362 name = devm_kzalloc(pcm_dev->dev,
1363 SNDRV_CTL_ELEM_ID_NAME_MAXLEN, GFP_KERNEL);
1364 if (!name) {
1365 ret = -ENOMEM;
1366 goto out;
1367 }
1368 scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1369 ctrl_name, pcm_dev->upper_dev_name, adap->nr,
1370 dev_no, chn);
1371 pcmdev_controls[mix_index].tlv.p =
1372 pcmdev_gain_ctl_info[id][ctl_id].gain;
1373 pcmdev_ctrl = devm_kmemdup(pcm_dev->dev,
1374 &pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl[chn - 1],
1375 sizeof(*pcmdev_ctrl), GFP_KERNEL);
1376 if (!pcmdev_ctrl) {
1377 ret = -ENOMEM;
1378 goto out;
1379 }
1380 pcmdev_ctrl->dev_no = dev_no;
1381 pcmdev_controls[mix_index].private_value =
1382 (unsigned long)pcmdev_ctrl;
1383 pcmdev_controls[mix_index].name = name;
1384 pcmdev_controls[mix_index].access =
1385 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1386 SNDRV_CTL_ELEM_ACCESS_READWRITE;
1387 pcmdev_controls[mix_index].iface =
1388 SNDRV_CTL_ELEM_IFACE_MIXER;
1389 pcmdev_controls[mix_index].info = pcmdevice_info_volsw;
1390 pcmdev_controls[mix_index].get =
1391 pcmdev_gain_ctl_info[id][ctl_id].get;
1392 pcmdev_controls[mix_index].put =
1393 pcmdev_gain_ctl_info[id][ctl_id].put;
1394 mix_index++;
1395 }
1396
1397 ret = snd_soc_add_component_controls(comp, pcmdev_controls, mix_index);
1398 if (ret)
1399 dev_err(pcm_dev->dev, "%s: add_controls err = %d\n",
1400 __func__, ret);
1401 out:
1402 return ret;
1403 }
1404
pcmdev_profile_ctrl_add(struct pcmdevice_priv * pcm_dev)1405 static int pcmdev_profile_ctrl_add(struct pcmdevice_priv *pcm_dev)
1406 {
1407 struct snd_soc_component *comp = pcm_dev->component;
1408 struct i2c_adapter *adap = pcm_dev->client->adapter;
1409 struct snd_kcontrol_new *pcmdev_ctrl;
1410 char *name;
1411 int ret;
1412
1413 pcmdev_ctrl = devm_kzalloc(pcm_dev->dev,
1414 sizeof(struct snd_kcontrol_new), GFP_KERNEL);
1415 if (!pcmdev_ctrl)
1416 return -ENOMEM;
1417
1418 /* Create a mixer item for selecting the active profile */
1419 name = devm_kzalloc(pcm_dev->dev, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1420 GFP_KERNEL);
1421 if (!name)
1422 return -ENOMEM;
1423
1424 scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1425 "%s i2c%d Profile id", pcm_dev->upper_dev_name, adap->nr);
1426 pcmdev_ctrl->name = name;
1427 pcmdev_ctrl->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1428 pcmdev_ctrl->info = pcmdevice_info_profile;
1429 pcmdev_ctrl->get = pcmdevice_get_profile_id;
1430 pcmdev_ctrl->put = pcmdevice_set_profile_id;
1431
1432 ret = snd_soc_add_component_controls(comp, pcmdev_ctrl, 1);
1433 if (ret)
1434 dev_err(pcm_dev->dev, "%s: add_controls err = %d\n",
1435 __func__, ret);
1436
1437 return ret;
1438 }
1439
pcmdevice_config_info_remove(void * ctxt)1440 static void pcmdevice_config_info_remove(void *ctxt)
1441 {
1442 struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *) ctxt;
1443 struct pcmdevice_regbin *regbin = &(pcm_dev->regbin);
1444 struct pcmdevice_config_info **cfg_info = regbin->cfg_info;
1445 int i, j;
1446
1447 if (!cfg_info)
1448 return;
1449 for (i = 0; i < regbin->ncfgs; i++) {
1450 if (!cfg_info[i])
1451 continue;
1452 if (cfg_info[i]->blk_data) {
1453 for (j = 0; j < (int)cfg_info[i]->real_nblocks; j++) {
1454 if (!cfg_info[i]->blk_data[j])
1455 continue;
1456 kfree(cfg_info[i]->blk_data[j]->regdata);
1457 kfree(cfg_info[i]->blk_data[j]);
1458 }
1459 kfree(cfg_info[i]->blk_data);
1460 }
1461 kfree(cfg_info[i]);
1462 }
1463 kfree(cfg_info);
1464 }
1465
pcmdev_regbin_ready(const struct firmware * fmw,void * ctxt)1466 static int pcmdev_regbin_ready(const struct firmware *fmw, void *ctxt)
1467 {
1468 struct pcmdevice_config_info **cfg_info;
1469 struct pcmdevice_priv *pcm_dev = ctxt;
1470 struct pcmdevice_regbin_hdr *fw_hdr;
1471 struct pcmdevice_regbin *regbin;
1472 unsigned int total_config_sz = 0;
1473 int offset = 0, ret = 0, i;
1474 unsigned char *buf;
1475
1476 regbin = &(pcm_dev->regbin);
1477 fw_hdr = &(regbin->fw_hdr);
1478 if (!fmw || !fmw->data) {
1479 dev_err(pcm_dev->dev, "%s: failed to read %s\n",
1480 __func__, pcm_dev->bin_name);
1481 pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1482 ret = -EINVAL;
1483 goto out;
1484 }
1485 buf = (unsigned char *)fmw->data;
1486
1487 fw_hdr->img_sz = get_unaligned_be32(&buf[offset]);
1488 offset += 4;
1489 if (fw_hdr->img_sz != fmw->size) {
1490 dev_err(pcm_dev->dev, "%s: file size(%d) not match %u",
1491 __func__, (int)fmw->size, fw_hdr->img_sz);
1492 pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1493 ret = -EINVAL;
1494 goto out;
1495 }
1496
1497 fw_hdr->checksum = get_unaligned_be32(&buf[offset]);
1498 offset += 4;
1499 fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]);
1500 if (fw_hdr->binary_version_num < 0x103) {
1501 dev_err(pcm_dev->dev, "%s: bin version 0x%04x is out of date",
1502 __func__, fw_hdr->binary_version_num);
1503 pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1504 ret = -EINVAL;
1505 goto out;
1506 }
1507 offset += 4;
1508 fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]);
1509 offset += 8;
1510 fw_hdr->plat_type = buf[offset];
1511 offset += 1;
1512 fw_hdr->dev_family = buf[offset];
1513 offset += 1;
1514 fw_hdr->reserve = buf[offset];
1515 offset += 1;
1516 fw_hdr->ndev = buf[offset];
1517 offset += 1;
1518 if (fw_hdr->ndev != pcm_dev->ndev) {
1519 dev_err(pcm_dev->dev, "%s: invalid ndev(%u)\n", __func__,
1520 fw_hdr->ndev);
1521 pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1522 ret = -EINVAL;
1523 goto out;
1524 }
1525
1526 if (offset + PCMDEVICE_MAX_REGBIN_DEVICES > fw_hdr->img_sz) {
1527 dev_err(pcm_dev->dev, "%s: devs out of boundary!\n", __func__);
1528 pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1529 ret = -EINVAL;
1530 goto out;
1531 }
1532
1533 for (i = 0; i < PCMDEVICE_MAX_REGBIN_DEVICES; i++, offset++)
1534 fw_hdr->devs[i] = buf[offset];
1535
1536 fw_hdr->nconfig = get_unaligned_be32(&buf[offset]);
1537 offset += 4;
1538
1539 for (i = 0; i < PCMDEVICE_CONFIG_SUM; i++) {
1540 fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]);
1541 offset += 4;
1542 total_config_sz += fw_hdr->config_size[i];
1543 }
1544
1545 if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) {
1546 dev_err(pcm_dev->dev, "%s: bin file error!\n", __func__);
1547 pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1548 ret = -EINVAL;
1549 goto out;
1550 }
1551 cfg_info = kzalloc_objs(*cfg_info, fw_hdr->nconfig);
1552 if (!cfg_info) {
1553 pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1554 ret = -ENOMEM;
1555 goto out;
1556 }
1557 regbin->cfg_info = cfg_info;
1558 regbin->ncfgs = 0;
1559 for (i = 0; i < (int)fw_hdr->nconfig; i++) {
1560 cfg_info[i] = pcmdevice_add_config(ctxt, &buf[offset],
1561 fw_hdr->config_size[i], &ret);
1562 if (ret) {
1563 /* In case the bin file is partially destroyed. */
1564 if (regbin->ncfgs == 0)
1565 pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1566 break;
1567 }
1568 offset += (int)fw_hdr->config_size[i];
1569 regbin->ncfgs += 1;
1570 }
1571
1572 out:
1573 if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) {
1574 dev_err(pcm_dev->dev,
1575 "%s: remove config due to fw load error!\n", __func__);
1576 pcmdevice_config_info_remove(pcm_dev);
1577 }
1578
1579 return ret;
1580 }
1581
pcmdevice_comp_probe(struct snd_soc_component * comp)1582 static int pcmdevice_comp_probe(struct snd_soc_component *comp)
1583 {
1584 struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(comp);
1585 struct i2c_adapter *adap = pcm_dev->client->adapter;
1586 const struct firmware *fw_entry = NULL;
1587 int ret, i, j;
1588
1589 mutex_lock(&pcm_dev->codec_lock);
1590
1591 pcm_dev->component = comp;
1592
1593 for (i = 0; i < pcm_dev->ndev; i++) {
1594 for (j = 0; j < 2; j++) {
1595 ret = pcmdev_gain_ctrl_add(pcm_dev, i, j);
1596 if (ret < 0)
1597 goto out;
1598 }
1599 }
1600
1601 if (comp->name_prefix) {
1602 /* There's name_prefix defined in DTS. Bin file name will be
1603 * name_prefix.bin stores the firmware including register
1604 * setting and params for different filters inside chips, it
1605 * must be copied into firmware folder. The same types of
1606 * pcmdevices sitting on the same i2c bus will be aggregated as
1607 * one single codec, all of them share the same bin file.
1608 */
1609 scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN,
1610 "%s.bin", comp->name_prefix);
1611 } else {
1612 /* There's NO name_prefix defined in DTS. Bin file name will be
1613 * device-name[defined in pcmdevice_i2c_id]-i2c-bus_id
1614 * [0,1,...,N]-sum[1,...,4]dev.bin stores the firmware
1615 * including register setting and params for different filters
1616 * inside chips, it must be copied into firmware folder. The
1617 * same types of pcmdevices sitting on the same i2c bus will be
1618 * aggregated as one single codec, all of them share the same
1619 * bin file.
1620 */
1621 scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN,
1622 "%s-i2c-%d-%udev.bin", pcm_dev->dev_name, adap->nr,
1623 pcm_dev->ndev);
1624 }
1625
1626 ret = request_firmware(&fw_entry, pcm_dev->bin_name, pcm_dev->dev);
1627 if (ret) {
1628 dev_err(pcm_dev->dev, "%s: request %s err = %d\n", __func__,
1629 pcm_dev->bin_name, ret);
1630 goto out;
1631 }
1632
1633 ret = pcmdev_regbin_ready(fw_entry, pcm_dev);
1634 if (ret) {
1635 dev_err(pcm_dev->dev, "%s: %s parse err = %d\n", __func__,
1636 pcm_dev->bin_name, ret);
1637 goto out;
1638 }
1639 ret = pcmdev_profile_ctrl_add(pcm_dev);
1640 out:
1641 release_firmware(fw_entry);
1642
1643 mutex_unlock(&pcm_dev->codec_lock);
1644 return ret;
1645 }
1646
1647
pcmdevice_comp_remove(struct snd_soc_component * codec)1648 static void pcmdevice_comp_remove(struct snd_soc_component *codec)
1649 {
1650 struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec);
1651
1652 if (!pcm_dev)
1653 return;
1654 mutex_lock(&pcm_dev->codec_lock);
1655 pcmdevice_config_info_remove(pcm_dev);
1656 mutex_unlock(&pcm_dev->codec_lock);
1657 }
1658
1659 static const struct snd_soc_dapm_widget pcmdevice_dapm_widgets[] = {
1660 SND_SOC_DAPM_AIF_IN("ASI", "ASI Playback", 0, SND_SOC_NOPM, 0, 0),
1661 SND_SOC_DAPM_AIF_OUT("ASI1 OUT", "ASI1 Capture",
1662 0, SND_SOC_NOPM, 0, 0),
1663 SND_SOC_DAPM_OUTPUT("OUT"),
1664 SND_SOC_DAPM_INPUT("MIC"),
1665 };
1666
1667 static const struct snd_soc_dapm_route pcmdevice_audio_map[] = {
1668 {"OUT", NULL, "ASI"},
1669 {"ASI1 OUT", NULL, "MIC"},
1670 };
1671
1672 static const struct snd_soc_component_driver
1673 soc_codec_driver_pcmdevice = {
1674 .probe = pcmdevice_comp_probe,
1675 .remove = pcmdevice_comp_remove,
1676 .dapm_widgets = pcmdevice_dapm_widgets,
1677 .num_dapm_widgets = ARRAY_SIZE(pcmdevice_dapm_widgets),
1678 .dapm_routes = pcmdevice_audio_map,
1679 .num_dapm_routes = ARRAY_SIZE(pcmdevice_audio_map),
1680 .suspend_bias_off = 1,
1681 .idle_bias_on = 0,
1682 .use_pmdown_time = 1,
1683 .endianness = 1,
1684 };
1685
pcmdev_single_byte_wr(struct pcmdevice_priv * pcm_dev,unsigned char * data,int devn,int sublocksize)1686 static int pcmdev_single_byte_wr(struct pcmdevice_priv *pcm_dev,
1687 unsigned char *data, int devn, int sublocksize)
1688 {
1689 unsigned short len = get_unaligned_be16(&data[2]);
1690 int offset = 2;
1691 int i, ret;
1692
1693 offset += 2;
1694 if (offset + 4 * len > sublocksize) {
1695 dev_err(pcm_dev->dev, "%s: dev-%d byt wr out of boundary\n",
1696 __func__, devn);
1697 return -EINVAL;
1698 }
1699
1700 for (i = 0; i < len; i++) {
1701 ret = pcmdev_dev_write(pcm_dev, devn,
1702 PCMDEVICE_REG(data[offset + 1], data[offset + 2]),
1703 data[offset + 3]);
1704 /* skip this error for next operation or next devices */
1705 if (ret < 0)
1706 dev_err(pcm_dev->dev, "%s: dev-%d single write err\n",
1707 __func__, devn);
1708
1709 offset += 4;
1710 }
1711
1712 return offset;
1713 }
1714
pcmdev_burst_wr(struct pcmdevice_priv * pcm_dev,unsigned char * data,int devn,int sublocksize)1715 static int pcmdev_burst_wr(struct pcmdevice_priv *pcm_dev,
1716 unsigned char *data, int devn, int sublocksize)
1717 {
1718 unsigned short len = get_unaligned_be16(&data[2]);
1719 int offset = 2;
1720 int ret;
1721
1722 offset += 2;
1723 if (offset + 4 + len > sublocksize) {
1724 dev_err(pcm_dev->dev, "%s: dev-%d burst Out of boundary\n",
1725 __func__, devn);
1726 return -EINVAL;
1727 }
1728 if (len % 4) {
1729 dev_err(pcm_dev->dev, "%s: dev-%d bst-len(%u) not div by 4\n",
1730 __func__, devn, len);
1731 return -EINVAL;
1732 }
1733 ret = pcmdev_dev_bulk_write(pcm_dev, devn,
1734 PCMDEVICE_REG(data[offset + 1], data[offset + 2]),
1735 &(data[offset + 4]), len);
1736 /* skip this error for next devices */
1737 if (ret < 0)
1738 dev_err(pcm_dev->dev, "%s: dev-%d bulk_write err = %d\n",
1739 __func__, devn, ret);
1740
1741 offset += (len + 4);
1742
1743 return offset;
1744 }
1745
pcmdev_delay(struct pcmdevice_priv * pcm_dev,unsigned char * data,int devn,int sublocksize)1746 static int pcmdev_delay(struct pcmdevice_priv *pcm_dev,
1747 unsigned char *data, int devn, int sublocksize)
1748 {
1749 unsigned int delay_time = 0;
1750 int offset = 2;
1751
1752 if (offset + 2 > sublocksize) {
1753 dev_err(pcm_dev->dev, "%s: dev-%d delay out of boundary\n",
1754 __func__, devn);
1755 return -EINVAL;
1756 }
1757 delay_time = get_unaligned_be16(&data[2]) * 1000;
1758 usleep_range(delay_time, delay_time + 50);
1759 offset += 2;
1760
1761 return offset;
1762 }
1763
pcmdev_bits_wr(struct pcmdevice_priv * pcm_dev,unsigned char * data,int devn,int sublocksize)1764 static int pcmdev_bits_wr(struct pcmdevice_priv *pcm_dev,
1765 unsigned char *data, int devn, int sublocksize)
1766 {
1767 int offset = 2;
1768 int ret;
1769
1770 if (offset + 6 > sublocksize) {
1771 dev_err(pcm_dev->dev, "%s: dev-%d bit write out of memory\n",
1772 __func__, devn);
1773 return -EINVAL;
1774 }
1775 ret = pcmdev_dev_update_bits(pcm_dev, devn,
1776 PCMDEVICE_REG(data[offset + 3], data[offset + 4]),
1777 data[offset + 1], data[offset + 5]);
1778 /* skip this error for next devices */
1779 if (ret < 0)
1780 dev_err(pcm_dev->dev, "%s: dev-%d update_bits err = %d\n",
1781 __func__, devn, ret);
1782
1783 offset += 6;
1784
1785 return offset;
1786 }
1787
pcmdevice_process_block(void * ctxt,unsigned char * data,unsigned char dev_idx,int sublocksize)1788 static int pcmdevice_process_block(void *ctxt, unsigned char *data,
1789 unsigned char dev_idx, int sublocksize)
1790 {
1791 struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1792 int devn, dev_end, ret = 0;
1793 unsigned char subblk_typ = data[1];
1794
1795 if (dev_idx) {
1796 devn = dev_idx - 1;
1797 dev_end = dev_idx;
1798 } else {
1799 devn = 0;
1800 dev_end = pcm_dev->ndev;
1801 }
1802
1803 /* loop in case of several devices sharing the same sub-block */
1804 for (; devn < dev_end; devn++) {
1805 switch (subblk_typ) {
1806 case PCMDEVICE_CMD_SING_W:
1807 ret = pcmdev_single_byte_wr(pcm_dev, data, devn, sublocksize);
1808 break;
1809 case PCMDEVICE_CMD_BURST:
1810 ret = pcmdev_burst_wr(pcm_dev, data, devn, sublocksize);
1811 break;
1812 case PCMDEVICE_CMD_DELAY:
1813 ret = pcmdev_delay(pcm_dev, data, devn, sublocksize);
1814 break;
1815 case PCMDEVICE_CMD_FIELD_W:
1816 ret = pcmdev_bits_wr(pcm_dev, data, devn, sublocksize);
1817 break;
1818 default:
1819 break;
1820 }
1821 /*
1822 * In case of sub-block error, break the loop for the rest of
1823 * devices.
1824 */
1825 if (ret < 0)
1826 break;
1827 }
1828
1829 return ret;
1830 }
1831
pcmdevice_select_cfg_blk(void * ctxt,int conf_no,unsigned char block_type)1832 static void pcmdevice_select_cfg_blk(void *ctxt, int conf_no,
1833 unsigned char block_type)
1834 {
1835 struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1836 struct pcmdevice_regbin *regbin = &(pcm_dev->regbin);
1837 struct pcmdevice_config_info **cfg_info = regbin->cfg_info;
1838 struct pcmdevice_block_data **blk_data;
1839 int j, k;
1840
1841 if (conf_no >= regbin->ncfgs || conf_no < 0 || NULL == cfg_info) {
1842 dev_err(pcm_dev->dev, "%s: conf_no should be less than %u\n",
1843 __func__, regbin->ncfgs);
1844 goto out;
1845 }
1846 blk_data = cfg_info[conf_no]->blk_data;
1847
1848 for (j = 0; j < (int)cfg_info[conf_no]->real_nblocks; j++) {
1849 unsigned int length = 0, ret;
1850
1851 if (block_type > 5 || block_type < 2) {
1852 dev_err(pcm_dev->dev,
1853 "%s: block_type should be out of range\n",
1854 __func__);
1855 goto out;
1856 }
1857 if (block_type != blk_data[j]->block_type)
1858 continue;
1859
1860 for (k = 0; k < (int)blk_data[j]->n_subblks; k++) {
1861 ret = pcmdevice_process_block(pcm_dev,
1862 blk_data[j]->regdata + length,
1863 blk_data[j]->dev_idx,
1864 blk_data[j]->block_size - length);
1865 length += ret;
1866 if (blk_data[j]->block_size < length) {
1867 dev_err(pcm_dev->dev,
1868 "%s: %u %u out of boundary\n",
1869 __func__, length,
1870 blk_data[j]->block_size);
1871 break;
1872 }
1873 }
1874 if (length != blk_data[j]->block_size)
1875 dev_err(pcm_dev->dev, "%s: %u %u size is not same\n",
1876 __func__, length, blk_data[j]->block_size);
1877 }
1878
1879 out:
1880 return;
1881 }
1882
pcmdevice_mute(struct snd_soc_dai * dai,int mute,int stream)1883 static int pcmdevice_mute(struct snd_soc_dai *dai, int mute, int stream)
1884 {
1885 struct snd_soc_component *codec = dai->component;
1886 struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec);
1887 unsigned char block_type;
1888
1889 if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) {
1890 dev_err(pcm_dev->dev, "%s: bin file not loaded\n", __func__);
1891 return -EINVAL;
1892 }
1893
1894 if (mute)
1895 block_type = PCMDEVICE_BIN_BLK_PRE_SHUTDOWN;
1896 else
1897 block_type = PCMDEVICE_BIN_BLK_PRE_POWER_UP;
1898
1899 mutex_lock(&pcm_dev->codec_lock);
1900 pcmdevice_select_cfg_blk(pcm_dev, pcm_dev->cur_conf, block_type);
1901 mutex_unlock(&pcm_dev->codec_lock);
1902 return 0;
1903 }
1904
pcmdevice_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)1905 static int pcmdevice_hw_params(struct snd_pcm_substream *substream,
1906 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1907 {
1908 struct pcmdevice_priv *pcm_dev = snd_soc_dai_get_drvdata(dai);
1909 unsigned int fsrate;
1910 unsigned int slot_width;
1911 int bclk_rate;
1912 int ret = 0;
1913
1914 fsrate = params_rate(params);
1915 switch (fsrate) {
1916 case 48000:
1917 break;
1918 case 44100:
1919 break;
1920 default:
1921 dev_err(pcm_dev->dev, "%s: incorrect sample rate = %u\n",
1922 __func__, fsrate);
1923 ret = -EINVAL;
1924 goto out;
1925 }
1926
1927 slot_width = params_width(params);
1928 switch (slot_width) {
1929 case 16:
1930 break;
1931 case 20:
1932 break;
1933 case 24:
1934 break;
1935 case 32:
1936 break;
1937 default:
1938 dev_err(pcm_dev->dev, "%s: incorrect slot width = %u\n",
1939 __func__, slot_width);
1940 ret = -EINVAL;
1941 goto out;
1942 }
1943
1944 bclk_rate = snd_soc_params_to_bclk(params);
1945 if (bclk_rate < 0) {
1946 dev_err(pcm_dev->dev, "%s: incorrect bclk rate = %d\n",
1947 __func__, bclk_rate);
1948 ret = bclk_rate;
1949 }
1950
1951 out:
1952 return ret;
1953 }
1954
1955 static const struct snd_soc_dai_ops pcmdevice_dai_ops = {
1956 .mute_stream = pcmdevice_mute,
1957 .hw_params = pcmdevice_hw_params,
1958 };
1959
1960 static struct snd_soc_dai_driver pcmdevice_dai_driver[] = {
1961 {
1962 .name = "pcmdevice-codec",
1963 .capture = {
1964 .stream_name = "Capture",
1965 .channels_min = 2,
1966 .channels_max = PCMDEVICE_MAX_CHANNELS,
1967 .rates = PCMDEVICE_RATES,
1968 .formats = PCMDEVICE_FORMATS,
1969 },
1970 .playback = {
1971 .stream_name = "Playback",
1972 .channels_min = 2,
1973 .channels_max = PCMDEVICE_MAX_CHANNELS,
1974 .rates = PCMDEVICE_RATES,
1975 .formats = PCMDEVICE_FORMATS,
1976 },
1977 .ops = &pcmdevice_dai_ops,
1978 .symmetric_rate = 1,
1979 }
1980 };
1981
1982 #ifdef CONFIG_OF
1983 static const struct of_device_id pcmdevice_of_match[] = {
1984 { .compatible = "ti,adc3120" },
1985 { .compatible = "ti,adc5120" },
1986 { .compatible = "ti,adc6120" },
1987 { .compatible = "ti,dix4192" },
1988 { .compatible = "ti,pcm1690" },
1989 { .compatible = "ti,pcm3120" },
1990 { .compatible = "ti,pcm3140" },
1991 { .compatible = "ti,pcm5120" },
1992 { .compatible = "ti,pcm5140" },
1993 { .compatible = "ti,pcm6120" },
1994 { .compatible = "ti,pcm6140" },
1995 { .compatible = "ti,pcm6240" },
1996 { .compatible = "ti,pcm6260" },
1997 { .compatible = "ti,pcm9211" },
1998 { .compatible = "ti,pcmd3140" },
1999 { .compatible = "ti,pcmd3180" },
2000 { .compatible = "ti,pcmd512x" },
2001 { .compatible = "ti,taa5212" },
2002 { .compatible = "ti,taa5412" },
2003 { .compatible = "ti,tad5212" },
2004 { .compatible = "ti,tad5412" },
2005 {},
2006 };
2007 MODULE_DEVICE_TABLE(of, pcmdevice_of_match);
2008 #endif
2009
2010 static const struct regmap_range_cfg pcmdevice_ranges[] = {
2011 {
2012 .range_min = 0,
2013 .range_max = 256 * 128,
2014 .selector_reg = PCMDEVICE_PAGE_SELECT,
2015 .selector_mask = 0xff,
2016 .selector_shift = 0,
2017 .window_start = 0,
2018 .window_len = 128,
2019 },
2020 };
2021
2022 static const struct regmap_config pcmdevice_i2c_regmap = {
2023 .reg_bits = 8,
2024 .val_bits = 8,
2025 .cache_type = REGCACHE_MAPLE,
2026 .ranges = pcmdevice_ranges,
2027 .num_ranges = ARRAY_SIZE(pcmdevice_ranges),
2028 .max_register = 256 * 128,
2029 };
2030
pcmdevice_remove(struct pcmdevice_priv * pcm_dev)2031 static void pcmdevice_remove(struct pcmdevice_priv *pcm_dev)
2032 {
2033 if (pcm_dev->irq)
2034 free_irq(pcm_dev->irq, pcm_dev);
2035 mutex_destroy(&pcm_dev->codec_lock);
2036 }
2037
str_to_upper(char * str)2038 static char *str_to_upper(char *str)
2039 {
2040 char *orig = str;
2041
2042 if (!str)
2043 return NULL;
2044
2045 while (*str) {
2046 *str = toupper(*str);
2047 str++;
2048 }
2049
2050 return orig;
2051 }
2052
pcmdevice_i2c_probe(struct i2c_client * i2c)2053 static int pcmdevice_i2c_probe(struct i2c_client *i2c)
2054 {
2055 struct pcmdevice_priv *pcm_dev;
2056 struct device_node *np;
2057 unsigned int dev_addrs[PCMDEVICE_MAX_I2C_DEVICES];
2058 int ret = 0, i = 0, ndev = 0;
2059
2060 pcm_dev = devm_kzalloc(&i2c->dev, sizeof(*pcm_dev), GFP_KERNEL);
2061 if (!pcm_dev)
2062 return -ENOMEM;
2063
2064 pcm_dev->chip_id = (uintptr_t)i2c_get_match_data(i2c);
2065
2066 pcm_dev->dev = &i2c->dev;
2067 pcm_dev->client = i2c;
2068
2069 if (pcm_dev->chip_id >= MAX_DEVICE)
2070 pcm_dev->chip_id = 0;
2071
2072 strscpy(pcm_dev->dev_name, pcmdevice_i2c_id[pcm_dev->chip_id].name,
2073 sizeof(pcm_dev->dev_name));
2074
2075 strscpy(pcm_dev->upper_dev_name,
2076 pcmdevice_i2c_id[pcm_dev->chip_id].name,
2077 sizeof(pcm_dev->upper_dev_name));
2078
2079 str_to_upper(pcm_dev->upper_dev_name);
2080
2081 pcm_dev->regmap = devm_regmap_init_i2c(i2c, &pcmdevice_i2c_regmap);
2082 if (IS_ERR(pcm_dev->regmap)) {
2083 ret = PTR_ERR(pcm_dev->regmap);
2084 dev_err(&i2c->dev, "%s: failed to allocate register map: %d\n",
2085 __func__, ret);
2086 goto out;
2087 }
2088
2089 i2c_set_clientdata(i2c, pcm_dev);
2090 mutex_init(&pcm_dev->codec_lock);
2091 np = pcm_dev->dev->of_node;
2092
2093 if (IS_ENABLED(CONFIG_OF)) {
2094 u64 addr;
2095
2096 for (i = 0; i < PCMDEVICE_MAX_I2C_DEVICES; i++) {
2097 if (of_property_read_reg(np, i, &addr, NULL))
2098 break;
2099 dev_addrs[ndev++] = addr;
2100 }
2101 } else {
2102 ndev = 1;
2103 dev_addrs[0] = i2c->addr;
2104 }
2105 pcm_dev->irq = of_irq_get(np, 0);
2106
2107 for (i = 0; i < ndev; i++)
2108 pcm_dev->addr[i] = dev_addrs[i];
2109
2110 pcm_dev->ndev = ndev;
2111
2112 pcm_dev->hw_rst = devm_gpiod_get_optional(&i2c->dev,
2113 "reset-gpios", GPIOD_OUT_HIGH);
2114 /* No reset GPIO, no side-effect */
2115 if (IS_ERR(pcm_dev->hw_rst)) {
2116 if (pcm_dev->chip_id == PCM9211 || pcm_dev->chip_id == PCM1690)
2117 pcm9211_sw_rst(pcm_dev);
2118 else
2119 pcmdevice_sw_rst(pcm_dev);
2120 } else {
2121 gpiod_set_value_cansleep(pcm_dev->hw_rst, 0);
2122 usleep_range(500, 1000);
2123 gpiod_set_value_cansleep(pcm_dev->hw_rst, 1);
2124 }
2125
2126 if (pcm_dev->chip_id == PCM1690)
2127 goto skip_interrupt;
2128 if (pcm_dev->irq) {
2129 dev_dbg(pcm_dev->dev, "irq = %d", pcm_dev->irq);
2130 } else
2131 dev_err(pcm_dev->dev, "No irq provided\n");
2132
2133 skip_interrupt:
2134 ret = devm_snd_soc_register_component(&i2c->dev,
2135 &soc_codec_driver_pcmdevice, pcmdevice_dai_driver,
2136 ARRAY_SIZE(pcmdevice_dai_driver));
2137 if (ret < 0)
2138 dev_err(&i2c->dev, "probe register comp failed %d\n", ret);
2139
2140 out:
2141 if (ret < 0)
2142 pcmdevice_remove(pcm_dev);
2143 return ret;
2144 }
2145
pcmdevice_i2c_remove(struct i2c_client * i2c)2146 static void pcmdevice_i2c_remove(struct i2c_client *i2c)
2147 {
2148 struct pcmdevice_priv *pcm_dev = i2c_get_clientdata(i2c);
2149
2150 pcmdevice_remove(pcm_dev);
2151 }
2152
2153 static struct i2c_driver pcmdevice_i2c_driver = {
2154 .driver = {
2155 .name = "pcmdevice-codec",
2156 .of_match_table = of_match_ptr(pcmdevice_of_match),
2157 },
2158 .probe = pcmdevice_i2c_probe,
2159 .remove = pcmdevice_i2c_remove,
2160 .id_table = pcmdevice_i2c_id,
2161 };
2162 module_i2c_driver(pcmdevice_i2c_driver);
2163
2164 MODULE_AUTHOR("Shenghao Ding <shenghao-ding@ti.com>");
2165 MODULE_DESCRIPTION("ASoC PCM6240 Family Audio ADC/DAC Driver");
2166 MODULE_LICENSE("GPL");
2167