Skip to content

Commit

Permalink
ASoC: madera: Update handling of DAPM routes for mono muxed outputs
Browse files Browse the repository at this point in the history
Correctly link both channels on the DAC if an output muxed between a
stereo and mono output. Without this one channel of the DAC may be
erroneously powered down whilst in mono mode.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20200114161841.451-4-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Charles Keepax authored and Mark Brown committed Jan 17, 2020
1 parent 73ecf1a commit 8ab6ddc
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 9 deletions.
13 changes: 12 additions & 1 deletion sound/soc/codecs/cs47l15.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),

SND_SOC_DAPM_DEMUX("HPOUT1 Demux", SND_SOC_NOPM, 0, 0, &cs47l15_outdemux),
SND_SOC_DAPM_MUX("HPOUT1 Mono Mux", SND_SOC_NOPM, 0, 0, &cs47l15_outdemux),

SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT,
0, NULL, 0),
Expand Down Expand Up @@ -1084,6 +1085,9 @@ static const struct snd_soc_dapm_route cs47l15_dapm_routes[] = {
{ "AEC2 Loopback", "HPOUT1R", "OUT1R" },
{ "HPOUT1 Demux", NULL, "OUT1L" },
{ "HPOUT1 Demux", NULL, "OUT1R" },

{ "OUT1R", NULL, "HPOUT1 Mono Mux" },

{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
{ "EPOUTP", "EPOUT", "HPOUT1 Demux" },
Expand Down Expand Up @@ -1261,6 +1265,11 @@ static irqreturn_t cs47l15_adsp2_irq(int irq, void *data)
return IRQ_HANDLED;
}

static const struct snd_soc_dapm_route cs47l15_mono_routes[] = {
{ "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
};

static int cs47l15_component_probe(struct snd_soc_component *component)
{
struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
Expand All @@ -1277,7 +1286,9 @@ static int cs47l15_component_probe(struct snd_soc_component *component)
if (ret)
return ret;

ret = madera_init_outputs(component, CS47L15_MONO_OUTPUTS);
ret = madera_init_outputs(component, cs47l15_mono_routes,
ARRAY_SIZE(cs47l15_mono_routes),
CS47L15_MONO_OUTPUTS);
if (ret)
return ret;

Expand Down
12 changes: 11 additions & 1 deletion sound/soc/codecs/cs47l35.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,7 @@ SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),

SND_SOC_DAPM_DEMUX("HPOUT1 Demux", SND_SOC_NOPM, 0, 0, &cs47l35_outdemux),
SND_SOC_DAPM_MUX("HPOUT1 Mono Mux", SND_SOC_NOPM, 0, 0, &cs47l35_outdemux),

SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT,
0, NULL, 0),
Expand Down Expand Up @@ -1309,6 +1310,8 @@ static const struct snd_soc_dapm_route cs47l35_dapm_routes[] = {
{ "SPKOUTN", NULL, "OUT4L" },
{ "SPKOUTP", NULL, "OUT4L" },

{ "OUT1R", NULL, "HPOUT1 Mono Mux" },

{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
{ "EPOUTP", "EPOUT", "HPOUT1 Demux" },
Expand Down Expand Up @@ -1552,6 +1555,11 @@ static irqreturn_t cs47l35_adsp2_irq(int irq, void *data)
return IRQ_HANDLED;
}

static const struct snd_soc_dapm_route cs47l35_mono_routes[] = {
{ "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
};

static int cs47l35_component_probe(struct snd_soc_component *component)
{
struct cs47l35 *cs47l35 = snd_soc_component_get_drvdata(component);
Expand All @@ -1568,7 +1576,9 @@ static int cs47l35_component_probe(struct snd_soc_component *component)
if (ret)
return ret;

ret = madera_init_outputs(component, CS47L35_MONO_OUTPUTS);
ret = madera_init_outputs(component, cs47l35_mono_routes,
ARRAY_SIZE(cs47l35_mono_routes),
CS47L35_MONO_OUTPUTS);
if (ret)
return ret;

Expand Down
3 changes: 2 additions & 1 deletion sound/soc/codecs/cs47l85.c
Original file line number Diff line number Diff line change
Expand Up @@ -2507,7 +2507,8 @@ static int cs47l85_component_probe(struct snd_soc_component *component)
if (ret)
return ret;

ret = madera_init_outputs(component, CS47L85_MONO_OUTPUTS);
ret = madera_init_outputs(component, NULL, CS47L85_MONO_OUTPUTS,
CS47L85_MONO_OUTPUTS);
if (ret)
return ret;

Expand Down
3 changes: 2 additions & 1 deletion sound/soc/codecs/cs47l90.c
Original file line number Diff line number Diff line change
Expand Up @@ -2418,7 +2418,8 @@ static int cs47l90_component_probe(struct snd_soc_component *component)
if (ret)
return ret;

ret = madera_init_outputs(component, CS47L90_MONO_OUTPUTS);
ret = madera_init_outputs(component, NULL, CS47L90_MONO_OUTPUTS,
CS47L90_MONO_OUTPUTS);
if (ret)
return ret;

Expand Down
14 changes: 13 additions & 1 deletion sound/soc/codecs/cs47l92.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,7 @@ SND_SOC_DAPM_MUX("IN2L Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]),
SND_SOC_DAPM_MUX("IN2R Mode", SND_SOC_NOPM, 0, 0, &madera_inmode[1]),

SND_SOC_DAPM_DEMUX("OUT3 Demux", SND_SOC_NOPM, 0, 0, &cs47l92_outdemux),
SND_SOC_DAPM_MUX("OUT3 Mono Mux", SND_SOC_NOPM, 0, 0, &cs47l92_outdemux),

SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
Expand Down Expand Up @@ -1584,6 +1585,8 @@ static const struct snd_soc_dapm_route cs47l92_dapm_routes[] = {
{ "OUT3 Demux", NULL, "OUT3L" },
{ "OUT3 Demux", NULL, "OUT3R" },

{ "OUT3R", NULL, "OUT3 Mono Mux" },

{ "HPOUT3L", "HPOUT3", "OUT3 Demux" },
{ "HPOUT3R", "HPOUT3", "OUT3 Demux" },
{ "HPOUT4L", "HPOUT4", "OUT3 Demux" },
Expand Down Expand Up @@ -1817,6 +1820,13 @@ static irqreturn_t cs47l92_adsp2_irq(int irq, void *data)
return IRQ_HANDLED;
}

static const struct snd_soc_dapm_route cs47l92_mono_routes[] = {
{ "OUT1R", NULL, "OUT1L" },
{ "OUT2R", NULL, "OUT2L" },
{ "OUT3 Mono Mux", "HPOUT3", "OUT3L" },
{ "OUT3 Mono Mux", "HPOUT4", "OUT3L" },
};

static int cs47l92_component_probe(struct snd_soc_component *component)
{
struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
Expand All @@ -1833,7 +1843,9 @@ static int cs47l92_component_probe(struct snd_soc_component *component)
if (ret)
return ret;

ret = madera_init_outputs(component, CS47L92_MONO_OUTPUTS);
ret = madera_init_outputs(component, cs47l92_mono_routes,
ARRAY_SIZE(cs47l92_mono_routes),
CS47L92_MONO_OUTPUTS);
if (ret)
return ret;

Expand Down
13 changes: 10 additions & 3 deletions sound/soc/codecs/madera.c
Original file line number Diff line number Diff line change
Expand Up @@ -1162,7 +1162,9 @@ static const struct snd_soc_dapm_route madera_mono_routes[] = {
{ "OUT6R", NULL, "OUT6L" },
};

int madera_init_outputs(struct snd_soc_component *component, int n_mono_routes)
int madera_init_outputs(struct snd_soc_component *component,
const struct snd_soc_dapm_route *routes,
int n_mono_routes, int n_real)
{
struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(component);
Expand All @@ -1179,16 +1181,21 @@ int madera_init_outputs(struct snd_soc_component *component, int n_mono_routes)
n_mono_routes = MADERA_MAX_OUTPUT;
}

if (!routes)
routes = madera_mono_routes;

for (i = 0; i < n_mono_routes; i++) {
/* Default is 0 so noop with defaults */
if (pdata->out_mono[i]) {
val = MADERA_OUT1_MONO;
snd_soc_dapm_add_routes(dapm,
&madera_mono_routes[i], 1);
snd_soc_dapm_add_routes(dapm, &routes[i], 1);
} else {
val = 0;
}

if (i >= n_real)
continue;

regmap_update_bits(madera->regmap,
MADERA_OUTPUT_PATH_CONFIG_1L + (i * 8),
MADERA_OUT1_MONO, val);
Expand Down
4 changes: 3 additions & 1 deletion sound/soc/codecs/madera.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,9 @@ int madera_core_free(struct madera_priv *priv);
int madera_init_overheat(struct madera_priv *priv);
int madera_free_overheat(struct madera_priv *priv);
int madera_init_inputs(struct snd_soc_component *component);
int madera_init_outputs(struct snd_soc_component *component, int n_mono_routes);
int madera_init_outputs(struct snd_soc_component *component,
const struct snd_soc_dapm_route *routes,
int n_mono_routes, int n_real);
int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,
irq_handler_t handler);
void madera_free_bus_error_irq(struct madera_priv *priv, int dsp_num);
Expand Down

0 comments on commit 8ab6ddc

Please sign in to comment.