From: Hermes Wu <hermes...@ite.com.tw>

IT6505 supports audio form I2S to DP audio data sub stream

Support audio codec operation include
hw_params, audio_startup, audio_shutdown, hook_plugged_cb.

In order to prevent pop noise from sink devise, delay audio by
after I2S signal is enable by source.

Signed-off-by: Hermes Wu <hermes...@ite.com.tw>
---
 drivers/gpu/drm/bridge/ite-it6505.c | 67 ++++++++++++++++++++++++++++++++++---
 1 file changed, 62 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index 
88ef76a37fe6accacdd343839ff2569b31b18ceb..9dc58d307dae360ffab5df15e8fe8420d084c764
 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -3095,18 +3095,39 @@ static int __maybe_unused 
it6505_audio_setup_hw_params(struct it6505 *it6505,
        return 0;
 }
 
-static void __maybe_unused it6505_audio_shutdown(struct device *dev, void 
*data)
+static void it6505_audio_shutdown(struct device *dev, void *data)
 {
        struct it6505 *it6505 = dev_get_drvdata(dev);
 
+       cancel_delayed_work_sync(&it6505->delayed_audio);
+
        if (it6505->powered)
                it6505_disable_audio(it6505);
 }
 
-static int __maybe_unused it6505_audio_hook_plugged_cb(struct device *dev,
-                                                      void *data,
-                                                      hdmi_codec_plugged_cb fn,
-                                                      struct device *codec_dev)
+static int it6505_audio_hw_params(struct device *dev,
+                                 void *data,
+                                 struct hdmi_codec_daifmt *daifmt,
+                                 struct hdmi_codec_params *params)
+{
+       struct it6505 *it6505 = dev_get_drvdata(dev);
+
+       return it6505_audio_setup_hw_params(it6505, params);
+}
+
+static int it6505_audio_startup(struct device *dev, void *data)
+{
+       struct it6505 *it6505 = dev_get_drvdata(dev);
+
+       queue_delayed_work(system_wq, &it6505->delayed_audio,
+                          msecs_to_jiffies(180));
+       return 0;
+}
+
+static int it6505_audio_hook_plugged_cb(struct device *dev,
+                                       void *data,
+                                       hdmi_codec_plugged_cb fn,
+                                       struct device *codec_dev)
 {
        struct it6505 *it6505 = data;
 
@@ -3117,6 +3138,36 @@ static int __maybe_unused 
it6505_audio_hook_plugged_cb(struct device *dev,
        return 0;
 }
 
+static const struct hdmi_codec_ops it6505_audio_codec_ops = {
+       .hw_params = it6505_audio_hw_params,
+       .audio_startup = it6505_audio_startup,
+       .audio_shutdown = it6505_audio_shutdown,
+       .hook_plugged_cb = it6505_audio_hook_plugged_cb,
+};
+
+static int it6505_register_audio_driver(struct device *dev)
+{
+       struct it6505 *it6505 = dev_get_drvdata(dev);
+       struct hdmi_codec_pdata codec_data = {
+               .ops = &it6505_audio_codec_ops,
+               .max_i2s_channels = 8,
+               .i2s = 1,
+               .data = it6505,
+       };
+       struct platform_device *pdev;
+
+       pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+                                            PLATFORM_DEVID_AUTO, &codec_data,
+                                            sizeof(codec_data));
+       if (IS_ERR(pdev))
+               return PTR_ERR(pdev);
+
+       INIT_DELAYED_WORK(&it6505->delayed_audio, it6505_delayed_audio);
+       DRM_DEV_DEBUG_DRIVER(dev, "bound to %s", HDMI_CODEC_DRV_NAME);
+
+       return 0;
+}
+
 static inline struct it6505 *bridge_to_it6505(struct drm_bridge *bridge)
 {
        return container_of(bridge, struct it6505, bridge);
@@ -3677,6 +3728,12 @@ static int it6505_i2c_probe(struct i2c_client *client)
                return err;
        }
 
+       err = it6505_register_audio_driver(dev);
+       if (err < 0) {
+               dev_err(dev, "Failed to register audio driver: %d", err);
+               return err;
+       }
+
        INIT_WORK(&it6505->link_works, it6505_link_training_work);
        INIT_WORK(&it6505->hdcp_wait_ksv_list, it6505_hdcp_wait_ksv_list);
        INIT_DELAYED_WORK(&it6505->hdcp_work, it6505_hdcp_work);

---
base-commit: fe003bcb69f7bff9ff2b30b659b004dbafe52907
change-id: 20250114-add-audio-codec-8c9d47062a6c

Best regards,
-- 
Hermes Wu <hermes...@ite.com.tw>


Reply via email to