Update Allo Piano Dac Driver
authorpaul-1 <6473457+paul-1@users.noreply.github.com>
Fri, 2 Apr 2021 14:56:19 +0000 (10:56 -0400)
committerPhil Elwell <8911409+pelwell@users.noreply.github.com>
Fri, 9 Apr 2021 08:33:23 +0000 (09:33 +0100)
Add unique names to the individual dac coded drivers
Remove some of the codec controls that are not used.

Signed-off-by: Paul Hermann <paul@picoreplayer.org>
# Conflicts:
# sound/soc/bcm/allo-piano-dac-plus.c

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

index 0e04c47..fd0fe58 100644 (file)
@@ -2,7 +2,8 @@
  * ALSA ASoC Machine Driver for Allo Piano DAC Plus Subwoofer
  *
  * Author:     Baswaraj K <jaikumar@cem-solutions.net>
- *             Copyright 2016
+ *             Copyright 2020
+ *             based on code by David Knell <david.knell@gmail.com)
  *             based on code by Daniel Matuschek <info@crazy-audio.com>
  *             based on code by Florian Meier <florian.meier@koalo.de>
  *
@@ -276,8 +277,15 @@ static int snd_allo_piano_dual_mode_put(struct snd_kcontrol *kcontrol,
                                PCM512x_DIGITAL_VOLUME_2, 0xff);
 
                list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
-                       if (!strncmp(kctl->id.name, "Digital Playback Volume",
-                                       sizeof(kctl->id.name))) {
+                       if (!strncmp(kctl->id.name, "Main Digital Playback Volume",
+                               sizeof(kctl->id.name))) {
+                               mc = (struct soc_mixer_control *)
+                                       kctl->private_value;
+                               mc->rreg = mc->reg;
+                               break;
+                       }
+                       if (!strncmp(kctl->id.name, "Sub Digital Playback Volume",
+                               sizeof(kctl->id.name))) {
                                mc = (struct soc_mixer_control *)
                                        kctl->private_value;
                                mc->rreg = mc->reg;
@@ -291,13 +299,20 @@ static int snd_allo_piano_dual_mode_put(struct snd_kcontrol *kcontrol,
                                                PCM512x_DIGITAL_VOLUME_3);
 
                list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
-                       if (!strncmp(kctl->id.name, "Digital Playback Volume",
-                                       sizeof(kctl->id.name))) {
+                       if (!strncmp(kctl->id.name, "Main Digital Playback Volume",
+                               sizeof(kctl->id.name))) {
                                mc = (struct soc_mixer_control *)
                                        kctl->private_value;
                                mc->rreg = PCM512x_DIGITAL_VOLUME_3;
                                break;
                        }
+                       if (!strncmp(kctl->id.name, "Sub Digital Playback Volume",
+                               sizeof(kctl->id.name))) {
+                               mc = (struct soc_mixer_control *)
+                                       kctl->private_value;
+                               mc->rreg = PCM512x_DIGITAL_VOLUME_2;
+                               break;
+                       }
                }
 
                snd_soc_component_write(asoc_rtd_to_codec(rtd, 0)->component,
@@ -344,13 +359,20 @@ static int snd_allo_piano_mode_put(struct snd_kcontrol *kcontrol,
                                                PCM512x_DIGITAL_VOLUME_2);
 
                list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
-                       if (!strncmp(kctl->id.name, "Digital Playback Volume",
-                                       sizeof(kctl->id.name))) {
+                       if (!strncmp(kctl->id.name, "Main Digital Playback Volume",
+                               sizeof(kctl->id.name))) {
                                mc = (struct soc_mixer_control *)
                                        kctl->private_value;
                                mc->rreg = PCM512x_DIGITAL_VOLUME_3;
                                break;
                        }
+                       if (!strncmp(kctl->id.name, "Sub Digital Playback Volume",
+                               sizeof(kctl->id.name))) {
+                               mc = (struct soc_mixer_control *)
+                                       kctl->private_value;
+                               mc->rreg = PCM512x_DIGITAL_VOLUME_2;
+                               break;
+                       }
                }
                snd_soc_component_write(asoc_rtd_to_codec(rtd, 0)->component,
                                PCM512x_DIGITAL_VOLUME_3, left_val);
@@ -397,6 +419,7 @@ static int pcm512x_get_reg_sub(struct snd_kcontrol *kcontrol,
        unsigned int left_val = 0;
        unsigned int right_val = 0;
        rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
+
        right_val = snd_soc_component_read(asoc_rtd_to_codec(rtd, 1)->component,
                        PCM512x_DIGITAL_VOLUME_3);
        if (glb_ptr->dual_mode != 1) {
@@ -428,12 +451,6 @@ static int pcm512x_set_reg_sub(struct snd_kcontrol *kcontrol,
        int ret = 0;
 
        rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
-       if (glb_ptr->dual_mode != 1) {
-               ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 1)->component,
-                               PCM512x_DIGITAL_VOLUME_2, (~left_val));
-               if (ret < 0)
-                       return ret;
-       }
 
        if (digital_gain_0db_limit) {
                ret = snd_soc_limit_volume(card, "Subwoofer Playback Volume",
@@ -443,10 +460,20 @@ static int pcm512x_set_reg_sub(struct snd_kcontrol *kcontrol,
                                ret);
        }
 
-       ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 1)->component,
-                       PCM512x_DIGITAL_VOLUME_3, (~right_val));
-       if (ret < 0)
-               return ret;
+       // When in Dual Mono, Sub vol control should not set anything.
+       if (glb_ptr->dual_mode != 1) { //Not in Dual Mono mode
+
+               ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 1)->component,
+                               PCM512x_DIGITAL_VOLUME_2, (~left_val));
+               if (ret < 0)
+                       return ret;
+
+               ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 1)->component,
+                               PCM512x_DIGITAL_VOLUME_3, (~right_val));
+               if (ret < 0)
+                       return ret;
+
+       }
 
        return 1;
 }
