[alsa-devel] [PATCH 0/3] ASoC: mediatek: mt8173-rt5650: HDMI jack reporting
The series supports HDMI jack reporting to mt8173-rt5650.
The 1st patch is less related. It stops running in probe() if failed to register audio driver.
The 2nd patch supports jack reporting in DRM driver.
The 3rd patch supports jack reporting in mt8173-rt5650 ASoC machine driver.
Tzung-Bi Shih (3): drm/mediatek: exit earlier if failed to register audio driver drm/mediatek: support HDMI jack status reporting ASoC: mediatek: mt8173-rt5650: support HDMI jack reporting
drivers/gpu/drm/mediatek/mtk_hdmi.c | 52 ++++++++++++++++++++--- sound/soc/mediatek/mt8173/mt8173-rt5650.c | 17 +++++++- 2 files changed, 63 insertions(+), 6 deletions(-)
Exits earlier if register_audio_driver() returns errors.
Signed-off-by: Tzung-Bi Shih tzungbi@google.com --- drivers/gpu/drm/mediatek/mtk_hdmi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index c79b1f855d89..23c2b0e8693d 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1656,7 +1656,7 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = { .get_eld = mtk_hdmi_audio_get_eld, };
-static void mtk_hdmi_register_audio_driver(struct device *dev) +static int mtk_hdmi_register_audio_driver(struct device *dev) { struct hdmi_codec_pdata codec_data = { .ops = &mtk_hdmi_audio_codec_ops, @@ -1669,9 +1669,10 @@ static void mtk_hdmi_register_audio_driver(struct device *dev) PLATFORM_DEVID_AUTO, &codec_data, sizeof(codec_data)); if (IS_ERR(pdev)) - return; + return PTR_ERR(pdev);
DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME); + return 0; }
static int mtk_drm_hdmi_probe(struct platform_device *pdev) @@ -1705,7 +1706,11 @@ static int mtk_drm_hdmi_probe(struct platform_device *pdev) return ret; }
- mtk_hdmi_register_audio_driver(dev); + ret = mtk_hdmi_register_audio_driver(dev); + if (ret) { + dev_err(dev, "Failed to register audio driver: %d\n", ret); + return ret; + }
hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs; hdmi->bridge.of_node = pdev->dev.of_node;
1. Provides a callback (i.e. mtk_hdmi_audio_hook_plugged_cb) to hdmi-codec. When ASoC machine driver calls hdmi_codec_set_jack_detect(), the callback will be invoked to save plugged_cb and codec_dev parameters.
+---------+ set_jack_ +------------+ plugged_cb +----------+ | machine | ----------> | hdmi-codec | ----------> | mtk-hdmi | +---------+ detect() +------------+ codec_dev +----------+
2. When there is any jack status changes, mtk-hdmi will call the plugged_cb() to notify hdmi-codec. And then hdmi-codec will call snd_soc_jack_report().
+----------+ plugged_cb +------------+ | mtk-hdmi | ----------> | hdmi-codec | -> snd_soc_jack_report() +----------+ codec_dev +------------+ connector_status
Signed-off-by: Tzung-Bi Shih tzungbi@google.com --- drivers/gpu/drm/mediatek/mtk_hdmi.c | 41 +++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 23c2b0e8693d..15736ed0a96a 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -169,6 +169,8 @@ struct mtk_hdmi { bool audio_enable; bool powered; bool enabled; + hdmi_codec_plugged_cb plugged_cb; + struct device *codec_dev; };
static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b) @@ -1194,13 +1196,27 @@ static void mtk_hdmi_clk_disable_audio(struct mtk_hdmi *hdmi) clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]); }
+static void mtk_hdmi_update_plugged_status(struct mtk_hdmi *hdmi, + enum drm_connector_status status) +{ + if (hdmi->plugged_cb && hdmi->codec_dev) + hdmi->plugged_cb(hdmi->codec_dev, + status == connector_status_connected); +} + static enum drm_connector_status hdmi_conn_detect(struct drm_connector *conn, bool force) { struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); + enum drm_connector_status status;
- return mtk_cec_hpd_high(hdmi->cec_dev) ? - connector_status_connected : connector_status_disconnected; + if (mtk_cec_hpd_high(hdmi->cec_dev)) + status = connector_status_connected; + else + status = connector_status_disconnected; + + mtk_hdmi_update_plugged_status(hdmi, status); + return status; }
static void hdmi_conn_destroy(struct drm_connector *conn) @@ -1648,20 +1664,41 @@ static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, return 0; }
+static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data, + hdmi_codec_plugged_cb fn, + struct device *codec_dev) +{ + struct mtk_hdmi *hdmi = data; + + hdmi->plugged_cb = fn; + hdmi->codec_dev = codec_dev; + + if (mtk_cec_hpd_high(hdmi->cec_dev)) + mtk_hdmi_update_plugged_status( + hdmi, connector_status_connected); + else + mtk_hdmi_update_plugged_status( + hdmi, connector_status_disconnected); + return 0; +} + static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = { .hw_params = mtk_hdmi_audio_hw_params, .audio_startup = mtk_hdmi_audio_startup, .audio_shutdown = mtk_hdmi_audio_shutdown, .digital_mute = mtk_hdmi_audio_digital_mute, .get_eld = mtk_hdmi_audio_get_eld, + .hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb, };
static int mtk_hdmi_register_audio_driver(struct device *dev) { + struct mtk_hdmi *hdmi = dev_get_drvdata(dev); struct hdmi_codec_pdata codec_data = { .ops = &mtk_hdmi_audio_codec_ops, .max_i2s_channels = 2, .i2s = 1, + .data = hdmi, }; struct platform_device *pdev;
Uses hdmi-codec to support HDMI jack reporting.
Signed-off-by: Tzung-Bi Shih tzungbi@google.com --- sound/soc/mediatek/mt8173/mt8173-rt5650.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c index ef6f23675286..849b050a54d1 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c @@ -11,6 +11,7 @@ #include <linux/of_gpio.h> #include <sound/soc.h> #include <sound/jack.h> +#include <sound/hdmi-codec.h> #include "../../codecs/rt5645.h"
#define MCLK_FOR_CODECS 12288000 @@ -98,7 +99,7 @@ static const struct snd_soc_ops mt8173_rt5650_ops = { .hw_params = mt8173_rt5650_hw_params, };
-static struct snd_soc_jack mt8173_rt5650_jack; +static struct snd_soc_jack mt8173_rt5650_jack, mt8173_rt5650_hdmi_jack;
static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime) { @@ -144,6 +145,19 @@ static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime) &mt8173_rt5650_jack); }
+static int mt8173_rt5650_hdmi_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, + &mt8173_rt5650_hdmi_jack, NULL, 0); + if (ret) + return ret; + + return hdmi_codec_set_jack_detect(rtd->codec_dai->component, + &mt8173_rt5650_hdmi_jack); +} + enum { DAI_LINK_PLAYBACK, DAI_LINK_CAPTURE, @@ -222,6 +236,7 @@ static struct snd_soc_dai_link mt8173_rt5650_dais[] = { .name = "HDMI BE", .no_pcm = 1, .dpcm_playback = 1, + .init = mt8173_rt5650_hdmi_init, SND_SOC_DAILINK_REG(hdmi_be), }, };
participants (1)
-
Tzung-Bi Shih