pmic: add RK817 support
include sub modules: pmic, regulator, pwrkey Change-Id: I3a1cbaa3c4d069cbac17124f9c0fe3b01184697c Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
parent
2f22a22f29
commit
7f18d96c70
|
|
@ -14,6 +14,17 @@
|
||||||
#include <asm/arch/periph.h>
|
#include <asm/arch/periph.h>
|
||||||
#include <dm/pinctrl.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
|
||||||
|
#define RK817_INT_MSK_REG1 0xfb
|
||||||
|
#define RK817_INT_STS_REG2 0xfc
|
||||||
|
#define RK817_INT_MSK_REG2 0xfd
|
||||||
|
#define RK817_PWRON_RISE_INT (1 << 1)
|
||||||
|
#define RK817_PWRON_FALL_INT (1 << 0)
|
||||||
|
#define RK817_INT_POL_MSK BIT(1)
|
||||||
|
|
||||||
#define RK816_INT_STS_REG1 0x49
|
#define RK816_INT_STS_REG1 0x49
|
||||||
#define RK816_INT_MSK_REG1 0x4a
|
#define RK816_INT_MSK_REG1 0x4a
|
||||||
#define RK816_INT_STS_REG2 0x4c
|
#define RK816_INT_STS_REG2 0x4c
|
||||||
|
|
@ -44,6 +55,26 @@ struct rk8xx_key_priv {
|
||||||
u32 irq_reg_num;
|
u32 irq_reg_num;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct reg_data rk817_init_reg[] = {
|
||||||
|
/* only enable rise/fall interrupt */
|
||||||
|
{ RK817_INT_MSK_REG0, 0xfc },
|
||||||
|
{ RK817_INT_MSK_REG1, 0xff },
|
||||||
|
{ RK817_INT_MSK_REG2, 0xff },
|
||||||
|
/* clear all interrupt states */
|
||||||
|
{ 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[] = {
|
||||||
|
/* clear all interrupt states */
|
||||||
|
{ RK817_INT_STS_REG0, 0xff },
|
||||||
|
{ RK817_INT_STS_REG1, 0xff },
|
||||||
|
{ RK817_INT_STS_REG2, 0xff },
|
||||||
|
};
|
||||||
|
|
||||||
static struct reg_data rk816_init_reg[] = {
|
static struct reg_data rk816_init_reg[] = {
|
||||||
/* only enable rise/fall interrupt */
|
/* only enable rise/fall interrupt */
|
||||||
{ RK816_INT_MSK_REG1, 0x9f },
|
{ RK816_INT_MSK_REG1, 0x9f },
|
||||||
|
|
@ -118,6 +149,8 @@ static void pwrkey_irq_handler(int irq, void *data)
|
||||||
struct input_key *key = dev_get_platdata(dev);
|
struct input_key *key = dev_get_platdata(dev);
|
||||||
int ret, val, i;
|
int ret, val, i;
|
||||||
|
|
||||||
|
debug("%s: irq = %d\n", __func__, irq);
|
||||||
|
|
||||||
/* read status */
|
/* read status */
|
||||||
val = pmic_reg_read(dev->parent, priv->int_sts_reg);
|
val = pmic_reg_read(dev->parent, priv->int_sts_reg);
|
||||||
if (val < 0) {
|
if (val < 0) {
|
||||||
|
|
@ -146,6 +179,9 @@ static void pwrkey_irq_handler(int irq, void *data)
|
||||||
printf("%s: i2c write reg 0x%x failed, ret=%d\n",
|
printf("%s: i2c write reg 0x%x failed, ret=%d\n",
|
||||||
__func__, priv->irq_reg[i].reg, ret);
|
__func__, priv->irq_reg[i].reg, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug("%s: reg[0x%x] = 0x%x\n", __func__, priv->irq_reg[i].reg,
|
||||||
|
pmic_reg_read(dev->parent, priv->irq_reg[i].reg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,7 +246,16 @@ static int rk8xx_pwrkey_probe(struct udevice *dev)
|
||||||
priv->irq_reg = rk816_irq_reg;
|
priv->irq_reg = rk816_irq_reg;
|
||||||
priv->irq_reg_num = ARRAY_SIZE(rk816_irq_reg);
|
priv->irq_reg_num = ARRAY_SIZE(rk816_irq_reg);
|
||||||
break;
|
break;
|
||||||
|
case RK817_ID:
|
||||||
|
priv->int_sts_reg = RK817_INT_STS_REG0;
|
||||||
|
priv->int_msk_reg = RK817_INT_MSK_REG0;
|
||||||
|
priv->pwron_rise_int = RK817_PWRON_RISE_INT;
|
||||||
|
priv->pwron_fall_int = RK817_PWRON_FALL_INT;
|
||||||
|
priv->init_reg = rk817_init_reg;
|
||||||
|
priv->init_reg_num = ARRAY_SIZE(rk817_init_reg);
|
||||||
|
priv->irq_reg = rk817_irq_reg;
|
||||||
|
priv->irq_reg_num = ARRAY_SIZE(rk817_irq_reg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -225,6 +270,9 @@ static int rk8xx_pwrkey_probe(struct udevice *dev)
|
||||||
__func__, priv->init_reg[i].reg, ret);
|
__func__, priv->init_reg[i].reg, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug("%s: reg[%x] = 0x%x\n", __func__, priv->init_reg[i].reg,
|
||||||
|
pmic_reg_read(dev->parent, priv->init_reg[i].reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pwrkey_interrupt_init(dev);
|
return pwrkey_interrupt_init(dev);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ static const struct pmic_child_info power_key_info[] = {
|
||||||
|
|
||||||
static const struct pmic_child_info fuel_gauge_info[] = {
|
static const struct pmic_child_info fuel_gauge_info[] = {
|
||||||
{ .prefix = "battery", .driver = "rk818_fg"},
|
{ .prefix = "battery", .driver = "rk818_fg"},
|
||||||
|
{ .prefix = "battery", .driver = "rk817_fg"},
|
||||||
{ .prefix = "battery", .driver = "rk816_fg"},
|
{ .prefix = "battery", .driver = "rk816_fg"},
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
@ -66,16 +67,22 @@ static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||||
static int rk8xx_shutdown(struct udevice *dev)
|
static int rk8xx_shutdown(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct rk8xx_priv *priv = dev_get_priv(dev);
|
struct rk8xx_priv *priv = dev_get_priv(dev);
|
||||||
u8 val, dev_off;
|
u8 val, dev_off, devctrl_reg;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
switch (priv->variant) {
|
switch (priv->variant) {
|
||||||
case RK808_ID:
|
case RK808_ID:
|
||||||
|
devctrl_reg = REG_DEVCTRL;
|
||||||
dev_off = BIT(3);
|
dev_off = BIT(3);
|
||||||
break;
|
break;
|
||||||
case RK805_ID:
|
case RK805_ID:
|
||||||
case RK816_ID:
|
case RK816_ID:
|
||||||
case RK818_ID:
|
case RK818_ID:
|
||||||
|
devctrl_reg = REG_DEVCTRL;
|
||||||
|
dev_off = BIT(0);
|
||||||
|
break;
|
||||||
|
case RK817_ID:
|
||||||
|
devctrl_reg = RK817_REG_SYS_CFG3;
|
||||||
dev_off = BIT(0);
|
dev_off = BIT(0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -83,18 +90,18 @@ static int rk8xx_shutdown(struct udevice *dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dm_i2c_read(dev, REG_DEVCTRL, &val, 1);
|
ret = dm_i2c_read(dev, devctrl_reg, &val, 1);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("read error from device: %p register: %#x!",
|
printf("read error from device: %p register: %#x!",
|
||||||
dev, REG_DEVCTRL);
|
dev, devctrl_reg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
val |= dev_off;
|
val |= dev_off;
|
||||||
ret = dm_i2c_write(dev, REG_DEVCTRL, &val, 1);
|
ret = dm_i2c_write(dev, devctrl_reg, &val, 1);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("write error to device: %p register: %#x!",
|
printf("write error to device: %p register: %#x!",
|
||||||
dev, REG_DEVCTRL);
|
dev, devctrl_reg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,14 +143,24 @@ static int rk8xx_bind(struct udevice *dev)
|
||||||
static int rk8xx_probe(struct udevice *dev)
|
static int rk8xx_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct rk8xx_priv *priv = dev_get_priv(dev);
|
struct rk8xx_priv *priv = dev_get_priv(dev);
|
||||||
uint8_t msb, lsb;
|
uint8_t msb, lsb, id_msb, id_lsb;
|
||||||
|
|
||||||
/* read Chip variant */
|
/* read Chip variant */
|
||||||
rk8xx_read(dev, ID_MSB, &msb, 1);
|
if (device_is_compatible(dev, "rockchip,rk817")) {
|
||||||
rk8xx_read(dev, ID_LSB, &lsb, 1);
|
id_msb = RK817_ID_MSB;
|
||||||
|
id_lsb = RK817_ID_LSB;
|
||||||
|
} else {
|
||||||
|
id_msb = ID_MSB;
|
||||||
|
id_lsb = ID_LSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
rk8xx_read(dev, id_msb, &msb, 1);
|
||||||
|
rk8xx_read(dev, id_lsb, &lsb, 1);
|
||||||
|
|
||||||
priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
|
priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
|
||||||
|
|
||||||
|
printf("PMIC: RK%x\n", priv->variant);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,6 +175,7 @@ static const struct udevice_id rk8xx_ids[] = {
|
||||||
{ .compatible = "rockchip,rk805" },
|
{ .compatible = "rockchip,rk805" },
|
||||||
{ .compatible = "rockchip,rk808" },
|
{ .compatible = "rockchip,rk808" },
|
||||||
{ .compatible = "rockchip,rk816" },
|
{ .compatible = "rockchip,rk816" },
|
||||||
|
{ .compatible = "rockchip,rk817" },
|
||||||
{ .compatible = "rockchip,rk818" },
|
{ .compatible = "rockchip,rk818" },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,27 @@
|
||||||
#define RK818_USB_ILIM_SEL_MASK 0x0f
|
#define RK818_USB_ILIM_SEL_MASK 0x0f
|
||||||
#define RK818_USB_CHG_SD_VSEL_MASK 0x70
|
#define RK818_USB_CHG_SD_VSEL_MASK 0x70
|
||||||
|
|
||||||
|
/* RK817 BUCK */
|
||||||
|
#define RK817_BUCK_ON_VSEL(n) (0xbb + 3 * (n - 1))
|
||||||
|
#define RK817_BUCK_SLP_VSEL(n) (0xbc + 3 * (n - 1))
|
||||||
|
#define RK817_BUCK_VSEL_MASK 0x7f
|
||||||
|
|
||||||
|
/* RK817 LDO */
|
||||||
|
#define RK817_LDO_ON_VSEL(n) (0xcc + 2 * (n - 1))
|
||||||
|
#define RK817_LDO_SLP_VSEL(n) (0xcd + 2 * (n - 1))
|
||||||
|
#define RK817_LDO_VSEL_MASK 0x7f
|
||||||
|
|
||||||
|
/* RK817 ENABLE */
|
||||||
|
#define RK817_POWER_EN(n) (0xb1 + (n))
|
||||||
|
#define RK817_POWER_SLP_EN(n) (0xb5 + (n))
|
||||||
|
|
||||||
struct rk8xx_reg_info {
|
struct rk8xx_reg_info {
|
||||||
uint min_uv;
|
uint min_uv;
|
||||||
uint step_uv;
|
uint step_uv;
|
||||||
s8 vsel_reg;
|
u8 vsel_reg;
|
||||||
s8 vsel_sleep_reg;
|
u8 vsel_sleep_reg;
|
||||||
u8 vsel_mask;
|
u8 vsel_mask;
|
||||||
|
u8 min_sel;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rk8xx_reg_info rk808_buck[] = {
|
static const struct rk8xx_reg_info rk808_buck[] = {
|
||||||
|
|
@ -63,6 +78,25 @@ static const struct rk8xx_reg_info rk816_buck[] = {
|
||||||
{ 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, RK818_BUCK4_VSEL_MASK, },
|
{ 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, RK818_BUCK4_VSEL_MASK, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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, },
|
||||||
|
{ 1500000, 100000, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_VSEL_MASK, 0x50, },
|
||||||
|
{ 2400000, 0, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_VSEL_MASK, 0x59, },
|
||||||
|
/* buck 2 */
|
||||||
|
{ 500000, 12500, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_VSEL_MASK, 0x00, },
|
||||||
|
{ 1500000, 100000, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_VSEL_MASK, 0x50, },
|
||||||
|
{ 2400000, 0, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_VSEL_MASK, 0x59, },
|
||||||
|
/* buck 3 */
|
||||||
|
{ 500000, 12500, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_VSEL_MASK, 0x00, },
|
||||||
|
{ 1500000, 100000, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_VSEL_MASK, 0x50, },
|
||||||
|
{ 2400000, 0, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_VSEL_MASK, 0x59, },
|
||||||
|
/* buck 4 */
|
||||||
|
{ 500000, 12500, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_VSEL_MASK, 0x00, },
|
||||||
|
{ 1500000, 100000, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_VSEL_MASK, 0x50, },
|
||||||
|
{ 3400000, 0, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_VSEL_MASK, 0x63, },
|
||||||
|
};
|
||||||
|
|
||||||
static const struct rk8xx_reg_info rk818_buck[] = {
|
static const struct rk8xx_reg_info rk818_buck[] = {
|
||||||
{ 712500, 12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, RK818_BUCK_VSEL_MASK, },
|
{ 712500, 12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, RK818_BUCK_VSEL_MASK, },
|
||||||
{ 712500, 12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, RK818_BUCK_VSEL_MASK, },
|
{ 712500, 12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, RK818_BUCK_VSEL_MASK, },
|
||||||
|
|
@ -91,6 +125,36 @@ static const struct rk8xx_reg_info rk816_ldo[] = {
|
||||||
{ 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, RK818_LDO_VSEL_MASK, },
|
{ 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, RK818_LDO_VSEL_MASK, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct rk8xx_reg_info rk817_ldo[] = {
|
||||||
|
/* ldo1 */
|
||||||
|
{ 600000, 25000, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), RK817_LDO_VSEL_MASK, 0x00, },
|
||||||
|
{ 3400000, 0, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), RK817_LDO_VSEL_MASK, 0x70, },
|
||||||
|
/* ldo2 */
|
||||||
|
{ 600000, 25000, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), RK817_LDO_VSEL_MASK, 0x00, },
|
||||||
|
{ 3400000, 0, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), RK817_LDO_VSEL_MASK, 0x70, },
|
||||||
|
/* ldo3 */
|
||||||
|
{ 600000, 25000, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), RK817_LDO_VSEL_MASK, 0x00, },
|
||||||
|
{ 3400000, 0, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), RK817_LDO_VSEL_MASK, 0x70, },
|
||||||
|
/* ldo4 */
|
||||||
|
{ 600000, 25000, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), RK817_LDO_VSEL_MASK, 0x00, },
|
||||||
|
{ 3400000, 0, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), RK817_LDO_VSEL_MASK, 0x70, },
|
||||||
|
/* ldo5 */
|
||||||
|
{ 600000, 25000, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), RK817_LDO_VSEL_MASK, 0x00, },
|
||||||
|
{ 3400000, 0, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), RK817_LDO_VSEL_MASK, 0x70, },
|
||||||
|
/* ldo6 */
|
||||||
|
{ 600000, 25000, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), RK817_LDO_VSEL_MASK, 0x00, },
|
||||||
|
{ 3400000, 0, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), RK817_LDO_VSEL_MASK, 0x70, },
|
||||||
|
/* ldo7 */
|
||||||
|
{ 600000, 25000, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), RK817_LDO_VSEL_MASK, 0x00, },
|
||||||
|
{ 3400000, 0, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), RK817_LDO_VSEL_MASK, 0x70, },
|
||||||
|
/* ldo8 */
|
||||||
|
{ 600000, 25000, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), RK817_LDO_VSEL_MASK, 0x00, },
|
||||||
|
{ 3400000, 0, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), RK817_LDO_VSEL_MASK, 0x70, },
|
||||||
|
/* ldo9 */
|
||||||
|
{ 600000, 25000, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), RK817_LDO_VSEL_MASK, 0x00, },
|
||||||
|
{ 3400000, 0, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), RK817_LDO_VSEL_MASK, 0x70, },
|
||||||
|
};
|
||||||
|
|
||||||
static const struct rk8xx_reg_info rk818_ldo[] = {
|
static const struct rk8xx_reg_info rk818_ldo[] = {
|
||||||
{ 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, RK818_LDO_VSEL_MASK, },
|
{ 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, RK818_LDO_VSEL_MASK, },
|
||||||
{ 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, RK818_LDO_VSEL_MASK, },
|
{ 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, RK818_LDO_VSEL_MASK, },
|
||||||
|
|
@ -131,6 +195,24 @@ static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
|
||||||
default:
|
default:
|
||||||
return &rk816_buck[num + 4];
|
return &rk816_buck[num + 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case RK817_ID:
|
||||||
|
switch (num) {
|
||||||
|
case 0 ... 2:
|
||||||
|
if (uvolt < 1500000)
|
||||||
|
return &rk817_buck[num * 3 + 0];
|
||||||
|
else if (uvolt < 2400000)
|
||||||
|
return &rk817_buck[num * 3 + 1];
|
||||||
|
else
|
||||||
|
return &rk817_buck[num * 3 + 2];
|
||||||
|
default:
|
||||||
|
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];
|
||||||
|
}
|
||||||
case RK818_ID:
|
case RK818_ID:
|
||||||
return &rk818_buck[num];
|
return &rk818_buck[num];
|
||||||
default:
|
default:
|
||||||
|
|
@ -146,9 +228,14 @@ static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
|
||||||
|
|
||||||
if (info->vsel_reg == -1)
|
if (info->vsel_reg == -1)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
val = (uvolt - info->min_uv) / info->step_uv;
|
|
||||||
debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
|
if (info->step_uv == 0) /* Fixed voltage */
|
||||||
val);
|
val = info->min_sel;
|
||||||
|
else
|
||||||
|
val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
|
||||||
|
|
||||||
|
debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
|
||||||
|
__func__, uvolt, buck+1, info->vsel_reg, mask, val);
|
||||||
|
|
||||||
return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
|
return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
|
||||||
}
|
}
|
||||||
|
|
@ -191,6 +278,13 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
|
||||||
ret = pmic_clrsetbits(pmic, REG_DCDC_EN, mask,
|
ret = pmic_clrsetbits(pmic, REG_DCDC_EN, mask,
|
||||||
enable ? mask : 0);
|
enable ? mask : 0);
|
||||||
break;
|
break;
|
||||||
|
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);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -207,9 +301,14 @@ static int _buck_set_suspend_value(struct udevice *pmic, int buck, int uvolt)
|
||||||
|
|
||||||
if (info->vsel_sleep_reg == -1)
|
if (info->vsel_sleep_reg == -1)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
val = (uvolt - info->min_uv) / info->step_uv;
|
|
||||||
debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_sleep_reg, mask,
|
if (info->step_uv == 0)
|
||||||
val);
|
val = info->min_sel;
|
||||||
|
else
|
||||||
|
val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
|
||||||
|
|
||||||
|
debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
|
||||||
|
__func__, uvolt, buck+1, info->vsel_sleep_reg, mask, val);
|
||||||
|
|
||||||
return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
|
return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
|
||||||
}
|
}
|
||||||
|
|
@ -238,6 +337,11 @@ static int _buck_get_enable(struct udevice *pmic, int buck)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
|
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);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return ret & mask ? true : false;
|
return ret & mask ? true : false;
|
||||||
}
|
}
|
||||||
|
|
@ -262,6 +366,11 @@ static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
|
||||||
ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask,
|
ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask,
|
||||||
enable ? 0 : mask);
|
enable ? 0 : mask);
|
||||||
break;
|
break;
|
||||||
|
case RK817_ID:
|
||||||
|
mask = 1 << buck;
|
||||||
|
ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
|
||||||
|
enable ? mask : 0);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -270,7 +379,7 @@ static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
|
static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
|
||||||
int num)
|
int num, int uvolt)
|
||||||
{
|
{
|
||||||
struct rk8xx_priv *priv = dev_get_priv(pmic);
|
struct rk8xx_priv *priv = dev_get_priv(pmic);
|
||||||
|
|
||||||
|
|
@ -278,6 +387,11 @@ static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
|
||||||
case RK805_ID:
|
case RK805_ID:
|
||||||
case RK816_ID:
|
case RK816_ID:
|
||||||
return &rk816_ldo[num];
|
return &rk816_ldo[num];
|
||||||
|
case RK817_ID:
|
||||||
|
if (uvolt < 3400000)
|
||||||
|
return &rk817_ldo[num * 2 + 0];
|
||||||
|
else
|
||||||
|
return &rk817_ldo[num * 2 + 1];
|
||||||
case RK818_ID:
|
case RK818_ID:
|
||||||
return &rk818_ldo[num];
|
return &rk818_ldo[num];
|
||||||
default:
|
default:
|
||||||
|
|
@ -309,6 +423,20 @@ static int _ldo_get_enable(struct udevice *pmic, int ldo)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
|
case RK817_ID:
|
||||||
|
if (ldo < 4) {
|
||||||
|
mask = 1 << ldo;
|
||||||
|
ret = pmic_reg_read(pmic, RK817_POWER_EN(1));
|
||||||
|
} else if (ldo < 8) {
|
||||||
|
mask = 1 << (ldo - 4);
|
||||||
|
ret = pmic_reg_read(pmic, RK817_POWER_EN(2));
|
||||||
|
} else if (ldo == 8) {
|
||||||
|
mask = 1 << 0;
|
||||||
|
ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return ret & mask ? true : false;
|
return ret & mask ? true : false;
|
||||||
}
|
}
|
||||||
|
|
@ -341,6 +469,24 @@ static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
|
||||||
ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
|
ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
|
||||||
enable ? mask : 0);
|
enable ? mask : 0);
|
||||||
break;
|
break;
|
||||||
|
case RK817_ID:
|
||||||
|
if (ldo < 4) {
|
||||||
|
en_reg = RK817_POWER_EN(1);
|
||||||
|
} else if (ldo < 8) {
|
||||||
|
ldo -= 4;
|
||||||
|
en_reg = RK817_POWER_EN(2);
|
||||||
|
} else if (ldo == 8) {
|
||||||
|
ldo = 0; /* BIT 0 */
|
||||||
|
en_reg = RK817_POWER_EN(3);
|
||||||
|
} else {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (enable)
|
||||||
|
value = ((1 << ldo) | (1 << (ldo + 4)));
|
||||||
|
else
|
||||||
|
value = ((0 << ldo) | (1 << (ldo + 4)));
|
||||||
|
ret = pmic_reg_write(pmic, en_reg, value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -365,6 +511,17 @@ static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
|
||||||
ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask,
|
ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask,
|
||||||
enable ? 0 : mask);
|
enable ? 0 : mask);
|
||||||
break;
|
break;
|
||||||
|
case RK817_ID:
|
||||||
|
if (ldo == 8) {
|
||||||
|
mask = 1 << 4; /* LDO9 */
|
||||||
|
ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
|
||||||
|
enable ? mask : 0);
|
||||||
|
} else {
|
||||||
|
mask = 1 << ldo;
|
||||||
|
ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(1), mask,
|
||||||
|
enable ? mask : 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -373,12 +530,14 @@ static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
|
||||||
static int buck_get_value(struct udevice *dev)
|
static int buck_get_value(struct udevice *dev)
|
||||||
{
|
{
|
||||||
int buck = dev->driver_data - 1;
|
int buck = dev->driver_data - 1;
|
||||||
|
/* We assume level-1 voltage is enough for usage in U-Boot */
|
||||||
const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
|
const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
|
||||||
int mask = info->vsel_mask;
|
int mask = info->vsel_mask;
|
||||||
int ret, val;
|
int ret, val;
|
||||||
|
|
||||||
if (info->vsel_reg == -1)
|
if (info->vsel_reg == -1)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
ret = pmic_reg_read(dev->parent, info->vsel_reg);
|
ret = pmic_reg_read(dev->parent, info->vsel_reg);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -425,7 +584,7 @@ static int buck_get_enable(struct udevice *dev)
|
||||||
static int ldo_get_value(struct udevice *dev)
|
static int ldo_get_value(struct udevice *dev)
|
||||||
{
|
{
|
||||||
int ldo = dev->driver_data - 1;
|
int ldo = dev->driver_data - 1;
|
||||||
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
|
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
|
||||||
int mask = info->vsel_mask;
|
int mask = info->vsel_mask;
|
||||||
int ret, val;
|
int ret, val;
|
||||||
|
|
||||||
|
|
@ -442,15 +601,20 @@ static int ldo_get_value(struct udevice *dev)
|
||||||
static int ldo_set_value(struct udevice *dev, int uvolt)
|
static int ldo_set_value(struct udevice *dev, int uvolt)
|
||||||
{
|
{
|
||||||
int ldo = dev->driver_data - 1;
|
int ldo = dev->driver_data - 1;
|
||||||
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
|
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
|
||||||
int mask = info->vsel_mask;
|
int mask = info->vsel_mask;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
if (info->vsel_reg == -1)
|
if (info->vsel_reg == -1)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
val = (uvolt - info->min_uv) / info->step_uv;
|
|
||||||
debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
|
if (info->step_uv == 0)
|
||||||
val);
|
val = info->min_sel;
|
||||||
|
else
|
||||||
|
val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
|
||||||
|
|
||||||
|
debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
|
||||||
|
__func__, uvolt, ldo+1, info->vsel_reg, mask, val);
|
||||||
|
|
||||||
return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
|
return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
|
||||||
}
|
}
|
||||||
|
|
@ -458,15 +622,20 @@ static int ldo_set_value(struct udevice *dev, int uvolt)
|
||||||
static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
|
static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
|
||||||
{
|
{
|
||||||
int ldo = dev->driver_data - 1;
|
int ldo = dev->driver_data - 1;
|
||||||
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
|
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
|
||||||
int mask = info->vsel_mask;
|
int mask = info->vsel_mask;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
if (info->vsel_sleep_reg == -1)
|
if (info->vsel_sleep_reg == -1)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
val = (uvolt - info->min_uv) / info->step_uv;
|
|
||||||
debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_sleep_reg, mask,
|
if (info->step_uv == 0)
|
||||||
val);
|
val = info->min_sel;
|
||||||
|
else
|
||||||
|
val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
|
||||||
|
|
||||||
|
debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
|
||||||
|
__func__, uvolt, ldo+1, info->vsel_sleep_reg, mask, val);
|
||||||
|
|
||||||
return pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, mask, val);
|
return pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, mask, val);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,10 @@ enum {
|
||||||
RK808_NUM_OF_REGS,
|
RK808_NUM_OF_REGS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RK817_REG_SYS_CFG3 = 0xf4,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RK816_REG_DCDC_EN1 = 0x23,
|
RK816_REG_DCDC_EN1 = 0x23,
|
||||||
RK816_REG_DCDC_EN2,
|
RK816_REG_DCDC_EN2,
|
||||||
|
|
@ -183,9 +187,12 @@ enum {
|
||||||
RK805_ID = 0x8050,
|
RK805_ID = 0x8050,
|
||||||
RK808_ID = 0x0000,
|
RK808_ID = 0x0000,
|
||||||
RK816_ID = 0x8160,
|
RK816_ID = 0x8160,
|
||||||
|
RK817_ID = 0x8170,
|
||||||
RK818_ID = 0x8180,
|
RK818_ID = 0x8180,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RK817_ID_MSB 0xed
|
||||||
|
#define RK817_ID_LSB 0xee
|
||||||
#define RK8XX_ID_MSK 0xfff0
|
#define RK8XX_ID_MSK 0xfff0
|
||||||
|
|
||||||
struct rk8xx_reg_table {
|
struct rk8xx_reg_table {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue