rk: rename rk808 to rk-rk808
authorHuang, Tao <huangtao@rock-chips.com>
Wed, 11 Nov 2015 07:02:36 +0000 (15:02 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 11 Nov 2015 07:02:36 +0000 (15:02 +0800)
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
drivers/mfd/rk-rk808.c [new file with mode: 0644]
drivers/mfd/rk808.c [deleted file]
drivers/rtc/rtc-rk-rk808.c [new file with mode: 0644]
drivers/rtc/rtc-rk808.c [deleted file]
include/linux/mfd/rk-rk808.h [new file with mode: 0644]
include/linux/mfd/rk808.h [deleted file]

diff --git a/drivers/mfd/rk-rk808.c b/drivers/mfd/rk-rk808.c
new file mode 100644 (file)
index 0000000..c42c3af
--- /dev/null
@@ -0,0 +1,1570 @@
+/*
+ * Regulator driver for rk808 PMIC chip for rk31xx
+ *
+ * Based on rk808.c that is work by zhangqing<zhangqing@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/rk808.h>
+#include <linux/mfd/core.h>
+#include <linux/delay.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>
+#include <linux/syscore_ops.h>
+
+#if 0
+#define DBG(x...)      printk(KERN_INFO x)
+#else
+#define DBG(x...)
+#endif
+#if 1
+#define DBG_INFO(x...) printk(KERN_INFO x)
+#else
+#define DBG_INFO(x...)
+#endif
+#define PM_CONTROL
+
+struct rk808 *g_rk808;
+#define DCDC_RAISE_VOL_BYSTEP 1
+#define DCDC_VOL_STEP 12500  /*12.5mv*/
+
+static struct mfd_cell rk808s[] = {
+       {
+               .name = "rk808-rtc",
+       },
+};
+
+#define BUCK_VOL_MASK 0x3f
+#define LDO_VOL_MASK 0x3f
+
+#define VOL_MIN_IDX 0x00
+#define VOL_MAX_IDX 0x3f
+
+const static int buck_set_vol_base_addr[] = {
+       RK808_BUCK1_ON_REG,
+       RK808_BUCK2_ON_REG,
+       RK808_BUCK3_CONFIG_REG,
+       RK808_BUCK4_ON_REG,
+};
+const static int buck_contr_base_addr[] = {
+       RK808_BUCK1_CONFIG_REG,
+       RK808_BUCK2_CONFIG_REG,
+       RK808_BUCK3_CONFIG_REG,
+       RK808_BUCK4_CONFIG_REG,
+};
+#define rk808_BUCK_SET_VOL_REG(x) (buck_set_vol_base_addr[x])
+#define rk808_BUCK_CONTR_REG(x) (buck_contr_base_addr[x])
+
+
+const static int ldo_set_vol_base_addr[] = {
+       RK808_LDO1_ON_VSEL_REG,
+       RK808_LDO2_ON_VSEL_REG,
+       RK808_LDO3_ON_VSEL_REG,
+       RK808_LDO4_ON_VSEL_REG, 
+       RK808_LDO5_ON_VSEL_REG, 
+       RK808_LDO6_ON_VSEL_REG, 
+       RK808_LDO7_ON_VSEL_REG, 
+       RK808_LDO8_ON_VSEL_REG, 
+//     RK808_LDO1_ON_VSEL_REG, 
+};
+/*
+const static int ldo_contr_base_addr[] = {
+       rk808_LDO1_CONTR_BASE,
+       rk808_LDO2_CONTR_BASE,
+       rk808_LDO3_CONTR_BASE,
+       rk808_LDO4_CONTR_BASE,
+       rk808_LDO5_CONTR_BASE,
+       rk808_LDO6_CONTR_BASE,
+       rk808_LDO7_CONTR_BASE,
+       rk808_LDO8_CONTR_BASE,
+//     rk808_LDO9_CONTR_BASE,
+};
+*/
+#define rk808_LDO_SET_VOL_REG(x) (ldo_set_vol_base_addr[x])
+//#define rk808_LDO_CONTR_REG(x) (ldo_contr_base_addr[x])
+
+const static int buck_voltage_map[] = {
+         712,  725,  737,  750, 762,  775,  787,  800,
+         812,  825,  837,  850,862,  875,  887,  900,  912,
+         925,  937,  950, 962,  975,  987, 1000, 1012, 1025, 
+         1037, 1050,1062, 1075, 1087, 1100, 1112, 1125, 1137, 
+         1150,1162, 1175, 1187, 1200, 1212, 1225, 1237, 1250,
+         1262, 1275, 1287, 1300, 1312, 1325, 1337, 1350,1362, 
+         1375, 1387, 1400, 1412, 1425, 1437, 1450,1462, 1475, 
+         1487, 1500,
+};
+
+const static int buck4_voltage_map[] = {
+           1800, 1900, 2000, 2100, 2200,  2300,  2400, 2500, 2600,
+          2700, 2800, 2900, 3000, 3100, 3200,3300, 
+};
+
+const static int ldo_voltage_map[] = {
+         1800, 1900, 2000, 2100, 2200,  2300,  2400, 2500, 2600, 
+         2700, 2800, 2900, 3000, 3100, 3200,3300, 3400, 
+};
+const static int ldo3_voltage_map[] = {
+        800, 900, 1000, 1100, 1200,  1300, 1400, 1500, 1600, 
+        1700, 1800, 1900,  2000,2100,  2200,  2500,
+};
+const static int ldo6_voltage_map[] = {
+        800, 900, 1000, 1100, 1200,  1300, 1400, 1500, 1600, 
+        1700, 1800, 1900,  2000,2100,  2200,  2300,2400,2500,
+};
+
+static int rk808_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
+{
+       int ldo= rdev_get_id(dev) - RK808_LDO1;
+       if (ldo == 2){
+       if (index >= ARRAY_SIZE(ldo3_voltage_map))
+               return -EINVAL;
+       return 1000 * ldo3_voltage_map[index];
+       }
+       else if (ldo == 5 || ldo ==6){
+       if (index >= ARRAY_SIZE(ldo6_voltage_map))
+               return -EINVAL;
+       return 1000 * ldo6_voltage_map[index];
+       }
+       else{
+       if (index >= ARRAY_SIZE(ldo_voltage_map))
+               return -EINVAL;
+       return 1000 * ldo_voltage_map[index];
+       }
+}
+static int rk808_ldo_is_enabled(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo= rdev_get_id(dev) - RK808_LDO1; 
+       u16 val;
+
+        if ((ldo ==8) ||(ldo ==9)){
+               val = rk808_reg_read(rk808, RK808_DCDC_EN_REG);
+               if (val < 0)
+                       return val;
+               if (val & (1 <<( ldo -3)))
+                       return 1;
+               else
+               return 0; 
+       }
+       else{
+               val = rk808_reg_read(rk808, RK808_LDO_EN_REG);
+               if (val < 0)
+                       return val;
+               if (val & (1 << ldo))
+                       return 1;
+               else
+                       return 0;       
+       }
+}
+static int rk808_ldo_enable(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo= rdev_get_id(dev) - RK808_LDO1;
+       
+       if(ldo == 8)
+               return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << 5, 1 << 5);
+       else if(ldo ==9)
+               return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << 6, 1 << 6);
+       else
+               return rk808_set_bits(rk808, RK808_LDO_EN_REG, 1 << ldo, 1 << ldo);
+       
+}
+static int rk808_ldo_disable(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo= rdev_get_id(dev) - RK808_LDO1;
+       
+       if(ldo == 8)
+               return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << 5, 0);
+       else if(ldo ==9)
+               return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << 6, 0);
+       else
+               return rk808_set_bits(rk808, RK808_LDO_EN_REG, 1 << ldo, 0);
+
+}
+static int rk808_ldo_suspend_enable(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo= rdev_get_id(dev) - RK808_LDO1;
+
+       if(ldo == 8)
+               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << 5, 0);
+       else if(ldo ==9)
+               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << 6, 0);
+       else
+               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG2, 1 << ldo, 0);
+       
+}
+static int rk808_ldo_suspend_disable(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo= rdev_get_id(dev) - RK808_LDO1;
+       
+       if(ldo == 8)
+               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << 5, 1 << 5);
+       else if(ldo ==9)
+               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << 6, 1 << 6);
+       else
+       return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG2, 1 << ldo, 1 << ldo);
+
+}
+static int rk808_ldo_get_voltage(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo= rdev_get_id(dev) - RK808_LDO1;
+       u16 reg = 0;
+       int val;
+
+       if  ((ldo ==8 ) || (ldo ==9)){
+               reg = rk808_reg_read(rk808,rk808_BUCK_SET_VOL_REG(3));
+               reg &= BUCK_VOL_MASK;
+               val = 1000 * buck4_voltage_map[reg];            
+       }
+       else{
+               reg = rk808_reg_read(rk808,rk808_LDO_SET_VOL_REG(ldo));
+               reg &= LDO_VOL_MASK;
+               if (ldo ==2){
+               val = 1000 * ldo3_voltage_map[reg];     
+               }
+               else if (ldo == 5 || ldo ==6){
+               val = 1000 * ldo6_voltage_map[reg];     
+               }
+               else{
+               val = 1000 * ldo_voltage_map[reg];      
+               }
+       }
+       return val;
+}
+static int rk808_ldo_set_sleep_voltage(struct regulator_dev *dev,
+                                           int uV)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo= rdev_get_id(dev) - RK808_LDO1;
+       const int *vol_map = ldo_voltage_map;
+       int min_vol = uV / 1000;
+       u16 val;
+       int ret = 0,num =0;
+       
+       if (ldo ==2){
+       vol_map = ldo3_voltage_map;     
+       num = 15;
+       }
+       else if (ldo == 5 || ldo ==6){
+       vol_map = ldo6_voltage_map;             
+       num = 17;
+       }
+       else {
+       num = 16;
+       }
+       
+       if (min_vol < vol_map[0] ||
+           min_vol > vol_map[num])
+               return -EINVAL;
+
+       for (val = 0; val <= num; val++){
+               if (vol_map[val] >= min_vol)
+                       break;  
+        }
+
+       ret = rk808_set_bits(rk808, rk808_LDO_SET_VOL_REG(ldo) +0x01,
+               LDO_VOL_MASK, val);
+       return ret;
+}
+
+static int rk808_ldo_set_voltage(struct regulator_dev *dev,
+                                 int min_uV, int max_uV,unsigned *selector)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo= rdev_get_id(dev) - RK808_LDO1;
+       const int *vol_map;
+       int min_vol = min_uV / 1000;
+       u16 val;
+       int ret = 0,num =0;
+       
+       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;
+
+       for (val = 0; val <= num; val++){
+               if (vol_map[val] >= min_vol)
+                       break;  
+        }
+       
+       ret = rk808_set_bits(rk808, rk808_LDO_SET_VOL_REG(ldo),
+               LDO_VOL_MASK, val);
+       return ret;
+
+}
+static unsigned int rk808_ldo_get_mode(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - RK808_LDO1;
+       u16 mask = 0x80;
+       u16 val;
+       val = rk808_reg_read(rk808, rk808_LDO_SET_VOL_REG(ldo));
+        if (val < 0) {
+                return val;
+        }
+       val=val & mask;
+       if (val== mask)
+               return REGULATOR_MODE_NORMAL;
+       else
+               return REGULATOR_MODE_STANDBY;
+
+}
+static int rk808_ldo_set_mode(struct regulator_dev *dev, unsigned int mode)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - RK808_LDO1;
+       u16 mask = 0x80;
+       switch(mode)
+       {
+       case REGULATOR_MODE_FAST:
+               return rk808_set_bits(rk808, rk808_LDO_SET_VOL_REG(ldo), mask, mask);           
+       case REGULATOR_MODE_NORMAL:
+               return rk808_set_bits(rk808, rk808_LDO_SET_VOL_REG(ldo), mask, 0);
+       default:
+               printk("error:pmu_rk808 only lowpower and nomal mode\n");
+               return -EINVAL;
+       }
+
+
+}
+static struct regulator_ops rk808_ldo_ops = {
+       .set_voltage = rk808_ldo_set_voltage,
+       .get_voltage = rk808_ldo_get_voltage,
+       .list_voltage = rk808_ldo_list_voltage,
+       .is_enabled = rk808_ldo_is_enabled,
+       .enable = rk808_ldo_enable,
+       .disable = rk808_ldo_disable,
+       .set_suspend_enable =rk808_ldo_suspend_enable,
+       .set_suspend_disable =rk808_ldo_suspend_disable,
+       .get_mode = rk808_ldo_get_mode,
+       .set_mode = rk808_ldo_set_mode,
+       .set_suspend_voltage = rk808_ldo_set_sleep_voltage,
+       
+};
+
+static int rk808_dcdc_list_voltage(struct regulator_dev *dev, unsigned selector)
+{
+       int volt;
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+
+       if (selector < 0x0 ||selector > BUCK_VOL_MASK )
+               return -EINVAL;
+
+       switch (buck) {
+       case 0:
+       case 1:
+               volt = 712500 + selector * 12500;
+               break;
+       case 3:
+               volt = 1800000 + selector * 100000;
+               break;
+       case 2:
+               volt = 1200000;
+               break;
+       default:
+               BUG();
+               return -EINVAL;
+       }
+
+       return  volt ;
+}
+static int rk808_dcdc_is_enabled(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+       u16 val;
+       
+       val = rk808_reg_read(rk808, RK808_DCDC_EN_REG);
+       if (val < 0)
+               return val;
+       if (val & (1 << buck))
+               return 1;
+       else
+               return 0;       
+}
+static int rk808_dcdc_enable(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+
+       return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << buck, 1 << buck);
+
+}
+static int rk808_dcdc_disable(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+       
+        return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << buck , 0);
+}
+
+static int rk808_dcdc_suspend_enable(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+
+       return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << buck, 0);
+
+}
+static int rk808_dcdc_suspend_disable(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+       
+        return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << buck , 1 << buck);
+}
+static int rk808_dcdc_get_voltage(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+       u16 reg = 0;
+       int val;
+
+       reg = rk808_reg_read(rk808,rk808_BUCK_SET_VOL_REG(buck));
+       
+       reg &= BUCK_VOL_MASK;
+       val = rk808_dcdc_list_voltage(dev,reg);
+       return val;
+}
+static int rk808_dcdc_select_min_voltage(struct regulator_dev *dev,
+                                          int min_uV, int max_uV ,int buck)
+{
+       u16 vsel =0;
+       
+       if (buck == 0 || buck ==  1){
+               if (min_uV < 712500)
+               vsel = 0;
+               else if (min_uV <= 1500000)
+               vsel = ((min_uV - 712500) / 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;
+       }
+       if (rk808_dcdc_list_voltage(dev, vsel) > max_uV)
+               return -EINVAL;
+       return vsel;
+}
+
+static int rk808_dcdc_set_voltage(struct regulator_dev *dev,
+                                 int min_uV, int max_uV,unsigned *selector)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+       u16 val;
+       int ret = 0,old_voltage =0,vol_temp =0;
+
+       if (buck ==2){
+               return 0;
+       }else if (buck==3){
+               val = rk808_dcdc_select_min_voltage(dev,min_uV,max_uV,buck);    
+               ret = rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), BUCK_VOL_MASK, val);
+       }
+       else {
+#if defined(DCDC_RAISE_VOL_BYSTEP)
+               old_voltage = rk808_dcdc_get_voltage(dev);
+                       if (max_uV >old_voltage){
+                               vol_temp = old_voltage;
+                              do{
+                                       vol_temp +=   DCDC_VOL_STEP;
+                                       val = rk808_dcdc_select_min_voltage(dev,vol_temp,vol_temp,buck);
+                               //      printk("rk808_dcdc_set_voltage buck = %d vol_temp= %d old_voltage= %d min_uV =%d \n",buck,vol_temp,old_voltage,min_uV);
+                                       ret = rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), BUCK_VOL_MASK, val);  
+                               } while (vol_temp < max_uV);
+                       }
+                       else{
+                               val = rk808_dcdc_select_min_voltage(dev,min_uV,max_uV,buck);
+                               ret = rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), BUCK_VOL_MASK, val);
+                       }
+#else
+               val = rk808_dcdc_select_min_voltage(dev,min_uV,max_uV,buck);
+               ret = rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), BUCK_VOL_MASK, val);
+#endif
+       }
+       if(ret<0)
+               printk("################WARNING:set voltage is error!voltage set is %d mv %d\n",min_uV,ret);
+
+       return ret;
+}
+static int rk808_dcdc_set_sleep_voltage(struct regulator_dev *dev,
+                                           int uV)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+       u16 val;
+       int ret = 0;
+
+       if (buck ==2){
+       return 0;
+       }else{
+       val = rk808_dcdc_select_min_voltage(dev,uV,uV,buck);
+       ret = rk808_set_bits(rk808, (rk808_BUCK_SET_VOL_REG(buck) + 0x01), BUCK_VOL_MASK, val);
+       }
+       return ret;
+}
+static unsigned int rk808_dcdc_get_mode(struct regulator_dev *dev)
+{
+       struct rk808 *rk808 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - RK808_DCDC1;
+       u16 mask = 0x80;
+       u16 val;
+       val = rk808_reg_read(rk808, rk808_BUCK_SET_VOL_REG(buck));
+        if (val < 0) {
+                return val;
+        }
+       val=val & mask;
+       if (val== mask)
+               return REGULATOR_MODE_FAST;
+       else
+               return REGULATOR_MODE_NORMAL;
+
+}
+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:
+               return rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), mask, mask);
+       case REGULATOR_MODE_NORMAL:
+               return rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), mask, 0);
+       default:
+               printk("error:pmu_rk808 only powersave and pwm mode\n");
+               return -EINVAL;
+       }
+
+}
+static int rk808_dcdc_set_suspend_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:
+               return rk808_set_bits(rk808, (rk808_BUCK_SET_VOL_REG(buck) + 0x01), mask, mask);
+       case REGULATOR_MODE_NORMAL:
+               return rk808_set_bits(rk808, (rk808_BUCK_SET_VOL_REG(buck) + 0x01), mask, 0);
+       default:
+               printk("error:pmu_rk808 only powersave and pwm mode\n");
+               return -EINVAL;
+       }
+
+}
+static int rk808_dcdc_set_voltage_time_sel(struct regulator_dev *dev,   unsigned int old_selector,
+                                    unsigned int new_selector)
+{
+       int old_volt, new_volt;
+       
+       old_volt = rk808_dcdc_list_voltage(dev, old_selector);
+       if (old_volt < 0)
+               return old_volt;
+       
+       new_volt = rk808_dcdc_list_voltage(dev, new_selector);
+       if (new_volt < 0)
+               return new_volt;
+
+       return DIV_ROUND_UP(abs(old_volt - new_volt)*2, 2500);
+}
+
+static struct regulator_ops rk808_dcdc_ops = { 
+       .set_voltage = rk808_dcdc_set_voltage,
+       .get_voltage = rk808_dcdc_get_voltage,
+       .list_voltage= rk808_dcdc_list_voltage,
+       .is_enabled = rk808_dcdc_is_enabled,
+       .enable = rk808_dcdc_enable,
+       .disable = rk808_dcdc_disable,
+       .set_suspend_enable =rk808_dcdc_suspend_enable,
+       .set_suspend_disable =rk808_dcdc_suspend_disable,
+       .get_mode = rk808_dcdc_get_mode,
+       .set_mode = rk808_dcdc_set_mode,
+       .set_suspend_mode = rk808_dcdc_set_suspend_mode,
+       .set_suspend_voltage = rk808_dcdc_set_sleep_voltage,
+       .set_voltage_time_sel = rk808_dcdc_set_voltage_time_sel,
+};
+static struct regulator_desc regulators[] = {
+
+        {
+               .name = "RK_DCDC1",
+               .id = 0,
+               .ops = &rk808_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_DCDC2",
+               .id = 1,
+               .ops = &rk808_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_DCDC3",
+               .id = 2,
+               .ops = &rk808_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck4_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_DCDC4",
+               .id = 3,
+               .ops = &rk808_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck4_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+
+       {
+               .name = "RK_LDO1",
+               .id =4,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_LDO2",
+               .id = 5,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_LDO3",
+               .id = 6,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo3_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_LDO4",
+               .id = 7,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+
+       {
+               .name = "RK_LDO5",
+               .id =8,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_LDO6",
+               .id = 9,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo6_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_LDO7",
+               .id = 10,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo6_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_LDO8",
+               .id = 11,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_LDO9",
+               .id = 12,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(buck4_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "RK_LDO10",
+               .id = 13,
+               .ops = &rk808_ldo_ops,
+               .n_voltages = ARRAY_SIZE(buck4_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       
+};
+
+/*
+ *
+ */
+ int rk808_i2c_read(struct rk808 *rk808, char reg, int count,u8 *dest)
+{
+       struct i2c_client *i2c = rk808->i2c;
+       int ret;
+    struct i2c_adapter *adap;
+    struct i2c_msg msgs[2];
+
+    if(!i2c)
+               return ret;
+
+       if (count != 1)
+               return -EIO;  
+  
+    adap = i2c->adapter;               
+    
+    msgs[0].addr = i2c->addr;
+    msgs[0].buf = &reg;
+    msgs[0].flags = i2c->flags;
+    msgs[0].len = 1;
+    msgs[0].scl_rate = 100*1000;
+    
+    msgs[1].buf = (u8 *)dest;
+    msgs[1].addr = i2c->addr;
+    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[1].buf));
+    return ret;
+}
+
+int rk808_i2c_write(struct rk808 *rk808, char reg, int count,  const u8 src)
+{
+       int ret=-1;
+       struct i2c_client *i2c = rk808->i2c;
+       struct i2c_adapter *adap;
+       struct i2c_msg msg;
+       char tx_buf[2];
+
+       if(!i2c)
+               return ret;
+       if (count != 1)
+               return -EIO;
+    
+       adap = i2c->adapter;            
+       tx_buf[0] = reg;
+       tx_buf[1] = src;
+       
+       msg.addr = i2c->addr;
+       msg.buf = &tx_buf[0];
+       msg.len = 1 +1;
+       msg.flags = i2c->flags;   
+       msg.scl_rate = 100*1000;        
+
+       ret = i2c_transfer(adap, &msg, 1);
+       return ret;     
+}
+
+int rk808_reg_read(struct rk808 *rk808, u8 reg)
+{
+       u8 val = 0;
+       int ret;
+
+       mutex_lock(&rk808->io_lock);
+
+       ret = rk808_i2c_read(rk808, reg, 1, &val);
+       DBG("reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)val&0xff);
+       if (ret < 0){
+                mutex_unlock(&rk808->io_lock);
+                return ret;
+       }
+       mutex_unlock(&rk808->io_lock);
+
+       return val & 0xff;      
+}
+EXPORT_SYMBOL_GPL(rk808_reg_read);
+
+int rk808_reg_write(struct rk808 *rk808, u8 reg, u8 val)
+{
+       int err =0;
+
+       mutex_lock(&rk808->io_lock);
+
+       err = rk808_i2c_write(rk808, reg, 1,val);
+       if (err < 0)
+               dev_err(rk808->dev, "Write for reg 0x%x failed\n", reg);
+
+       mutex_unlock(&rk808->io_lock);
+       return err;
+}
+EXPORT_SYMBOL_GPL(rk808_reg_write);
+
+ int rk808_set_bits(struct rk808 *rk808, u8 reg, u8 mask, u8 val)
+{
+       u8 tmp;
+       int ret;
+
+       mutex_lock(&rk808->io_lock);
+
+       ret = rk808_i2c_read(rk808, reg, 1, &tmp);
+       DBG("1 reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)tmp&0xff);
+       if (ret < 0){
+                mutex_unlock(&rk808->io_lock);
+                return ret;
+       }
+       tmp = (tmp & ~mask) | val;
+       ret = rk808_i2c_write(rk808, reg, 1, tmp);
+       DBG("reg write 0x%02x -> 0x%02x\n", (int)reg, (unsigned)val&0xff);
+       if (ret < 0){
+                mutex_unlock(&rk808->io_lock);
+                return ret;
+       }
+       ret = rk808_i2c_read(rk808, reg, 1, &tmp);
+       if (ret < 0){
+                mutex_unlock(&rk808->io_lock);
+                return ret;
+       }
+       DBG("2 reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)tmp&0xff);
+       mutex_unlock(&rk808->io_lock);
+
+       return 0;//ret; 
+}
+EXPORT_SYMBOL_GPL(rk808_set_bits);
+
+int rk808_clear_bits(struct rk808 *rk808, u8 reg, u8 mask)
+{
+       u8 data;
+       int err;
+
+       mutex_lock(&rk808->io_lock);
+       err = rk808_i2c_read(rk808, reg, 1, &data);
+       if (err <0) {
+               dev_err(rk808->dev, "read from reg %x failed\n", reg);
+               goto out;
+       }
+
+       data &= ~mask;
+       err = rk808_i2c_write(rk808, reg, 1, data);
+       if (err <0)
+               dev_err(rk808->dev, "write to reg %x failed\n", reg);
+
+out:
+       mutex_unlock(&rk808->io_lock);
+       return err;
+}
+EXPORT_SYMBOL_GPL(rk808_clear_bits);
+#if 0
+int rk808_bulk_read(struct rk808 *rk808, u8 reg,
+                    int count, u8 *buf)
+{
+       int ret;
+                    
+#if defined(CONFIG_MFD_RK610)    
+       int i;             //Solve communication conflict when rk610 and rk808 on the same i2c 
+
+       mutex_lock(&rk808->io_lock);
+       for(i=0; i<count; i++){
+               ret = rk808_reg_read(rk808, reg+i);
+               if(ret < 0){
+                       printk("%s: failed read reg 0x%0x, ret = %d\n", __FUNCTION__, reg+i, ret);
+                       mutex_unlock(&rk808->io_lock);
+                       return ret;
+               }else{
+                       buf[i] = ret & 0x000000FF;
+               }
+       }
+       mutex_unlock(&rk808->io_lock);
+#else
+       mutex_lock(&rk808->io_lock);
+       
+       ret = rk808->read(rk808, reg, count, buf);
+
+       mutex_unlock(&rk808->io_lock);
+#endif
+       return 0;
+
+}
+EXPORT_SYMBOL_GPL(rk808_bulk_read);
+
+int rk808_bulk_write(struct rk808 *rk808, u8 reg,
+                    int count, u8 *buf)
+{
+       int ret;
+       
+#if defined(CONFIG_MFD_RK610)    
+       int i;       // //Solve communication conflict when rk610 and 808 on the same i2c 
+
+       mutex_lock(&rk808->io_lock);
+       for(i=0; i<count; i++){
+               ret = rk808_reg_write(rk808, reg+i, buf[i]);
+               if(ret < 0){
+                       printk("%s: failed write reg=0x%0x, val=0x%0x, ret = %d\n", __FUNCTION__, reg+i, buf[i], ret);
+                       mutex_unlock(&rk808->io_lock);
+                       return ret;
+               }
+       }
+       mutex_unlock(&rk808->io_lock);
+#else
+       mutex_lock(&rk808->io_lock);
+       
+       ret = rk808->write(rk808, reg, count, buf);
+
+       mutex_unlock(&rk808->io_lock);
+#endif
+       return 0;
+
+}
+EXPORT_SYMBOL_GPL(rk808_bulk_write);
+#endif
+
+#if 1
+static ssize_t rk808_test_store(struct kobject *kobj, struct kobj_attribute *attr,
+                                const char *buf, size_t n)
+{
+    u32 getdata[8];
+    u8 regAddr;
+    u8 data;
+    char cmd;
+    const char *buftmp = buf;
+    struct rk808 *rk808 = g_rk808;
+    /**
+     * W Addr(8Bit) regAddr(8Bit) data0(8Bit) data1(8Bit) data2(8Bit) data3(8Bit)
+     *                 :data can be less than 4 byte
+     * R regAddr(8Bit)
+     * C gpio_name(poweron/powerhold/sleep/boot0/boot1) value(H/L)
+     */
+       sscanf(buftmp, "%c ", &cmd);
+       printk("------zhangqing: get cmd = %c\n", cmd);
+       switch (cmd) {
+       case 'w':
+               sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0], &getdata[1]);
+               regAddr = (u8)(getdata[0] & 0xff);
+               data = (u8)(getdata[1] & 0xff);
+               printk("get value = %x\n", data);
+
+               rk808_i2c_write(rk808, regAddr, 1, data);
+               rk808_i2c_read(rk808, regAddr, 1, &data);
+               printk("%x   %x\n", getdata[1], data);
+               break;
+       case 'r':
+               sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
+               printk("CMD : %c %x\n", cmd, getdata[0]);
+
+               regAddr = (u8)(getdata[0] & 0xff);
+               rk808_i2c_read(rk808, regAddr, 1, &data);
+               printk("%x %x\n", getdata[0], data);
+               break;
+       default:
+               printk("Unknown command\n");
+               break;
+       }
+       return n;
+
+}
+static ssize_t rk808_test_show(struct kobject *kobj, struct kobj_attribute *attr,
+                               char *buf)
+{
+   char *s = buf;
+    buf = "hello";
+    return sprintf(s, "%s\n", buf);
+
+}
+
+static struct kobject *rk808_kobj;
+struct rk808_attribute {
+       struct attribute        attr;
+       ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
+                       char *buf);
+       ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
+                       const char *buf, size_t n);
+};
+
+static struct rk808_attribute rk808_attrs[] = {
+       /*     node_name        permision               show_func       store_func */
+       __ATTR(rk808_test,      S_IRUGO | S_IWUSR,      rk808_test_show,        rk808_test_store),
+};
+#endif
+#if 0
+extern void rk_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));
+//     rk_send_wakeup_key();
+        return IRQ_HANDLED;
+}
+#endif
+#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 },
+       { .name = "rk_ldo9", .driver_data = (void *)12 },
+       { .name = "rk_ldo10", .driver_data = (void *)13 },
+};
+
+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;
+       }
+
+       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;
+               }
+
+       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);
+               }
+       pdata->pmic_sleep = true;
+       
+       pdata->pm_off = of_property_read_bool(rk808_pmic_np,"rk808,system-power-controller");
+               
+       return pdata;
+}
+
+#else
+static struct rk808_board *rk808_parse_dt(struct i2c_client *i2c)
+{
+       return NULL;
+}
+#endif
+static void rk808_shutdown(void)
+{
+       int ret,i,val;
+       u16 reg = 0;
+       struct rk808 *rk808 = g_rk808;
+       
+       printk("%s\n",__func__);
+       /***************get dc1\dc2 voltage *********************/
+       for(i=0;i<2;i++){
+       reg = rk808_reg_read(rk808,rk808_BUCK_SET_VOL_REG(i));
+       reg &= BUCK_VOL_MASK;
+       val = 712500 + reg * 12500;
+       printk("%s,line=%d dc[%d]= %d\n", __func__,__LINE__,(i+1),val);
+       }
+       /*****************************************************/
+       ret = rk808_set_bits(rk808, RK808_INT_STS_MSK_REG1,(0x3<<5),(0x3<<5)); //close rtc int when power off
+       ret = rk808_clear_bits(rk808, RK808_RTC_INT_REG,(0x3<<2)); //close rtc int when power off
+       mutex_lock(&rk808->io_lock);
+       mdelay(100);
+}
+
+static struct syscore_ops rk808_syscore_ops = {
+       .shutdown = rk808_shutdown,
+};
+
+static void rk808_device_shutdown(void)
+{
+       int ret,i;
+       u8 reg = 0;
+       struct rk808 *rk808 = g_rk808;
+       for(i=0;i < 10;i++){
+               printk("%s\n",__func__);
+               ret = rk808_i2c_read(rk808,RK808_DEVCTRL_REG,1,&reg);
+               if(ret < 0)
+                       continue;
+               ret = rk808_i2c_write(rk808, RK808_DEVCTRL_REG, 1,(reg |(0x1 <<3)));
+               if (ret < 0) {
+                       printk("rk808 power off error!\n");
+                       continue;
+               }
+       }
+       while(1)wfi();  
+}
+EXPORT_SYMBOL_GPL(rk808_device_shutdown);
+
+__weak void  rk808_device_suspend(void) {}
+__weak void  rk808_device_resume(void) {}
+#ifdef CONFIG_PM
+static int rk808_suspend(struct device *dev)
+{              
+       rk808_device_suspend();
+       return 0;
+}
+
+static int rk808_resume(struct device *dev)
+{
+       rk808_device_resume();
+       return 0;
+}
+#else
+static int rk808_suspend(struct device *dev)
+{              
+       return 0;
+}
+
+static int rk808_resume(struct device *dev)
+{
+       return 0;
+}
+#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 rk808_pre_init(struct rk808 *rk808)
+{
+       int ret,val;
+        printk("%s,line=%d\n", __func__,__LINE__);
+        /**********disable dcdc uv func****************/
+        ret = rk808_reg_write(rk808,RK808_DCDC_UV_ACT_REG,0x10);
+         if (ret <0) {
+                printk(KERN_ERR "Unable to write RK808_DCDC_UV_ACT_REG reg\n");
+                return ret;
+        }
+       /**********************************/
+        /***********set ILIM ************/
+       val = rk808_reg_read(rk808,RK808_BUCK3_CONFIG_REG);
+       val &= (~(0x7 <<0));
+       val |= (0x2 <<0);
+       ret = rk808_reg_write(rk808,RK808_BUCK3_CONFIG_REG,val);
+       if (ret < 0) {
+                printk(KERN_ERR "Unable to write RK808_BUCK3_CONFIG_REG reg\n");
+                return ret;
+        }
+
+       val = rk808_reg_read(rk808,RK808_BUCK4_CONFIG_REG);
+       val &= (~(0x7 <<0));
+       val |= (0x3 <<0);
+       ret = rk808_reg_write(rk808,RK808_BUCK4_CONFIG_REG,val);
+       if (ret < 0) {
+                printk(KERN_ERR "Unable to write RK808_BUCK4_CONFIG_REG reg\n");
+                return ret;
+        }
+       
+       val = rk808_reg_read(rk808,RK808_BOOST_CONFIG_REG);
+       val &= (~(0x7 <<0));
+       val |= (0x1 <<0);
+       ret = rk808_reg_write(rk808,RK808_BOOST_CONFIG_REG,val);
+       if (ret < 0) {
+                printk(KERN_ERR "Unable to write RK808_BOOST_CONFIG_REG reg\n");
+                return ret;
+        }
+       /*****************************************/
+       /***********set buck OTP function************/
+       ret = rk808_reg_write(rk808,0x6f,0x5a);
+       if (ret < 0) {
+                printk(KERN_ERR "Unable to write 0x6f reg\n");
+                return ret;
+        }
+       
+       ret = rk808_reg_write(rk808,0x91,0x80);
+       if (ret < 0) {
+                printk(KERN_ERR "Unable to write 0x91 reg\n");
+                return ret;
+        }
+
+        ret = rk808_reg_write(rk808,0x92,0x55);
+        if (ret <0) {
+                printk(KERN_ERR "Unable to write 0x92 reg\n");
+                return ret;
+        }
+       /*****************************************/
+       /***********set buck 12.5mv/us ************/
+       val = rk808_reg_read(rk808,RK808_BUCK1_CONFIG_REG);
+       val &= (~(0x3 <<3));
+       val |= (0x3 <<0);
+       ret = rk808_reg_write(rk808,RK808_BUCK1_CONFIG_REG,val);
+       if (ret < 0) {
+                printk(KERN_ERR "Unable to write RK808_BUCK1_CONFIG_REG reg\n");
+                return ret;
+        }
+
+       val = rk808_reg_read(rk808,RK808_BUCK2_CONFIG_REG);
+        val &= (~(0x3 <<3));
+       val |= (0x3 <<0);
+        ret = rk808_reg_write(rk808,RK808_BUCK2_CONFIG_REG,val);
+        if (ret <0) {
+                printk(KERN_ERR "Unable to write RK808_BUCK2_CONFIG_REG reg\n");
+                return ret;
+        }
+       /*****************************************/
+
+       /*******enable switch and boost***********/
+       val = rk808_reg_read(rk808,RK808_DCDC_EN_REG);
+        val |= (0x3 << 5);    //enable switch1/2
+       val |= (0x1 << 4);    //enable boost
+        ret = rk808_reg_write(rk808,RK808_DCDC_EN_REG,val);
+         if (ret <0) {
+                printk(KERN_ERR "Unable to write RK808_DCDC_EN_REG reg\n");
+                return ret;
+       }
+       /****************************************/
+       
+       /****************set vbat low **********/
+       val = rk808_reg_read(rk808,RK808_VB_MON_REG);
+       val &=(~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
+       val |= (RK808_VBAT_LOW_3V5 | EN_VBAT_LOW_IRQ);
+       ret = rk808_reg_write(rk808,RK808_VB_MON_REG,val);
+         if (ret <0) {
+                printk(KERN_ERR "Unable to write RK818_VB_MON_REG reg\n");
+                return ret;
+        }
+       /**************************************/
+       
+       /**********mask int****************/
+        val = rk808_reg_read(rk808,RK808_INT_STS_MSK_REG1);
+         val |= (0x1<<0); //mask vout_lo_int    
+        ret = rk808_reg_write(rk808,RK808_INT_STS_MSK_REG1,val);
+         if (ret <0) {
+                printk(KERN_ERR "Unable to write RK808_INT_STS_MSK_REG1 reg\n");
+                return ret;
+        }
+       /**********************************/
+       /**********enable clkout2****************/
+        ret = rk808_reg_write(rk808,RK808_CLK32OUT_REG,0x01);
+         if (ret <0) {
+                printk(KERN_ERR "Unable to write RK808_CLK32OUT_REG reg\n");
+                return ret;
+        }
+       /**********************************/
+       ret = rk808_clear_bits(rk808, RK808_INT_STS_MSK_REG1,(0x3<<5)); //open rtc int when power on
+       ret = rk808_set_bits(rk808, RK808_RTC_INT_REG,(0x1<<3),(0x1<<3)); //open rtc int when power on
+
+       return 0;
+}
+
+static int rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+       struct rk808 *rk808;    
+       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,i=0;
+//     int vlow_irq;
+       
+       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 = devm_kzalloc(&i2c->dev,sizeof(struct rk808), GFP_KERNEL);
+       if (rk808 == NULL) {
+               ret = -ENOMEM;          
+               goto err;
+       }
+       rk808->i2c = i2c;
+       rk808->dev = &i2c->dev;
+       i2c_set_clientdata(i2c, rk808);
+//     rk808->read = rk808_i2c_read;
+//     rk808->write = rk808_i2c_write;
+
+       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 %d\n",ret);
+               goto err;
+       }
+
+       ret = rk808_pre_init(rk808);
+       if (ret < 0){
+               printk("The rk808_pre_init failed %d\n",ret);
+               goto err;
+       }
+
+       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 (gpio_is_valid(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_output(rk808->pmic_sleep_gpio,0);
+                       ret = gpio_get_value(rk808->pmic_sleep_gpio);
+                       gpio_free(rk808->pmic_sleep_gpio);
+                       pr_info("%s: rk808_pmic_sleep=%x\n", __func__, ret);
+       }       
+       #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;
+
+               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;
+               }
+       }
+
+//     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);
+       #if 0   
+       /********************vbat low int**************/
+       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",
+                        vlow_irq+ RK808_IRQ_VB_LO, ret);
+
+        }
+       #endif
+       /*********************************************/
+       
+       g_rk808 = rk808;
+       if (pdev->pm_off && !pm_power_off) {
+               pm_power_off = rk808_device_shutdown;
+       }
+
+       #ifdef CONFIG_HAS_EARLYSUSPEND
+       rk808->rk808_suspend.suspend = rk808_early_suspend,
+       rk808->rk808_suspend.resume = rk808_late_resume,
+       rk808->rk808_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1,
+       register_early_suspend(&rk808->rk808_suspend);
+       #endif
+
+       #if 1
+       rk808_kobj = kobject_create_and_add("rk808", NULL);
+       if (!rk808_kobj)
+               return -ENOMEM;
+       for (i = 0; i < ARRAY_SIZE(rk808_attrs); i++) {
+               ret = sysfs_create_file(rk808_kobj, &rk808_attrs[i].attr);
+               if (ret != 0) {
+                       printk("create index %d error\n", i);
+                       return ret;
+               }
+       }
+       #endif
+
+       register_syscore_ops(&rk808_syscore_ops);
+       
+       return 0;
+
+err:
+       mfd_remove_devices(rk808->dev);
+       return ret;     
+
+}
+
+static int rk808_i2c_remove(struct i2c_client *i2c)
+{
+       struct rk808 *rk808 = i2c_get_clientdata(i2c);
+       int i;
+
+       unregister_syscore_ops(&rk808_syscore_ops);
+       for (i = 0; i < rk808->num_regulators; i++)
+               if (rk808->rdev[i])
+                       regulator_unregister(rk808->rdev[i]);
+       kfree(rk808->rdev);
+       i2c_set_clientdata(i2c, NULL);
+
+       return 0;
+}
+
+static const struct dev_pm_ops rk808_pm_ops = {
+       .suspend = rk808_suspend,
+       .resume =  rk808_resume,
+};
+
+static const struct i2c_device_id rk808_i2c_id[] = {
+       { "rk808", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, rk808_i2c_id);
+
+static struct i2c_driver rk808_i2c_driver = {
+       .driver = {
+               .name = "rk808",
+               .owner = THIS_MODULE,
+               #ifdef CONFIG_PM
+               .pm = &rk808_pm_ops,
+               #endif
+               .of_match_table =of_match_ptr(rk808_of_match),
+       },
+       .probe    = rk808_i2c_probe,
+       .remove   = rk808_i2c_remove,
+       .id_table = rk808_i2c_id,
+};
+
+static int __init rk808_module_init(void)
+{
+       int ret;
+       ret = i2c_add_driver(&rk808_i2c_driver);
+       if (ret != 0)
+               pr_err("Failed to register I2C driver: %d\n", ret);
+       return ret;
+}
+//module_init(rk808_module_init);
+//subsys_initcall(rk808_module_init);
+//rootfs_initcall(rk808_module_init);
+subsys_initcall_sync(rk808_module_init);
+
+static void __exit rk808_module_exit(void)
+{
+       i2c_del_driver(&rk808_i2c_driver);
+}
+module_exit(rk808_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
+MODULE_DESCRIPTION("rk808 PMIC driver");
+
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
deleted file mode 100644 (file)
index c42c3af..0000000
+++ /dev/null
@@ -1,1570 +0,0 @@
-/*
- * Regulator driver for rk808 PMIC chip for rk31xx
- *
- * Based on rk808.c that is work by zhangqing<zhangqing@rock-chips.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/bug.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/regulator/driver.h>
-#include <linux/mfd/rk808.h>
-#include <linux/mfd/core.h>
-#include <linux/delay.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>
-#include <linux/syscore_ops.h>
-
-#if 0
-#define DBG(x...)      printk(KERN_INFO x)
-#else
-#define DBG(x...)
-#endif
-#if 1
-#define DBG_INFO(x...) printk(KERN_INFO x)
-#else
-#define DBG_INFO(x...)
-#endif
-#define PM_CONTROL
-
-struct rk808 *g_rk808;
-#define DCDC_RAISE_VOL_BYSTEP 1
-#define DCDC_VOL_STEP 12500  /*12.5mv*/
-
-static struct mfd_cell rk808s[] = {
-       {
-               .name = "rk808-rtc",
-       },
-};
-
-#define BUCK_VOL_MASK 0x3f
-#define LDO_VOL_MASK 0x3f
-
-#define VOL_MIN_IDX 0x00
-#define VOL_MAX_IDX 0x3f
-
-const static int buck_set_vol_base_addr[] = {
-       RK808_BUCK1_ON_REG,
-       RK808_BUCK2_ON_REG,
-       RK808_BUCK3_CONFIG_REG,
-       RK808_BUCK4_ON_REG,
-};
-const static int buck_contr_base_addr[] = {
-       RK808_BUCK1_CONFIG_REG,
-       RK808_BUCK2_CONFIG_REG,
-       RK808_BUCK3_CONFIG_REG,
-       RK808_BUCK4_CONFIG_REG,
-};
-#define rk808_BUCK_SET_VOL_REG(x) (buck_set_vol_base_addr[x])
-#define rk808_BUCK_CONTR_REG(x) (buck_contr_base_addr[x])
-
-
-const static int ldo_set_vol_base_addr[] = {
-       RK808_LDO1_ON_VSEL_REG,
-       RK808_LDO2_ON_VSEL_REG,
-       RK808_LDO3_ON_VSEL_REG,
-       RK808_LDO4_ON_VSEL_REG, 
-       RK808_LDO5_ON_VSEL_REG, 
-       RK808_LDO6_ON_VSEL_REG, 
-       RK808_LDO7_ON_VSEL_REG, 
-       RK808_LDO8_ON_VSEL_REG, 
-//     RK808_LDO1_ON_VSEL_REG, 
-};
-/*
-const static int ldo_contr_base_addr[] = {
-       rk808_LDO1_CONTR_BASE,
-       rk808_LDO2_CONTR_BASE,
-       rk808_LDO3_CONTR_BASE,
-       rk808_LDO4_CONTR_BASE,
-       rk808_LDO5_CONTR_BASE,
-       rk808_LDO6_CONTR_BASE,
-       rk808_LDO7_CONTR_BASE,
-       rk808_LDO8_CONTR_BASE,
-//     rk808_LDO9_CONTR_BASE,
-};
-*/
-#define rk808_LDO_SET_VOL_REG(x) (ldo_set_vol_base_addr[x])
-//#define rk808_LDO_CONTR_REG(x) (ldo_contr_base_addr[x])
-
-const static int buck_voltage_map[] = {
-         712,  725,  737,  750, 762,  775,  787,  800,
-         812,  825,  837,  850,862,  875,  887,  900,  912,
-         925,  937,  950, 962,  975,  987, 1000, 1012, 1025, 
-         1037, 1050,1062, 1075, 1087, 1100, 1112, 1125, 1137, 
-         1150,1162, 1175, 1187, 1200, 1212, 1225, 1237, 1250,
-         1262, 1275, 1287, 1300, 1312, 1325, 1337, 1350,1362, 
-         1375, 1387, 1400, 1412, 1425, 1437, 1450,1462, 1475, 
-         1487, 1500,
-};
-
-const static int buck4_voltage_map[] = {
-           1800, 1900, 2000, 2100, 2200,  2300,  2400, 2500, 2600,
-          2700, 2800, 2900, 3000, 3100, 3200,3300, 
-};
-
-const static int ldo_voltage_map[] = {
-         1800, 1900, 2000, 2100, 2200,  2300,  2400, 2500, 2600, 
-         2700, 2800, 2900, 3000, 3100, 3200,3300, 3400, 
-};
-const static int ldo3_voltage_map[] = {
-        800, 900, 1000, 1100, 1200,  1300, 1400, 1500, 1600, 
-        1700, 1800, 1900,  2000,2100,  2200,  2500,
-};
-const static int ldo6_voltage_map[] = {
-        800, 900, 1000, 1100, 1200,  1300, 1400, 1500, 1600, 
-        1700, 1800, 1900,  2000,2100,  2200,  2300,2400,2500,
-};
-
-static int rk808_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
-{
-       int ldo= rdev_get_id(dev) - RK808_LDO1;
-       if (ldo == 2){
-       if (index >= ARRAY_SIZE(ldo3_voltage_map))
-               return -EINVAL;
-       return 1000 * ldo3_voltage_map[index];
-       }
-       else if (ldo == 5 || ldo ==6){
-       if (index >= ARRAY_SIZE(ldo6_voltage_map))
-               return -EINVAL;
-       return 1000 * ldo6_voltage_map[index];
-       }
-       else{
-       if (index >= ARRAY_SIZE(ldo_voltage_map))
-               return -EINVAL;
-       return 1000 * ldo_voltage_map[index];
-       }
-}
-static int rk808_ldo_is_enabled(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo= rdev_get_id(dev) - RK808_LDO1; 
-       u16 val;
-
-        if ((ldo ==8) ||(ldo ==9)){
-               val = rk808_reg_read(rk808, RK808_DCDC_EN_REG);
-               if (val < 0)
-                       return val;
-               if (val & (1 <<( ldo -3)))
-                       return 1;
-               else
-               return 0; 
-       }
-       else{
-               val = rk808_reg_read(rk808, RK808_LDO_EN_REG);
-               if (val < 0)
-                       return val;
-               if (val & (1 << ldo))
-                       return 1;
-               else
-                       return 0;       
-       }
-}
-static int rk808_ldo_enable(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo= rdev_get_id(dev) - RK808_LDO1;
-       
-       if(ldo == 8)
-               return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << 5, 1 << 5);
-       else if(ldo ==9)
-               return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << 6, 1 << 6);
-       else
-               return rk808_set_bits(rk808, RK808_LDO_EN_REG, 1 << ldo, 1 << ldo);
-       
-}
-static int rk808_ldo_disable(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo= rdev_get_id(dev) - RK808_LDO1;
-       
-       if(ldo == 8)
-               return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << 5, 0);
-       else if(ldo ==9)
-               return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << 6, 0);
-       else
-               return rk808_set_bits(rk808, RK808_LDO_EN_REG, 1 << ldo, 0);
-
-}
-static int rk808_ldo_suspend_enable(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo= rdev_get_id(dev) - RK808_LDO1;
-
-       if(ldo == 8)
-               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << 5, 0);
-       else if(ldo ==9)
-               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << 6, 0);
-       else
-               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG2, 1 << ldo, 0);
-       
-}
-static int rk808_ldo_suspend_disable(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo= rdev_get_id(dev) - RK808_LDO1;
-       
-       if(ldo == 8)
-               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << 5, 1 << 5);
-       else if(ldo ==9)
-               return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << 6, 1 << 6);
-       else
-       return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG2, 1 << ldo, 1 << ldo);
-
-}
-static int rk808_ldo_get_voltage(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo= rdev_get_id(dev) - RK808_LDO1;
-       u16 reg = 0;
-       int val;
-
-       if  ((ldo ==8 ) || (ldo ==9)){
-               reg = rk808_reg_read(rk808,rk808_BUCK_SET_VOL_REG(3));
-               reg &= BUCK_VOL_MASK;
-               val = 1000 * buck4_voltage_map[reg];            
-       }
-       else{
-               reg = rk808_reg_read(rk808,rk808_LDO_SET_VOL_REG(ldo));
-               reg &= LDO_VOL_MASK;
-               if (ldo ==2){
-               val = 1000 * ldo3_voltage_map[reg];     
-               }
-               else if (ldo == 5 || ldo ==6){
-               val = 1000 * ldo6_voltage_map[reg];     
-               }
-               else{
-               val = 1000 * ldo_voltage_map[reg];      
-               }
-       }
-       return val;
-}
-static int rk808_ldo_set_sleep_voltage(struct regulator_dev *dev,
-                                           int uV)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo= rdev_get_id(dev) - RK808_LDO1;
-       const int *vol_map = ldo_voltage_map;
-       int min_vol = uV / 1000;
-       u16 val;
-       int ret = 0,num =0;
-       
-       if (ldo ==2){
-       vol_map = ldo3_voltage_map;     
-       num = 15;
-       }
-       else if (ldo == 5 || ldo ==6){
-       vol_map = ldo6_voltage_map;             
-       num = 17;
-       }
-       else {
-       num = 16;
-       }
-       
-       if (min_vol < vol_map[0] ||
-           min_vol > vol_map[num])
-               return -EINVAL;
-
-       for (val = 0; val <= num; val++){
-               if (vol_map[val] >= min_vol)
-                       break;  
-        }
-
-       ret = rk808_set_bits(rk808, rk808_LDO_SET_VOL_REG(ldo) +0x01,
-               LDO_VOL_MASK, val);
-       return ret;
-}
-
-static int rk808_ldo_set_voltage(struct regulator_dev *dev,
-                                 int min_uV, int max_uV,unsigned *selector)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo= rdev_get_id(dev) - RK808_LDO1;
-       const int *vol_map;
-       int min_vol = min_uV / 1000;
-       u16 val;
-       int ret = 0,num =0;
-       
-       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;
-
-       for (val = 0; val <= num; val++){
-               if (vol_map[val] >= min_vol)
-                       break;  
-        }
-       
-       ret = rk808_set_bits(rk808, rk808_LDO_SET_VOL_REG(ldo),
-               LDO_VOL_MASK, val);
-       return ret;
-
-}
-static unsigned int rk808_ldo_get_mode(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo = rdev_get_id(dev) - RK808_LDO1;
-       u16 mask = 0x80;
-       u16 val;
-       val = rk808_reg_read(rk808, rk808_LDO_SET_VOL_REG(ldo));
-        if (val < 0) {
-                return val;
-        }
-       val=val & mask;
-       if (val== mask)
-               return REGULATOR_MODE_NORMAL;
-       else
-               return REGULATOR_MODE_STANDBY;
-
-}
-static int rk808_ldo_set_mode(struct regulator_dev *dev, unsigned int mode)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int ldo = rdev_get_id(dev) - RK808_LDO1;
-       u16 mask = 0x80;
-       switch(mode)
-       {
-       case REGULATOR_MODE_FAST:
-               return rk808_set_bits(rk808, rk808_LDO_SET_VOL_REG(ldo), mask, mask);           
-       case REGULATOR_MODE_NORMAL:
-               return rk808_set_bits(rk808, rk808_LDO_SET_VOL_REG(ldo), mask, 0);
-       default:
-               printk("error:pmu_rk808 only lowpower and nomal mode\n");
-               return -EINVAL;
-       }
-
-
-}
-static struct regulator_ops rk808_ldo_ops = {
-       .set_voltage = rk808_ldo_set_voltage,
-       .get_voltage = rk808_ldo_get_voltage,
-       .list_voltage = rk808_ldo_list_voltage,
-       .is_enabled = rk808_ldo_is_enabled,
-       .enable = rk808_ldo_enable,
-       .disable = rk808_ldo_disable,
-       .set_suspend_enable =rk808_ldo_suspend_enable,
-       .set_suspend_disable =rk808_ldo_suspend_disable,
-       .get_mode = rk808_ldo_get_mode,
-       .set_mode = rk808_ldo_set_mode,
-       .set_suspend_voltage = rk808_ldo_set_sleep_voltage,
-       
-};
-
-static int rk808_dcdc_list_voltage(struct regulator_dev *dev, unsigned selector)
-{
-       int volt;
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-
-       if (selector < 0x0 ||selector > BUCK_VOL_MASK )
-               return -EINVAL;
-
-       switch (buck) {
-       case 0:
-       case 1:
-               volt = 712500 + selector * 12500;
-               break;
-       case 3:
-               volt = 1800000 + selector * 100000;
-               break;
-       case 2:
-               volt = 1200000;
-               break;
-       default:
-               BUG();
-               return -EINVAL;
-       }
-
-       return  volt ;
-}
-static int rk808_dcdc_is_enabled(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-       u16 val;
-       
-       val = rk808_reg_read(rk808, RK808_DCDC_EN_REG);
-       if (val < 0)
-               return val;
-       if (val & (1 << buck))
-               return 1;
-       else
-               return 0;       
-}
-static int rk808_dcdc_enable(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-
-       return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << buck, 1 << buck);
-
-}
-static int rk808_dcdc_disable(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-       
-        return rk808_set_bits(rk808, RK808_DCDC_EN_REG, 1 << buck , 0);
-}
-
-static int rk808_dcdc_suspend_enable(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-
-       return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << buck, 0);
-
-}
-static int rk808_dcdc_suspend_disable(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-       
-        return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG1, 1 << buck , 1 << buck);
-}
-static int rk808_dcdc_get_voltage(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-       u16 reg = 0;
-       int val;
-
-       reg = rk808_reg_read(rk808,rk808_BUCK_SET_VOL_REG(buck));
-       
-       reg &= BUCK_VOL_MASK;
-       val = rk808_dcdc_list_voltage(dev,reg);
-       return val;
-}
-static int rk808_dcdc_select_min_voltage(struct regulator_dev *dev,
-                                          int min_uV, int max_uV ,int buck)
-{
-       u16 vsel =0;
-       
-       if (buck == 0 || buck ==  1){
-               if (min_uV < 712500)
-               vsel = 0;
-               else if (min_uV <= 1500000)
-               vsel = ((min_uV - 712500) / 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;
-       }
-       if (rk808_dcdc_list_voltage(dev, vsel) > max_uV)
-               return -EINVAL;
-       return vsel;
-}
-
-static int rk808_dcdc_set_voltage(struct regulator_dev *dev,
-                                 int min_uV, int max_uV,unsigned *selector)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-       u16 val;
-       int ret = 0,old_voltage =0,vol_temp =0;
-
-       if (buck ==2){
-               return 0;
-       }else if (buck==3){
-               val = rk808_dcdc_select_min_voltage(dev,min_uV,max_uV,buck);    
-               ret = rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), BUCK_VOL_MASK, val);
-       }
-       else {
-#if defined(DCDC_RAISE_VOL_BYSTEP)
-               old_voltage = rk808_dcdc_get_voltage(dev);
-                       if (max_uV >old_voltage){
-                               vol_temp = old_voltage;
-                              do{
-                                       vol_temp +=   DCDC_VOL_STEP;
-                                       val = rk808_dcdc_select_min_voltage(dev,vol_temp,vol_temp,buck);
-                               //      printk("rk808_dcdc_set_voltage buck = %d vol_temp= %d old_voltage= %d min_uV =%d \n",buck,vol_temp,old_voltage,min_uV);
-                                       ret = rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), BUCK_VOL_MASK, val);  
-                               } while (vol_temp < max_uV);
-                       }
-                       else{
-                               val = rk808_dcdc_select_min_voltage(dev,min_uV,max_uV,buck);
-                               ret = rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), BUCK_VOL_MASK, val);
-                       }
-#else
-               val = rk808_dcdc_select_min_voltage(dev,min_uV,max_uV,buck);
-               ret = rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), BUCK_VOL_MASK, val);
-#endif
-       }
-       if(ret<0)
-               printk("################WARNING:set voltage is error!voltage set is %d mv %d\n",min_uV,ret);
-
-       return ret;
-}
-static int rk808_dcdc_set_sleep_voltage(struct regulator_dev *dev,
-                                           int uV)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-       u16 val;
-       int ret = 0;
-
-       if (buck ==2){
-       return 0;
-       }else{
-       val = rk808_dcdc_select_min_voltage(dev,uV,uV,buck);
-       ret = rk808_set_bits(rk808, (rk808_BUCK_SET_VOL_REG(buck) + 0x01), BUCK_VOL_MASK, val);
-       }
-       return ret;
-}
-static unsigned int rk808_dcdc_get_mode(struct regulator_dev *dev)
-{
-       struct rk808 *rk808 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - RK808_DCDC1;
-       u16 mask = 0x80;
-       u16 val;
-       val = rk808_reg_read(rk808, rk808_BUCK_SET_VOL_REG(buck));
-        if (val < 0) {
-                return val;
-        }
-       val=val & mask;
-       if (val== mask)
-               return REGULATOR_MODE_FAST;
-       else
-               return REGULATOR_MODE_NORMAL;
-
-}
-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:
-               return rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), mask, mask);
-       case REGULATOR_MODE_NORMAL:
-               return rk808_set_bits(rk808, rk808_BUCK_SET_VOL_REG(buck), mask, 0);
-       default:
-               printk("error:pmu_rk808 only powersave and pwm mode\n");
-               return -EINVAL;
-       }
-
-}
-static int rk808_dcdc_set_suspend_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:
-               return rk808_set_bits(rk808, (rk808_BUCK_SET_VOL_REG(buck) + 0x01), mask, mask);
-       case REGULATOR_MODE_NORMAL:
-               return rk808_set_bits(rk808, (rk808_BUCK_SET_VOL_REG(buck) + 0x01), mask, 0);
-       default:
-               printk("error:pmu_rk808 only powersave and pwm mode\n");
-               return -EINVAL;
-       }
-
-}
-static int rk808_dcdc_set_voltage_time_sel(struct regulator_dev *dev,   unsigned int old_selector,
-                                    unsigned int new_selector)
-{
-       int old_volt, new_volt;
-       
-       old_volt = rk808_dcdc_list_voltage(dev, old_selector);
-       if (old_volt < 0)
-               return old_volt;
-       
-       new_volt = rk808_dcdc_list_voltage(dev, new_selector);
-       if (new_volt < 0)
-               return new_volt;
-
-       return DIV_ROUND_UP(abs(old_volt - new_volt)*2, 2500);
-}
-
-static struct regulator_ops rk808_dcdc_ops = { 
-       .set_voltage = rk808_dcdc_set_voltage,
-       .get_voltage = rk808_dcdc_get_voltage,
-       .list_voltage= rk808_dcdc_list_voltage,
-       .is_enabled = rk808_dcdc_is_enabled,
-       .enable = rk808_dcdc_enable,
-       .disable = rk808_dcdc_disable,
-       .set_suspend_enable =rk808_dcdc_suspend_enable,
-       .set_suspend_disable =rk808_dcdc_suspend_disable,
-       .get_mode = rk808_dcdc_get_mode,
-       .set_mode = rk808_dcdc_set_mode,
-       .set_suspend_mode = rk808_dcdc_set_suspend_mode,
-       .set_suspend_voltage = rk808_dcdc_set_sleep_voltage,
-       .set_voltage_time_sel = rk808_dcdc_set_voltage_time_sel,
-};
-static struct regulator_desc regulators[] = {
-
-        {
-               .name = "RK_DCDC1",
-               .id = 0,
-               .ops = &rk808_dcdc_ops,
-               .n_voltages = ARRAY_SIZE(buck_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_DCDC2",
-               .id = 1,
-               .ops = &rk808_dcdc_ops,
-               .n_voltages = ARRAY_SIZE(buck_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_DCDC3",
-               .id = 2,
-               .ops = &rk808_dcdc_ops,
-               .n_voltages = ARRAY_SIZE(buck4_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_DCDC4",
-               .id = 3,
-               .ops = &rk808_dcdc_ops,
-               .n_voltages = ARRAY_SIZE(buck4_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-
-       {
-               .name = "RK_LDO1",
-               .id =4,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_LDO2",
-               .id = 5,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_LDO3",
-               .id = 6,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(ldo3_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_LDO4",
-               .id = 7,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-
-       {
-               .name = "RK_LDO5",
-               .id =8,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_LDO6",
-               .id = 9,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(ldo6_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_LDO7",
-               .id = 10,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(ldo6_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_LDO8",
-               .id = 11,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(ldo_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_LDO9",
-               .id = 12,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(buck4_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "RK_LDO10",
-               .id = 13,
-               .ops = &rk808_ldo_ops,
-               .n_voltages = ARRAY_SIZE(buck4_voltage_map),
-               .type = REGULATOR_VOLTAGE,
-               .owner = THIS_MODULE,
-       },
-       
-};
-
-/*
- *
- */
- int rk808_i2c_read(struct rk808 *rk808, char reg, int count,u8 *dest)
-{
-       struct i2c_client *i2c = rk808->i2c;
-       int ret;
-    struct i2c_adapter *adap;
-    struct i2c_msg msgs[2];
-
-    if(!i2c)
-               return ret;
-
-       if (count != 1)
-               return -EIO;  
-  
-    adap = i2c->adapter;               
-    
-    msgs[0].addr = i2c->addr;
-    msgs[0].buf = &reg;
-    msgs[0].flags = i2c->flags;
-    msgs[0].len = 1;
-    msgs[0].scl_rate = 100*1000;
-    
-    msgs[1].buf = (u8 *)dest;
-    msgs[1].addr = i2c->addr;
-    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[1].buf));
-    return ret;
-}
-
-int rk808_i2c_write(struct rk808 *rk808, char reg, int count,  const u8 src)
-{
-       int ret=-1;
-       struct i2c_client *i2c = rk808->i2c;
-       struct i2c_adapter *adap;
-       struct i2c_msg msg;
-       char tx_buf[2];
-
-       if(!i2c)
-               return ret;
-       if (count != 1)
-               return -EIO;
-    
-       adap = i2c->adapter;            
-       tx_buf[0] = reg;
-       tx_buf[1] = src;
-       
-       msg.addr = i2c->addr;
-       msg.buf = &tx_buf[0];
-       msg.len = 1 +1;
-       msg.flags = i2c->flags;   
-       msg.scl_rate = 100*1000;        
-
-       ret = i2c_transfer(adap, &msg, 1);
-       return ret;     
-}
-
-int rk808_reg_read(struct rk808 *rk808, u8 reg)
-{
-       u8 val = 0;
-       int ret;
-
-       mutex_lock(&rk808->io_lock);
-
-       ret = rk808_i2c_read(rk808, reg, 1, &val);
-       DBG("reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)val&0xff);
-       if (ret < 0){
-                mutex_unlock(&rk808->io_lock);
-                return ret;
-       }
-       mutex_unlock(&rk808->io_lock);
-
-       return val & 0xff;      
-}
-EXPORT_SYMBOL_GPL(rk808_reg_read);
-
-int rk808_reg_write(struct rk808 *rk808, u8 reg, u8 val)
-{
-       int err =0;
-
-       mutex_lock(&rk808->io_lock);
-
-       err = rk808_i2c_write(rk808, reg, 1,val);
-       if (err < 0)
-               dev_err(rk808->dev, "Write for reg 0x%x failed\n", reg);
-
-       mutex_unlock(&rk808->io_lock);
-       return err;
-}
-EXPORT_SYMBOL_GPL(rk808_reg_write);
-
- int rk808_set_bits(struct rk808 *rk808, u8 reg, u8 mask, u8 val)
-{
-       u8 tmp;
-       int ret;
-
-       mutex_lock(&rk808->io_lock);
-
-       ret = rk808_i2c_read(rk808, reg, 1, &tmp);
-       DBG("1 reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)tmp&0xff);
-       if (ret < 0){
-                mutex_unlock(&rk808->io_lock);
-                return ret;
-       }
-       tmp = (tmp & ~mask) | val;
-       ret = rk808_i2c_write(rk808, reg, 1, tmp);
-       DBG("reg write 0x%02x -> 0x%02x\n", (int)reg, (unsigned)val&0xff);
-       if (ret < 0){
-                mutex_unlock(&rk808->io_lock);
-                return ret;
-       }
-       ret = rk808_i2c_read(rk808, reg, 1, &tmp);
-       if (ret < 0){
-                mutex_unlock(&rk808->io_lock);
-                return ret;
-       }
-       DBG("2 reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)tmp&0xff);
-       mutex_unlock(&rk808->io_lock);
-
-       return 0;//ret; 
-}
-EXPORT_SYMBOL_GPL(rk808_set_bits);
-
-int rk808_clear_bits(struct rk808 *rk808, u8 reg, u8 mask)
-{
-       u8 data;
-       int err;
-
-       mutex_lock(&rk808->io_lock);
-       err = rk808_i2c_read(rk808, reg, 1, &data);
-       if (err <0) {
-               dev_err(rk808->dev, "read from reg %x failed\n", reg);
-               goto out;
-       }
-
-       data &= ~mask;
-       err = rk808_i2c_write(rk808, reg, 1, data);
-       if (err <0)
-               dev_err(rk808->dev, "write to reg %x failed\n", reg);
-
-out:
-       mutex_unlock(&rk808->io_lock);
-       return err;
-}
-EXPORT_SYMBOL_GPL(rk808_clear_bits);
-#if 0
-int rk808_bulk_read(struct rk808 *rk808, u8 reg,
-                    int count, u8 *buf)
-{
-       int ret;
-                    
-#if defined(CONFIG_MFD_RK610)    
-       int i;             //Solve communication conflict when rk610 and rk808 on the same i2c 
-
-       mutex_lock(&rk808->io_lock);
-       for(i=0; i<count; i++){
-               ret = rk808_reg_read(rk808, reg+i);
-               if(ret < 0){
-                       printk("%s: failed read reg 0x%0x, ret = %d\n", __FUNCTION__, reg+i, ret);
-                       mutex_unlock(&rk808->io_lock);
-                       return ret;
-               }else{
-                       buf[i] = ret & 0x000000FF;
-               }
-       }
-       mutex_unlock(&rk808->io_lock);
-#else
-       mutex_lock(&rk808->io_lock);
-       
-       ret = rk808->read(rk808, reg, count, buf);
-
-       mutex_unlock(&rk808->io_lock);
-#endif
-       return 0;
-
-}
-EXPORT_SYMBOL_GPL(rk808_bulk_read);
-
-int rk808_bulk_write(struct rk808 *rk808, u8 reg,
-                    int count, u8 *buf)
-{
-       int ret;
-       
-#if defined(CONFIG_MFD_RK610)    
-       int i;       // //Solve communication conflict when rk610 and 808 on the same i2c 
-
-       mutex_lock(&rk808->io_lock);
-       for(i=0; i<count; i++){
-               ret = rk808_reg_write(rk808, reg+i, buf[i]);
-               if(ret < 0){
-                       printk("%s: failed write reg=0x%0x, val=0x%0x, ret = %d\n", __FUNCTION__, reg+i, buf[i], ret);
-                       mutex_unlock(&rk808->io_lock);
-                       return ret;
-               }
-       }
-       mutex_unlock(&rk808->io_lock);
-#else
-       mutex_lock(&rk808->io_lock);
-       
-       ret = rk808->write(rk808, reg, count, buf);
-
-       mutex_unlock(&rk808->io_lock);
-#endif
-       return 0;
-
-}
-EXPORT_SYMBOL_GPL(rk808_bulk_write);
-#endif
-
-#if 1
-static ssize_t rk808_test_store(struct kobject *kobj, struct kobj_attribute *attr,
-                                const char *buf, size_t n)
-{
-    u32 getdata[8];
-    u8 regAddr;
-    u8 data;
-    char cmd;
-    const char *buftmp = buf;
-    struct rk808 *rk808 = g_rk808;
-    /**
-     * W Addr(8Bit) regAddr(8Bit) data0(8Bit) data1(8Bit) data2(8Bit) data3(8Bit)
-     *                 :data can be less than 4 byte
-     * R regAddr(8Bit)
-     * C gpio_name(poweron/powerhold/sleep/boot0/boot1) value(H/L)
-     */
-       sscanf(buftmp, "%c ", &cmd);
-       printk("------zhangqing: get cmd = %c\n", cmd);
-       switch (cmd) {
-       case 'w':
-               sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0], &getdata[1]);
-               regAddr = (u8)(getdata[0] & 0xff);
-               data = (u8)(getdata[1] & 0xff);
-               printk("get value = %x\n", data);
-
-               rk808_i2c_write(rk808, regAddr, 1, data);
-               rk808_i2c_read(rk808, regAddr, 1, &data);
-               printk("%x   %x\n", getdata[1], data);
-               break;
-       case 'r':
-               sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
-               printk("CMD : %c %x\n", cmd, getdata[0]);
-
-               regAddr = (u8)(getdata[0] & 0xff);
-               rk808_i2c_read(rk808, regAddr, 1, &data);
-               printk("%x %x\n", getdata[0], data);
-               break;
-       default:
-               printk("Unknown command\n");
-               break;
-       }
-       return n;
-
-}
-static ssize_t rk808_test_show(struct kobject *kobj, struct kobj_attribute *attr,
-                               char *buf)
-{
-   char *s = buf;
-    buf = "hello";
-    return sprintf(s, "%s\n", buf);
-
-}
-
-static struct kobject *rk808_kobj;
-struct rk808_attribute {
-       struct attribute        attr;
-       ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
-                       char *buf);
-       ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
-                       const char *buf, size_t n);
-};
-
-static struct rk808_attribute rk808_attrs[] = {
-       /*     node_name        permision               show_func       store_func */
-       __ATTR(rk808_test,      S_IRUGO | S_IWUSR,      rk808_test_show,        rk808_test_store),
-};
-#endif
-#if 0
-extern void rk_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));
-//     rk_send_wakeup_key();
-        return IRQ_HANDLED;
-}
-#endif
-#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 },
-       { .name = "rk_ldo9", .driver_data = (void *)12 },
-       { .name = "rk_ldo10", .driver_data = (void *)13 },
-};
-
-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;
-       }
-
-       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;
-               }
-
-       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);
-               }
-       pdata->pmic_sleep = true;
-       
-       pdata->pm_off = of_property_read_bool(rk808_pmic_np,"rk808,system-power-controller");
-               
-       return pdata;
-}
-
-#else
-static struct rk808_board *rk808_parse_dt(struct i2c_client *i2c)
-{
-       return NULL;
-}
-#endif
-static void rk808_shutdown(void)
-{
-       int ret,i,val;
-       u16 reg = 0;
-       struct rk808 *rk808 = g_rk808;
-       
-       printk("%s\n",__func__);
-       /***************get dc1\dc2 voltage *********************/
-       for(i=0;i<2;i++){
-       reg = rk808_reg_read(rk808,rk808_BUCK_SET_VOL_REG(i));
-       reg &= BUCK_VOL_MASK;
-       val = 712500 + reg * 12500;
-       printk("%s,line=%d dc[%d]= %d\n", __func__,__LINE__,(i+1),val);
-       }
-       /*****************************************************/
-       ret = rk808_set_bits(rk808, RK808_INT_STS_MSK_REG1,(0x3<<5),(0x3<<5)); //close rtc int when power off
-       ret = rk808_clear_bits(rk808, RK808_RTC_INT_REG,(0x3<<2)); //close rtc int when power off
-       mutex_lock(&rk808->io_lock);
-       mdelay(100);
-}
-
-static struct syscore_ops rk808_syscore_ops = {
-       .shutdown = rk808_shutdown,
-};
-
-static void rk808_device_shutdown(void)
-{
-       int ret,i;
-       u8 reg = 0;
-       struct rk808 *rk808 = g_rk808;
-       for(i=0;i < 10;i++){
-               printk("%s\n",__func__);
-               ret = rk808_i2c_read(rk808,RK808_DEVCTRL_REG,1,&reg);
-               if(ret < 0)
-                       continue;
-               ret = rk808_i2c_write(rk808, RK808_DEVCTRL_REG, 1,(reg |(0x1 <<3)));
-               if (ret < 0) {
-                       printk("rk808 power off error!\n");
-                       continue;
-               }
-       }
-       while(1)wfi();  
-}
-EXPORT_SYMBOL_GPL(rk808_device_shutdown);
-
-__weak void  rk808_device_suspend(void) {}
-__weak void  rk808_device_resume(void) {}
-#ifdef CONFIG_PM
-static int rk808_suspend(struct device *dev)
-{              
-       rk808_device_suspend();
-       return 0;
-}
-
-static int rk808_resume(struct device *dev)
-{
-       rk808_device_resume();
-       return 0;
-}
-#else
-static int rk808_suspend(struct device *dev)
-{              
-       return 0;
-}
-
-static int rk808_resume(struct device *dev)
-{
-       return 0;
-}
-#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 rk808_pre_init(struct rk808 *rk808)
-{
-       int ret,val;
-        printk("%s,line=%d\n", __func__,__LINE__);
-        /**********disable dcdc uv func****************/
-        ret = rk808_reg_write(rk808,RK808_DCDC_UV_ACT_REG,0x10);
-         if (ret <0) {
-                printk(KERN_ERR "Unable to write RK808_DCDC_UV_ACT_REG reg\n");
-                return ret;
-        }
-       /**********************************/
-        /***********set ILIM ************/
-       val = rk808_reg_read(rk808,RK808_BUCK3_CONFIG_REG);
-       val &= (~(0x7 <<0));
-       val |= (0x2 <<0);
-       ret = rk808_reg_write(rk808,RK808_BUCK3_CONFIG_REG,val);
-       if (ret < 0) {
-                printk(KERN_ERR "Unable to write RK808_BUCK3_CONFIG_REG reg\n");
-                return ret;
-        }
-
-       val = rk808_reg_read(rk808,RK808_BUCK4_CONFIG_REG);
-       val &= (~(0x7 <<0));
-       val |= (0x3 <<0);
-       ret = rk808_reg_write(rk808,RK808_BUCK4_CONFIG_REG,val);
-       if (ret < 0) {
-                printk(KERN_ERR "Unable to write RK808_BUCK4_CONFIG_REG reg\n");
-                return ret;
-        }
-       
-       val = rk808_reg_read(rk808,RK808_BOOST_CONFIG_REG);
-       val &= (~(0x7 <<0));
-       val |= (0x1 <<0);
-       ret = rk808_reg_write(rk808,RK808_BOOST_CONFIG_REG,val);
-       if (ret < 0) {
-                printk(KERN_ERR "Unable to write RK808_BOOST_CONFIG_REG reg\n");
-                return ret;
-        }
-       /*****************************************/
-       /***********set buck OTP function************/
-       ret = rk808_reg_write(rk808,0x6f,0x5a);
-       if (ret < 0) {
-                printk(KERN_ERR "Unable to write 0x6f reg\n");
-                return ret;
-        }
-       
-       ret = rk808_reg_write(rk808,0x91,0x80);
-       if (ret < 0) {
-                printk(KERN_ERR "Unable to write 0x91 reg\n");
-                return ret;
-        }
-
-        ret = rk808_reg_write(rk808,0x92,0x55);
-        if (ret <0) {
-                printk(KERN_ERR "Unable to write 0x92 reg\n");
-                return ret;
-        }
-       /*****************************************/
-       /***********set buck 12.5mv/us ************/
-       val = rk808_reg_read(rk808,RK808_BUCK1_CONFIG_REG);
-       val &= (~(0x3 <<3));
-       val |= (0x3 <<0);
-       ret = rk808_reg_write(rk808,RK808_BUCK1_CONFIG_REG,val);
-       if (ret < 0) {
-                printk(KERN_ERR "Unable to write RK808_BUCK1_CONFIG_REG reg\n");
-                return ret;
-        }
-
-       val = rk808_reg_read(rk808,RK808_BUCK2_CONFIG_REG);
-        val &= (~(0x3 <<3));
-       val |= (0x3 <<0);
-        ret = rk808_reg_write(rk808,RK808_BUCK2_CONFIG_REG,val);
-        if (ret <0) {
-                printk(KERN_ERR "Unable to write RK808_BUCK2_CONFIG_REG reg\n");
-                return ret;
-        }
-       /*****************************************/
-
-       /*******enable switch and boost***********/
-       val = rk808_reg_read(rk808,RK808_DCDC_EN_REG);
-        val |= (0x3 << 5);    //enable switch1/2
-       val |= (0x1 << 4);    //enable boost
-        ret = rk808_reg_write(rk808,RK808_DCDC_EN_REG,val);
-         if (ret <0) {
-                printk(KERN_ERR "Unable to write RK808_DCDC_EN_REG reg\n");
-                return ret;
-       }
-       /****************************************/
-       
-       /****************set vbat low **********/
-       val = rk808_reg_read(rk808,RK808_VB_MON_REG);
-       val &=(~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
-       val |= (RK808_VBAT_LOW_3V5 | EN_VBAT_LOW_IRQ);
-       ret = rk808_reg_write(rk808,RK808_VB_MON_REG,val);
-         if (ret <0) {
-                printk(KERN_ERR "Unable to write RK818_VB_MON_REG reg\n");
-                return ret;
-        }
-       /**************************************/
-       
-       /**********mask int****************/
-        val = rk808_reg_read(rk808,RK808_INT_STS_MSK_REG1);
-         val |= (0x1<<0); //mask vout_lo_int    
-        ret = rk808_reg_write(rk808,RK808_INT_STS_MSK_REG1,val);
-         if (ret <0) {
-                printk(KERN_ERR "Unable to write RK808_INT_STS_MSK_REG1 reg\n");
-                return ret;
-        }
-       /**********************************/
-       /**********enable clkout2****************/
-        ret = rk808_reg_write(rk808,RK808_CLK32OUT_REG,0x01);
-         if (ret <0) {
-                printk(KERN_ERR "Unable to write RK808_CLK32OUT_REG reg\n");
-                return ret;
-        }
-       /**********************************/
-       ret = rk808_clear_bits(rk808, RK808_INT_STS_MSK_REG1,(0x3<<5)); //open rtc int when power on
-       ret = rk808_set_bits(rk808, RK808_RTC_INT_REG,(0x1<<3),(0x1<<3)); //open rtc int when power on
-
-       return 0;
-}
-
-static int rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
-{
-       struct rk808 *rk808;    
-       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,i=0;
-//     int vlow_irq;
-       
-       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 = devm_kzalloc(&i2c->dev,sizeof(struct rk808), GFP_KERNEL);
-       if (rk808 == NULL) {
-               ret = -ENOMEM;          
-               goto err;
-       }
-       rk808->i2c = i2c;
-       rk808->dev = &i2c->dev;
-       i2c_set_clientdata(i2c, rk808);
-//     rk808->read = rk808_i2c_read;
-//     rk808->write = rk808_i2c_write;
-
-       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 %d\n",ret);
-               goto err;
-       }
-
-       ret = rk808_pre_init(rk808);
-       if (ret < 0){
-               printk("The rk808_pre_init failed %d\n",ret);
-               goto err;
-       }
-
-       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 (gpio_is_valid(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_output(rk808->pmic_sleep_gpio,0);
-                       ret = gpio_get_value(rk808->pmic_sleep_gpio);
-                       gpio_free(rk808->pmic_sleep_gpio);
-                       pr_info("%s: rk808_pmic_sleep=%x\n", __func__, ret);
-       }       
-       #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;
-
-               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;
-               }
-       }
-
-//     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);
-       #if 0   
-       /********************vbat low int**************/
-       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",
-                        vlow_irq+ RK808_IRQ_VB_LO, ret);
-
-        }
-       #endif
-       /*********************************************/
-       
-       g_rk808 = rk808;
-       if (pdev->pm_off && !pm_power_off) {
-               pm_power_off = rk808_device_shutdown;
-       }
-
-       #ifdef CONFIG_HAS_EARLYSUSPEND
-       rk808->rk808_suspend.suspend = rk808_early_suspend,
-       rk808->rk808_suspend.resume = rk808_late_resume,
-       rk808->rk808_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1,
-       register_early_suspend(&rk808->rk808_suspend);
-       #endif
-
-       #if 1
-       rk808_kobj = kobject_create_and_add("rk808", NULL);
-       if (!rk808_kobj)
-               return -ENOMEM;
-       for (i = 0; i < ARRAY_SIZE(rk808_attrs); i++) {
-               ret = sysfs_create_file(rk808_kobj, &rk808_attrs[i].attr);
-               if (ret != 0) {
-                       printk("create index %d error\n", i);
-                       return ret;
-               }
-       }
-       #endif
-
-       register_syscore_ops(&rk808_syscore_ops);
-       
-       return 0;
-
-err:
-       mfd_remove_devices(rk808->dev);
-       return ret;     
-
-}
-
-static int rk808_i2c_remove(struct i2c_client *i2c)
-{
-       struct rk808 *rk808 = i2c_get_clientdata(i2c);
-       int i;
-
-       unregister_syscore_ops(&rk808_syscore_ops);
-       for (i = 0; i < rk808->num_regulators; i++)
-               if (rk808->rdev[i])
-                       regulator_unregister(rk808->rdev[i]);
-       kfree(rk808->rdev);
-       i2c_set_clientdata(i2c, NULL);
-
-       return 0;
-}
-
-static const struct dev_pm_ops rk808_pm_ops = {
-       .suspend = rk808_suspend,
-       .resume =  rk808_resume,
-};
-
-static const struct i2c_device_id rk808_i2c_id[] = {
-       { "rk808", 0 },
-       { }
-};
-
-MODULE_DEVICE_TABLE(i2c, rk808_i2c_id);
-
-static struct i2c_driver rk808_i2c_driver = {
-       .driver = {
-               .name = "rk808",
-               .owner = THIS_MODULE,
-               #ifdef CONFIG_PM
-               .pm = &rk808_pm_ops,
-               #endif
-               .of_match_table =of_match_ptr(rk808_of_match),
-       },
-       .probe    = rk808_i2c_probe,
-       .remove   = rk808_i2c_remove,
-       .id_table = rk808_i2c_id,
-};
-
-static int __init rk808_module_init(void)
-{
-       int ret;
-       ret = i2c_add_driver(&rk808_i2c_driver);
-       if (ret != 0)
-               pr_err("Failed to register I2C driver: %d\n", ret);
-       return ret;
-}
-//module_init(rk808_module_init);
-//subsys_initcall(rk808_module_init);
-//rootfs_initcall(rk808_module_init);
-subsys_initcall_sync(rk808_module_init);
-
-static void __exit rk808_module_exit(void)
-{
-       i2c_del_driver(&rk808_i2c_driver);
-}
-module_exit(rk808_module_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
-MODULE_DESCRIPTION("rk808 PMIC driver");
-
diff --git a/drivers/rtc/rtc-rk-rk808.c b/drivers/rtc/rtc-rk-rk808.c
new file mode 100644 (file)
index 0000000..c396f36
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ *     Real Time Clock driver for  rk808
+ *
+ *  Author: zhangqing <zhangqing@rock-chips.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+#include <linux/bcd.h>
+#include <linux/interrupt.h>
+#include <linux/ioctl.h>
+#include <linux/completion.h>
+#include <linux/mfd/rk808.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/irqdomain.h>
+
+
+/* RTC Definitions */
+/* RTC_CTRL_REG bitfields */
+#define BIT_RTC_CTRL_REG_STOP_RTC_M            0x01
+#define BIT_RTC_CTRL_REG_ROUND_30S_M           0x02
+#define BIT_RTC_CTRL_REG_AUTO_COMP_M           0x04
+#define BIT_RTC_CTRL_REG_MODE_12_24_M          0x08
+#define BIT_RTC_CTRL_REG_TEST_MODE_M           0x10
+#define BIT_RTC_CTRL_REG_SET_32_COUNTER_M      0x20
+#define BIT_RTC_CTRL_REG_GET_TIME_M            0x40
+#define BIT_RTC_CTRL_REG_RTC_V_OPT_M           0x80
+
+/* RTC_STATUS_REG bitfields */
+#define BIT_RTC_STATUS_REG_RUN_M               0x02
+#define BIT_RTC_STATUS_REG_1S_EVENT_M          0x04
+#define BIT_RTC_STATUS_REG_1M_EVENT_M          0x08
+#define BIT_RTC_STATUS_REG_1H_EVENT_M          0x10
+#define BIT_RTC_STATUS_REG_1D_EVENT_M          0x20
+#define BIT_RTC_STATUS_REG_ALARM_M             0x40
+#define BIT_RTC_STATUS_REG_POWER_UP_M          0x80
+
+/* RTC_INTERRUPTS_REG bitfields */
+#define BIT_RTC_INTERRUPTS_REG_EVERY_M         0x03
+#define BIT_RTC_INTERRUPTS_REG_IT_TIMER_M      0x04
+#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M      0x08
+
+/* DEVCTRL bitfields */
+#define BIT_RTC_PWDN                           0x40
+
+/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
+#define ALL_TIME_REGS                          7
+#define ALL_ALM_REGS                           6
+
+
+#define RTC_SET_TIME_RETRIES   5
+#define RTC_GET_TIME_RETRIES   5
+
+
+struct rk808_rtc {
+       struct rk808 *rk808;
+       struct rtc_device *rtc;
+       unsigned int alarm_enabled:1;
+};
+
+/*
+ * Read current time and date in RTC
+ */
+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;
+       unsigned char rtc_data[ALL_TIME_REGS + 1];
+       u8 rtc_ctl;
+
+       /*Dummy read*/  
+       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
+       
+       /* Has the RTC been programmed? */
+       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
+       if (ret < 0) {
+               dev_err(dev, "Failed to read RTC control: %d\n", ret);
+               return ret;
+       }
+
+       rtc_ctl = ret & (~BIT_RTC_CTRL_REG_RTC_V_OPT_M);
+
+       ret = rk808_reg_write(rk808, RK808_RTC_CTRL_REG, rtc_ctl);
+       if (ret < 0) {
+               dev_err(dev, "Failed to write RTC control: %d\n", ret);
+               return ret;
+       }
+
+#if 0  
+       /* Read twice to make sure we don't read a corrupt, partially
+        * incremented, value.
+        */
+       do {
+               ret = rk808_bulk_read(rk808, RK808_SECONDS_REG,
+                                      ALL_TIME_REGS, rtc_data);
+               if (ret != 0)
+                       continue;
+
+               tm->tm_sec = bcd2bin(rtc_data[0]);
+               tm->tm_min = bcd2bin(rtc_data[1]);
+               tm->tm_hour = bcd2bin(rtc_data[2]) ;
+               tm->tm_mday = bcd2bin(rtc_data[3]);
+               tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
+               tm->tm_year = bcd2bin(rtc_data[5]) + 100;       
+               tm->tm_wday = bcd2bin(rtc_data[6]);
+
+               printk( "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+                       1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,
+                       tm->tm_hour, tm->tm_min, tm->tm_sec);
+               
+               return ret;
+
+       } while (++count < RTC_GET_TIME_RETRIES);
+       dev_err(dev, "Timed out reading current time\n");
+#else
+       rtc_data[0] = rk808_reg_read(rk808,0x00);
+       rtc_data[1] = rk808_reg_read(rk808,0x01);
+       rtc_data[2] = rk808_reg_read(rk808,0x02);
+       rtc_data[3] = rk808_reg_read(rk808,0x03);
+       rtc_data[4] = rk808_reg_read(rk808,0x04);
+       rtc_data[5] = rk808_reg_read(rk808,0x05);
+       rtc_data[6] = rk808_reg_read(rk808,0x06);
+       
+        tm->tm_sec = bcd2bin(rtc_data[0]);
+         tm->tm_min = bcd2bin(rtc_data[1]);
+         tm->tm_hour = bcd2bin(rtc_data[2]) ;
+         tm->tm_mday = bcd2bin(rtc_data[3]);
+         tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
+         tm->tm_year = bcd2bin(rtc_data[5]) + 100;       
+         tm->tm_wday = bcd2bin(rtc_data[6]);
+
+         dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+                        1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,tm->tm_hour , tm->tm_min, tm->tm_sec);
+
+#endif
+       return 0;
+
+}
+
+/*
+ * Set current time and date in RTC
+ */
+static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
+       struct rk808 *rk808 = rk808_rtc->rk808;
+       int ret;
+       u8 rtc_ctl;     
+       unsigned char rtc_data[ALL_TIME_REGS + 1];
+       
+       rtc_data[0] = bin2bcd(tm->tm_sec);
+       rtc_data[1] = bin2bcd(tm->tm_min);
+       rtc_data[2] = bin2bcd(tm->tm_hour );
+       rtc_data[3] = bin2bcd(tm->tm_mday);
+       rtc_data[4] = bin2bcd(tm->tm_mon + 1);
+       rtc_data[5] = bin2bcd(tm->tm_year - 100);
+       rtc_data[6] = bin2bcd(tm->tm_wday);
+
+        dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+                        1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,tm->tm_hour , tm->tm_min, tm->tm_sec);
+
+       /*Dummy read*/  
+       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
+       
+       /* Stop RTC while updating the TC registers */
+       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
+       if (ret < 0) {
+               dev_err(dev, "Failed to read RTC control: %d\n", ret);
+               return ret;
+       }
+       
+       rtc_ctl = ret | (BIT_RTC_CTRL_REG_STOP_RTC_M);
+
+       ret = rk808_reg_write(rk808, RK808_RTC_CTRL_REG, rtc_ctl);
+       if (ret < 0) {
+               dev_err(dev, "Failed to write RTC control: %d\n", ret);
+               return ret;
+       }
+#if 0  
+       /* update all the time registers in one shot */
+       ret = rk808_bulk_write(rk808, RK808_SECONDS_REG,
+                                      ALL_TIME_REGS, rtc_data);
+       if (ret < 0) {
+               dev_err(dev, "Failed to read RTC times: %d\n", ret);
+               return ret;
+       }
+#else
+       rk808_reg_write(rk808,0x00,rtc_data[0]);
+       rk808_reg_write(rk808,0x01,rtc_data[1]);
+       rk808_reg_write(rk808,0x02,rtc_data[2]);
+       rk808_reg_write(rk808,0x03,rtc_data[3]);
+       rk808_reg_write(rk808,0x04,rtc_data[4]);
+       rk808_reg_write(rk808,0x05,rtc_data[5]);
+       rk808_reg_write(rk808,0x06,rtc_data[6]);
+
+#endif 
+       /*Dummy read*/  
+       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
+       
+       /* Start RTC again */
+       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
+       if (ret < 0) {
+               dev_err(dev, "Failed to read RTC control: %d\n", ret);
+               return ret;
+       }
+       
+       rtc_ctl = ret &(~ BIT_RTC_CTRL_REG_STOP_RTC_M);
+
+       ret = rk808_reg_write(rk808, RK808_RTC_CTRL_REG, rtc_ctl);
+       if (ret < 0) {
+               dev_err(dev, "Failed to write RTC control: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+/*
+ * Read alarm time and date in RTC
+ */
+static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
+       int ret;
+       unsigned char alrm_data[ALL_ALM_REGS + 1];
+#if 0
+       ret = rk808_bulk_read(rk808_rtc->rk808, RK808_ALARM_SECONDS_REG,
+                              ALL_ALM_REGS, alrm_data);
+       if (ret != 0) {
+               dev_err(dev, "Failed to read alarm time: %d\n", ret);
+               return ret;
+       }
+#else
+       alrm_data[0] = rk808_reg_read(rk808_rtc->rk808,0x08);
+        alrm_data[1] = rk808_reg_read(rk808_rtc->rk808,0x09);
+        alrm_data[2] = rk808_reg_read(rk808_rtc->rk808,0x0a);
+        alrm_data[3] = rk808_reg_read(rk808_rtc->rk808,0x0b);
+        alrm_data[4] = rk808_reg_read(rk808_rtc->rk808,0x0c);
+        alrm_data[5] = rk808_reg_read(rk808_rtc->rk808,0x0d);
+
+       
+#endif
+       /* some of these fields may be wildcard/"match all" */
+       alrm->time.tm_sec = bcd2bin(alrm_data[0]);
+       alrm->time.tm_min = bcd2bin(alrm_data[1]);
+       alrm->time.tm_hour = bcd2bin(alrm_data[2]);
+       alrm->time.tm_mday = bcd2bin(alrm_data[3]);
+       alrm->time.tm_mon = bcd2bin(alrm_data[4]) - 1;
+       alrm->time.tm_year = bcd2bin(alrm_data[5]) + 100;
+
+       ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_INT_REG);
+       if (ret < 0) {
+               dev_err(dev, "Failed to read RTC control: %d\n", ret);
+               return ret;
+       }
+       dev_dbg(dev,"alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+                        1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, alrm->time.tm_min, alrm->time.tm_sec);
+
+
+
+       if (ret & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
+               alrm->enabled = 1;
+       else
+               alrm->enabled = 0;
+
+       return 0;
+}
+
+static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
+{
+       rk808_rtc->alarm_enabled = 0;
+
+       return rk808_clear_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,
+                              BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+
+}
+
+static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
+{
+       rk808_rtc->alarm_enabled = 1;
+
+       return rk808_set_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,
+                              BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+
+}
+
+static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
+       int ret;
+       unsigned char alrm_data[ALL_TIME_REGS + 1];
+       
+       ret = rk808_rtc_stop_alarm(rk808_rtc);
+       if (ret < 0) {
+               dev_err(dev, "Failed to stop alarm: %d\n", ret);
+               return ret;
+       }
+
+        dev_dbg(dev,"alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+                        1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, alrm->time.tm_min, alrm->time.tm_sec);
+
+       alrm_data[0] = bin2bcd(alrm->time.tm_sec);
+       alrm_data[1] = bin2bcd(alrm->time.tm_min);
+       alrm_data[2] = bin2bcd(alrm->time.tm_hour );
+       alrm_data[3] = bin2bcd(alrm->time.tm_mday);
+       alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
+       alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
+#if 0
+       ret = rk808_bulk_write(rk808_rtc->rk808, RK808_ALARM_SECONDS_REG,
+                              ALL_ALM_REGS, alrm_data);
+       if (ret != 0) {
+               dev_err(dev, "Failed to read alarm time: %d\n", ret);
+               return ret;
+       }
+#else
+        rk808_reg_write(rk808_rtc->rk808,0x08,alrm_data[0]);
+        rk808_reg_write(rk808_rtc->rk808,0x09,alrm_data[1]);
+        rk808_reg_write(rk808_rtc->rk808,0x0a,alrm_data[2]);
+        rk808_reg_write(rk808_rtc->rk808,0x0b,alrm_data[3]);
+        rk808_reg_write(rk808_rtc->rk808,0x0c,alrm_data[4]);
+        rk808_reg_write(rk808_rtc->rk808,0x0d,alrm_data[5]);
+
+#endif
+       if (alrm->enabled) {
+               ret = rk808_rtc_start_alarm(rk808_rtc);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to start alarm: %d\n", ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int rk808_rtc_alarm_irq_enable(struct device *dev,
+                                      unsigned int enabled)
+{
+       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
+
+       if (enabled)
+               return rk808_rtc_start_alarm(rk808_rtc);
+       else
+               return rk808_rtc_stop_alarm(rk808_rtc);
+}
+
+static int rk808_rtc_update_irq_enable(struct device *dev,
+                                      unsigned int enabled)
+{
+       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
+
+       if (enabled)
+               return rk808_set_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,
+                              BIT_RTC_INTERRUPTS_REG_IT_TIMER_M,BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+       else
+               return rk808_clear_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,
+                              BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+}
+
+/*
+ * We will just handle setting the frequency and make use the framework for
+ * reading the periodic interupts.
+ *
+ * @freq: Current periodic IRQ freq:
+ * bit 0: every second
+ * bit 1: every minute
+ * bit 2: every hour
+ * bit 3: every day
+ */
+#if 0
+static int rk808_rtc_irq_set_freq(struct device *dev, int freq)
+{      
+       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
+       int ret;        
+       u8 rtc_ctl;     
+       
+       if (freq < 0 || freq > 3)
+               return -EINVAL;
+
+       ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_INT_REG);
+       if (ret < 0) {
+               dev_err(dev, "Failed to read RTC interrupt: %d\n", ret);
+               return ret;
+       }
+       
+       rtc_ctl = ret | freq;
+       
+       ret = rk808_reg_write(rk808_rtc->rk808, RK808_RTC_INT_REG, rtc_ctl);
+       if (ret < 0) {
+               dev_err(dev, "Failed to write RTC control: %d\n", ret);
+               return ret;
+       }
+       
+       return ret;
+}
+#endif
+static irqreturn_t rk808_alm_irq(int irq, void *data)
+{
+       struct rk808_rtc *rk808_rtc = data;
+       int ret;
+       u8 rtc_ctl;
+       
+       /*Dummy read -- mandatory for status register*/
+       ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_STATUS_REG);
+       if (ret < 0) {
+               printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+               return ret;
+       }
+               
+       ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_STATUS_REG);
+       if (ret < 0) {
+               printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+               return ret;
+       }
+       rtc_ctl = ret&0xff;
+
+       //The alarm interrupt keeps its low level, until the micro-controller write 1 in the ALARM bit of the RTC_STATUS_REG register.  
+       ret = rk808_reg_write(rk808_rtc->rk808, RK808_RTC_STATUS_REG,rtc_ctl);
+       if (ret < 0) {
+               printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+               return ret;
+       }
+       
+       rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF);
+       
+       printk("%s:irq=%d,rtc_ctl=0x%x\n",__func__,irq,rtc_ctl);
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t rk808_per_irq(int irq, void *data)
+{
+       struct rk808_rtc *rk808_rtc = data;
+       
+       rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_UF);
+
+       //printk("%s:irq=%d\n",__func__,irq);
+       return IRQ_HANDLED;
+}
+
+static const struct rtc_class_ops rk808_rtc_ops = {
+       .read_time = rk808_rtc_readtime,
+       //.set_mmss = rk808_rtc_set_mmss,
+       .set_time = rk808_rtc_set_time,
+       .read_alarm = rk808_rtc_readalarm,
+       .set_alarm = rk808_rtc_setalarm,
+       .alarm_irq_enable = rk808_rtc_alarm_irq_enable,
+       //.update_irq_enable = rk808_rtc_update_irq_enable,
+       //.irq_set_freq = rk808_rtc_irq_set_freq,
+};
+
+#ifdef CONFIG_PM
+/* Turn off the alarm if it should not be a wake source. */
+static int rk808_rtc_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev);
+       int ret;
+       
+       if (rk808_rtc->alarm_enabled && device_may_wakeup(&pdev->dev))
+               ret = rk808_rtc_start_alarm(rk808_rtc);
+       else
+               ret = rk808_rtc_stop_alarm(rk808_rtc);
+
+       if (ret < 0)
+               dev_err(&pdev->dev, "Failed to update RTC alarm: %d\n", ret);
+
+       return 0;
+}
+
+/* Enable the alarm if it should be enabled (in case it was disabled to
+ * prevent use as a wake source).
+ */
+static int rk808_rtc_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev);
+       int ret;
+
+       if (rk808_rtc->alarm_enabled) {
+               ret = rk808_rtc_start_alarm(rk808_rtc);
+               if (ret <0)
+                       dev_err(&pdev->dev,
+                               "Failed to restart RTC alarm: %d\n", ret);
+       }
+
+       return 0;
+}
+
+/* Unconditionally disable the alarm */
+static int rk808_rtc_freeze(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev);
+       int ret;
+       
+       ret = rk808_rtc_stop_alarm(rk808_rtc);
+       if (ret < 0)
+               dev_err(&pdev->dev, "Failed to stop RTC alarm: %d\n", ret);
+
+       return 0;
+}
+#else
+#define rk808_rtc_suspend NULL
+#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;
+       u8 rtc_ctl;
+
+       printk("%s,line=%d\n", __func__,__LINE__);
+
+       rk808_rtc = kzalloc(sizeof(*rk808_rtc), GFP_KERNEL);
+       if (rk808_rtc == NULL)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, rk808_rtc);
+       rk808_rtc->rk808 = rk808;
+       
+       /* Take rtc out of reset */
+       /*
+       ret = rk808_reg_read(rk808, RK808_DEVCTRL);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to read RK808_DEVCTRL: %d\n", ret);
+               return ret;
+       }
+       
+       if(ret & BIT_RTC_PWDN)
+       {
+               rtc_ctl = ret & (~BIT_RTC_PWDN);
+
+               ret = rk808_reg_write(rk808, RK808_DEVCTRL, rtc_ctl);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "Failed to write RTC control: %d\n", ret);
+                       return ret;
+               }
+       }
+       */
+       /*start rtc default*/
+       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to read RTC control: %d\n", ret);
+               return ret;
+       }
+       rtc_ctl = ret & (~BIT_RTC_CTRL_REG_STOP_RTC_M);
+
+       ret = rk808_reg_write(rk808, RK808_RTC_CTRL_REG, rtc_ctl);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to write RTC control: %d\n", ret);
+                       return ret;
+               }
+       
+       ret = rk808_reg_read(rk808, RK808_RTC_STATUS_REG);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to read RTC status: %d\n", ret);
+               return ret;
+       }
+       rk808_reg_write(rk808,RK808_RTC_STATUS_REG,0xfe);       
+       /*set init time*/
+
+       ret = rk808_rtc_readtime(&pdev->dev, &tm);
+       if (ret<0)
+       {
+               dev_err(&pdev->dev, "Failed to read RTC time\n");
+               return ret;
+       }
+
+       ret = rtc_valid_tm(&tm);
+       if (ret) {
+       dev_err(&pdev->dev,"invalid date/time and init time\n");
+               rk808_rtc_set_time(&pdev->dev, &tm_def); // 2012-01-01 12:00:00
+//             DBG( "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",1900 + tm_def.tm_year, tm_def.tm_mon + 1, tm_def.tm_mday, tm_def.tm_wday,tm_def.tm_hour, tm_def.tm_min, tm_def.tm_sec);
+       }
+
+       device_init_wakeup(&pdev->dev, 1);
+
+       rk808_rtc->rtc = rtc_device_register("rk808", &pdev->dev,
+                                             &rk808_rtc_ops, THIS_MODULE);
+       if (IS_ERR(rk808_rtc->rtc)) {
+               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 = devm_request_threaded_irq(rk808->dev,per_irq, NULL, rk808_per_irq,
+                                  IRQF_TRIGGER_RISING, "RTC period",
+                                  rk808_rtc);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n",
+                       per_irq, ret);
+       }
+
+       ret = devm_request_threaded_irq(rk808->dev,alm_irq, NULL, rk808_alm_irq,
+                                  IRQF_TRIGGER_RISING, "RTC alarm",
+                                  rk808_rtc);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
+                       alm_irq, ret);
+       }
+
+       //for rtc irq test
+       /*
+       rk808_set_bits(rk808_rtc->rk808, RK808_RTC_STATUS_REG,(0x1<< 6),(0x1 <<6));
+       rk808_set_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,0x0c,0x0c);
+       rk808_set_bits(rk808_rtc->rk808,RK808_INT_STS_REG1,(0x3 << 5),(0x3 <<5));
+       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
+       rk808_pdev = pdev;
+       
+       printk("%s:ok\n",__func__);
+       
+       return 0;
+
+err:
+       kfree(rk808_rtc);
+       return ret;
+}
+
+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;
+       int alm_irq = rk808_rtc->rk808->irq_base + RK808_IRQ_RTC_ALARM;
+
+       free_irq(alm_irq, rk808_rtc);
+       free_irq(per_irq, rk808_rtc);
+       rtc_device_unregister(rk808_rtc->rtc);
+       kfree(rk808_rtc);
+
+       return 0;
+}
+
+static const struct dev_pm_ops rk808_rtc_pm_ops = {
+       .suspend = rk808_rtc_suspend,
+       .resume = rk808_rtc_resume,
+
+       .freeze = rk808_rtc_freeze,
+       .thaw = rk808_rtc_resume,
+       .restore = rk808_rtc_resume,
+
+       .poweroff = rk808_rtc_suspend,
+};
+
+static struct platform_driver rk808_rtc_driver = {
+       .probe = rk808_rtc_probe,
+       .remove = rk808_rtc_remove,
+       .driver = {
+               .name = "rk808-rtc",
+               .pm = &rk808_rtc_pm_ops,
+       },
+};
+
+static ssize_t rtc_rk808_test_write(struct file *file, 
+                       const char __user *buf, size_t count, loff_t *offset)
+{
+       char nr_buf[8];
+       int nr = 0, ret;
+       struct platform_device *pdev;   
+       struct rtc_time tm;
+       struct rtc_wkalrm alrm;
+       struct rk808_rtc *rk808_rtc;
+       
+       if(count > 3)
+               return -EFAULT;
+       ret = copy_from_user(nr_buf, buf, count);
+       if(ret < 0)
+               return -EFAULT;
+
+       sscanf(nr_buf, "%d", &nr);
+       if(nr > 5 || nr < 0)
+       {
+               printk("%s:data is error\n",__func__);
+               return -EFAULT;
+       }
+
+       if(!rk808_pdev)
+               return -EFAULT;
+       else
+               pdev = rk808_pdev;
+
+       
+       rk808_rtc = dev_get_drvdata(&pdev->dev);
+       
+       //test rtc time
+       if(nr == 0)
+       {       
+               tm.tm_wday = 6;
+               tm.tm_year = 111;
+               tm.tm_mon = 0;
+               tm.tm_mday = 1;
+               tm.tm_hour = 12;
+               tm.tm_min = 0;
+               tm.tm_sec = 0;
+       
+               ret = rk808_rtc_set_time(&pdev->dev, &tm); // 2011-01-01 12:00:00
+               if (ret)
+               {
+                       dev_err(&pdev->dev, "Failed to set RTC time\n");
+                       return -EFAULT;
+               }
+
+       }
+       
+       /*set init time*/
+       ret = rk808_rtc_readtime(&pdev->dev, &tm);
+       if (ret)
+               dev_err(&pdev->dev, "Failed to read RTC time\n");
+       else
+               dev_info(&pdev->dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+                       1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_wday,
+                       tm.tm_hour, tm.tm_min, tm.tm_sec);
+               
+       if(!ret)
+       printk("%s:ok\n",__func__);
+       else
+       printk("%s:error\n",__func__);
+       
+
+       //test rtc alarm
+       if(nr == 2)
+       {
+               //2000-01-01 00:00:30
+               if(tm.tm_sec < 30)
+               {
+                       alrm.time.tm_sec = tm.tm_sec+30;        
+                       alrm.time.tm_min = tm.tm_min;
+               }
+               else
+               {
+                       alrm.time.tm_sec = tm.tm_sec-30;
+                       alrm.time.tm_min = tm.tm_min+1;
+               }
+               alrm.time.tm_hour = tm.tm_hour;
+               alrm.time.tm_mday = tm.tm_mday;
+               alrm.time.tm_mon = tm.tm_mon;
+               alrm.time.tm_year = tm.tm_year;         
+               rk808_rtc_alarm_irq_enable(&pdev->dev, 1);
+               rk808_rtc_setalarm(&pdev->dev, &alrm);
+
+               dev_info(&pdev->dev, "Set alarm %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+                               1900 + alrm.time.tm_year, alrm.time.tm_mon + 1, alrm.time.tm_mday, alrm.time.tm_wday,
+                               alrm.time.tm_hour, alrm.time.tm_min, alrm.time.tm_sec);
+       }
+
+       
+       if(nr == 3)
+       {       
+               ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_STATUS_REG);
+               if (ret < 0) {
+                       printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+                       return ret;
+               }
+               printk("%s:ret=0x%x\n",__func__,ret&0xff);
+
+               ret = rk808_reg_write(rk808_rtc->rk808, RK808_RTC_STATUS_REG, ret&0xff);
+               if (ret < 0) {
+                       printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+                       return ret;
+               }
+       }
+
+       if(nr == 4)
+       rk808_rtc_update_irq_enable(&pdev->dev, 1);
+
+       if(nr == 5)
+       rk808_rtc_update_irq_enable(&pdev->dev, 0);
+       
+       return count;
+}
+
+static const struct file_operations rtc_rk808_test_fops = {
+       .write = rtc_rk808_test_write,
+};
+
+static struct miscdevice rtc_rk808_test_misc = {
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "rtc_rk808_test",
+       .fops = &rtc_rk808_test_fops,
+};
+
+
+static int __init rk808_rtc_init(void)
+{
+       misc_register(&rtc_rk808_test_misc);
+       return platform_driver_register(&rk808_rtc_driver);
+}
+subsys_initcall_sync(rk808_rtc_init);
+
+static void __exit rk808_rtc_exit(void)
+{      
+        misc_deregister(&rtc_rk808_test_misc);
+       platform_driver_unregister(&rk808_rtc_driver);
+}
+module_exit(rk808_rtc_exit);
+
+MODULE_DESCRIPTION("RTC driver for the rk808 series PMICs");
+MODULE_AUTHOR("ZHANGQING <zhanqging@rock-chips.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:rk808-rtc");
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
deleted file mode 100644 (file)
index c396f36..0000000
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- *     Real Time Clock driver for  rk808
- *
- *  Author: zhangqing <zhangqing@rock-chips.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/rtc.h>
-#include <linux/slab.h>
-#include <linux/bcd.h>
-#include <linux/interrupt.h>
-#include <linux/ioctl.h>
-#include <linux/completion.h>
-#include <linux/mfd/rk808.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/miscdevice.h>
-#include <linux/irqdomain.h>
-
-
-/* RTC Definitions */
-/* RTC_CTRL_REG bitfields */
-#define BIT_RTC_CTRL_REG_STOP_RTC_M            0x01
-#define BIT_RTC_CTRL_REG_ROUND_30S_M           0x02
-#define BIT_RTC_CTRL_REG_AUTO_COMP_M           0x04
-#define BIT_RTC_CTRL_REG_MODE_12_24_M          0x08
-#define BIT_RTC_CTRL_REG_TEST_MODE_M           0x10
-#define BIT_RTC_CTRL_REG_SET_32_COUNTER_M      0x20
-#define BIT_RTC_CTRL_REG_GET_TIME_M            0x40
-#define BIT_RTC_CTRL_REG_RTC_V_OPT_M           0x80
-
-/* RTC_STATUS_REG bitfields */
-#define BIT_RTC_STATUS_REG_RUN_M               0x02
-#define BIT_RTC_STATUS_REG_1S_EVENT_M          0x04
-#define BIT_RTC_STATUS_REG_1M_EVENT_M          0x08
-#define BIT_RTC_STATUS_REG_1H_EVENT_M          0x10
-#define BIT_RTC_STATUS_REG_1D_EVENT_M          0x20
-#define BIT_RTC_STATUS_REG_ALARM_M             0x40
-#define BIT_RTC_STATUS_REG_POWER_UP_M          0x80
-
-/* RTC_INTERRUPTS_REG bitfields */
-#define BIT_RTC_INTERRUPTS_REG_EVERY_M         0x03
-#define BIT_RTC_INTERRUPTS_REG_IT_TIMER_M      0x04
-#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M      0x08
-
-/* DEVCTRL bitfields */
-#define BIT_RTC_PWDN                           0x40
-
-/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
-#define ALL_TIME_REGS                          7
-#define ALL_ALM_REGS                           6
-
-
-#define RTC_SET_TIME_RETRIES   5
-#define RTC_GET_TIME_RETRIES   5
-
-
-struct rk808_rtc {
-       struct rk808 *rk808;
-       struct rtc_device *rtc;
-       unsigned int alarm_enabled:1;
-};
-
-/*
- * Read current time and date in RTC
- */
-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;
-       unsigned char rtc_data[ALL_TIME_REGS + 1];
-       u8 rtc_ctl;
-
-       /*Dummy read*/  
-       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
-       
-       /* Has the RTC been programmed? */
-       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
-       if (ret < 0) {
-               dev_err(dev, "Failed to read RTC control: %d\n", ret);
-               return ret;
-       }
-
-       rtc_ctl = ret & (~BIT_RTC_CTRL_REG_RTC_V_OPT_M);
-
-       ret = rk808_reg_write(rk808, RK808_RTC_CTRL_REG, rtc_ctl);
-       if (ret < 0) {
-               dev_err(dev, "Failed to write RTC control: %d\n", ret);
-               return ret;
-       }
-
-#if 0  
-       /* Read twice to make sure we don't read a corrupt, partially
-        * incremented, value.
-        */
-       do {
-               ret = rk808_bulk_read(rk808, RK808_SECONDS_REG,
-                                      ALL_TIME_REGS, rtc_data);
-               if (ret != 0)
-                       continue;
-
-               tm->tm_sec = bcd2bin(rtc_data[0]);
-               tm->tm_min = bcd2bin(rtc_data[1]);
-               tm->tm_hour = bcd2bin(rtc_data[2]) ;
-               tm->tm_mday = bcd2bin(rtc_data[3]);
-               tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
-               tm->tm_year = bcd2bin(rtc_data[5]) + 100;       
-               tm->tm_wday = bcd2bin(rtc_data[6]);
-
-               printk( "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
-                       1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,
-                       tm->tm_hour, tm->tm_min, tm->tm_sec);
-               
-               return ret;
-
-       } while (++count < RTC_GET_TIME_RETRIES);
-       dev_err(dev, "Timed out reading current time\n");
-#else
-       rtc_data[0] = rk808_reg_read(rk808,0x00);
-       rtc_data[1] = rk808_reg_read(rk808,0x01);
-       rtc_data[2] = rk808_reg_read(rk808,0x02);
-       rtc_data[3] = rk808_reg_read(rk808,0x03);
-       rtc_data[4] = rk808_reg_read(rk808,0x04);
-       rtc_data[5] = rk808_reg_read(rk808,0x05);
-       rtc_data[6] = rk808_reg_read(rk808,0x06);
-       
-        tm->tm_sec = bcd2bin(rtc_data[0]);
-         tm->tm_min = bcd2bin(rtc_data[1]);
-         tm->tm_hour = bcd2bin(rtc_data[2]) ;
-         tm->tm_mday = bcd2bin(rtc_data[3]);
-         tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
-         tm->tm_year = bcd2bin(rtc_data[5]) + 100;       
-         tm->tm_wday = bcd2bin(rtc_data[6]);
-
-         dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
-                        1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,tm->tm_hour , tm->tm_min, tm->tm_sec);
-
-#endif
-       return 0;
-
-}
-
-/*
- * Set current time and date in RTC
- */
-static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
-       struct rk808 *rk808 = rk808_rtc->rk808;
-       int ret;
-       u8 rtc_ctl;     
-       unsigned char rtc_data[ALL_TIME_REGS + 1];
-       
-       rtc_data[0] = bin2bcd(tm->tm_sec);
-       rtc_data[1] = bin2bcd(tm->tm_min);
-       rtc_data[2] = bin2bcd(tm->tm_hour );
-       rtc_data[3] = bin2bcd(tm->tm_mday);
-       rtc_data[4] = bin2bcd(tm->tm_mon + 1);
-       rtc_data[5] = bin2bcd(tm->tm_year - 100);
-       rtc_data[6] = bin2bcd(tm->tm_wday);
-
-        dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
-                        1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_wday,tm->tm_hour , tm->tm_min, tm->tm_sec);
-
-       /*Dummy read*/  
-       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
-       
-       /* Stop RTC while updating the TC registers */
-       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
-       if (ret < 0) {
-               dev_err(dev, "Failed to read RTC control: %d\n", ret);
-               return ret;
-       }
-       
-       rtc_ctl = ret | (BIT_RTC_CTRL_REG_STOP_RTC_M);
-
-       ret = rk808_reg_write(rk808, RK808_RTC_CTRL_REG, rtc_ctl);
-       if (ret < 0) {
-               dev_err(dev, "Failed to write RTC control: %d\n", ret);
-               return ret;
-       }
-#if 0  
-       /* update all the time registers in one shot */
-       ret = rk808_bulk_write(rk808, RK808_SECONDS_REG,
-                                      ALL_TIME_REGS, rtc_data);
-       if (ret < 0) {
-               dev_err(dev, "Failed to read RTC times: %d\n", ret);
-               return ret;
-       }
-#else
-       rk808_reg_write(rk808,0x00,rtc_data[0]);
-       rk808_reg_write(rk808,0x01,rtc_data[1]);
-       rk808_reg_write(rk808,0x02,rtc_data[2]);
-       rk808_reg_write(rk808,0x03,rtc_data[3]);
-       rk808_reg_write(rk808,0x04,rtc_data[4]);
-       rk808_reg_write(rk808,0x05,rtc_data[5]);
-       rk808_reg_write(rk808,0x06,rtc_data[6]);
-
-#endif 
-       /*Dummy read*/  
-       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
-       
-       /* Start RTC again */
-       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
-       if (ret < 0) {
-               dev_err(dev, "Failed to read RTC control: %d\n", ret);
-               return ret;
-       }
-       
-       rtc_ctl = ret &(~ BIT_RTC_CTRL_REG_STOP_RTC_M);
-
-       ret = rk808_reg_write(rk808, RK808_RTC_CTRL_REG, rtc_ctl);
-       if (ret < 0) {
-               dev_err(dev, "Failed to write RTC control: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-/*
- * Read alarm time and date in RTC
- */
-static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
-       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
-       int ret;
-       unsigned char alrm_data[ALL_ALM_REGS + 1];
-#if 0
-       ret = rk808_bulk_read(rk808_rtc->rk808, RK808_ALARM_SECONDS_REG,
-                              ALL_ALM_REGS, alrm_data);
-       if (ret != 0) {
-               dev_err(dev, "Failed to read alarm time: %d\n", ret);
-               return ret;
-       }
-#else
-       alrm_data[0] = rk808_reg_read(rk808_rtc->rk808,0x08);
-        alrm_data[1] = rk808_reg_read(rk808_rtc->rk808,0x09);
-        alrm_data[2] = rk808_reg_read(rk808_rtc->rk808,0x0a);
-        alrm_data[3] = rk808_reg_read(rk808_rtc->rk808,0x0b);
-        alrm_data[4] = rk808_reg_read(rk808_rtc->rk808,0x0c);
-        alrm_data[5] = rk808_reg_read(rk808_rtc->rk808,0x0d);
-
-       
-#endif
-       /* some of these fields may be wildcard/"match all" */
-       alrm->time.tm_sec = bcd2bin(alrm_data[0]);
-       alrm->time.tm_min = bcd2bin(alrm_data[1]);
-       alrm->time.tm_hour = bcd2bin(alrm_data[2]);
-       alrm->time.tm_mday = bcd2bin(alrm_data[3]);
-       alrm->time.tm_mon = bcd2bin(alrm_data[4]) - 1;
-       alrm->time.tm_year = bcd2bin(alrm_data[5]) + 100;
-
-       ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_INT_REG);
-       if (ret < 0) {
-               dev_err(dev, "Failed to read RTC control: %d\n", ret);
-               return ret;
-       }
-       dev_dbg(dev,"alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
-                        1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, alrm->time.tm_min, alrm->time.tm_sec);
-
-
-
-       if (ret & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
-               alrm->enabled = 1;
-       else
-               alrm->enabled = 0;
-
-       return 0;
-}
-
-static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
-{
-       rk808_rtc->alarm_enabled = 0;
-
-       return rk808_clear_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,
-                              BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-
-}
-
-static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
-{
-       rk808_rtc->alarm_enabled = 1;
-
-       return rk808_set_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,
-                              BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-
-}
-
-static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
-       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
-       int ret;
-       unsigned char alrm_data[ALL_TIME_REGS + 1];
-       
-       ret = rk808_rtc_stop_alarm(rk808_rtc);
-       if (ret < 0) {
-               dev_err(dev, "Failed to stop alarm: %d\n", ret);
-               return ret;
-       }
-
-        dev_dbg(dev,"alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
-                        1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, alrm->time.tm_min, alrm->time.tm_sec);
-
-       alrm_data[0] = bin2bcd(alrm->time.tm_sec);
-       alrm_data[1] = bin2bcd(alrm->time.tm_min);
-       alrm_data[2] = bin2bcd(alrm->time.tm_hour );
-       alrm_data[3] = bin2bcd(alrm->time.tm_mday);
-       alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
-       alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
-#if 0
-       ret = rk808_bulk_write(rk808_rtc->rk808, RK808_ALARM_SECONDS_REG,
-                              ALL_ALM_REGS, alrm_data);
-       if (ret != 0) {
-               dev_err(dev, "Failed to read alarm time: %d\n", ret);
-               return ret;
-       }
-#else
-        rk808_reg_write(rk808_rtc->rk808,0x08,alrm_data[0]);
-        rk808_reg_write(rk808_rtc->rk808,0x09,alrm_data[1]);
-        rk808_reg_write(rk808_rtc->rk808,0x0a,alrm_data[2]);
-        rk808_reg_write(rk808_rtc->rk808,0x0b,alrm_data[3]);
-        rk808_reg_write(rk808_rtc->rk808,0x0c,alrm_data[4]);
-        rk808_reg_write(rk808_rtc->rk808,0x0d,alrm_data[5]);
-
-#endif
-       if (alrm->enabled) {
-               ret = rk808_rtc_start_alarm(rk808_rtc);
-               if (ret < 0) {
-                       dev_err(dev, "Failed to start alarm: %d\n", ret);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-static int rk808_rtc_alarm_irq_enable(struct device *dev,
-                                      unsigned int enabled)
-{
-       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
-
-       if (enabled)
-               return rk808_rtc_start_alarm(rk808_rtc);
-       else
-               return rk808_rtc_stop_alarm(rk808_rtc);
-}
-
-static int rk808_rtc_update_irq_enable(struct device *dev,
-                                      unsigned int enabled)
-{
-       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
-
-       if (enabled)
-               return rk808_set_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,
-                              BIT_RTC_INTERRUPTS_REG_IT_TIMER_M,BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-       else
-               return rk808_clear_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,
-                              BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-}
-
-/*
- * We will just handle setting the frequency and make use the framework for
- * reading the periodic interupts.
- *
- * @freq: Current periodic IRQ freq:
- * bit 0: every second
- * bit 1: every minute
- * bit 2: every hour
- * bit 3: every day
- */
-#if 0
-static int rk808_rtc_irq_set_freq(struct device *dev, int freq)
-{      
-       struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
-       int ret;        
-       u8 rtc_ctl;     
-       
-       if (freq < 0 || freq > 3)
-               return -EINVAL;
-
-       ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_INT_REG);
-       if (ret < 0) {
-               dev_err(dev, "Failed to read RTC interrupt: %d\n", ret);
-               return ret;
-       }
-       
-       rtc_ctl = ret | freq;
-       
-       ret = rk808_reg_write(rk808_rtc->rk808, RK808_RTC_INT_REG, rtc_ctl);
-       if (ret < 0) {
-               dev_err(dev, "Failed to write RTC control: %d\n", ret);
-               return ret;
-       }
-       
-       return ret;
-}
-#endif
-static irqreturn_t rk808_alm_irq(int irq, void *data)
-{
-       struct rk808_rtc *rk808_rtc = data;
-       int ret;
-       u8 rtc_ctl;
-       
-       /*Dummy read -- mandatory for status register*/
-       ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_STATUS_REG);
-       if (ret < 0) {
-               printk("%s:Failed to read RTC status: %d\n", __func__, ret);
-               return ret;
-       }
-               
-       ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_STATUS_REG);
-       if (ret < 0) {
-               printk("%s:Failed to read RTC status: %d\n", __func__, ret);
-               return ret;
-       }
-       rtc_ctl = ret&0xff;
-
-       //The alarm interrupt keeps its low level, until the micro-controller write 1 in the ALARM bit of the RTC_STATUS_REG register.  
-       ret = rk808_reg_write(rk808_rtc->rk808, RK808_RTC_STATUS_REG,rtc_ctl);
-       if (ret < 0) {
-               printk("%s:Failed to read RTC status: %d\n", __func__, ret);
-               return ret;
-       }
-       
-       rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF);
-       
-       printk("%s:irq=%d,rtc_ctl=0x%x\n",__func__,irq,rtc_ctl);
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t rk808_per_irq(int irq, void *data)
-{
-       struct rk808_rtc *rk808_rtc = data;
-       
-       rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_UF);
-
-       //printk("%s:irq=%d\n",__func__,irq);
-       return IRQ_HANDLED;
-}
-
-static const struct rtc_class_ops rk808_rtc_ops = {
-       .read_time = rk808_rtc_readtime,
-       //.set_mmss = rk808_rtc_set_mmss,
-       .set_time = rk808_rtc_set_time,
-       .read_alarm = rk808_rtc_readalarm,
-       .set_alarm = rk808_rtc_setalarm,
-       .alarm_irq_enable = rk808_rtc_alarm_irq_enable,
-       //.update_irq_enable = rk808_rtc_update_irq_enable,
-       //.irq_set_freq = rk808_rtc_irq_set_freq,
-};
-
-#ifdef CONFIG_PM
-/* Turn off the alarm if it should not be a wake source. */
-static int rk808_rtc_suspend(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev);
-       int ret;
-       
-       if (rk808_rtc->alarm_enabled && device_may_wakeup(&pdev->dev))
-               ret = rk808_rtc_start_alarm(rk808_rtc);
-       else
-               ret = rk808_rtc_stop_alarm(rk808_rtc);
-
-       if (ret < 0)
-               dev_err(&pdev->dev, "Failed to update RTC alarm: %d\n", ret);
-
-       return 0;
-}
-
-/* Enable the alarm if it should be enabled (in case it was disabled to
- * prevent use as a wake source).
- */
-static int rk808_rtc_resume(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev);
-       int ret;
-
-       if (rk808_rtc->alarm_enabled) {
-               ret = rk808_rtc_start_alarm(rk808_rtc);
-               if (ret <0)
-                       dev_err(&pdev->dev,
-                               "Failed to restart RTC alarm: %d\n", ret);
-       }
-
-       return 0;
-}
-
-/* Unconditionally disable the alarm */
-static int rk808_rtc_freeze(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev);
-       int ret;
-       
-       ret = rk808_rtc_stop_alarm(rk808_rtc);
-       if (ret < 0)
-               dev_err(&pdev->dev, "Failed to stop RTC alarm: %d\n", ret);
-
-       return 0;
-}
-#else
-#define rk808_rtc_suspend NULL
-#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;
-       u8 rtc_ctl;
-
-       printk("%s,line=%d\n", __func__,__LINE__);
-
-       rk808_rtc = kzalloc(sizeof(*rk808_rtc), GFP_KERNEL);
-       if (rk808_rtc == NULL)
-               return -ENOMEM;
-
-       platform_set_drvdata(pdev, rk808_rtc);
-       rk808_rtc->rk808 = rk808;
-       
-       /* Take rtc out of reset */
-       /*
-       ret = rk808_reg_read(rk808, RK808_DEVCTRL);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to read RK808_DEVCTRL: %d\n", ret);
-               return ret;
-       }
-       
-       if(ret & BIT_RTC_PWDN)
-       {
-               rtc_ctl = ret & (~BIT_RTC_PWDN);
-
-               ret = rk808_reg_write(rk808, RK808_DEVCTRL, rtc_ctl);
-               if (ret < 0) {
-                       dev_err(&pdev->dev, "Failed to write RTC control: %d\n", ret);
-                       return ret;
-               }
-       }
-       */
-       /*start rtc default*/
-       ret = rk808_reg_read(rk808, RK808_RTC_CTRL_REG);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to read RTC control: %d\n", ret);
-               return ret;
-       }
-       rtc_ctl = ret & (~BIT_RTC_CTRL_REG_STOP_RTC_M);
-
-       ret = rk808_reg_write(rk808, RK808_RTC_CTRL_REG, rtc_ctl);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to write RTC control: %d\n", ret);
-                       return ret;
-               }
-       
-       ret = rk808_reg_read(rk808, RK808_RTC_STATUS_REG);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to read RTC status: %d\n", ret);
-               return ret;
-       }
-       rk808_reg_write(rk808,RK808_RTC_STATUS_REG,0xfe);       
-       /*set init time*/
-
-       ret = rk808_rtc_readtime(&pdev->dev, &tm);
-       if (ret<0)
-       {
-               dev_err(&pdev->dev, "Failed to read RTC time\n");
-               return ret;
-       }
-
-       ret = rtc_valid_tm(&tm);
-       if (ret) {
-       dev_err(&pdev->dev,"invalid date/time and init time\n");
-               rk808_rtc_set_time(&pdev->dev, &tm_def); // 2012-01-01 12:00:00
-//             DBG( "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",1900 + tm_def.tm_year, tm_def.tm_mon + 1, tm_def.tm_mday, tm_def.tm_wday,tm_def.tm_hour, tm_def.tm_min, tm_def.tm_sec);
-       }
-
-       device_init_wakeup(&pdev->dev, 1);
-
-       rk808_rtc->rtc = rtc_device_register("rk808", &pdev->dev,
-                                             &rk808_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rk808_rtc->rtc)) {
-               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 = devm_request_threaded_irq(rk808->dev,per_irq, NULL, rk808_per_irq,
-                                  IRQF_TRIGGER_RISING, "RTC period",
-                                  rk808_rtc);
-       if (ret != 0) {
-               dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n",
-                       per_irq, ret);
-       }
-
-       ret = devm_request_threaded_irq(rk808->dev,alm_irq, NULL, rk808_alm_irq,
-                                  IRQF_TRIGGER_RISING, "RTC alarm",
-                                  rk808_rtc);
-       if (ret != 0) {
-               dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
-                       alm_irq, ret);
-       }
-
-       //for rtc irq test
-       /*
-       rk808_set_bits(rk808_rtc->rk808, RK808_RTC_STATUS_REG,(0x1<< 6),(0x1 <<6));
-       rk808_set_bits(rk808_rtc->rk808, RK808_RTC_INT_REG,0x0c,0x0c);
-       rk808_set_bits(rk808_rtc->rk808,RK808_INT_STS_REG1,(0x3 << 5),(0x3 <<5));
-       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
-       rk808_pdev = pdev;
-       
-       printk("%s:ok\n",__func__);
-       
-       return 0;
-
-err:
-       kfree(rk808_rtc);
-       return ret;
-}
-
-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;
-       int alm_irq = rk808_rtc->rk808->irq_base + RK808_IRQ_RTC_ALARM;
-
-       free_irq(alm_irq, rk808_rtc);
-       free_irq(per_irq, rk808_rtc);
-       rtc_device_unregister(rk808_rtc->rtc);
-       kfree(rk808_rtc);
-
-       return 0;
-}
-
-static const struct dev_pm_ops rk808_rtc_pm_ops = {
-       .suspend = rk808_rtc_suspend,
-       .resume = rk808_rtc_resume,
-
-       .freeze = rk808_rtc_freeze,
-       .thaw = rk808_rtc_resume,
-       .restore = rk808_rtc_resume,
-
-       .poweroff = rk808_rtc_suspend,
-};
-
-static struct platform_driver rk808_rtc_driver = {
-       .probe = rk808_rtc_probe,
-       .remove = rk808_rtc_remove,
-       .driver = {
-               .name = "rk808-rtc",
-               .pm = &rk808_rtc_pm_ops,
-       },
-};
-
-static ssize_t rtc_rk808_test_write(struct file *file, 
-                       const char __user *buf, size_t count, loff_t *offset)
-{
-       char nr_buf[8];
-       int nr = 0, ret;
-       struct platform_device *pdev;   
-       struct rtc_time tm;
-       struct rtc_wkalrm alrm;
-       struct rk808_rtc *rk808_rtc;
-       
-       if(count > 3)
-               return -EFAULT;
-       ret = copy_from_user(nr_buf, buf, count);
-       if(ret < 0)
-               return -EFAULT;
-
-       sscanf(nr_buf, "%d", &nr);
-       if(nr > 5 || nr < 0)
-       {
-               printk("%s:data is error\n",__func__);
-               return -EFAULT;
-       }
-
-       if(!rk808_pdev)
-               return -EFAULT;
-       else
-               pdev = rk808_pdev;
-
-       
-       rk808_rtc = dev_get_drvdata(&pdev->dev);
-       
-       //test rtc time
-       if(nr == 0)
-       {       
-               tm.tm_wday = 6;
-               tm.tm_year = 111;
-               tm.tm_mon = 0;
-               tm.tm_mday = 1;
-               tm.tm_hour = 12;
-               tm.tm_min = 0;
-               tm.tm_sec = 0;
-       
-               ret = rk808_rtc_set_time(&pdev->dev, &tm); // 2011-01-01 12:00:00
-               if (ret)
-               {
-                       dev_err(&pdev->dev, "Failed to set RTC time\n");
-                       return -EFAULT;
-               }
-
-       }
-       
-       /*set init time*/
-       ret = rk808_rtc_readtime(&pdev->dev, &tm);
-       if (ret)
-               dev_err(&pdev->dev, "Failed to read RTC time\n");
-       else
-               dev_info(&pdev->dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
-                       1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_wday,
-                       tm.tm_hour, tm.tm_min, tm.tm_sec);
-               
-       if(!ret)
-       printk("%s:ok\n",__func__);
-       else
-       printk("%s:error\n",__func__);
-       
-
-       //test rtc alarm
-       if(nr == 2)
-       {
-               //2000-01-01 00:00:30
-               if(tm.tm_sec < 30)
-               {
-                       alrm.time.tm_sec = tm.tm_sec+30;        
-                       alrm.time.tm_min = tm.tm_min;
-               }
-               else
-               {
-                       alrm.time.tm_sec = tm.tm_sec-30;
-                       alrm.time.tm_min = tm.tm_min+1;
-               }
-               alrm.time.tm_hour = tm.tm_hour;
-               alrm.time.tm_mday = tm.tm_mday;
-               alrm.time.tm_mon = tm.tm_mon;
-               alrm.time.tm_year = tm.tm_year;         
-               rk808_rtc_alarm_irq_enable(&pdev->dev, 1);
-               rk808_rtc_setalarm(&pdev->dev, &alrm);
-
-               dev_info(&pdev->dev, "Set alarm %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
-                               1900 + alrm.time.tm_year, alrm.time.tm_mon + 1, alrm.time.tm_mday, alrm.time.tm_wday,
-                               alrm.time.tm_hour, alrm.time.tm_min, alrm.time.tm_sec);
-       }
-
-       
-       if(nr == 3)
-       {       
-               ret = rk808_reg_read(rk808_rtc->rk808, RK808_RTC_STATUS_REG);
-               if (ret < 0) {
-                       printk("%s:Failed to read RTC status: %d\n", __func__, ret);
-                       return ret;
-               }
-               printk("%s:ret=0x%x\n",__func__,ret&0xff);
-
-               ret = rk808_reg_write(rk808_rtc->rk808, RK808_RTC_STATUS_REG, ret&0xff);
-               if (ret < 0) {
-                       printk("%s:Failed to read RTC status: %d\n", __func__, ret);
-                       return ret;
-               }
-       }
-
-       if(nr == 4)
-       rk808_rtc_update_irq_enable(&pdev->dev, 1);
-
-       if(nr == 5)
-       rk808_rtc_update_irq_enable(&pdev->dev, 0);
-       
-       return count;
-}
-
-static const struct file_operations rtc_rk808_test_fops = {
-       .write = rtc_rk808_test_write,
-};
-
-static struct miscdevice rtc_rk808_test_misc = {
-       .minor = MISC_DYNAMIC_MINOR,
-       .name = "rtc_rk808_test",
-       .fops = &rtc_rk808_test_fops,
-};
-
-
-static int __init rk808_rtc_init(void)
-{
-       misc_register(&rtc_rk808_test_misc);
-       return platform_driver_register(&rk808_rtc_driver);
-}
-subsys_initcall_sync(rk808_rtc_init);
-
-static void __exit rk808_rtc_exit(void)
-{      
-        misc_deregister(&rtc_rk808_test_misc);
-       platform_driver_unregister(&rk808_rtc_driver);
-}
-module_exit(rk808_rtc_exit);
-
-MODULE_DESCRIPTION("RTC driver for the rk808 series PMICs");
-MODULE_AUTHOR("ZHANGQING <zhanqging@rock-chips.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:rk808-rtc");
diff --git a/include/linux/mfd/rk-rk808.h b/include/linux/mfd/rk-rk808.h
new file mode 100644 (file)
index 0000000..f59f327
--- /dev/null
@@ -0,0 +1,191 @@
+/* include/linux/regulator/rk808.h
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __LINUX_REGULATOR_rk808_H
+#define __LINUX_REGULATOR_rk808_H
+
+#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) 
+
+#define RK808_LDO1 4                //(4+RK808_START)
+
+#define RK808_SECONDS_REG 0x00
+#define RK808_MINUTES_REG 0x01
+#define RK808_HOURS_REG 0x02
+#define RK808_DAYS_REG 0x03
+#define RK808_MONTHS_REG 0x04
+#define RK808_YEARS_REG 0x05
+#define RK808_WEEKS_REG 0x06
+#define RK808_ALARM_SECONDS_REG 0x07
+#define RK808_ALARM_MINUTES_REG 0x08
+#define RK808_ALARM_HOURS_REG 0x09
+#define RK808_ALARM_DAYS_REG 0x0a
+#define RK808_ALARM_MONTHS_REG 0x0b
+#define RK808_ALARM_YEARS_REG 0x0c
+#define RK808_RTC_CTRL_REG 0x10
+#define RK808_RTC_STATUS_REG 0x11
+#define RK808_RTC_INT_REG 0x12
+#define RK808_RTC_COMP_LSB_REG 0x13
+#define RK808_RTC_COMP_MSB_REG 0x14
+#define RK808_CLK32OUT_REG 0x20
+#define RK808_VB_MON_REG 0x21
+#define RK808_THERMAL_REG 0x22
+#define RK808_DCDC_EN_REG 0x23
+#define RK808_LDO_EN_REG 0x24
+#define RK808_SLEEP_SET_OFF_REG1 0x25
+#define RK808_SLEEP_SET_OFF_REG2 0x26
+#define RK808_DCDC_UV_STS_REG 0x27
+#define RK808_DCDC_UV_ACT_REG 0x28
+#define RK808_LDO_UV_STS_REG 0x29
+#define RK808_LDO_UV_ACT_REG 0x2a
+#define RK808_DCDC_PG_REG 0x2b
+#define RK808_LDO_PG_REG 0x2c
+#define RK808_VOUT_MON_TDB_REG 0x2d
+#define RK808_BUCK1_CONFIG_REG 0x2e
+#define RK808_BUCK1_ON_REG 0x2f
+#define RK808_BUCK1_SLP_REG 0x30
+#define RK808_BUCK1_DVS_REG 0x31
+#define RK808_BUCK2_CONFIG_REG 0x32
+#define RK808_BUCK2_ON_REG 0x33
+#define RK808_BUCK2_SLP_REG 0x34
+#define RK808_BUCK2_DVS_REG 0x35
+#define RK808_BUCK3_CONFIG_REG 0x36
+#define RK808_BUCK4_CONFIG_REG 0x37
+#define RK808_BUCK4_ON_REG 0x38
+#define RK808_BUCK4_SLP_VSEL_REG 0x39
+#define RK808_BOOST_CONFIG_REG 0x3a
+#define RK808_LDO1_ON_VSEL_REG 0x3b
+#define RK808_LDO1_SLP_VSEL_REG 0x3c
+#define RK808_LDO2_ON_VSEL_REG 0x3d
+#define RK808_LDO2_SLP_VSEL_REG 0x3e
+#define RK808_LDO3_ON_VSEL_REG 0x3f
+#define RK808_LDO3_SLP_VSEL_REG 0x40
+#define RK808_LDO4_ON_VSEL_REG 0x41
+#define RK808_LDO4_SLP_VSEL_REG 0x42
+#define RK808_LDO5_ON_VSEL_REG 0x43
+#define RK808_LDO5_SLP_VSEL_REG 0x44
+#define RK808_LDO6_ON_VSEL_REG 0x45
+#define RK808_LDO6_SLP_VSEL_REG 0x46
+#define RK808_LDO7_ON_VSEL_REG 0x47
+#define RK808_LDO7_SLP_VSEL_REG 0x48
+#define RK808_LDO8_ON_VSEL_REG 0x49
+#define RK808_LDO8_SLP_VSEL_REG 0x4a
+#define RK808_DEVCTRL_REG 0x4b
+#define RK808_INT_STS_REG1 0X4c
+#define RK808_INT_STS_MSK_REG1 0X4d
+#define RK808_INT_STS_REG2 0X4e
+#define RK808_INT_STS_MSK_REG2 0X4f
+#define RK808_IO_POL_REG 0X50
+
+/* IRQ Definitions */
+#define RK808_IRQ_VOUT_LO                      0
+#define RK808_IRQ_VB_LO                                1
+#define RK808_IRQ_PWRON                                2
+#define RK808_IRQ_PWRON_LP                             3
+#define RK808_IRQ_HOTDIE                               4
+#define RK808_IRQ_RTC_ALARM                            5
+#define RK808_IRQ_RTC_PERIOD                           6
+
+#define RK808_NUM_IRQ  9
+
+#define rk808_NUM_REGULATORS 14
+
+#define RK808_VBAT_LOW_2V8  0x00
+#define RK808_VBAT_LOW_2V9  0x01
+#define RK808_VBAT_LOW_3V0  0x02
+#define RK808_VBAT_LOW_3V1  0x03
+#define RK808_VBAT_LOW_3V2  0x04
+#define RK808_VBAT_LOW_3V3  0x05
+#define RK808_VBAT_LOW_3V4  0x06
+#define RK808_VBAT_LOW_3V5  0x07
+#define VBAT_LOW_VOL_MASK (0x07 << 0)
+#define EN_VABT_LOW_SHUT_DOWN (0x00 << 4)
+#define EN_VBAT_LOW_IRQ (0x1 <<4 )
+#define VBAT_LOW_ACT_MASK (0x1 << 4)
+
+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];
+       bool pm_off;
+};
+
+struct rk808_regulator_subdev {
+       int id;
+       struct regulator_init_data *initdata;
+};
+
+struct rk808 {
+       struct device *dev;
+       struct mutex io_lock;
+       struct i2c_client *i2c;
+       int num_regulators;
+       struct regulator_dev **rdev;
+       struct wake_lock        irq_wake;
+//     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 {
+       int num_regulators;
+       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_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); 
+int rk808_i2c_write(struct rk808 *rk808, char reg, int count, const u8 src);
+int rk808_set_bits(struct rk808 *rk808, u8 reg, u8 mask, u8 val);
+int rk808_clear_bits(struct rk808 *rk808, u8 reg, u8 mask);
+int rk808_reg_read(struct rk808 *rk808, u8 reg);
+int rk808_reg_write(struct rk808 *rk808, u8 reg, u8 val);
+int rk808_bulk_read(struct rk808 *rk808, u8 reg,
+                    int count, u8 *buf);
+int rk808_bulk_write(struct rk808 *rk808, u8 reg,
+                    int count, u8 *buf);
+
+#endif
+
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
deleted file mode 100644 (file)
index f59f327..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/* include/linux/regulator/rk808.h
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#ifndef __LINUX_REGULATOR_rk808_H
-#define __LINUX_REGULATOR_rk808_H
-
-#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) 
-
-#define RK808_LDO1 4                //(4+RK808_START)
-
-#define RK808_SECONDS_REG 0x00
-#define RK808_MINUTES_REG 0x01
-#define RK808_HOURS_REG 0x02
-#define RK808_DAYS_REG 0x03
-#define RK808_MONTHS_REG 0x04
-#define RK808_YEARS_REG 0x05
-#define RK808_WEEKS_REG 0x06
-#define RK808_ALARM_SECONDS_REG 0x07
-#define RK808_ALARM_MINUTES_REG 0x08
-#define RK808_ALARM_HOURS_REG 0x09
-#define RK808_ALARM_DAYS_REG 0x0a
-#define RK808_ALARM_MONTHS_REG 0x0b
-#define RK808_ALARM_YEARS_REG 0x0c
-#define RK808_RTC_CTRL_REG 0x10
-#define RK808_RTC_STATUS_REG 0x11
-#define RK808_RTC_INT_REG 0x12
-#define RK808_RTC_COMP_LSB_REG 0x13
-#define RK808_RTC_COMP_MSB_REG 0x14
-#define RK808_CLK32OUT_REG 0x20
-#define RK808_VB_MON_REG 0x21
-#define RK808_THERMAL_REG 0x22
-#define RK808_DCDC_EN_REG 0x23
-#define RK808_LDO_EN_REG 0x24
-#define RK808_SLEEP_SET_OFF_REG1 0x25
-#define RK808_SLEEP_SET_OFF_REG2 0x26
-#define RK808_DCDC_UV_STS_REG 0x27
-#define RK808_DCDC_UV_ACT_REG 0x28
-#define RK808_LDO_UV_STS_REG 0x29
-#define RK808_LDO_UV_ACT_REG 0x2a
-#define RK808_DCDC_PG_REG 0x2b
-#define RK808_LDO_PG_REG 0x2c
-#define RK808_VOUT_MON_TDB_REG 0x2d
-#define RK808_BUCK1_CONFIG_REG 0x2e
-#define RK808_BUCK1_ON_REG 0x2f
-#define RK808_BUCK1_SLP_REG 0x30
-#define RK808_BUCK1_DVS_REG 0x31
-#define RK808_BUCK2_CONFIG_REG 0x32
-#define RK808_BUCK2_ON_REG 0x33
-#define RK808_BUCK2_SLP_REG 0x34
-#define RK808_BUCK2_DVS_REG 0x35
-#define RK808_BUCK3_CONFIG_REG 0x36
-#define RK808_BUCK4_CONFIG_REG 0x37
-#define RK808_BUCK4_ON_REG 0x38
-#define RK808_BUCK4_SLP_VSEL_REG 0x39
-#define RK808_BOOST_CONFIG_REG 0x3a
-#define RK808_LDO1_ON_VSEL_REG 0x3b
-#define RK808_LDO1_SLP_VSEL_REG 0x3c
-#define RK808_LDO2_ON_VSEL_REG 0x3d
-#define RK808_LDO2_SLP_VSEL_REG 0x3e
-#define RK808_LDO3_ON_VSEL_REG 0x3f
-#define RK808_LDO3_SLP_VSEL_REG 0x40
-#define RK808_LDO4_ON_VSEL_REG 0x41
-#define RK808_LDO4_SLP_VSEL_REG 0x42
-#define RK808_LDO5_ON_VSEL_REG 0x43
-#define RK808_LDO5_SLP_VSEL_REG 0x44
-#define RK808_LDO6_ON_VSEL_REG 0x45
-#define RK808_LDO6_SLP_VSEL_REG 0x46
-#define RK808_LDO7_ON_VSEL_REG 0x47
-#define RK808_LDO7_SLP_VSEL_REG 0x48
-#define RK808_LDO8_ON_VSEL_REG 0x49
-#define RK808_LDO8_SLP_VSEL_REG 0x4a
-#define RK808_DEVCTRL_REG 0x4b
-#define RK808_INT_STS_REG1 0X4c
-#define RK808_INT_STS_MSK_REG1 0X4d
-#define RK808_INT_STS_REG2 0X4e
-#define RK808_INT_STS_MSK_REG2 0X4f
-#define RK808_IO_POL_REG 0X50
-
-/* IRQ Definitions */
-#define RK808_IRQ_VOUT_LO                      0
-#define RK808_IRQ_VB_LO                                1
-#define RK808_IRQ_PWRON                                2
-#define RK808_IRQ_PWRON_LP                             3
-#define RK808_IRQ_HOTDIE                               4
-#define RK808_IRQ_RTC_ALARM                            5
-#define RK808_IRQ_RTC_PERIOD                           6
-
-#define RK808_NUM_IRQ  9
-
-#define rk808_NUM_REGULATORS 14
-
-#define RK808_VBAT_LOW_2V8  0x00
-#define RK808_VBAT_LOW_2V9  0x01
-#define RK808_VBAT_LOW_3V0  0x02
-#define RK808_VBAT_LOW_3V1  0x03
-#define RK808_VBAT_LOW_3V2  0x04
-#define RK808_VBAT_LOW_3V3  0x05
-#define RK808_VBAT_LOW_3V4  0x06
-#define RK808_VBAT_LOW_3V5  0x07
-#define VBAT_LOW_VOL_MASK (0x07 << 0)
-#define EN_VABT_LOW_SHUT_DOWN (0x00 << 4)
-#define EN_VBAT_LOW_IRQ (0x1 <<4 )
-#define VBAT_LOW_ACT_MASK (0x1 << 4)
-
-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];
-       bool pm_off;
-};
-
-struct rk808_regulator_subdev {
-       int id;
-       struct regulator_init_data *initdata;
-};
-
-struct rk808 {
-       struct device *dev;
-       struct mutex io_lock;
-       struct i2c_client *i2c;
-       int num_regulators;
-       struct regulator_dev **rdev;
-       struct wake_lock        irq_wake;
-//     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 {
-       int num_regulators;
-       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_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); 
-int rk808_i2c_write(struct rk808 *rk808, char reg, int count, const u8 src);
-int rk808_set_bits(struct rk808 *rk808, u8 reg, u8 mask, u8 val);
-int rk808_clear_bits(struct rk808 *rk808, u8 reg, u8 mask);
-int rk808_reg_read(struct rk808 *rk808, u8 reg);
-int rk808_reg_write(struct rk808 *rk808, u8 reg, u8 val);
-int rk808_bulk_read(struct rk808 *rk808, u8 reg,
-                    int count, u8 *buf);
-int rk808_bulk_write(struct rk808 *rk808, u8 reg,
-                    int count, u8 *buf);
-
-#endif
-