[PATCH v4 1/7] mfd: axp20x: add AXP221 PMIC support
Lee Jones
lee.jones at linaro.org
Wed Jun 18 01:36:05 PDT 2014
On Tue, 17 Jun 2014, Boris BREZILLON wrote:
> Add support for the AXP221 PMIC device to the existing AXP20x driver.
>
> The AXP221 defines a new set of registers, power supplies and regulators,
> but most of the API is similar to the AXP20x ones.
> The AXP20x irq chip definition is reused, though some interrupts are not
> available in the AXP221.
>
> Signed-off-by: Boris BREZILLON <boris.brezillon at free-electrons.com>
> ---
> drivers/mfd/axp20x.c | 64 ++++++++++++++++++++++++++++++++++++++++++----
> include/linux/mfd/axp20x.h | 56 ++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 115 insertions(+), 5 deletions(-)
Looks good to me now.
Acked-by: Lee Jones <lee.jones at linaro.org>
Can this go in independently to the other patches in the set?
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index dee6539..ad4c177 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -33,6 +33,11 @@ static const struct regmap_range axp20x_writeable_ranges[] = {
> regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
> };
>
> +static const struct regmap_range axp22x_writeable_ranges[] = {
> + regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
> + regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
> +};
> +
> static const struct regmap_range axp20x_volatile_ranges[] = {
> regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
> };
> @@ -42,6 +47,11 @@ static const struct regmap_access_table axp20x_writeable_table = {
> .n_yes_ranges = ARRAY_SIZE(axp20x_writeable_ranges),
> };
>
> +static const struct regmap_access_table axp22x_writeable_table = {
> + .yes_ranges = axp22x_writeable_ranges,
> + .n_yes_ranges = ARRAY_SIZE(axp22x_writeable_ranges),
> +};
> +
> static const struct regmap_access_table axp20x_volatile_table = {
> .yes_ranges = axp20x_volatile_ranges,
> .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
> @@ -70,6 +80,15 @@ static const struct regmap_config axp20x_regmap_config = {
> .cache_type = REGCACHE_RBTREE,
> };
>
> +static const struct regmap_config axp22x_regmap_config = {
> + .reg_bits = 8,
> + .val_bits = 8,
> + .wr_table = &axp22x_writeable_table,
> + .volatile_table = &axp20x_volatile_table,
> + .max_register = AXP22X_BATLOW_THRES1,
> + .cache_type = REGCACHE_RBTREE,
> +};
> +
> #define AXP20X_IRQ(_irq, _off, _mask) \
> [AXP20X_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
>
> @@ -116,6 +135,7 @@ static const struct regmap_irq axp20x_regmap_irqs[] = {
> static const struct of_device_id axp20x_of_match[] = {
> { .compatible = "x-powers,axp202", .data = (void *) AXP202_ID },
> { .compatible = "x-powers,axp209", .data = (void *) AXP209_ID },
> + { .compatible = "x-powers,axp221", .data = (void *) AXP221_ID },
> { },
> };
> MODULE_DEVICE_TABLE(of, axp20x_of_match);
> @@ -149,6 +169,21 @@ static const char * const axp20x_supplies[] = {
> "ldo5in",
> };
>
> +static const char *axp22x_supplies[] = {
> + "vbus",
> + "acin",
> + "vin1",
> + "vin2",
> + "vin3",
> + "vin4",
> + "vin5",
> + "aldoin",
> + "dldoin",
> + "eldoin",
> + "ldoioin",
> + "rtcldoin",
> +};
> +
> static struct mfd_cell axp20x_cells[] = {
> {
> .name = "axp20x-pek",
> @@ -161,6 +196,14 @@ static struct mfd_cell axp20x_cells[] = {
> },
> };
>
> +static struct mfd_cell axp22x_cells[] = {
> + {
> + .name = "axp20x-regulator",
> + .parent_supplies = axp22x_supplies,
> + .num_parent_supplies = ARRAY_SIZE(axp22x_supplies),
> + },
> +};
> +
> static struct axp20x_dev *axp20x_pm_power_off;
> static void axp20x_power_off(void)
> {
> @@ -171,8 +214,11 @@ static void axp20x_power_off(void)
> static int axp20x_i2c_probe(struct i2c_client *i2c,
> const struct i2c_device_id *id)
> {
> - struct axp20x_dev *axp20x;
> + const struct regmap_config *regmap_cfg;
> const struct of_device_id *of_id;
> + struct axp20x_dev *axp20x;
> + struct mfd_cell *cells;
> + int ncells;
> int ret;
>
> axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL);
> @@ -190,7 +236,17 @@ static int axp20x_i2c_probe(struct i2c_client *i2c,
> axp20x->dev = &i2c->dev;
> dev_set_drvdata(axp20x->dev, axp20x);
>
> - axp20x->regmap = devm_regmap_init_i2c(i2c, &axp20x_regmap_config);
> + if (axp20x->variant == AXP221_ID) {
> + regmap_cfg = &axp22x_regmap_config;
> + cells = axp22x_cells;
> + ncells = ARRAY_SIZE(axp22x_cells);
> + } else {
> + regmap_cfg = &axp20x_regmap_config;
> + cells = axp20x_cells;
> + ncells = ARRAY_SIZE(axp20x_cells);
> + }
> +
> + axp20x->regmap = devm_regmap_init_i2c(i2c, regmap_cfg);
> if (IS_ERR(axp20x->regmap)) {
> ret = PTR_ERR(axp20x->regmap);
> dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
> @@ -206,9 +262,7 @@ static int axp20x_i2c_probe(struct i2c_client *i2c,
> return ret;
> }
>
> - ret = mfd_add_devices(axp20x->dev, -1, axp20x_cells,
> - ARRAY_SIZE(axp20x_cells), NULL, 0, NULL);
> -
> + ret = mfd_add_devices(axp20x->dev, -1, cells, ncells, NULL, 0, NULL);
> if (ret) {
> dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
> regmap_del_irq_chip(i2c->irq, axp20x->regmap_irqc);
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index d0e31a2..8a8ce02 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -14,6 +14,7 @@
> enum {
> AXP202_ID = 0,
> AXP209_ID,
> + AXP221_ID,
> };
>
> #define AXP20X_DATACACHE(m) (0x04 + (m))
> @@ -43,6 +44,28 @@ enum {
> #define AXP20X_V_LTF_DISCHRG 0x3c
> #define AXP20X_V_HTF_DISCHRG 0x3d
>
> +#define AXP22X_PWR_OUT_CTRL1 0x10
> +#define AXP22X_PWR_OUT_CTRL2 0x12
> +#define AXP22X_PWR_OUT_CTRL3 0x13
> +#define AXP22X_DLDO1_V_OUT 0x15
> +#define AXP22X_DLDO2_V_OUT 0x16
> +#define AXP22X_DLDO3_V_OUT 0x17
> +#define AXP22X_DLDO4_V_OUT 0x18
> +#define AXP22X_ELDO1_V_OUT 0x19
> +#define AXP22X_ELDO2_V_OUT 0x1a
> +#define AXP22X_ELDO3_V_OUT 0x1b
> +#define AXP22X_DC5LDO_V_OUT 0x1c
> +#define AXP22X_DCDC1_V_OUT 0x21
> +#define AXP22X_DCDC2_V_OUT 0x22
> +#define AXP22X_DCDC3_V_OUT 0x23
> +#define AXP22X_DCDC4_V_OUT 0x24
> +#define AXP22X_DCDC5_V_OUT 0x25
> +#define AXP22X_DCDC23_V_RAMP_CTRL 0x27
> +#define AXP22X_ALDO1_V_OUT 0x28
> +#define AXP22X_ALDO2_V_OUT 0x29
> +#define AXP22X_ALDO3_V_OUT 0x2a
> +#define AXP22X_CHRG_CTRL3 0x35
> +
> /* Interrupt */
> #define AXP20X_IRQ1_EN 0x40
> #define AXP20X_IRQ2_EN 0x41
> @@ -96,6 +119,9 @@ enum {
> #define AXP20X_VBUS_MON 0x8b
> #define AXP20X_OVER_TMP 0x8f
>
> +#define AXP22X_PWREN_CTRL1 0x8c
> +#define AXP22X_PWREN_CTRL2 0x8d
> +
> /* GPIO */
> #define AXP20X_GPIO0_CTRL 0x90
> #define AXP20X_LDO5_V_OUT 0x91
> @@ -104,6 +130,11 @@ enum {
> #define AXP20X_GPIO20_SS 0x94
> #define AXP20X_GPIO3_CTRL 0x95
>
> +#define AXP22X_LDO_IO0_V_OUT 0x91
> +#define AXP22X_LDO_IO1_V_OUT 0x93
> +#define AXP22X_GPIO_STATE 0x94
> +#define AXP22X_GPIO_PULL_DOWN 0x95
> +
> /* Battery */
> #define AXP20X_CHRG_CC_31_24 0xb0
> #define AXP20X_CHRG_CC_23_16 0xb1
> @@ -116,6 +147,8 @@ enum {
> #define AXP20X_CC_CTRL 0xb8
> #define AXP20X_FG_RES 0xb9
>
> +#define AXP22X_BATLOW_THRES1 0xe6
> +
> /* Regulators IDs */
> enum {
> AXP20X_LDO1 = 0,
> @@ -128,6 +161,29 @@ enum {
> AXP20X_REG_ID_MAX,
> };
>
> +enum {
> + AXP22X_DCDC1 = 0,
> + AXP22X_DCDC2,
> + AXP22X_DCDC3,
> + AXP22X_DCDC4,
> + AXP22X_DCDC5,
> + AXP22X_DC5LDO,
> + AXP22X_ALDO1,
> + AXP22X_ALDO2,
> + AXP22X_ALDO3,
> + AXP22X_ELDO1,
> + AXP22X_ELDO2,
> + AXP22X_ELDO3,
> + AXP22X_DLDO1,
> + AXP22X_DLDO2,
> + AXP22X_DLDO3,
> + AXP22X_DLDO4,
> + AXP22X_RTC_LDO,
> + AXP22X_LDO_IO0,
> + AXP22X_LDO_IO1,
> + AXP22X_REG_ID_MAX,
> +};
> +
> /* IRQs */
> enum {
> AXP20X_IRQ_ACIN_OVER_V = 1,
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
More information about the linux-arm-kernel
mailing list