mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
mfd: rk808: Add rk801 PMIC support
PMIC RK801 consists of: - 4 x BUCK - 2 x LDO - 1 x SWITCH - 1 x Pwrkey Signed-off-by: Joseph Chen <chenjh@rock-chips.com> Change-Id: If65c2c3ac41cd6c6199e22c65c54e8600c113148
This commit is contained in:
@@ -30,6 +30,23 @@ struct rk808_reg_data {
|
||||
int value;
|
||||
};
|
||||
|
||||
static bool rk801_is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case RK801_SYS_STS_REG:
|
||||
case RK801_INT_STS0_REG:
|
||||
case RK801_SYS_CFG0_REG:
|
||||
case RK801_SYS_CFG1_REG:
|
||||
case RK801_SYS_CFG2_REG:
|
||||
case RK801_SYS_CFG3_REG:
|
||||
case RK801_SYS_CFG4_REG:
|
||||
case RK801_SLEEP_CFG_REG:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
/*
|
||||
@@ -126,6 +143,14 @@ static const struct regmap_config rk818_regmap_config = {
|
||||
.volatile_reg = rk818_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk801_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK801_SYS_CFG3_OTP_REG,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = rk801_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk805_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@@ -171,6 +196,11 @@ static const struct resource rk817_rtc_resources[] = {
|
||||
DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM),
|
||||
};
|
||||
|
||||
static const struct resource rk801_key_resources[] = {
|
||||
DEFINE_RES_IRQ(RK801_IRQ_PWRON_FALL),
|
||||
DEFINE_RES_IRQ(RK801_IRQ_PWRON_RISE),
|
||||
};
|
||||
|
||||
static const struct resource rk805_key_resources[] = {
|
||||
DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
|
||||
DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
|
||||
@@ -186,6 +216,15 @@ static const struct resource rk817_pwrkey_resources[] = {
|
||||
DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
|
||||
};
|
||||
|
||||
static const struct mfd_cell rk801s[] = {
|
||||
{ .name = "rk808-regulator", },
|
||||
{
|
||||
.name = "rk805-pwrkey",
|
||||
.num_resources = ARRAY_SIZE(rk801_key_resources),
|
||||
.resources = &rk801_key_resources[0],
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell rk805s[] = {
|
||||
{ .name = "rk808-clkout", },
|
||||
{ .name = "rk808-regulator", },
|
||||
@@ -258,6 +297,15 @@ static const struct mfd_cell rk818s[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rk808_reg_data rk801_pre_init_reg[] = {
|
||||
{ RK801_SLEEP_CFG_REG, RK801_SLEEP_FUN_MSK, RK801_NONE_FUN },
|
||||
{ RK801_SYS_CFG2_REG, RK801_SLEEP_POL_MSK, RK801_SLEEP_ACT_H },
|
||||
{ RK801_INT_CONFIG_REG, RK801_INT_POL_MSK, RK801_INT_ACT_L },
|
||||
{ RK801_POWER_FPWM_EN_REG, RK801_PLDO_HRDEC_EN, RK801_PLDO_HRDEC_EN },
|
||||
{ RK801_BUCK_DEBUG5_REG, 0xff, 0x54 },
|
||||
{ RK801_CON_BACK1_REG, 0xff, 0x18 },
|
||||
};
|
||||
|
||||
static const struct rk808_reg_data rk805_pre_init_reg[] = {
|
||||
{RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
|
||||
{RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SLEEP_FUN},
|
||||
@@ -415,6 +463,37 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = {
|
||||
{RK808_CLK32OUT_REG, CLK32KOUT2_FUNC_MASK, CLK32KOUT2_FUNC},
|
||||
};
|
||||
|
||||
static const struct regmap_irq rk801_irqs[] = {
|
||||
[RK801_IRQ_PWRON_FALL] = {
|
||||
.mask = RK801_IRQ_PWRON_FALL_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK801_IRQ_PWRON_RISE] = {
|
||||
.mask = RK801_IRQ_PWRON_RISE_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK801_IRQ_PWRON] = {
|
||||
.mask = RK801_IRQ_PWRON_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK801_IRQ_PWRON_LP] = {
|
||||
.mask = RK801_IRQ_PWRON_LP_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK801_IRQ_HOTDIE] = {
|
||||
.mask = RK801_IRQ_HOTDIE_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK801_IRQ_VDC_RISE] = {
|
||||
.mask = RK801_IRQ_VDC_RISE_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK801_IRQ_VDC_FALL] = {
|
||||
.mask = RK801_IRQ_VDC_FALL_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_irq rk805_irqs[] = {
|
||||
[RK805_IRQ_PWRON_RISE] = {
|
||||
.mask = RK805_IRQ_PWRON_RISE_MSK,
|
||||
@@ -653,6 +732,17 @@ static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
|
||||
REGMAP_IRQ_REG_LINE(23, 8)
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip rk801_irq_chip = {
|
||||
.name = "rk801",
|
||||
.irqs = rk801_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk801_irqs),
|
||||
.num_regs = 1,
|
||||
.status_base = RK801_INT_STS0_REG,
|
||||
.mask_base = RK801_INT_MASK0_REG,
|
||||
.ack_base = RK801_INT_STS0_REG,
|
||||
.init_ack_masked = true,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip rk805_irq_chip = {
|
||||
.name = "rk805",
|
||||
.irqs = rk805_irqs,
|
||||
@@ -759,6 +849,23 @@ static struct i2c_client *rk808_i2c_client;
|
||||
static struct rk808_reg_data *suspend_reg, *resume_reg;
|
||||
static int suspend_reg_num, resume_reg_num;
|
||||
|
||||
static int rk801_device_shutdown_prepare(struct sys_off_data *data)
|
||||
{
|
||||
int ret = 0;
|
||||
struct rk808 *rk808 = data->cb_data;
|
||||
|
||||
if (!rk808)
|
||||
return -1;
|
||||
|
||||
ret = regmap_update_bits(rk808->regmap, RK801_SYS_CFG2_REG,
|
||||
RK801_SLEEP_POL_MSK, RK801_SLEEP_ACT_H);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return regmap_update_bits(rk808->regmap, RK801_SLEEP_CFG_REG,
|
||||
RK801_SLEEP_FUN_MSK, RK801_SHUTDOWN_FUN);
|
||||
}
|
||||
|
||||
static int rk805_device_shutdown_prepare(struct sys_off_data *data)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -828,6 +935,10 @@ static void rk8xx_device_shutdown(void)
|
||||
struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
|
||||
|
||||
switch (rk808->variant) {
|
||||
case RK801_ID:
|
||||
reg = RK801_SYS_CFG2_REG;
|
||||
bit = DEV_OFF;
|
||||
break;
|
||||
case RK805_ID:
|
||||
reg = RK805_DEV_CTRL_REG;
|
||||
bit = DEV_OFF;
|
||||
@@ -866,13 +977,16 @@ static void rk8xx_syscore_shutdown(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/* close rtc int when power off */
|
||||
regmap_update_bits(rk808->regmap,
|
||||
RK808_INT_STS_MSK_REG1,
|
||||
(0x3 << 5), (0x3 << 5));
|
||||
regmap_update_bits(rk808->regmap,
|
||||
RK808_RTC_INT_REG,
|
||||
(0x3 << 2), (0x0 << 2));
|
||||
if (rk808->variant != RK801_ID) {
|
||||
/* close rtc int when power off */
|
||||
regmap_update_bits(rk808->regmap,
|
||||
RK808_INT_STS_MSK_REG1,
|
||||
(0x3 << 5), (0x3 << 5));
|
||||
regmap_update_bits(rk808->regmap,
|
||||
RK808_RTC_INT_REG,
|
||||
(0x3 << 2), (0x0 << 2));
|
||||
}
|
||||
|
||||
/*
|
||||
* For PMIC that power off supplies by write register via i2c bus,
|
||||
* it's better to do power off at syscore shutdown here.
|
||||
@@ -1181,6 +1295,7 @@ static struct device_attribute rk8xx_attrs =
|
||||
__ATTR(rk8xx_dbg, 0200, NULL, rk8xx_dbg_store);
|
||||
|
||||
static const struct of_device_id rk808_of_match[] = {
|
||||
{ .compatible = "rockchip,rk801" },
|
||||
{ .compatible = "rockchip,rk805" },
|
||||
{ .compatible = "rockchip,rk808" },
|
||||
{ .compatible = "rockchip,rk809" },
|
||||
@@ -1220,6 +1335,9 @@ static int rk808_probe(struct i2c_client *client,
|
||||
of_device_is_compatible(np, "rockchip,rk809")) {
|
||||
pmic_id_msb = RK817_ID_MSB;
|
||||
pmic_id_lsb = RK817_ID_LSB;
|
||||
} else if (of_device_is_compatible(np, "rockchip,rk801")) {
|
||||
pmic_id_msb = RK801_ID_MSB;
|
||||
pmic_id_lsb = RK801_ID_LSB;
|
||||
} else {
|
||||
pmic_id_msb = RK808_ID_MSB;
|
||||
pmic_id_lsb = RK808_ID_LSB;
|
||||
@@ -1244,6 +1362,17 @@ static int rk808_probe(struct i2c_client *client,
|
||||
dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
|
||||
|
||||
switch (rk808->variant) {
|
||||
case RK801_ID:
|
||||
rk808->regmap_cfg = &rk801_regmap_config;
|
||||
rk808->regmap_irq_chip = &rk801_irq_chip;
|
||||
pre_init_reg = rk801_pre_init_reg;
|
||||
nr_pre_init_regs = ARRAY_SIZE(rk801_pre_init_reg);
|
||||
cells = rk801s;
|
||||
nr_cells = ARRAY_SIZE(rk801s);
|
||||
on_source = RK801_ON_SOURCE_REG;
|
||||
off_source = RK801_OFF_SOURCE_REG;
|
||||
device_shutdown_fn = rk8xx_device_shutdown;
|
||||
break;
|
||||
case RK805_ID:
|
||||
rk808->regmap_cfg = &rk805_regmap_config;
|
||||
rk808->regmap_irq_chip = &rk805_irq_chip;
|
||||
@@ -1403,6 +1532,18 @@ static int rk808_probe(struct i2c_client *client,
|
||||
|
||||
if (of_property_read_bool(np, "rockchip,system-power-controller")) {
|
||||
switch (rk808->variant) {
|
||||
case RK801_ID:
|
||||
ret = devm_register_sys_off_handler(&client->dev,
|
||||
SYS_OFF_MODE_POWER_OFF_PREPARE,
|
||||
SYS_OFF_PRIO_DEFAULT,
|
||||
rk801_device_shutdown_prepare,
|
||||
rk808);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to register sys-off handler: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case RK805_ID:
|
||||
ret = devm_register_sys_off_handler(&client->dev,
|
||||
SYS_OFF_MODE_POWER_OFF_PREPARE,
|
||||
@@ -1493,6 +1634,15 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
|
||||
}
|
||||
|
||||
switch (rk808->variant) {
|
||||
case RK801_ID:
|
||||
ret = regmap_update_bits(rk808->regmap, RK801_SYS_CFG2_REG,
|
||||
RK801_SLEEP_POL_MSK, RK801_SLEEP_ACT_H);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(rk808->regmap, RK801_SLEEP_CFG_REG,
|
||||
RK801_SLEEP_FUN_MSK, RK801_SLEEP_FUN);
|
||||
break;
|
||||
case RK805_ID:
|
||||
ret = regmap_update_bits(rk808->regmap,
|
||||
RK805_GPIO_IO_POL_REG,
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
/* Field Definitions */
|
||||
#define RK801_BUCK_VSEL_MASK 0x7f
|
||||
#define RK801_LDO_VSEL_MASK 0x3f
|
||||
|
||||
#define RK808_BUCK_VSEL_MASK 0x3f
|
||||
#define RK808_BUCK4_VSEL_MASK 0xf
|
||||
#define RK808_LDO_VSEL_MASK 0x1f
|
||||
@@ -118,6 +121,11 @@
|
||||
.ops = _ops, \
|
||||
}
|
||||
|
||||
#define RK801_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
_vmask, _ereg, _emask, _disval, _etime) \
|
||||
RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
_vmask, _ereg, _emask, _emask, _disval, _etime, &rk801_reg_ops)
|
||||
|
||||
#define RK816_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
_vmask, _ereg, _emask, _disval, _etime) \
|
||||
RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
@@ -155,6 +163,10 @@
|
||||
.ops = _ops \
|
||||
}
|
||||
|
||||
#define RK801_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, _disval) \
|
||||
RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \
|
||||
_emask, _disval, &rk801_switch_ops)
|
||||
|
||||
#define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, _enval, \
|
||||
_disval) \
|
||||
RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \
|
||||
@@ -175,6 +187,31 @@ static const int rk808_buck_config_regs[] = {
|
||||
RK808_BUCK4_CONFIG_REG,
|
||||
};
|
||||
|
||||
static const struct linear_range rk801_buck1_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */
|
||||
REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */
|
||||
REGULATOR_LINEAR_RANGE(3300000, 83, 83, 0), /* 3.3v */
|
||||
REGULATOR_LINEAR_RANGE(5000000, 84, 84, 0), /* 5.0v */
|
||||
REGULATOR_LINEAR_RANGE(5250000, 85, 85, 0), /* 5.25v */
|
||||
};
|
||||
|
||||
static const struct linear_range rk801_buck2_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0, 2, 50000), /* 0.8v - 0.9v */
|
||||
REGULATOR_LINEAR_RANGE(1800000, 3, 4, 400000), /* 1.8v - 2.2v */
|
||||
REGULATOR_LINEAR_RANGE(3300000, 5, 5, 0), /* 3.3v */
|
||||
REGULATOR_LINEAR_RANGE(5000000, 6, 6, 0), /* 5.0v */
|
||||
REGULATOR_LINEAR_RANGE(5250000, 7, 7, 0), /* 5.25v */
|
||||
};
|
||||
|
||||
static const struct linear_range rk801_buck4_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */
|
||||
REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */
|
||||
REGULATOR_LINEAR_RANGE(2500000, 83, 83, 0), /* 2.5v */
|
||||
REGULATOR_LINEAR_RANGE(2800000, 84, 84, 0), /* 2.8v */
|
||||
REGULATOR_LINEAR_RANGE(3000000, 85, 85, 0), /* 3.0v */
|
||||
REGULATOR_LINEAR_RANGE(3300000, 86, 86, 0), /* 3.3v */
|
||||
};
|
||||
|
||||
static const struct linear_range rk805_buck_1_2_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500), /* 0.7125v - 1.45v */
|
||||
REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),/* 1.8v - 2.2v */
|
||||
@@ -709,6 +746,145 @@ static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int rk801_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int pmw_mode_msk;
|
||||
unsigned int val;
|
||||
int err;
|
||||
|
||||
if (rdev->desc->id == RK801_ID_DCDC3)
|
||||
pmw_mode_msk = BIT(RK801_ID_DCDC3 + 1);
|
||||
else if (rdev->desc->id == RK801_ID_DCDC4)
|
||||
pmw_mode_msk = BIT(RK801_ID_DCDC4 - 1);
|
||||
else
|
||||
pmw_mode_msk = BIT(rdev->desc->id);
|
||||
|
||||
err = regmap_read(rdev->regmap, RK801_POWER_FPWM_EN_REG, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if ((val & pmw_mode_msk) == RK801_FPWM_MODE)
|
||||
return REGULATOR_MODE_FAST;
|
||||
else
|
||||
return REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static int rk801_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
unsigned int offset;
|
||||
|
||||
if (rdev->desc->id == RK801_ID_DCDC3)
|
||||
offset = RK801_ID_DCDC3 + 1;
|
||||
else if (rdev->desc->id == RK801_ID_DCDC4)
|
||||
offset = RK801_ID_DCDC4 - 1;
|
||||
else
|
||||
offset = rdev->desc->id;
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_FAST:
|
||||
return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG,
|
||||
BIT(offset), RK801_FPWM_MODE << offset);
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG,
|
||||
BIT(offset), RK801_AUTO_PWM_MODE << offset);
|
||||
default:
|
||||
dev_err(&rdev->dev, "do not support this mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk801_set_suspend_voltage(struct regulator_dev *rdev, int uv)
|
||||
{
|
||||
unsigned int reg;
|
||||
int sel;
|
||||
|
||||
sel = regulator_map_voltage_linear(rdev, uv, uv);
|
||||
if (sel < 0)
|
||||
return -EINVAL;
|
||||
|
||||
reg = rdev->desc->vsel_reg + RK801_SLP_REG_OFFSET;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, reg,
|
||||
rdev->desc->vsel_mask,
|
||||
sel);
|
||||
}
|
||||
|
||||
static int rk801_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
|
||||
{
|
||||
unsigned int reg;
|
||||
int sel;
|
||||
|
||||
sel = regulator_map_voltage_linear_range(rdev, uv, uv);
|
||||
if (sel < 0)
|
||||
return -EINVAL;
|
||||
|
||||
reg = rdev->desc->vsel_reg + RK801_SLP_REG_OFFSET;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, reg,
|
||||
rdev->desc->vsel_mask,
|
||||
sel);
|
||||
}
|
||||
|
||||
static int rk801_set_suspend_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG,
|
||||
rdev->desc->enable_mask,
|
||||
rdev->desc->enable_val);
|
||||
}
|
||||
|
||||
static int rk801_set_suspend_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG,
|
||||
rdev->desc->enable_mask,
|
||||
rdev->desc->disable_val);
|
||||
}
|
||||
|
||||
static int rk801_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
unsigned int old_selector,
|
||||
unsigned int new_selector)
|
||||
{
|
||||
return regulator_set_voltage_time_sel(rdev, old_selector, new_selector) + 32;
|
||||
}
|
||||
|
||||
static const struct regulator_ops rk801_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = rk801_set_voltage_time_sel,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_mode = rk801_set_mode,
|
||||
.get_mode = rk801_get_mode,
|
||||
.set_suspend_voltage = rk801_set_suspend_voltage_range,
|
||||
.set_suspend_enable = rk801_set_suspend_enable,
|
||||
.set_suspend_disable = rk801_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops rk801_reg_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_voltage = rk801_set_suspend_voltage,
|
||||
.set_suspend_enable = rk801_set_suspend_enable,
|
||||
.set_suspend_disable = rk801_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops rk801_switch_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_enable = rk801_set_suspend_enable,
|
||||
.set_suspend_disable = rk801_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops rk808_buck1_2_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
@@ -850,6 +1026,94 @@ static const struct regulator_ops rk817_switch_ops = {
|
||||
.set_suspend_disable = rk817_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_desc rk801_reg[] = {
|
||||
{
|
||||
.name = "DCDC_REG1",
|
||||
.supply_name = "vcc1",
|
||||
.of_match = of_match_ptr("DCDC_REG1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK801_ID_DCDC1,
|
||||
.ops = &rk801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 86,
|
||||
.linear_ranges = rk801_buck1_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk801_buck1_voltage_ranges),
|
||||
.vsel_reg = RK801_BUCK1_ON_VSEL_REG,
|
||||
.vsel_mask = RK801_BUCK_VSEL_MASK,
|
||||
.enable_reg = RK801_POWER_EN0_REG,
|
||||
.enable_mask = ENABLE_MASK(RK801_ID_DCDC1),
|
||||
.enable_val = ENABLE_MASK(RK801_ID_DCDC1),
|
||||
.disable_val = DISABLE_VAL(RK801_ID_DCDC1),
|
||||
.ramp_delay = 1,
|
||||
.of_map_mode = rk8xx_regulator_of_map_mode,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "DCDC_REG2",
|
||||
.supply_name = "vcc2",
|
||||
.of_match = of_match_ptr("DCDC_REG2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK801_ID_DCDC2,
|
||||
.ops = &rk801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 8,
|
||||
.linear_ranges = rk801_buck2_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk801_buck2_voltage_ranges),
|
||||
.vsel_reg = RK801_BUCK2_ON_VSEL_REG,
|
||||
.vsel_mask = RK801_BUCK_VSEL_MASK,
|
||||
.enable_reg = RK801_POWER_EN0_REG,
|
||||
.enable_mask = ENABLE_MASK(RK801_ID_DCDC2),
|
||||
.enable_val = ENABLE_MASK(RK801_ID_DCDC2),
|
||||
.disable_val = DISABLE_VAL(RK801_ID_DCDC2),
|
||||
.ramp_delay = 1,
|
||||
.of_map_mode = rk8xx_regulator_of_map_mode,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "DCDC_REG3",
|
||||
.supply_name = "vcc3",
|
||||
.of_match = of_match_ptr("DCDC_REG3"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK801_ID_DCDC3,
|
||||
.ops = &rk801_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 1,
|
||||
.enable_reg = RK801_POWER_EN0_REG,
|
||||
.enable_mask = ENABLE_MASK(RK801_ID_DCDC3 + 1),
|
||||
.enable_val = ENABLE_MASK(RK801_ID_DCDC3 + 1),
|
||||
.disable_val = DISABLE_VAL(RK801_ID_DCDC3 + 1),
|
||||
.of_map_mode = rk8xx_regulator_of_map_mode,
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "DCDC_REG4",
|
||||
.supply_name = "vcc4",
|
||||
.of_match = of_match_ptr("DCDC_REG4"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK801_ID_DCDC4,
|
||||
.ops = &rk801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 87,
|
||||
.linear_ranges = rk801_buck4_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk801_buck4_voltage_ranges),
|
||||
.vsel_reg = RK801_BUCK4_ON_VSEL_REG,
|
||||
.vsel_mask = RK801_BUCK_VSEL_MASK,
|
||||
.enable_reg = RK801_POWER_EN0_REG,
|
||||
.enable_mask = ENABLE_MASK(RK801_ID_DCDC4 - 1),
|
||||
.enable_val = ENABLE_MASK(RK801_ID_DCDC4 - 1),
|
||||
.disable_val = DISABLE_VAL(RK801_ID_DCDC4 - 1),
|
||||
.ramp_delay = 1,
|
||||
.of_map_mode = rk8xx_regulator_of_map_mode,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
RK801_DESC(RK801_ID_LDO1, "LDO_REG1", "vcc5", 500, 3400, 50,
|
||||
RK801_LDO1_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG,
|
||||
ENABLE_MASK(0), DISABLE_VAL(0), 400),
|
||||
RK801_DESC(RK801_ID_LDO2, "LDO_REG2", "vcc6", 500, 3400, 50,
|
||||
RK801_LDO2_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG,
|
||||
ENABLE_MASK(1), DISABLE_VAL(1), 400),
|
||||
RK801_DESC_SWITCH(RK801_ID_SWITCH, "SWITCH_REG", "vcc7", RK801_POWER_EN1_REG,
|
||||
ENABLE_MASK(2), DISABLE_VAL(2)),
|
||||
};
|
||||
|
||||
static const struct regulator_desc rk805_reg[] = {
|
||||
{
|
||||
.name = "DCDC_REG1",
|
||||
@@ -1616,6 +1880,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, pdata);
|
||||
|
||||
switch (rk808->variant) {
|
||||
case RK801_ID:
|
||||
regulators = rk801_reg;
|
||||
nregulators = RK801_NUM_REGULATORS;
|
||||
break;
|
||||
case RK805_ID:
|
||||
regulators = rk805_reg;
|
||||
nregulators = RK805_NUM_REGULATORS;
|
||||
|
||||
@@ -18,6 +18,116 @@
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* RK801 */
|
||||
enum rk801_reg {
|
||||
RK801_ID_DCDC1,
|
||||
RK801_ID_DCDC2,
|
||||
RK801_ID_DCDC3,
|
||||
RK801_ID_DCDC4,
|
||||
RK801_ID_LDO1,
|
||||
RK801_ID_LDO2,
|
||||
RK801_ID_SWITCH,
|
||||
};
|
||||
|
||||
#define RK801_SLP_REG_OFFSET 5
|
||||
#define RK801_NUM_REGULATORS 7
|
||||
|
||||
/* RK801 Register Definitions */
|
||||
#define RK801_ID_MSB 0x00
|
||||
#define RK801_ID_LSB 0x01
|
||||
#define RK801_OTP_VER_REG 0x02
|
||||
#define RK801_POWER_EN0_REG 0x03
|
||||
#define RK801_POWER_EN1_REG 0x04
|
||||
#define RK801_POWER_SLP_EN_REG 0x05
|
||||
#define RK801_POWER_FPWM_EN_REG 0x06
|
||||
#define RK801_SLP_LP_CONFIG_REG 0x07
|
||||
#define RK801_BUCK_CONFIG_REG 0x08
|
||||
#define RK801_BUCK1_ON_VSEL_REG 0x09
|
||||
#define RK801_BUCK2_ON_VSEL_REG 0x0a
|
||||
#define RK801_BUCK4_ON_VSEL_REG 0x0b
|
||||
#define RK801_LDO1_ON_VSEL_REG 0x0c
|
||||
#define RK801_LDO2_ON_VSEL_REG 0x0d
|
||||
#define RK801_BUCK1_SLP_VSEL_REG 0x0e
|
||||
#define RK801_BUCK2_SLP_VSEL_REG 0x0f
|
||||
#define RK801_BUCK4_SLP_VSEL_REG 0x10
|
||||
#define RK801_LDO1_SLP_VSEL_REG 0x11
|
||||
#define RK801_LDO2_SLP_VSEL_REG 0x12
|
||||
#define RK801_LDO_SW_IMAX_REG 0x13
|
||||
#define RK801_SYS_STS_REG 0x14
|
||||
#define RK801_SYS_CFG0_REG 0x15
|
||||
#define RK801_SYS_CFG1_REG 0x16
|
||||
#define RK801_SYS_CFG2_REG 0x17
|
||||
#define RK801_SYS_CFG3_REG 0x18
|
||||
#define RK801_SYS_CFG4_REG 0x19
|
||||
#define RK801_SLEEP_CFG_REG 0x1a
|
||||
#define RK801_ON_SOURCE_REG 0x1b
|
||||
#define RK801_OFF_SOURCE_REG 0x1c
|
||||
#define RK801_PWRON_KEY_REG 0x1d
|
||||
#define RK801_INT_STS0_REG 0x1e
|
||||
#define RK801_INT_MASK0_REG 0x1f
|
||||
#define RK801_INT_CONFIG_REG 0x20
|
||||
#define RK801_CON_BACK1_REG 0x21
|
||||
#define RK801_CON_BACK2_REG 0x22
|
||||
#define RK801_DATA_CON0_REG 0x23
|
||||
#define RK801_DATA_CON1_REG 0x24
|
||||
#define RK801_DATA_CON2_REG 0x25
|
||||
#define RK801_DATA_CON3_REG 0x26
|
||||
#define RK801_POWER_EXIT_SLP_SEQ0_REG 0x27
|
||||
#define RK801_POWER_EXIT_SLP_SEQ1_REG 0x28
|
||||
#define RK801_POWER_EXIT_SLP_SEQ2_REG 0x29
|
||||
#define RK801_POWER_EXIT_SLP_SEQ3_REG 0x2a
|
||||
#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ0_REG 0x2b
|
||||
#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ1_REG 0x2c
|
||||
#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ2_REG 0x2d
|
||||
#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ3_REG 0x2e
|
||||
#define RK801_BUCK_DEBUG1_REG 0x2f
|
||||
#define RK801_BUCK_DEBUG2_REG 0x30
|
||||
#define RK801_BUCK_DEBUG3_REG 0x31
|
||||
#define RK801_BUCK_DEBUG4_REG 0x32
|
||||
#define RK801_BUCK_DEBUG5_REG 0x33
|
||||
#define RK801_BUCK_DEBUG7_REG 0x34
|
||||
#define RK801_OTP_EN_CON_REG 0x35
|
||||
#define RK801_TEST_CON_REG 0x36
|
||||
#define RK801_EFUSE_CONTROL_REG 0x37
|
||||
#define RK801_SYS_CFG3_OTP_REG 0x38
|
||||
|
||||
/* RK801 IRQ Definitions */
|
||||
#define RK801_IRQ_PWRON_FALL 0
|
||||
#define RK801_IRQ_PWRON_RISE 1
|
||||
#define RK801_IRQ_PWRON 2
|
||||
#define RK801_IRQ_PWRON_LP 3
|
||||
#define RK801_IRQ_HOTDIE 4
|
||||
#define RK801_IRQ_VDC_RISE 5
|
||||
#define RK801_IRQ_VDC_FALL 6
|
||||
#define RK801_IRQ_PWRON_FALL_MSK BIT(0)
|
||||
#define RK801_IRQ_PWRON_RISE_MSK BIT(1)
|
||||
#define RK801_IRQ_PWRON_MSK BIT(2)
|
||||
#define RK801_IRQ_PWRON_LP_MSK BIT(3)
|
||||
#define RK801_IRQ_HOTDIE_MSK BIT(4)
|
||||
#define RK801_IRQ_VDC_RISE_MSK BIT(5)
|
||||
#define RK801_IRQ_VDC_FALL_MSK BIT(6)
|
||||
|
||||
/* RK801_SLEEP_CFG_REG */
|
||||
#define RK801_SLEEP_FUN_MSK 0x3
|
||||
#define RK801_NONE_FUN 0x0
|
||||
#define RK801_SLEEP_FUN 0x1
|
||||
#define RK801_SHUTDOWN_FUN 0x2
|
||||
#define RK801_RESET_FUN 0x3
|
||||
|
||||
/* RK801_SYS_CFG2_REG */
|
||||
#define RK801_SLEEP_POL_MSK BIT(1)
|
||||
#define RK801_SLEEP_ACT_H BIT(1)
|
||||
#define RK801_SLEEP_ACT_L 0
|
||||
|
||||
/* RK801_INT_CONFIG_REG */
|
||||
#define RK801_INT_POL_MSK BIT(1)
|
||||
#define RK801_INT_ACT_H BIT(1)
|
||||
#define RK801_INT_ACT_L 0
|
||||
|
||||
#define RK801_FPWM_MODE 1
|
||||
#define RK801_AUTO_PWM_MODE 0
|
||||
#define RK801_PLDO_HRDEC_EN BIT(6)
|
||||
|
||||
/*
|
||||
* rk808 Global Register Map.
|
||||
*/
|
||||
@@ -1214,6 +1324,7 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
RK801_ID = 0x8010,
|
||||
RK805_ID = 0x8050,
|
||||
RK808_ID = 0x0000,
|
||||
RK809_ID = 0x8090,
|
||||
|
||||
Reference in New Issue
Block a user