Skip to content

Master volume added #2149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 171 additions & 10 deletions sound/soc/bcm/allo-piano-dac-plus.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ static int __snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd,
if (dsp_code_read->offset == 0) {
glb_ptr->dsp_page_number = dsp_code_read->val;
ret = snd_soc_write(rtd->codec_dais[dac]->codec,
PCM512x_PAGE_BASE(0),
dsp_code_read->val);
PCM512x_PAGE_BASE(0),
dsp_code_read->val);

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

mutex_lock(&glb_ptr->lock);

ret = __snd_allo_piano_dsp_program(rtd,
mode, rate, lowpass);
ret = __snd_allo_piano_dsp_program(rtd, mode, rate, lowpass);

mutex_unlock(&glb_ptr->lock);

return ret;
Expand Down Expand Up @@ -245,17 +245,16 @@ static int snd_allo_piano_dual_mode_put(struct snd_kcontrol *kcontrol,
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) {
} else {
if (glb_ptr->set_mode <= 0) {
glb_ptr->dual_mode = 1;
glb_ptr->set_mode = 0;
} else {
glb_ptr->dual_mode = 0;
}
} else {
glb_ptr->dual_mode = 0;
return 0;
}

if (glb_ptr->dual_mode == 1) {
if (glb_ptr->dual_mode == 1) { // Dual Mono
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,
Expand Down Expand Up @@ -400,7 +399,7 @@ static int pcm512x_get_reg_sub(struct snd_kcontrol *kcontrol,
}

ucontrol->value.integer.value[0] =
(~(left_val >> mc->shift)) & mc->max;
(~(left_val >> mc->shift)) & mc->max;
ucontrol->value.integer.value[1] =
(~(right_val >> mc->shift)) & mc->max;

Expand Down Expand Up @@ -474,7 +473,151 @@ static int pcm512x_set_reg_sub_switch(struct snd_kcontrol *kcontrol,

}

static int pcm512x_get_reg_master(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct glb_pool *glb_ptr = card->drvdata;
struct snd_soc_pcm_runtime *rtd;
unsigned int left_val = 0, right_val = 0;

rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);

left_val = snd_soc_read(rtd->codec_dais[0]->codec,
PCM512x_DIGITAL_VOLUME_2);
if (left_val < 0)
return left_val;

if (glb_ptr->dual_mode == 1) {
right_val = snd_soc_read(rtd->codec_dais[1]->codec,
PCM512x_DIGITAL_VOLUME_3);
if (right_val < 0)
return right_val;
} else {
right_val = snd_soc_read(rtd->codec_dais[0]->codec,
PCM512x_DIGITAL_VOLUME_3);
if (right_val < 0)
return right_val;
}

ucontrol->value.integer.value[0] =
(~(left_val >> mc->shift)) & mc->max;
ucontrol->value.integer.value[1] =
(~(right_val >> mc->shift)) & mc->max;

return 0;
}

static int pcm512x_set_reg_master(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct glb_pool *glb_ptr = card->drvdata;
struct snd_soc_pcm_runtime *rtd;
unsigned int left_val = (ucontrol->value.integer.value[0] & mc->max);
unsigned int right_val = (ucontrol->value.integer.value[1] & mc->max);
int ret = 0;

rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);

if (glb_ptr->dual_mode != 1) {
ret = snd_soc_write(rtd->codec_dais[1]->codec,
PCM512x_DIGITAL_VOLUME_2, (~left_val));
if (ret < 0)
return ret;

ret = snd_soc_write(rtd->codec_dais[0]->codec,
PCM512x_DIGITAL_VOLUME_3, (~right_val));
if (ret < 0)
return ret;

}

ret = snd_soc_write(rtd->codec_dais[1]->codec,
PCM512x_DIGITAL_VOLUME_3, (~right_val));
if (ret < 0)
return ret;

ret = snd_soc_write(rtd->codec_dais[0]->codec,
PCM512x_DIGITAL_VOLUME_2, (~left_val));
if (ret < 0)
return ret;
return 1;
}

static int pcm512x_get_reg_master_switch(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;
int val = 0;

rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);

val = snd_soc_read(rtd->codec_dais[0]->codec, PCM512x_MUTE);
if (val < 0)
return val;

ucontrol->value.integer.value[0] = (val & 0x10) ? 0 : 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more named constants, such as a name for bit 4 of PCM512x_MUTE, would make your code easier to understand.


if (glb_ptr->dual_mode == 1) {
val = snd_soc_read(rtd->codec_dais[1]->codec, PCM512x_MUTE);
if (val < 0)
return val;
}
ucontrol->value.integer.value[1] = (val & 0x01) ? 0 : 1;

return val;
}

static int pcm512x_set_reg_master_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct snd_soc_pcm_runtime *rtd;
struct glb_pool *glb_ptr = card->drvdata;
unsigned int left_val = (ucontrol->value.integer.value[0]);
unsigned int right_val = (ucontrol->value.integer.value[1]);
int ret = 0;

rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
if (glb_ptr->dual_mode == 1) {
ret = snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE,
~((left_val & 0x01)<<4));
if (ret < 0)
return ret;
ret = snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE,
~((right_val & 0x01)));
if (ret < 0)
return ret;

} else if (glb_ptr->set_mode == 1) {
ret = snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE,
~((left_val & 0x01)<<4 | (right_val & 0x01)));
if (ret < 0)
return ret;

} else {
ret = snd_soc_write(rtd->codec_dais[0]->codec, PCM512x_MUTE,
~((left_val & 0x01)<<4 | (right_val & 0x01)));
if (ret < 0)
return ret;

ret = snd_soc_write(rtd->codec_dais[1]->codec, PCM512x_MUTE,
~((left_val & 0x01)<<4 | (right_val & 0x01)));
if (ret < 0)
return ret;
}
return 1;
}

static const DECLARE_TLV_DB_SCALE(digital_tlv_sub, -10350, 50, 1);
static const DECLARE_TLV_DB_SCALE(digital_tlv_master, -10350, 50, 1);

static const struct snd_kcontrol_new allo_piano_controls[] = {
SOC_ENUM_EXT("Subwoofer mode Route",
Expand Down Expand Up @@ -504,6 +647,20 @@ static const struct snd_kcontrol_new allo_piano_controls[] = {
PCM512x_RQMR_SHIFT, 1, 1,
pcm512x_get_reg_sub_switch,
pcm512x_set_reg_sub_switch),

SOC_DOUBLE_R_EXT_TLV("Master Playback Volume",
PCM512x_DIGITAL_VOLUME_2,
PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
pcm512x_get_reg_master,
pcm512x_set_reg_master,
digital_tlv_master),

SOC_DOUBLE_EXT("Master Playback Switch",
PCM512x_MUTE,
PCM512x_RQML_SHIFT,
PCM512x_RQMR_SHIFT, 1, 1,
pcm512x_get_reg_master_switch,
pcm512x_set_reg_master_switch),
};

static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd)
Expand Down Expand Up @@ -645,6 +802,10 @@ static int snd_allo_piano_dac_hw_params(
if (ret < 0)
dev_warn(card->dev, "Failed to set volume limit: %d\n",
ret);
ret = snd_soc_limit_volume(card, "Master Playback Volume", 207);
if (ret < 0)
dev_warn(card->dev, "Failed to set volume limit: %d\n",
ret);
}

ret = snd_allo_piano_dsp_program(rtd, glb_ptr->set_mode, rate,
Expand Down