Skip to content

Commit 3222d6d

Browse files
allocompopcornmix
allocom
authored andcommitted
allo-piano-dac-plus: Master volume added
Master volume added, which controls both DACs volumes. See: #2149
1 parent fb44d00 commit 3222d6d

File tree

1 file changed

+204
-24
lines changed

1 file changed

+204
-24
lines changed

sound/soc/bcm/allo-piano-dac-plus.c

Lines changed: 204 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@
2828
#include <sound/tlv.h>
2929
#include "../codecs/pcm512x.h"
3030

31+
#define P_DAC_LEFT_MUTE 0x10
32+
#define P_DAC_RIGHT_MUTE 0x01
33+
#define P_DAC_MUTE 0x11
34+
#define P_DAC_UNMUTE 0x00
35+
#define P_MUTE 1
36+
#define P_UNMUTE 0
37+
3138
struct dsp_code {
3239
char i2c_addr;
3340
char offset;
@@ -129,16 +136,20 @@ static int __snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd,
129136
return 1;
130137

131138
case 1: /* 2.0 */
132-
snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE, 0x00);
133-
snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE, 0x11);
139+
snd_soc_write(rtd->codec_dais[0]->codec,
140+
PCM512x_MUTE, P_DAC_UNMUTE);
141+
snd_soc_write(rtd->codec_dais[1]->codec,
142+
PCM512x_MUTE, P_DAC_MUTE);
134143
glb_ptr->set_rate = rate;
135144
glb_ptr->set_mode = mode;
136145
glb_ptr->set_lowpass = lowpass;
137146
return 1;
138147

139148
default:
140-
snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE, 0x00);
141-
snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE, 0x00);
149+
snd_soc_write(rtd->codec_dais[0]->codec,
150+
PCM512x_MUTE, P_DAC_UNMUTE);
151+
snd_soc_write(rtd->codec_dais[1]->codec,
152+
PCM512x_MUTE, P_DAC_UNMUTE);
142153
}
143154

