[PATCH v3 20/21] OMAP: DSS2: Taal: Add regulator configuration support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Jani Nikula <ext-jani.1.nikula@xxxxxxxxx>

Add support for configuring regulators in the panel specific
configuration data.

Signed-off-by: Jani Nikula <ext-jani.1.nikula@xxxxxxxxx>
---
 drivers/video/omap2/displays/panel-taal.c |   83 +++++++++++++++++++++++++++++
 1 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index b73cd12..617723b 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -30,6 +30,7 @@
 #include <linux/gpio.h>
 #include <linux/workqueue.h>
 #include <linux/slab.h>
+#include <linux/regulator/consumer.h>
 #include <linux/mutex.h>
 
 #include <plat/display.h>
@@ -68,6 +69,73 @@ static irqreturn_t taal_te_isr(int irq, void *data);
 static void taal_te_timeout_work_callback(struct work_struct *work);
 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
 
+struct panel_regulator {
+	struct regulator *regulator;
+	const char *name;
+	int min_uV;
+	int max_uV;
+};
+
+static void free_regulators(struct panel_regulator *regulators, int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++) {
+		/* disable/put in reverse order */
+		regulator_disable(regulators[n - i - 1].regulator);
+		regulator_put(regulators[n - i - 1].regulator);
+	}
+}
+
+static int init_regulators(struct omap_dss_device *dssdev,
+			struct panel_regulator *regulators, int n)
+{
+	int r, i, v;
+
+	for (i = 0; i < n; i++) {
+		struct regulator *reg;
+
+		reg = regulator_get(&dssdev->dev, regulators[i].name);
+		if (IS_ERR(reg)) {
+			dev_err(&dssdev->dev, "failed to get regulator %s\n",
+				regulators[i].name);
+			r = PTR_ERR(reg);
+			goto err;
+		}
+
+		/* FIXME: better handling of fixed vs. variable regulators */
+		v = regulator_get_voltage(reg);
+		if (v < regulators[i].min_uV || v > regulators[i].max_uV) {
+			r = regulator_set_voltage(reg, regulators[i].min_uV,
+						regulators[i].max_uV);
+			if (r) {
+				dev_err(&dssdev->dev,
+					"failed to set regulator %s voltage\n",
+					regulators[i].name);
+				regulator_put(reg);
+				goto err;
+			}
+		}
+
+		r = regulator_enable(reg);
+		if (r) {
+			dev_err(&dssdev->dev, "failed to enable regulator %s\n",
+				regulators[i].name);
+			regulator_put(reg);
+			goto err;
+		}
+
+		regulators[i].regulator = reg;
+	}
+
+	return 0;
+
+err:
+	free_regulators(regulators, i);
+
+	return r;
+}
+
 /**
  * struct panel_config - panel configuration
  * @name: panel name
@@ -75,6 +143,8 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
  * @timings: panel resolution
  * @sleep: various panel specific delays, passed to msleep() if non-zero
  * @reset_sequence: reset sequence timings, passed to udelay() if non-zero
+ * @regulators: array of panel regulators
+ * @num_regulators: number of regulators in the array
  */
 struct panel_config {
 	const char *name;
@@ -93,6 +163,9 @@ struct panel_config {
 		unsigned int high;
 		unsigned int low;
 	} reset_sequence;
+
+	struct panel_regulator *regulators;
+	int num_regulators;
 };
 
 enum {
@@ -629,6 +702,11 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
 	atomic_set(&td->do_update, 0);
 
+	r = init_regulators(dssdev, panel_config->regulators,
+			panel_config->num_regulators);
+	if (r)
+		goto err_reg;
+
 	td->esd_wq = create_singlethread_workqueue("taal_esd");
 	if (td->esd_wq == NULL) {
 		dev_err(&dssdev->dev, "can't create ESD workqueue\n");
@@ -714,6 +792,8 @@ err_gpio:
 err_bl:
 	destroy_workqueue(td->esd_wq);
 err_wq:
+	free_regulators(panel_config->regulators, panel_config->num_regulators);
+err_reg:
 	kfree(td);
 err:
 	return r;
@@ -746,6 +826,9 @@ static void taal_remove(struct omap_dss_device *dssdev)
 	/* reset, to be sure that the panel is in a valid state */
 	taal_hw_reset(dssdev);
 
+	free_regulators(td->panel_config->regulators,
+			td->panel_config->num_regulators);
+
 	kfree(td);
 }
 
-- 
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux