From 1cc2780bd87769e121bf0000d4f439b12ba8e7b2 Mon Sep 17 00:00:00 2001 From: cym Date: Fri, 20 Aug 2010 11:23:56 +0800 Subject: [PATCH] modify lp8725,add set mode function(normal and sleep),add DVS function --- arch/arm/mach-rk2818/board-raho.c | 52 ++++++- drivers/regulator/rk2818_lp8725.c | 180 ++++++++++++++++++++---- include/linux/regulator/rk2818_lp8725.h | 4 +- 3 files changed, 205 insertions(+), 31 deletions(-) diff --git a/arch/arm/mach-rk2818/board-raho.c b/arch/arm/mach-rk2818/board-raho.c index dc5014ecbf42..db51d3f1c361 100755 --- a/arch/arm/mach-rk2818/board-raho.c +++ b/arch/arm/mach-rk2818/board-raho.c @@ -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={ diff --git a/drivers/regulator/rk2818_lp8725.c b/drivers/regulator/rk2818_lp8725.c index 0ac3c7a55f4f..ba29580aa38e 100644 --- a/drivers/regulator/rk2818_lp8725.c +++ b/drivers/regulator/rk2818_lp8725.c @@ -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; diff --git a/include/linux/regulator/rk2818_lp8725.h b/include/linux/regulator/rk2818_lp8725.h index 74caf43d8fd9..4cb2415c5d0c 100644 --- a/include/linux/regulator/rk2818_lp8725.h +++ b/include/linux/regulator/rk2818_lp8725.h @@ -28,8 +28,10 @@ #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; -- 2.34.1