2022-11-24 09:10:09

by Jiaxin Yu (俞家鑫)

[permalink] [raw]
Subject: [PATCH 0/3] ASoC: mediatek:mt8186: fix both the speaker and hdmi

The speaker and hdmi of mt8186 platform are shared the same port of I2S,
when connect the external display, use build-in speakers to play audio,
they both playback at the same time. So we want to manage the playback
device through DAPM events.

Jiaxin Yu (3):
drm: bridge: it6505: bridge to hdmi-codec
ASoC: hdmi-codec: Add event handler for hdmi TX
ASoC: mediatek: mt8186: correct the HDMI widgets

drivers/gpu/drm/bridge/ite-it6505.c | 36 +++++++++++++++---
include/sound/hdmi-codec.h | 6 +++
sound/soc/codecs/hdmi-codec.c | 37 +++++++++++++++++--
.../mt8186/mt8186-mt6366-da7219-max98357.c | 2 +-
.../mt8186/mt8186-mt6366-rt1019-rt5682s.c | 2 +-
5 files changed, 71 insertions(+), 12 deletions(-)

--
2.18.0


2022-11-24 09:12:17

by Jiaxin Yu (俞家鑫)

[permalink] [raw]
Subject: [PATCH 2/3] ASoC: hdmi-codec: Add event handler for hdmi TX

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 <[email protected]>
---
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)
+{
+ 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

2022-11-24 09:55:29

by Jiaxin Yu (俞家鑫)

[permalink] [raw]
Subject: [PATCH 1/3] drm: bridge: it6505: bridge to hdmi-codec

1. Bridge to hdmi-codec to support audio feature. At the same time,
the function of automatically detecting audio is removed.
2. It is observed that some DP-to-HDMI dongles will get into bad
states if sending InfoFrame without audio data. Defer to enable
it6505's audio feature when PCM triggers START or RESUME.

Signed-off-by: Jiaxin Yu <[email protected]>
---
drivers/gpu/drm/bridge/ite-it6505.c | 36 ++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
index dfe4351c9bdd..f4e1a1d94ed8 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -2159,7 +2159,6 @@ static void it6505_stop_link_train(struct it6505 *it6505)

static void it6505_link_train_ok(struct it6505 *it6505)
{
- struct device *dev = &it6505->client->dev;

it6505->link_state = LINK_OK;
/* disalbe mute enable avi info frame */
@@ -2167,11 +2166,6 @@ static void it6505_link_train_ok(struct it6505 *it6505)
it6505_set_bits(it6505, REG_INFOFRAME_CTRL,
EN_VID_CTRL_PKT, EN_VID_CTRL_PKT);

- if (it6505_audio_input(it6505)) {
- DRM_DEV_DEBUG_DRIVER(dev, "Enable audio!");
- it6505_enable_audio(it6505);
- }
-
if (it6505->hdcp_desired)
it6505_start_hdcp(it6505);
}
@@ -2823,6 +2817,36 @@ static void __maybe_unused it6505_audio_shutdown(struct device *dev, void *data)
it6505_disable_audio(it6505);
}

+static int __maybe_unused it6505_audio_setup_trigger(struct it6505 *it6505, int cmd)
+{
+ struct device *dev = &it6505->client->dev;
+
+ DRM_DEV_DEBUG_DRIVER(dev, "event: %d", cmd);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ queue_delayed_work(system_wq, &it6505->delayed_audio,
+ msecs_to_jiffies(180));
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ cancel_delayed_work(&it6505->delayed_audio);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __maybe_unused it6505_audio_trigger(struct device *dev, int cmd)
+{
+ struct it6505 *it6505 = dev_get_drvdata(dev);
+
+ return it6505_audio_setup_trigger(it6505, cmd);
+}
+
static int __maybe_unused it6505_audio_hook_plugged_cb(struct device *dev,
void *data,
hdmi_codec_plugged_cb fn,
--
2.18.0

2022-11-29 17:51:08

by Robert Foss

[permalink] [raw]
Subject: Re: [PATCH 2/3] ASoC: hdmi-codec: Add event handler for hdmi TX

On Thu, 24 Nov 2022 at 09:54, Jiaxin Yu <[email protected]> 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 <[email protected]>
> ---
> 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
>