diff options
author | Allo <sparky-dev@allo.com> | 2017-07-03 15:45:20 +0530 |
---|---|---|
committer | Phil Elwell <pelwell@users.noreply.github.com> | 2017-07-03 11:15:20 +0100 |
commit | 0c929b3c94636bd4c0cd62181145c733b3d19c0a (patch) | |
tree | df78ede911c5b45a3544d14579fc79f9873d06d6 /sound | |
parent | be2540e540f5442d7b372208787fb64100af0c54 (diff) | |
download | linux-rpi3-0c929b3c94636bd4c0cd62181145c733b3d19c0a.tar.gz linux-rpi3-0c929b3c94636bd4c0cd62181145c733b3d19c0a.tar.bz2 linux-rpi3-0c929b3c94636bd4c0cd62181145c733b3d19c0a.zip |
PianoPlus: Dual Mono & Dual Stereo features added (#2069)
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/bcm/allo-piano-dac-plus.c | 160 |
1 files changed, 141 insertions, 19 deletions
diff --git a/sound/soc/bcm/allo-piano-dac-plus.c b/sound/soc/bcm/allo-piano-dac-plus.c index 56e43f98846b..d4e99e3c6a38 100644 --- a/sound/soc/bcm/allo-piano-dac-plus.c +++ b/sound/soc/bcm/allo-piano-dac-plus.c @@ -36,6 +36,7 @@ struct dsp_code { struct glb_pool { struct mutex lock; + unsigned int dual_mode; unsigned int set_lowpass; unsigned int set_mode; unsigned int set_rate; @@ -47,8 +48,8 @@ bool glb_mclk; static struct gpio_desc *mute_gpio[2]; - static const char * const allo_piano_mode_texts[] = { + "None", "2.0", "2.1", "2.2", @@ -57,6 +58,15 @@ static const char * const allo_piano_mode_texts[] = { static const SOC_ENUM_SINGLE_DECL(allo_piano_mode_enum, 0, 0, allo_piano_mode_texts); +static const char * const allo_piano_dual_mode_texts[] = { + "None", + "Dual-Mono", + "Dual-Stereo", +}; + +static const SOC_ENUM_SINGLE_DECL(allo_piano_dual_mode_enum, + 0, 0, allo_piano_dual_mode_texts); + static const char * const allo_piano_dsp_low_pass_texts[] = { "60", "70", @@ -82,10 +92,10 @@ static int __snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd, unsigned int mode, unsigned int rate, unsigned int lowpass) { const struct firmware *fw; - char firmware_name[60]; - int ret = 0, dac = 0; struct snd_soc_card *card = rtd->card; struct glb_pool *glb_ptr = card->drvdata; + char firmware_name[60]; + int ret = 0, dac = 0; if (rate <= 46000) rate = 44100; @@ -100,26 +110,35 @@ static int __snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd, else rate = 192000; - if ((lowpass > 14) || (lowpass < 0)) - lowpass = 3; - if ((mode > 2) || (mode < 0)) - mode = 0; + if (lowpass > 14) + glb_ptr->set_lowpass = lowpass = 3; + + if (mode > 3) + glb_ptr->set_mode = mode = 0; + + if (mode > 0) + glb_ptr->dual_mode = 0; /* same configuration loaded */ if ((rate == glb_ptr->set_rate) && (lowpass == glb_ptr->set_lowpass) && (mode == glb_ptr->set_mode)) return 0; - if (mode == 0) { /* 2.0 */ - snd_soc_write(rtd->codec_dais[1]->codec, - PCM512x_MUTE, 0x11); + switch (mode) { + case 0: /* None */ + return 1; + + case 1: /* 2.0 */ + snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE, 0x00); + snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE, 0x11); glb_ptr->set_rate = rate; glb_ptr->set_mode = mode; glb_ptr->set_lowpass = lowpass; return 1; - } else { - snd_soc_write(rtd->codec_dais[1]->codec, - PCM512x_MUTE, 0x00); + + default: + snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE, 0x00); + snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE, 0x00); } for (dac = 0; dac < rtd->num_codecs; dac++) { @@ -128,13 +147,13 @@ static int __snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd, int i = 1; if (dac == 0) { /* high */ - sprintf(firmware_name, + snprintf(firmware_name, sizeof(firmware_name), "allo/piano/2.2/allo-piano-dsp-%d-%d-%d.bin", rate, ((lowpass * 10) + 60), dac); } else { /* low */ - sprintf(firmware_name, + snprintf(firmware_name, sizeof(firmware_name), "allo/piano/2.%d/allo-piano-dsp-%d-%d-%d.bin", - mode, rate, ((lowpass * 10) + 60), dac); + (mode - 1), rate, ((lowpass * 10) + 60), dac); } dev_info(codec->dev, "Dsp Firmware File Name: %s\n", @@ -199,6 +218,80 @@ static int snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd, return ret; } +static int snd_allo_piano_dual_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct glb_pool *glb_ptr = card->drvdata; + + ucontrol->value.integer.value[0] = glb_ptr->dual_mode; + + return 0; +} + +static int snd_allo_piano_dual_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct glb_pool *glb_ptr = card->drvdata; + struct snd_soc_pcm_runtime *rtd; + struct snd_card *snd_card_ptr = card->snd_card; + struct snd_kcontrol *kctl; + struct soc_mixer_control *mc; + unsigned int left_val = 0; + + rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name); + + if (ucontrol->value.integer.value[0] > 0) { + glb_ptr->dual_mode = ucontrol->value.integer.value[0]; + glb_ptr->set_mode = 0; + } else if (ucontrol->value.integer.value[0] <= 0) { + if (glb_ptr->set_mode <= 0) { + glb_ptr->dual_mode = 1; + glb_ptr->set_mode = 0; + } + } else { + glb_ptr->dual_mode = 0; + return 0; + } + + if (glb_ptr->dual_mode == 1) { + snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE, 0x01); + snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE, 0x10); + snd_soc_write(rtd->codec_dais[0]->codec, + PCM512x_DIGITAL_VOLUME_3, 0xff); + + list_for_each_entry(kctl, &snd_card_ptr->controls, list) { + if (!strncmp(kctl->id.name, "Digital Playback Volume", + sizeof(kctl->id.name))) { + mc = (struct soc_mixer_control *) + kctl->private_value; + mc->rreg = mc->reg; + break; + } + } + } else { + left_val = snd_soc_read(rtd->codec_dais[0]->codec, + 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))) { + mc = (struct soc_mixer_control *) + kctl->private_value; + mc->rreg = PCM512x_DIGITAL_VOLUME_3; + break; + } + } + + snd_soc_write(rtd->codec_dais[0]->codec, + PCM512x_DIGITAL_VOLUME_3, left_val); + snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE, 0x00); + snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE, 0x00); + } + + return 0; +} + static int snd_allo_piano_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -215,8 +308,30 @@ static int snd_allo_piano_mode_put(struct snd_kcontrol *kcontrol, struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); struct snd_soc_pcm_runtime *rtd; struct glb_pool *glb_ptr = card->drvdata; + struct snd_card *snd_card_ptr = card->snd_card; + struct snd_kcontrol *kctl; + struct soc_mixer_control *mc; + unsigned int left_val = 0; rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name); + + if ((glb_ptr->dual_mode == 1) && + (ucontrol->value.integer.value[0] > 0)) { + left_val = snd_soc_read(rtd->codec_dais[0]->codec, + 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))) { + mc = (struct soc_mixer_control *) + kctl->private_value; + mc->rreg = PCM512x_DIGITAL_VOLUME_3; + break; + } + } + snd_soc_write(rtd->codec_dais[0]->codec, + PCM512x_DIGITAL_VOLUME_3, left_val); + } + return(snd_allo_piano_dsp_program(rtd, ucontrol->value.integer.value[0], glb_ptr->set_rate, glb_ptr->set_lowpass)); @@ -344,6 +459,11 @@ static const struct snd_kcontrol_new allo_piano_controls[] = { snd_allo_piano_mode_get, snd_allo_piano_mode_put), + SOC_ENUM_EXT("Dual Mode Route", + allo_piano_dual_mode_enum, + snd_allo_piano_dual_mode_get, + snd_allo_piano_dual_mode_put), + SOC_ENUM_EXT("Lowpass Route", allo_piano_enum, snd_allo_piano_lowpass_get, snd_allo_piano_lowpass_put), @@ -472,7 +592,7 @@ static int snd_allo_piano_dac_hw_params( PCM512x_RATE_DET_4); if (val < 0) { dev_err(rtd->codec_dais[dac]->codec->dev, - "Failed to read register PCM512x_RATE_DET_4\n"); + "Failed to read register PCM512x_RATE_DET_4\n"); return val; } @@ -482,7 +602,7 @@ static int snd_allo_piano_dac_hw_params( PCM512x_SREF_BCK); dev_info(rtd->codec_dais[dac]->codec->dev, - "Setting BCLK as input clock & Enable PLL\n"); + "Setting BCLK as input clock & Enable PLL\n"); } else { snd_soc_write(rtd->codec_dais[dac]->codec, PCM512x_PLL_EN, @@ -493,7 +613,7 @@ static int snd_allo_piano_dac_hw_params( PCM512x_SREF_SCK); dev_info(rtd->codec_dais[dac]->codec->dev, - "Setting SCLK as input clock & disabled PLL\n"); + "Setting SCLK as input clock & disabled PLL\n"); } } @@ -504,6 +624,7 @@ static int snd_allo_piano_dac_hw_params( dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); } + ret = snd_allo_piano_dsp_program(rtd, glb_ptr->set_mode, rate, glb_ptr->set_lowpass); if (ret < 0) @@ -521,6 +642,7 @@ static int snd_allo_piano_dac_prepare( struct snd_soc_card *card = rtd->card; snd_allo_piano_gpio_unmute(card); + return 0; } |