modify lp8725,add set mode function(normal and sleep),add DVS function
authorcym <cym@rock-chips.com>
Fri, 20 Aug 2010 03:23:56 +0000 (11:23 +0800)
committercym <cym@rock-chips.com>
Fri, 20 Aug 2010 03:24:52 +0000 (11:24 +0800)
arch/arm/mach-rk2818/board-raho.c
drivers/regulator/rk2818_lp8725.c
include/linux/regulator/rk2818_lp8725.h

index dc5014ecbf4212195b2a72c21bc0ea0e0dfcf619..db51d3f1c361bca07da1092e0fe6ea5e32fc9305 100755 (executable)
@@ -417,7 +417,8 @@ static struct regulator_init_data rk2818_lp8725_buck1_data = {
                .max_uV = 1500000,
                .apply_uV = 1,
                .always_on = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+               .valid_modes_mask = REGULATOR_MODE_IDLE | REGULATOR_MODE_NORMAL,
        },
        .num_consumer_supplies = ARRAY_SIZE(buck1_consumers),
        .consumer_supplies = buck1_consumers
@@ -437,14 +438,51 @@ static struct regulator_init_data rk2818_lp8725_buck2_data = {
                .max_uV = 1800000,
                .apply_uV = 1,
                .always_on = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
        },
        .num_consumer_supplies = ARRAY_SIZE(buck2_consumers),
        .consumer_supplies = buck2_consumers
 };
 
+/*buck1_v2 VDD12 Core*/
+static struct regulator_consumer_supply buck1_v2_consumers[] = {
+       {
+               .supply = "vdd12_v2",
+       }
+};
 