144155
for (dac = 0; dac < rtd->num_codecs; dac++) {
@@ -173,8 +184,8 @@ static int __snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd,
173184
if (dsp_code_read->offset == 0) {
174185
glb_ptr->dsp_page_number = dsp_code_read->val;
175186
ret = snd_soc_write(rtd->codec_dais[dac]->codec,
176-
PCM512x_PAGE_BASE(0),
177-
dsp_code_read->val);
187+
PCM512x_PAGE_BASE(0),
188+
dsp_code_read->val);
178189

179190
} else if (dsp_code_read->offset != 0) {
180191
ret = snd_soc_write(rtd->codec_dais[dac]->codec,
@@ -211,8 +222,8 @@ static int snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd,
211222

212223
mutex_lock(&glb_ptr->lock);
213224

214-
ret = __snd_allo_piano_dsp_program(rtd,
215-
mode, rate, lowpass);
225+
ret = __snd_allo_piano_dsp_program(rtd, mode, rate, lowpass);
226+
216227
mutex_unlock(&glb_ptr->lock);
217228

218229
return ret;
@@ -245,19 +256,20 @@ static int snd_allo_piano_dual_mode_put(struct snd_kcontrol *kcontrol,
245256
if (ucontrol->value.integer.value[0] > 0) {
246257
glb_ptr->dual_mode = ucontrol->value.integer.value[0];
247258
glb_ptr->set_mode = 0;
248-
} else if (ucontrol->value.integer.value[0] <= 0) {
259+
} else {
249260
if (glb_ptr->set_mode <= 0) {
250261
glb_ptr->dual_mode = 1;
251262
glb_ptr->set_mode = 0;
263+
} else {
264+
glb_ptr->dual_mode = 0;
252265
}
253-
} else {
254-
glb_ptr->dual_mode = 0;
255-
return 0;
256266
}
257267

258-
if (glb_ptr->dual_mode == 1) {
259-
snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE, 0x01);
260-
snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE, 0x10);
268+
if (glb_ptr->dual_mode == 1) { // Dual Mono
269+
snd_soc_write(rtd->codec_dais[0]->codec,
270+
PCM512x_MUTE, P_DAC_RIGHT_MUTE);
271+
snd_soc_write(rtd->codec_dais[1]->codec,
272+
PCM512x_MUTE, P_DAC_LEFT_MUTE);
261273
snd_soc_write(rtd->codec_dais[0]->codec,
262274
PCM512x_DIGITAL_VOLUME_3, 0xff);
263275
snd_soc_write(rtd->codec_dais[1]->codec,
@@ -292,8 +304,10 @@ static int snd_allo_piano_dual_mode_put(struct snd_kcontrol *kcontrol,
292304
PCM512x_DIGITAL_VOLUME_3, left_val);
293305
snd_soc_write(rtd->codec_dais[1]->codec,
294306
PCM512x_DIGITAL_VOLUME_2, right_val);
295-
snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE, 0x00);
296-
snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE, 0x00);
307+
snd_soc_write(rtd->codec_dais[0]->codec,
308+
PCM512x_MUTE, P_DAC_UNMUTE);
309+
snd_soc_write(rtd->codec_dais[1]->codec,
310+
PCM512x_MUTE, P_DAC_UNMUTE);
297311
}
298312

299313
return 0;
@@ -400,7 +414,7 @@ static int pcm512x_get_reg_sub(struct snd_kcontrol *kcontrol,
400414
}
401415

402416
ucontrol->value.integer.value[0] =
403-
(~(left_val >> mc->shift)) & mc->max;
417+
(~(left_val >> mc->shift)) & mc->max;
404418
ucontrol->value.integer.value[1] =
405419
(~(right_val >> mc->shift)) & mc->max;
406420

@@ -447,8 +461,10 @@ static int pcm512x_get_reg_sub_switch(struct snd_kcontrol *kcontrol,
447461
if (val < 0)
448462
return val;
449463

450-
ucontrol->value.integer.value[0] = (val & 0x10) ? 0 : 1;
451-
ucontrol->value.integer.value[1] = (val & 0x01) ? 0 : 1;
464+
ucontrol->value.integer.value[0] =
465+
(val & P_DAC_LEFT_MUTE) ? P_UNMUTE : P_MUTE;
466+
ucontrol->value.integer.value[1] =
467+
(val & P_DAC_RIGHT_MUTE) ? P_UNMUTE : P_MUTE;
452468

453469
return val;
454470
}
@@ -474,7 +490,153 @@ static int pcm512x_set_reg_sub_switch(struct snd_kcontrol *kcontrol,
474490

475491
}
476492

493+
static int pcm512x_get_reg_master(struct snd_kcontrol *kcontrol,
494+
struct snd_ctl_elem_value *ucontrol)
495+
{
496+
struct soc_mixer_control *mc =
497+
(struct soc_mixer_control *)kcontrol->private_value;
498+
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
499+
struct glb_pool *glb_ptr = card->drvdata;
500+
struct snd_soc_pcm_runtime *rtd;
501+
unsigned int left_val = 0, right_val = 0;
502+
503+
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
504+
505+
left_val = snd_soc_read(rtd->codec_dais[0]->codec,
506+
PCM512x_DIGITAL_VOLUME_2);
507+
if (left_val < 0)
508+
return left_val;
509+
510+
if (glb_ptr->dual_mode == 1) {
511+
right_val = snd_soc_read(rtd->codec_dais[1]->codec,
512+
PCM512x_DIGITAL_VOLUME_3);
513+
if (right_val < 0)
514+
return right_val;
515+
} else {
516+
right_val = snd_soc_read(rtd->codec_dais[0]->codec,
517+
PCM512x_DIGITAL_VOLUME_3);
518+
if (right_val < 0)
519+
return right_val;
520+
}
521+
522+
ucontrol->value.integer.value[0] =
523+
(~(left_val >> mc->shift)) & mc->max;
524+
ucontrol->value.integer.value[1] =
525+
(~(right_val >> mc->shift)) & mc->max;
526+
527+
return 0;
528+
}
529+
530+
static int pcm512x_set_reg_master(struct snd_kcontrol *kcontrol,
531+
struct snd_ctl_elem_value *ucontrol)
532+
{
533+
struct soc_mixer_control *mc =
534+
(struct soc_mixer_control *)kcontrol->private_value;
535+
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
536+
struct glb_pool *glb_ptr = card->drvdata;
537+
struct snd_soc_pcm_runtime *rtd;
538+
unsigned int left_val = (ucontrol->value.integer.value[0] & mc->max);
539+
unsigned int right_val = (ucontrol->value.integer.value[1] & mc->max);
540+
int ret = 0;
541+
542+
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
543+
544+
if (glb_ptr->dual_mode != 1) {
545+
ret = snd_soc_write(rtd->codec_dais[1]->codec,
546+
PCM512x_DIGITAL_VOLUME_2, (~left_val));
547+
if (ret < 0)
548+
return ret;
549+
550+
ret = snd_soc_write(rtd->codec_dais[0]->codec,
551+
PCM512x_DIGITAL_VOLUME_3, (~right_val));
552+
if (ret < 0)
553+
return ret;
554+
555+
}
556+
557+
ret = snd_soc_write(rtd->codec_dais[1]->codec,
558+
PCM512x_DIGITAL_VOLUME_3, (~right_val));
559+
if (ret < 0)
560+
return ret;
561+
562+
ret = snd_soc_write(rtd->codec_dais[0]->codec,
563+
PCM512x_DIGITAL_VOLUME_2, (~left_val));
564+
if (ret < 0)
565+
return ret;
566+
return 1;
567+
}
568+
569+
static int pcm512x_get_reg_master_switch(struct snd_kcontrol *kcontrol,
570+
struct snd_ctl_elem_value *ucontrol)
571+
{
572+
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
573+
struct glb_pool *glb_ptr = card->drvdata;
574+
struct snd_soc_pcm_runtime *rtd;
575+
int val = 0;
576+
577+
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
578+
579+
val = snd_soc_read(rtd->codec_dais[0]->codec, PCM512x_MUTE);
580+
if (val < 0)
581+
return val;
582+
583+
ucontrol->value.integer.value[0] =
584+
(val & P_DAC_LEFT_MUTE) ? P_UNMUTE : P_MUTE;
585+
586+
if (glb_ptr->dual_mode == 1) {
587+
val = snd_soc_read(rtd->codec_dais[1]->codec, PCM512x_MUTE);
588+
if (val < 0)
589+
return val;
590+
}
591+
ucontrol->value.integer.value[1] =
592+
(val & P_DAC_RIGHT_MUTE) ? P_UNMUTE : P_MUTE;
593+
594+
return val;
595+
}
596+
597+
static int pcm512x_set_reg_master_switch(struct snd_kcontrol *kcontrol,
598+
struct snd_ctl_elem_value *ucontrol)
599+
{
600+
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
601+
struct snd_soc_pcm_runtime *rtd;
602+
struct glb_pool *glb_ptr = card->drvdata;
603+
unsigned int left_val = (ucontrol->value.integer.value[0]);
604+
unsigned int right_val = (ucontrol->value.integer.value[1]);
605+
int ret = 0;
606+
607+
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
608+
if (glb_ptr->dual_mode == 1) {
609+
ret = snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE,
610+
~((left_val & 0x01)<<4));
611+
if (ret < 0)
612+
return ret;
613+
ret = snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE,
614+
~((right_val & 0x01)));
615+
if (ret < 0)
616+
return ret;
617+
618+
} else if (glb_ptr->set_mode == 1) {
619+
ret = snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE,
620+
~((left_val & 0x01)<<4 | (right_val & 0x01)));
621+
if (ret < 0)
622+
return ret;
623+
624+
} else {
625+
ret = snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE,
626+
~((left_val & 0x01)<<4 | (right_val & 0x01)));
627+
if (ret < 0)
628+
return ret;
629+
630+
ret = snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE,
631+
~((left_val & 0x01)<<4 | (right_val & 0x01)));
632+
if (ret < 0)
633+
return ret;
634+
}
635+
return 1;
636+
}
637+
477638
static const DECLARE_TLV_DB_SCALE(digital_tlv_sub, -10350, 50, 1);
639+
static const DECLARE_TLV_DB_SCALE(digital_tlv_master, -10350, 50, 1);
478640

