Blob Blame History Raw
From: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Date: Mon, 24 Jul 2017 19:33:06 +0200
Subject: drm/omap: panel-dsi-cm: add regulator support
Git-commit: 82fa10d46be9d1b3ce5e5bf7b8ee2e38dc166029
Patch-mainline: v4.16-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Add support for regulators used by panels found inside
of the Nokia N950, N9 and Motorola Droid 4.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c |   57 ++++++++++++++++++++++--
 1 file changed, 53 insertions(+), 4 deletions(-)

--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -23,6 +23,7 @@
 #include <linux/workqueue.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
 
 #include <video/mipi_display.h>
 #include <video/of_display_timing.h>
@@ -60,6 +61,9 @@ struct panel_drv_data {
 	int reset_gpio;
 	int ext_te_gpio;
 
+	struct regulator *vpnl;
+	struct regulator *vddi;
+
 	bool use_dsi_backlight;
 
 	struct omap_dsi_pin_config pin_config;
@@ -590,25 +594,43 @@ static int dsicm_power_on(struct panel_d
 		.lp_clk_max = 10000000,
 	};
 
+	if (ddata->vpnl) {
+		r = regulator_enable(ddata->vpnl);
+		if (r) {
+			dev_err(&ddata->pdev->dev,
+				"failed to enable VPNL: %d\n", r);
+			return r;
+		}
+	}
+
+	if (ddata->vddi) {
+		r = regulator_enable(ddata->vddi);
+		if (r) {
+			dev_err(&ddata->pdev->dev,
+				"failed to enable VDDI: %d\n", r);
+			goto err_vpnl;
+		}
+	}
+
 	if (ddata->pin_config.num_pins > 0) {
 		r = in->ops.dsi->configure_pins(in, &ddata->pin_config);
 		if (r) {
 			dev_err(&ddata->pdev->dev,
 				"failed to configure DSI pins\n");
-			goto err0;
+			goto err_vddi;
 		}
 	}
 
 	r = in->ops.dsi->set_config(in, &dsi_config);
 	if (r) {
 		dev_err(&ddata->pdev->dev, "failed to configure DSI\n");
-		goto err0;
+		goto err_vddi;
 	}
 
 	r = in->ops.dsi->enable(in);
 	if (r) {
 		dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
-		goto err0;
+		goto err_vddi;
 	}
 
 	dsicm_hw_reset(ddata);
@@ -666,7 +688,13 @@ err:
 	dsicm_hw_reset(ddata);
 
 	in->ops.dsi->disable(in, true, false);
-err0:
+err_vddi:
+	if (ddata->vddi)
+		regulator_disable(ddata->vddi);
+err_vpnl:
+	if (ddata->vpnl)
+		regulator_disable(ddata->vpnl);
+
 	return r;
 }
 
@@ -689,6 +717,11 @@ static void dsicm_power_off(struct panel
 
 	in->ops.dsi->disable(in, true, false);
 
+	if (ddata->vddi)
+		regulator_disable(ddata->vddi);
+	if (ddata->vpnl)
+		regulator_disable(ddata->vpnl);
+
 	ddata->enabled = 0;
 }
 
@@ -1189,6 +1222,22 @@ static int dsicm_probe_of(struct platfor
 		return PTR_ERR(in);
 	}
 
+	ddata->vpnl = devm_regulator_get_optional(&pdev->dev, "vpnl");
+	if (IS_ERR(ddata->vpnl)) {
+		err = PTR_ERR(ddata->vpnl);
+		if (err == -EPROBE_DEFER)
+			return err;
+		ddata->vpnl = NULL;
+	}
+
+	ddata->vddi = devm_regulator_get_optional(&pdev->dev, "vddi");
+	if (IS_ERR(ddata->vddi)) {
+		err = PTR_ERR(ddata->vddi);
+		if (err == -EPROBE_DEFER)
+			return err;
+		ddata->vddi = NULL;
+	}
+
 	ddata->in = in;
 
 	/* TODO: ulps, backlight */