From: 张晴 <zhangqing@rock-chips.com>
Date: Sun, 26 Jan 2014 01:58:37 +0000 (+0800)
Subject: rk:pmu:rk808&act8846:support dts for linux 3.1
X-Git-Tag: firefly_0821_release~6361
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5d87f43f8a425d81b0dd915103c134d5175bea32;p=firefly-linux-kernel-4.4.55.git

rk:pmu:rk808&act8846:support dts for linux 3.1
---

diff --git a/arch/arm/boot/dts/act8846.dtsi b/arch/arm/boot/dts/act8846.dtsi
new file mode 100644
index 000000000000..a69b8ba9b2f8
--- /dev/null
+++ b/arch/arm/boot/dts/act8846.dtsi
@@ -0,0 +1,76 @@
+
+&act8846{
+
+	compatible = "act,act8846";
+
+	regulators {
+	
+		#address-cells = <1>;
+		#size-cells = <0>;	
+
+		 dcdc1_reg: regulator@0{
+			reg = <0>;
+			regulator-compatible= "act_dcdc1";
+		};
+
+		dcdc2_reg: regulator@1 {
+			reg = <1>;
+			regulator-compatible = "act_dcdc2";	
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1500000>;
+		};
+
+		dcdc3_reg: regulator@2 {
+			reg = <2>;
+			regulator-compatible = "act_dcdc3";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1500000>;
+		};
+
+		dcdc4_reg: regulator@3 {
+			reg = <3>;
+			regulator-compatible = "act_dcdc4";
+		};
+
+		ldo1_reg: regulator@4 {
+			reg = <4>;
+			regulator-compatible= "act_ldo1";
+		};
+
+		ldo2_reg: regulator@5 {
+			reg = <5>;
+			regulator-compatible = "act_ldo2";
+		};
+
+		ldo3_reg: regulator@6 {
+			reg = <6>;
+			regulator-compatible = "act_ldo3";
+		};
+
+		ldo4_reg:regulator@7 {
+			reg = <7>;
+			regulator-compatible = "act_ldo4";
+		};
+
+		ldo5_reg: regulator@8 {
+			reg = <8>;
+			regulator-compatible= "act_ldo5";
+		};
+
+		ldo6_reg: regulator@9 {
+			reg = <9>;
+			regulator-compatible = "act_ldo6";
+		};
+
+		ldo7_reg: regulator@10 {
+			reg = <10>;
+			regulator-compatible = "act_ldo7";
+		};
+
+		ldo8_reg: regulator@11 {
+			reg = <11>;
+			regulator-compatible = "act_ldo8";
+		};
+	};
+		
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/rk3188-tb.dts b/arch/arm/boot/dts/rk3188-tb.dts
index 037dacbabfa8..1340e1334b9f 100644
--- a/arch/arm/boot/dts/rk3188-tb.dts
+++ b/arch/arm/boot/dts/rk3188-tb.dts
@@ -47,6 +47,15 @@
 		compatible = "nxp,pcf8563";
 		reg = <0x51>;
 	};
+	
+	act8846: act8846@5a {
+		reg = <0x5a>;
+		status = "okay";
+	};
+	rk808: rk808@1b {
+		reg = <0x1b>;
+		status = "okay";
+	};
 };
 
 &i2c3 {
@@ -69,5 +78,209 @@
 &pwm3 {
         status = "okay";
 };
+/include/ "act8846.dtsi"
+&act8846 {
+	gpios =<&gpio3 GPIO_D3 GPIO_ACTIVE_LOW>; 
+	act,pmic-dcdc-sleep-voltage = <1200000>,<1200000>,<1200000>,<3000000>;
+	act,pmic-ldo-sleep-voltage = <1000000>,<1200000>,<1800000>,<3300000>,<3300000>,<3300000>,<1800000>,<2800000>;	
+
+regulators {
+		
+		 dcdc1_reg: regulator@0{
+			regulator-name= "act_dcdc1";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		dcdc2_reg: regulator@1 {
+			regulator-name= "vdd_logic";
+			regulator-always-on;
+			regulator-boot-on;			
+		};
+
+		dcdc3_reg: regulator@2 {
+			regulator-name= "vdd_arm";
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		dcdc4_reg: regulator@3 {
+			regulator-name= "act_dcdc4";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo1_reg: regulator@4 {
+			regulator-name= "act_ldo1";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo2_reg: regulator@5 {
+			regulator-name= "act_ldo2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo3_reg: regulator@6 {
+			regulator-name= "act_ldo3";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo4_reg:regulator@7 {
+			regulator-name= "act_ldo4";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo5_reg: regulator@8 {
+			regulator-name= "act_ldo5";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo6_reg: regulator@9 {
+			regulator-name= "act_ldo6";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo7_reg: regulator@10 {
+			regulator-name= "act_ldo7";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo8_reg: regulator@11 {
+			regulator-name= "act_ldo8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+	};
+};
+/include/ "rk808.dtsi"
+&rk808{
+	gpios =<&gpio0 GPIO_B3 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_A1 GPIO_ACTIVE_LOW>; 
+	rockchip,pmic-dcdc-sleep-voltage = <900000>,<900000>,<1200000>,<3000000>;
+	rockchip,pmic-ldo-sleep-voltage = <3300000>,<3300000>,<1000000>,<1800000>,<2800000>,<1200000>,<1800000>,<1800000>;
+
+regulators {
+		
+		 rk808_dcdc1_reg: regulator@0{
+			regulator-name= "vdd_arm";	
+			regulator-always-on;
+			regulator-boot-on;
+	/*		regulator-initial-mode = <2>;*/
+		};
+
+		rk808_dcdc2_reg: regulator@1 {
+			regulator-name= "vdd_logic";
+			regulator-always-on;
+			regulator-boot-on;		
+	/*		regulator-initial-mode = <2>;*/
+		};
+
+		rk808_dcdc3_reg: regulator@2 {
+			regulator-name= "rk_dcdc3";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		rk808_dcdc4_reg: regulator@3 {
+			regulator-name= "rk_dcdc4";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		rk808_ldo1_reg: regulator@4 {
+			regulator-name= "rk_ldo1";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		rk808_ldo2_reg: regulator@5 {
+			regulator-name= "rk_ldo2";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		rk808_ldo3_reg: regulator@6 {
+			regulator-name= "rk_ldo3";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		rk808_ldo4_reg:regulator@7 {
+			regulator-name= "rk_ldo4";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		rk808_ldo5_reg: regulator@8 {
+			regulator-name= "rk_ldo5";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		rk808_ldo6_reg: regulator@9 {
+			regulator-name= "rk_ldo6";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		rk808_ldo7_reg: regulator@10 {
+			regulator-name= "rk_ldo7";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		rk808_ldo8_reg: regulator@11 {
+			regulator-name= "rk_ldo8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+	};
+};
 
 
diff --git a/arch/arm/boot/dts/rk808.dtsi b/arch/arm/boot/dts/rk808.dtsi
new file mode 100644
index 000000000000..2ad195719137
--- /dev/null
+++ b/arch/arm/boot/dts/rk808.dtsi
@@ -0,0 +1,75 @@
+
+
+&rk808 {
+	compatible = "rockchip,rk808";
+	
+	regulators {
+		#address-cells = <1>;
+		#size-cells = <0>;	
+
+		rk808_dcdc1_reg: regulator@0 {
+			reg = <0>;
+			regulator-compatible = "rk_dcdc1";
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <1500000>;
+		};
+
+		rk808_dcdc2_reg: regulator@1 {
+			reg = <1>;
+			regulator-compatible = "rk_dcdc2";
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <1500000>;
+		};
+
+		rk808_dcdc3_reg: regulator@2 {
+			reg = <2>;
+			regulator-compatible = "rk_dcdc3";
+		};
+
+		rk808_dcdc4_reg: regulator@3 {
+			reg = <3>;
+			regulator-compatible = "rk_dcdc4";
+		};
+
+		rk808_ldo1_reg: regulator@4 {
+			reg = <4>;
+			regulator-compatible = "rk_ldo1";
+		};
+
+		rk808_ldo2_reg: regulator@5 {
+			reg = <5>;
+			regulator-compatible = "rk_ldo2";
+		};
+
+		rk808_ldo3_reg: regulator@6 {
+			reg = <6>;
+			regulator-compatible = "rk_ldo3";
+		};
+
+		rk808_ldo4_reg: regulator@7{
+			reg = <7>;
+			regulator-compatible = "rk_ldo4";
+		};
+
+		rk808_ldo5_reg: regulator@8{
+			reg = <8>;
+			regulator-compatible = "rk_ldo5";
+		};
+
+		rk808_ldo6_reg: regulator@9{
+			reg = <9>;
+			regulator-compatible = "rk_ldo6";
+		};
+
+		rk808_ldo7_reg: regulator@10 {
+			reg = <10>;
+			regulator-compatible = "rk_ldo7";
+		};
+
+		rk808_ldo8_reg: regulator@11{
+			reg = <11>;
+			regulator-compatible = "rk_ldo8";
+		};
+
+	};
+};
diff --git a/arch/arm/configs/rockchip_defconfig b/arch/arm/configs/rockchip_defconfig
index fa47b6ede65e..7af47ef708cd 100644
--- a/arch/arm/configs/rockchip_defconfig
+++ b/arch/arm/configs/rockchip_defconfig
@@ -276,8 +276,10 @@ CONFIG_SPI=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_THERMAL=y
+CONFIG_MFD_RK808=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ACT8846=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_RC_SUPPORT=y
@@ -395,6 +397,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_SWITCH=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RK808_RTC=y
 CONFIG_STAGING=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a5e54f0d6a73..53ba537bf47c 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -349,6 +349,15 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 
+config MFD_RK808
+	bool "RK808 Power Management chip"
+	depends on I2C=y 
+	select MFD_CORE
+	select RTC_RK808
+	help
+	  if you say yes here you get support for the RK808 series of
+	  Power Management chips.
+
 config EZX_PCAP
 	bool "Motorola EZXPCAP Support"
 	depends on GENERIC_HARDIRQS && SPI_MASTER
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 3a0120315aa3..72f479c0971d 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -144,6 +144,7 @@ obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o
 obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
+obj-$(CONFIG_MFD_RK808)	+= rk808.o rk808-irq.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
 obj-$(CONFIG_MFD_INTEL_MSIC)	+= intel_msic.o
 obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
diff --git a/drivers/mfd/rk808-irq.c b/drivers/mfd/rk808-irq.c
index 229a968f7e71..dbae25e4dccf 100755
--- a/drivers/mfd/rk808-irq.c
+++ b/drivers/mfd/rk808-irq.c
@@ -21,11 +21,14 @@
 #include <linux/mfd/rk808.h>
 #include <linux/wakelock.h>
 #include <linux/kthread.h>
+#include <linux/irqdomain.h>
+#include <linux/regmap.h>
+
 
 static inline int irq_to_rk808_irq(struct rk808 *rk808,
 							int irq)
 {
-	return (irq - rk808->irq_base);
+	return (irq - rk808->chip_irq);
 }
 
 /*
@@ -43,8 +46,9 @@ static irqreturn_t rk808_irq(int irq, void *irq_data)
 	u32 irq_sts;
 	u32 irq_mask;
 	u8 reg;
-	int i;
-	//printk(" rk808 irq %d \n",irq);	
+	int i, cur_irq;
+//	printk("%s,line=%d\n", __func__,__LINE__);	
+
 	wake_lock(&rk808->irq_wake);	
 	rk808_i2c_read(rk808, RK808_INT_STS_REG1, 1, &reg);
 	irq_sts = reg;
@@ -65,11 +69,12 @@ static irqreturn_t rk808_irq(int irq, void *irq_data)
 	}
 
 	for (i = 0; i < rk808->irq_num; i++) {
-
 		if (!(irq_sts & (1 << i)))
 			continue;
+		cur_irq = irq_find_mapping(rk808->irq_domain, i);
 
-		handle_nested_irq(rk808->irq_base + i);
+		if (cur_irq)
+		handle_nested_irq(cur_irq);
 	}
 
 	/* Write the STS register back to clear IRQs we handled */
@@ -141,26 +146,38 @@ static struct irq_chip rk808_irq_chip = {
 	.irq_enable = rk808_irq_enable,
 	.irq_set_wake = rk808_irq_set_wake,
 };
-
-int rk808_irq_init(struct rk808 *rk808, int irq,struct rk808_platform_data *pdata)
+static int rk808_irq_domain_map(struct irq_domain *d, unsigned int irq,
+					irq_hw_number_t hw)
 {
-	int ret, cur_irq;
-	int flags = IRQF_ONESHOT;
-	u8 reg;
+	struct rk808 *rk808 = d->host_data;
 
-	printk("%s,line=%d\n", __func__,__LINE__);
+	irq_set_chip_data(irq, rk808);
+	irq_set_chip_and_handler(irq, &rk808_irq_chip, handle_edge_irq);
+	irq_set_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+	set_irq_flags(irq, IRQF_VALID);
+#else
+	irq_set_noprobe(irq);
+#endif
+	return 0;
+}
 
+static struct irq_domain_ops rk808_irq_domain_ops = {
+	.map = rk808_irq_domain_map,
+};
 
+int rk808_irq_init(struct rk808 *rk808, int irq,struct rk808_board *pdata)
+{
+	struct irq_domain *domain;
+	int ret,val;
+	u8 reg;
+
+//	printk("%s,line=%d\n", __func__,__LINE__);	
 	if (!irq) {
 		dev_warn(rk808->dev, "No interrupt support, no core IRQ\n");
 		return 0;
 	}
 
-	if (!pdata || !pdata->irq_base) {
-		dev_warn(rk808->dev, "No interrupt support, no IRQ base\n");
-		return 0;
-	}
-
 	/* Clear unattended interrupts */
 	rk808_i2c_read(rk808, RK808_INT_STS_REG1, 1, &reg);
 	rk808_i2c_write(rk808, RK808_INT_STS_REG1, 1, reg);
@@ -171,35 +188,39 @@ int rk808_irq_init(struct rk808 *rk808, int irq,struct rk808_platform_data *pdat
 
 	/* Mask top level interrupts */
 	rk808->irq_mask = 0xFFFFFF;
-
 	mutex_init(&rk808->irq_lock);	
 	wake_lock_init(&rk808->irq_wake, WAKE_LOCK_SUSPEND, "rk808_irq_wake");
-	rk808->chip_irq = irq;
-	rk808->irq_base = pdata->irq_base;
-
 	rk808->irq_num = RK808_NUM_IRQ;
-
-	/* Register with genirq */
-	for (cur_irq = rk808->irq_base;
-	     cur_irq < rk808->irq_num + rk808->irq_base;
-	     cur_irq++) {
-		irq_set_chip_data(cur_irq, rk808);
-		irq_set_chip_and_handler(cur_irq, &rk808_irq_chip,
-					 handle_edge_irq);
-		irq_set_nested_thread(cur_irq, 1);
-
-		/* ARM needs us to explicitly flag the IRQ as valid
-		 * and will set them noprobe when we do so. */
-#ifdef CONFIG_ARM
-		set_irq_flags(cur_irq, IRQF_VALID);
-#else
-		irq_set_noprobe(cur_irq);
-#endif
+	rk808->irq_gpio = pdata->irq_gpio;
+	if (rk808->irq_gpio && !rk808->chip_irq) {
+		rk808->chip_irq = gpio_to_irq(rk808->irq_gpio);
+
+		if (rk808->irq_gpio) {
+			ret = gpio_request(rk808->irq_gpio, "rk808_pmic_irq");
+			if (ret < 0) {
+				dev_err(rk808->dev,
+					"Failed to request gpio %d with ret:"
+					"%d\n",	rk808->irq_gpio, ret);
+				return IRQ_NONE;
+			}
+			gpio_direction_input(rk808->irq_gpio);
+			val = gpio_get_value(rk808->irq_gpio);
+			gpio_free(rk808->irq_gpio);
+			pr_info("%s: rk808_pmic_irq=%x\n", __func__, val);
+		}
+	}
+	
+	domain = irq_domain_add_linear(NULL, RK808_NUM_IRQ,
+					&rk808_irq_domain_ops, rk808);
+	if (!domain) {
+		dev_err(rk808->dev, "could not create irq domain\n");
+		return -ENODEV;
 	}
+	rk808->irq_domain = domain;
 
-	ret = request_threaded_irq(irq, NULL, rk808_irq, flags, "rk808", rk808);
+	ret = request_threaded_irq(rk808->chip_irq, NULL, rk808_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "rk808", rk808);
 
-	irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
+	irq_set_irq_type(rk808->chip_irq, IRQ_TYPE_LEVEL_LOW);
 
 	if (ret != 0)
 		dev_err(rk808->dev, "Failed to request IRQ: %d\n", ret);
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 80b153126e8a..f8c17039ea9f 100755
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -16,15 +16,22 @@
 #include <linux/regulator/driver.h>
 #include <linux/mfd/rk808.h>
 #include <linux/mfd/core.h>
-#include <mach/gpio.h>
 #include <linux/delay.h>
-#include <mach/iomux.h>
 #include <linux/slab.h>
+#include <linux/mutex.h>
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
 #endif
 #include <linux/interrupt.h>
-
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regmap.h>
 
 #if 0
 #define DBG(x...)	printk(KERN_INFO x)
@@ -484,6 +491,7 @@ static int rk808_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
 	struct rk808 *rk808 = rdev_get_drvdata(dev);
 	int buck = rdev_get_id(dev) - RK808_DCDC1;
 	u16 mask = 0x80;
+
 	switch(mode)
 	{
 	case REGULATOR_MODE_FAST:
@@ -633,8 +641,7 @@ static struct regulator_desc regulators[] = {
  int rk808_i2c_read(struct rk808 *rk808, char reg, int count,u8 *dest)
 {
 	struct i2c_client *i2c = rk808->i2c;
-
-      int ret;
+	int ret;
     struct i2c_adapter *adap;
     struct i2c_msg msgs[2];
 
@@ -648,19 +655,19 @@ static struct regulator_desc regulators[] = {
     
     msgs[0].addr = i2c->addr;
     msgs[0].buf = &reg;
-    msgs[0].flags = 0;
+    msgs[0].flags = i2c->flags;
     msgs[0].len = 1;
-    msgs[0].scl_rate = 200*1000;
+    msgs[0].scl_rate = 100*1000;
     
-    msgs[1].buf = dest;
+    msgs[1].buf = (u8 *)dest;
     msgs[1].addr = i2c->addr;
-    msgs[1].flags =  I2C_M_RD;
-    msgs[1].len = count;
-    msgs[1].scl_rate = 200*1000;
+    msgs[1].flags =  i2c->flags |I2C_M_RD;
+    msgs[1].len = 1;
+    msgs[1].scl_rate = 100*1000;
 
     ret = i2c_transfer(adap, msgs, 2);
 
-	DBG("***run in %s %x  % x\n",__FUNCTION__,i2c->addr,msgs[0].buf);
+	DBG("***run in %s %x  % x\n",__FUNCTION__,i2c->addr,*(msgs[1].buf));
     return 0;
 }
 
@@ -685,7 +692,7 @@ int rk808_i2c_write(struct rk808 *rk808, char reg, int count,  const u8 src)
 	msg.buf = &tx_buf[0];
 	msg.len = 1 +1;
 	msg.flags = i2c->flags;   
-	msg.scl_rate = 200*1000;	
+	msg.scl_rate = 100*1000;	
 
 	ret = i2c_transfer(adap, &msg, 1);
 	return ret;	
@@ -766,7 +773,7 @@ out:
 	return err;
 }
 EXPORT_SYMBOL_GPL(rk808_clear_bits);
-
+#if 0
 int rk808_bulk_read(struct rk808 *rk808, u8 reg,
 		     int count, u8 *buf)
 {
@@ -828,7 +835,7 @@ int rk808_bulk_write(struct rk808 *rk808, u8 reg,
 
 }
 EXPORT_SYMBOL_GPL(rk808_bulk_write);
-
+#endif
 
 #if 1
 static ssize_t rk808_test_store(struct kobject *kobj, struct kobj_attribute *attr,
@@ -911,47 +918,166 @@ static struct rk808_attribute rk808_attrs[] = {
 };
 #endif
 
-static int __devinit setup_regulators(struct rk808 *rk808, struct rk808_platform_data *pdata)
-{	
-	int i, err;
+extern void rk28_send_wakeup_key(void);
+static irqreturn_t rk808_vbat_lo_irq(int irq, void *data)
+{
+        printk("rk808 vbat low %s:irq=%d\n",__func__,irq);
+	rk808_set_bits(g_rk808,0x4c,(0x1 << 1),(0x1 <<1));
+//	rk28_send_wakeup_key();
+        return IRQ_HANDLED;
+}
 
-	rk808->num_regulators = pdata->num_regulators;
-	rk808->rdev = kcalloc(pdata->num_regulators,
-			       sizeof(struct regulator_dev *), GFP_KERNEL);
-	if (!rk808->rdev) {
-		return -ENOMEM;
+#ifdef CONFIG_OF
+static struct of_device_id rk808_of_match[] = {
+	{ .compatible = "rockchip,rk808"},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, rk808_of_match);
+#endif
+
+#ifdef CONFIG_OF
+static struct of_regulator_match rk808_reg_matches[] = {
+	{ .name = "rk_dcdc1", .driver_data = (void *)0 },
+	{ .name = "rk_dcdc2", .driver_data = (void *)1 },
+	{ .name = "rk_dcdc3", .driver_data = (void *)2 },
+	{ .name = "rk_dcdc4", .driver_data = (void *)3 },
+	{ .name = "rk_ldo1", .driver_data = (void *)4 },
+	{ .name = "rk_ldo2", .driver_data = (void *)5 },
+	{ .name = "rk_ldo3", .driver_data = (void *)6 },
+	{ .name = "rk_ldo4", .driver_data = (void *)7 },
+	{ .name = "rk_ldo5", .driver_data = (void *)8 },
+	{ .name = "rk_ldo6", .driver_data = (void *)9 },
+	{ .name = "rk_ldo7", .driver_data = (void *)10 },
+	{ .name = "rk_ldo8", .driver_data = (void *)11 },
+};
+
+static struct rk808_board *rk808_parse_dt(struct rk808 *rk808)
+{
+	struct rk808_board *pdata;
+	struct device_node *regs,*rk808_pmic_np;
+	int i, count;
+
+	rk808_pmic_np = of_node_get(rk808->dev->of_node);
+	if (!rk808_pmic_np) {
+		printk("could not find pmic sub-node\n");
+		return NULL;
 	}
-	/* Instantiate the regulators */
-	for (i = 0; i < pdata->num_regulators; i++) {
-		int id = pdata->regulators[i].id;
-		rk808->rdev[i] = regulator_register(&regulators[id],
-			rk808->dev, pdata->regulators[i].initdata, rk808);
-/*
-		if (IS_ERR(rk808->rdev[i])) {
-			err = PTR_ERR(rk808->rdev[i]);
-			dev_err(rk808->dev, "regulator init failed: %d\n",
-				err);
-			goto error;
-		}*/
+
+	regs = of_find_node_by_name(rk808_pmic_np, "regulators");
+	if (!regs)
+		return NULL;
+
+	count = of_regulator_match(rk808->dev, regs, rk808_reg_matches,
+				   rk808_NUM_REGULATORS);
+	of_node_put(regs);
+	if ((count < 0) || (count > rk808_NUM_REGULATORS))
+		return NULL;
+
+	pdata = devm_kzalloc(rk808->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+
+	for (i = 0; i < count; i++) {
+		if (!rk808_reg_matches[i].init_data || !rk808_reg_matches[i].of_node)
+			continue;
+
+		pdata->rk808_init_data[i] = rk808_reg_matches[i].init_data;
+		pdata->of_node[i] = rk808_reg_matches[i].of_node;
 	}
+	pdata->irq = rk808->chip_irq;
+	pdata->irq_base = -1;
+	
+	pdata->irq_gpio = of_get_named_gpio(rk808_pmic_np,"gpios",0);
+		if (!gpio_is_valid(pdata->irq_gpio)) {
+			printk("invalid gpio: %d\n",  pdata->irq_gpio);
+			return NULL;
+		}
 
-	return 0;
-error:
-	while (--i >= 0)
-		regulator_unregister(rk808->rdev[i]);
-	kfree(rk808->rdev);
-	rk808->rdev = NULL;
-	return err;
+	if (of_get_property(rk808_pmic_np, "rockchip,pmic-dcdc-sleep-voltage", NULL))
+		pdata->pmic_sleep = true;
+
+	if (of_get_property(rk808_pmic_np, "rockchip,pmic-ldo-sleep-voltage", NULL))
+		pdata->pmic_sleep = true;
+	if (pdata->pmic_sleep){
+		pdata->pmic_sleep_gpio = of_get_named_gpio(rk808_pmic_np,"gpios",1);
+			if (!gpio_is_valid(pdata->pmic_sleep_gpio)) {
+				printk("invalid gpio: %d\n",  pdata->pmic_sleep_gpio);
+			}
+	}
+	if (of_property_read_u32_array(rk808_pmic_np,
+				"rockchip,pmic-dcdc-sleep-voltage",
+				pdata->dcdc_slp_voltage, 4)) {
+		printk("dcdc sleep voltages not specified\n");
+	}
+
+	if (of_property_read_u32_array(rk808_pmic_np,
+				"rockchip,pmic-ldo-sleep-voltage",
+				pdata->ldo_slp_voltage, 8)) {
+		printk("ldo sleep voltages not specified\n");
+	}
+	
+	return pdata;
+}
+static int rk808_dcdc_sleep_voltage_get_val(int min_uV,int buck)
+{
+	u16 vsel =0;
+	
+	if (buck == 0 || buck ==  1){
+		if (min_uV < 700000)
+		vsel = 0;
+		else if (min_uV <= 1500000)
+		vsel = ((min_uV - 700000) / 12500) ;
+		else
+		return -EINVAL;
+	}
+	else if (buck ==3){
+		if (min_uV < 1800000)
+		vsel = 0;
+		else if (min_uV <= 3300000)
+		vsel = ((min_uV - 1800000) / 100000) ;
+		else
+		return -EINVAL;
+	}
+	return vsel;
 }
+static int rk808_ldo_sleep_voltage_get_val(int min_uV,int ldo)
+{
+	const int *vol_map;
+	int min_vol = min_uV / 1000;
+	int num =0;
+	u16 val;
+	
+	if (ldo ==2){
+	vol_map = ldo3_voltage_map;	
+	num = 15;
+	}
+	else if (ldo == 5 || ldo ==6){
+	vol_map = ldo6_voltage_map;		
+	num = 17;
+	}
+	else {
+	vol_map = ldo_voltage_map;
+	num = 16;
+	}
+	
+	if (min_vol < vol_map[0] ||
+	    min_vol > vol_map[num])
+		return -EINVAL;
 
-extern void rk28_send_wakeup_key(void);
-static irqreturn_t rk808_vbat_lo_irq(int irq, void *data)
+	for (val = 0; val <= num; val++){
+		if (vol_map[val] >= min_vol)
+			break;	
+        }
+
+	return val;
+}
+#else
+static struct rk808_board *rk808_parse_dt(struct i2c_client *i2c)
 {
-        printk("rk808 vbat low %s:irq=%d\n",__func__,irq);
-	rk808_set_bits(g_rk808,0x4c,(0x1 << 1),(0x1 <<1));
-	rk28_send_wakeup_key();
-        return IRQ_HANDLED;
+	return NULL;
 }
+#endif
+
 
 int rk808_device_shutdown(void)
 {
@@ -998,21 +1124,48 @@ static int rk808_resume(struct i2c_client *i2c)
 }
 #endif
 
+static bool is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	if ((reg >= RK808_DCDC_EN_REG) && (reg <= RK808_LDO8_SLP_VSEL_REG)) {
+		return true;
+	}
+	return true;
+}
+
+static const struct regmap_config rk808_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_reg = is_volatile_reg,
+	.max_register = rk808_NUM_REGULATORS - 1,
+	.cache_type = REGCACHE_RBTREE,
+};
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
 __weak void rk808_early_suspend(struct early_suspend *h) {}
 __weak void rk808_late_resume(struct early_suspend *h) {}
 #endif
 
- 
-static int __devinit rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+static int rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
 {
 	struct rk808 *rk808;	
-	struct rk808_platform_data *pdata = i2c->dev.platform_data;
-	int ret;
+	struct rk808_board *pdev;
+	const struct of_device_id *match;
+	struct regulator_config config = { };
+	struct regulator_dev *rk808_rdev;
+	struct regulator_init_data *reg_data;
+	const char *rail_name = NULL;
+	int ret,vlow_irq,i=0;
 	
 	printk("%s,line=%d\n", __func__,__LINE__);
 
+	if (i2c->dev.of_node) {
+		match = of_match_device(rk808_of_match, &i2c->dev);
+		if (!match) {
+			dev_err(&i2c->dev,"Failed to find matching dt id\n");
+			return -EINVAL;
+		}
+	}
+
 	rk808 = kzalloc(sizeof(struct rk808), GFP_KERNEL);
 	if (rk808 == NULL) {
 		ret = -ENOMEM;		
@@ -1021,49 +1174,119 @@ static int __devinit rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_de
 	rk808->i2c = i2c;
 	rk808->dev = &i2c->dev;
 	i2c_set_clientdata(i2c, rk808);
-	rk808->read = rk808_i2c_read;
-	rk808->write = rk808_i2c_write;
-	mutex_init(&rk808->io_lock);	
+//	rk808->read = rk808_i2c_read;
+//	rk808->write = rk808_i2c_write;
 
-	ret = mfd_add_devices(rk808->dev, -1,
-			      rk808s, ARRAY_SIZE(rk808s),
-			      NULL, 0);
-	if (ret < 0)
-		goto err;
+	rk808->regmap = devm_regmap_init_i2c(i2c, &rk808_regmap_config);
+	if (IS_ERR(rk808->regmap)) {
+		printk("regmap initialization failed\n");
+		return ret;
+	}
+	
+	mutex_init(&rk808->io_lock);	
 
-     
 	ret = rk808_reg_read(rk808,0x2f);
 	if ((ret < 0) || (ret == 0xff)){
-		printk("The device is not rk808\n");
+		printk("The device is not rk808 %d\n",ret);
 		return 0;
 	}
+	rk808_set_bits(rk808,0x21,(1<<4),(1 <<4));
+	rk808_set_bits(rk808,0x21,(7<<0),(7 <<0));
 
+	if (ret < 0)
+		goto err;
 
-	if (pdata) {
-		ret = setup_regulators(rk808, pdata);
-		if (ret < 0)		
-			goto err;
-	} else
-		dev_warn(rk808->dev, "No platform init data supplied\n");
+	if (rk808->dev->of_node)
+		pdev = rk808_parse_dt(rk808);
+	
+	/******************************set sleep vol & dcdc mode******************/
+	#ifdef CONFIG_OF
+	rk808->pmic_sleep_gpio = pdev->pmic_sleep_gpio;
+	if (rk808->pmic_sleep_gpio) {
+			ret = gpio_request(rk808->pmic_sleep_gpio, "rk808_pmic_sleep");
+			if (ret < 0) {
+				dev_err(rk808->dev,"Failed to request gpio %d with ret:""%d\n",	rk808->pmic_sleep_gpio, ret);
+				return IRQ_NONE;
+			}
+			gpio_direction_input(rk808->pmic_sleep_gpio);
+			ret = gpio_get_value(rk808->pmic_sleep_gpio);
+			gpio_free(rk808->pmic_sleep_gpio);
+			pr_info("%s: rk808_pmic_sleep=%x\n", __func__, ret);
+	}
+	for (i = 0;i <4 ; i ++){
+	rk808->dcdc_slp_voltage[i] = pdev->dcdc_slp_voltage[i];
+	if (rk808->dcdc_slp_voltage[i]){
+		if (i ==2)
+			continue;	
+		ret = rk808_set_bits(rk808, (rk808_BUCK_SET_VOL_REG(i) + 0x01), BUCK_VOL_MASK, rk808_dcdc_sleep_voltage_get_val(rk808->dcdc_slp_voltage[i],i));
+		}
+	}
+	for (i = 0;i <8 ; i ++){
+	rk808->ldo_slp_voltage[i] = pdev->ldo_slp_voltage[i];
+	if (rk808->ldo_slp_voltage[i] ==0)
+		ret = rk808_set_bits(rk808, RK808_LDO_EN_REG, 1 << i, 0);
+	ret = rk808_set_bits(rk808, (rk808_LDO_SET_VOL_REG(i) + 0x01), LDO_VOL_MASK, rk808_ldo_sleep_voltage_get_val(rk808->ldo_slp_voltage[i],i));
+	}	
+	#endif
+	/**********************************************************/
+	
+	if (pdev) {
+		rk808->num_regulators = rk808_NUM_REGULATORS;
+		rk808->rdev = kcalloc(rk808_NUM_REGULATORS,sizeof(struct regulator_dev *), GFP_KERNEL);
+		if (!rk808->rdev) {
+			return -ENOMEM;
+		}
+		/* Instantiate the regulators */
+		for (i = 0; i < rk808_NUM_REGULATORS; i++) {
+		reg_data = pdev->rk808_init_data[i];
+		if (!reg_data)
+			continue;
+		config.dev = rk808->dev;
+		config.driver_data = rk808;
+		config.regmap = rk808->regmap;
+		if (rk808->dev->of_node)
+			config.of_node = pdev->of_node[i];
+		if (reg_data && reg_data->constraints.name)
+				rail_name = reg_data->constraints.name;
+			else
+				rail_name = regulators[i].name;
+			reg_data->supply_regulator = rail_name;
+	
+		config.init_data =reg_data;
 
-	pdata->pre_init(rk808);
+		rk808_rdev = regulator_register(&regulators[i],&config);
+		if (IS_ERR(rk808_rdev)) {
+			printk("failed to register %d regulator\n",i);
+		goto err;
+		}
+		rk808->rdev[i] = rk808_rdev;
+		}
+	}
 
-	ret = rk808_irq_init(rk808, pdata->irq, pdata);
+//	rk808->wakeup = pdev->wakeup;
+	rk808->irq_gpio = pdev->irq_gpio;
+	ret = rk808_irq_init(rk808, rk808->irq_gpio, pdev);
 	if (ret < 0)
 		goto err;
+
+	ret = mfd_add_devices(rk808->dev, -1,
+			      rk808s, ARRAY_SIZE(rk808s),
+			      NULL, 0,NULL);
+		
 	/********************vbat low int**************/
-	 ret = request_threaded_irq(rk808->irq_base + RK808_IRQ_VB_LO, NULL, rk808_vbat_lo_irq,
+	vlow_irq = irq_create_mapping(rk808->irq_domain, RK808_IRQ_VB_LO);
+	 ret = request_threaded_irq(vlow_irq, NULL, rk808_vbat_lo_irq,
                                    IRQF_TRIGGER_RISING, "rk808_vbatlow",
                                    rk808);
         if (ret != 0) {
                 dev_err(rk808->dev, "Failed to request periodic IRQ %d: %d\n",
-                        rk808->irq_base + RK808_IRQ_VB_LO, ret);
+                        vlow_irq+ RK808_IRQ_VB_LO, ret);
 
         }
 
 	/*********************************************/
+	
 	g_rk808 = rk808;
-	pdata->set_init(rk808);
 
 	#ifdef CONFIG_HAS_EARLYSUSPEND
 	rk808->rk808_suspend.suspend = rk808_early_suspend,
@@ -1073,7 +1296,6 @@ static int __devinit rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_de
 	#endif
 
 	#if 1
-	int i =0;
 	rk808_kobj = kobject_create_and_add("rk808", NULL);
 	if (!rk808_kobj)
 		return -ENOMEM;
@@ -1093,7 +1315,7 @@ err:
 
 }
 
-static int __devexit rk808_i2c_remove(struct i2c_client *i2c)
+static int rk808_i2c_remove(struct i2c_client *i2c)
 {
 	struct rk808 *rk808 = i2c_get_clientdata(i2c);
 	int i;
@@ -1119,9 +1341,10 @@ static struct i2c_driver rk808_i2c_driver = {
 	.driver = {
 		.name = "rk808",
 		.owner = THIS_MODULE,
+		.of_match_table =of_match_ptr(rk808_of_match),
 	},
 	.probe    = rk808_i2c_probe,
-	.remove   = __devexit_p(rk808_i2c_remove),
+	.remove   = rk808_i2c_remove,
 	.id_table = rk808_i2c_id,
 	#ifdef CONFIG_PM
 	.suspend	= rk808_suspend,
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 8bb26446037e..3d074b03a8fb 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -250,6 +250,18 @@ config REGULATOR_MAX77686
 	  via I2C bus. The provided regulator is suitable for
 	  Exynos-4 chips to control VARM and VINT voltages.
 
+config REGULATOR_ACT8846
+	tristate "Active Semi ACT8846 PMIC regulators"
+	depends on I2C
+	help
+	  Support the voltage and current regulators of the ACT8846 series of PMIC devices.
+
+config ACT8846_SUPPORT_RESET
+	tristate "ACT8846 PMIC SUPPORT RESET"
+	depends on REGULATOR_ACT8846=y
+	help
+	  Support short press key to restart.
+
 config REGULATOR_PCAP
 	tristate "Motorola PCAP2 regulator driver"
 	depends on EZX_PCAP
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 47a34ff88f98..dafe1c4cdc0e 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
+obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o
 
 
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/act8846.c b/drivers/regulator/act8846.c
index 6b8aa666ea95..be07922ce36c 100755
--- a/drivers/regulator/act8846.c
+++ b/drivers/regulator/act8846.c
@@ -17,14 +17,22 @@
 #include <linux/kernel.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/act8846.h>
-#include <mach/gpio.h>
 #include <linux/delay.h>
-#include <mach/iomux.h>
 #include <linux/slab.h>
+#include <linux/mutex.h>
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
 #endif
-
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regmap.h>
 
 #if 0
 #define DBG(x...)	printk(KERN_INFO x)
@@ -44,9 +52,22 @@ struct act8846 {
 	struct i2c_client *i2c;
 	int num_regulators;
 	struct regulator_dev **rdev;
-	struct early_suspend act8846_suspend;
+//	struct early_suspend act8846_suspend;
+	int irq_base;
+	int chip_irq;
+	int pmic_sleep_gpio; /* */
+	unsigned int dcdc_slp_voltage[3]; /* buckx_voltage in uV */
+	bool pmic_sleep;
+	struct regmap *regmap;
+};
+
+struct act8846_regulator {
+	struct device		*dev;
+	struct regulator_desc	*desc;
+	struct regulator_dev	*rdev;
 };
 
+
 struct act8846 *g_act8846;
 
 static u8 act8846_reg_read(struct act8846 *act8846, u8 reg);
@@ -142,7 +163,7 @@ const static int buck_voltage_map[] = {
 	 1500, 1550, 1600, 1650, 1700, 1750, 1800, 
 	 1850, 1900, 1950, 2000, 2050, 2100, 2150, 
 	 2200, 2250, 2300, 2350, 2400, 2500, 2600, 
-	 2700, 2800, 2850, 2900, 3000, 3100, 3200,
+	 2700, 2800, 2900, 3000, 3100, 3200,
 	 3300, 3400, 3500, 3600, 3700, 3800, 3900,
 };
 
@@ -154,7 +175,7 @@ const static int ldo_voltage_map[] = {
 	 1500, 1550, 1600, 1650, 1700, 1750, 1800, 
 	 1850, 1900, 1950, 2000, 2050, 2100, 2150, 
 	 2200, 2250, 2300, 2350, 2400, 2500, 2600, 
-	 2700, 2800, 2850, 2900, 3000, 3100, 3200,
+	 2700, 2800, 2900, 3000, 3100, 3200,
 	 3300, 3400, 3500, 3600, 3700, 3800, 3900,
 };
 
@@ -184,7 +205,7 @@ static int act8846_ldo_enable(struct regulator_dev *dev)
 	struct act8846 *act8846 = rdev_get_drvdata(dev);
 	int ldo= rdev_get_id(dev) - ACT8846_LDO1;
 	u16 mask=0x80;	
-	
+
 	return act8846_set_bits(act8846, act8846_LDO_CONTR_REG(ldo), mask, 0x80);
 	
 }
@@ -217,6 +238,7 @@ static int act8846_ldo_set_voltage(struct regulator_dev *dev,
 	const int *vol_map =ldo_voltage_map;
 	u16 val;
 	int ret = 0;
+
 	if (min_vol < vol_map[VOL_MIN_IDX] ||
 	    min_vol > vol_map[VOL_MAX_IDX])
 		return -EINVAL;
@@ -307,6 +329,7 @@ static int act8846_dcdc_enable(struct regulator_dev *dev)
 	struct act8846 *act8846 = rdev_get_drvdata(dev);
 	int buck = rdev_get_id(dev) - ACT8846_DCDC1;
 	u16 mask=0x80;	
+	
 	return act8846_set_bits(act8846, act8846_BUCK_CONTR_REG(buck), mask, 0x80);
 
 }
@@ -329,9 +352,7 @@ static int act8846_dcdc_get_voltage(struct regulator_dev *dev)
 	reg = act8846_reg_read(act8846,act8846_BUCK_SET_VOL_REG(buck));
 	#endif
 	reg &= BUCK_VOL_MASK;
-        DBG("%d\n", reg);
 	val = 1000 * buck_voltage_map[reg];	
-        DBG("%d\n", val);
 	return val;
 }
 static int act8846_dcdc_set_voltage(struct regulator_dev *dev,
@@ -344,7 +365,6 @@ static int act8846_dcdc_set_voltage(struct regulator_dev *dev,
 	u16 val;
 	int ret = 0;
 
-        DBG("%s, min_uV = %d, max_uV = %d!\n", __func__, min_uV, max_uV);
 	if (min_vol < vol_map[VOL_MIN_IDX] ||
 	    min_vol > vol_map[VOL_MAX_IDX])
 		return -EINVAL;
@@ -375,7 +395,6 @@ static int act8846_dcdc_set_sleep_voltage(struct regulator_dev *dev,
 	u16 val;
 	int ret = 0;
 
-        DBG("%s, min_uV = %d, max_uV = %d!\n", __func__, min_uV, max_uV);
 	if (min_vol < vol_map[VOL_MIN_IDX] ||
 	    min_vol > vol_map[VOL_MAX_IDX])
 		return -EINVAL;
@@ -417,6 +436,7 @@ static int act8846_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
 	struct act8846 *act8846 = rdev_get_drvdata(dev);
 	int buck = rdev_get_id(dev) - ACT8846_DCDC1;
 	u16 mask = 0x80;
+
 	switch(mode)
 	{
 	case REGULATOR_MODE_STANDBY:
@@ -462,7 +482,7 @@ static struct regulator_ops act8846_dcdc_ops = {
 static struct regulator_desc regulators[] = {
 
         {
-		.name = "DCDC1",
+		.name = "ACT_DCDC1",
 		.id = 0,
 		.ops = &act8846_dcdc_ops,
 		.n_voltages = ARRAY_SIZE(buck_voltage_map),
@@ -470,7 +490,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "DCDC2",
+		.name = "ACT_DCDC2",
 		.id = 1,
 		.ops = &act8846_dcdc_ops,
 		.n_voltages = ARRAY_SIZE(buck_voltage_map),
@@ -478,7 +498,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "DCDC3",
+		.name = "ACT_DCDC3",
 		.id = 2,
 		.ops = &act8846_dcdc_ops,
 		.n_voltages = ARRAY_SIZE(buck_voltage_map),
@@ -486,7 +506,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "DCDC4",
+		.name = "ACT_DCDC4",
 		.id = 3,
 		.ops = &act8846_dcdc_ops,
 		.n_voltages = ARRAY_SIZE(buck_voltage_map),
@@ -495,7 +515,7 @@ static struct regulator_desc regulators[] = {
 	},
 
 	{
-		.name = "LDO1",
+		.name = "ACT_LDO1",
 		.id =4,
 		.ops = &act8846_ldo_ops,
 		.n_voltages = ARRAY_SIZE(ldo_voltage_map),
@@ -503,7 +523,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "LDO2",
+		.name = "ACT_LDO2",
 		.id = 5,
 		.ops = &act8846_ldo_ops,
 		.n_voltages = ARRAY_SIZE(ldo_voltage_map),
@@ -511,7 +531,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "LDO3",
+		.name = "ACT_LDO3",
 		.id = 6,
 		.ops = &act8846_ldo_ops,
 		.n_voltages = ARRAY_SIZE(ldo_voltage_map),
@@ -519,7 +539,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "LDO4",
+		.name = "ACT_LDO4",
 		.id = 7,
 		.ops = &act8846_ldo_ops,
 		.n_voltages = ARRAY_SIZE(ldo_voltage_map),
@@ -528,7 +548,7 @@ static struct regulator_desc regulators[] = {
 	},
 
 	{
-		.name = "LDO5",
+		.name = "ACT_LDO5",
 		.id =8,
 		.ops = &act8846_ldo_ops,
 		.n_voltages = ARRAY_SIZE(ldo_voltage_map),
@@ -536,7 +556,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "LDO6",
+		.name = "ACT_LDO6",
 		.id = 9,
 		.ops = &act8846_ldo_ops,
 		.n_voltages = ARRAY_SIZE(ldo_voltage_map),
@@ -544,7 +564,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "LDO7",
+		.name = "ACT_LDO7",
 		.id = 10,
 		.ops = &act8846_ldo_ops,
 		.n_voltages = ARRAY_SIZE(ldo_voltage_map),
@@ -552,7 +572,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "LDO8",
+		.name = "ACT_LDO8",
 		.id = 11,
 		.ops = &act8846_ldo_ops,
 		.n_voltages = ARRAY_SIZE(ldo_voltage_map),
@@ -560,7 +580,7 @@ static struct regulator_desc regulators[] = {
 		.owner = THIS_MODULE,
 	},
 	{
-		.name = "LDO9",
+		.name = "ACT_LDO9",
 		.id = 12,
 		.ops = &act8846_ldo_ops,
 		.n_voltages = ARRAY_SIZE(ldo_voltage_map),
@@ -666,38 +686,127 @@ static int act8846_set_bits(struct act8846 *act8846, u8 reg, u16 mask, u16 val)
 
 	return 0;//ret;	
 }
-static int __devinit setup_regulators(struct act8846 *act8846, struct act8846_platform_data *pdata)
-{	
-	int i, err;
 
-	act8846->num_regulators = pdata->num_regulators;
-	act8846->rdev = kcalloc(pdata->num_regulators,
-			       sizeof(struct regulator_dev *), GFP_KERNEL);
-	if (!act8846->rdev) {
-		return -ENOMEM;
+#ifdef CONFIG_OF
+static struct of_device_id act8846_of_match[] = {
+	{ .compatible = "act,act8846"},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, act8846_of_match);
+#endif
+#ifdef CONFIG_OF
+static struct of_regulator_match act8846_reg_matches[] = {
+	{ .name = "act_dcdc1" ,.driver_data = (void *)0},
+	{ .name = "act_dcdc2" ,.driver_data = (void *)1},
+	{ .name = "act_dcdc3", .driver_data = (void *)2 },
+	{ .name = "act_dcdc4", .driver_data = (void *)3 },
+	{ .name = "act_ldo1", .driver_data = (void *)4 },
+	{ .name = "act_ldo2", .driver_data = (void *)5 },
+	{ .name = "act_ldo3", .driver_data = (void *)6 },
+	{ .name = "act_ldo4", .driver_data = (void *)7 },
+	{ .name = "act_ldo5", .driver_data = (void *)8 },
+	{ .name = "act_ldo6", .driver_data = (void *)9 },
+	{ .name = "act_ldo7", .driver_data = (void *)10 },
+	{ .name = "act_ldo8", .driver_data = (void *)11 },
+};
+
+static struct act8846_board *act8846_parse_dt(struct act8846 *act8846)
+{
+//	struct act8846 *act8846 = i2c->dev.parent;
+	struct act8846_board *pdata;
+	struct device_node *regs;
+	struct device_node *act8846_pmic_np;
+	int i, count,sleep_voltage_nr =1;
+	int gpio;
+	printk("%s,line=%d\n", __func__,__LINE__);	
+	
+	act8846_pmic_np = of_node_get(act8846->dev->of_node);
+	if (!act8846_pmic_np) {
+		printk("could not find pmic sub-node\n");
+		return NULL;
 	}
-	/* Instantiate the regulators */
-	for (i = 0; i < pdata->num_regulators; i++) {
-		int id = pdata->regulators[i].id;
-		act8846->rdev[i] = regulator_register(&regulators[id],
-			act8846->dev, pdata->regulators[i].initdata, act8846);
-/*
-		if (IS_ERR(act8846->rdev[i])) {
-			err = PTR_ERR(act8846->rdev[i]);
-			dev_err(act8846->dev, "regulator init failed: %d\n",
-				err);
-			goto error;
-		}*/
+	
+	regs = of_find_node_by_name(act8846_pmic_np, "regulators");
+	if (!regs)
+		return NULL;
+	
+	count = of_regulator_match(act8846->dev, regs, act8846_reg_matches,act8846_NUM_REGULATORS);
+	of_node_put(regs);
+
+	if ((count < 0) || (count > act8846_NUM_REGULATORS))
+		return NULL;
+
+	pdata = devm_kzalloc(act8846->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+	for (i = 0; i < count; i++) {
+		if (!act8846_reg_matches[i].init_data || !act8846_reg_matches[i].of_node)
+			continue;
+		pdata->act8846_init_data[i] = act8846_reg_matches[i].init_data;
+		pdata->of_node[i] = act8846_reg_matches[i].of_node;
 	}
+	pdata->irq = act8846->chip_irq;
+	pdata->irq_base = -1;
 
-	return 0;
-error:
-	while (--i >= 0)
-		regulator_unregister(act8846->rdev[i]);
-	kfree(act8846->rdev);
-	act8846->rdev = NULL;
-	return err;
+	if (of_get_property(act8846_pmic_np, "act,pmic-dcdc-sleep-voltage", NULL))
+		pdata->pmic_sleep = true;
+
+	if (of_get_property(act8846_pmic_np, "act,pmic-ldo-sleep-voltage", NULL))
+		pdata->pmic_sleep = true;
+
+	gpio = of_get_named_gpio(act8846_pmic_np,"gpios", 0);
+		if (!gpio_is_valid(gpio)) 
+			printk("invalid gpio: %d\n",gpio);
+	pdata->pmic_sleep_gpio = gpio;
+	
+	if (of_property_read_u32_array(act8846_pmic_np,
+				"act,pmic-dcdc-sleep-voltage",
+				pdata->dcdc_slp_voltage, sleep_voltage_nr)) {
+		printk("dcdc sleep voltages not specified\n");
+	}
	
+
+	return pdata;
 }
+static int act8846_dcdc_sleep_voltage_get_val(int min_uV,int buck)
+{
+	int min_vol = min_uV / 1000, max_vol = min_uV / 1000;
+	const int *vol_map = buck_voltage_map;
+	u16 val;
+
+	if (min_vol < vol_map[VOL_MIN_IDX] ||
+	    min_vol > vol_map[VOL_MAX_IDX])
+		return -EINVAL;
+
+	for (val = VOL_MIN_IDX; val <= VOL_MAX_IDX; val++){
+		if (vol_map[val] >= min_vol)
+			break;
+        }
+
+	if (vol_map[val] > max_vol)
+		printk("WARNING:this voltage is not support!voltage set is %d mv\n",vol_map[val]);
+	return val;
+}
+static int act8846_dts_dcdc_set_mode(unsigned int mode,int buck)
+{
+	struct act8846 *act8846 = g_act8846;
+	u16 mask = 0x80;
+	switch(mode)
+	{
+	case REGULATOR_MODE_STANDBY:
+		return act8846_set_bits(act8846, act8846_BUCK_CONTR_REG(buck), mask, 0);
+	case REGULATOR_MODE_NORMAL:
+		return act8846_set_bits(act8846, act8846_BUCK_CONTR_REG(buck), mask, mask);
+	default:
+		printk("error:pmu_act8846 only powersave and pwm mode\n");
+		return -EINVAL;
+	}
+}
+#else
+static struct act8846_board *act8846_parse_dt(struct i2c_client *i2c)
+{
+	return NULL;
+}
+#endif
 
 
 int act8846_device_shutdown(void)
@@ -751,11 +860,43 @@ __weak void act8846_early_suspend(struct early_suspend *h) {}
 __weak void act8846_late_resume(struct early_suspend *h) {}
 #endif
 
-static int __devinit act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+static bool is_volatile_reg(struct device *dev, unsigned int reg)
+{
+
+	if ((reg >= act8846_BUCK1_SET_VOL_BASE) && (reg <= act8846_LDO8_CONTR_BASE)) {
+		return true;
+	}
+	return true;
+}
+
+static const struct regmap_config act8846_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_reg = is_volatile_reg,
+	.max_register = act8846_NUM_REGULATORS - 1,
+	.cache_type = REGCACHE_RBTREE,
+};
+static int act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
 {
 	struct act8846 *act8846;	
-	struct act8846_platform_data *pdata = i2c->dev.platform_data;
-	int ret;
+	struct act8846_board *pdev ;
+	const struct of_device_id *match;
+	struct regulator_config config = { };
+	struct regulator_dev *act_rdev;
+	struct regulator_init_data *reg_data;
+	const char *rail_name = NULL;
+	int ret,i=0;
+	
+	printk("%s,line=%d\n", __func__,__LINE__);	
+
+	if (i2c->dev.of_node) {
+		match = of_match_device(act8846_of_match, &i2c->dev);
+		if (!match) {
+			printk("Failed to find matching dt id\n");
+			return -EINVAL;
+		}
+	}
+
 	act8846 = kzalloc(sizeof(struct act8846), GFP_KERNEL);
 	if (act8846 == NULL) {
 		ret = -ENOMEM;		
@@ -764,11 +905,20 @@ static int __devinit act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_
 	act8846->i2c = i2c;
 	act8846->dev = &i2c->dev;
 	i2c_set_clientdata(i2c, act8846);
+	g_act8846 = act8846;
+	
+	act8846->regmap = devm_regmap_init_i2c(i2c, &act8846_regmap_config);
+	if (IS_ERR(act8846->regmap)) {
+		ret = PTR_ERR(act8846->regmap);
+		printk("regmap initialization failed: %d\n", ret);
+		return ret;
+	}
+	
 	mutex_init(&act8846->io_lock);	
 
 	ret = act8846_reg_read(act8846,0x22);
 	if ((ret < 0) || (ret == 0xff)){
-		printk("The device is not act8846 \n");
+		printk("The device is not act8846 %x \n",ret);
 		return 0;
 	}
 
@@ -777,24 +927,80 @@ static int __devinit act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_
 		printk("act8846 set 0xf4 error!\n");
 		goto err;
 	}
-	
-	if (pdata) {
-		ret = setup_regulators(act8846, pdata);
-		if (ret < 0)		
-			goto err;
-	} else
-		dev_warn(act8846->dev, "No platform init data supplied\n");
-
-	g_act8846 = act8846;
-	pdata->set_init(act8846);
 
+	if (act8846->dev->of_node)
+		pdev = act8846_parse_dt(act8846);
+	
+	/******************************set sleep vol & dcdc mode******************/
+	#ifdef CONFIG_OF
+	act8846->pmic_sleep_gpio = pdev->pmic_sleep_gpio;
+	if (act8846->pmic_sleep_gpio) {
+			ret = gpio_request(act8846->pmic_sleep_gpio, "act8846_pmic_sleep");
+			if (ret < 0) {
+				dev_err(act8846->dev,"Failed to request gpio %d with ret:""%d\n",	act8846->pmic_sleep_gpio, ret);
+				return IRQ_NONE;
+			}
+			gpio_direction_input(act8846->pmic_sleep_gpio);
+			ret = gpio_get_value(act8846->pmic_sleep_gpio);
+			gpio_free(act8846->pmic_sleep_gpio);
+			printk("%s: act8846_pmic_sleep=%x\n", __func__, ret);
+	}
+	for (i = 0;i <4 ; i ++){
+	act8846->dcdc_slp_voltage[i] = pdev->dcdc_slp_voltage[i];
+		if (act8846->dcdc_slp_voltage[i]){
+			if (i ==0)
+				continue;
+
+			#ifdef CONFIG_ACT8846_SUPPORT_RESET
+			ret = act8846_set_bits(act8846, act8846_BUCK_SET_VOL_REG(i) ,BUCK_VOL_MASK, act8846_dcdc_sleep_voltage_get_val(act8846->dcdc_slp_voltage[i],i));
+			#else
+			ret = act8846_set_bits(act8846, (act8846_BUCK_SET_VOL_REG(i) +0x01),BUCK_VOL_MASK, act8846_dcdc_sleep_voltage_get_val(act8846->dcdc_slp_voltage[i],i));
+			#endif
+		}
+	}
+	#endif
+	
+	if (pdev) {
+		act8846->num_regulators = act8846_NUM_REGULATORS;
+		act8846->rdev = kcalloc(act8846_NUM_REGULATORS,sizeof(struct regulator_dev *), GFP_KERNEL);
+		if (!act8846->rdev) {
+			return -ENOMEM;
+		}
+		/* Instantiate the regulators */
+		for (i = 0; i < act8846_NUM_REGULATORS; i++) {
+		reg_data = pdev->act8846_init_data[i];
+		if (!reg_data)
+			continue;
+		config.dev = act8846->dev;
+		config.driver_data = act8846;
+		config.regmap = act8846->regmap;
+		if (act8846->dev->of_node)
+			config.of_node = pdev->of_node[i];
+
+			if (reg_data && reg_data->constraints.name)
+				rail_name = reg_data->constraints.name;
+			else
+				rail_name = regulators[i].name;
+			reg_data->supply_regulator = rail_name;
+	
+		config.init_data =reg_data;
+		
+		act_rdev = regulator_register(&regulators[i],&config);
+		if (IS_ERR(act_rdev)) {
+			printk("failed to register %d regulator\n",i);
+		goto err;
+		}
+		act8846->rdev[i] = act_rdev;
+		}
+	}
+	
 	#ifdef CONFIG_HAS_EARLYSUSPEND
 	act8846->act8846_suspend.suspend = act8846_early_suspend,
 	act8846->act8846_suspend.resume = act8846_late_resume,
 	act8846->act8846_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1,
 	register_early_suspend(&act8846->act8846_suspend);
-	#endif
-	
+	#endif	
+
 	return 0;
 
 err:
@@ -802,7 +1008,7 @@ err:
 
 }
 
-static int __devexit act8846_i2c_remove(struct i2c_client *i2c)
+static int  act8846_i2c_remove(struct i2c_client *i2c)
 {
 	struct act8846 *act8846 = i2c_get_clientdata(i2c);
 	int i;
@@ -828,9 +1034,10 @@ static struct i2c_driver act8846_i2c_driver = {
 	.driver = {
 		.name = "act8846",
 		.owner = THIS_MODULE,
+		.of_match_table =of_match_ptr(act8846_of_match),
 	},
 	.probe    = act8846_i2c_probe,
-	.remove   = __devexit_p(act8846_i2c_remove),
+	.remove   = act8846_i2c_remove,
 	.id_table = act8846_i2c_id,
 	#ifdef CONFIG_PM
 	.suspend	= act8846_suspend,
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index b9838130a7b0..33d86af2a60d 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -414,6 +414,12 @@ config RTC_DRV_TPS65910
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-tps65910.
 
+config  RK808_RTC
+	tristate "rk808 rtc for rk"
+	depends on MFD_RK808
+	help
+		enable rk808 rtc for system
+
 config RTC_DRV_TPS80031
 	tristate "TI TPS80031/TPS80032 RTC driver"
 	depends on MFD_TPS80031
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index c33f86f1a69b..d90aa263eec0 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -126,5 +126,6 @@ obj-$(CONFIG_RTC_DRV_V3020)	+= rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)	+= rtc-vr41xx.o
 obj-$(CONFIG_RTC_DRV_VT8500)	+= rtc-vt8500.o
 obj-$(CONFIG_RTC_DRV_WM831X)	+= rtc-wm831x.o
+obj-$(CONFIG_RK808_RTC)  += rtc-rk808.o
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index adaec3302db5..b79fed58a9c5 100755
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/miscdevice.h>
+#include <linux/irqdomain.h>
 
 
 /* RTC Definitions */
@@ -76,7 +77,6 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 	struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
 	struct rk808 *rk808 = rk808_rtc->rk808;
 	int ret;
-	int count = 0;
 	unsigned char rtc_data[ALL_TIME_REGS + 1];
 	u8 rtc_ctl;
 
@@ -514,12 +514,23 @@ static int rk808_rtc_freeze(struct device *dev)
 #define rk808_rtc_resume NULL
 #define rk808_rtc_freeze NULL
 #endif
-
+extern struct rk808 *g_rk808;
 struct platform_device *rk808_pdev;
+struct rtc_time tm_def = {	//	2012.1.1 12:00:00 Saturday
+			.tm_wday = 6,
+			.tm_year = 112,
+			.tm_mon = 0,
+			.tm_mday = 1,
+			.tm_hour = 12,
+			.tm_min = 0,
+			.tm_sec = 0,
+};
+	
 static int rk808_rtc_probe(struct platform_device *pdev)
 {
 	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
 	struct rk808_rtc *rk808_rtc;
+	struct rtc_time tm;
 	int per_irq;
 	int alm_irq;
 	int ret = 0;
@@ -527,26 +538,12 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 
 	printk("%s,line=%d\n", __func__,__LINE__);
 
-	
-	struct rtc_time tm;
-	struct rtc_time tm_def = {	//	2012.1.1 12:00:00 Saturday
-			.tm_wday = 6,
-			.tm_year = 112,
-			.tm_mon = 0,
-			.tm_mday = 1,
-			.tm_hour = 12,
-			.tm_min = 0,
-			.tm_sec = 0,
-		};
-	
 	rk808_rtc = kzalloc(sizeof(*rk808_rtc), GFP_KERNEL);
 	if (rk808_rtc == NULL)
 		return -ENOMEM;
 
 	platform_set_drvdata(pdev, rk808_rtc);
 	rk808_rtc->rk808 = rk808;
-	per_irq = rk808->irq_base + RK808_IRQ_RTC_PERIOD;
-	alm_irq = rk808->irq_base + RK808_IRQ_RTC_ALARM;
 	
 	/* Take rtc out of reset */
 	/*
@@ -611,9 +608,12 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 		ret = PTR_ERR(rk808_rtc->rtc);
 		goto err;
 	}
+	
+	per_irq = irq_create_mapping(rk808->irq_domain, RK808_IRQ_RTC_PERIOD);
+	alm_irq = irq_create_mapping(rk808->irq_domain, RK808_IRQ_RTC_ALARM);	
 
 	/*request rtc and alarm irq of rk808*/
-	ret = request_threaded_irq(per_irq, NULL, rk808_per_irq,
+	ret = devm_request_threaded_irq(rk808->dev,per_irq, NULL, rk808_per_irq,
 				   IRQF_TRIGGER_RISING, "RTC period",
 				   rk808_rtc);
 	if (ret != 0) {
@@ -621,7 +621,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 			per_irq, ret);
 	}
 
-	ret = request_threaded_irq(alm_irq, NULL, rk808_alm_irq,
+	ret = devm_request_threaded_irq(rk808->dev,alm_irq, NULL, rk808_alm_irq,
 				   IRQF_TRIGGER_RISING, "RTC alarm",
 				   rk808_rtc);
 	if (ret != 0) {
@@ -637,7 +637,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 	rk808_set_bits(rk808_rtc->rk808, RK808_INT_STS_MSK_REG1,(0x3 <<5),0);
 */
 
-	enable_irq_wake(alm_irq); // so rk808 alarm irq can wake up system
+//	enable_irq_wake(alm_irq); // so rk808 alarm irq can wake up system
 	rk808_pdev = pdev;
 	
 	printk("%s:ok\n",__func__);
@@ -649,7 +649,7 @@ err:
 	return ret;
 }
 
-static int __devexit rk808_rtc_remove(struct platform_device *pdev)
+static int rk808_rtc_remove(struct platform_device *pdev)
 {
 	struct rk808_rtc *rk808_rtc = platform_get_drvdata(pdev);
 	int per_irq = rk808_rtc->rk808->irq_base + RK808_IRQ_RTC_PERIOD;
@@ -676,7 +676,7 @@ static const struct dev_pm_ops rk808_rtc_pm_ops = {
 
 static struct platform_driver rk808_rtc_driver = {
 	.probe = rk808_rtc_probe,
-	.remove = __devexit_p(rk808_rtc_remove),
+	.remove = rk808_rtc_remove,
 	.driver = {
 		.name = "rk808-rtc",
 		.pm = &rk808_rtc_pm_ops,
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 7ede72c9e456..66bfbc240404 100755
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -15,8 +15,10 @@
 
 #include <linux/regulator/machine.h>
 #include <linux/wakelock.h>
+#include <linux/regmap.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
-
+#endif
 //#define RK808_START 30
 
 #define RK808_DCDC1  0                     //(0+RK808_START) 
@@ -105,6 +107,19 @@
 #define rk808_NUM_REGULATORS 12
 struct rk808;
 
+struct rk808_board {
+	int irq;
+	int irq_base;
+	int irq_gpio;
+	int wakeup;
+	struct regulator_init_data *rk808_init_data[rk808_NUM_REGULATORS];
+	struct device_node *of_node[rk808_NUM_REGULATORS];
+	int pmic_sleep_gpio; /* */
+	unsigned int dcdc_slp_voltage[3]; /* buckx_voltage in uV */
+	bool pmic_sleep;
+	unsigned int ldo_slp_voltage[7];
+};
+
 struct rk808_regulator_subdev {
 	int id;
 	struct regulator_init_data *initdata;
@@ -117,14 +132,22 @@ struct rk808 {
 	int num_regulators;
 	struct regulator_dev **rdev;
 	struct wake_lock 	irq_wake;
-	struct early_suspend rk808_suspend;
+//	struct early_suspend rk808_suspend;
 	struct mutex irq_lock;
 	int irq_base;
 	int irq_num;
 	int chip_irq;
+	int irq_gpio;
+	int wakeup;
 	u32 irq_mask;
+	struct regmap *regmap;
+	struct irq_domain *irq_domain;
 	int (*read)(struct rk808 *rk808, u8 reg, int size, void *dest);
 	int (*write)(struct rk808 *rk808, u8 reg, int size, void *src);
+	int pmic_sleep_gpio; /* */
+	unsigned int dcdc_slp_voltage[3]; /* buckx_voltage in uV */
+	bool pmic_sleep;
+	unsigned int ldo_slp_voltage[7];
 };
 
 struct rk808_platform_data {
@@ -134,9 +157,10 @@ struct rk808_platform_data {
 	struct rk808_regulator_subdev *regulators;
 	int irq;
 	int irq_base;
+	struct irq_domain *irq_domain;
 };
 
-int rk808_irq_init(struct rk808 *rk808, int irq,struct rk808_platform_data *pdata);
+int rk808_irq_init(struct rk808 *rk808, int irq,struct rk808_board *pdata);
  int rk808_i2c_read(struct rk808 *rk808, char reg, int count,u8 *dest);
 //int rk808_i2c_read(struct i2c_client *i2c, char reg, int count,u16 *dest);
 // int rk808_i2c_read(struct rk808 *rk808 , u8 reg, int bytes,void *dest); 
diff --git a/include/linux/regulator/act8846.h b/include/linux/regulator/act8846.h
index 9914372b3297..24f2ae969e0c 100755
--- a/include/linux/regulator/act8846.h
+++ b/include/linux/regulator/act8846.h
@@ -24,20 +24,39 @@
 #define ACT8846_LDO1 4                //(4+ACT8846_START)
 
 
-#define act8846_NUM_REGULATORS 13
+#define act8846_NUM_REGULATORS 12
 struct act8846;
 
 int act8846_device_shutdown(void);
 
+struct act8846_board {
+	int irq;
+	int irq_base;
+	struct regulator_init_data *act8846_init_data[act8846_NUM_REGULATORS];
+	struct device_node *of_node[act8846_NUM_REGULATORS];
+	int pmic_sleep_gpio; /* */
+	unsigned int dcdc_slp_voltage[3]; /* buckx_voltage in uV */
+	unsigned int dcdc_mode[3]; /* buckx_voltage in uV */
+	bool pmic_sleep;
+	unsigned int ldo_slp_voltage[7];
+};
+
 struct act8846_regulator_subdev {
 	int id;
 	struct regulator_init_data *initdata;
+	struct device_node *reg_node;
 };
 
 struct act8846_platform_data {
+	int ono;
 	int num_regulators;
 	int (*set_init)(struct act8846 *act8846);
 	struct act8846_regulator_subdev *regulators;
+	
+	int pmic_sleep_gpio; /* */
+	unsigned int dcdc_slp_voltage[3]; /* buckx_voltage in uV */
+	bool pmic_sleep;
+	unsigned int ldo_slp_voltage[7];
 };
 
 #endif