diff options
Diffstat (limited to 'drivers/mfd/rk8xx-core.c')
-rw-r--r-- | drivers/mfd/rk8xx-core.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c index e2261b68b844..5eda3c0dbbdf 100644 --- a/drivers/mfd/rk8xx-core.c +++ b/drivers/mfd/rk8xx-core.c @@ -28,6 +28,10 @@ static const struct resource rtc_resources[] = { DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM), }; +static const struct resource rk816_rtc_resources[] = { + DEFINE_RES_IRQ(RK816_IRQ_RTC_ALARM), +}; + static const struct resource rk817_rtc_resources[] = { DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM), }; @@ -87,6 +91,22 @@ static const struct mfd_cell rk808s[] = { }, }; +static const struct mfd_cell rk816s[] = { + { .name = "rk805-pinctrl", }, + { .name = "rk808-clkout", }, + { .name = "rk808-regulator", }, + { + .name = "rk805-pwrkey", + .num_resources = ARRAY_SIZE(rk805_key_resources), + .resources = rk805_key_resources, + }, + { + .name = "rk808-rtc", + .num_resources = ARRAY_SIZE(rk816_rtc_resources), + .resources = rk816_rtc_resources, + }, +}; + static const struct mfd_cell rk817s[] = { { .name = "rk808-clkout", }, { .name = "rk808-regulator", }, @@ -148,6 +168,17 @@ static const struct rk808_reg_data rk808_pre_init_reg[] = { VB_LO_SEL_3500MV }, }; +static const struct rk808_reg_data rk816_pre_init_reg[] = { + { RK818_BUCK1_CONFIG_REG, RK817_RAMP_RATE_MASK, + RK817_RAMP_RATE_12_5MV_PER_US }, + { RK818_BUCK2_CONFIG_REG, RK817_RAMP_RATE_MASK, + RK817_RAMP_RATE_12_5MV_PER_US }, + { RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_250MA }, + { RK808_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP105C}, + { RK808_VB_MON_REG, VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK, + RK808_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN }, +}; + static const struct rk808_reg_data rk817_pre_init_reg[] = { {RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP}, /* Codec specific registers */ @@ -350,6 +381,59 @@ static const struct regmap_irq rk808_irqs[] = { }, }; +static const unsigned int rk816_irq_status_offsets[] = { + RK816_IRQ_STS_OFFSET(RK816_INT_STS_REG1), + RK816_IRQ_STS_OFFSET(RK816_INT_STS_REG2), + RK816_IRQ_STS_OFFSET(RK816_INT_STS_REG3), +}; + +static const unsigned int rk816_irq_mask_offsets[] = { + RK816_IRQ_MSK_OFFSET(RK816_INT_STS_MSK_REG1), + RK816_IRQ_MSK_OFFSET(RK816_INT_STS_MSK_REG2), + RK816_IRQ_MSK_OFFSET(RK816_INT_STS_MSK_REG3), +}; + +static unsigned int rk816_get_irq_reg(struct regmap_irq_chip_data *data, + unsigned int base, int index) +{ + unsigned int irq_reg = base; + + switch (base) { + case RK816_INT_STS_REG1: + irq_reg += rk816_irq_status_offsets[index]; + break; + case RK816_INT_STS_MSK_REG1: + irq_reg += rk816_irq_mask_offsets[index]; + break; + } + + return irq_reg; +}; + +static const struct regmap_irq rk816_irqs[] = { + /* INT_STS_REG1 IRQs */ + REGMAP_IRQ_REG(RK816_IRQ_PWRON_FALL, 0, RK816_INT_STS_PWRON_FALL), + REGMAP_IRQ_REG(RK816_IRQ_PWRON_RISE, 0, RK816_INT_STS_PWRON_RISE), + + /* INT_STS_REG2 IRQs */ + REGMAP_IRQ_REG(RK816_IRQ_VB_LOW, 1, RK816_INT_STS_VB_LOW), + REGMAP_IRQ_REG(RK816_IRQ_PWRON, 1, RK816_INT_STS_PWRON), + REGMAP_IRQ_REG(RK816_IRQ_PWRON_LP, 1, RK816_INT_STS_PWRON_LP), + REGMAP_IRQ_REG(RK816_IRQ_HOTDIE, 1, RK816_INT_STS_HOTDIE), + REGMAP_IRQ_REG(RK816_IRQ_RTC_ALARM, 1, RK816_INT_STS_RTC_ALARM), + REGMAP_IRQ_REG(RK816_IRQ_RTC_PERIOD, 1, RK816_INT_STS_RTC_PERIOD), + REGMAP_IRQ_REG(RK816_IRQ_USB_OV, 1, RK816_INT_STS_USB_OV), + + /* INT_STS3 IRQs */ + REGMAP_IRQ_REG(RK816_IRQ_PLUG_IN, 2, RK816_INT_STS_PLUG_IN), + REGMAP_IRQ_REG(RK816_IRQ_PLUG_OUT, 2, RK816_INT_STS_PLUG_OUT), + REGMAP_IRQ_REG(RK816_IRQ_CHG_OK, 2, RK816_INT_STS_CHG_OK), + REGMAP_IRQ_REG(RK816_IRQ_CHG_TE, 2, RK816_INT_STS_CHG_TE), + REGMAP_IRQ_REG(RK816_IRQ_CHG_TS, 2, RK816_INT_STS_CHG_TS), + REGMAP_IRQ_REG(RK816_IRQ_CHG_CVTLIM, 2, RK816_INT_STS_CHG_CVTLIM), + REGMAP_IRQ_REG(RK816_IRQ_DISCHG_ILIM, 2, RK816_INT_STS_DISCHG_ILIM), +}; + static const struct regmap_irq rk818_irqs[] = { /* INT_STS */ [RK818_IRQ_VOUT_LO] = { @@ -482,6 +566,18 @@ static const struct regmap_irq_chip rk808_irq_chip = { .init_ack_masked = true, }; +static const struct regmap_irq_chip rk816_irq_chip = { + .name = "rk816", + .irqs = rk816_irqs, + .num_irqs = ARRAY_SIZE(rk816_irqs), + .num_regs = 3, + .get_irq_reg = rk816_get_irq_reg, + .status_base = RK816_INT_STS_REG1, + .mask_base = RK816_INT_STS_MSK_REG1, + .ack_base = RK816_INT_STS_REG1, + .init_ack_masked = true, +}; + static struct regmap_irq_chip rk817_irq_chip = { .name = "rk817", .irqs = rk817_irqs, @@ -530,6 +626,7 @@ static int rk808_power_off(struct sys_off_data *data) reg = RK817_SYS_CFG(3); bit = DEV_OFF; break; + case RK816_ID: case RK818_ID: reg = RK818_DEVCTRL_REG; bit = DEV_OFF; @@ -637,6 +734,13 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap cells = rk808s; nr_cells = ARRAY_SIZE(rk808s); break; + case RK816_ID: + rk808->regmap_irq_chip = &rk816_irq_chip; + pre_init_reg = rk816_pre_init_reg; + nr_pre_init_regs = ARRAY_SIZE(rk816_pre_init_reg); + cells = rk816s; + nr_cells = ARRAY_SIZE(rk816s); + break; case RK818_ID: rk808->regmap_irq_chip = &rk818_irq_chip; pre_init_reg = rk818_pre_init_reg; |