rk31:linux3.10:pmic:support dc&ldo suspend en/disable,add rk808 pre_init
author张晴 <zhangqing@rock-chips.com>
Mon, 10 Mar 2014 06:21:07 +0000 (14:21 +0800)
committer张晴 <zhangqing@rock-chips.com>
Mon, 10 Mar 2014 06:21:07 +0000 (14:21 +0800)
drivers/mfd/rk808.c
drivers/regulator/act8846.c
include/linux/mfd/rk808.h
include/linux/regulator/act8846.h

index 6ec645c5df9cb197c934c0cc9f6142b8f7c7a5c5..3402e1411eac8b551ef41613d2aebeffefe858c2 100755 (executable)
@@ -181,6 +181,22 @@ static int rk808_ldo_disable(struct regulator_dev *dev)
        
        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;
+       
+       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;
+       
+       return rk808_set_bits(rk808, RK808_SLEEP_SET_OFF_REG2, 1 << ldo, 1 << ldo);
+
 }
 static int rk808_ldo_get_voltage(struct regulator_dev *dev)
 {
@@ -316,6 +332,8 @@ static struct regulator_ops rk808_ldo_ops = {
        .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,
@@ -377,6 +395,22 @@ static int rk808_dcdc_disable(struct regulator_dev *dev)
        
         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);
@@ -503,6 +537,24 @@ static int rk808_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
                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)
@@ -527,8 +579,11 @@ static struct regulator_ops rk808_dcdc_ops = {
        .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,
 };
@@ -1076,6 +1131,112 @@ __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__);
+        /***********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;
+        }
+       /**********************************/
+       return 0;
+}
+
 static int rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
 {
        struct rk808 *rk808;    
@@ -1097,7 +1258,7 @@ static int rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i
                }
        }
 
-       rk808 = kzalloc(sizeof(struct rk808), GFP_KERNEL);
+       rk808 = devm_kzalloc(&i2c->dev,sizeof(struct rk808), GFP_KERNEL);
        if (rk808 == NULL) {
                ret = -ENOMEM;          
                goto err;
@@ -1119,14 +1280,14 @@ static int rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i
        ret = rk808_reg_read(rk808,0x2f);
        if ((ret < 0) || (ret == 0xff)){
                printk("The device is not rk808 %d\n",ret);
-               return 0;
+               goto err;
        }
-       rk808_set_bits(rk808,0x21,(1<<4),(1 <<4));
-       rk808_set_bits(rk808,0x21,(7<<0),(7 <<0));
-       rk808_set_bits(rk808,0x23,(7<<4),(7 <<4)); //enable boost &swith0\1
 
-       if (ret < 0)
+       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);
@@ -1229,6 +1390,7 @@ static int rk808_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i
        return 0;
 
 err:
+       mfd_remove_devices(rk808->dev);
        return ret;     
 
 }
index 65129800aa71492e471e5b29869703752f9fd587..9046baee8bba037b8ab9182729218986dcc173e3 100755 (executable)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
+#include <linux/mfd/core.h>
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
 #endif
@@ -853,7 +854,7 @@ static int act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id
                }
        }
 
-       act8846 = kzalloc(sizeof(struct act8846), GFP_KERNEL);
+       act8846 = devm_kzalloc(&i2c->dev,sizeof(struct act8846), GFP_KERNEL);
        if (act8846 == NULL) {
                ret = -ENOMEM;          
                goto err;
@@ -875,7 +876,7 @@ static int act8846_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id
        ret = act8846_reg_read(act8846,0x22);
        if ((ret < 0) || (ret == 0xff)){
                printk("The device is not act8846 %x \n",ret);
-               return 0;
+               goto err;
        }
 
        ret = act8846_set_bits(act8846, 0xf4,(0x1<<7),(0x0<<7));
index 66bfbc2404042011affde662de63bfc61e09b770..9038aa88c9307628e64498c2b92354cd6ae7ba1d 100755 (executable)
 #define RK808_NUM_IRQ  9
 
 #define rk808_NUM_REGULATORS 12
+
+#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 {
@@ -152,8 +166,6 @@ struct rk808 {
 
 struct rk808_platform_data {
        int num_regulators;
-       int (*pre_init)(struct rk808 *rk808);
-       int (*set_init)(struct rk808 *rk808);
        struct rk808_regulator_subdev *regulators;
        int irq;
        int irq_base;
index 24f2ae969e0c64fe17ddc5864c8e7a00f86e1864..1e9cbaaa3d1b4a6dceff898697de5d7218926811 100755 (executable)
@@ -50,7 +50,6 @@ struct act8846_regulator_subdev {
 struct act8846_platform_data {
        int ono;
        int num_regulators;
-       int (*set_init)(struct act8846 *act8846);
        struct act8846_regulator_subdev *regulators;
        
        int pmic_sleep_gpio; /* */