acc636068af31df02b180f0abce3f7df60d10a06
[oweals/openwrt.git] /
1 From 9a43360b6f8d6073b0bd67077229fe1d63076733 Mon Sep 17 00:00:00 2001
2 From: Raashid Muhammed <raashidmuhammed@zilogic.com>
3 Date: Mon, 27 Mar 2017 12:35:00 +0530
4 Subject: [PATCH 076/703] Add support for Allo Piano DAC 2.1 plus add-on board
5  for Raspberry Pi.
6
7 The Piano DAC 2.1 has support for 4 channels with subwoofer.
8
9 Signed-off-by: Baswaraj K <jaikumar@cem-solutions.net>
10 Reviewed-by: Vijay Kumar B. <vijaykumar@zilogic.com>
11 Reviewed-by: Raashid Muhammed <raashidmuhammed@zilogic.com>
12
13 Add clock changes and mute gpios (#1938)
14
15 Also improve code style and adhere to ALSA coding conventions.
16
17 Signed-off-by: Baswaraj K <jaikumar@cem-solutions.net>
18 Reviewed-by: Vijay Kumar B. <vijaykumar@zilogic.com>
19 Reviewed-by: Raashid Muhammed <raashidmuhammed@zilogic.com>
20
21 PianoPlus: Dual Mono & Dual Stereo features added (#2069)
22
23 allo-piano-dac-plus: Master volume added + fixes
24
25 Master volume added, which controls both DACs volumes.
26
27 See: https://github.com/raspberrypi/linux/pull/2149
28
29 Also fix initial max volume, default mode value, and unmute.
30
31 Signed-off-by: allocom <sparky-dev@allo.com>
32
33 ASoC: allo-piano-dac-plus: fix S24_LE format
34
35 Remove set_bclk_ratio call so 24-bit data is transmitted in
36 24 bclk cycles.
37
38 Signed-off-by: Matthias Reichl <hias@horus.com>
39 ---
40  sound/soc/bcm/allo-piano-dac-plus.c | 1011 +++++++++++++++++++++++++++
41  1 file changed, 1011 insertions(+)
42  create mode 100644 sound/soc/bcm/allo-piano-dac-plus.c
43
44 --- /dev/null
45 +++ b/sound/soc/bcm/allo-piano-dac-plus.c
46 @@ -0,0 +1,1011 @@
47 +/*
48 + * ALSA ASoC Machine Driver for Allo Piano DAC Plus Subwoofer
49 + *
50 + * Author:     Baswaraj K <jaikumar@cem-solutions.net>
51 + *             Copyright 2016
52 + *             based on code by Daniel Matuschek <info@crazy-audio.com>
53 + *             based on code by Florian Meier <florian.meier@koalo.de>
54 + *
55 + * This program is free software; you can redistribute it and/or
56 + * modify it under the terms of the GNU General Public License
57 + * version 2 as published by the Free Software Foundation.
58 + *
59 + * This program is distributed in the hope that it will be useful, but
60 + * WITHOUT ANY WARRANTY; without even the implied warranty of
61 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
62 + * General Public License for more details.
63 + */
64 +
65 +#include <linux/module.h>
66 +#include <linux/platform_device.h>
67 +#include <linux/gpio/consumer.h>
68 +#include <sound/core.h>
69 +#include <sound/pcm.h>
70 +#include <sound/pcm_params.h>
71 +#include <sound/soc.h>
72 +#include <linux/firmware.h>
73 +#include <linux/delay.h>
74 +#include <sound/tlv.h>
75 +#include "../codecs/pcm512x.h"
76 +
77 +#define P_DAC_LEFT_MUTE                0x10
78 +#define P_DAC_RIGHT_MUTE       0x01
79 +#define P_DAC_MUTE             0x11
80 +#define P_DAC_UNMUTE           0x00
81 +#define P_MUTE                 1
82 +#define P_UNMUTE               0
83 +
84 +struct dsp_code {
85 +       char i2c_addr;
86 +       char offset;
87 +       char val;
88 +};
89 +
90 +struct glb_pool {
91 +       struct mutex lock;
92 +       unsigned int dual_mode;
93 +       unsigned int set_lowpass;
94 +       unsigned int set_mode;
95 +       unsigned int set_rate;
96 +       unsigned int dsp_page_number;
97 +};
98 +
99 +static bool digital_gain_0db_limit = true;
100 +bool glb_mclk;
101 +
102 +static struct gpio_desc *mute_gpio[2];
103 +
104 +static const char * const allo_piano_mode_texts[] = {
105 +       "None",
106 +       "2.0",
107 +       "2.1",
108 +       "2.2",
109 +};
110 +
111 +static const SOC_ENUM_SINGLE_DECL(allo_piano_mode_enum,
112 +               0, 0, allo_piano_mode_texts);
113 +
114 +static const char * const allo_piano_dual_mode_texts[] = {
115 +       "None",
116 +       "Dual-Mono",
117 +       "Dual-Stereo",
118 +};
119 +
120 +static const SOC_ENUM_SINGLE_DECL(allo_piano_dual_mode_enum,
121 +               0, 0, allo_piano_dual_mode_texts);
122 +
123 +static const char * const allo_piano_dsp_low_pass_texts[] = {
124 +       "60",
125 +       "70",
126 +       "80",
127 +       "90",
128 +       "100",
129 +       "110",
130 +       "120",
131 +       "130",
132 +       "140",
133 +       "150",
134 +       "160",
135 +       "170",
136 +       "180",
137 +       "190",
138 +       "200",
139 +};
140 +
141 +static const SOC_ENUM_SINGLE_DECL(allo_piano_enum,
142 +               0, 0, allo_piano_dsp_low_pass_texts);
143 +
144 +static int __snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd,
145 +               unsigned int mode, unsigned int rate, unsigned int lowpass)
146 +{
147 +       const struct firmware *fw;
148 +       struct snd_soc_card *card = rtd->card;
149 +       struct glb_pool *glb_ptr = card->drvdata;
150 +       char firmware_name[60];
151 +       int ret = 0, dac = 0;
152 +
153 +       if (rate <= 46000)
154 +               rate = 44100;
155 +       else if (rate <= 68000)
156 +               rate = 48000;
157 +       else if (rate <= 92000)
158 +               rate = 88200;
159 +       else if (rate <= 136000)
160 +               rate = 96000;
161 +       else if (rate <= 184000)
162 +               rate = 176400;
163 +       else
164 +               rate = 192000;
165 +
166 +       if (lowpass > 14)
167 +               glb_ptr->set_lowpass = lowpass = 0;
168 +
169 +       if (mode > 3)
170 +               glb_ptr->set_mode = mode = 0;
171 +
172 +       if (mode > 0)
173 +               glb_ptr->dual_mode = 0;
174 +
175 +       /* same configuration loaded */
176 +       if ((rate == glb_ptr->set_rate) && (lowpass == glb_ptr->set_lowpass)
177 +                       && (mode == glb_ptr->set_mode))
178 +               return 0;
179 +
180 +       switch (mode) {
181 +       case 0: /* None */
182 +               return 1;
183 +
184 +       case 1: /* 2.0 */
185 +               snd_soc_component_write(rtd->codec_dais[0]->component,
186 +                               PCM512x_MUTE, P_DAC_UNMUTE);
187 +               snd_soc_component_write(rtd->codec_dais[1]->component,
188 +                               PCM512x_MUTE, P_DAC_MUTE);
189 +               glb_ptr->set_rate = rate;
190 +               glb_ptr->set_mode = mode;
191 +               glb_ptr->set_lowpass = lowpass;
192 +               return 1;
193 +
194 +       default:
195 +               snd_soc_component_write(rtd->codec_dais[0]->component,
196 +                               PCM512x_MUTE, P_DAC_UNMUTE);
197 +               snd_soc_component_write(rtd->codec_dais[1]->component,
198 +                               PCM512x_MUTE, P_DAC_UNMUTE);
199 +       }
200 +
201 +       for (dac = 0; dac < rtd->num_codecs; dac++) {
202 +               struct dsp_code *dsp_code_read;
203 +               int i = 1;
204 +
205 +               if (dac == 0) { /* high */
206 +                       snprintf(firmware_name, sizeof(firmware_name),
207 +                               "allo/piano/2.2/allo-piano-dsp-%d-%d-%d.bin",
208 +                               rate, ((lowpass * 10) + 60), dac);
209 +               } else { /* low */
210 +                       snprintf(firmware_name, sizeof(firmware_name),
211 +                               "allo/piano/2.%d/allo-piano-dsp-%d-%d-%d.bin",
212 +                               (mode - 1), rate, ((lowpass * 10) + 60), dac);
213 +               }
214 +
215 +               dev_info(rtd->card->dev, "Dsp Firmware File Name: %s\n",
216 +                               firmware_name);
217 +
218 +               ret = request_firmware(&fw, firmware_name, rtd->card->dev);
219 +               if (ret < 0) {
220 +                       dev_err(rtd->card->dev,
221 +                               "Error: Allo Piano Firmware %s missing. %d\n",
222 +                               firmware_name, ret);
223 +                       goto err;
224 +               }
225 +
226 +               while (i < (fw->size - 1)) {
227 +                       dsp_code_read = (struct dsp_code *)&fw->data[i];
228 +
229 +                       if (dsp_code_read->offset == 0) {
230 +                               glb_ptr->dsp_page_number = dsp_code_read->val;
231 +                               ret = snd_soc_component_write(rtd->codec_dais[dac]->component,
232 +                                               PCM512x_PAGE_BASE(0),
233 +                                               dsp_code_read->val);
234 +
235 +                       } else if (dsp_code_read->offset != 0) {
236 +                               ret = snd_soc_component_write(rtd->codec_dais[dac]->component,
237 +                                       (PCM512x_PAGE_BASE(
238 +                                               glb_ptr->dsp_page_number) +
239 +                                       dsp_code_read->offset),
240 +                                       dsp_code_read->val);
241 +                       }
242 +                       if (ret < 0) {
243 +                               dev_err(rtd->card->dev,
244 +                                       "Failed to write Register: %d\n", ret);
245 +                               release_firmware(fw);
246 +                               goto err;
247 +                       }
248 +                       i = i + 3;
249 +               }
250 +               release_firmware(fw);
251 +       }
252 +       glb_ptr->set_rate = rate;
253 +       glb_ptr->set_mode = mode;
254 +       glb_ptr->set_lowpass = lowpass;
255 +       return 1;
256 +
257 +err:
258 +       return ret;
259 +}
260 +
261 +static int snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd,
262 +               unsigned int mode, unsigned int rate, unsigned int lowpass)
263 +{
264 +       struct snd_soc_card *card = rtd->card;
265 +       struct glb_pool *glb_ptr = card->drvdata;
266 +       int ret = 0;
267 +
268 +       mutex_lock(&glb_ptr->lock);
269 +
270 +       ret = __snd_allo_piano_dsp_program(rtd, mode, rate, lowpass);
271 +
272 +       mutex_unlock(&glb_ptr->lock);
273 +
274 +       return ret;
275 +}
276 +
277 +static int snd_allo_piano_dual_mode_get(struct snd_kcontrol *kcontrol,
278 +               struct snd_ctl_elem_value *ucontrol)
279 +{
280 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
281 +       struct glb_pool *glb_ptr = card->drvdata;
282 +
283 +       ucontrol->value.integer.value[0] = glb_ptr->dual_mode;
284 +
285 +       return 0;
286 +}
287 +
288 +static int snd_allo_piano_dual_mode_put(struct snd_kcontrol *kcontrol,
289 +               struct snd_ctl_elem_value *ucontrol)
290 +{
291 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
292 +       struct glb_pool *glb_ptr = card->drvdata;
293 +       struct snd_soc_pcm_runtime *rtd;
294 +       struct snd_card *snd_card_ptr = card->snd_card;
295 +       struct snd_kcontrol *kctl;
296 +       struct soc_mixer_control *mc;
297 +       unsigned int left_val = 0, right_val = 0;
298 +
299 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
300 +
301 +       if (ucontrol->value.integer.value[0] > 0) {
302 +               glb_ptr->dual_mode = ucontrol->value.integer.value[0];
303 +               glb_ptr->set_mode = 0;
304 +       } else {
305 +               if (glb_ptr->set_mode <= 0) {
306 +                       glb_ptr->dual_mode = 1;
307 +                       glb_ptr->set_mode = 0;
308 +               } else {
309 +                       glb_ptr->dual_mode = 0;
310 +                       return 0;
311 +               }
312 +       }
313 +
314 +       if (glb_ptr->dual_mode == 1) { // Dual Mono
315 +               snd_soc_component_write(rtd->codec_dais[0]->component,
316 +                               PCM512x_MUTE, P_DAC_RIGHT_MUTE);
317 +               snd_soc_component_write(rtd->codec_dais[1]->component,
318 +                               PCM512x_MUTE, P_DAC_LEFT_MUTE);
319 +               snd_soc_component_write(rtd->codec_dais[0]->component,
320 +                               PCM512x_DIGITAL_VOLUME_3, 0xff);
321 +               snd_soc_component_write(rtd->codec_dais[1]->component,
322 +                               PCM512x_DIGITAL_VOLUME_2, 0xff);
323 +
324 +               list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
325 +                       if (!strncmp(kctl->id.name, "Digital Playback Volume",
326 +                                       sizeof(kctl->id.name))) {
327 +                               mc = (struct soc_mixer_control *)
328 +                                       kctl->private_value;
329 +                               mc->rreg = mc->reg;
330 +                               break;
331 +                       }
332 +               }
333 +       } else {
334 +               snd_soc_component_read(rtd->codec_dais[0]->component,
335 +                                               PCM512x_DIGITAL_VOLUME_2, &left_val);
336 +               snd_soc_component_read(rtd->codec_dais[1]->component,
337 +                                               PCM512x_DIGITAL_VOLUME_3, &right_val);
338 +
339 +               list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
340 +                       if (!strncmp(kctl->id.name, "Digital Playback Volume",
341 +                                       sizeof(kctl->id.name))) {
342 +                               mc = (struct soc_mixer_control *)
343 +                                       kctl->private_value;
344 +                               mc->rreg = PCM512x_DIGITAL_VOLUME_3;
345 +                               break;
346 +                       }
347 +               }
348 +
349 +               snd_soc_component_write(rtd->codec_dais[0]->component,
350 +                               PCM512x_DIGITAL_VOLUME_3, left_val);
351 +               snd_soc_component_write(rtd->codec_dais[1]->component,
352 +                               PCM512x_DIGITAL_VOLUME_2, right_val);
353 +               snd_soc_component_write(rtd->codec_dais[0]->component,
354 +                               PCM512x_MUTE, P_DAC_UNMUTE);
355 +               snd_soc_component_write(rtd->codec_dais[1]->component,
356 +                               PCM512x_MUTE, P_DAC_UNMUTE);
357 +       }
358 +
359 +       return 0;
360 +}
361 +
362 +static int snd_allo_piano_mode_get(struct snd_kcontrol *kcontrol,
363 +               struct snd_ctl_elem_value *ucontrol)
364 +{
365 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
366 +       struct glb_pool *glb_ptr = card->drvdata;
367 +
368 +       ucontrol->value.integer.value[0] = glb_ptr->set_mode;
369 +       return 0;
370 +}
371 +
372 +static int snd_allo_piano_mode_put(struct snd_kcontrol *kcontrol,
373 +               struct snd_ctl_elem_value *ucontrol)
374 +{
375 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
376 +       struct snd_soc_pcm_runtime *rtd;
377 +       struct glb_pool *glb_ptr = card->drvdata;
378 +       struct snd_card *snd_card_ptr = card->snd_card;
379 +       struct snd_kcontrol *kctl;
380 +       struct soc_mixer_control *mc;
381 +       unsigned int left_val = 0, right_val = 0;
382 +
383 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
384 +
385 +       if ((glb_ptr->dual_mode == 1) &&
386 +                       (ucontrol->value.integer.value[0] > 0)) {
387 +               snd_soc_component_read(rtd->codec_dais[0]->component,
388 +                                               PCM512x_DIGITAL_VOLUME_2, &left_val);
389 +               snd_soc_component_read(rtd->codec_dais[1]->component,
390 +                                               PCM512x_DIGITAL_VOLUME_2, &right_val);
391 +
392 +               list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
393 +                       if (!strncmp(kctl->id.name, "Digital Playback Volume",
394 +                                       sizeof(kctl->id.name))) {
395 +                               mc = (struct soc_mixer_control *)
396 +                                       kctl->private_value;
397 +                               mc->rreg = PCM512x_DIGITAL_VOLUME_3;
398 +                               break;
399 +                       }
400 +               }
401 +               snd_soc_component_write(rtd->codec_dais[0]->component,
402 +                               PCM512x_DIGITAL_VOLUME_3, left_val);
403 +               snd_soc_component_write(rtd->codec_dais[1]->component,
404 +                               PCM512x_DIGITAL_VOLUME_3, right_val);
405 +       }
406 +
407 +       return(snd_allo_piano_dsp_program(rtd,
408 +                               ucontrol->value.integer.value[0],
409 +                               glb_ptr->set_rate, glb_ptr->set_lowpass));
410 +}
411 +
412 +static int snd_allo_piano_lowpass_get(struct snd_kcontrol *kcontrol,
413 +               struct snd_ctl_elem_value *ucontrol)
414 +{
415 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
416 +       struct glb_pool *glb_ptr = card->drvdata;
417 +
418 +       ucontrol->value.integer.value[0] = glb_ptr->set_lowpass;
419 +       return 0;
420 +}
421 +
422 +static int snd_allo_piano_lowpass_put(struct snd_kcontrol *kcontrol,
423 +               struct snd_ctl_elem_value *ucontrol)
424 +{
425 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
426 +       struct snd_soc_pcm_runtime *rtd;
427 +       struct glb_pool *glb_ptr = card->drvdata;
428 +
429 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
430 +       return(snd_allo_piano_dsp_program(rtd,
431 +                               glb_ptr->set_mode, glb_ptr->set_rate,
432 +                               ucontrol->value.integer.value[0]));
433 +}
434 +
435 +static int pcm512x_get_reg_sub(struct snd_kcontrol *kcontrol,
436 +               struct snd_ctl_elem_value *ucontrol)
437 +{
438 +       struct soc_mixer_control *mc =
439 +               (struct soc_mixer_control *)kcontrol->private_value;
440 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
441 +       struct glb_pool *glb_ptr = card->drvdata;
442 +       struct snd_soc_pcm_runtime *rtd;
443 +       unsigned int left_val = 0;
444 +       unsigned int right_val = 0;
445 +       int ret;
446 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
447 +       ret = snd_soc_component_read(rtd->codec_dais[1]->component,
448 +                       PCM512x_DIGITAL_VOLUME_3, &right_val);
449 +       if (ret < 0)
450 +               return ret;
451 +
452 +       if (glb_ptr->dual_mode != 1) {
453 +               ret = snd_soc_component_read(rtd->codec_dais[1]->component,
454 +                               PCM512x_DIGITAL_VOLUME_2, &left_val);
455 +               if ( ret < 0)
456 +                       return ret;
457 +
458 +       } else {
459 +               left_val = right_val;
460 +       }
461 +
462 +       ucontrol->value.integer.value[0] =
463 +                               (~(left_val >> mc->shift)) & mc->max;
464 +       ucontrol->value.integer.value[1] =
465 +                               (~(right_val >> mc->shift)) & mc->max;
466 +
467 +       return 0;
468 +}
469 +
470 +static int pcm512x_set_reg_sub(struct snd_kcontrol *kcontrol,
471 +               struct snd_ctl_elem_value *ucontrol)
472 +{
473 +       struct soc_mixer_control *mc =
474 +               (struct soc_mixer_control *)kcontrol->private_value;
475 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
476 +       struct glb_pool *glb_ptr = card->drvdata;
477 +       struct snd_soc_pcm_runtime *rtd;
478 +       unsigned int left_val = (ucontrol->value.integer.value[0] & mc->max);
479 +       unsigned int right_val = (ucontrol->value.integer.value[1] & mc->max);
480 +       int ret = 0;
481 +
482 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
483 +       if (glb_ptr->dual_mode != 1) {
484 +               ret = snd_soc_component_write(rtd->codec_dais[1]->component,
485 +                               PCM512x_DIGITAL_VOLUME_2, (~left_val));
486 +               if (ret < 0)
487 +                       return ret;
488 +       }
489 +
490 +       if (digital_gain_0db_limit) {
491 +               ret = snd_soc_limit_volume(card, "Subwoofer Playback Volume",
492 +                                       207);
493 +               if (ret < 0)
494 +                       dev_warn(card->dev, "Failed to set volume limit: %d\n",
495 +                               ret);
496 +       }
497 +
498 +       ret = snd_soc_component_write(rtd->codec_dais[1]->component,
499 +                       PCM512x_DIGITAL_VOLUME_3, (~right_val));
500 +       if (ret < 0)
501 +               return ret;
502 +
503 +       return 1;
504 +}
505 +
506 +static int pcm512x_get_reg_sub_switch(struct snd_kcontrol *kcontrol,
507 +               struct snd_ctl_elem_value *ucontrol)
508 +{
509 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
510 +       struct snd_soc_pcm_runtime *rtd;
511 +       int val = 0;
512 +       int ret;
513 +
514 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
515 +       ret = snd_soc_component_read(rtd->codec_dais[1]->component, PCM512x_MUTE, &val);
516 +       if (ret < 0)
517 +               return ret;
518 +
519 +       ucontrol->value.integer.value[0] =
520 +                       (val & P_DAC_LEFT_MUTE) ? P_UNMUTE : P_MUTE;
521 +       ucontrol->value.integer.value[1] =
522 +                       (val & P_DAC_RIGHT_MUTE) ? P_UNMUTE : P_MUTE;
523 +
524 +       return val;
525 +}
526 +
527 +static int pcm512x_set_reg_sub_switch(struct snd_kcontrol *kcontrol,
528 +               struct snd_ctl_elem_value *ucontrol)
529 +{
530 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
531 +       struct snd_soc_pcm_runtime *rtd;
532 +       struct glb_pool *glb_ptr = card->drvdata;
533 +       unsigned int left_val = (ucontrol->value.integer.value[0]);
534 +       unsigned int right_val = (ucontrol->value.integer.value[1]);
535 +       int ret = 0;
536 +
537 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
538 +       if (glb_ptr->set_mode != 1) {
539 +               ret = snd_soc_component_write(rtd->codec_dais[1]->component, PCM512x_MUTE,
540 +                               ~((left_val & 0x01)<<4 | (right_val & 0x01)));
541 +               if (ret < 0)
542 +                       return ret;
543 +       }
544 +       return 1;
545 +
546 +}
547 +
548 +static int pcm512x_get_reg_master(struct snd_kcontrol *kcontrol,
549 +               struct snd_ctl_elem_value *ucontrol)
550 +{
551 +       struct soc_mixer_control *mc =
552 +               (struct soc_mixer_control *)kcontrol->private_value;
553 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
554 +       struct glb_pool *glb_ptr = card->drvdata;
555 +       struct snd_soc_pcm_runtime *rtd;
556 +       unsigned int left_val = 0, right_val = 0;
557 +       int ret;
558 +
559 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
560 +
561 +       ret = snd_soc_component_read(rtd->codec_dais[0]->component,
562 +                       PCM512x_DIGITAL_VOLUME_2, &left_val);
563 +       if ( ret < 0)
564 +               return ret;
565 +
566 +       if (glb_ptr->dual_mode == 1) {
567 +               ret = snd_soc_component_read(rtd->codec_dais[1]->component,
568 +                               PCM512x_DIGITAL_VOLUME_3, &right_val);
569 +               if (ret < 0)
570 +                       return ret;
571 +       } else {
572 +               ret = snd_soc_component_read(rtd->codec_dais[0]->component,
573 +                               PCM512x_DIGITAL_VOLUME_3, &right_val);
574 +               if (ret < 0)
575 +                       return ret;
576 +       }
577 +
578 +       ucontrol->value.integer.value[0] =
579 +               (~(left_val  >> mc->shift)) & mc->max;
580 +       ucontrol->value.integer.value[1] =
581 +               (~(right_val >> mc->shift)) & mc->max;
582 +
583 +       return 0;
584 +}
585 +
586 +static int pcm512x_set_reg_master(struct snd_kcontrol *kcontrol,
587 +               struct snd_ctl_elem_value *ucontrol)
588 +{
589 +       struct soc_mixer_control *mc =
590 +               (struct soc_mixer_control *)kcontrol->private_value;
591 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
592 +       struct glb_pool *glb_ptr = card->drvdata;
593 +       struct snd_soc_pcm_runtime *rtd;
594 +       unsigned int left_val = (ucontrol->value.integer.value[0] & mc->max);
595 +       unsigned int right_val = (ucontrol->value.integer.value[1] & mc->max);
596 +       int ret = 0;
597 +
598 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
599 +
600 +       if (digital_gain_0db_limit) {
601 +               ret = snd_soc_limit_volume(card, "Master Playback Volume",
602 +                                       207);
603 +               if (ret < 0)
604 +                       dev_warn(card->dev, "Failed to set volume limit: %d\n",
605 +                               ret);
606 +       }
607 +
608 +       if (glb_ptr->dual_mode != 1) {
609 +               ret = snd_soc_component_write(rtd->codec_dais[1]->component,
610 +                               PCM512x_DIGITAL_VOLUME_2, (~left_val));
611 +               if (ret < 0)
612 +                       return ret;
613 +
614 +               ret = snd_soc_component_write(rtd->codec_dais[0]->component,
615 +                               PCM512x_DIGITAL_VOLUME_3, (~right_val));
616 +               if (ret < 0)
617 +                       return ret;
618 +
619 +       }
620 +
621 +       ret = snd_soc_component_write(rtd->codec_dais[1]->component,
622 +                       PCM512x_DIGITAL_VOLUME_3, (~right_val));
623 +       if (ret < 0)
624 +               return ret;
625 +
626 +       ret = snd_soc_component_write(rtd->codec_dais[0]->component,
627 +                       PCM512x_DIGITAL_VOLUME_2, (~left_val));
628 +       if (ret < 0)
629 +               return ret;
630 +       return 1;
631 +}
632 +
633 +static int pcm512x_get_reg_master_switch(struct snd_kcontrol *kcontrol,
634 +               struct snd_ctl_elem_value *ucontrol)
635 +{
636 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
637 +       struct glb_pool *glb_ptr = card->drvdata;
638 +       struct snd_soc_pcm_runtime *rtd;
639 +       int val = 0;
640 +       int ret;
641 +
642 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
643 +
644 +       ret = snd_soc_component_read(rtd->codec_dais[0]->component, PCM512x_MUTE, &val);
645 +       if (ret < 0)
646 +               return ret;
647 +
648 +       ucontrol->value.integer.value[0] =
649 +                       (val & P_DAC_LEFT_MUTE) ? P_UNMUTE : P_MUTE;
650 +
651 +       if (glb_ptr->dual_mode == 1) {
652 +               ret = snd_soc_component_read(rtd->codec_dais[1]->component, PCM512x_MUTE, &val);
653 +               if (ret < 0)
654 +                       return ret;
655 +       }
656 +       ucontrol->value.integer.value[1] =
657 +                       (val & P_DAC_RIGHT_MUTE) ? P_UNMUTE : P_MUTE;
658 +
659 +       return val;
660 +}
661 +
662 +static int pcm512x_set_reg_master_switch(struct snd_kcontrol *kcontrol,
663 +               struct snd_ctl_elem_value *ucontrol)
664 +{
665 +       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
666 +       struct snd_soc_pcm_runtime *rtd;
667 +       struct glb_pool *glb_ptr = card->drvdata;
668 +       unsigned int left_val = (ucontrol->value.integer.value[0]);
669 +       unsigned int right_val = (ucontrol->value.integer.value[1]);
670 +       int ret = 0;
671 +
672 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
673 +       if (glb_ptr->dual_mode == 1) {
674 +               ret = snd_soc_component_write(rtd->codec_dais[0]->component, PCM512x_MUTE,
675 +                               ~((left_val & 0x01)<<4));
676 +               if (ret < 0)
677 +                       return ret;
678 +               ret = snd_soc_component_write(rtd->codec_dais[1]->component, PCM512x_MUTE,
679 +                               ~((right_val & 0x01)));
680 +               if (ret < 0)
681 +                       return ret;
682 +
683 +       } else if (glb_ptr->set_mode == 1) {
684 +               ret = snd_soc_component_write(rtd->codec_dais[0]->component, PCM512x_MUTE,
685 +                               ~((left_val & 0x01)<<4 | (right_val & 0x01)));
686 +               if (ret < 0)
687 +                       return ret;
688 +
689 +       } else {
690 +               ret = snd_soc_component_write(rtd->codec_dais[0]->component, PCM512x_MUTE,
691 +                               ~((left_val & 0x01)<<4 | (right_val & 0x01)));
692 +               if (ret < 0)
693 +                       return ret;
694 +
695 +               ret = snd_soc_component_write(rtd->codec_dais[1]->component, PCM512x_MUTE,
696 +                               ~((left_val & 0x01)<<4 | (right_val & 0x01)));
697 +               if (ret < 0)
698 +                       return ret;
699 +       }
700 +       return 1;
701 +}
702 +
703 +static const DECLARE_TLV_DB_SCALE(digital_tlv_sub, -10350, 50, 1);
704 +static const DECLARE_TLV_DB_SCALE(digital_tlv_master, -10350, 50, 1);
705 +
706 +static const struct snd_kcontrol_new allo_piano_controls[] = {
707 +       SOC_ENUM_EXT("Subwoofer mode Route",
708 +                       allo_piano_mode_enum,
709 +                       snd_allo_piano_mode_get,
710 +                       snd_allo_piano_mode_put),
711 +
712 +       SOC_ENUM_EXT("Dual Mode Route",
713 +                       allo_piano_dual_mode_enum,
714 +                       snd_allo_piano_dual_mode_get,
715 +                       snd_allo_piano_dual_mode_put),
716 +
717 +       SOC_ENUM_EXT("Lowpass Route", allo_piano_enum,
718 +                       snd_allo_piano_lowpass_get,
719 +                       snd_allo_piano_lowpass_put),
720 +
721 +       SOC_DOUBLE_R_EXT_TLV("Subwoofer Playback Volume",
722 +                       PCM512x_DIGITAL_VOLUME_2,
723 +                       PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
724 +                       pcm512x_get_reg_sub,
725 +                       pcm512x_set_reg_sub,
726 +                       digital_tlv_sub),
727 +
728 +       SOC_DOUBLE_EXT("Subwoofer Playback Switch",
729 +                       PCM512x_MUTE,
730 +                       PCM512x_RQML_SHIFT,
731 +                       PCM512x_RQMR_SHIFT, 1, 1,
732 +                       pcm512x_get_reg_sub_switch,
733 +                       pcm512x_set_reg_sub_switch),
734 +
735 +       SOC_DOUBLE_R_EXT_TLV("Master Playback Volume",
736 +                       PCM512x_DIGITAL_VOLUME_2,
737 +                       PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
738 +                       pcm512x_get_reg_master,
739 +                       pcm512x_set_reg_master,
740 +                       digital_tlv_master),
741 +
742 +       SOC_DOUBLE_EXT("Master Playback Switch",
743 +                       PCM512x_MUTE,
744 +                       PCM512x_RQML_SHIFT,
745 +                       PCM512x_RQMR_SHIFT, 1, 1,
746 +                       pcm512x_get_reg_master_switch,
747 +                       pcm512x_set_reg_master_switch),
748 +};
749 +
750 +static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd)
751 +{
752 +       struct snd_soc_card *card = rtd->card;
753 +       struct glb_pool *glb_ptr;
754 +
755 +       glb_ptr = kmalloc(sizeof(struct glb_pool), GFP_KERNEL);
756 +       if (!glb_ptr)
757 +               return -ENOMEM;
758 +
759 +       memset(glb_ptr, 0x00, sizeof(glb_ptr));
760 +       card->drvdata = glb_ptr;
761 +       glb_ptr->dual_mode = 2;
762 +       glb_ptr->set_mode = 0;
763 +
764 +       mutex_init(&glb_ptr->lock);
765 +
766 +       if (digital_gain_0db_limit) {
767 +               int ret;
768 +
769 +               ret = snd_soc_limit_volume(card, "Digital Playback Volume",
770 +                                       207);
771 +               if (ret < 0)
772 +                       dev_warn(card->dev, "Failed to set volume limit: %d\n",
773 +                               ret);
774 +       }
775 +       return 0;
776 +}
777 +
778 +static void snd_allo_piano_gpio_mute(struct snd_soc_card *card)
779 +{
780 +       if (mute_gpio[0])
781 +               gpiod_set_value_cansleep(mute_gpio[0], P_MUTE);
782 +
783 +       if (mute_gpio[1])
784 +               gpiod_set_value_cansleep(mute_gpio[1], P_MUTE);
785 +}
786 +
787 +static void snd_allo_piano_gpio_unmute(struct snd_soc_card *card)
788 +{
789 +       if (mute_gpio[0])
790 +               gpiod_set_value_cansleep(mute_gpio[0], P_UNMUTE);
791 +
792 +       if (mute_gpio[1])
793 +               gpiod_set_value_cansleep(mute_gpio[1], P_UNMUTE);
794 +}
795 +
796 +static int snd_allo_piano_set_bias_level(struct snd_soc_card *card,
797 +       struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
798 +{
799 +       struct snd_soc_pcm_runtime *rtd;
800 +       struct snd_soc_dai *codec_dai;
801 +
802 +       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
803 +       codec_dai = rtd->codec_dai;
804 +
805 +       if (dapm->dev != codec_dai->dev)
806 +               return 0;
807 +
808 +       switch (level) {
809 +       case SND_SOC_BIAS_PREPARE:
810 +               if (dapm->bias_level != SND_SOC_BIAS_STANDBY)
811 +                       break;
812 +               /* UNMUTE DAC */
813 +               snd_allo_piano_gpio_unmute(card);
814 +               break;
815 +
816 +       case SND_SOC_BIAS_STANDBY:
817 +               if (dapm->bias_level != SND_SOC_BIAS_PREPARE)
818 +                       break;
819 +               /* MUTE DAC */
820 +               snd_allo_piano_gpio_mute(card);
821 +               break;
822 +
823 +       default:
824 +               break;
825 +       }
826 +
827 +       return 0;
828 +}
829 +
830 +static int snd_allo_piano_dac_startup(
831 +       struct snd_pcm_substream *substream)
832 +{
833 +       struct snd_soc_pcm_runtime *rtd = substream->private_data;
834 +       struct snd_soc_card *card = rtd->card;
835 +
836 +       snd_allo_piano_gpio_mute(card);
837 +
838 +       return 0;
839 +}
840 +
841 +static int snd_allo_piano_dac_hw_params(
842 +               struct snd_pcm_substream *substream,
843 +               struct snd_pcm_hw_params *params)
844 +{
845 +       struct snd_soc_pcm_runtime *rtd = substream->private_data;
846 +       unsigned int rate = params_rate(params);
847 +       struct snd_soc_card *card = rtd->card;
848 +       struct glb_pool *glb_ptr = card->drvdata;
849 +       int ret = 0, val = 0, dac;
850 +
851 +       for (dac = 0; (glb_mclk && dac < 2); dac++) {
852 +               /* Configure the PLL clock reference for both the Codecs */
853 +               ret = snd_soc_component_read(rtd->codec_dais[dac]->component,
854 +                                       PCM512x_RATE_DET_4, &val);
855 +               if (ret < 0) {
856 +                       dev_err(rtd->codec_dais[dac]->component->dev,
857 +                               "Failed to read register PCM512x_RATE_DET_4\n");
858 +                       return ret;
859 +               }
860 +
861 +               if (val & 0x40) {
862 +                       snd_soc_component_write(rtd->codec_dais[dac]->component,
863 +                                       PCM512x_PLL_REF,
864 +                                       PCM512x_SREF_BCK);
865 +
866 +                       dev_info(rtd->codec_dais[dac]->component->dev,
867 +                               "Setting BCLK as input clock & Enable PLL\n");
868 +               } else {
869 +                       snd_soc_component_write(rtd->codec_dais[dac]->component,
870 +                                       PCM512x_PLL_EN,
871 +                                       0x00);
872 +
873 +                       snd_soc_component_write(rtd->codec_dais[dac]->component,
874 +                                       PCM512x_PLL_REF,
875 +                                       PCM512x_SREF_SCK);
876 +
877 +                       dev_info(rtd->codec_dais[dac]->component->dev,
878 +                               "Setting SCLK as input clock & disabled PLL\n");
879 +               }
880 +       }
881 +
882 +       ret = snd_allo_piano_dsp_program(rtd, glb_ptr->set_mode, rate,
883 +                                               glb_ptr->set_lowpass);
884 +       if (ret < 0)
885 +               return ret;
886 +
887 +       return ret;
888 +}
889 +
890 +static int snd_allo_piano_dac_prepare(
891 +       struct snd_pcm_substream *substream)
892 +{
893 +       struct snd_soc_pcm_runtime *rtd = substream->private_data;
894 +       struct snd_soc_card *card = rtd->card;
895 +
896 +       snd_allo_piano_gpio_unmute(card);
897 +
898 +       return 0;
899 +}
900 +
901 +/* machine stream operations */
902 +static struct snd_soc_ops snd_allo_piano_dac_ops = {
903 +       .startup = snd_allo_piano_dac_startup,
904 +       .hw_params = snd_allo_piano_dac_hw_params,
905 +       .prepare = snd_allo_piano_dac_prepare,
906 +};
907 +
908 +static struct snd_soc_dai_link_component allo_piano_2_1_codecs[] = {
909 +       {
910 +               .dai_name = "pcm512x-hifi",
911 +       },
912 +       {
913 +               .dai_name = "pcm512x-hifi",
914 +       },
915 +};
916 +
917 +static struct snd_soc_dai_link snd_allo_piano_dac_dai[] = {
918 +       {
919 +               .name           = "PianoDACPlus",
920 +               .stream_name    = "PianoDACPlus",
921 +               .cpu_dai_name   = "bcm2708-i2s.0",
922 +               .platform_name  = "bcm2708-i2s.0",
923 +               .codecs         = allo_piano_2_1_codecs,
924 +               .num_codecs     = 2,
925 +               .dai_fmt        = SND_SOC_DAIFMT_I2S |
926 +                               SND_SOC_DAIFMT_NB_NF |
927 +                               SND_SOC_DAIFMT_CBS_CFS,
928 +               .ops            = &snd_allo_piano_dac_ops,
929 +               .init           = snd_allo_piano_dac_init,
930 +       },
931 +};
932 +
933 +/* audio machine driver */
934 +static struct snd_soc_card snd_allo_piano_dac = {
935 +       .name = "PianoDACPlus",
936 +       .owner = THIS_MODULE,
937 +       .dai_link = snd_allo_piano_dac_dai,
938 +       .num_links = ARRAY_SIZE(snd_allo_piano_dac_dai),
939 +       .controls = allo_piano_controls,
940 +       .num_controls = ARRAY_SIZE(allo_piano_controls),
941 +};
942 +
943 +static int snd_allo_piano_dac_probe(struct platform_device *pdev)
944 +{
945 +       struct snd_soc_card *card = &snd_allo_piano_dac;
946 +       int ret = 0, i = 0;
947 +
948 +       card->dev = &pdev->dev;
949 +       platform_set_drvdata(pdev, &snd_allo_piano_dac);
950 +
951 +       if (pdev->dev.of_node) {
952 +               struct device_node *i2s_node;
953 +               struct snd_soc_dai_link *dai;
954 +
955 +               dai = &snd_allo_piano_dac_dai[0];
956 +               i2s_node = of_parse_phandle(pdev->dev.of_node,
957 +                                               "i2s-controller", 0);
958 +               if (i2s_node) {
959 +                       for (i = 0; i < card->num_links; i++) {
960 +                               dai->cpu_dai_name = NULL;
961 +                               dai->cpu_of_node = i2s_node;
962 +                               dai->platform_name = NULL;
963 +                               dai->platform_of_node = i2s_node;
964 +                       }
965 +               }
966 +               digital_gain_0db_limit =
967 +                       !of_property_read_bool(pdev->dev.of_node,
968 +                                               "allo,24db_digital_gain");
969 +
970 +               glb_mclk = of_property_read_bool(pdev->dev.of_node,
971 +                                               "allo,glb_mclk");
972 +
973 +               allo_piano_2_1_codecs[0].of_node =
974 +                       of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
975 +               if (!allo_piano_2_1_codecs[0].of_node) {
976 +                       dev_err(&pdev->dev,
977 +                               "Property 'audio-codec' missing or invalid\n");
978 +                       return -EINVAL;
979 +               }
980 +
981 +               allo_piano_2_1_codecs[1].of_node =
982 +                       of_parse_phandle(pdev->dev.of_node, "audio-codec", 1);
983 +               if (!allo_piano_2_1_codecs[1].of_node) {
984 +                       dev_err(&pdev->dev,
985 +                               "Property 'audio-codec' missing or invalid\n");
986 +                       return -EINVAL;
987 +               }
988 +
989 +               mute_gpio[0] = devm_gpiod_get_optional(&pdev->dev, "mute1",
990 +                                                       GPIOD_OUT_LOW);
991 +               if (IS_ERR(mute_gpio[0])) {
992 +                       ret = PTR_ERR(mute_gpio[0]);
993 +                       dev_err(&pdev->dev,
994 +                               "failed to get mute1 gpio6: %d\n", ret);
995 +                       return ret;
996 +               }
997 +
998 +               mute_gpio[1] = devm_gpiod_get_optional(&pdev->dev, "mute2",
999 +                                                       GPIOD_OUT_LOW);
1000 +               if (IS_ERR(mute_gpio[1])) {
1001 +                       ret = PTR_ERR(mute_gpio[1]);
1002 +                       dev_err(&pdev->dev,
1003 +                               "failed to get mute2 gpio25: %d\n", ret);
1004 +                       return ret;
1005 +               }
1006 +
1007 +               if (mute_gpio[0] && mute_gpio[1])
1008 +                       snd_allo_piano_dac.set_bias_level =
1009 +                               snd_allo_piano_set_bias_level;
1010 +
1011 +               ret = snd_soc_register_card(&snd_allo_piano_dac);
1012 +               if (ret < 0) {
1013 +                       dev_err(&pdev->dev,
1014 +                               "snd_soc_register_card() failed: %d\n", ret);
1015 +                       return ret;
1016 +               }
1017 +
1018 +               if ((mute_gpio[0]) && (mute_gpio[1]))
1019 +                       snd_allo_piano_gpio_mute(&snd_allo_piano_dac);
1020 +
1021 +               return 0;
1022 +       }
1023 +
1024 +       return -EINVAL;
1025 +}
1026 +
1027 +static int snd_allo_piano_dac_remove(struct platform_device *pdev)
1028 +{
1029 +       struct snd_soc_card *card = platform_get_drvdata(pdev);
1030 +
1031 +       kfree(&card->drvdata);
1032 +       snd_allo_piano_gpio_mute(&snd_allo_piano_dac);
1033 +       return snd_soc_unregister_card(&snd_allo_piano_dac);
1034 +}
1035 +
1036 +static const struct of_device_id snd_allo_piano_dac_of_match[] = {
1037 +       { .compatible = "allo,piano-dac-plus", },
1038 +       { /* sentinel */ },
1039 +};
1040 +
1041 +MODULE_DEVICE_TABLE(of, snd_allo_piano_dac_of_match);
1042 +
1043 +static struct platform_driver snd_allo_piano_dac_driver = {
1044 +       .driver = {
1045 +               .name = "snd-allo-piano-dac-plus",
1046 +               .owner = THIS_MODULE,
1047 +               .of_match_table = snd_allo_piano_dac_of_match,
1048 +       },
1049 +       .probe = snd_allo_piano_dac_probe,
1050 +       .remove = snd_allo_piano_dac_remove,
1051 +};
1052 +
1053 +module_platform_driver(snd_allo_piano_dac_driver);
1054 +
1055 +MODULE_AUTHOR("Baswaraj K <jaikumar@cem-solutions.net>");
1056 +MODULE_DESCRIPTION("ALSA ASoC Machine Driver for Allo Piano DAC Plus");
1057 +MODULE_LICENSE("GPL v2");