From 44716efd924c1cb65c32a198112718c6568387a4 Mon Sep 17 00:00:00 2001
From: zwl <zwl@rockchips.com>
Date: Wed, 5 Nov 2014 20:14:04 +0800
Subject: [PATCH] rk fb: 	* add support the regulator type of power
 control for lcd 	Signed-off-by: zwl <zwl@rock-chips.com>

---
 drivers/video/rockchip/rk_fb.c | 52 ++++++++++++++++++++++++++++++++--
 include/linux/rk_fb.h          |  2 +-
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c
index 2db236f0762f..4a97c5fd7b4e 100755
--- a/drivers/video/rockchip/rk_fb.c
+++ b/drivers/video/rockchip/rk_fb.c
@@ -29,6 +29,7 @@
 #include <linux/rk_fb.h>
 #include <linux/linux_logo.h>
 #include <linux/dma-mapping.h>
+#include <linux/regulator/consumer.h>
 
 #if defined(CONFIG_RK_HDMI)
 #include "hdmi/rk_hdmi.h"
@@ -264,7 +265,15 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv)
 
 			} else {
 				pwr_ctr->pwr_ctr.type = REGULATOR;
-
+				pwr_ctr->pwr_ctr.rgl_name = NULL;
+				ret = of_property_read_string(child, "rockchip,regulator_name",
+							     &(pwr_ctr->pwr_ctr.rgl_name));
+				if (ret || IS_ERR_OR_NULL(pwr_ctr->pwr_ctr.rgl_name))
+					dev_err(dev_drv->dev, "get regulator name failed!\n");
+				if (!of_property_read_u32(child, "rockchip,regulator_voltage", &val))
+					pwr_ctr->pwr_ctr.volt = val;
+				else
+					pwr_ctr->pwr_ctr.volt = 0;
 			}
 		};
 		of_property_read_u32(child, "rockchip,delay", &val);
@@ -300,6 +309,9 @@ int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv)
 	struct list_head *pos;
 	struct rk_disp_pwr_ctr_list *pwr_ctr_list;
 	struct pwr_ctr *pwr_ctr;
+	struct regulator *regulator_lcd = NULL;
+	int count = 10;
+
 	if (list_empty(&dev_drv->pwrlist_head))
 		return 0;
 	list_for_each(pos, &dev_drv->pwrlist_head) {
@@ -309,6 +321,23 @@ int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv)
 		if (pwr_ctr->type == GPIO) {
 			gpio_direction_output(pwr_ctr->gpio, pwr_ctr->atv_val);
 			mdelay(pwr_ctr->delay);
+		} else if (pwr_ctr->type == REGULATOR) {
+			if (pwr_ctr->rgl_name)
+				regulator_lcd = regulator_get(NULL, pwr_ctr->rgl_name);
+			if (regulator_lcd == NULL) {
+				dev_err(dev_drv->dev, "%s: regulator get failed,regulator name:%s\n",
+				            __func__, pwr_ctr->rgl_name);
+				continue;
+			}
+			regulator_set_voltage(regulator_lcd, pwr_ctr->volt, pwr_ctr->volt);
+			while (!regulator_is_enabled(regulator_lcd)) {
+				if (regulator_enable(regulator_lcd) == 0 || count == 0)
+					break;
+				else
+					count--;
+			}
+			regulator_put(regulator_lcd);
+			msleep(pwr_ctr->delay);
 		}
 	}
 
@@ -320,14 +349,33 @@ int rk_disp_pwr_disable(struct rk_lcdc_driver *dev_drv)
 	struct list_head *pos;
 	struct rk_disp_pwr_ctr_list *pwr_ctr_list;
 	struct pwr_ctr *pwr_ctr;
+	struct regulator *regulator_lcd = NULL;
+	int count = 10;
+
 	if (list_empty(&dev_drv->pwrlist_head))
 		return 0;
 	list_for_each(pos, &dev_drv->pwrlist_head) {
 		pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list,
 					  list);
 		pwr_ctr = &pwr_ctr_list->pwr_ctr;
-		if (pwr_ctr->type == GPIO)
+		if (pwr_ctr->type == GPIO) {
 			gpio_set_value(pwr_ctr->gpio, !pwr_ctr->atv_val);
+		} else if (pwr_ctr->type == REGULATOR) {
+			if (pwr_ctr->rgl_name)
+				regulator_lcd = regulator_get(NULL, pwr_ctr->rgl_name);
+			if (regulator_lcd == NULL) {
+				dev_err(dev_drv->dev, "%s: regulator get failed,regulator name:%s\n",
+				            __func__, pwr_ctr->rgl_name);
+				continue;
+			}
+			while (regulator_is_enabled(regulator_lcd) > 0) {
+				if (regulator_disable(regulator_lcd) == 0 || count == 0)
+					break;
+				else
+					count--;
+			}
+			regulator_put(regulator_lcd);
+		}
 	}
 	return 0;
 }
diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h
index bf9b6205d68f..e34158bcf540 100755
--- a/include/linux/rk_fb.h
+++ b/include/linux/rk_fb.h
@@ -273,7 +273,7 @@ struct pwr_ctr {
 	int is_rst;
 	int gpio;
 	int atv_val;
-	char rgl_name[32];
+	const char *rgl_name;
 	int volt;
 	int delay;
 };
-- 
2.34.1