pmic: add rk809 support

include sub modules: pmic, regulator, pwrkey

Change-Id: I840983ceafc7677840674e7d1aebab703e3a537d
Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
Joseph Chen 2018-02-22 15:03:04 +08:00 committed by Kever Yang
parent 1c223666dc
commit 1b6b965c67
4 changed files with 150 additions and 26 deletions

View File

@ -14,7 +14,6 @@
#include <asm/arch/periph.h>
#include <dm/pinctrl.h>
#define RK817_GPIO_INT_CFG 0xfe
#define RK817_INT_STS_REG0 0xf8
#define RK817_INT_MSK_REG0 0xf9
#define RK817_INT_STS_REG1 0xfa
@ -24,7 +23,6 @@
#define RK817_PWRON_RISE_INT (1 << 1)
#define RK817_PWRON_FALL_INT (1 << 0)
#define RK817_PLUG_OUT_INT (1 << 1)
#define RK817_INT_POL_MSK BIT(1)
#define RK816_INT_STS_REG1 0x49
#define RK816_INT_MSK_REG1 0x4a
@ -64,8 +62,6 @@ static struct reg_data rk817_init_reg[] = {
{ RK817_INT_STS_REG0, 0xff },
{ RK817_INT_STS_REG1, 0xff },
{ RK817_INT_STS_REG2, 0xff },
/* pmic_int active low */
{ RK817_GPIO_INT_CFG, 0x20 },
};
static struct reg_data rk817_irq_reg[] = {
@ -265,6 +261,7 @@ static int rk8xx_pwrkey_probe(struct udevice *dev)
priv->irq_reg = rk816_irq_reg;
priv->irq_reg_num = ARRAY_SIZE(rk816_irq_reg);
break;
case RK809_ID:
case RK817_ID:
priv->key_int_sts_reg = RK817_INT_STS_REG0;
priv->key_int_msk_reg = RK817_INT_MSK_REG0;

View File

@ -93,6 +93,7 @@ static int rk8xx_shutdown(struct udevice *dev)
devctrl_reg = REG_DEVCTRL;
dev_off = BIT(0);
break;
case RK809_ID:
case RK817_ID:
devctrl_reg = RK817_REG_SYS_CFG3;
dev_off = BIT(0);
@ -161,7 +162,8 @@ static int rk8xx_probe(struct udevice *dev)
uint8_t msb, lsb, id_msb, id_lsb;
/* read Chip variant */
if (device_is_compatible(dev, "rockchip,rk817")) {
if (device_is_compatible(dev, "rockchip,rk817") ||
device_is_compatible(dev, "rockchip,rk809")) {
id_msb = RK817_ID_MSB;
id_lsb = RK817_ID_LSB;
} else {
@ -179,6 +181,7 @@ static int rk8xx_probe(struct udevice *dev)
case RK816_ID:
case RK818_ID:
break;
case RK809_ID:
case RK817_ID:
#ifdef CONFIG_DM_CHARGE_DISPLAY
init_data = rk817_init_reg;
@ -219,6 +222,7 @@ static struct dm_pmic_ops rk8xx_ops = {
static const struct udevice_id rk8xx_ids[] = {
{ .compatible = "rockchip,rk805" },
{ .compatible = "rockchip,rk808" },
{ .compatible = "rockchip,rk809" },
{ .compatible = "rockchip,rk816" },
{ .compatible = "rockchip,rk817" },
{ .compatible = "rockchip,rk818" },

View File

@ -33,6 +33,10 @@
#define RK818_USB_ILIM_SEL_MASK 0x0f
#define RK818_USB_CHG_SD_VSEL_MASK 0x70
/* RK809 BUCK5 */
#define RK809_BUCK5_CONFIG(n) (0xde + (n) * 1)
#define RK809_BUCK5_VSEL_MASK 0x07
/* RK817 BUCK */
#define RK817_BUCK_ON_VSEL(n) (0xbb + 3 * (n - 1))
#define RK817_BUCK_SLP_VSEL(n) (0xbc + 3 * (n - 1))
@ -78,6 +82,14 @@ static const struct rk8xx_reg_info rk816_buck[] = {
{ 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, RK818_BUCK4_VSEL_MASK, },
};
static const struct rk8xx_reg_info rk809_buck5[] = {
/* buck 5 */
{ 1500000, 0, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), RK809_BUCK5_VSEL_MASK, 0x00, },
{ 1800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), RK809_BUCK5_VSEL_MASK, 0x01, },
{ 2800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), RK809_BUCK5_VSEL_MASK, 0x04, },
{ 3300000, 300000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), RK809_BUCK5_VSEL_MASK, 0x06, },
};
static const struct rk8xx_reg_info rk817_buck[] = {
/* buck 1 */
{ 500000, 12500, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_VSEL_MASK, 0x00, },
@ -196,6 +208,7 @@ static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
return &rk816_buck[num + 4];
}
case RK809_ID:
case RK817_ID:
switch (num) {
case 0 ... 2:
@ -205,13 +218,23 @@ static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
return &rk817_buck[num * 3 + 1];
else
return &rk817_buck[num * 3 + 2];
default:
case 3:
if (uvolt < 1500000)
return &rk817_buck[num * 3 + 0];
else if (uvolt < 3400000)
return &rk817_buck[num * 3 + 1];
else
return &rk817_buck[num * 3 + 2];
/* BUCK5 for RK809 */
default:
if (uvolt < 1800000)
return &rk809_buck5[0];
else if (uvolt < 2800000)
return &rk809_buck5[1];
else if (uvolt < 3300000)
return &rk809_buck5[2];
else
return &rk809_buck5[3];
}
case RK818_ID:
return &rk818_buck[num];
@ -278,12 +301,22 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
ret = pmic_clrsetbits(pmic, REG_DCDC_EN, mask,
enable ? mask : 0);
break;
case RK809_ID:
case RK817_ID:
if (enable)
value = ((1 << buck) | (1 << (buck + 4)));
else
value = ((0 << buck) | (1 << (buck + 4)));
ret = pmic_reg_write(pmic, RK817_POWER_EN(0), value);
if (buck < 4) {
if (enable)
value = ((1 << buck) | (1 << (buck + 4)));
else
value = ((0 << buck) | (1 << (buck + 4)));
ret = pmic_reg_write(pmic, RK817_POWER_EN(0), value);
/* BUCK5 for RK809 */
} else {
if (enable)
value = ((1 << 1) | (1 << 5));
else
value = ((0 << 1) | (1 << 5));
ret = pmic_reg_write(pmic, RK817_POWER_EN(3), value);
}
break;
default:
ret = -EINVAL;
@ -337,12 +370,22 @@ static int _buck_get_enable(struct udevice *pmic, int buck)
if (ret < 0)
return ret;
break;
case RK809_ID:
case RK817_ID:
mask = 1 << buck;
ret = pmic_reg_read(pmic, RK817_POWER_EN(0));
debug("%s: %s, buck=%d, en=%x\n", __func__, pmic->name, buck, ret);
if (buck < 4) {
mask = 1 << buck;
ret = pmic_reg_read(pmic, RK817_POWER_EN(0));
/* BUCK5 for RK809 */
} else {
mask = 1 << 1;
ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
}
break;
}
if (ret < 0)
return ret;
return ret & mask ? true : false;
}
@ -359,15 +402,18 @@ static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
ret = pmic_clrsetbits(pmic, RK816_REG_DCDC_SLP_EN, mask,
enable ? mask : 0);
break;
case RK808_ID:
case RK818_ID:
mask = 1 << buck;
ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask,
enable ? 0 : mask);
break;
case RK809_ID:
case RK817_ID:
mask = 1 << buck;
if (buck < 4)
mask = 1 << buck;
else
mask = 1 << 5; /* BUCK5 for RK809 */
ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
enable ? mask : 0);
break;
@ -387,6 +433,7 @@ static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
case RK805_ID:
case RK816_ID:
return &rk816_ldo[num];
case RK809_ID:
case RK817_ID:
if (uvolt < 3400000)
return &rk817_ldo[num * 2 + 0];
@ -423,6 +470,7 @@ static int _ldo_get_enable(struct udevice *pmic, int ldo)
if (ret < 0)
return ret;
break;
case RK809_ID:
case RK817_ID:
if (ldo < 4) {
mask = 1 << ldo;
@ -438,6 +486,10 @@ static int _ldo_get_enable(struct udevice *pmic, int ldo)
}
break;
}
if (ret < 0)
return ret;
return ret & mask ? true : false;
}
@ -469,6 +521,7 @@ static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
enable ? mask : 0);
break;
case RK809_ID:
case RK817_ID:
if (ldo < 4) {
en_reg = RK817_POWER_EN(1);
@ -511,6 +564,7 @@ static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask,
enable ? 0 : mask);
break;
case RK809_ID:
case RK817_ID:
if (ldo == 8) {
mask = 1 << 4; /* LDO9 */
@ -663,30 +717,96 @@ static int ldo_get_enable(struct udevice *dev)
static int switch_set_enable(struct udevice *dev, bool enable)
{
int sw = dev->driver_data - 1;
uint mask;
struct rk8xx_priv *priv = dev_get_priv(dev->parent);
int ret = 0, sw = dev->driver_data - 1;
uint mask = 0;
mask = 1 << (sw + 5);
switch (priv->variant) {
case RK808_ID:
mask = 1 << (sw + 5);
ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
enable ? mask : 0);
break;
case RK809_ID:
mask = (1 << (sw + 2)) | (1 << (sw + 6));
ret = pmic_clrsetbits(dev->parent, RK817_POWER_EN(3), mask,
enable ? mask : 0);
break;
case RK818_ID:
mask = 1 << 6;
ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
enable ? mask : 0);
break;
}
return pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
enable ? mask : 0);
debug("%s: switch%d, enable=%d, mask=0x%x\n",
__func__, sw + 1, enable, mask);
return ret;
}
static int switch_get_enable(struct udevice *dev)
{
int sw = dev->driver_data - 1;
int ret;
uint mask;
struct rk8xx_priv *priv = dev_get_priv(dev->parent);
int ret = 0, sw = dev->driver_data - 1;
uint mask = 0;
mask = 1 << (sw + 5);
switch (priv->variant) {
case RK808_ID:
mask = 1 << (sw + 5);
ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
break;
case RK809_ID:
mask = 1 << (sw + 2);
ret = pmic_reg_read(dev->parent, RK817_POWER_EN(3));
break;
case RK818_ID:
mask = 1 << 6;
ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
break;
}
ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
if (ret < 0)
return ret;
return ret & mask ? true : false;
}
static int switch_set_suspend_value(struct udevice *dev, int uvolt)
{
return 0;
}
static int switch_set_suspend_enable(struct udevice *dev, bool enable)
{
struct rk8xx_priv *priv = dev_get_priv(dev->parent);
int ret = 0, sw = dev->driver_data - 1;
uint mask = 0;
switch (priv->variant) {
case RK808_ID:
mask = 1 << (sw + 5);
ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
enable ? 0 : mask);
break;
case RK809_ID:
mask = 1 << (sw + 6);
ret = pmic_clrsetbits(dev->parent, RK817_POWER_SLP_EN(0), mask,
enable ? mask : 0);
break;
case RK818_ID:
mask = 1 << 6;
ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
enable ? 0 : mask);
break;
}
debug("%s: switch%d, enable=%d, mask=0x%x\n",
__func__, sw + 1, enable, mask);
return ret;
}
static int rk8xx_buck_probe(struct udevice *dev)
{
struct dm_regulator_uclass_platdata *uc_pdata;
@ -744,6 +864,8 @@ static const struct dm_regulator_ops rk8xx_ldo_ops = {
static const struct dm_regulator_ops rk8xx_switch_ops = {
.get_enable = switch_get_enable,
.set_enable = switch_set_enable,
.set_suspend_enable = switch_set_suspend_enable,
.set_suspend_value = switch_set_suspend_value,
};
U_BOOT_DRIVER(rk8xx_buck) = {

View File

@ -186,6 +186,7 @@ enum {
enum {
RK805_ID = 0x8050,
RK808_ID = 0x0000,
RK809_ID = 0x8090,
RK816_ID = 0x8160,
RK817_ID = 0x8170,
RK818_ID = 0x8180,