479641
static const struct snd_kcontrol_new allo_piano_controls[] = {
480642
SOC_ENUM_EXT("Subwoofer mode Route",
@@ -504,6 +666,20 @@ static const struct snd_kcontrol_new allo_piano_controls[] = {
504666
PCM512x_RQMR_SHIFT, 1, 1,
505667
pcm512x_get_reg_sub_switch,
506668
pcm512x_set_reg_sub_switch),
669+
670+
SOC_DOUBLE_R_EXT_TLV("Master Playback Volume",
671+
PCM512x_DIGITAL_VOLUME_2,
672+
PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
673+
pcm512x_get_reg_master,
674+
pcm512x_set_reg_master,
675+
digital_tlv_master),
676+
677+
SOC_DOUBLE_EXT("Master Playback Switch",
678+
PCM512x_MUTE,
679+
PCM512x_RQML_SHIFT,
680+
PCM512x_RQMR_SHIFT, 1, 1,
681+
pcm512x_get_reg_master_switch,
682+
pcm512x_set_reg_master_switch),
507683
};
508684

509685
static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd)
@@ -535,19 +711,19 @@ static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd)
535711
static void snd_allo_piano_gpio_mute(struct snd_soc_card *card)
536712
{
537713
if (mute_gpio[0])
538-
gpiod_set_value_cansleep(mute_gpio[0], 1);
714+
gpiod_set_value_cansleep(mute_gpio[0], P_MUTE);
539715

540716
if (mute_gpio[1])
541-
gpiod_set_value_cansleep(mute_gpio[1], 1);
717+
gpiod_set_value_cansleep(mute_gpio[1], P_MUTE);
542718
}
543719

544720
static void snd_allo_piano_gpio_unmute(struct snd_soc_card *card)
545721
{
546722
if (mute_gpio[0])
547-
gpiod_set_value_cansleep(mute_gpio[0], 0);
723+
gpiod_set_value_cansleep(mute_gpio[0], P_UNMUTE);
548724

549725
if (mute_gpio[1])
550-
gpiod_set_value_cansleep(mute_gpio[1], 0);
726+
gpiod_set_value_cansleep(mute_gpio[1], P_UNMUTE);
551727
}
552728

553729
static int snd_allo_piano_set_bias_level(struct snd_soc_card *card,
@@ -645,6 +821,10 @@ static int snd_allo_piano_dac_hw_params(
645821
if (ret < 0)
646822
dev_warn(card->dev, "Failed to set volume limit: %d\n",
647823
ret);
824+
ret = snd_soc_limit_volume(card, "Master Playback Volume", 207);
825+
if (ret < 0)
826+
dev_warn(card->dev, "Failed to set volume limit: %d\n",
827+
ret);
648828
}
649829

650830
ret = snd_allo_piano_dsp_program(rtd, glb_ptr->set_mode, rate,

0 commit comments

Comments
 (0)