Commit 0bebd2f1 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/fix/topology' and 'asoc/fix/wm8998' into asoc-linus

...@@ -101,7 +101,7 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w, ...@@ -101,7 +101,7 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
return 0; return 0;
} }
static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol, static int wm8998_inmux_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
...@@ -109,84 +109,38 @@ static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol, ...@@ -109,84 +109,38 @@ static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol,
struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec); struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = wm8998->core.arizona; struct arizona *arizona = wm8998->core.arizona;
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int mux, inmode; unsigned int mode_reg, mode_index;
unsigned int mode_val, src_val; unsigned int mux, inmode, src_val, mode_val;
mux = ucontrol->value.enumerated.item[0]; mux = ucontrol->value.enumerated.item[0];
if (mux > 1) if (mux > 1)
return -EINVAL; return -EINVAL;
/* L and R registers have same shift and mask */ switch (e->reg) {
inmode = arizona->pdata.inmode[2 * mux]; case ARIZONA_ADC_DIGITAL_VOLUME_2L:
src_val = mux << ARIZONA_IN1L_SRC_SHIFT; mode_reg = ARIZONA_IN2L_CONTROL;
if (inmode & ARIZONA_INMODE_SE) mode_index = 1 + (2 * mux);
src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
switch (arizona->pdata.inmode[0]) {
case ARIZONA_INMODE_DMIC:
if (mux)
mode_val = 0; /* B always analogue */
else
mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
snd_soc_update_bits(codec, ARIZONA_IN1L_CONTROL,
ARIZONA_IN1_MODE_MASK, mode_val);
/* IN1A is digital so L and R must change together */
/* src_val setting same for both registers */
snd_soc_update_bits(codec,
ARIZONA_ADC_DIGITAL_VOLUME_1L,
ARIZONA_IN1L_SRC_MASK |
ARIZONA_IN1L_SRC_SE_MASK, src_val);
snd_soc_update_bits(codec,
ARIZONA_ADC_DIGITAL_VOLUME_1R,
ARIZONA_IN1R_SRC_MASK |
ARIZONA_IN1R_SRC_SE_MASK, src_val);
break; break;
default: default:
/* both analogue */ mode_reg = ARIZONA_IN1L_CONTROL;
snd_soc_update_bits(codec, mode_index = (2 * mux);
e->reg,
ARIZONA_IN1L_SRC_MASK |
ARIZONA_IN1L_SRC_SE_MASK,
src_val);
break; break;
} }
return snd_soc_dapm_mux_update_power(dapm, kcontrol, inmode = arizona->pdata.inmode[mode_index];
ucontrol->value.enumerated.item[0],
e, NULL);
}
static int wm8998_in2mux_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = wm8998->core.arizona;
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int mux, inmode, src_val, mode_val;
mux = ucontrol->value.enumerated.item[0];
if (mux > 1)
return -EINVAL;
inmode = arizona->pdata.inmode[1 + (2 * mux)];
if (inmode & ARIZONA_INMODE_DMIC) if (inmode & ARIZONA_INMODE_DMIC)
mode_val = 1 << ARIZONA_IN2_MODE_SHIFT; mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
else else
mode_val = 0; mode_val = 0;
src_val = mux << ARIZONA_IN2L_SRC_SHIFT; src_val = mux << ARIZONA_IN1L_SRC_SHIFT;
if (inmode & ARIZONA_INMODE_SE) if (inmode & ARIZONA_INMODE_SE)
src_val |= 1 << ARIZONA_IN2L_SRC_SE_SHIFT; src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
snd_soc_update_bits(codec, ARIZONA_IN2L_CONTROL, snd_soc_update_bits(codec, mode_reg, ARIZONA_IN1_MODE_MASK, mode_val);
ARIZONA_IN2_MODE_MASK, mode_val);
snd_soc_update_bits(codec, ARIZONA_ADC_DIGITAL_VOLUME_2L, snd_soc_update_bits(codec, e->reg,
ARIZONA_IN2L_SRC_MASK | ARIZONA_IN2L_SRC_SE_MASK, ARIZONA_IN1L_SRC_MASK | ARIZONA_IN1L_SRC_SE_MASK,
src_val); src_val);
return snd_soc_dapm_mux_update_power(dapm, kcontrol, return snd_soc_dapm_mux_update_power(dapm, kcontrol,
...@@ -216,14 +170,14 @@ static SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum, ...@@ -216,14 +170,14 @@ static SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum,
static const struct snd_kcontrol_new wm8998_in1mux[2] = { static const struct snd_kcontrol_new wm8998_in1mux[2] = {
SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum, SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum,
snd_soc_dapm_get_enum_double, wm8998_in1mux_put), snd_soc_dapm_get_enum_double, wm8998_inmux_put),
SOC_DAPM_ENUM_EXT("IN1R Mux", wm8998_in1muxr_enum, SOC_DAPM_ENUM_EXT("IN1R Mux", wm8998_in1muxr_enum,
snd_soc_dapm_get_enum_double, wm8998_in1mux_put), snd_soc_dapm_get_enum_double, wm8998_inmux_put),
}; };
static const struct snd_kcontrol_new wm8998_in2mux = static const struct snd_kcontrol_new wm8998_in2mux =
SOC_DAPM_ENUM_EXT("IN2 Mux", wm8998_in2mux_enum, SOC_DAPM_ENUM_EXT("IN2 Mux", wm8998_in2mux_enum,
snd_soc_dapm_get_enum_double, wm8998_in2mux_put); snd_soc_dapm_get_enum_double, wm8998_inmux_put);
static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
......
...@@ -1301,7 +1301,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( ...@@ -1301,7 +1301,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
/* validate kcontrol */ /* validate kcontrol */
if (strnlen(ec->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == if (strnlen(ec->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) ==
SNDRV_CTL_ELEM_ID_NAME_MAXLEN) SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
return NULL; goto err;
se = kzalloc(sizeof(*se), GFP_KERNEL); se = kzalloc(sizeof(*se), GFP_KERNEL);
if (se == NULL) if (se == NULL)
...@@ -1378,6 +1378,9 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( ...@@ -1378,6 +1378,9 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
for (; i >= 0; i--) { for (; i >= 0; i--) {
/* free values and texts */ /* free values and texts */
se = (struct soc_enum *)kc[i].private_value; se = (struct soc_enum *)kc[i].private_value;
if (!se)
continue;
kfree(se->dobj.control.dvalues); kfree(se->dobj.control.dvalues);
for (j = 0; j < ec->items; j++) for (j = 0; j < ec->items; j++)
kfree(se->dobj.control.dtexts[j]); kfree(se->dobj.control.dtexts[j]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment