On Fri, 18 Nov 2016, Eric Jeong wrote: > > From: Eric Jeong <eric.jeong.opensource@xxxxxxxxxxx> > > This patch adds supports for PV88080 MFD core device. > > It provides communication through the I2C interface. > It contains the following components: > - Regulators > - Configurable GPIOs > > Kconfig and Makefile are updated to reflect support for PV88080 PMIC. > > Signed-off-by: Eric Jeong <eric.jeong.opensource@xxxxxxxxxxx> > > --- > This patch applies against linux-next and next-20161117 > > Hi, > > This patch adds MFD core driver for PV88080 PMIC. > This is done as part of the existing PV88080 regulator driver by expending > the driver for GPIO function support. > > Change since PATCH V2 > - Make one file insted of usging core and i2c file > - Use devm_ function to be managed resource automatically > - Separated mfd_cell and regmap_irq_chip declaration for clarification. > - Updated Kconfig to use OF and assign yes to I2C > > Change since PATCH V1 > - Patch separated from PATCH V1 > > Regards, > Eric Jeong, Dialog Semiconductor Ltd. > > > drivers/mfd/Kconfig | 12 ++ > drivers/mfd/Makefile | 1 + > drivers/mfd/pv88080.c | 331 +++++++++++++++++++++++++++++++++++++++++++ > include/linux/mfd/pv88080.h | 222 +++++++++++++++++++++++++++++ > 4 files changed, 566 insertions(+) > create mode 100644 drivers/mfd/pv88080.c > create mode 100644 include/linux/mfd/pv88080.h > > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index 06dc9b0..75abf2d 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -792,6 +792,18 @@ config MFD_PM8921_CORE > Say M here if you want to include support for PM8921 chip as a module. > This will build a module called "pm8921-core". > > +config MFD_PV88080 > + tristate "Powerventure Semiconductor PV88080 PMIC Support" > + select MFD_CORE > + select REGMAP_I2C > + select REGMAP_IRQ > + depends on I2C=y && OF > + help > + Say yes here for support for the Powerventure Semiconductor PV88080 PMIC. > + This includes the I2C driver and core APIs. > + Additional drivers must be enabled in order to use the functionality > + of the device. > + > config MFD_QCOM_RPM > tristate "Qualcomm Resource Power Manager (RPM)" > depends on ARCH_QCOM && OF > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index db39377..e9e16c6 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -173,6 +173,7 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o > obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o > obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o > obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o > +obj-$(CONFIG_MFD_PV88080) += pv88080.o > obj-$(CONFIG_MFD_QCOM_RPM) += qcom_rpm.o > obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o > obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o > diff --git a/drivers/mfd/pv88080.c b/drivers/mfd/pv88080.c > new file mode 100644 > index 0000000..518b44f > --- /dev/null > +++ b/drivers/mfd/pv88080.c > @@ -0,0 +1,331 @@ > +/* > + * pv88080-i2c.c - I2C access driver for PV88080 Remove the filename. They have a habit of becoming out of date (like now). > + * Copyright (C) 2016 Powerventure Semiconductor Ltd. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include <linux/i2c.h> > +#include <linux/module.h> > +#include <linux/regmap.h> > +#include <linux/interrupt.h> > +#include <linux/mfd/core.h> > +#include <linux/module.h> Alphabetical. > +#include <linux/mfd/pv88080.h> This doesn't need to be separated from the rest. > +#define PV88080_REG_EVENT_A_OFFSET 0 > +#define PV88080_REG_EVENT_B_OFFSET 1 > +#define PV88080_REG_EVENT_C_OFFSET 2 Spaces after 'define'. > +static const struct resource regulators_aa_resources[] = { > + { > + .name = "VDD_TEMP_FAULT", > + .start = PV88080_AA_IRQ_VDD_FLT, > + .end = PV88080_AA_IRQ_OVER_TEMP, > + .flags = IORESOURCE_IRQ, > + }, > +}; > + > +static const struct resource regulators_ba_resources[] = { > + { > + .name = "VDD_TEMP_FAULT", > + .start = PV88080_BA_IRQ_VDD_FLT, > + .end = PV88080_BA_IRQ_OVER_TEMP, > + .flags = IORESOURCE_IRQ, > + }, > +}; Use the DEFINE_RES_* macros. > +static const struct mfd_cell pv88080_aa_cells[] = { > + { > + .name = "pv88080-regulator", > + .num_resources = ARRAY_SIZE(regulators_aa_resources), > + .resources = regulators_aa_resources, > + .of_compatible = "pvs,pv88080-regulator", > + }, > + { > + .name = "pv88080-gpio", > + .of_compatible = "pvs,pv88080-gpio", > + }, > +}; > + > +static const struct mfd_cell pv88080_ba_cells[] = { > + { > + .name = "pv88080-regulator", > + .num_resources = ARRAY_SIZE(regulators_ba_resources), > + .resources = regulators_ba_resources, > + .of_compatible = "pvs,pv88080-regulator", > + }, > + { > + .name = "pv88080-gpio", > + .of_compatible = "pvs,pv88080-gpio", > + }, > +}; > + > +static const struct regmap_irq pv88080_aa_irqs[] = { > + /* PV88080 event A register for AA/AB silicon */ > + [PV88080_AA_IRQ_VDD_FLT] = { > + .reg_offset = PV88080_REG_EVENT_A_OFFSET, > + .mask = PV88080_M_VDD_FLT, > + }, > + [PV88080_AA_IRQ_OVER_TEMP] = { > + .reg_offset = PV88080_REG_EVENT_A_OFFSET, > + .mask = PV88080_M_OVER_TEMP, > + }, > + [PV88080_AA_IRQ_SEQ_RDY] = { > + .reg_offset = PV88080_REG_EVENT_A_OFFSET, > + .mask = PV88080_M_SEQ_RDY, > + }, > + /* PV88080 event B register for AA/AB silicon */ > + [PV88080_AA_IRQ_HVBUCK_OV] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_HVBUCK_OV, > + }, > + [PV88080_AA_IRQ_HVBUCK_UV] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_HVBUCK_UV, > + }, > + [PV88080_AA_IRQ_HVBUCK_SCP] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_HVBUCK_SCP, > + }, > + [PV88080_AA_IRQ_BUCK1_SCP] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_BUCK1_SCP, > + }, > + [PV88080_AA_IRQ_BUCK2_SCP] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_BUCK2_SCP, > + }, > + [PV88080_AA_IRQ_BUCK3_SCP] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_BUCK3_SCP, > + }, > + /* PV88080 event C register for AA/AB silicon */ > + [PV88080_AA_IRQ_GPIO_FLAG0] = { > + .reg_offset = PV88080_REG_EVENT_C_OFFSET, > + .mask = PV88080_M_GPIO_FLAG0, > + }, > + [PV88080_AA_IRQ_GPIO_FLAG1] = { > + .reg_offset = PV88080_REG_EVENT_C_OFFSET, > + .mask = PV88080_M_GPIO_FLAG1, > + }, > +}; > + > +static const struct regmap_irq pv88080_ba_irqs[] = { > + /* PV88080 event A register for BA/BB silicon */ > + [PV88080_BA_IRQ_VDD_FLT] = { > + .reg_offset = PV88080_REG_EVENT_A_OFFSET, > + .mask = PV88080_M_VDD_FLT, > + }, > + [PV88080_BA_IRQ_OVER_TEMP] = { > + .reg_offset = PV88080_REG_EVENT_A_OFFSET, > + .mask = PV88080_M_OVER_TEMP, > + }, > + [PV88080_BA_IRQ_SEQ_RDY] = { > + .reg_offset = PV88080_REG_EVENT_A_OFFSET, > + .mask = PV88080_M_SEQ_RDY, > + }, > + [PV88080_BA_IRQ_EXT_OT] = { > + .reg_offset = PV88080_REG_EVENT_A_OFFSET, > + .mask = PV88080_M_EXT_OT, > + }, > + /* PV88080 event B register for BA/BB silicon */ > + [PV88080_BA_IRQ_HVBUCK_OV] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_HVBUCK_OV, > + }, > + [PV88080_BA_IRQ_HVBUCK_UV] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_HVBUCK_UV, > + }, > + [PV88080_BA_IRQ_HVBUCK_SCP] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_HVBUCK_SCP, > + }, > + [PV88080_BA_IRQ_BUCK1_SCP] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_BUCK1_SCP, > + }, > + [PV88080_BA_IRQ_BUCK2_SCP] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_BUCK2_SCP, > + }, > + [PV88080_BA_IRQ_BUCK3_SCP] = { > + .reg_offset = PV88080_REG_EVENT_B_OFFSET, > + .mask = PV88080_M_BUCK3_SCP, > + }, > + /* PV88080 event C register for BA/BB silicon */ > + [PV88080_BA_IRQ_GPIO_FLAG0] = { > + .reg_offset = PV88080_REG_EVENT_C_OFFSET, > + .mask = PV88080_M_GPIO_FLAG0, > + }, > + [PV88080_BA_IRQ_GPIO_FLAG1] = { > + .reg_offset = PV88080_REG_EVENT_C_OFFSET, > + .mask = PV88080_M_GPIO_FLAG1, > + }, > + [PV88080_BA_IRQ_BUCK1_DROP_TIMEOUT] = { > + .reg_offset = PV88080_REG_EVENT_C_OFFSET, > + .mask = PV88080_M_BUCK1_DROP_TIMEOUT, > + }, > + [PV88080_BA_IRQ_BUCK2_DROP_TIMEOUT] = { > + .reg_offset = PV88080_REG_EVENT_C_OFFSET, > + .mask = PV88080_M_BUCK2_DROP_TIMEOUT, > + }, > + [PB88080_BA_IRQ_BUCK3_DROP_TIMEOUT] = { > + .reg_offset = PV88080_REG_EVENT_C_OFFSET, > + .mask = PV88080_M_BUCk3_DROP_TIMEOUT, > + }, > +}; > + > +static const struct regmap_irq_chip pv88080_aa_irq_chip = { > + .name = "pv88080-irq", > + .irqs = pv88080_aa_irqs, > + .num_irqs = ARRAY_SIZE(pv88080_aa_irqs), > + .num_regs = 3, > + .status_base = PV88080_REG_EVENT_A, > + .mask_base = PV88080_REG_MASK_A, > + .ack_base = PV88080_REG_EVENT_A, > + .init_ack_masked = true, > +}; > + > +static const struct regmap_irq_chip pv88080_ba_irq_chip = { > + .name = "pv88080-irq", > + .irqs = pv88080_ba_irqs, > + .num_irqs = ARRAY_SIZE(pv88080_ba_irqs), > + .num_regs = 3, > + .status_base = PV88080_REG_EVENT_A, > + .mask_base = PV88080_REG_MASK_A, > + .ack_base = PV88080_REG_EVENT_A, > + .init_ack_masked = true, > +}; > + > +static const struct regmap_config pv88080_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > +}; > + > +static const struct of_device_id pv88080_of_match_table[] = { > + { .compatible = "pvs,pv88080", .data = (void *)TYPE_PV88080_AA }, > + { .compatible = "pvs,pv88080-aa", .data = (void *)TYPE_PV88080_AA }, > + { .compatible = "pvs,pv88080-ba", .data = (void *)TYPE_PV88080_BA }, > + { }, > +}; > +MODULE_DEVICE_TABLE(of, pv88080_of_match_table); > + > +static int pv88080_probe(struct i2c_client *client, > + const struct i2c_device_id *ids) > +{ > + struct pv88080 *chip; > + const struct of_device_id *match; > + const struct regmap_irq_chip *pv88080_irq_chips; > + const struct mfd_cell *pv88080_mfd_cells; > + int ret, n_devs; > + > + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); > + if (!chip) > + return -ENOMEM; > + > + if (client->dev.of_node) { > + match = of_match_node(pv88080_of_match_table, > + client->dev.of_node); > + if (!match) { > + dev_err(&client->dev, "Failed to get of_match_node\n"); > + return -EINVAL; -ENODEV > + } > + chip->type = (unsigned long)match->data; > + } else { > + chip->type = ids->driver_data; > + } > + > + i2c_set_clientdata(client, chip); > + > + chip->irq = client->irq; > + chip->dev = &client->dev; > + > + chip->regmap = devm_regmap_init_i2c(client, &pv88080_regmap_config); > + if (IS_ERR(chip->regmap)) { > + dev_err(chip->dev, "Failed to initialize register map\n"); > + return PTR_ERR(chip->regmap); > + } > + > + ret = regmap_write(chip->regmap, PV88080_REG_MASK_A, 0xFF); > + if (ret < 0) { > + dev_err(chip->dev, "Failed to mask A reg: %d\n", ret); > + return ret; > + } > + ret = regmap_write(chip->regmap, PV88080_REG_MASK_B, 0xFF); > + if (ret < 0) { > + dev_err(chip->dev, "Failed to mask B reg: %d\n", ret); > + return ret; > + } > + ret = regmap_write(chip->regmap, PV88080_REG_MASK_C, 0xFF); > + if (ret < 0) { > + dev_err(chip->dev, "Failed to mask C reg: %d\n", ret); > + return ret; > + } What do these calls do? > + switch (chip->type) { > + case TYPE_PV88080_AA: > + pv88080_irq_chips = &pv88080_aa_irq_chip; > + pv88080_mfd_cells = pv88080_aa_cells; > + n_devs = ARRAY_SIZE(pv88080_aa_cells); > + break; > + case TYPE_PV88080_BA: > + pv88080_irq_chips = &pv88080_ba_irq_chip; > + pv88080_mfd_cells = pv88080_ba_cells; > + n_devs = ARRAY_SIZE(pv88080_ba_cells); > + break; > + } > + > + ret = devm_regmap_add_irq_chip(chip->dev, chip->regmap, > + chip->irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, > + 0, pv88080_irq_chips, &chip->irq_data); > + if (ret) { > + dev_err(chip->dev, "Failed to add IRQ %d: %d\n", > + chip->irq, ret); > + return ret; > + } > + > + ret = devm_mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, > + pv88080_mfd_cells, n_devs, > + NULL, 0, NULL); > + if (ret) { > + dev_err(chip->dev, "Failed to add MFD devices\n"); > + return ret; > + } > + > + return 0; > +} > + > +static const struct i2c_device_id pv88080_id_table[] = { > + { "pv88080", TYPE_PV88080_AA }, > + { "pv88080-aa", TYPE_PV88080_AA }, > + { "pv88080-ba", TYPE_PV88080_BA }, > + { }, > +}; > +MODULE_DEVICE_TABLE(i2c, pv88080_id_table); > + > +static struct i2c_driver pv88080_driver = { > + .driver = { > + .name = "pv88080", > + .of_match_table = of_match_ptr(pv88080_of_match_table), > + }, > + .probe = pv88080_probe, > + .id_table = pv88080_id_table, > +}; > +module_i2c_driver(pv88080_driver); > + > +MODULE_AUTHOR("Eric Jeong <eric.jeong.opensource@xxxxxxxxxxx>"); > +MODULE_DESCRIPTION("MFD Driver for Powerventure PV88080"); > +MODULE_LICENSE("GPL"); > + > diff --git a/include/linux/mfd/pv88080.h b/include/linux/mfd/pv88080.h > new file mode 100644 > index 0000000..76d6656 > --- /dev/null > +++ b/include/linux/mfd/pv88080.h > @@ -0,0 +1,222 @@ > +/* > + * pv88080.h - Declarations for PV88080. Remove filename. > + * Copyright (C) 2016 Powerventure Semiconductor Ltd. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#ifndef __PV88080_H__ > +#define __PV88080_H__ > + > +#include <linux/regulator/machine.h> > +#include <linux/device.h> > +#include <linux/regmap.h> > + > +/* System Control and Event Registers */ > +#define PV88080_REG_STATUS_A 0x01 > +#define PV88080_REG_EVENT_A 0x04 > +#define PV88080_REG_MASK_A 0x09 > +#define PV88080_REG_MASK_B 0x0A > +#define PV88080_REG_MASK_C 0x0B > + > +/* GPIO Registers - rev. AA */ > +#define PV88080AA_REG_GPIO_INPUT 0x18 > +#define PV88080AA_REG_GPIO_OUTPUT 0x19 > +#define PV88080AA_REG_GPIO_GPIO0 0x1A > + > +/* Regulator Registers - rev. AA */ > +#define PV88080AA_REG_HVBUCK_CONF1 0x2D > +#define PV88080AA_REG_HVBUCK_CONF2 0x2E > +#define PV88080AA_REG_BUCK1_CONF0 0x27 > +#define PV88080AA_REG_BUCK1_CONF1 0x28 > +#define PV88080AA_REG_BUCK1_CONF2 0x59 > +#define PV88080AA_REG_BUCK1_CONF5 0x5C > +#define PV88080AA_REG_BUCK2_CONF0 0x29 > +#define PV88080AA_REG_BUCK2_CONF1 0x2A > +#define PV88080AA_REG_BUCK2_CONF2 0x61 > +#define PV88080AA_REG_BUCK2_CONF5 0x64 > +#define PV88080AA_REG_BUCK3_CONF0 0x2B > +#define PV88080AA_REG_BUCK3_CONF1 0x2C > +#define PV88080AA_REG_BUCK3_CONF2 0x69 > +#define PV88080AA_REG_BUCK3_CONF5 0x6C > + > +/* GPIO Registers - rev. BA */ > +#define PV88080BA_REG_GPIO_INPUT 0x17 > +#define PV88080BA_REG_GPIO_OUTPUT 0x18 > +#define PV88080BA_REG_GPIO_GPIO0 0x19 > + > +/* Regulator Registers - rev. BA */ > +#define PV88080BA_REG_HVBUCK_CONF1 0x33 > +#define PV88080BA_REG_HVBUCK_CONF2 0x34 > +#define PV88080BA_REG_BUCK1_CONF0 0x2A > +#define PV88080BA_REG_BUCK1_CONF1 0x2C > +#define PV88080BA_REG_BUCK1_CONF2 0x5A > +#define PV88080BA_REG_BUCK1_CONF5 0x5D > +#define PV88080BA_REG_BUCK2_CONF0 0x2D > +#define PV88080BA_REG_BUCK2_CONF1 0x2F > +#define PV88080BA_REG_BUCK2_CONF2 0x63 > +#define PV88080BA_REG_BUCK2_CONF5 0x66 > +#define PV88080BA_REG_BUCK3_CONF0 0x30 > +#define PV88080BA_REG_BUCK3_CONF1 0x32 > +#define PV88080BA_REG_BUCK3_CONF2 0x6C > +#define PV88080BA_REG_BUCK3_CONF5 0x6F > + > +/* PV88080_REG_EVENT_A (addr=0x04) */ > +#define PV88080_E_VDD_FLT 0x01 > +#define PV88080_E_OVER_TEMP 0x02 > +#define PV88080_E_SEQ_RDY 0x04 > +#define PV88080_E_EXT_OT 0x08 > + > +/* PV88080_REG_MASK_A (addr=0x09) */ > +#define PV88080_M_VDD_FLT 0x01 > +#define PV88080_M_OVER_TEMP 0x02 > +#define PV88080_M_SEQ_RDY 0x04 > +#define PV88080_M_EXT_OT 0x08 > + > +/* PV88080_REG_EVENT_B (addr=0x05) */ > +#define PV88080_E_HVBUCK_OV 0x01 > +#define PV88080_E_HVBUCK_UV 0x02 > +#define PV88080_E_HVBUCK_SCP 0x04 > +#define PV88080_E_BUCK1_SCP 0x08 > +#define PV88080_E_BUCK2_SCP 0x10 > +#define PV88080_E_BUCK3_SCP 0x20 > + > +/* PV88080_REG_MASK_B (addr=0x0A) */ > +#define PV88080_M_HVBUCK_OV 0x01 > +#define PV88080_M_HVBUCK_UV 0x02 > +#define PV88080_M_HVBUCK_SCP 0x04 > +#define PV88080_M_BUCK1_SCP 0x08 > +#define PV88080_M_BUCK2_SCP 0x10 > +#define PV88080_M_BUCK3_SCP 0x20 > + > +/* PV88080_REG_EVENT_C (addr=0x06) */ > +#define PV88080_E_GPIO_FLAG0 0x01 > +#define PV88080_E_GPIO_FLAG1 0x02 > +#define PV88080_E_BUCK1_DROP_TIMEOUT 0x08 > +#define PV88080_E_BUCK2_DROP_TIMEOUT 0x10 > +#define PV88080_E_BUCk3_DROP_TIMEOUT 0x20 > + > +/* PV88080_REG_MASK_C (addr=0x0B) */ > +#define PV88080_M_GPIO_FLAG0 0x01 > +#define PV88080_M_GPIO_FLAG1 0x02 > +#define PV88080_M_BUCK1_DROP_TIMEOUT 0x08 > +#define PV88080_M_BUCK2_DROP_TIMEOUT 0x10 > +#define PV88080_M_BUCk3_DROP_TIMEOUT 0x20 > + > +/* PV88080xx_REG_GPIO_GPIO0 (addr=0x1A|0x19) */ > +#define PV88080_GPIO_DIRECTION_MASK 0x01 > +#define PV88080_GPIO_SINGLE_ENDED_MASK 0x02 > + > +/* PV88080_REG_BUCK1_CONF0 (addr=0x27|0x2A) */ > +#define PV88080_BUCK1_EN 0x80 > +#define PV88080_VBUCK1_MASK 0x7F > + > +/* PV88080_REG_BUCK2_CONF0 (addr=0x29|0x2D) */ > +#define PV88080_BUCK2_EN 0x80 > +#define PV88080_VBUCK2_MASK 0x7F > + > +/* PV88080_REG_BUCK3_CONF0 (addr=0x2B|0x30) */ > +#define PV88080_BUCK3_EN 0x80 > +#define PV88080_VBUCK3_MASK 0x7F > + > +/* PV88080_REG_BUCK1_CONF1 (addr=0x28|0x2C) */ > +#define PV88080_BUCK1_ILIM_SHIFT 2 > +#define PV88080_BUCK1_ILIM_MASK 0x0C > +#define PV88080_BUCK1_MODE_MASK 0x03 > + > +/* PV88080_REG_BUCK2_CONF1 (addr=0x2A|0x2F) */ > +#define PV88080_BUCK2_ILIM_SHIFT 2 > +#define PV88080_BUCK2_ILIM_MASK 0x0C > +#define PV88080_BUCK2_MODE_MASK 0x03 > + > +/* PV88080_REG_BUCK3_CONF1 (addr=0x2C|0x32) */ > +#define PV88080_BUCK3_ILIM_SHIFT 2 > +#define PV88080_BUCK3_ILIM_MASK 0x0C > +#define PV88080_BUCK3_MODE_MASK 0x03 > + > +#define PV88080_BUCK_MODE_SLEEP 0x00 > +#define PV88080_BUCK_MODE_AUTO 0x01 > +#define PV88080_BUCK_MODE_SYNC 0x02 > + > +/* PV88080_REG_HVBUCK_CONF1 (addr=0x2D|0x33) */ > +#define PV88080_VHVBUCK_MASK 0xFF > + > +/* PV88080_REG_HVBUCK_CONF1 (addr=0x2E|0x34) */ > +#define PV88080_HVBUCK_EN 0x01 > + > +/* PV88080_REG_BUCK2_CONF2 (addr=0x61|0x63) */ > +/* PV88080_REG_BUCK3_CONF2 (addr=0x69|0x6C) */ > +#define PV88080_BUCK_VDAC_RANGE_SHIFT 7 > +#define PV88080_BUCK_VDAC_RANGE_MASK 0x01 > + > +#define PV88080_BUCK_VDAC_RANGE_1 0x00 > +#define PV88080_BUCK_VDAC_RANGE_2 0x01 > + > +/* PV88080_REG_BUCK2_CONF5 (addr=0x64|0x66) */ > +/* PV88080_REG_BUCK3_CONF5 (addr=0x6C|0x6F) */ > +#define PV88080_BUCK_VRANGE_GAIN_SHIFT 0 > +#define PV88080_BUCK_VRANGE_GAIN_MASK 0x01 > + > +#define PV88080_BUCK_VRANGE_GAIN_1 0x00 > +#define PV88080_BUCK_VRANGE_GAIN_2 0x01 > + > +#define PV88080_MAX_REGULATORS 4 > + > +enum pv88080_types { > + TYPE_PV88080_AA, > + TYPE_PV88080_BA, > +}; > + > +/* Interrupts */ > +enum pv88080_aa_irqs { > + PV88080_AA_IRQ_VDD_FLT, > + PV88080_AA_IRQ_OVER_TEMP, > + PV88080_AA_IRQ_SEQ_RDY, > + PV88080_AA_IRQ_HVBUCK_OV, > + PV88080_AA_IRQ_HVBUCK_UV, > + PV88080_AA_IRQ_HVBUCK_SCP, > + PV88080_AA_IRQ_BUCK1_SCP, > + PV88080_AA_IRQ_BUCK2_SCP, > + PV88080_AA_IRQ_BUCK3_SCP, > + PV88080_AA_IRQ_GPIO_FLAG0, > + PV88080_AA_IRQ_GPIO_FLAG1, > +}; > + > +enum pv88080_ba_irqs { > + PV88080_BA_IRQ_VDD_FLT, > + PV88080_BA_IRQ_OVER_TEMP, > + PV88080_BA_IRQ_SEQ_RDY, > + PV88080_BA_IRQ_EXT_OT, > + PV88080_BA_IRQ_HVBUCK_OV, > + PV88080_BA_IRQ_HVBUCK_UV, > + PV88080_BA_IRQ_HVBUCK_SCP, > + PV88080_BA_IRQ_BUCK1_SCP, > + PV88080_BA_IRQ_BUCK2_SCP, > + PV88080_BA_IRQ_BUCK3_SCP, > + PV88080_BA_IRQ_GPIO_FLAG0, > + PV88080_BA_IRQ_GPIO_FLAG1, > + PV88080_BA_IRQ_BUCK1_DROP_TIMEOUT, > + PV88080_BA_IRQ_BUCK2_DROP_TIMEOUT, > + PB88080_BA_IRQ_BUCK3_DROP_TIMEOUT, > +}; > + > +struct pv88080 { > + struct device *dev; > + struct regmap *regmap; > + unsigned long type; Does this really need to be in here? > + /* IRQ Data */ > + int irq; > + struct regmap_irq_chip_data *irq_data; > +}; > + > +#endif /* __PV88080_H__ */ > + -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html