From: Khiem Nguyen <khiem.nguyen.xt@xxxxxxxxxxx> The new PMIC BD9574MWF inherits features from BD9571MWV. Add the support of new PMIC to existing bd9571mwv driver. Signed-off-by: Khiem Nguyen <khiem.nguyen.xt@xxxxxxxxxxx> [shimoda: rebase and refactor] Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@xxxxxxxxxxx> --- drivers/mfd/bd9571mwv.c | 92 +++++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/bd9571mwv.h | 80 +++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/drivers/mfd/bd9571mwv.c b/drivers/mfd/bd9571mwv.c index 57bdb6a..f8f0a87 100644 --- a/drivers/mfd/bd9571mwv.c +++ b/drivers/mfd/bd9571mwv.c @@ -20,6 +20,7 @@ static const struct mfd_cell bd9571mwv_cells[] = { { .name = "bd9571mwv-gpio", }, }; +/* Regmap for BD9571MWV */ static const struct regmap_range bd9571mwv_readable_yes_ranges[] = { regmap_reg_range(BD9571MWV_VENDOR_CODE, BD9571MWV_PRODUCT_REVISION), regmap_reg_range(BD9571MWV_BKUP_MODE_CNT, BD9571MWV_BKUP_MODE_CNT), @@ -112,6 +113,95 @@ static const struct bd957x_data bd9571mwv_data = { .num_cells = ARRAY_SIZE(bd9571mwv_cells), }; +static const struct mfd_cell bd9574mwf_cells[] = { + { .name = "bd9571mwv-gpio", }, +}; + +/* Regmap for BD9574MWF */ +static const struct regmap_range bd9574mwf_readable_yes_ranges[] = { + regmap_reg_range(BD9574MWF_VENDOR_CODE, BD9574MWF_PRODUCT_REVISION), + regmap_reg_range(BD9574MWF_GPIO_IN, BD9574MWF_GPIO_IN), + regmap_reg_range(BD9574MWF_GPIO_INT, BD9574MWF_GPIO_INTMASK), + regmap_reg_range(BD9574MWF_GPIO_MUX, BD9574MWF_GPIO_MUX), + regmap_reg_range(BD9574MWF_INT_INTREQ, BD9574MWF_INT_INTMASK), +}; + +static const struct regmap_access_table bd9574mwf_readable_table = { + .yes_ranges = bd9574mwf_readable_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(bd9574mwf_readable_yes_ranges), +}; + +static const struct regmap_range bd9574mwf_writable_yes_ranges[] = { + regmap_reg_range(BD9574MWF_GPIO_DIR, BD9574MWF_GPIO_OUT), + regmap_reg_range(BD9574MWF_GPIO_INT_SET, BD9574MWF_GPIO_INTMASK), + regmap_reg_range(BD9574MWF_INT_INTREQ, BD9574MWF_INT_INTMASK), +}; + +static const struct regmap_access_table bd9574mwf_writable_table = { + .yes_ranges = bd9574mwf_writable_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(bd9574mwf_writable_yes_ranges), +}; + +static const struct regmap_range bd9574mwf_volatile_yes_ranges[] = { + regmap_reg_range(BD9574MWF_GPIO_IN, BD9574MWF_GPIO_IN), + regmap_reg_range(BD9574MWF_GPIO_INT, BD9574MWF_GPIO_INT), + regmap_reg_range(BD9574MWF_INT_INTREQ, BD9574MWF_INT_INTREQ), +}; + +static const struct regmap_access_table bd9574mwf_volatile_table = { + .yes_ranges = bd9574mwf_volatile_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(bd9574mwf_volatile_yes_ranges), +}; + +static const struct regmap_config bd9574mwf_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .rd_table = &bd9574mwf_readable_table, + .wr_table = &bd9574mwf_writable_table, + .volatile_table = &bd9574mwf_volatile_table, + .max_register = 0xff, +}; + +static const struct regmap_irq bd9574mwf_irqs[] = { + REGMAP_IRQ_REG(BD9574MWF_IRQ_MD1, 0, + BD9574MWF_INT_INTREQ_MD1_INT), + REGMAP_IRQ_REG(BD9574MWF_IRQ_MD2_E1, 0, + BD9574MWF_INT_INTREQ_MD2_E1_INT), + REGMAP_IRQ_REG(BD9574MWF_IRQ_MD2_E2, 0, + BD9574MWF_INT_INTREQ_MD2_E2_INT), + REGMAP_IRQ_REG(BD9574MWF_IRQ_PROT_ERR, 0, + BD9574MWF_INT_INTREQ_PROT_ERR_INT), + REGMAP_IRQ_REG(BD9574MWF_IRQ_GP, 0, + BD9574MWF_INT_INTREQ_GP_INT), + REGMAP_IRQ_REG(BD9574MWF_IRQ_BKUP_HOLD_OF, 0, + BD9574MWF_INT_INTREQ_BKUP_HOLD_OF_INT), + REGMAP_IRQ_REG(BD9574MWF_IRQ_WDT_OF, 0, + BD9574MWF_INT_INTREQ_WDT_OF_INT), + REGMAP_IRQ_REG(BD9574MWF_IRQ_BKUP_TRG, 0, + BD9574MWF_INT_INTREQ_BKUP_TRG_INT), +}; + +static struct regmap_irq_chip bd9574mwf_irq_chip = { + .name = "bd9574mwf", + .status_base = BD9574MWF_INT_INTREQ, + .mask_base = BD9574MWF_INT_INTMASK, + .ack_base = BD9574MWF_INT_INTREQ, + .init_ack_masked = true, + .num_regs = 1, + .irqs = bd9574mwf_irqs, + .num_irqs = ARRAY_SIZE(bd9574mwf_irqs), +}; + +static const struct bd957x_data bd9574mwf_data = { + .product_code_val = BD9574MWF_PRODUCT_CODE_VAL, + .part_number = BD9574MWF_PART_NUMBER, + .regmap_config = &bd9574mwf_regmap_config, + .irq_chip = &bd9574mwf_irq_chip, + .cells = bd9574mwf_cells, + .num_cells = ARRAY_SIZE(bd9574mwf_cells), +}; + static int bd9571mwv_identify(struct bd9571mwv *bd) { struct device *dev = bd->dev; @@ -182,6 +272,8 @@ static int bd9571mwv_probe(struct i2c_client *client, product_code = (unsigned int)ret; if (product_code == BD9571MWV_PRODUCT_CODE_VAL) bd->data = &bd9571mwv_data; + else if (product_code == BD9574MWF_PRODUCT_CODE_VAL) + bd->data = &bd9574mwf_data; if (!bd->data) { dev_err(bd->dev, "No found supported device %d\n", diff --git a/include/linux/mfd/bd9571mwv.h b/include/linux/mfd/bd9571mwv.h index 0126b52..e9e219b 100644 --- a/include/linux/mfd/bd9571mwv.h +++ b/include/linux/mfd/bd9571mwv.h @@ -99,6 +99,86 @@ enum bd9571mwv_irqs { BD9571MWV_IRQ_BKUP_TRG, }; +/* List of registers for BD9574MWF */ +#define BD9574MWF_VENDOR_CODE 0x00 +#define BD9574MWF_VENDOR_CODE_VAL 0xdb +#define BD9574MWF_PRODUCT_CODE 0x01 +#define BD9574MWF_PRODUCT_CODE_VAL 0x74 +#define BD9574MWF_PRODUCT_REVISION 0x02 + +#define BD9574MWF_I2C_FUSA_MODE 0x10 +#define BD9574MWF_I2C_MD2_E1_BIT_1 0x11 +#define BD9574MWF_I2C_MD2_E1_BIT_2 0x12 + +#define BD9574MWF_BKUP_MODE_CNT 0x20 +#define BD9574MWF_BKUP_MODE_STATUS 0x21 +#define BD9574MWF_BKUP_RECOVERY_CNT 0x22 +#define BD9574MWF_BKUP_CTRL_TIM_CNT 0x23 +#define BD9574MWF_WAITBKUP_WDT_CNT 0x24 +#define BD9574MWF_BKUP_HOLD_TIM_CNT1 0x26 +#define BD9574MWF_QLLM_CNT 0x27 +#define BD9574MWF_BKUP_HOLD_TIM_CNT2 0x28 + +#define BD9574MWF_DCDC_FREQ 0x48 + +#define BD9574MWF_VDCORE_VINIT 0x50 +#define BD9574MWF_VD09_VINIT 0x51 +#define BD9574MWF_VDCORE_SETVMAX 0x52 +#define BD9574MWF_VDCORE_SETVID 0x54 +#define BD9574MWF_VDCORE_MONIVDAC 0x55 +#define BD9574MWF_VDCORE_PGD_CNT 0x56 + +#define BD9574MWF_GPIO_DIR 0x60 +#define BD9574MWF_GPIO_OUT 0x61 +#define BD9574MWF_GPIO_IN 0x62 +#define BD9574MWF_GPIO_DEB 0x63 +#define BD9574MWF_GPIO_INT_SET 0x64 +#define BD9574MWF_GPIO_INT 0x65 +#define BD9574MWF_GPIO_INTMASK 0x66 +#define BD9574MWF_GPIO_MUX 0x67 + +#define BD9574MWF_REG_KEEP(n) (0x70 + (n)) + +#define BD9574MWF_PMIC_INTERNAL_STATUS 0x80 +#define BD9574MWF_PROT_ERROR_STATUS0 0x81 +#define BD9574MWF_PROT_ERROR_STATUS1 0x82 +#define BD9574MWF_PROT_ERROR_STATUS2 0x83 +#define BD9574MWF_PROT_ERROR_STATUS3 0x84 +#define BD9574MWF_PROT_ERROR_STATUS4 0x85 +#define BD9574MWF_PROT_ERROR_STATUS5 0x86 +#define BD9574MWF_SYS_ERROR_STATUS 0x87 + +#define BD9574MWF_INT_INTREQ 0x90 +#define BD9574MWF_INT_INTREQ_MD1_INT BIT(0) +#define BD9574MWF_INT_INTREQ_MD2_E1_INT BIT(1) +#define BD9574MWF_INT_INTREQ_MD2_E2_INT BIT(2) +#define BD9574MWF_INT_INTREQ_PROT_ERR_INT BIT(3) +#define BD9574MWF_INT_INTREQ_GP_INT BIT(4) +#define BD9574MWF_INT_INTREQ_BKUP_HOLD_OF_INT BIT(5) +#define BD9574MWF_INT_INTREQ_WDT_OF_INT BIT(6) +#define BD9574MWF_INT_INTREQ_BKUP_TRG_INT BIT(7) +#define BD9574MWF_INT_INTMASK 0x91 + +#define BD9574MWF_SSCG_CNT 0xA0 +#define BD9574MWF_POFFB_MRB 0xA1 +#define BD9574MWF_SMRB_WR_PROT 0xA2 +#define BD9574MWF_SMRB_ASSERT 0xA3 +#define BD9574MWF_SMRB_STATUS 0xA4 + +#define BD9574MWF_PART_NUMBER "BD9574MWF" + +/* Define the BD9574MWF IRQ numbers */ +enum bd9574mwf_irqs { + BD9574MWF_IRQ_MD1, + BD9574MWF_IRQ_MD2_E1, + BD9574MWF_IRQ_MD2_E2, + BD9574MWF_IRQ_PROT_ERR, + BD9574MWF_IRQ_GP, + BD9574MWF_IRQ_BKUP_HOLD_OF, + BD9574MWF_IRQ_WDT_OF, + BD9574MWF_IRQ_BKUP_TRG, +}; + /** * struct bd957x_data - internal data for the bd957x driver * -- 2.7.4