From a5a04358148a9aab0b433ddfca8349747fcfa841 Mon Sep 17 00:00:00 2001 From: shengfei Xu Date: Wed, 24 Nov 2021 01:57:01 +0000 Subject: [PATCH] regulator: rk806: optimize regulator code update: 1. use gpiod_get_value() instead of gpio_get_value() 2. updtae the rk806 register offset Signed-off-by: shengfei Xu Change-Id: I55b7dfdde06dabe3f8ab6285366059930f282a42 --- drivers/mfd/rk806-core.c | 109 ++--- drivers/regulator/rk806-regulator.c | 690 ++++++++++++---------------- include/linux/mfd/rk806.h | 78 ++-- 3 files changed, 389 insertions(+), 488 deletions(-) diff --git a/drivers/mfd/rk806-core.c b/drivers/mfd/rk806-core.c index e54b1b5dce17..d0b382ae86a2 100644 --- a/drivers/mfd/rk806-core.c +++ b/drivers/mfd/rk806-core.c @@ -56,20 +56,22 @@ static const struct reg_field rk806_reg_fields[] = { [NLDO3_EN] = REG_FIELD(0x03, 2, 2), [NLDO2_EN] = REG_FIELD(0x03, 1, 1), [NLDO1_EN] = REG_FIELD(0x03, 0, 0), - [PLDO4_EN_MASK] = REG_FIELD(0x04, 7, 7), - [PLDO3_EN_MASK] = REG_FIELD(0x04, 6, 6), - [PLDO2_EN_MASK] = REG_FIELD(0x04, 5, 5), - [PLDO1_EN_MASK] = REG_FIELD(0x04, 4, 4), - [PLDO4_EN] = REG_FIELD(0x04, 3, 3), - [PLDO3_EN] = REG_FIELD(0x04, 2, 2), - [PLDO2_EN] = REG_FIELD(0x04, 1, 1), - [PLDO1_EN] = REG_FIELD(0x04, 0, 0), + + [PLDO3_EN_MASK] = REG_FIELD(0x04, 7, 7), + [PLDO2_EN_MASK] = REG_FIELD(0x04, 6, 6), + [PLDO1_EN_MASK] = REG_FIELD(0x04, 5, 5), + [PLDO6_EN_MASK] = REG_FIELD(0x04, 4, 4), + [PLDO3_EN] = REG_FIELD(0x04, 3, 3), + [PLDO2_EN] = REG_FIELD(0x04, 2, 2), + [PLDO1_EN] = REG_FIELD(0x04, 1, 1), + [PLDO6_EN] = REG_FIELD(0x04, 0, 0), + [NLDO5_EN_MASK] = REG_FIELD(0x05, 6, 6), - [PLDO6_EN_MASK] = REG_FIELD(0x05, 5, 5), - [PLDO5_EN_MASK] = REG_FIELD(0x05, 4, 4), - [NLDO5_EN] = REG_FIELD(0x05, 3, 3), - [PLDO6_EN] = REG_FIELD(0x05, 2, 2), + [PLDO5_EN_MASK] = REG_FIELD(0x05, 5, 5), + [PLDO4_EN_MASK] = REG_FIELD(0x05, 4, 4), + [NLDO5_EN] = REG_FIELD(0x05, 2, 2), [PLDO5_EN] = REG_FIELD(0x05, 1, 1), + [PLDO4_EN] = REG_FIELD(0x05, 0, 0), [BUCK8_SLP_EN] = REG_FIELD(0x06, 7, 7), [BUCK7_SLP_EN] = REG_FIELD(0x06, 6, 6), @@ -88,12 +90,12 @@ static const struct reg_field rk806_reg_fields[] = { [NLDO2_SLP_EN] = REG_FIELD(0x07, 1, 1), [NLDO1_SLP_EN] = REG_FIELD(0x07, 0, 0), - [PLDO6_SLP_EN] = REG_FIELD(0x08, 5, 5), - [PLDO5_SLP_EN] = REG_FIELD(0x08, 4, 4), - [PLDO4_SLP_EN] = REG_FIELD(0x08, 3, 3), - [PLDO3_SLP_EN] = REG_FIELD(0x08, 2, 2), - [PLDO2_SLP_EN] = REG_FIELD(0x08, 1, 1), - [PLDO1_SLP_EN] = REG_FIELD(0x08, 0, 0), + [PLDO5_SLP_EN] = REG_FIELD(0x08, 5, 5), + [PLDO4_SLP_EN] = REG_FIELD(0x08, 4, 4), + [PLDO3_SLP_EN] = REG_FIELD(0x08, 3, 3), + [PLDO2_SLP_EN] = REG_FIELD(0x08, 2, 2), + [PLDO1_SLP_EN] = REG_FIELD(0x08, 1, 1), + [PLDO6_SLP_EN] = REG_FIELD(0x08, 0, 0), [BUCK1_RATE] = REG_FIELD(0x10, 6, 7), [BUCK2_RATE] = REG_FIELD(0x11, 6, 7), @@ -183,40 +185,40 @@ static const struct reg_field rk806_reg_fields[] = { [ENB2_2M] = REG_FIELD(0x61, 1, 1), [ENB_32K] = REG_FIELD(0x61, 0, 0), /* SLEEP_CONFIG0 */ - [SLP2_POL] = REG_FIELD(0x62, 7, 7), - [SLP2_FUN] = REG_FIELD(0x62, 4, 6), - [SLP1_POL] = REG_FIELD(0x62, 3, 3), - [SLP1_FUN] = REG_FIELD(0x62, 0, 2), + [PWRCTRL2_POL] = REG_FIELD(0x62, 7, 7), + [PWRCTRL2_FUN] = REG_FIELD(0x62, 4, 6), + [PWRCTRL1_POL] = REG_FIELD(0x62, 3, 3), + [PWRCTRL1_FUN] = REG_FIELD(0x62, 0, 2), /* SLEEP_CONFIG1 */ - [SLP3_POL] = REG_FIELD(0x63, 3, 3), - [SLP3_FUN] = REG_FIELD(0x63, 0, 2), - /* SLEEP_SLP_CTR_SEL0 */ - [BUCK4_SLP_CTR_SEL] = REG_FIELD(0x65, 4, 5), - [BUCK3_SLP_CTR_SEL] = REG_FIELD(0x65, 0, 1), - [BUCK2_SLP_CTR_SEL] = REG_FIELD(0x64, 4, 5), - [BUCK1_SLP_CTR_SEL] = REG_FIELD(0x64, 0, 1), - /* SLEEP_SLP_CTR_SEL1 */ - [BUCK8_SLP_CTR_SEL] = REG_FIELD(0x67, 4, 5), - [BUCK7_SLP_CTR_SEL] = REG_FIELD(0x67, 0, 1), - [BUCK6_SLP_CTR_SEL] = REG_FIELD(0x66, 4, 5), - [BUCK5_SLP_CTR_SEL] = REG_FIELD(0x66, 0, 1), - /* SLEEP_SLP_CTR_SEL2 */ - [NLDO2_SLP_CTR_SEL] = REG_FIELD(0x69, 4, 5), - [NLDO1_SLP_CTR_SEL] = REG_FIELD(0x69, 0, 1), - [BUCK10_SLP_CTR_SEL] = REG_FIELD(0x68, 4, 5), - [BUCK9_SLP_CTR_SEL] = REG_FIELD(0x68, 0, 1), - /* SLEEP_SLP_CTR_SEL3 */ - [NLDO5_SLP_CTR_SEL] = REG_FIELD(0x6b, 0, 1), - [NLDO4_SLP_CTR_SEL] = REG_FIELD(0x6a, 4, 5), - [NLDO3_SLP_CTR_SEL] = REG_FIELD(0x6a, 0, 1), - /* SLEEP_SLP_CTR_SEL4 */ - [PLDO4_SLP_CTR_SEL] = REG_FIELD(0x6d, 4, 5), - [PLDO3_SLP_CTR_SEL] = REG_FIELD(0x6d, 0, 0), - [PLDO2_SLP_CTR_SEL] = REG_FIELD(0x6c, 4, 5), - [PLDO1_SLP_CTR_SEL] = REG_FIELD(0x6c, 0, 1), - /* SLEEP_SLP_CTR_SEL5 */ - [PLDO6_SLP_CTR_SEL] = REG_FIELD(0x6e, 4, 5), - [PLDO5_SLP_CTR_SEL] = REG_FIELD(0x6e, 0, 1), + [PWRCTRL3_POL] = REG_FIELD(0x63, 3, 3), + [PWRCTRL3_FUN] = REG_FIELD(0x63, 0, 2), + /* SLEEP_VSEL_CTR_SEL0 */ + [BUCK4_VSEL_CTR_SEL] = REG_FIELD(0x65, 4, 5), + [BUCK3_VSEL_CTR_SEL] = REG_FIELD(0x65, 0, 1), + [BUCK2_VSEL_CTR_SEL] = REG_FIELD(0x64, 4, 5), + [BUCK1_VSEL_CTR_SEL] = REG_FIELD(0x64, 0, 1), + /* SLEEP_VSEL_CTR_SEL1 */ + [BUCK8_VSEL_CTR_SEL] = REG_FIELD(0x67, 4, 5), + [BUCK7_VSEL_CTR_SEL] = REG_FIELD(0x67, 0, 1), + [BUCK6_VSEL_CTR_SEL] = REG_FIELD(0x66, 4, 5), + [BUCK5_VSEL_CTR_SEL] = REG_FIELD(0x66, 0, 1), + /* SLEEP_VSEL_CTR_SEL2 */ + [NLDO2_VSEL_CTR_SEL] = REG_FIELD(0x69, 4, 5), + [NLDO1_VSEL_CTR_SEL] = REG_FIELD(0x69, 0, 1), + [BUCK10_VSEL_CTR_SEL] = REG_FIELD(0x68, 4, 5), + [BUCK9_VSEL_CTR_SEL] = REG_FIELD(0x68, 0, 1), + /* SLEEP_VSEL_CTR_SEL3 */ + [NLDO5_VSEL_CTR_SEL] = REG_FIELD(0x6b, 0, 1), + [NLDO4_VSEL_CTR_SEL] = REG_FIELD(0x6a, 4, 5), + [NLDO3_VSEL_CTR_SEL] = REG_FIELD(0x6a, 0, 1), + /* SLEEP_VSEL_CTR_SEL4 */ + [PLDO4_VSEL_CTR_SEL] = REG_FIELD(0x6d, 4, 5), + [PLDO3_VSEL_CTR_SEL] = REG_FIELD(0x6d, 0, 0), + [PLDO2_VSEL_CTR_SEL] = REG_FIELD(0x6c, 4, 5), + [PLDO1_VSEL_CTR_SEL] = REG_FIELD(0x6c, 0, 1), + /* SLEEP_VSEL_CTR_SEL5 */ + [PLDO6_VSEL_CTR_SEL] = REG_FIELD(0x6e, 4, 5), + [PLDO5_VSEL_CTR_SEL] = REG_FIELD(0x6e, 0, 1), /* DVS_CTRL_SEL0 */ [BUCK4_DVS_CTR_SEL] = REG_FIELD(0x65, 6, 7), [BUCK3_DVS_CTR_SEL] = REG_FIELD(0x65, 2, 3), @@ -296,13 +298,14 @@ static struct resource rk806_pwrkey_resources[] = { }; static const struct mfd_cell rk806_cells[] = { - { .name = "rk806-regulator", }, + { .name = "rk806-pinctrl", }, { .name = "rk805-pwrkey", .num_resources = ARRAY_SIZE(rk806_pwrkey_resources), .resources = &rk806_pwrkey_resources[0], }, - { .name = "rk806-pinctrl", }, + { .name = "rk806-regulator", }, + }; static const struct regmap_irq rk806_irqs[] = { diff --git a/drivers/regulator/rk806-regulator.c b/drivers/regulator/rk806-regulator.c index 5e0843e5956a..6fdf9267e436 100644 --- a/drivers/regulator/rk806-regulator.c +++ b/drivers/regulator/rk806-regulator.c @@ -9,11 +9,11 @@ #include #include +#include #include #include #include #include -#include #include #include #include "internal.h" @@ -64,31 +64,31 @@ module_param_named(dbg_level, dbg_enable, int, 0644); #define RK806_RAMP_RATE_1LSB_PER_13CLK 0x06/* LDO 1.9mV/uS buck 961mV/us */ #define RK806_RAMP_RATE_1LSB_PER_32CLK 0x07/* LDO 0.78mV/uS buck 0.39mV/us */ -static int gpio_dvs_id[] = { - BUCK1_SLP_CTR_SEL, - BUCK2_SLP_CTR_SEL, - BUCK3_SLP_CTR_SEL, - BUCK4_SLP_CTR_SEL, - BUCK5_SLP_CTR_SEL, - BUCK6_SLP_CTR_SEL, - BUCK7_SLP_CTR_SEL, - BUCK8_SLP_CTR_SEL, - BUCK9_SLP_CTR_SEL, - BUCK10_SLP_CTR_SEL, - NLDO1_SLP_CTR_SEL, - NLDO2_SLP_CTR_SEL, - NLDO3_SLP_CTR_SEL, - NLDO4_SLP_CTR_SEL, - NLDO5_SLP_CTR_SEL, - PLDO1_SLP_CTR_SEL, - PLDO2_SLP_CTR_SEL, - PLDO3_SLP_CTR_SEL, - PLDO4_SLP_CTR_SEL, - PLDO5_SLP_CTR_SEL, - PLDO6_SLP_CTR_SEL, +static int vsel_ctr_sel_id[RK806_ID_END] = { + BUCK1_VSEL_CTR_SEL, + BUCK2_VSEL_CTR_SEL, + BUCK3_VSEL_CTR_SEL, + BUCK4_VSEL_CTR_SEL, + BUCK5_VSEL_CTR_SEL, + BUCK6_VSEL_CTR_SEL, + BUCK7_VSEL_CTR_SEL, + BUCK8_VSEL_CTR_SEL, + BUCK9_VSEL_CTR_SEL, + BUCK10_VSEL_CTR_SEL, + NLDO1_VSEL_CTR_SEL, + NLDO2_VSEL_CTR_SEL, + NLDO3_VSEL_CTR_SEL, + NLDO4_VSEL_CTR_SEL, + NLDO5_VSEL_CTR_SEL, + PLDO1_VSEL_CTR_SEL, + PLDO2_VSEL_CTR_SEL, + PLDO3_VSEL_CTR_SEL, + PLDO4_VSEL_CTR_SEL, + PLDO5_VSEL_CTR_SEL, + PLDO6_VSEL_CTR_SEL, }; -static int start_dvs_id[] = { +static int start_dvs_id[RK806_ID_END] = { BUCK1_DVS_CTR_SEL, BUCK2_DVS_CTR_SEL, BUCK3_DVS_CTR_SEL, @@ -131,7 +131,7 @@ struct rk806_dvs_field { int sleep_en; int on_vsel; int sleep_vsel; - int sleep_ctrl_sel; + int vsel_ctrl_sel; }; struct rk806_dvs_status { @@ -140,7 +140,7 @@ struct rk806_dvs_status { int sleep_en_val; int on_vsel_val; int sleep_vsel_val; - int sleep_ctrl_sel_val; + int vsel_ctrl_sel_val; int dvs_gpio_level[3]; }; @@ -152,76 +152,79 @@ struct rk806_regulator_data { int dvs_ctrl_mode_init[RK806_ID_END]; int dvs_ctrl_mode[RK806_ID_END]; - int dvs_gpios[3]; + int dvs_ctrl_id[RK806_ID_END]; + int vsel_ctrl_id[RK806_ID_END]; int dvs_flag[RK806_DVS_END]; int dvs_used[RK806_DVS_END]; int dvs_count[RK806_DVS_END]; + int regulator_init; int support_dvs; + struct gpio_desc *dvs_gpios[3]; struct rk806 *rk806; }; #define INIT_DVS_FIELD(_en_reg, _en_bit, _sleep_en, _on_vsel, \ - _sleep_vsel, _sleep_ctrl_sel) \ + _sleep_vsel, _vsel_ctrl_sel) \ { \ .en_reg = _en_reg, \ .en_bit = _en_bit, \ .sleep_en = _sleep_en, \ .on_vsel = _on_vsel, \ .sleep_vsel = _sleep_vsel, \ - .sleep_ctrl_sel = _sleep_ctrl_sel, \ + .vsel_ctrl_sel = _vsel_ctrl_sel, \ } -static const struct rk806_dvs_field rk806_dvs_field[] = { +static const struct rk806_dvs_field rk806_dvs_fields[RK806_ID_END] = { INIT_DVS_FIELD(POWER_EN0, BIT(0), BUCK1_SLP_EN, - BUCK1_ON_VSEL, BUCK1_SLP_VSEL, BUCK1_SLP_CTR_SEL), + BUCK1_ON_VSEL, BUCK1_SLP_VSEL, BUCK1_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN0, BIT(1), BUCK2_SLP_EN, - BUCK2_ON_VSEL, BUCK2_SLP_VSEL, BUCK2_SLP_CTR_SEL), + BUCK2_ON_VSEL, BUCK2_SLP_VSEL, BUCK2_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN0, BIT(2), BUCK3_SLP_EN, - BUCK3_ON_VSEL, BUCK3_SLP_VSEL, BUCK3_SLP_CTR_SEL), + BUCK3_ON_VSEL, BUCK3_SLP_VSEL, BUCK3_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN0, BIT(3), BUCK4_SLP_EN, - BUCK4_ON_VSEL, BUCK4_SLP_VSEL, BUCK4_SLP_CTR_SEL), + BUCK4_ON_VSEL, BUCK4_SLP_VSEL, BUCK4_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN1, BIT(0), BUCK5_SLP_EN, - BUCK5_ON_VSEL, BUCK5_SLP_VSEL, BUCK5_SLP_CTR_SEL), + BUCK5_ON_VSEL, BUCK5_SLP_VSEL, BUCK5_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN1, BIT(1), BUCK6_SLP_EN, - BUCK6_ON_VSEL, BUCK6_SLP_VSEL, BUCK6_SLP_CTR_SEL), + BUCK6_ON_VSEL, BUCK6_SLP_VSEL, BUCK6_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN1, BIT(2), BUCK7_SLP_EN, - BUCK7_ON_VSEL, BUCK7_SLP_VSEL, BUCK7_SLP_CTR_SEL), + BUCK7_ON_VSEL, BUCK7_SLP_VSEL, BUCK7_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN1, BIT(3), BUCK8_SLP_EN, - BUCK8_ON_VSEL, BUCK8_SLP_VSEL, BUCK8_SLP_CTR_SEL), + BUCK8_ON_VSEL, BUCK8_SLP_VSEL, BUCK8_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN2, BIT(0), BUCK9_SLP_EN, - BUCK9_ON_VSEL, BUCK9_SLP_VSEL, BUCK9_SLP_CTR_SEL), + BUCK9_ON_VSEL, BUCK9_SLP_VSEL, BUCK9_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN2, BIT(1), BUCK10_SLP_EN, - BUCK10_ON_VSEL, BUCK10_SLP_VSEL, BUCK10_SLP_CTR_SEL), + BUCK10_ON_VSEL, BUCK10_SLP_VSEL, BUCK10_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN3, BIT(0), NLDO1_SLP_EN, - NLDO1_ON_VSEL, NLDO1_SLP_VSEL, NLDO1_SLP_CTR_SEL), + NLDO1_ON_VSEL, NLDO1_SLP_VSEL, NLDO1_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN3, BIT(1), NLDO2_SLP_EN, - NLDO2_ON_VSEL, NLDO2_SLP_VSEL, NLDO2_SLP_CTR_SEL), + NLDO2_ON_VSEL, NLDO2_SLP_VSEL, NLDO2_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN3, BIT(2), NLDO3_SLP_EN, - NLDO3_ON_VSEL, NLDO3_SLP_VSEL, NLDO3_SLP_CTR_SEL), + NLDO3_ON_VSEL, NLDO3_SLP_VSEL, NLDO3_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN3, BIT(3), NLDO4_SLP_EN, - NLDO4_ON_VSEL, NLDO4_SLP_VSEL, NLDO4_SLP_CTR_SEL), + NLDO4_ON_VSEL, NLDO4_SLP_VSEL, NLDO4_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN5, BIT(2), NLDO5_SLP_EN, - NLDO5_ON_VSEL, NLDO5_SLP_VSEL, NLDO5_SLP_CTR_SEL), + NLDO5_ON_VSEL, NLDO5_SLP_VSEL, NLDO5_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN4, BIT(0), PLDO1_SLP_EN, - PLDO1_ON_VSEL, PLDO1_SLP_VSEL, PLDO1_SLP_CTR_SEL), + PLDO1_ON_VSEL, PLDO1_SLP_VSEL, PLDO1_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN4, BIT(1), PLDO2_SLP_EN, - PLDO2_ON_VSEL, PLDO2_SLP_VSEL, PLDO2_SLP_CTR_SEL), + PLDO2_ON_VSEL, PLDO2_SLP_VSEL, PLDO2_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN4, BIT(2), PLDO3_SLP_EN, - PLDO3_ON_VSEL, PLDO3_SLP_VSEL, PLDO3_SLP_CTR_SEL), + PLDO3_ON_VSEL, PLDO3_SLP_VSEL, PLDO3_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN4, BIT(3), PLDO4_SLP_EN, - PLDO4_ON_VSEL, PLDO4_SLP_VSEL, PLDO4_SLP_CTR_SEL), + PLDO4_ON_VSEL, PLDO4_SLP_VSEL, PLDO4_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN5, BIT(0), PLDO5_SLP_EN, - PLDO5_ON_VSEL, PLDO5_SLP_VSEL, PLDO5_SLP_CTR_SEL), + PLDO5_ON_VSEL, PLDO5_SLP_VSEL, PLDO5_VSEL_CTR_SEL), INIT_DVS_FIELD(POWER_EN5, BIT(1), PLDO6_SLP_EN, - PLDO6_ON_VSEL, PLDO6_SLP_VSEL, PLDO6_SLP_CTR_SEL), + PLDO6_ON_VSEL, PLDO6_SLP_VSEL, PLDO6_VSEL_CTR_SEL), }; static const struct linear_range rk806_buck_voltage_ranges[] = { @@ -248,49 +251,79 @@ static int get_count(int value) return count; } -static int get_dvs_mode(struct regulator_dev *rdev) +static void rk806_dvs_start_fun_init(struct regulator_dev *rdev) { struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); struct rk806 *rk806 = pdata->rk806; int rid = rdev_get_id(rdev); - int i, j; - if (!pdata->support_dvs) - return RK806_DVS_NOT_SUPPORT; + rk806_field_write(rk806, + pdata->dvs_ctrl_id[rid], + pdata->dvs_ctrl_mode[rid]); +} - if (pdata->dvs_ctrl_mode_init[rid] || pdata->regulator_init) - return pdata->dvs_ctrl_mode[rid]; +static void rk806_dvs_pwrctrl_fun_init(struct regulator_dev *rdev) +{ + struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); + struct rk806 *rk806 = pdata->rk806; + int rid = rdev_get_id(rdev); + int offset; - for (i = 0; i < RK806_DVS_END; i++) { + /* init dvs pin function */ + offset = pdata->dvs_ctrl_mode[rid] - RK806_DVS_PWRCTRL1; + rk806_field_write(rk806, PWRCTRL1_FUN + offset, PWRCTRL_DVS_FUN); + + rk806_field_write(rk806, + pdata->dvs_ctrl_id[rid], + pdata->dvs_ctrl_mode[rid] - RK806_DVS_START3); +} + +static void rk806_dvs_start_pwrctrl_fun_init(struct regulator_dev *rdev) +{ + struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); + struct rk806 *rk806 = pdata->rk806; + int rid = rdev_get_id(rdev); + int offset; + + /* init dvs pin function */ + offset = pdata->dvs_ctrl_mode[rid] - RK806_DVS_START_PWRCTR1; + /*set pin polarity, active high */ + rk806_field_write(rk806, PWRCTRL1_POL + offset, POL_HIGH); + rk806_field_write(rk806, PWRCTRL1_FUN + offset, PWRCTRL_DVS_FUN); + + /* enable start bit dvs function */ + rk806_field_write(rk806, + pdata->dvs_ctrl_id[rid], + pdata->dvs_ctrl_mode[rid] - RK806_DVS_PWRCTRL3); + rk806_field_write(rk806, + pdata->vsel_ctrl_id[rid], + pdata->dvs_ctrl_mode[rid] - RK806_DVS_PWRCTRL3); + +} + +static int rk806_dvs_mode_init(struct regulator_dev *rdev) +{ + struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); + int rid = rdev_get_id(rdev); + int mode, j; + + for (mode = RK806_DVS_START1; mode < RK806_DVS_END; mode++) { for (j = 0; j < RK806_ID_END; j++) { - if ((pdata->dvs_dn[i][j] == NULL) || - (strcmp(pdata->dvs_dn[i][j]->name, rdev->desc->name))) + if ((pdata->dvs_dn[mode][j] == NULL) || + (strcmp(pdata->dvs_dn[mode][j]->name, rdev->desc->name))) continue; - pdata->dvs_ctrl_mode[rid] = i; + pdata->dvs_ctrl_mode[rid] = mode; pdata->dvs_ctrl_mode_init[rid] = 1; - pdata->dvs_flag[i] |= BIT(rid); - pdata->dvs_field[j] = rk806_dvs_field[j]; - - /* init dvs pin function */ - if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN1) - rk806_field_write(rk806, SLP1_FUN, RK806_PIN_FUN_DVS); - else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN2) - rk806_field_write(rk806, SLP2_FUN, RK806_PIN_FUN_DVS); - else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN3) - rk806_field_write(rk806, SLP3_FUN, RK806_PIN_FUN_DVS); + pdata->dvs_flag[mode] |= BIT(rid); /* init dvs function, dvs-pin or start bit */ - if ((pdata->dvs_ctrl_mode[rid] >= RK806_DVS_BY_CTR_PIN1) && - (pdata->dvs_ctrl_mode[rid] <= RK806_DVS_BY_CTR_PIN3)) - rk806_field_write(rk806, gpio_dvs_id[rid], pdata->dvs_ctrl_mode[rid]); - - if ((pdata->dvs_ctrl_mode[rid] >= RK806_DVS_BY_CTR_START1) && - (pdata->dvs_ctrl_mode[rid] <= RK806_DVS_BY_CTR_START3)) - rk806_field_write(rk806, - start_dvs_id[rid], - pdata->dvs_ctrl_mode[rid] - RK806_DVS_BY_CTR_PIN3); - + if (mode <= RK806_DVS_START3) + rk806_dvs_start_fun_init(rdev); + else if (mode <= RK806_DVS_PWRCTRL3) + rk806_dvs_pwrctrl_fun_init(rdev); + else if (mode <= RK806_DVS_START_PWRCTR3) + rk806_dvs_start_pwrctrl_fun_init(rdev); return pdata->dvs_ctrl_mode[rid]; } } @@ -298,9 +331,28 @@ static int get_dvs_mode(struct regulator_dev *rdev) return pdata->dvs_ctrl_mode[rid]; } -static int get_gpio_id(struct regulator_dev *rdev) +static int get_dvs_mode(struct regulator_dev *rdev) { - return get_dvs_mode(rdev) - 1; + struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); + int rid = rdev_get_id(rdev); + + if (!pdata->support_dvs) + return RK806_DVS_NOT_SUPPORT; + + if (pdata->dvs_ctrl_mode_init[rid] || pdata->regulator_init) + return pdata->dvs_ctrl_mode[rid]; + + return rk806_dvs_mode_init(rdev); +} + +static int get_gpio_id(int mode) +{ + int pid = -1; + + if ((mode >= RK806_DVS_PWRCTRL1) && (mode <= RK806_DVS_PWRCTRL3)) + pid = mode - RK806_DVS_PWRCTRL1; + + return pid; } static int rk806_get_reg_offset(int id) @@ -325,19 +377,16 @@ static int rk806_get_read_vsel_register(struct regulator_dev *rdev) int rid = rdev_get_id(rdev); int mode; + vsel_reg = rdev->desc->vsel_reg; + if (!pdata->support_dvs) + return vsel_reg; + mode = get_dvs_mode(rdev); - if (mode == RK806_DVS_NOT_SUPPORT) - return rdev->desc->vsel_reg; - - if ((mode < RK806_DVS_BY_CTR_PIN1) || (mode > RK806_DVS_BY_CTR_PIN3)) { - vsel_reg = rdev->desc->vsel_reg; - } else { - pid = get_gpio_id(rdev); - level = gpio_get_value(pdata->dvs_gpios[pid]); - + pid = get_gpio_id(mode); + if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) { + level = gpiod_get_value(pdata->dvs_gpios[pid]); + /* level == 0, the Output high level, the SLP_VSEL output */ if (level == 0) - vsel_reg = rdev->desc->vsel_reg; - else vsel_reg = rdev->desc->vsel_reg + rk806_get_reg_offset(rid); } @@ -351,19 +400,16 @@ static int rk806_get_write_vsel_register(struct regulator_dev *rdev) int rid = rdev_get_id(rdev); int mode; + vsel_reg = rdev->desc->vsel_reg; + if (!pdata->support_dvs) + return vsel_reg; + mode = get_dvs_mode(rdev); - if (mode == RK806_DVS_NOT_SUPPORT) - return rdev->desc->vsel_reg; - - if ((mode < RK806_DVS_BY_CTR_PIN1) || (mode > RK806_DVS_BY_CTR_PIN3)) { - vsel_reg = rdev->desc->vsel_reg; - } else { - pid = get_gpio_id(rdev); - level = gpio_get_value(pdata->dvs_gpios[pid]); - + pid = get_gpio_id(mode); + if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) { + level = gpiod_get_value(pdata->dvs_gpios[pid]); + /* level == 1, output low level, the ON_VSEL output, next SLP_VSEL */ if (level == 1) - vsel_reg = rdev->desc->vsel_reg; - else vsel_reg = rdev->desc->vsel_reg + rk806_get_reg_offset(rid); } @@ -373,76 +419,78 @@ static int rk806_get_write_vsel_register(struct regulator_dev *rdev) static void rk806_do_gpio_dvs(struct regulator_dev *rdev) { struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); - char dvs_ctrl_name[7][32] = { "dvs_default", - "dvs_pin1_ctrl", - "dvs_pin2_ctrl", - "dvs_pin3_ctrl", - "start_dvs1_ctrl", - "start_dvs2_ctrl", - "start_dvs3_ctrl" }; + char dvs_ctrl_name[10][32] = { + "dvs_default", + "start_dvs1_ctrl", + "start_dvs2_ctrl", + "start_dvs3_ctrl", + "dvs_pin1_ctrl", + "dvs_pin2_ctrl", + "dvs_pin3_ctrl", + "start_and_pwrctrl1", + "start_and_pwrctrl2", + "start_and_pwrctrl3"}; int rid = rdev_get_id(rdev); int gpio_level, pid; int mode, count; mode = get_dvs_mode(rdev); - if ((mode >= RK806_DVS_BY_CTR_PIN1) && - (mode <= RK806_DVS_BY_CTR_PIN3)) { - pid = get_gpio_id(rdev); - pdata->dvs_used[mode] |= BIT(rid); - count = get_count(pdata->dvs_used[mode]); + pdata->dvs_used[mode] |= BIT(rid); + count = get_count(pdata->dvs_used[mode]); - if ((pdata->dvs_used[mode] != pdata->dvs_flag[mode]) || - (count != pdata->dvs_count[mode])) - return; + if ((pdata->dvs_used[mode] != pdata->dvs_flag[mode]) || + (count != pdata->dvs_count[mode])) + return; - pdata->dvs_used[mode] = 0; - gpio_level = gpio_get_value(pdata->dvs_gpios[pid]); + pdata->dvs_used[mode] = 0; - if (gpio_level == 0) - gpio_set_value(pdata->dvs_gpios[pid], 1); + pid = get_gpio_id(mode); + if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) { + gpio_level = gpiod_get_value(pdata->dvs_gpios[pid]); + if (gpio_level == 1) + gpiod_set_value(pdata->dvs_gpios[pid], 0); else - gpio_set_value(pdata->dvs_gpios[pid], 0); - - REG_DBG("pin: name: %s, %s\n", dvs_ctrl_name[mode], rdev->desc->name); + gpiod_set_value(pdata->dvs_gpios[pid], 1); } + REG_DBG("pin: name: %s, %s\n", dvs_ctrl_name[mode], rdev->desc->name); } static void rk806_do_soft_dvs(struct regulator_dev *rdev) { struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); - char dvs_ctrl_name[7][32] = { "dvs_default", - "dvs_pin1_ctrl", - "dvs_pin2_ctrl", - "dvs_pin3_ctrl", - "start_dvs1_ctrl", - "start_dvs2_ctrl", - "start_dvs3_ctrl" }; + char dvs_ctrl_name[10][32] = { + "dvs_default", + "start_dvs1_ctrl", + "start_dvs2_ctrl", + "start_dvs3_ctrl", + "dvs_pin1_ctrl", + "dvs_pin2_ctrl", + "dvs_pin3_ctrl", + "start_and_pwrctrl1", + "start_and_pwrctrl2", + "start_and_pwrctrl3"}; struct rk806 *rk806 = pdata->rk806; int rid = rdev_get_id(rdev); int soft_mode, count; + int offset; soft_mode = get_dvs_mode(rdev); + pdata->dvs_used[soft_mode] |= BIT(rid); + count = get_count(pdata->dvs_used[soft_mode]); - if ((soft_mode >= RK806_DVS_BY_CTR_START1) && - (soft_mode <= RK806_DVS_BY_CTR_START3)) { - pdata->dvs_used[soft_mode] |= BIT(rid); - count = get_count(pdata->dvs_used[soft_mode]); + if ((pdata->dvs_used[soft_mode] != pdata->dvs_flag[soft_mode]) || + (count != pdata->dvs_count[soft_mode])) + return; - if ((pdata->dvs_used[soft_mode] != pdata->dvs_flag[soft_mode]) || - (count != pdata->dvs_count[soft_mode])) - return; + pdata->dvs_used[soft_mode] = 0; - pdata->dvs_used[soft_mode] = 0; + if (soft_mode < RK806_DVS_START_PWRCTR1) + offset = soft_mode - RK806_DVS_START1; + else + offset = soft_mode - RK806_DVS_START_PWRCTR1; - if (soft_mode == RK806_DVS_BY_CTR_START1) - rk806_field_write(rk806, DVS_START1, 0x01); - else if (soft_mode == RK806_DVS_BY_CTR_START2) - rk806_field_write(rk806, DVS_START2, 0x01); - else if (soft_mode == RK806_DVS_BY_CTR_START3) - rk806_field_write(rk806, DVS_START3, 0x01); - - REG_DBG("soft:%s, %s\n", dvs_ctrl_name[soft_mode], rdev->desc->name); - } + rk806_field_write(rk806, DVS_START1 + offset, 0x01); + REG_DBG("soft:%s, %s\n", dvs_ctrl_name[soft_mode], rdev->desc->name); } static void rk806_regulator_sync_voltage(struct regulator_dev *rdev) @@ -453,7 +501,7 @@ static void rk806_regulator_sync_voltage(struct regulator_dev *rdev) if (mode == RK806_DVS_NOT_SUPPORT) return; - if ((mode >= RK806_DVS_BY_CTR_PIN1) && (mode <= RK806_DVS_BY_CTR_PIN3)) + if ((mode >= RK806_DVS_PWRCTRL1) && (mode <= RK806_DVS_PWRCTRL3)) rk806_do_gpio_dvs(rdev); else rk806_do_soft_dvs(rdev); @@ -484,8 +532,8 @@ static int rk806_set_suspend_enable_ctrl(struct regulator_dev *rdev, else val = 0; - if ((get_dvs_mode(rdev) < RK806_DVS_BY_CTR_PIN1) || - (get_dvs_mode(rdev) > RK806_DVS_BY_CTR_PIN3)) + if ((get_dvs_mode(rdev) < RK806_DVS_PWRCTRL1) || + (get_dvs_mode(rdev) > RK806_DVS_PWRCTRL3)) return rk806_field_write(rk806, pdata->dvs_field[rid].sleep_en, val); pdata->sleep_mode[rid].sleep_en_val = val; @@ -558,18 +606,19 @@ static int rk806_regulator_sleep2dvs_mode(struct regulator_dev *rdev) { struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); struct rk806 *rk806 = pdata->rk806; - int rid = rdev_get_id(rdev); - int gpio_id = get_gpio_id(rdev); int mode = get_dvs_mode(rdev); + int rid = rdev_get_id(rdev); + int pid = get_gpio_id(mode); int gpio_level, j; /* set slp_fun NULL*/ - if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN1) - rk806_field_write(rk806, SLP1_FUN, RK806_DVS_BY_CTR_PIN1); - else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN2) - rk806_field_write(rk806, SLP2_FUN, RK806_DVS_BY_CTR_PIN2); - else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN3) - rk806_field_write(rk806, SLP3_FUN, RK806_DVS_BY_CTR_PIN3); + if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_PWRCTRL1) + rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_DVS_FUN); + else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_PWRCTRL2) + rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_DVS_FUN); + else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_PWRCTRL3) + rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_DVS_FUN); + /* 3.check the used count 1*/ pdata->dvs_used[mode] |= BIT(rid); @@ -581,19 +630,20 @@ static int rk806_regulator_sleep2dvs_mode(struct regulator_dev *rdev) for (j = 0; j < RK806_ID_END; j++) if (pdata->dvs_ctrl_mode[j] == mode) rk806_field_write(rk806, - pdata->dvs_field[j].sleep_ctrl_sel, + pdata->dvs_field[j].vsel_ctrl_sel, pdata->dvs_ctrl_mode[j]); - gpio_level = pdata->dvs_mode[rid].dvs_gpio_level[gpio_id]; - - if (gpio_level == 1) { - gpio_set_value(pdata->dvs_gpios[gpio_id], 1); - rk806_field_write(rk806, - pdata->dvs_field[rid].on_vsel, - pdata->dvs_mode[rid].on_vsel_val); - rk806_field_write(rk806, - pdata->dvs_field[rid].en_reg, - pdata->dvs_mode[rid].en_reg_val | (pdata->dvs_field[rid].en_bit << 4)); + if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) { + gpio_level = pdata->dvs_mode[rid].dvs_gpio_level[pid]; + if (gpio_level == 1) { + gpiod_set_value(pdata->dvs_gpios[pid], 0); + rk806_field_write(rk806, + pdata->dvs_field[rid].on_vsel, + pdata->dvs_mode[rid].on_vsel_val); + rk806_field_write(rk806, + pdata->dvs_field[rid].en_reg, + pdata->dvs_mode[rid].en_reg_val | (pdata->dvs_field[rid].en_bit << 4)); + } } return 0; } @@ -605,10 +655,13 @@ static int rk806_regulator_resume(struct regulator_dev *rdev) int rid = rdev_get_id(rdev); int j; + if (!pdata->support_dvs) + return 0; + if (rid == RK806_ID_DCDC1) { for (j = 0; j < RK806_ID_END; j++) { rk806_field_write(rk806, - pdata->dvs_field[j].sleep_ctrl_sel, + pdata->dvs_field[j].vsel_ctrl_sel, 0x00); rk806_field_write(rk806, pdata->dvs_field[j].sleep_vsel, @@ -619,137 +672,12 @@ static int rk806_regulator_resume(struct regulator_dev *rdev) } } - if ((get_dvs_mode(rdev) >= RK806_DVS_BY_CTR_PIN1) && - (get_dvs_mode(rdev) <= RK806_DVS_BY_CTR_PIN3)) + if ((get_dvs_mode(rdev) >= RK806_DVS_PWRCTRL1) && + (get_dvs_mode(rdev) <= RK806_DVS_PWRCTRL3)) rk806_regulator_sleep2dvs_mode(rdev); - return 0; } -static int rk806_regulator_dvs2sleep_mode(struct regulator_dev *rdev) -{ - struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); - struct rk806 *rk806 = pdata->rk806; - int rid = rdev_get_id(rdev); - int gpio_id = get_gpio_id(rdev); - int mode = get_dvs_mode(rdev); - int gpio_level, j; - - /* 1. save ON_VSEL/ON_EN, SLP_VSEL/SLP_EN, dvs_pin level, SLP_CTRL_SEL */ - gpio_level = gpio_get_value(pdata->dvs_gpios[gpio_id]); - pdata->dvs_mode[rid].dvs_gpio_level[gpio_id] = gpio_level; - - if (gpio_level == 1) { - /* 2.if dvs_pin high level, the output voltage from SLP_VSEL/SLP_EN */ - rk806_field_write(rk806, - pdata->dvs_field[rid].on_vsel, - pdata->dvs_mode[rid].sleep_vsel_val); - rk806_field_write(rk806, - pdata->dvs_field[rid].en_reg, - pdata->dvs_mode[rid].sleep_en_val | (pdata->dvs_field[rid].en_bit << 4)); - } - - /* 3.check the used count 1 */ - pdata->dvs_used[mode] |= BIT(rid); - if (pdata->dvs_used[mode] != pdata->dvs_flag[mode]) - return 0; - - pdata->dvs_used[mode] = 0; - /* 4.switch to ON_VSEL/ON_EN */ - gpio_set_value(pdata->dvs_gpios[gpio_id], 0); - - /*first set SLEEP_CTRL_SEL, then set SLP_FUN */ - /* 5.clear the SLP_CTRL_SEL */ - for (j = 0; j < RK806_ID_END; j++) - if (pdata->dvs_ctrl_mode[j] == mode) - rk806_field_write(rk806, - pdata->dvs_field[j].sleep_ctrl_sel, - 0x00); - - /* set slp_fun NULL */ - if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN1) - rk806_field_write(rk806, SLP1_FUN, RK806_PIN_FUN_NULL); - else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN2) - rk806_field_write(rk806, SLP2_FUN, RK806_PIN_FUN_NULL); - else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN3) - rk806_field_write(rk806, SLP3_FUN, RK806_PIN_FUN_NULL); - - if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN1) { - /* 6.the slp pin avctive high */ - /* rk806_field_write(rk806, SLP1_POL, 0x01); */ - /* 7.switch to sleep function */ - rk806_field_write(rk806, SLP1_FUN, RK806_PIN_FUN_SLP); - } - - /* 8.set the SLP_VSEL/SLP_EN */ - for (j = 0; j < RK806_ID_END; j++) { - if (pdata->dvs_ctrl_mode[j] == mode) { - if (pdata->sleep_mode[j].sleep_en_val != 0) - rk806_field_write(rk806, - pdata->dvs_field[j].sleep_vsel, - pdata->sleep_mode[j].sleep_vsel_val); - rk806_field_write(rk806, - pdata->dvs_field[j].sleep_en, - pdata->sleep_mode[j].sleep_en_val); - } - } - - if (rk806->pins && rk806->pins->p && rk806->pins->sleep) - pinctrl_select_state(rk806->pins->p, rk806->pins->sleep); - - return 0; -} - - -static int rk806_regulator_dvs2noeffect_mode(struct platform_device *pdev) -{ - struct rk806_regulator_data *pdata = platform_get_drvdata(pdev); - struct rk806 *rk806 = pdata->rk806; - int rid; - int mode; - int gpio_level; - - - for (rid = RK806_ID_DCDC1; rid < RK806_ID_END; rid++) { - mode = pdata->dvs_ctrl_mode[rid]; - if ((mode < RK806_DVS_BY_CTR_PIN1) || (mode < RK806_DVS_BY_CTR_PIN3)) - break; - - /* 1. get the ctrl pin level */ - gpio_level = gpio_get_value(pdata->dvs_gpios[mode - 1]); - - if (gpio_level == 1) { - /* 2.if dvs_pin high level, the output voltage from SLP_VSEL/SLP_EN */ - rk806_field_write(rk806, - pdata->dvs_field[rid].on_vsel, - pdata->dvs_mode[rid].sleep_vsel_val); - rk806_field_write(rk806, - pdata->dvs_field[rid].en_reg, - pdata->dvs_mode[rid].sleep_en_val | - (pdata->dvs_field[rid].en_bit << 4)); - } - - /* 3.check the used count 1 */ - pdata->dvs_used[mode] |= BIT(rid); - if (pdata->dvs_used[mode] != pdata->dvs_flag[mode]) - break; - pdata->dvs_used[mode] = 0; - /* 4.switch to ON_VSEL/ON_EN */ - gpio_set_value(pdata->dvs_gpios[mode - 1], 0); - - /* set slp_fun NULL */ - if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN1) - rk806_field_write(rk806, SLP1_FUN, RK806_PIN_FUN_NULL); - else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN2) - rk806_field_write(rk806, SLP2_FUN, RK806_PIN_FUN_NULL); - else if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN3) - rk806_field_write(rk806, SLP3_FUN, RK806_PIN_FUN_NULL); - } - - return 0; -} - - static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int uv) { struct rk806_regulator_data *pdata = rdev_get_drvdata(rdev); @@ -757,52 +685,17 @@ static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int uv) struct rk806 *rk806 = pdata->rk806; int rid = rdev_get_id(rdev); int reg_offset; - unsigned int reg, j; - + unsigned int reg; if (sel < 0) return -EINVAL; - pdata->dvs_mode[rid].en_reg_val = rk806_field_read(rk806, - pdata->dvs_field[rid].en_reg); - pdata->dvs_mode[rid].on_vsel_val = rk806_field_read(rk806, - pdata->dvs_field[rid].on_vsel); - pdata->dvs_mode[rid].sleep_vsel_val = rk806_field_read(rk806, - pdata->dvs_field[rid].sleep_vsel); - pdata->dvs_mode[rid].sleep_en_val = rk806_field_read(rk806, - pdata->dvs_field[rid].sleep_en); - pdata->dvs_mode[rid].sleep_ctrl_sel_val = rk806_field_read(rk806, - pdata->dvs_field[rid].sleep_ctrl_sel); + reg_offset = rk806_get_reg_offset(rid); + reg = rdev->desc->vsel_reg + reg_offset; - if ((get_dvs_mode(rdev) < RK806_DVS_BY_CTR_PIN1) || - (get_dvs_mode(rdev) > RK806_DVS_BY_CTR_PIN3)) { - reg_offset = rk806_get_reg_offset(rid); - reg = rdev->desc->vsel_reg + reg_offset; - - if (rid == RK806_ID_PLDO6) { - for (j = 0; j < RK806_ID_END; j++) - rk806_field_write(rk806, - pdata->dvs_field[j].sleep_ctrl_sel, - RK806_PIN_FUN_SLP); - /* rk806_field_write(rk806, SLP1_POL, 0x01); */ - } - return regmap_update_bits(rdev->regmap, reg, - rdev->desc->vsel_mask, - sel); - } else { - pdata->sleep_mode[rid].sleep_vsel_val = sel; - rk806_regulator_dvs2sleep_mode(rdev); - - if (rid == RK806_ID_PLDO6) { - for (j = 0; j < RK806_ID_END; j++) - rk806_field_write(rk806, - gpio_dvs_id[j], - RK806_PIN_FUN_SLP); - /* rk806_field_write(rk806, SLP1_POL, 0x01); */ - } - } - - return 0; + return regmap_update_bits(rk806->regmap, reg, + rdev->desc->vsel_mask, + sel); } static int rk806_get_voltage_sel_regmap(struct regulator_dev *rdev) @@ -848,12 +741,11 @@ static int rk806_set_voltage(struct regulator_dev *rdev, rdev->desc->vsel_mask, sel); mode = get_dvs_mode(rdev); - if (mode == RK806_DVS_NOT_SUPPORT) return ret; - if ((mode >= RK806_DVS_BY_CTR_PIN1) && - (mode <= RK806_DVS_BY_CTR_PIN3)) + if ((mode >= RK806_DVS_PWRCTRL1) && + (mode <= RK806_DVS_PWRCTRL3)) rk806_do_gpio_dvs(rdev); else rk806_do_soft_dvs(rdev); @@ -871,13 +763,10 @@ static int rk806_regulator_is_enabled_regmap(struct regulator_dev *rdev) int mode; mode = get_dvs_mode(rdev); - - if ((mode >= RK806_DVS_BY_CTR_PIN1) && - (mode <= RK806_DVS_BY_CTR_PIN3)) { - pid = get_gpio_id(rdev); - gpio_level = gpio_get_value(pdata->dvs_gpios[pid]); - - if (gpio_level == 1) + pid = get_gpio_id(mode); + if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) { + gpio_level = gpiod_get_value(pdata->dvs_gpios[pid]); + if (gpio_level == 0) return rk806_field_read(rk806, pdata->dvs_field[rid].sleep_en); } @@ -894,13 +783,10 @@ static int rk806_regulator_enable_regmap(struct regulator_dev *rdev) int mode; mode = get_dvs_mode(rdev); - - if ((mode >= RK806_DVS_BY_CTR_PIN1) && - (mode <= RK806_DVS_BY_CTR_PIN3)) { - pid = get_gpio_id(rdev); - gpio_level = gpio_get_value(pdata->dvs_gpios[pid]); - - if (gpio_level == 1) + pid = get_gpio_id(mode); + if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) { + gpio_level = gpiod_get_value(pdata->dvs_gpios[pid]); + if (gpio_level == 0) return rk806_field_write(rk806, pdata->dvs_field[rid].sleep_en, 0x01); @@ -920,13 +806,10 @@ static int rk806_regulator_disable_regmap(struct regulator_dev *rdev) int mode; mode = get_dvs_mode(rdev); - - if ((mode >= RK806_DVS_BY_CTR_PIN1) && - (mode <= RK806_DVS_BY_CTR_PIN3)) { - pid = get_gpio_id(rdev); - gpio_level = gpio_get_value(pdata->dvs_gpios[pid]); - - if (gpio_level == 1) + pid = get_gpio_id(mode); + if ((pid >= 0) && (pdata->dvs_gpios[pid] != NULL)) { + gpio_level = gpiod_get_value(pdata->dvs_gpios[pid]); + if (gpio_level == 0) return rk806_field_write(rk806, pdata->dvs_field[rid].sleep_en, 0x00); @@ -1135,23 +1018,24 @@ static const struct regulator_desc rk806_regulators[] = { RK806_REGULATOR("PLDO_REG1", "vcc11", RK806_ID_PLDO1, rk806_ops_ldo, RK806_LDO_SEL_CNT, RK806_PLDO1_ON_VSEL, - RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0), + RK806_POWER_EN4, rk806_ldo_voltage_ranges, 1), RK806_REGULATOR("PLDO_REG2", "vcc11", RK806_ID_PLDO2, rk806_ops_ldo, RK806_LDO_SEL_CNT, RK806_PLDO2_ON_VSEL, - RK806_POWER_EN4, rk806_ldo_voltage_ranges, 1), + RK806_POWER_EN4, rk806_ldo_voltage_ranges, 2), RK806_REGULATOR("PLDO_REG3", "vcc11", RK806_ID_PLDO3, rk806_ops_ldo, RK806_LDO_SEL_CNT, RK806_PLDO3_ON_VSEL, - RK806_POWER_EN4, rk806_ldo_voltage_ranges, 2), - RK806_REGULATOR("PLDO_REG4", "vcc12", RK806_ID_PLDO4, rk806_ops_ldo, - RK806_LDO_SEL_CNT, RK806_PLDO4_ON_VSEL, RK806_POWER_EN4, rk806_ldo_voltage_ranges, 3), + RK806_REGULATOR("PLDO_REG4", "vcc12", RK806_ID_PLDO4, rk806_ops_ldo, + RK806_LDO_SEL_CNT, RK806_PLDO4_ON_VSEL, + RK806_POWER_EN5, rk806_ldo_voltage_ranges, 0), RK806_REGULATOR("PLDO_REG5", "vcc12", RK806_ID_PLDO5, rk806_ops_ldo, RK806_LDO_SEL_CNT, RK806_PLDO5_ON_VSEL, - RK806_POWER_EN5, rk806_ldo_voltage_ranges, 0), + RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1), + RK806_REGULATOR("PLDO_REG6", "vcca", RK806_ID_PLDO6, rk806_ops_ldo, RK806_LDO_SEL_CNT, RK806_PLDO6_ON_VSEL, - RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1), + RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0), }; static void rk806_regulator_dt_parse_pdata(struct rk806 *rk806, @@ -1159,22 +1043,32 @@ static void rk806_regulator_dt_parse_pdata(struct rk806 *rk806, struct rk806_regulator_data *pdata) { - char dvs_ctrl_name[7][32] = { "dvs_default", - "dvs_pin1_ctrl", - "dvs_pin2_ctrl", - "dvs_pin3_ctrl", - "start_dvs1_ctrl", - "start_dvs2_ctrl", - "start_dvs3_ctrl" }; + char dvs_ctrl_name[10][32] = { + "dvs_default", + "start_dvs1_ctrl", + "start_dvs2_ctrl", + "start_dvs3_ctrl", + "dvs_pin1_ctrl", + "dvs_pin2_ctrl", + "dvs_pin3_ctrl", + "start_and_pwrctrl1", + "start_and_pwrctrl2", + "start_and_pwrctrl3"}; char dvs_pin_name[3][30] = { "rk806,pmic-dvs-gpio1", "rk806,pmic-dvs-gpio2", "rk806,pmic-dvs-gpio3" }; struct device_node *np = rk806->dev->of_node; struct device_node *dn; - int i, j, gpio; + int i, j; pdata->support_dvs = 0; + for (i = 0; i < RK806_ID_END; i++) { + pdata->dvs_field[i] = rk806_dvs_fields[i]; + pdata->dvs_ctrl_id[i] = start_dvs_id[i]; + pdata->vsel_ctrl_id[i] = vsel_ctr_sel_id[i]; + } + for (j = 1; j < RK806_DVS_END; j++) { if (device_property_present(rk806->dev, dvs_ctrl_name[j])) { REG_DBG("%s:\n", dvs_ctrl_name[j]); @@ -1192,24 +1086,16 @@ static void rk806_regulator_dt_parse_pdata(struct rk806 *rk806, } } } - if (!pdata->support_dvs) return; for (i = 0; i < 3; i++) { - gpio = of_get_named_gpio(np, dvs_pin_name[i], i); - if (!gpio_is_valid(gpio)) { - dev_err(rk806->dev, "invalid gpio[%d]: %d\n", i, gpio); - break; - } - - pdata->dvs_gpios[i] = gpio; - } - - for (i = 0; i < 3; i++) { - if (pdata->dvs_gpios[i] >= 0) { - gpio_request(pdata->dvs_gpios[i], dvs_pin_name[i]); - gpio_direction_output(pdata->dvs_gpios[i], 0); + pdata->dvs_gpios[i] = devm_gpiod_get_optional(rk806->dev, + dvs_pin_name[i], + GPIOD_OUT_HIGH); + if (IS_ERR(pdata->dvs_gpios[i])) { + pdata->dvs_gpios[i] = NULL; + dev_info(rk806->dev, "Failed to get %s\n", dvs_pin_name[i]); } } } @@ -1257,8 +1143,16 @@ static int rk806_regulator_probe(struct platform_device *pdev) static int __maybe_unused rk806_suspend(struct device *dev) { struct rk806 *rk806 = dev_get_drvdata(dev->parent); + int i; - pinctrl_select_state(rk806->pins->p, rk806->pins->sleep); + rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_NULL_FUN); + rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_NULL_FUN); + rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_NULL_FUN); + + for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++) + rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_NO_EFFECT); + + rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_SLP_FUN); return 0; } @@ -1267,7 +1161,7 @@ static int __maybe_unused rk806_resume(struct device *dev) { struct rk806 *rk806 = dev_get_drvdata(dev->parent); - pinctrl_select_state(rk806->pins->p, rk806->pins->default_st); + rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_NULL_FUN); return 0; } @@ -1277,8 +1171,6 @@ static void rk806_regulator_shutdown(struct platform_device *pdev) { struct rk806 *rk806 = dev_get_drvdata(pdev->dev.parent); - rk806_regulator_dvs2noeffect_mode(pdev); - if (system_state == SYSTEM_POWER_OFF) if ((rk806->pins->p) && (rk806->pins->power_off)) pinctrl_select_state(rk806->pins->p, rk806->pins->power_off); diff --git a/include/linux/mfd/rk806.h b/include/linux/mfd/rk806.h index 1e35b09e468b..e422ddac6d1b 100644 --- a/include/linux/mfd/rk806.h +++ b/include/linux/mfd/rk806.h @@ -352,28 +352,30 @@ enum rk806_uv_sel { }; /* pin function */ -enum rk806_pin_fun { - RK806_PIN_FUN_NULL, - RK806_PIN_FUN_SLP, - RK806_PIN_FUN_PWROFF, - RK806_PIN_FUN_RST, - RK806_PIN_FUN_DVS, - RK806_PIN_FUN_GPIO, +enum rk806_pwrctrl_fun { + PWRCTRL_NULL_FUN, + PWRCTRL_SLP_FUN, + PWRCTRL_POWOFF_FUN, + PWRCTRL_RST_FUN, + PWRCTRL_DVS_FUN, + PWRCTRL_GPIO_FUN, }; /* pin pol */ enum rk806_pin_level { - RK806_PIN_POL_LOW, - RK806_PIN_POL_HIGH, + POL_LOW, + POL_HIGH, }; -enum rk806_pin_ctr_sel { - CTR_SEL_PIN1, - CTR_SEL_PIN2, - CTR_SEL_PIN3, +enum rk806_vsel_ctr_sel { + CTR_BY_NO_EFFECT, + CTR_BY_PWRCTRL1, + CTR_BY_PWRCTRL2, + CTR_BY_PWRCTRL3, }; -enum rk806_start_dvs_sel { +enum rk806_dvs_ctr_sel { + CTR_SEL_NO_EFFECT, CTR_SEL_DVS_START1, CTR_SEL_DVS_START2, CTR_SEL_DVS_START3, @@ -396,12 +398,15 @@ enum rk806_int_fun { enum rk806_dvs_mode { RK806_DVS_NOT_SUPPORT, - RK806_DVS_BY_CTR_PIN1, - RK806_DVS_BY_CTR_PIN2, - RK806_DVS_BY_CTR_PIN3, - RK806_DVS_BY_CTR_START1, - RK806_DVS_BY_CTR_START2, - RK806_DVS_BY_CTR_START3, + RK806_DVS_START1, + RK806_DVS_START2, + RK806_DVS_START3, + RK806_DVS_PWRCTRL1, + RK806_DVS_PWRCTRL2, + RK806_DVS_PWRCTRL3, + RK806_DVS_START_PWRCTR1, + RK806_DVS_START_PWRCTR2, + RK806_DVS_START_PWRCTR3, RK806_DVS_END, }; @@ -441,22 +446,23 @@ enum rk806_fields { VB_UV_DLY, VB_UV_SEL, VB_LO_ACT, VB_LO_SEL, ABNORDET_EN, TSD_TEMP, HOTDIE_TMP, SYS_OV_SD_EN, SYS_OV_SD_DLY_SEL, DLY_ABN_SHORT, VCCXDET_DIS, OSC_TC, ENB2_2M, ENB_32K, - SLP2_POL, SLP2_FUN, SLP1_POL, SLP1_FUN, - SLP3_POL, SLP3_FUN, - - BUCK4_SLP_CTR_SEL, BUCK3_SLP_CTR_SEL, BUCK2_SLP_CTR_SEL, BUCK1_SLP_CTR_SEL, - BUCK8_SLP_CTR_SEL, BUCK7_SLP_CTR_SEL, BUCK6_SLP_CTR_SEL, BUCK5_SLP_CTR_SEL, - NLDO2_SLP_CTR_SEL, NLDO1_SLP_CTR_SEL, BUCK10_SLP_CTR_SEL, BUCK9_SLP_CTR_SEL, - NLDO5_SLP_CTR_SEL, NLDO4_SLP_CTR_SEL, NLDO3_SLP_CTR_SEL, - PLDO4_SLP_CTR_SEL, PLDO3_SLP_CTR_SEL, PLDO2_SLP_CTR_SEL, PLDO1_SLP_CTR_SEL, - PLDO6_SLP_CTR_SEL, PLDO5_SLP_CTR_SEL, - BUCK4_DVS_CTR_SEL, BUCK3_DVS_CTR_SEL, BUCK2_DVS_CTR_SEL, BUCK1_DVS_CTR_SEL, - BUCK8_DVS_CTR_SEL, BUCK7_DVS_CTR_SEL, BUCK6_DVS_CTR_SEL, BUCK5_DVS_CTR_SEL, - NLDO2_DVS_CTR_SEL, NLDO1_DVS_CTR_SEL, BUCK10_DVS_CTR_SEL, BUCK9_DVS_CTR_SEL, - NLDO5_DVS_CTR_SEL, NLDO4_DVS_CTR_SEL, NLDO3_DVS_CTR_SEL, - PLDO4_DVS_CTR_SEL, PLDO3_DVS_CTR_SEL, PLDO2_DVS_CTR_SEL, PLDO1_DVS_CTR_SEL, - PLDO6_DVS_CTR_SEL, PLDO5_DVS_CTR_SEL, - DVS_START3, DVS_START2, DVS_START1, + PWRCTRL1_FUN, PWRCTRL2_FUN, PWRCTRL3_FUN, + PWRCTRL1_POL, PWRCTRL2_POL, PWRCTRL3_POL, + BUCK1_VSEL_CTR_SEL, BUCK2_VSEL_CTR_SEL, BUCK3_VSEL_CTR_SEL, BUCK4_VSEL_CTR_SEL, + BUCK5_VSEL_CTR_SEL, BUCK6_VSEL_CTR_SEL, BUCK7_VSEL_CTR_SEL, BUCK8_VSEL_CTR_SEL, + BUCK9_VSEL_CTR_SEL, BUCK10_VSEL_CTR_SEL, + NLDO1_VSEL_CTR_SEL, NLDO2_VSEL_CTR_SEL, NLDO3_VSEL_CTR_SEL, NLDO4_VSEL_CTR_SEL, + NLDO5_VSEL_CTR_SEL, + PLDO1_VSEL_CTR_SEL, PLDO2_VSEL_CTR_SEL, PLDO3_VSEL_CTR_SEL, PLDO4_VSEL_CTR_SEL, + PLDO5_VSEL_CTR_SEL, PLDO6_VSEL_CTR_SEL, + BUCK1_DVS_CTR_SEL, BUCK2_DVS_CTR_SEL, BUCK3_DVS_CTR_SEL, BUCK4_DVS_CTR_SEL, + BUCK5_DVS_CTR_SEL, BUCK6_DVS_CTR_SEL, BUCK7_DVS_CTR_SEL, BUCK8_DVS_CTR_SEL, + BUCK9_DVS_CTR_SEL, BUCK10_DVS_CTR_SEL, + NLDO1_DVS_CTR_SEL, NLDO2_DVS_CTR_SEL, NLDO3_DVS_CTR_SEL, NLDO4_DVS_CTR_SEL, + NLDO5_DVS_CTR_SEL, + PLDO1_DVS_CTR_SEL, PLDO2_DVS_CTR_SEL, PLDO3_DVS_CTR_SEL, PLDO4_DVS_CTR_SEL, + PLDO5_DVS_CTR_SEL, PLDO6_DVS_CTR_SEL, + DVS_START1, DVS_START2, DVS_START3, SLP3_DATA, SLP2_DATA, SLP1_DATA, SLP3_DR, SLP2_DR, SLP1_DR, RST_FUN, DEV_RST, DEV_SLP, SLAVE_RESTART_FUN, DEV_OFF,