@@ -505,7 +532,7 @@ static int pcm512x_get_reg_master(struct snd_kcontrol *kcontrol,
        left_val = snd_soc_component_read(asoc_rtd_to_codec(rtd, 0)->component,
                        PCM512x_DIGITAL_VOLUME_2);
 
-       if (glb_ptr->dual_mode == 1) {
+       if (glb_ptr->dual_mode == 1) {  // in Dual Mono mode
                right_val = snd_soc_component_read(asoc_rtd_to_codec(rtd, 1)->component,
                                PCM512x_DIGITAL_VOLUME_3);
        } else {
@@ -543,8 +570,21 @@ static int pcm512x_set_reg_master(struct snd_kcontrol *kcontrol,
                                ret);
        }
 
-       if (glb_ptr->dual_mode != 1) {
+       if (glb_ptr->dual_mode == 1) { //in Dual Mono Mode
+
+               ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 0)->component,
+                               PCM512x_DIGITAL_VOLUME_2, (~left_val));
+               if (ret < 0)
+                       return ret;
+
                ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 1)->component,
+                               PCM512x_DIGITAL_VOLUME_3, (~right_val));
+               if (ret < 0)
+                       return ret;
+
+       } else {
+
+               ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 0)->component,
                                PCM512x_DIGITAL_VOLUME_2, (~left_val));
                if (ret < 0)
                        return ret;
@@ -555,16 +595,6 @@ static int pcm512x_set_reg_master(struct snd_kcontrol *kcontrol,
                        return ret;
 
        }
-
-       ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 1)->component,
-                       PCM512x_DIGITAL_VOLUME_3, (~right_val));
-       if (ret < 0)
-               return ret;
-
-       ret = snd_soc_component_write(asoc_rtd_to_codec(rtd, 0)->component,
-                       PCM512x_DIGITAL_VOLUME_2, (~left_val));
-       if (ret < 0)
-               return ret;
        return 1;
 }
 
@@ -680,10 +710,32 @@ static const struct snd_kcontrol_new allo_piano_controls[] = {
                        pcm512x_set_reg_master_switch),
 };
 
+static const char * const codec_ctl_pfx[] = { "Main", "Sub" };
+static const char * const codec_ctl_name[] = {
+       "Digital Playback Volume",
+       "Digital Playback Switch",
+       "Auto Mute Mono Switch",
+       "Auto Mute Switch",
+       "Auto Mute Time Left",
+       "Auto Mute Time Right",
+       "Clock Missing Period",
+       "Max Overclock DAC",
+       "Max Overclock DSP",
+       "Max Overclock PLL",
+       "Volume Ramp Down Emergency Rate",
+       "Volume Ramp Down Emergency Step",
+       "Volume Ramp Up Rate",
+       "Volume Ramp Down Rate",
+       "Volume Ramp Up Step",
+       "Volume Ramp Down Step"
+};
+
 static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_card *card = rtd->card;
        struct glb_pool *glb_ptr;
+       struct snd_kcontrol *kctl;
+       int i, j;
 
        glb_ptr = kzalloc(sizeof(struct glb_pool), GFP_KERNEL);
        if (!glb_ptr)
@@ -698,12 +750,36 @@ static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd)
        if (digital_gain_0db_limit) {
                int ret;
 
-               ret = snd_soc_limit_volume(card, "Digital Playback Volume",
-                                       207);
-               if (ret < 0)
-                       dev_warn(card->dev, "Failed to set volume limit: %d\n",
-                               ret);
+               //Set volume limit on both dacs
+               for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) {
+                       char cname[256];
+
+                       sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[0]);
+                       ret = snd_soc_limit_volume(card, cname, 207);
+                       if (ret < 0)
+                               dev_warn(card->dev, "Failed to set volume limit: %d\n",
+                                       ret);
+               }
+       }
+
+       // Remove codec controls
+       for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) {
+               for (j = 0; j < ARRAY_SIZE(codec_ctl_name); j++) {
+                       char cname[256];
+
+                       sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[j]);
+                       kctl = snd_soc_card_get_kcontrol(card, cname);
+                       if (!kctl) {
+                               dev_err(rtd->card->dev, "Control %s not found\n",
+                                      cname);
+                       } else {
+                               kctl->vd[0].access =
+                                       SNDRV_CTL_ELEM_ACCESS_READWRITE;
+                               snd_ctl_remove(card->snd_card, kctl);
+                       }
+               }
        }
+
        return 0;
 }
 
@@ -842,10 +918,10 @@ static struct snd_soc_dai_link_component allo_piano_2_1_codecs[] = {
 };
 
 SND_SOC_DAILINK_DEFS(allo_piano_dai_plus,
-       DAILINK_COMP_ARRAY(COMP_CPU("bcm2708-i2s.0")),
-       DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "pcm512x-hifi"),
-                          COMP_CODEC(NULL, "pcm512x-hifi")),
-       DAILINK_COMP_ARRAY(COMP_PLATFORM("bcm2708-i2s.0")));
+       DAILINK_COMP_ARRAY(COMP_EMPTY()),
+       DAILINK_COMP_ARRAY(COMP_CODEC("pcm512x.1-004c", "pcm512x-hifi"),
+                          COMP_CODEC("pcm512x.1-004d", "pcm512x-hifi")),
+       DAILINK_COMP_ARRAY(COMP_EMPTY()));
 
 static struct snd_soc_dai_link snd_allo_piano_dac_dai[] = {
        {