+static struct regulator_init_data rk2818_lp8725_buck1_v2_data = {
+       .constraints = {
+               .name = "VDD12_V2",
+               .min_uV = 800000,
+               .max_uV = 1500000,
+               .apply_uV = 1,
+               //.always_on = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(buck1_v2_consumers),
+       .consumer_supplies = buck1_v2_consumers
+};
 
+/*buck2_v2 VDDDR MobileDDR VCC*/
+static struct regulator_consumer_supply buck2_v2_consumers[] = {
+       {
+               .supply = "vccdr_v2",
+       }
+};
+
+static struct regulator_init_data rk2818_lp8725_buck2_v2_data = {
+       .constraints = {
+               .name = "VCCDR_V2",
+               .min_uV = 1800000,
+               .max_uV = 1800000,
+               .apply_uV = 1,
+               //.always_on = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(buck2_v2_consumers),
+       .consumer_supplies = buck2_v2_consumers
+};
 
 struct lp8725_regulator_subdev rk2818_lp8725_regulator_subdev[] = {
        {
@@ -491,7 +529,15 @@ struct lp8725_regulator_subdev rk2818_lp8725_regulator_subdev[] = {
                .id=LP8725_DCDC2,
                .initdata=&rk2818_lp8725_buck2_data,            
         },
-       
+       {
+               .id=LP8725_DCDC1_V2,
+               .initdata=&rk2818_lp8725_buck1_v2_data,         
+        },
+
+       {
+               .id=LP8725_DCDC2_V2,
+               .initdata=&rk2818_lp8725_buck2_v2_data,         
+        },
 };
 
 struct lp8725_platform_data rk2818_lp8725_data={
index 0ac3c7a55f4fb0f1d11e04feef6ee7908a562408..ba29580aa38ef0f2c265114413d31a290ea4726d 100644 (file)
@@ -290,42 +290,113 @@ static int lp8725_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
 static int lp8725_dcdc_is_enabled(struct regulator_dev *dev)
 {
        struct lp8725 *lp8725 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - LP8725_DCDC1;
-       u16 mask = 1 << (buck * 2);
+       int buck = rdev_get_id(dev);
        u16 val;
+       u16 mask,mask2;
 
-       val = lp8725_reg_read(lp8725, LP8725_BUCK_VOL_ENABLE_REG);
-       return (val & mask) != 0;
+       switch(buck)
+       {
+       case LP8725_DCDC1:
+               mask = 1 << 0;
+               mask2 = 1 << 2;         
+               val = lp8725_reg_read(lp8725, LP8725_BUCK_VOL_ENABLE_REG);              
+               return ((val & mask) && (val & mask2)) != 0;    
+       case LP8725_DCDC2:              
+               mask = 1 << 4;
+               mask2 = 1 << 3;
+               val = lp8725_reg_read(lp8725, LP8725_BUCK_VOL_ENABLE_REG);              
+               return ((val & mask) && (val & mask2)) != 0;
+       case LP8725_DCDC1_V2:
+               mask = 1 << 0;
+               mask2 = 1<< 2;
+               val = lp8725_reg_read(lp8725, LP8725_BUCK_VOL_ENABLE_REG);              
+               return  ((val & mask) && (!(val & mask2))) !=0;
+       case LP8725_DCDC2_V2:           
+               mask = 1 << 4;
+               mask2 = 1 << 3;
+               val = lp8725_reg_read(lp8725, LP8725_BUCK_VOL_ENABLE_REG);              
+               return ((val & mask) && (!(val & mask2))) !=0;
+       }
 }
 
 static int lp8725_dcdc_enable(struct regulator_dev *dev)
 {
        struct lp8725 *lp8725 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - LP8725_DCDC1;
-       u16 mask = 1 << (buck * 2);
-
-       return lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, mask);
+       int buck = rdev_get_id(dev);
+       u16 mask;
+       int ret = 0;
+       switch(buck)
+       {
+       case LP8725_DCDC1:
+               mask = 1 << 0;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, mask);
+               mask = 1 << 2;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, mask);          
+               break;
+       case LP8725_DCDC1_V2:
+               mask = 1 << 0;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, mask);
+               mask = 1 << 2;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, 0);             
+               break;
+       case LP8725_DCDC2:
+               mask = 1 << 4;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, mask);  
+               mask = 1 << 3;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, mask);          
+               break;
+       case LP8725_DCDC2_V2:
+               mask = 1 << 4;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, mask);  
+               mask = 1 << 3;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, 0);             
+               break;
+       }
+       dev->use_count--;
+       return ret;
 }
 
 static int lp8725_dcdc_disable(struct regulator_dev *dev)
 {
        struct lp8725 *lp8725 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - LP8725_DCDC1;
-       u16 mask = 1 << (buck * 2);
+       int buck = rdev_get_id(dev) ;
+       u16 mask;       
 
-       return lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, 0);
+       switch(buck)
+       {
+       case LP8725_DCDC1:
+       case LP8725_DCDC1_V2:
+               mask = 1 << 0;
+               return lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, 0);
+       case LP8725_DCDC2:
+       case LP8725_DCDC2_V2:
+               mask = 1 << 4;
+               return lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask,0);
+       }
 }
 
 static int lp8725_dcdc_get_voltage(struct regulator_dev *dev)
 {
        struct lp8725 *lp8725 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - LP8725_DCDC1;
-       u16 reg;
+       int buck = rdev_get_id(dev) ;
+       u16 reg = 0;
        int val;
 
-       reg = lp8725_reg_read(lp8725, LP8725_BUCK_TARGET_VOL1_REG(buck));
-       reg &= BUCK_TARGET_VOL_MASK;
+       switch(buck)
+       {
+       case LP8725_DCDC1:
+       case LP8725_DCDC2:
+               buck -= LP8725_DCDC1;
+               reg = lp8725_reg_read(lp8725, LP8725_BUCK_TARGET_VOL1_REG(buck));
+               break;
+       case LP8725_DCDC1_V2:
+       case LP8725_DCDC2_V2:
+               buck -= LP8725_DCDC1_V2;
+               reg = lp8725_reg_read(lp8725, LP8725_BUCK_TARGET_VOL2_REG(buck));
+               break;
+       }
 
+       reg &= BUCK_TARGET_VOL_MASK;
        val = 1000 * buck_voltage_map[reg];
        
        return val;
@@ -335,11 +406,11 @@ static int lp8725_dcdc_set_voltage(struct regulator_dev *dev,
                                  int min_uV, int max_uV)
 {
        struct lp8725 *lp8725 = rdev_get_drvdata(dev);
-       int buck = rdev_get_id(dev) - LP8725_DCDC1;
+       int buck = rdev_get_id(dev);
        int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
        const int *vol_map = buck_voltage_map;
        u16 val;
-       int ret;
+       int ret = 0;
 
        if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
            min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
@@ -353,17 +424,55 @@ static int lp8725_dcdc_set_voltage(struct regulator_dev *dev,
        if (vol_map[val] > max_vol)
                return -EINVAL;
 
-       ret = lp8725_set_bits(lp8725, LP8725_BUCK_TARGET_VOL1_REG(buck),
-              BUCK_TARGET_VOL_MASK, val);
-       if (ret)
-               return ret;
+       switch(buck)
+       {
+       case LP8725_DCDC1:
+       case LP8725_DCDC2:
+               buck -= LP8725_DCDC1;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_TARGET_VOL1_REG(buck),
+               BUCK_TARGET_VOL_MASK, val);
+               if (ret)
+                       return ret;
+               break;
+       case LP8725_DCDC1_V2:
+       case LP8725_DCDC2_V2:
+               buck -= LP8725_DCDC1_V2;
+               ret = lp8725_set_bits(lp8725, LP8725_BUCK_TARGET_VOL2_REG(buck),
+               BUCK_TARGET_VOL_MASK, val);
+               if (ret)
+                       return ret;
+               break;
+       }
 
-       ret = lp8725_set_bits(lp8725, LP8725_BUCK_TARGET_VOL2_REG(buck),
-              BUCK_TARGET_VOL_MASK, val);
-       if (ret)
-               return ret;
+       return ret;
+}
 
-               return ret;
+static int lp8725_dcdc_get_mode(struct regulator_dev *dev)
+{
+       struct lp8725 *lp8725 = rdev_get_drvdata(dev);
+       u16 mask = 1 << 1;
+       u16 val;
+       val = lp8725_reg_read(lp8725, LP8725_BUCK_VOL_ENABLE_REG);
+       if ((val & mask) == 0)
+               return REGULATOR_MODE_NORMAL;
+       else
+               return REGULATOR_MODE_IDLE;
+}
+
+static int lp8725_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
+{
+       struct lp8725 *lp8725 = rdev_get_drvdata(dev);  
+       u16 mask = 1 << 1;
+       switch(mode)
+       {
+       case REGULATOR_MODE_NORMAL:
+               return lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, 0);            
+       case REGULATOR_MODE_IDLE:
+               return lp8725_set_bits(lp8725, LP8725_BUCK_VOL_ENABLE_REG, mask, mask);
+       default:
+               printk("error:pmu_lp8725 only normal and idle mode\n");
+               return -EINVAL;
+       }       
 }
 
 static struct regulator_ops lp8725_dcdc_ops = {
@@ -373,6 +482,8 @@ static struct regulator_ops lp8725_dcdc_ops = {
        .disable = lp8725_dcdc_disable,
        .get_voltage = lp8725_dcdc_get_voltage,
        .set_voltage = lp8725_dcdc_set_voltage,
+       .get_mode = lp8725_dcdc_get_mode,
+       .set_mode = lp8725_dcdc_set_mode,
 };
 
 static struct regulator_desc regulators[] = {
@@ -448,6 +559,22 @@ static struct regulator_desc regulators[] = {
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
        },
+       {
+               .name = "DCDC1_V2",
+               .id = LP8725_DCDC1_V2,
+               .ops = &lp8725_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "DCDC2_V2",
+               .id = LP8725_DCDC2_V2,
+               .ops = &lp8725_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
 };
 
 static int lp8725_i2c_read(struct i2c_client *i2c, char reg, int count,        u16 *dest)
@@ -545,7 +672,6 @@ static int lp8725_set_bits(struct lp8725 *lp8725, u8 reg, u16 mask, u16 val)
 
 static int lp8725_set_init(void)
 {
-       int ret;
        int tmp = 0;
        struct regulator *ldo1,*ldo2,*ldo3,*ldo4,*ldo5;
        struct regulator *lilo1,*lilo2;
index 74caf43d8fd94b54bc2421149cef432428fb4a04..4cb2415c5d0c38d53f1b3ef86cf84d99e960304c 100644 (file)
 
 #define LP8725_DCDC1 7
 #define LP8725_DCDC2 8
+#define LP8725_DCDC1_V2 9
+#define LP8725_DCDC2_V2 10
 
-#define LP8725_NUM_REGULATORS 9
+#define LP8725_NUM_REGULATORS 11
 
 struct lp8725_regulator_subdev {
        int id;