drm/sun4i: Add support for HDMI voltage regulator
authorJernej Skrabec <jernej.skrabec@siol.net>
Tue, 4 Sep 2018 04:40:52 +0000 (12:40 +0800)
committerMaxime Ripard <maxime.ripard@bootlin.com>
Wed, 5 Sep 2018 07:20:28 +0000 (09:20 +0200)
Some boards have HDMI VCC pin connected to voltage regulator which may
not be turned on by default.

Add support for such boards by adding voltage regulator handling code to
HDMI driver.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
[Icenowy: change supply name to "hvcc"]
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180904044053.15425-11-icenowy@aosc.io
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h

index 31875b636434a12337b597f6358fac37861c8303..ed2983770e9cb598bf6c60da201f9b2988701161 100644 (file)
@@ -125,10 +125,22 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
                return PTR_ERR(hdmi->clk_tmds);
        }
 
+       hdmi->regulator = devm_regulator_get(dev, "hvcc");
+       if (IS_ERR(hdmi->regulator)) {
+               dev_err(dev, "Couldn't get regulator\n");
+               return PTR_ERR(hdmi->regulator);
+       }
+
+       ret = regulator_enable(hdmi->regulator);
+       if (ret) {
+               dev_err(dev, "Failed to enable regulator\n");
+               return ret;
+       }
+
        ret = reset_control_deassert(hdmi->rst_ctrl);
        if (ret) {
                dev_err(dev, "Could not deassert ctrl reset control\n");
-               return ret;
+               goto err_disable_regulator;
        }
 
        ret = clk_prepare_enable(hdmi->clk_tmds);
@@ -183,6 +195,8 @@ err_disable_clk_tmds:
        clk_disable_unprepare(hdmi->clk_tmds);
 err_assert_ctrl_reset:
        reset_control_assert(hdmi->rst_ctrl);
+err_disable_regulator:
+       regulator_disable(hdmi->regulator);
 
        return ret;
 }
@@ -196,6 +210,7 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master,
        sun8i_hdmi_phy_remove(hdmi);
        clk_disable_unprepare(hdmi->clk_tmds);
        reset_control_assert(hdmi->rst_ctrl);
+       regulator_disable(hdmi->regulator);
 }
 
 static const struct component_ops sun8i_dw_hdmi_ops = {
index aadbe0a10b0c6b6dbd5da6b6538526994897abec..7fdc1ecd28922189f7fd1de9163006850a95fac5 100644 (file)
@@ -10,6 +10,7 @@
 #include <drm/drm_encoder.h>
 #include <linux/clk.h>
 #include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 
 #define SUN8I_HDMI_PHY_DBG_CTRL_REG    0x0000
@@ -176,6 +177,7 @@ struct sun8i_dw_hdmi {
        struct drm_encoder              encoder;
        struct sun8i_hdmi_phy           *phy;
        struct dw_hdmi_plat_data        plat_data;
+       struct regulator                *regulator;
        struct reset_control            *rst_ctrl;
 };