ASoC: madera: Update handling of DAPM routes for mono muxed outputs
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>
This commit is contained in:
parent
73ecf1a673
commit
8ab6ddc5c5
@ -529,6 +529,7 @@ SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
|
|||||||
SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
|
SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
|
||||||
|
|
||||||
SND_SOC_DAPM_DEMUX("HPOUT1 Demux", SND_SOC_NOPM, 0, 0, &cs47l15_outdemux),
|
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,
|
SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT,
|
||||||
0, NULL, 0),
|
0, NULL, 0),
|
||||||
@ -1084,6 +1085,9 @@ static const struct snd_soc_dapm_route cs47l15_dapm_routes[] = {
|
|||||||
{ "AEC2 Loopback", "HPOUT1R", "OUT1R" },
|
{ "AEC2 Loopback", "HPOUT1R", "OUT1R" },
|
||||||
{ "HPOUT1 Demux", NULL, "OUT1L" },
|
{ "HPOUT1 Demux", NULL, "OUT1L" },
|
||||||
{ "HPOUT1 Demux", NULL, "OUT1R" },
|
{ "HPOUT1 Demux", NULL, "OUT1R" },
|
||||||
|
|
||||||
|
{ "OUT1R", NULL, "HPOUT1 Mono Mux" },
|
||||||
|
|
||||||
{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
|
{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
|
||||||
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
|
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
|
||||||
{ "EPOUTP", "EPOUT", "HPOUT1 Demux" },
|
{ "EPOUTP", "EPOUT", "HPOUT1 Demux" },
|
||||||
@ -1261,6 +1265,11 @@ static irqreturn_t cs47l15_adsp2_irq(int irq, void *data)
|
|||||||
return IRQ_HANDLED;
|
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)
|
static int cs47l15_component_probe(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
|
struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
|
||||||
@ -1277,7 +1286,9 @@ static int cs47l15_component_probe(struct snd_soc_component *component)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return 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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -631,6 +631,7 @@ SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
|
|||||||
SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
|
SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
|
||||||
|
|
||||||
SND_SOC_DAPM_DEMUX("HPOUT1 Demux", SND_SOC_NOPM, 0, 0, &cs47l35_outdemux),
|
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,
|
SND_SOC_DAPM_PGA("PWM1 Driver", MADERA_PWM_DRIVE_1, MADERA_PWM1_ENA_SHIFT,
|
||||||
0, NULL, 0),
|
0, NULL, 0),
|
||||||
@ -1309,6 +1310,8 @@ static const struct snd_soc_dapm_route cs47l35_dapm_routes[] = {
|
|||||||
{ "SPKOUTN", NULL, "OUT4L" },
|
{ "SPKOUTN", NULL, "OUT4L" },
|
||||||
{ "SPKOUTP", NULL, "OUT4L" },
|
{ "SPKOUTP", NULL, "OUT4L" },
|
||||||
|
|
||||||
|
{ "OUT1R", NULL, "HPOUT1 Mono Mux" },
|
||||||
|
|
||||||
{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
|
{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
|
||||||
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
|
{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
|
||||||
{ "EPOUTP", "EPOUT", "HPOUT1 Demux" },
|
{ "EPOUTP", "EPOUT", "HPOUT1 Demux" },
|
||||||
@ -1552,6 +1555,11 @@ static irqreturn_t cs47l35_adsp2_irq(int irq, void *data)
|
|||||||
return IRQ_HANDLED;
|
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)
|
static int cs47l35_component_probe(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
struct cs47l35 *cs47l35 = snd_soc_component_get_drvdata(component);
|
struct cs47l35 *cs47l35 = snd_soc_component_get_drvdata(component);
|
||||||
@ -1568,7 +1576,9 @@ static int cs47l35_component_probe(struct snd_soc_component *component)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return 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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -2507,7 +2507,8 @@ static int cs47l85_component_probe(struct snd_soc_component *component)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return 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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -2418,7 +2418,8 @@ static int cs47l90_component_probe(struct snd_soc_component *component)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return 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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -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_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_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("DRC1 Signal Activity"),
|
||||||
SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
|
SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
|
||||||
@ -1584,6 +1585,8 @@ static const struct snd_soc_dapm_route cs47l92_dapm_routes[] = {
|
|||||||
{ "OUT3 Demux", NULL, "OUT3L" },
|
{ "OUT3 Demux", NULL, "OUT3L" },
|
||||||
{ "OUT3 Demux", NULL, "OUT3R" },
|
{ "OUT3 Demux", NULL, "OUT3R" },
|
||||||
|
|
||||||
|
{ "OUT3R", NULL, "OUT3 Mono Mux" },
|
||||||
|
|
||||||
{ "HPOUT3L", "HPOUT3", "OUT3 Demux" },
|
{ "HPOUT3L", "HPOUT3", "OUT3 Demux" },
|
||||||
{ "HPOUT3R", "HPOUT3", "OUT3 Demux" },
|
{ "HPOUT3R", "HPOUT3", "OUT3 Demux" },
|
||||||
{ "HPOUT4L", "HPOUT4", "OUT3 Demux" },
|
{ "HPOUT4L", "HPOUT4", "OUT3 Demux" },
|
||||||
@ -1817,6 +1820,13 @@ static irqreturn_t cs47l92_adsp2_irq(int irq, void *data)
|
|||||||
return IRQ_HANDLED;
|
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)
|
static int cs47l92_component_probe(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
|
struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
|
||||||
@ -1833,7 +1843,9 @@ static int cs47l92_component_probe(struct snd_soc_component *component)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return 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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1162,7 +1162,9 @@ static const struct snd_soc_dapm_route madera_mono_routes[] = {
|
|||||||
{ "OUT6R", NULL, "OUT6L" },
|
{ "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 =
|
struct snd_soc_dapm_context *dapm =
|
||||||
snd_soc_component_get_dapm(component);
|
snd_soc_component_get_dapm(component);
|
||||||
@ -1179,16 +1181,21 @@ int madera_init_outputs(struct snd_soc_component *component, int n_mono_routes)
|
|||||||
n_mono_routes = MADERA_MAX_OUTPUT;
|
n_mono_routes = MADERA_MAX_OUTPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!routes)
|
||||||
|
routes = madera_mono_routes;
|
||||||
|
|
||||||
for (i = 0; i < n_mono_routes; i++) {
|
for (i = 0; i < n_mono_routes; i++) {
|
||||||
/* Default is 0 so noop with defaults */
|
/* Default is 0 so noop with defaults */
|
||||||
if (pdata->out_mono[i]) {
|
if (pdata->out_mono[i]) {
|
||||||
val = MADERA_OUT1_MONO;
|
val = MADERA_OUT1_MONO;
|
||||||
snd_soc_dapm_add_routes(dapm,
|
snd_soc_dapm_add_routes(dapm, &routes[i], 1);
|
||||||
&madera_mono_routes[i], 1);
|
|
||||||
} else {
|
} else {
|
||||||
val = 0;
|
val = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i >= n_real)
|
||||||
|
continue;
|
||||||
|
|
||||||
regmap_update_bits(madera->regmap,
|
regmap_update_bits(madera->regmap,
|
||||||
MADERA_OUTPUT_PATH_CONFIG_1L + (i * 8),
|
MADERA_OUTPUT_PATH_CONFIG_1L + (i * 8),
|
||||||
MADERA_OUT1_MONO, val);
|
MADERA_OUT1_MONO, val);
|
||||||
|
@ -421,7 +421,9 @@ int madera_core_free(struct madera_priv *priv);
|
|||||||
int madera_init_overheat(struct madera_priv *priv);
|
int madera_init_overheat(struct madera_priv *priv);
|
||||||
int madera_free_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_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,
|
int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,
|
||||||
irq_handler_t handler);
|
irq_handler_t handler);
|
||||||
void madera_free_bus_error_irq(struct madera_priv *priv, int dsp_num);
|
void madera_free_bus_error_irq(struct madera_priv *priv, int dsp_num);
|
||||||
|
Loading…
Reference in New Issue
Block a user