From c0e78d288acb363e10642e21f1be6a76ec8faaf1 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 4 Dec 2015 12:41:49 +0530 Subject: [PATCH] drm/i2c: adv7511: Init regulators ADV7533 requires a constant supply to the AVDD and V3P3 pins for it to function. The driver wrongly assumed that these will be enabled all the time. Configure these regulators during probe itself. We can later enable and disable it dynamically. Signed-off-by: Archit Taneja --- drivers/gpu/drm/i2c/adv7511.c | 61 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i2c/adv7511.h | 3 ++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index 7298f794ae20..3e672a4c766c 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -1096,6 +1097,57 @@ static struct drm_bridge_funcs adv7533_bridge_funcs = { * Probe & remove */ +static int adv7533_init_regulators(struct adv7511 *adv) +{ + int ret; + struct device *dev = &adv->i2c_main->dev; + + adv->avdd = devm_regulator_get(dev, "avdd"); + if (IS_ERR(adv->avdd)) { + ret = PTR_ERR(adv->avdd); + dev_err(dev, "failed to get avdd regulator %d\n", ret); + return ret; + } + + adv->v3p3 = devm_regulator_get(dev, "v3p3"); + if (IS_ERR(adv->v3p3)) { + ret = PTR_ERR(adv->v3p3); + dev_err(dev, "failed to get v3p3 regulator %d\n", ret); + return ret; + } + + if (regulator_can_change_voltage(adv->avdd)) { + ret = regulator_set_voltage(adv->avdd, 1800000, 1800000); + if (ret) { + dev_err(dev, "failed to set avdd voltage %d\n", ret); + return ret; + } + } + + if (regulator_can_change_voltage(adv->v3p3)) { + ret = regulator_set_voltage(adv->v3p3, 3300000, 3300000); + if (ret) { + dev_err(dev, "failed to set v3p3 voltage %d\n", ret); + return ret; + } + } + + /* keep the regulators always on */ + ret = regulator_enable(adv->avdd); + if (ret) { + dev_err(dev, "failed to enable avdd %d\n", ret); + return ret; + } + + ret = regulator_enable(adv->v3p3); + if (ret) { + dev_err(dev, "failed to enable v3p3 %d\n", ret); + return ret; + } + + return 0; +} + static int adv7511_parse_dt(struct device_node *np, struct adv7511_link_config *config) { @@ -1263,6 +1315,14 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) if (ret) return ret; + adv7511->i2c_main = i2c; + + if (adv7511->type == ADV7533) { + ret = adv7533_init_regulators(adv7511); + if (ret) + return ret; + } + /* * The power down GPIO is optional. If present, toggle it from active to * inactive to wake up the encoder. @@ -1305,7 +1365,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, cec_i2c_addr); adv7511_packet_disable(adv7511, 0xffff); - adv7511->i2c_main = i2c; adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); if (!adv7511->i2c_edid) return -ENOMEM; diff --git a/drivers/gpu/drm/i2c/adv7511.h b/drivers/gpu/drm/i2c/adv7511.h index e9008bf69caa..a5a892178613 100644 --- a/drivers/gpu/drm/i2c/adv7511.h +++ b/drivers/gpu/drm/i2c/adv7511.h @@ -279,6 +279,9 @@ struct adv7511 { struct gpio_desc *gpio_pd; + struct regulator *avdd; + struct regulator *v3p3; + /* ADV7533 DSI RX related params */ struct device_node *host_node; struct mipi_dsi_device *dsi; -- 2.39.5