On Thu, 24 Nov 2022 at 09:54, Jiaxin Yu <jiaxin.yu@xxxxxxxxxxxx> wrote: > > If the speaker and hdmi are connect to the same port of I2S, > when try to switch to speaker playback, we will find that hdmi > is always turned on automatically. The way of switching is > through SOC_DAPM_PIN_SWITCH, however, such events can not be > handled in hdmi-codec driver. > > So add event handler for hdmi TX to solve the above issue. > > Signed-off-by: Jiaxin Yu <jiaxin.yu@xxxxxxxxxxxx> > --- > include/sound/hdmi-codec.h | 6 ++++++ > sound/soc/codecs/hdmi-codec.c | 37 +++++++++++++++++++++++++++++++---- > 2 files changed, 39 insertions(+), 4 deletions(-) > > diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h > index 48ad33aba393..dcbc09254144 100644 > --- a/include/sound/hdmi-codec.h > +++ b/include/sound/hdmi-codec.h > @@ -81,6 +81,12 @@ struct hdmi_codec_ops { > struct hdmi_codec_daifmt *fmt, > struct hdmi_codec_params *hparms); > > + /* > + * PCM trigger callback. > + * Mandatory > + */ > + int (*trigger)(struct device *dev, int cmd); > + > /* > * Shuts down the audio stream. > * Mandatory > diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c > index 0b1cdb2d6049..cb4479372e09 100644 > --- a/sound/soc/codecs/hdmi-codec.c > +++ b/sound/soc/codecs/hdmi-codec.c > @@ -276,7 +276,31 @@ struct hdmi_codec_priv { > u8 iec_status[AES_IEC958_STATUS_SIZE]; > }; > > +static int hdmi_tx_event(struct snd_soc_dapm_widget *w, > + struct snd_kcontrol *kcontrol, int event) checkpatch --strict caught this alignment issue. ASoC: hdmi-codec: Add event handler for hdmi TX -:44: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #44: FILE: sound/soc/codecs/hdmi-codec.c:280: +static int hdmi_tx_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) > +{ > + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); > + struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); > + > + switch (event) { > + case SND_SOC_DAPM_PRE_PMU: > + if (hcp->hcd.ops->trigger) > + hcp->hcd.ops->trigger(component->dev->parent, SNDRV_PCM_TRIGGER_START); > + break; > + case SND_SOC_DAPM_POST_PMD: > + if (hcp->hcd.ops->trigger) > + hcp->hcd.ops->trigger(component->dev->parent, SNDRV_PCM_TRIGGER_STOP); > + break; > + default: > + break; > + } > + > + return 0; > +} > + > static const struct snd_soc_dapm_widget hdmi_widgets[] = { > + SND_SOC_DAPM_OUT_DRV_E("SDB", SND_SOC_NOPM, 0, 0, NULL, 0, hdmi_tx_event, > + SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU), > SND_SOC_DAPM_OUTPUT("TX"), > SND_SOC_DAPM_OUTPUT("RX"), > }; > @@ -808,18 +832,23 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai) > struct hdmi_codec_daifmt *daifmt; > struct snd_soc_dapm_route route[] = { > { > - .sink = "TX", > + .sink = dai->driver->capture.stream_name, > + .source = "RX", > + }, > + { > + .sink = "SDB", > .source = dai->driver->playback.stream_name, > }, > { > - .sink = dai->driver->capture.stream_name, > - .source = "RX", > + .sink = "TX", > + .source = "SDB", > }, > + > }; > int ret; > > dapm = snd_soc_component_get_dapm(dai->component); > - ret = snd_soc_dapm_add_routes(dapm, route, 2); > + ret = snd_soc_dapm_add_routes(dapm, route, ARRAY_SIZE(route)); > if (ret) > return ret; > > -- > 2.18.0 >