mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
regulator: rk806: support shutdown/reset function
Signed-off-by: shengfei Xu <xsf@rock-chips.com> Change-Id: I3fecda310463dd183bb85adc0671f356ff81cd1a
This commit is contained in:
@@ -7,6 +7,19 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
|
||||
&pinctrl {
|
||||
pmic {
|
||||
soc_slppin_gpio: soc_slppin_gpio {
|
||||
rockchip,pins = <0 RK_PA2
|
||||
RK_FUNC_GPIO &pcfg_output_low>;
|
||||
};
|
||||
soc_slppin_shutdown: soc_slppin_shutdown {
|
||||
rockchip,pins = <0 RK_PA2
|
||||
RK_FUNC_GPIO &pcfg_output_high>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi2 {
|
||||
status = "okay";
|
||||
assigned-clocks = <&cru CLK_SPI2>;
|
||||
@@ -21,9 +34,9 @@
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
pinctrl-names = "pmic-sleep", "pmic-power-off", "pmic-reset";
|
||||
pinctrl-0 = <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-1 = <&rk806_dvs1_slp>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-names = "default", "pmic-sleep", "pmic-power-off", "pmic-reset";
|
||||
pinctrl-0 = <&soc_slppin_gpio>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-1 = <&soc_slppin_gpio>, <&rk806_dvs1_slp>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-2 = <&rk806_dvs1_pwrdn>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-3 = <&rk806_dvs1_rst>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
|
||||
@@ -35,6 +48,15 @@
|
||||
shutdown_temperture_threshold = <160>;
|
||||
hotdie_temperture_threshold = <115>;
|
||||
|
||||
/* 0: restart PMU;
|
||||
* 1: reset all the power off reset registers,
|
||||
* forcing the state to switch to ACTIVE mode;
|
||||
* 2: Reset all the power off reset registers,
|
||||
* forcing the state to switch to ACTIVE mode,
|
||||
* and simultaneously pull down the RESETB PIN for 5mS before releasing
|
||||
*/
|
||||
pmic-reset-func = <1>;
|
||||
|
||||
vcc1-supply = <&vcc5v0_sys>;
|
||||
vcc2-supply = <&vcc5v0_sys>;
|
||||
vcc3-supply = <&vcc5v0_sys>;
|
||||
@@ -399,11 +421,18 @@
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
pinctrl-names = "pmic-sleep", "pmic-power-off";
|
||||
pinctrl-0 = <&rk806_dvs1_null>, <&rk806_dvs2_null>;//, <&rk806_dvs3_null>;
|
||||
pinctrl-1 = <&rk806_dvs1_slp>, <&rk806_dvs2_null>;//, <&rk806_dvs3_null>;
|
||||
pinctrl-2 = <&rk806_dvs1_pwrdn>, <&rk806_dvs2_null>;//, <&rk806_dvs3_null>;
|
||||
pinctrl-3 = <&rk806_dvs1_rst>, <&rk806_dvs2_null>;//, <&rk806_dvs3_null>;
|
||||
pinctrl-names = "default", "pmic-sleep";
|
||||
pinctrl-0 = <&rk806_slave_dvs1_null>, <&rk806_slave_dvs2_null>, <&rk806_slave_dvs3_null>;
|
||||
pinctrl-1 = <&rk806_slave_dvs1_slp>, <&rk806_slave_dvs2_null>, <&rk806_slave_dvs3_null>;
|
||||
|
||||
/* 0: restart PMU;
|
||||
* 1: reset all the power off reset registers,
|
||||
* forcing the state to switch to ACTIVE mode;
|
||||
* 2: Reset all the power off reset registers,
|
||||
* forcing the state to switch to ACTIVE mode,
|
||||
* and simultaneously pull down the RESETB PIN for 5mS before releasing
|
||||
*/
|
||||
pmic-reset-func = <1>;
|
||||
|
||||
vcc1-supply = <&vcc5v0_sys>;
|
||||
vcc2-supply = <&vcc5v0_sys>;
|
||||
@@ -425,6 +454,91 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pinctrl_slave_rk806: pinctrl_slave_rk806 {
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
rk806_slave_dvs1_null: rk806_slave_dvs1_null {
|
||||
pins = "gpio_pwrctrl2";
|
||||
function = "pin_fun0";
|
||||
};
|
||||
|
||||
rk806_slave_dvs1_slp: rk806_slave_dvs1_slp {
|
||||
pins = "gpio_pwrctrl1";
|
||||
function = "pin_fun1";
|
||||
};
|
||||
|
||||
rk806_slave_dvs1_pwrdn: rk806_slave_dvs1_pwrdn {
|
||||
pins = "gpio_pwrctrl1";
|
||||
function = "pin_fun2";
|
||||
};
|
||||
|
||||
rk806_slave_dvs1_rst: rk806_slave_dvs1_rst {
|
||||
pins = "gpio_pwrctrl1";
|
||||
function = "pin_fun3";
|
||||
};
|
||||
|
||||
rk806_slave_dvs2_null: rk806_slave_dvs2_null {
|
||||
pins = "gpio_pwrctrl2";
|
||||
function = "pin_fun0";
|
||||
};
|
||||
|
||||
rk806_slave_dvs2_slp: rk806_slave_dvs2_slp {
|
||||
pins = "gpio_pwrctrl2";
|
||||
function = "pin_fun1";
|
||||
};
|
||||
|
||||
rk806_slave_dvs2_pwrdn: rk806_slave_dvs2_pwrdn {
|
||||
pins = "gpio_pwrctrl2";
|
||||
function = "pin_fun2";
|
||||
};
|
||||
|
||||
rk806_slave_dvs2_rst: rk806_slave_dvs2_rst {
|
||||
pins = "gpio_pwrctrl2";
|
||||
function = "pin_fun3";
|
||||
};
|
||||
|
||||
rk806_slave_dvs2_dvs: rk806_slave_dvs2_dvs {
|
||||
pins = "gpio_pwrctrl2";
|
||||
function = "pin_fun4";
|
||||
};
|
||||
|
||||
rk806_slave_dvs2_gpio: rk806_slave_dvs2_gpio {
|
||||
pins = "gpio_pwrctrl2";
|
||||
function = "pin_fun5";
|
||||
};
|
||||
|
||||
rk806_slave_dvs3_null: rk806_slave_dvs3_null {
|
||||
pins = "gpio_pwrctrl3";
|
||||
function = "pin_fun0";
|
||||
};
|
||||
|
||||
rk806_slave_dvs3_slp: rk806_slave_dvs3_slp {
|
||||
pins = "gpio_pwrctrl3";
|
||||
function = "pin_fun1";
|
||||
};
|
||||
|
||||
rk806_slave_dvs3_pwrdn: rk806_slave_dvs3_pwrdn {
|
||||
pins = "gpio_pwrctrl3";
|
||||
function = "pin_fun2";
|
||||
};
|
||||
|
||||
rk806_slave_dvs3_rst: rk806_slave_dvs3_rst {
|
||||
pins = "gpio_pwrctrl3";
|
||||
function = "pin_fun3";
|
||||
};
|
||||
|
||||
rk806_slave_dvs3_dvs: rk806_slave_dvs3_dvs {
|
||||
pins = "gpio_pwrctrl3";
|
||||
function = "pin_fun4";
|
||||
};
|
||||
|
||||
rk806_slave_dvs3_gpio: rk806_slave_dvs3_gpio {
|
||||
pins = "gpio_pwrctrl3";
|
||||
function = "pin_fun5";
|
||||
};
|
||||
};
|
||||
|
||||
regulators {
|
||||
vdd_cpu_big1_s0: DCDC_REG1 {
|
||||
regulator-always-on;
|
||||
|
||||
@@ -127,6 +127,17 @@
|
||||
rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>;
|
||||
};
|
||||
};
|
||||
|
||||
pmic {
|
||||
soc_slppin_gpio: soc_slppin_gpio {
|
||||
rockchip,pins = <0 RK_PA2
|
||||
RK_FUNC_GPIO &pcfg_output_low>;
|
||||
};
|
||||
soc_slppin_shutdown: soc_slppin_shutdown {
|
||||
rockchip,pins = <0 RK_PA2
|
||||
RK_FUNC_GPIO &pcfg_output_high>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi2 {
|
||||
@@ -143,9 +154,9 @@
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
pinctrl-names = "pmic-sleep", "pmic-power-off", "pmic-reset";
|
||||
pinctrl-0 = <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-1 = <&rk806_dvs1_slp>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-names = "default", "pmic-sleep", "pmic-power-off", "pmic-reset";
|
||||
pinctrl-0 = <&soc_slppin_gpio>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-1 = <&soc_slppin_gpio>, <&rk806_dvs1_slp>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-2 = <&rk806_dvs1_pwrdn>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
pinctrl-3 = <&rk806_dvs1_rst>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
|
||||
|
||||
@@ -157,6 +168,15 @@
|
||||
shutdown_temperture_threshold = <160>;
|
||||
hotdie_temperture_threshold = <115>;
|
||||
|
||||
/* 0: restart PMU;
|
||||
* 1: reset all the power off reset registers,
|
||||
* forcing the state to switch to ACTIVE mode;
|
||||
* 2: Reset all the power off reset registers,
|
||||
* forcing the state to switch to ACTIVE mode,
|
||||
* and simultaneously pull down the RESETB PIN for 5mS before releasing
|
||||
*/
|
||||
pmic-reset-func = <1>;
|
||||
|
||||
vcc1-supply = <&vcc5v0_sys>;
|
||||
vcc2-supply = <&vcc5v0_sys>;
|
||||
vcc3-supply = <&vcc5v0_sys>;
|
||||
|
||||
@@ -171,9 +171,12 @@ static const struct reg_field rk806_reg_fields[] = {
|
||||
[VB_LO_ACT] = REG_FIELD(0x5E, 3, 3),
|
||||
[VB_LO_SEL] = REG_FIELD(0x5E, 0, 2),
|
||||
/* SYS_CFG1 */
|
||||
[ABNORDET_EN] = REG_FIELD(0x5F, 7, 7),
|
||||
[TSD_TEMP] = REG_FIELD(0x5F, 6, 6),
|
||||
[HOTDIE_TMP] = REG_FIELD(0x5F, 4, 5),
|
||||
[VPREREG_SEL] = REG_FIELD(0x5F, 0, 1),
|
||||
[SYS_OV_SD_EN] = REG_FIELD(0x5F, 3, 3),
|
||||
[SYS_OV_SD_DLY_SEL] = REG_FIELD(0x5F, 2, 2),
|
||||
[DLY_ABN_SHORT] = REG_FIELD(0x5F, 0, 1),
|
||||
/* SYS_OPTION */
|
||||
[VCCXDET_DIS] = REG_FIELD(0x61, 4, 5),
|
||||
[OSC_TC] = REG_FIELD(0x61, 2, 3),
|
||||
@@ -261,6 +264,8 @@ static const struct reg_field rk806_reg_fields[] = {
|
||||
[WDT_CLR] = REG_FIELD(0x73, 4, 4),
|
||||
[WDT_EN] = REG_FIELD(0x73, 3, 3),
|
||||
[WDT_SET] = REG_FIELD(0x73, 0, 3),
|
||||
[ON_SOURCE] = REG_FIELD(0x74, 0, 7),
|
||||
[OFF_SOURCE] = REG_FIELD(0x75, 0, 7),
|
||||
/* PWRON_KEY */
|
||||
[PWRON_ON_TIME] = REG_FIELD(0x76, 7, 7),
|
||||
[PWRON_LP_ACT] = REG_FIELD(0x76, 6, 6),
|
||||
@@ -479,6 +484,7 @@ static int rk806_parse_dt(struct rk806 *rk806)
|
||||
{
|
||||
struct rk806_platform_data *pdata;
|
||||
struct device *dev = rk806->dev;
|
||||
int rst_fun;
|
||||
int ret;
|
||||
|
||||
pdata = rk806->pdata;
|
||||
@@ -527,6 +533,13 @@ static int rk806_parse_dt(struct rk806 *rk806)
|
||||
if (ret < 0)
|
||||
dev_info(dev, "hotdie_temperture_threshold missing!\n");
|
||||
|
||||
ret = device_property_read_u32(dev, "pmic-reset-func", &rst_fun);
|
||||
if (ret < 0) {
|
||||
dev_info(dev, "pmic-reset-func missing!\n");
|
||||
rk806_field_write(rk806, RST_FUN, 0x00);
|
||||
} else
|
||||
rk806_field_write(rk806, RST_FUN, rst_fun);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -549,6 +562,9 @@ static int rk806_init(struct rk806 *rk806)
|
||||
if (pdata->hotdie_temperture_threshold >= 160)
|
||||
rk806_field_write(rk806, TSD_TEMP, TSD_TEMP_160);
|
||||
|
||||
/* When the slave chip goes through a shutdown process, it will automatically trigger a restart */
|
||||
rk806_field_write(rk806, SLAVE_RESTART_FUN, 0x01);
|
||||
|
||||
rk806_low_power_irqs(rk806);
|
||||
|
||||
return 0;
|
||||
@@ -587,9 +603,11 @@ int rk806_device_init(struct rk806 *rk806)
|
||||
otp_ver = rk806_field_read(rk806, OTP_VER);
|
||||
dev_info(rk806->dev, "chip id: RK%x%x,ver:0x%x, 0x%x\n",
|
||||
name_h, name_l, chip_ver, otp_ver);
|
||||
if (chip_ver == VERSION_AB)
|
||||
rk806_field_write(rk806, ABNORDET_EN, 0x01);
|
||||
|
||||
on_source = regmap_read(rk806->regmap, RK806_ON_SOURCE, &on_source);
|
||||
off_source = regmap_read(rk806->regmap, RK806_OFF_SOURCE, &off_source);
|
||||
on_source = rk806_field_read(rk806, ON_SOURCE);
|
||||
off_source = rk806_field_read(rk806, OFF_SOURCE);
|
||||
dev_info(rk806->dev, "ON: 0x%x OFF:0x%x\n", on_source, off_source);
|
||||
|
||||
rk806_parse_dt(rk806);
|
||||
|
||||
@@ -157,7 +157,7 @@ struct rk806_regulator_data {
|
||||
int dvs_flag[RK806_DVS_END];
|
||||
int dvs_used[RK806_DVS_END];
|
||||
int dvs_count[RK806_DVS_END];
|
||||
int dvs_init;
|
||||
int regulator_init;
|
||||
int support_dvs;
|
||||
struct rk806 *rk806;
|
||||
};
|
||||
@@ -258,7 +258,7 @@ static int get_dvs_mode(struct regulator_dev *rdev)
|
||||
if (!pdata->support_dvs)
|
||||
return RK806_DVS_NOT_SUPPORT;
|
||||
|
||||
if (pdata->dvs_ctrl_mode_init[rid])
|
||||
if (pdata->dvs_ctrl_mode_init[rid] || pdata->regulator_init)
|
||||
return pdata->dvs_ctrl_mode[rid];
|
||||
|
||||
for (i = 0; i < RK806_DVS_END; i++) {
|
||||
@@ -270,6 +270,7 @@ static int get_dvs_mode(struct regulator_dev *rdev)
|
||||
pdata->dvs_ctrl_mode[rid] = i;
|
||||
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)
|
||||
@@ -383,9 +384,6 @@ static void rk806_do_gpio_dvs(struct regulator_dev *rdev)
|
||||
int gpio_level, pid;
|
||||
int mode, count;
|
||||
|
||||
if (pdata->dvs_init == 0)
|
||||
return;
|
||||
|
||||
mode = get_dvs_mode(rdev);
|
||||
if ((mode >= RK806_DVS_BY_CTR_PIN1) &&
|
||||
(mode <= RK806_DVS_BY_CTR_PIN3)) {
|
||||
@@ -423,9 +421,6 @@ static void rk806_do_soft_dvs(struct regulator_dev *rdev)
|
||||
int rid = rdev_get_id(rdev);
|
||||
int soft_mode, count;
|
||||
|
||||
if (pdata->dvs_init == 0)
|
||||
return;
|
||||
|
||||
soft_mode = get_dvs_mode(rdev);
|
||||
|
||||
if ((soft_mode >= RK806_DVS_BY_CTR_START1) &&
|
||||
@@ -624,8 +619,6 @@ static int rk806_regulator_resume(struct regulator_dev *rdev)
|
||||
}
|
||||
}
|
||||
|
||||
rk806_field_write(rk806, SLP1_POL, 0x00);
|
||||
|
||||
if ((get_dvs_mode(rdev) >= RK806_DVS_BY_CTR_PIN1) &&
|
||||
(get_dvs_mode(rdev) <= RK806_DVS_BY_CTR_PIN3))
|
||||
rk806_regulator_sleep2dvs_mode(rdev);
|
||||
@@ -683,7 +676,7 @@ static int rk806_regulator_dvs2sleep_mode(struct regulator_dev *rdev)
|
||||
|
||||
if (pdata->dvs_ctrl_mode[rid] == RK806_DVS_BY_CTR_PIN1) {
|
||||
/* 6.the slp pin avctive high */
|
||||
rk806_field_write(rk806, SLP1_POL, 0x01);
|
||||
/* rk806_field_write(rk806, SLP1_POL, 0x01); */
|
||||
/* 7.switch to sleep function */
|
||||
rk806_field_write(rk806, SLP1_FUN, RK806_PIN_FUN_SLP);
|
||||
}
|
||||
@@ -707,6 +700,56 @@ static int rk806_regulator_dvs2sleep_mode(struct regulator_dev *rdev)
|
||||
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);
|
||||
@@ -716,6 +759,7 @@ static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
|
||||
int reg_offset;
|
||||
unsigned int reg, j;
|
||||
|
||||
|
||||
if (sel < 0)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -740,16 +784,12 @@ static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
|
||||
rk806_field_write(rk806,
|
||||
pdata->dvs_field[j].sleep_ctrl_sel,
|
||||
RK806_PIN_FUN_SLP);
|
||||
rk806_field_write(rk806, SLP1_POL, 0x01);
|
||||
/* rk806_field_write(rk806, SLP1_POL, 0x01); */
|
||||
}
|
||||
return regmap_update_bits(rdev->regmap, reg,
|
||||
rdev->desc->vsel_mask,
|
||||
sel);
|
||||
} else {
|
||||
/* power on set state */
|
||||
if (!pdata->dvs_init)
|
||||
return 0;
|
||||
|
||||
pdata->sleep_mode[rid].sleep_vsel_val = sel;
|
||||
rk806_regulator_dvs2sleep_mode(rdev);
|
||||
|
||||
@@ -758,7 +798,7 @@ static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
|
||||
rk806_field_write(rk806,
|
||||
gpio_dvs_id[j],
|
||||
RK806_PIN_FUN_SLP);
|
||||
rk806_field_write(rk806, SLP1_POL, 0x01);
|
||||
/* rk806_field_write(rk806, SLP1_POL, 0x01); */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,17 +877,12 @@ static int rk806_regulator_is_enabled_regmap(struct regulator_dev *rdev)
|
||||
pid = get_gpio_id(rdev);
|
||||
gpio_level = gpio_get_value(pdata->dvs_gpios[pid]);
|
||||
|
||||
if (gpio_level == 1) {
|
||||
if (gpio_level == 1)
|
||||
return rk806_field_read(rk806, pdata->dvs_field[rid].sleep_en);
|
||||
} else {
|
||||
val = rk806_field_read(rk806, pdata->dvs_field[rid].en_reg);
|
||||
return val & rdev->desc->enable_val;
|
||||
}
|
||||
}
|
||||
|
||||
val = rk806_field_read(rk806, pdata->dvs_field[rid].en_reg);
|
||||
|
||||
return val & rdev->desc->enable_val;
|
||||
val = rk806_field_read(rk806, pdata->dvs_field[rid].en_reg);
|
||||
return (val & rdev->desc->enable_val) != 0;
|
||||
}
|
||||
|
||||
static int rk806_regulator_enable_regmap(struct regulator_dev *rdev)
|
||||
@@ -869,10 +904,6 @@ static int rk806_regulator_enable_regmap(struct regulator_dev *rdev)
|
||||
return rk806_field_write(rk806,
|
||||
pdata->dvs_field[rid].sleep_en,
|
||||
0x01);
|
||||
else
|
||||
return rk806_field_write(rk806,
|
||||
pdata->dvs_field[rid].en_reg,
|
||||
rdev->desc->enable_val);
|
||||
}
|
||||
|
||||
return rk806_field_write(rk806,
|
||||
@@ -899,10 +930,6 @@ static int rk806_regulator_disable_regmap(struct regulator_dev *rdev)
|
||||
return rk806_field_write(rk806,
|
||||
pdata->dvs_field[rid].sleep_en,
|
||||
0x00);
|
||||
else
|
||||
return rk806_field_write(rk806,
|
||||
pdata->dvs_field[rid].en_reg,
|
||||
rdev->desc->disable_val);
|
||||
}
|
||||
|
||||
return rk806_field_write(rk806,
|
||||
@@ -1187,34 +1214,6 @@ static void rk806_regulator_dt_parse_pdata(struct rk806 *rk806,
|
||||
}
|
||||
}
|
||||
|
||||
static void rk806_init_dvs_mode(struct regulator_dev *rdev,
|
||||
struct rk806_regulator_data *pdata)
|
||||
{
|
||||
int rid;
|
||||
int i, j;
|
||||
|
||||
if (!pdata->support_dvs)
|
||||
return;
|
||||
|
||||
for (i = 0; i < RK806_DVS_END; i++) {
|
||||
for (j = 0; j < RK806_ID_END; j++) {
|
||||
pdata->dvs_ctrl_mode_init[j] = 1;
|
||||
if (!pdata->dvs_dn[i][j])
|
||||
break;
|
||||
if (strcmp(pdata->dvs_dn[i][j]->name, rdev->desc->name))
|
||||
continue;
|
||||
|
||||
rid = rdev_get_id(rdev);
|
||||
pdata->dvs_ctrl_mode[rid] = i;
|
||||
pdata->dvs_flag[i] |= BIT(rid);
|
||||
pdata->dvs_init = 1;
|
||||
pdata->dvs_field[j] = rk806_dvs_field[j];
|
||||
rk806_regulator_sync_voltage(rdev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int rk806_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk806 *rk806 = dev_get_drvdata(pdev->dev.parent);
|
||||
@@ -1247,12 +1246,49 @@ static int rk806_regulator_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
rk806_init_dvs_mode(rdev, pdata);
|
||||
rk806_regulator_sync_voltage(rdev);
|
||||
}
|
||||
|
||||
pdata->regulator_init = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rk806_suspend(struct device *dev)
|
||||
{
|
||||
struct rk806 *rk806 = dev_get_drvdata(dev->parent);
|
||||
|
||||
pinctrl_select_state(rk806->pins->p, rk806->pins->sleep);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
SIMPLE_DEV_PM_OPS(rk806_pm_ops, rk806_suspend, rk806_resume);
|
||||
|
||||
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);
|
||||
|
||||
if (system_state == SYSTEM_RESTART)
|
||||
if ((rk806->pins->p) && (rk806->pins->power_off))
|
||||
pinctrl_select_state(rk806->pins->p, rk806->pins->reset);
|
||||
|
||||
}
|
||||
|
||||
static const struct platform_device_id rk806_regulator_id_table[] = {
|
||||
{ "rk806-regulator", },
|
||||
{ /* sentinel */ }
|
||||
@@ -1262,9 +1298,11 @@ MODULE_DEVICE_TABLE(platform, rk806_regulator_id_table);
|
||||
static struct platform_driver rk806_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "rk806-regulator",
|
||||
.pm = &rk806_pm_ops,
|
||||
},
|
||||
.probe = rk806_regulator_probe,
|
||||
.id_table = rk806_regulator_id_table,
|
||||
.shutdown = rk806_regulator_shutdown,
|
||||
};
|
||||
module_platform_driver(rk806_regulator_driver);
|
||||
|
||||
|
||||
@@ -275,6 +275,8 @@
|
||||
#define RK806_CMD_LEN_MSK 0x0f
|
||||
#define RK806_REG_H 0x00
|
||||
|
||||
#define VERSION_AB 0x01
|
||||
|
||||
enum rk806_reg_id {
|
||||
RK806_ID_DCDC1 = 0,
|
||||
RK806_ID_DCDC2,
|
||||
@@ -437,7 +439,7 @@ enum rk806_fields {
|
||||
BUCK7_RATE, BUCK8_RATE, BUCK9_RATE, BUCK10_RATE,
|
||||
PWRON_STS, VDC_STS, VB_UV_STSS, VB_LO_STS, HOTDIE_STS, TSD_STS, VB_OV_STS,
|
||||
VB_UV_DLY, VB_UV_SEL, VB_LO_ACT, VB_LO_SEL,
|
||||
TSD_TEMP, HOTDIE_TMP, VPREREG_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,
|
||||
@@ -458,7 +460,7 @@ enum rk806_fields {
|
||||
SLP3_DATA, SLP2_DATA, SLP1_DATA, SLP3_DR, SLP2_DR, SLP1_DR,
|
||||
|
||||
RST_FUN, DEV_RST, DEV_SLP, SLAVE_RESTART_FUN, DEV_OFF,
|
||||
WDT_CLR, WDT_EN, WDT_SET,
|
||||
WDT_CLR, WDT_EN, WDT_SET, ON_SOURCE, OFF_SOURCE,
|
||||
ON_PWRON, ON_VDC, RESTART_RESETB, RESTART_PWRON_LP, RESTART_SLP,
|
||||
RESTART_DEV_RST, RESTART_WDT,
|
||||
OFF_SLP, VB_SYS_OV, OFF_TSD, OFF_DEV_OFF, OFF_PWRON_LP, OFF_VB_LO,
|
||||
|
||||
Reference in New Issue
Block a user