summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/bcm590xx-regulator.c1289
-rw-r--r--drivers/regulator/bd96801-regulator.c455
2 files changed, 1453 insertions, 291 deletions
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c
index 9f0cda46b015..50414f4cb109 100644
--- a/drivers/regulator/bcm590xx-regulator.c
+++ b/drivers/regulator/bcm590xx-regulator.c
@@ -18,112 +18,236 @@
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
-/* I2C slave 0 registers */
-#define BCM590XX_RFLDOPMCTRL1 0x60
-#define BCM590XX_IOSR1PMCTRL1 0x7a
-#define BCM590XX_IOSR2PMCTRL1 0x7c
-#define BCM590XX_CSRPMCTRL1 0x7e
-#define BCM590XX_SDSR1PMCTRL1 0x82
-#define BCM590XX_SDSR2PMCTRL1 0x86
-#define BCM590XX_MSRPMCTRL1 0x8a
-#define BCM590XX_VSRPMCTRL1 0x8e
-#define BCM590XX_RFLDOCTRL 0x96
-#define BCM590XX_CSRVOUT1 0xc0
-
-/* I2C slave 1 registers */
-#define BCM590XX_GPLDO5PMCTRL1 0x16
-#define BCM590XX_GPLDO6PMCTRL1 0x18
-#define BCM590XX_GPLDO1CTRL 0x1a
-#define BCM590XX_GPLDO2CTRL 0x1b
-#define BCM590XX_GPLDO3CTRL 0x1c
-#define BCM590XX_GPLDO4CTRL 0x1d
-#define BCM590XX_GPLDO5CTRL 0x1e
-#define BCM590XX_GPLDO6CTRL 0x1f
-#define BCM590XX_OTG_CTRL 0x40
-#define BCM590XX_GPLDO1PMCTRL1 0x57
-#define BCM590XX_GPLDO2PMCTRL1 0x59
-#define BCM590XX_GPLDO3PMCTRL1 0x5b
-#define BCM590XX_GPLDO4PMCTRL1 0x5d
-
#define BCM590XX_REG_ENABLE BIT(7)
#define BCM590XX_VBUS_ENABLE BIT(2)
#define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3)
#define BCM590XX_SR_VSEL_MASK GENMASK(5, 0)
+enum bcm590xx_reg_type {
+ BCM590XX_REG_TYPE_LDO,
+ BCM590XX_REG_TYPE_GPLDO,
+ BCM590XX_REG_TYPE_SR,
+ BCM590XX_REG_TYPE_VBUS
+};
+
+struct bcm590xx_reg_data {
+ enum bcm590xx_reg_type type;
+ enum bcm590xx_regmap_type regmap;
+ const struct regulator_desc desc;
+};
+
+struct bcm590xx_reg {
+ struct bcm590xx *mfd;
+ unsigned int n_regulators;
+ const struct bcm590xx_reg_data *regs;
+};
+
+static const struct regulator_ops bcm590xx_ops_ldo = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .list_voltage = regulator_list_voltage_table,
+ .map_voltage = regulator_map_voltage_iterate,
+};
+
+/*
+ * LDO ops without voltage selection, used for MICLDO on BCM59054.
+ * (These are currently the same as VBUS ops, but will be different
+ * in the future once full PMMODE support is implemented.)
+ */
+static const struct regulator_ops bcm590xx_ops_ldo_novolt = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+};
+
+static const struct regulator_ops bcm590xx_ops_dcdc = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+};
+
+static const struct regulator_ops bcm590xx_ops_vbus = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+};
+
+#define BCM590XX_REG_DESC(_model, _name, _name_lower) \
+ .id = _model##_REG_##_name, \
+ .name = #_name_lower, \
+ .of_match = of_match_ptr(#_name_lower), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE \
+
+#define BCM590XX_LDO_DESC(_model, _model_lower, _name, _name_lower, _table) \
+ BCM590XX_REG_DESC(_model, _name, _name_lower), \
+ .ops = &bcm590xx_ops_ldo, \
+ .n_voltages = ARRAY_SIZE(_model_lower##_##_table), \
+ .volt_table = _model_lower##_##_table, \
+ .vsel_reg = _model##_##_name##CTRL, \
+ .vsel_mask = BCM590XX_LDO_VSEL_MASK, \
+ .enable_reg = _model##_##_name##PMCTRL1, \
+ .enable_mask = BCM590XX_REG_ENABLE, \
+ .enable_is_inverted = true
+
+#define BCM590XX_SR_DESC(_model, _model_lower, _name, _name_lower, _ranges) \
+ BCM590XX_REG_DESC(_model, _name, _name_lower), \
+ .ops = &bcm590xx_ops_dcdc, \
+ .n_voltages = 64, \
+ .linear_ranges = _model_lower##_##_ranges, \
+ .n_linear_ranges = ARRAY_SIZE(_model_lower##_##_ranges), \
+ .vsel_reg = _model##_##_name##VOUT1, \
+ .vsel_mask = BCM590XX_SR_VSEL_MASK, \
+ .enable_reg = _model##_##_name##PMCTRL1, \
+ .enable_mask = BCM590XX_REG_ENABLE, \
+ .enable_is_inverted = true
+
+#define BCM59056_REG_DESC(_name, _name_lower) \
+ BCM590XX_REG_DESC(BCM59056, _name, _name_lower)
+#define BCM59056_LDO_DESC(_name, _name_lower, _table) \
+ BCM590XX_LDO_DESC(BCM59056, bcm59056, _name, _name_lower, _table)
+#define BCM59056_SR_DESC(_name, _name_lower, _ranges) \
+ BCM590XX_SR_DESC(BCM59056, bcm59056, _name, _name_lower, _ranges)
+
+#define BCM59054_REG_DESC(_name, _name_lower) \
+ BCM590XX_REG_DESC(BCM59054, _name, _name_lower)
+#define BCM59054_LDO_DESC(_name, _name_lower, _table) \
+ BCM590XX_LDO_DESC(BCM59054, bcm59054, _name, _name_lower, _table)
+#define BCM59054_SR_DESC(_name, _name_lower, _ranges) \
+ BCM590XX_SR_DESC(BCM59054, bcm59054, _name, _name_lower, _ranges)
+
+/* BCM59056 data */
+
+/* I2C slave 0 registers */
+#define BCM59056_RFLDOPMCTRL1 0x60
+#define BCM59056_CAMLDO1PMCTRL1 0x62
+#define BCM59056_CAMLDO2PMCTRL1 0x64
+#define BCM59056_SIMLDO1PMCTRL1 0x66
+#define BCM59056_SIMLDO2PMCTRL1 0x68
+#define BCM59056_SDLDOPMCTRL1 0x6a
+#define BCM59056_SDXLDOPMCTRL1 0x6c
+#define BCM59056_MMCLDO1PMCTRL1 0x6e
+#define BCM59056_MMCLDO2PMCTRL1 0x70
+#define BCM59056_AUDLDOPMCTRL1 0x72
+#define BCM59056_MICLDOPMCTRL1 0x74
+#define BCM59056_USBLDOPMCTRL1 0x76
+#define BCM59056_VIBLDOPMCTRL1 0x78
+#define BCM59056_IOSR1PMCTRL1 0x7a
+#define BCM59056_IOSR2PMCTRL1 0x7c
+#define BCM59056_CSRPMCTRL1 0x7e
+#define BCM59056_SDSR1PMCTRL1 0x82
+#define BCM59056_SDSR2PMCTRL1 0x86
+#define BCM59056_MSRPMCTRL1 0x8a
+#define BCM59056_VSRPMCTRL1 0x8e
+#define BCM59056_RFLDOCTRL 0x96
+#define BCM59056_CAMLDO1CTRL 0x97
+#define BCM59056_CAMLDO2CTRL 0x98
+#define BCM59056_SIMLDO1CTRL 0x99
+#define BCM59056_SIMLDO2CTRL 0x9a
+#define BCM59056_SDLDOCTRL 0x9b
+#define BCM59056_SDXLDOCTRL 0x9c
+#define BCM59056_MMCLDO1CTRL 0x9d
+#define BCM59056_MMCLDO2CTRL 0x9e
+#define BCM59056_AUDLDOCTRL 0x9f
+#define BCM59056_MICLDOCTRL 0xa0
+#define BCM59056_USBLDOCTRL 0xa1
+#define BCM59056_VIBLDOCTRL 0xa2
+#define BCM59056_CSRVOUT1 0xc0
+#define BCM59056_IOSR1VOUT1 0xc3
+#define BCM59056_IOSR2VOUT1 0xc6
+#define BCM59056_MSRVOUT1 0xc9
+#define BCM59056_SDSR1VOUT1 0xcc
+#define BCM59056_SDSR2VOUT1 0xcf
+#define BCM59056_VSRVOUT1 0xd2
+
+/* I2C slave 1 registers */
+#define BCM59056_GPLDO5PMCTRL1 0x16
+#define BCM59056_GPLDO6PMCTRL1 0x18
+#define BCM59056_GPLDO1CTRL 0x1a
+#define BCM59056_GPLDO2CTRL 0x1b
+#define BCM59056_GPLDO3CTRL 0x1c
+#define BCM59056_GPLDO4CTRL 0x1d
+#define BCM59056_GPLDO5CTRL 0x1e
+#define BCM59056_GPLDO6CTRL 0x1f
+#define BCM59056_OTG_CTRL 0x40
+#define BCM59056_GPLDO1PMCTRL1 0x57
+#define BCM59056_GPLDO2PMCTRL1 0x59
+#define BCM59056_GPLDO3PMCTRL1 0x5b
+#define BCM59056_GPLDO4PMCTRL1 0x5d
+
/*
* RFLDO to VSR regulators are
* accessed via I2C slave 0
*/
/* LDO regulator IDs */
-#define BCM590XX_REG_RFLDO 0
-#define BCM590XX_REG_CAMLDO1 1
-#define BCM590XX_REG_CAMLDO2 2
-#define BCM590XX_REG_SIMLDO1 3
-#define BCM590XX_REG_SIMLDO2 4
-#define BCM590XX_REG_SDLDO 5
-#define BCM590XX_REG_SDXLDO 6
-#define BCM590XX_REG_MMCLDO1 7
-#define BCM590XX_REG_MMCLDO2 8
-#define BCM590XX_REG_AUDLDO 9
-#define BCM590XX_REG_MICLDO 10
-#define BCM590XX_REG_USBLDO 11
-#define BCM590XX_REG_VIBLDO 12
+#define BCM59056_REG_RFLDO 0
+#define BCM59056_REG_CAMLDO1 1
+#define BCM59056_REG_CAMLDO2 2
+#define BCM59056_REG_SIMLDO1 3
+#define BCM59056_REG_SIMLDO2 4
+#define BCM59056_REG_SDLDO 5
+#define BCM59056_REG_SDXLDO 6
+#define BCM59056_REG_MMCLDO1 7
+#define BCM59056_REG_MMCLDO2 8
+#define BCM59056_REG_AUDLDO 9
+#define BCM59056_REG_MICLDO 10
+#define BCM59056_REG_USBLDO 11
+#define BCM59056_REG_VIBLDO 12
/* DCDC regulator IDs */
-#define BCM590XX_REG_CSR 13
-#define BCM590XX_REG_IOSR1 14
-#define BCM590XX_REG_IOSR2 15
-#define BCM590XX_REG_MSR 16
-#define BCM590XX_REG_SDSR1 17
-#define BCM590XX_REG_SDSR2 18
-#define BCM590XX_REG_VSR 19
+#define BCM59056_REG_CSR 13
+#define BCM59056_REG_IOSR1 14
+#define BCM59056_REG_IOSR2 15
+#define BCM59056_REG_MSR 16
+#define BCM59056_REG_SDSR1 17
+#define BCM59056_REG_SDSR2 18
+#define BCM59056_REG_VSR 19
/*
* GPLDO1 to VBUS regulators are
* accessed via I2C slave 1
*/
-#define BCM590XX_REG_GPLDO1 20
-#define BCM590XX_REG_GPLDO2 21
-#define BCM590XX_REG_GPLDO3 22
-#define BCM590XX_REG_GPLDO4 23
-#define BCM590XX_REG_GPLDO5 24
-#define BCM590XX_REG_GPLDO6 25
-#define BCM590XX_REG_VBUS 26
+#define BCM59056_REG_GPLDO1 20
+#define BCM59056_REG_GPLDO2 21
+#define BCM59056_REG_GPLDO3 22
+#define BCM59056_REG_GPLDO4 23
+#define BCM59056_REG_GPLDO5 24
+#define BCM59056_REG_GPLDO6 25
+#define BCM59056_REG_VBUS 26
-#define BCM590XX_NUM_REGS 27
-
-#define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR)
-#define BCM590XX_REG_IS_GPLDO(n) \
- ((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS))
-#define BCM590XX_REG_IS_VBUS(n) (n == BCM590XX_REG_VBUS)
+#define BCM59056_NUM_REGS 27
/* LDO group A: supported voltages in microvolts */
-static const unsigned int ldo_a_table[] = {
+static const unsigned int bcm59056_ldo_a_table[] = {
1200000, 1800000, 2500000, 2700000, 2800000,
2900000, 3000000, 3300000,
};
/* LDO group C: supported voltages in microvolts */
-static const unsigned int ldo_c_table[] = {
+static const unsigned int bcm59056_ldo_c_table[] = {
3100000, 1800000, 2500000, 2700000, 2800000,
2900000, 3000000, 3300000,
};
-static const unsigned int ldo_vbus[] = {
- 5000000,
-};
-
/* DCDC group CSR: supported voltages in microvolts */
-static const struct linear_range dcdc_csr_ranges[] = {
+static const struct linear_range bcm59056_dcdc_csr_ranges[] = {
REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000),
REGULATOR_LINEAR_RANGE(900000, 56, 63, 0),
};
/* DCDC group IOSR1: supported voltages in microvolts */
-static const struct linear_range dcdc_iosr1_ranges[] = {
+static const struct linear_range bcm59056_dcdc_iosr1_ranges[] = {
REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000),
REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0),
REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0),
@@ -131,155 +255,854 @@ static const struct linear_range dcdc_iosr1_ranges[] = {
};
/* DCDC group SDSR1: supported voltages in microvolts */
-static const struct linear_range dcdc_sdsr1_ranges[] = {
+static const struct linear_range bcm59056_dcdc_sdsr1_ranges[] = {
REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000),
REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0),
REGULATOR_LINEAR_RANGE(900000, 52, 63, 0),
};
-struct bcm590xx_info {
- const char *name;
- const char *vin_name;
- u8 n_voltages;
- const unsigned int *volt_table;
- u8 n_linear_ranges;
- const struct linear_range *linear_ranges;
-};
+static const struct bcm590xx_reg_data bcm59056_regs[BCM59056_NUM_REGS] = {
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(RFLDO, rfldo, ldo_a_table),
+ },
+ },
-#define BCM590XX_REG_TABLE(_name, _table) \
- { \
- .name = #_name, \
- .n_voltages = ARRAY_SIZE(_table), \
- .volt_table = _table, \
- }
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(CAMLDO1, camldo1, ldo_c_table),
+ },
+ },
-#define BCM590XX_REG_RANGES(_name, _ranges) \
- { \
- .name = #_name, \
- .n_voltages = 64, \
- .n_linear_ranges = ARRAY_SIZE(_ranges), \
- .linear_ranges = _ranges, \
- }
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(CAMLDO2, camldo2, ldo_c_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(SIMLDO1, simldo1, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(SIMLDO2, simldo2, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(SDLDO, sdldo, ldo_c_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(SDXLDO, sdxldo, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(MMCLDO1, mmcldo1, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(MMCLDO2, mmcldo2, ldo_a_table),
+ },
+ },
-static struct bcm590xx_info bcm590xx_regs[] = {
- BCM590XX_REG_TABLE(rfldo, ldo_a_table),
- BCM590XX_REG_TABLE(camldo1, ldo_c_table),
- BCM590XX_REG_TABLE(camldo2, ldo_c_table),
- BCM590XX_REG_TABLE(simldo1, ldo_a_table),
- BCM590XX_REG_TABLE(simldo2, ldo_a_table),
- BCM590XX_REG_TABLE(sdldo, ldo_c_table),
- BCM590XX_REG_TABLE(sdxldo, ldo_a_table),
- BCM590XX_REG_TABLE(mmcldo1, ldo_a_table),
- BCM590XX_REG_TABLE(mmcldo2, ldo_a_table),
- BCM590XX_REG_TABLE(audldo, ldo_a_table),
- BCM590XX_REG_TABLE(micldo, ldo_a_table),
- BCM590XX_REG_TABLE(usbldo, ldo_a_table),
- BCM590XX_REG_TABLE(vibldo, ldo_c_table),
- BCM590XX_REG_RANGES(csr, dcdc_csr_ranges),
- BCM590XX_REG_RANGES(iosr1, dcdc_iosr1_ranges),
- BCM590XX_REG_RANGES(iosr2, dcdc_iosr1_ranges),
- BCM590XX_REG_RANGES(msr, dcdc_iosr1_ranges),
- BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges),
- BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges),
- BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges),
- BCM590XX_REG_TABLE(gpldo1, ldo_a_table),
- BCM590XX_REG_TABLE(gpldo2, ldo_a_table),
- BCM590XX_REG_TABLE(gpldo3, ldo_a_table),
- BCM590XX_REG_TABLE(gpldo4, ldo_a_table),
- BCM590XX_REG_TABLE(gpldo5, ldo_a_table),
- BCM590XX_REG_TABLE(gpldo6, ldo_a_table),
- BCM590XX_REG_TABLE(vbus, ldo_vbus),
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(AUDLDO, audldo, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(MICLDO, micldo, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(USBLDO, usbldo, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_LDO_DESC(VIBLDO, vibldo, ldo_c_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_SR_DESC(CSR, csr, dcdc_csr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_SR_DESC(IOSR1, iosr1, dcdc_iosr1_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_SR_DESC(IOSR2, iosr2, dcdc_iosr1_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_SR_DESC(MSR, msr, dcdc_iosr1_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_SR_DESC(SDSR1, sdsr1, dcdc_sdsr1_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_SR_DESC(SDSR2, sdsr2, dcdc_iosr1_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59056_SR_DESC(VSR, vsr, dcdc_iosr1_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59056_LDO_DESC(GPLDO1, gpldo1, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59056_LDO_DESC(GPLDO2, gpldo2, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59056_LDO_DESC(GPLDO3, gpldo3, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59056_LDO_DESC(GPLDO4, gpldo4, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59056_LDO_DESC(GPLDO5, gpldo5, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59056_LDO_DESC(GPLDO6, gpldo6, ldo_a_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_VBUS,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59056_REG_DESC(VBUS, vbus),
+ .ops = &bcm590xx_ops_vbus,
+ .n_voltages = 1,
+ .fixed_uV = 5000000,
+ .enable_reg = BCM59056_OTG_CTRL,
+ .enable_mask = BCM590XX_VBUS_ENABLE,
+ },
+ },
};
-struct bcm590xx_reg {
- struct regulator_desc *desc;
- struct bcm590xx *mfd;
+/* BCM59054 data */
+
+/* I2C slave 0 registers */
+#define BCM59054_RFLDOPMCTRL1 0x60
+#define BCM59054_CAMLDO1PMCTRL1 0x62
+#define BCM59054_CAMLDO2PMCTRL1 0x64
+#define BCM59054_SIMLDO1PMCTRL1 0x66
+#define BCM59054_SIMLDO2PMCTRL1 0x68
+#define BCM59054_SDLDOPMCTRL1 0x6a
+#define BCM59054_SDXLDOPMCTRL1 0x6c
+#define BCM59054_MMCLDO1PMCTRL1 0x6e
+#define BCM59054_MMCLDO2PMCTRL1 0x70
+#define BCM59054_AUDLDOPMCTRL1 0x72
+#define BCM59054_MICLDOPMCTRL1 0x74
+#define BCM59054_USBLDOPMCTRL1 0x76
+#define BCM59054_VIBLDOPMCTRL1 0x78
+#define BCM59054_IOSR1PMCTRL1 0x7a
+#define BCM59054_IOSR2PMCTRL1 0x7c
+#define BCM59054_CSRPMCTRL1 0x7e
+#define BCM59054_SDSR1PMCTRL1 0x82
+#define BCM59054_SDSR2PMCTRL1 0x86
+#define BCM59054_MMSRPMCTRL1 0x8a
+#define BCM59054_VSRPMCTRL1 0x8e
+#define BCM59054_RFLDOCTRL 0x96
+#define BCM59054_CAMLDO1CTRL 0x97
+#define BCM59054_CAMLDO2CTRL 0x98
+#define BCM59054_SIMLDO1CTRL 0x99
+#define BCM59054_SIMLDO2CTRL 0x9a
+#define BCM59054_SDLDOCTRL 0x9b
+#define BCM59054_SDXLDOCTRL 0x9c
+#define BCM59054_MMCLDO1CTRL 0x9d
+#define BCM59054_MMCLDO2CTRL 0x9e
+#define BCM59054_AUDLDOCTRL 0x9f
+#define BCM59054_MICLDOCTRL 0xa0
+#define BCM59054_USBLDOCTRL 0xa1
+#define BCM59054_VIBLDOCTRL 0xa2
+#define BCM59054_CSRVOUT1 0xc0
+#define BCM59054_IOSR1VOUT1 0xc3
+#define BCM59054_IOSR2VOUT1 0xc6
+#define BCM59054_MMSRVOUT1 0xc9
+#define BCM59054_SDSR1VOUT1 0xcc
+#define BCM59054_SDSR2VOUT1 0xcf
+#define BCM59054_VSRVOUT1 0xd2
+
+/* I2C slave 1 registers */
+#define BCM59054_LVLDO1PMCTRL1 0x16
+#define BCM59054_LVLDO2PMCTRL1 0x18
+#define BCM59054_GPLDO1CTRL 0x1a
+#define BCM59054_GPLDO2CTRL 0x1b
+#define BCM59054_GPLDO3CTRL 0x1c
+#define BCM59054_TCXLDOCTRL 0x1d
+#define BCM59054_LVLDO1CTRL 0x1e
+#define BCM59054_LVLDO2CTRL 0x1f
+#define BCM59054_OTG_CTRL 0x40
+#define BCM59054_GPLDO1PMCTRL1 0x57
+#define BCM59054_GPLDO2PMCTRL1 0x59
+#define BCM59054_GPLDO3PMCTRL1 0x5b
+#define BCM59054_TCXLDOPMCTRL1 0x5d
+
+/*
+ * RFLDO to VSR regulators are
+ * accessed via I2C slave 0
+ */
+
+/* LDO regulator IDs */
+#define BCM59054_REG_RFLDO 0
+#define BCM59054_REG_CAMLDO1 1
+#define BCM59054_REG_CAMLDO2 2
+#define BCM59054_REG_SIMLDO1 3
+#define BCM59054_REG_SIMLDO2 4
+#define BCM59054_REG_SDLDO 5
+#define BCM59054_REG_SDXLDO 6
+#define BCM59054_REG_MMCLDO1 7
+#define BCM59054_REG_MMCLDO2 8
+#define BCM59054_REG_AUDLDO 9
+#define BCM59054_REG_MICLDO 10
+#define BCM59054_REG_USBLDO 11
+#define BCM59054_REG_VIBLDO 12
+
+/* DCDC regulator IDs */
+#define BCM59054_REG_CSR 13
+#define BCM59054_REG_IOSR1 14
+#define BCM59054_REG_IOSR2 15
+#define BCM59054_REG_MMSR 16
+#define BCM59054_REG_SDSR1 17
+#define BCM59054_REG_SDSR2 18
+#define BCM59054_REG_VSR 19
+
+/*
+ * GPLDO1 to VBUS regulators are
+ * accessed via I2C slave 1
+ */
+
+#define BCM59054_REG_GPLDO1 20
+#define BCM59054_REG_GPLDO2 21
+#define BCM59054_REG_GPLDO3 22
+#define BCM59054_REG_TCXLDO 23
+#define BCM59054_REG_LVLDO1 24
+#define BCM59054_REG_LVLDO2 25
+#define BCM59054_REG_VBUS 26
+
+#define BCM59054_NUM_REGS 27
+
+/* LDO group 1: supported voltages in microvolts */
+static const unsigned int bcm59054_ldo_1_table[] = {
+ 1200000, 1800000, 2500000, 2700000, 2800000,
+ 2900000, 3000000, 3300000,
};
-static int bcm590xx_get_vsel_register(int id)
-{
- if (BCM590XX_REG_IS_LDO(id))
- return BCM590XX_RFLDOCTRL + id;
- else if (BCM590XX_REG_IS_GPLDO(id))
- return BCM590XX_GPLDO1CTRL + id;
- else
- return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3;
-}
+/* LDO group 2: supported voltages in microvolts */
+static const unsigned int bcm59054_ldo_2_table[] = {
+ 3100000, 1800000, 2500000, 2700000, 2800000,
+ 2900000, 3000000, 3300000,
+};
-static int bcm590xx_get_enable_register(int id)
-{
- int reg = 0;
-
- if (BCM590XX_REG_IS_LDO(id))
- reg = BCM590XX_RFLDOPMCTRL1 + id * 2;
- else if (BCM590XX_REG_IS_GPLDO(id))
- reg = BCM590XX_GPLDO1PMCTRL1 + id * 2;
- else
- switch (id) {
- case BCM590XX_REG_CSR:
- reg = BCM590XX_CSRPMCTRL1;
- break;
- case BCM590XX_REG_IOSR1:
- reg = BCM590XX_IOSR1PMCTRL1;
- break;
- case BCM590XX_REG_IOSR2:
- reg = BCM590XX_IOSR2PMCTRL1;
- break;
- case BCM590XX_REG_MSR:
- reg = BCM590XX_MSRPMCTRL1;
- break;
- case BCM590XX_REG_SDSR1:
- reg = BCM590XX_SDSR1PMCTRL1;
- break;
- case BCM590XX_REG_SDSR2:
- reg = BCM590XX_SDSR2PMCTRL1;
- break;
- case BCM590XX_REG_VSR:
- reg = BCM590XX_VSRPMCTRL1;
- break;
- case BCM590XX_REG_VBUS:
- reg = BCM590XX_OTG_CTRL;
- break;
- }
+/* LDO group 3: supported voltages in microvolts */
+static const unsigned int bcm59054_ldo_3_table[] = {
+ 1000000, 1107000, 1143000, 1214000, 1250000,
+ 1464000, 1500000, 1786000,
+};
+/* DCDC group SR: supported voltages in microvolts */
+static const struct linear_range bcm59054_dcdc_sr_ranges[] = {
+ REGULATOR_LINEAR_RANGE(0, 0, 1, 0),
+ REGULATOR_LINEAR_RANGE(860000, 2, 60, 10000),
+ REGULATOR_LINEAR_RANGE(1500000, 61, 61, 0),
+ REGULATOR_LINEAR_RANGE(1800000, 62, 62, 0),
+ REGULATOR_LINEAR_RANGE(900000, 63, 63, 0),
+};
- return reg;
-}
+/* DCDC group VSR (BCM59054A1): supported voltages in microvolts */
+static const struct linear_range bcm59054_dcdc_vsr_a1_ranges[] = {
+ REGULATOR_LINEAR_RANGE(0, 0, 1, 0),
+ REGULATOR_LINEAR_RANGE(860000, 2, 59, 10000),
+ REGULATOR_LINEAR_RANGE(1700000, 60, 60, 0),
+ REGULATOR_LINEAR_RANGE(1500000, 61, 61, 0),
+ REGULATOR_LINEAR_RANGE(1800000, 62, 62, 0),
+ REGULATOR_LINEAR_RANGE(1600000, 63, 63, 0),
+};
-static const struct regulator_ops bcm590xx_ops_ldo = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .list_voltage = regulator_list_voltage_table,
- .map_voltage = regulator_map_voltage_iterate,
+/* DCDC group CSR: supported voltages in microvolts */
+static const struct linear_range bcm59054_dcdc_csr_ranges[] = {
+ REGULATOR_LINEAR_RANGE(700000, 0, 1, 100000),
+ REGULATOR_LINEAR_RANGE(860000, 2, 60, 10000),
+ REGULATOR_LINEAR_RANGE(900000, 61, 63, 0),
};
-static const struct regulator_ops bcm590xx_ops_dcdc = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .list_voltage = regulator_list_voltage_linear_range,
- .map_voltage = regulator_map_voltage_linear_range,
+static const struct bcm590xx_reg_data bcm59054_regs[BCM59054_NUM_REGS] = {
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(RFLDO, rfldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(CAMLDO1, camldo1, ldo_2_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(CAMLDO2, camldo2, ldo_2_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(SIMLDO1, simldo1, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(SIMLDO2, simldo2, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(SDLDO, sdldo, ldo_2_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(SDXLDO, sdxldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(MMCLDO1, mmcldo1, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(MMCLDO2, mmcldo2, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(AUDLDO, audldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_REG_DESC(MICLDO, micldo),
+ .ops = &bcm590xx_ops_ldo_novolt,
+ /* MICLDO is locked at 1.8V */
+ .n_voltages = 1,
+ .fixed_uV = 1800000,
+ .enable_reg = BCM59054_MICLDOPMCTRL1,
+ .enable_mask = BCM590XX_REG_ENABLE,
+ .enable_is_inverted = true,
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(USBLDO, usbldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(VIBLDO, vibldo, ldo_2_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(CSR, csr, dcdc_csr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(IOSR1, iosr1, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(IOSR2, iosr2, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(MMSR, mmsr, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(SDSR1, sdsr1, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(SDSR2, sdsr2, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(VSR, vsr, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(GPLDO1, gpldo1, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(GPLDO2, gpldo2, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(GPLDO3, gpldo3, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(TCXLDO, tcxldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(LVLDO1, lvldo1, ldo_3_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(LVLDO2, lvldo2, ldo_3_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_VBUS,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_REG_DESC(VBUS, vbus),
+ .ops = &bcm590xx_ops_vbus,
+ .n_voltages = 1,
+ .fixed_uV = 5000000,
+ .enable_reg = BCM59054_OTG_CTRL,
+ .enable_mask = BCM590XX_VBUS_ENABLE,
+ },
+ },
};
-static const struct regulator_ops bcm590xx_ops_vbus = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
+/*
+ * BCM59054A1 regulators; same as previous revision, but with different
+ * VSR voltage table.
+ */
+static const struct bcm590xx_reg_data bcm59054_a1_regs[BCM59054_NUM_REGS] = {
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(RFLDO, rfldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(CAMLDO1, camldo1, ldo_2_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(CAMLDO2, camldo2, ldo_2_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(SIMLDO1, simldo1, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(SIMLDO2, simldo2, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(SDLDO, sdldo, ldo_2_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(SDXLDO, sdxldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(MMCLDO1, mmcldo1, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(MMCLDO2, mmcldo2, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(AUDLDO, audldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_REG_DESC(MICLDO, micldo),
+ .ops = &bcm590xx_ops_ldo_novolt,
+ /* MICLDO is locked at 1.8V */
+ .n_voltages = 1,
+ .fixed_uV = 1800000,
+ .enable_reg = BCM59054_MICLDOPMCTRL1,
+ .enable_mask = BCM590XX_REG_ENABLE,
+ .enable_is_inverted = true,
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(USBLDO, usbldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_LDO,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_LDO_DESC(VIBLDO, vibldo, ldo_2_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(CSR, csr, dcdc_csr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(IOSR1, iosr1, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(IOSR2, iosr2, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(MMSR, mmsr, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(SDSR1, sdsr1, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(SDSR2, sdsr2, dcdc_sr_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_SR,
+ .regmap = BCM590XX_REGMAP_PRI,
+ .desc = {
+ BCM59054_SR_DESC(VSR, vsr, dcdc_vsr_a1_ranges),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(GPLDO1, gpldo1, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(GPLDO2, gpldo2, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(GPLDO3, gpldo3, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(TCXLDO, tcxldo, ldo_1_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(LVLDO1, lvldo1, ldo_3_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_GPLDO,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_LDO_DESC(LVLDO2, lvldo2, ldo_3_table),
+ },
+ },
+
+ {
+ .type = BCM590XX_REG_TYPE_VBUS,
+ .regmap = BCM590XX_REGMAP_SEC,
+ .desc = {
+ BCM59054_REG_DESC(VBUS, vbus),
+ .ops = &bcm590xx_ops_vbus,
+ .n_voltages = 1,
+ .fixed_uV = 5000000,
+ .enable_reg = BCM59054_OTG_CTRL,
+ .enable_mask = BCM590XX_VBUS_ENABLE,
+ },
+ },
};
static int bcm590xx_probe(struct platform_device *pdev)
{
struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent);
struct bcm590xx_reg *pmu;
+ const struct bcm590xx_reg_data *info;
struct regulator_config config = { };
- struct bcm590xx_info *info;
struct regulator_dev *rdev;
- int i;
+ unsigned int i;
pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL);
if (!pmu)
@@ -287,65 +1110,53 @@ static int bcm590xx_probe(struct platform_device *pdev)
pmu->mfd = bcm590xx;
- platform_set_drvdata(pdev, pmu);
-
- pmu->desc = devm_kcalloc(&pdev->dev,
- BCM590XX_NUM_REGS,
- sizeof(struct regulator_desc),
- GFP_KERNEL);
- if (!pmu->desc)
- return -ENOMEM;
+ switch (pmu->mfd->pmu_id) {
+ case BCM590XX_PMUID_BCM59054:
+ pmu->n_regulators = BCM59054_NUM_REGS;
+ if (pmu->mfd->rev_analog == BCM59054_REV_ANALOG_A1)
+ pmu->regs = bcm59054_a1_regs;
+ else
+ pmu->regs = bcm59054_regs;
+ break;
+ case BCM590XX_PMUID_BCM59056:
+ pmu->n_regulators = BCM59056_NUM_REGS;
+ pmu->regs = bcm59056_regs;
+ break;
+ default:
+ dev_err(bcm590xx->dev,
+ "unknown device type, could not initialize\n");
+ return -EINVAL;
+ }
- info = bcm590xx_regs;
-
- for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) {
- /* Register the regulators */
- pmu->desc[i].name = info->name;
- pmu->desc[i].of_match = of_match_ptr(info->name);
- pmu->desc[i].regulators_node = of_match_ptr("regulators");
- pmu->desc[i].supply_name = info->vin_name;
- pmu->desc[i].id = i;
- pmu->desc[i].volt_table = info->volt_table;
- pmu->desc[i].n_voltages = info->n_voltages;
- pmu->desc[i].linear_ranges = info->linear_ranges;
- pmu->desc[i].n_linear_ranges = info->n_linear_ranges;
-
- if ((BCM590XX_REG_IS_LDO(i)) || (BCM590XX_REG_IS_GPLDO(i))) {
- pmu->desc[i].ops = &bcm590xx_ops_ldo;
- pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK;
- } else if (BCM590XX_REG_IS_VBUS(i))
- pmu->desc[i].ops = &bcm590xx_ops_vbus;
- else {
- pmu->desc[i].ops = &bcm590xx_ops_dcdc;
- pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK;
- }
+ platform_set_drvdata(pdev, pmu);
- if (BCM590XX_REG_IS_VBUS(i))
- pmu->desc[i].enable_mask = BCM590XX_VBUS_ENABLE;
- else {
- pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i);
- pmu->desc[i].enable_is_inverted = true;
- pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE;
- }
- pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i);
- pmu->desc[i].type = REGULATOR_VOLTAGE;
- pmu->desc[i].owner = THIS_MODULE;
+ /* Register the regulators */
+ for (i = 0; i < pmu->n_regulators; i++) {
+ info = &pmu->regs[i];
config.dev = bcm590xx->dev;
config.driver_data = pmu;
- if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i))
- config.regmap = bcm590xx->regmap_sec;
- else
- config.regmap = bcm590xx->regmap_pri;
- rdev = devm_regulator_register(&pdev->dev, &pmu->desc[i],
- &config);
- if (IS_ERR(rdev)) {
+ switch (info->regmap) {
+ case BCM590XX_REGMAP_PRI:
+ config.regmap = bcm590xx->regmap_pri;
+ break;
+ case BCM590XX_REGMAP_SEC:
+ config.regmap = bcm590xx->regmap_sec;
+ break;
+ default:
dev_err(bcm590xx->dev,
- "failed to register %s regulator\n",
+ "invalid regmap for %s regulator; this is a driver bug\n",
pdev->name);
- return PTR_ERR(rdev);
+ return -EINVAL;
}
+
+ rdev = devm_regulator_register(&pdev->dev, &info->desc,
+ &config);
+ if (IS_ERR(rdev))
+ return dev_err_probe(bcm590xx->dev, PTR_ERR(rdev),
+ "failed to register %s regulator\n",
+ pdev->name);
}
return 0;
diff --git a/drivers/regulator/bd96801-regulator.c b/drivers/regulator/bd96801-regulator.c
index 3a9d772491a8..24d21172298b 100644
--- a/drivers/regulator/bd96801-regulator.c
+++ b/drivers/regulator/bd96801-regulator.c
@@ -83,6 +83,7 @@ enum {
#define BD96801_LDO6_VSEL_REG 0x26
#define BD96801_LDO7_VSEL_REG 0x27
#define BD96801_BUCK_VSEL_MASK 0x1F
+#define BD96805_BUCK_VSEL_MASK 0x3f
#define BD96801_LDO_VSEL_MASK 0xff
#define BD96801_MASK_RAMP_DELAY 0xc0
@@ -90,6 +91,7 @@ enum {
#define BD96801_BUCK_INT_VOUT_MASK 0xff
#define BD96801_BUCK_VOLTS 256
+#define BD96805_BUCK_VOLTS 64
#define BD96801_LDO_VOLTS 256
#define BD96801_OVP_MASK 0x03
@@ -160,6 +162,30 @@ static const struct linear_range bd96801_buck_init_volts[] = {
REGULATOR_LINEAR_RANGE(3300000 - 150000, 0xed, 0xff, 0),
};
+/* BD96802 uses same voltage ranges for bucks as BD96801 */
+#define bd96802_tune_volts bd96801_tune_volts
+#define bd96802_buck_init_volts bd96801_buck_init_volts
+
+/*
+ * On BD96805 we have similar "negative tuning range" as on BD96801, except
+ * that the max tuning is -310 ... +310 mV (instead of the 150mV). We use same
+ * approach as with the BD96801 ranges.
+ */
+static const struct linear_range bd96805_tune_volts[] = {
+ REGULATOR_LINEAR_RANGE(310000, 0x00, 0x1F, 10000),
+ REGULATOR_LINEAR_RANGE(0, 0x20, 0x3F, 10000),
+};
+
+static const struct linear_range bd96805_buck_init_volts[] = {
+ REGULATOR_LINEAR_RANGE(500000 - 310000, 0x00, 0xc8, 5000),
+ REGULATOR_LINEAR_RANGE(1550000 - 310000, 0xc9, 0xec, 50000),
+ REGULATOR_LINEAR_RANGE(3300000 - 310000, 0xed, 0xff, 0),
+};
+
+/* BD96806 uses same voltage ranges for bucks as BD96805 */
+#define bd96806_tune_volts bd96805_tune_volts
+#define bd96806_buck_init_volts bd96805_buck_init_volts
+
static const struct linear_range bd96801_ldo_int_volts[] = {
REGULATOR_LINEAR_RANGE(300000, 0x00, 0x78, 25000),
REGULATOR_LINEAR_RANGE(3300000, 0x79, 0xff, 0),
@@ -198,89 +224,89 @@ struct bd96801_irqinfo {
static const struct bd96801_irqinfo buck1_irqinfo[] = {
BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-h", 500,
- "bd96801-buck1-overcurr-h"),
+ "buck1-overcurr-h"),
BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-l", 500,
- "bd96801-buck1-overcurr-l"),
+ "buck1-overcurr-l"),
BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-n", 500,
- "bd96801-buck1-overcurr-n"),
+ "buck1-overcurr-n"),
BD96801_IRQINFO(BD96801_PROT_OVP, "buck1-over-voltage", 500,
- "bd96801-buck1-overvolt"),
+ "buck1-overvolt"),
BD96801_IRQINFO(BD96801_PROT_UVP, "buck1-under-voltage", 500,
- "bd96801-buck1-undervolt"),
+ "buck1-undervolt"),
BD96801_IRQINFO(BD96801_PROT_TEMP, "buck1-over-temp", 500,
- "bd96801-buck1-thermal")
+ "buck1-thermal")
};
static const struct bd96801_irqinfo buck2_irqinfo[] = {
BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-h", 500,
- "bd96801-buck2-overcurr-h"),
+ "buck2-overcurr-h"),
BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-l", 500,
- "bd96801-buck2-overcurr-l"),
+ "buck2-overcurr-l"),
BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-n", 500,
- "bd96801-buck2-overcurr-n"),
+ "buck2-overcurr-n"),
BD96801_IRQINFO(BD96801_PROT_OVP, "buck2-over-voltage", 500,
- "bd96801-buck2-overvolt"),
+ "buck2-overvolt"),
BD96801_IRQINFO(BD96801_PROT_UVP, "buck2-under-voltage", 500,
- "bd96801-buck2-undervolt"),
+ "buck2-undervolt"),
BD96801_IRQINFO(BD96801_PROT_TEMP, "buck2-over-temp", 500,
- "bd96801-buck2-thermal")
+ "buck2-thermal")
};
static const struct bd96801_irqinfo buck3_irqinfo[] = {
BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-h", 500,
- "bd96801-buck3-overcurr-h"),
+ "buck3-overcurr-h"),
BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-l", 500,
- "bd96801-buck3-overcurr-l"),
+ "buck3-overcurr-l"),
BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-n", 500,
- "bd96801-buck3-overcurr-n"),
+ "buck3-overcurr-n"),
BD96801_IRQINFO(BD96801_PROT_OVP, "buck3-over-voltage", 500,
- "bd96801-buck3-overvolt"),
+ "buck3-overvolt"),
BD96801_IRQINFO(BD96801_PROT_UVP, "buck3-under-voltage", 500,
- "bd96801-buck3-undervolt"),
+ "buck3-undervolt"),
BD96801_IRQINFO(BD96801_PROT_TEMP, "buck3-over-temp", 500,
- "bd96801-buck3-thermal")
+ "buck3-thermal")
};
static const struct bd96801_irqinfo buck4_irqinfo[] = {
BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-h", 500,
- "bd96801-buck4-overcurr-h"),
+ "buck4-overcurr-h"),
BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-l", 500,
- "bd96801-buck4-overcurr-l"),
+ "buck4-overcurr-l"),
BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-n", 500,
- "bd96801-buck4-overcurr-n"),
+ "buck4-overcurr-n"),
BD96801_IRQINFO(BD96801_PROT_OVP, "buck4-over-voltage", 500,
- "bd96801-buck4-overvolt"),
+ "buck4-overvolt"),
BD96801_IRQINFO(BD96801_PROT_UVP, "buck4-under-voltage", 500,
- "bd96801-buck4-undervolt"),
+ "buck4-undervolt"),
BD96801_IRQINFO(BD96801_PROT_TEMP, "buck4-over-temp", 500,
- "bd96801-buck4-thermal")
+ "buck4-thermal")
};
static const struct bd96801_irqinfo ldo5_irqinfo[] = {
BD96801_IRQINFO(BD96801_PROT_OCP, "ldo5-overcurr", 500,
- "bd96801-ldo5-overcurr"),
+ "ldo5-overcurr"),
BD96801_IRQINFO(BD96801_PROT_OVP, "ldo5-over-voltage", 500,
- "bd96801-ldo5-overvolt"),
+ "ldo5-overvolt"),
BD96801_IRQINFO(BD96801_PROT_UVP, "ldo5-under-voltage", 500,
- "bd96801-ldo5-undervolt"),
+ "ldo5-undervolt"),
};
static const struct bd96801_irqinfo ldo6_irqinfo[] = {
BD96801_IRQINFO(BD96801_PROT_OCP, "ldo6-overcurr", 500,
- "bd96801-ldo6-overcurr"),
+ "ldo6-overcurr"),
BD96801_IRQINFO(BD96801_PROT_OVP, "ldo6-over-voltage", 500,
- "bd96801-ldo6-overvolt"),
+ "ldo6-overvolt"),
BD96801_IRQINFO(BD96801_PROT_UVP, "ldo6-under-voltage", 500,
- "bd96801-ldo6-undervolt"),
+ "ldo6-undervolt"),
};
static const struct bd96801_irqinfo ldo7_irqinfo[] = {
BD96801_IRQINFO(BD96801_PROT_OCP, "ldo7-overcurr", 500,
- "bd96801-ldo7-overcurr"),
+ "ldo7-overcurr"),
BD96801_IRQINFO(BD96801_PROT_OVP, "ldo7-over-voltage", 500,
- "bd96801-ldo7-overvolt"),
+ "ldo7-overvolt"),
BD96801_IRQINFO(BD96801_PROT_UVP, "ldo7-under-voltage", 500,
- "bd96801-ldo7-undervolt"),
+ "ldo7-undervolt"),
};
struct bd96801_irq_desc {
@@ -302,6 +328,7 @@ struct bd96801_pmic_data {
struct bd96801_regulator_data regulator_data[BD96801_NUM_REGULATORS];
struct regmap *regmap;
int fatal_ind;
+ int num_regulators;
};
static int ldo_map_notif(int irq, struct regulator_irq_data *rid,
@@ -503,6 +530,70 @@ static int bd96801_walk_regulator_dt(struct device *dev, struct regmap *regmap,
* case later. What we can easly do for preparing is to not use static global
* data for regulators though.
*/
+static const struct bd96801_pmic_data bd96802_data = {
+ .regulator_data = {
+ {
+ .desc = {
+ .name = "buck1",
+ .of_match = of_match_ptr("buck1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_BUCK1,
+ .ops = &bd96801_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96802_tune_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96802_tune_volts),
+ .n_voltages = BD96801_BUCK_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_BUCK1_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_BUCK1_VSEL_REG,
+ .vsel_mask = BD96801_BUCK_VSEL_MASK,
+ .ramp_reg = BD96801_BUCK1_VSEL_REG,
+ .ramp_mask = BD96801_MASK_RAMP_DELAY,
+ .ramp_delay_table = &buck_ramp_table[0],
+ .n_ramp_values = ARRAY_SIZE(buck_ramp_table),
+ .owner = THIS_MODULE,
+ },
+ .init_ranges = bd96802_buck_init_volts,
+ .num_ranges = ARRAY_SIZE(bd96802_buck_init_volts),
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(buck1_irqinfo),
+ },
+ },
+ {
+ .desc = {
+ .name = "buck2",
+ .of_match = of_match_ptr("buck2"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_BUCK2,
+ .ops = &bd96801_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96802_tune_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96802_tune_volts),
+ .n_voltages = BD96801_BUCK_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_BUCK2_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_BUCK2_VSEL_REG,
+ .vsel_mask = BD96801_BUCK_VSEL_MASK,
+ .ramp_reg = BD96801_BUCK2_VSEL_REG,
+ .ramp_mask = BD96801_MASK_RAMP_DELAY,
+ .ramp_delay_table = &buck_ramp_table[0],
+ .n_ramp_values = ARRAY_SIZE(buck_ramp_table),
+ .owner = THIS_MODULE,
+ },
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(buck2_irqinfo),
+ },
+ .init_ranges = bd96802_buck_init_volts,
+ .num_ranges = ARRAY_SIZE(bd96802_buck_init_volts),
+ },
+ },
+ .num_regulators = 2,
+};
+
static const struct bd96801_pmic_data bd96801_data = {
.regulator_data = {
{
@@ -688,11 +779,265 @@ static const struct bd96801_pmic_data bd96801_data = {
.ldo_vol_lvl = BD96801_LDO7_VOL_LVL_REG,
},
},
+ .num_regulators = 7,
};
-static int initialize_pmic_data(struct device *dev,
+static const struct bd96801_pmic_data bd96805_data = {
+ .regulator_data = {
+ {
+ .desc = {
+ .name = "buck1",
+ .of_match = of_match_ptr("buck1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_BUCK1,
+ .ops = &bd96801_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96805_tune_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts),
+ .n_voltages = BD96805_BUCK_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_BUCK1_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_BUCK1_VSEL_REG,
+ .vsel_mask = BD96805_BUCK_VSEL_MASK,
+ .ramp_reg = BD96801_BUCK1_VSEL_REG,
+ .ramp_mask = BD96801_MASK_RAMP_DELAY,
+ .ramp_delay_table = &buck_ramp_table[0],
+ .n_ramp_values = ARRAY_SIZE(buck_ramp_table),
+ .owner = THIS_MODULE,
+ },
+ .init_ranges = bd96805_buck_init_volts,
+ .num_ranges = ARRAY_SIZE(bd96805_buck_init_volts),
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(buck1_irqinfo),
+ },
+ }, {
+ .desc = {
+ .name = "buck2",
+ .of_match = of_match_ptr("buck2"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_BUCK2,
+ .ops = &bd96801_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96805_tune_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts),
+ .n_voltages = BD96805_BUCK_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_BUCK2_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_BUCK2_VSEL_REG,
+ .vsel_mask = BD96805_BUCK_VSEL_MASK,
+ .ramp_reg = BD96801_BUCK2_VSEL_REG,
+ .ramp_mask = BD96801_MASK_RAMP_DELAY,
+ .ramp_delay_table = &buck_ramp_table[0],
+ .n_ramp_values = ARRAY_SIZE(buck_ramp_table),
+ .owner = THIS_MODULE,
+ },
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(buck2_irqinfo),
+ },
+ .init_ranges = bd96805_buck_init_volts,
+ .num_ranges = ARRAY_SIZE(bd96805_buck_init_volts),
+ }, {
+ .desc = {
+ .name = "buck3",
+ .of_match = of_match_ptr("buck3"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_BUCK3,
+ .ops = &bd96801_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96805_tune_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts),
+ .n_voltages = BD96805_BUCK_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_BUCK3_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_BUCK3_VSEL_REG,
+ .vsel_mask = BD96805_BUCK_VSEL_MASK,
+ .ramp_reg = BD96801_BUCK3_VSEL_REG,
+ .ramp_mask = BD96801_MASK_RAMP_DELAY,
+ .ramp_delay_table = &buck_ramp_table[0],
+ .n_ramp_values = ARRAY_SIZE(buck_ramp_table),
+ .owner = THIS_MODULE,
+ },
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&buck3_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(buck3_irqinfo),
+ },
+ .init_ranges = bd96805_buck_init_volts,
+ .num_ranges = ARRAY_SIZE(bd96805_buck_init_volts),
+ }, {
+ .desc = {
+ .name = "buck4",
+ .of_match = of_match_ptr("buck4"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_BUCK4,
+ .ops = &bd96801_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96805_tune_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts),
+ .n_voltages = BD96805_BUCK_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_BUCK4_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_BUCK4_VSEL_REG,
+ .vsel_mask = BD96805_BUCK_VSEL_MASK,
+ .ramp_reg = BD96801_BUCK4_VSEL_REG,
+ .ramp_mask = BD96801_MASK_RAMP_DELAY,
+ .ramp_delay_table = &buck_ramp_table[0],
+ .n_ramp_values = ARRAY_SIZE(buck_ramp_table),
+ .owner = THIS_MODULE,
+ },
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&buck4_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(buck4_irqinfo),
+ },
+ .init_ranges = bd96805_buck_init_volts,
+ .num_ranges = ARRAY_SIZE(bd96805_buck_init_volts),
+ }, {
+ .desc = {
+ .name = "ldo5",
+ .of_match = of_match_ptr("ldo5"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_LDO5,
+ .ops = &bd96801_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96801_ldo_int_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96801_ldo_int_volts),
+ .n_voltages = BD96801_LDO_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_LDO5_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_LDO5_VSEL_REG,
+ .vsel_mask = BD96801_LDO_VSEL_MASK,
+ .owner = THIS_MODULE,
+ },
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&ldo5_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(ldo5_irqinfo),
+ },
+ .ldo_vol_lvl = BD96801_LDO5_VOL_LVL_REG,
+ }, {
+ .desc = {
+ .name = "ldo6",
+ .of_match = of_match_ptr("ldo6"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_LDO6,
+ .ops = &bd96801_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96801_ldo_int_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96801_ldo_int_volts),
+ .n_voltages = BD96801_LDO_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_LDO6_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_LDO6_VSEL_REG,
+ .vsel_mask = BD96801_LDO_VSEL_MASK,
+ .owner = THIS_MODULE,
+ },
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&ldo6_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(ldo6_irqinfo),
+ },
+ .ldo_vol_lvl = BD96801_LDO6_VOL_LVL_REG,
+ }, {
+ .desc = {
+ .name = "ldo7",
+ .of_match = of_match_ptr("ldo7"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_LDO7,
+ .ops = &bd96801_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96801_ldo_int_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96801_ldo_int_volts),
+ .n_voltages = BD96801_LDO_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_LDO7_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_LDO7_VSEL_REG,
+ .vsel_mask = BD96801_LDO_VSEL_MASK,
+ .owner = THIS_MODULE,
+ },
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&ldo7_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(ldo7_irqinfo),
+ },
+ .ldo_vol_lvl = BD96801_LDO7_VOL_LVL_REG,
+ },
+ },
+ .num_regulators = 7,
+};
+
+static const struct bd96801_pmic_data bd96806_data = {
+ .regulator_data = {
+ {
+ .desc = {
+ .name = "buck1",
+ .of_match = of_match_ptr("buck1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_BUCK1,
+ .ops = &bd96801_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96806_tune_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96806_tune_volts),
+ .n_voltages = BD96805_BUCK_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_BUCK1_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_BUCK1_VSEL_REG,
+ .vsel_mask = BD96805_BUCK_VSEL_MASK,
+ .ramp_reg = BD96801_BUCK1_VSEL_REG,
+ .ramp_mask = BD96801_MASK_RAMP_DELAY,
+ .ramp_delay_table = &buck_ramp_table[0],
+ .n_ramp_values = ARRAY_SIZE(buck_ramp_table),
+ .owner = THIS_MODULE,
+ },
+ .init_ranges = bd96806_buck_init_volts,
+ .num_ranges = ARRAY_SIZE(bd96806_buck_init_volts),
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(buck1_irqinfo),
+ },
+ },
+ {
+ .desc = {
+ .name = "buck2",
+ .of_match = of_match_ptr("buck2"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD96801_BUCK2,
+ .ops = &bd96801_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd96806_tune_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd96806_tune_volts),
+ .n_voltages = BD96805_BUCK_VOLTS,
+ .enable_reg = BD96801_REG_ENABLE,
+ .enable_mask = BD96801_BUCK2_EN_MASK,
+ .enable_is_inverted = true,
+ .vsel_reg = BD96801_BUCK2_VSEL_REG,
+ .vsel_mask = BD96805_BUCK_VSEL_MASK,
+ .ramp_reg = BD96801_BUCK2_VSEL_REG,
+ .ramp_mask = BD96801_MASK_RAMP_DELAY,
+ .ramp_delay_table = &buck_ramp_table[0],
+ .n_ramp_values = ARRAY_SIZE(buck_ramp_table),
+ .owner = THIS_MODULE,
+ },
+ .irq_desc = {
+ .irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0],
+ .num_irqs = ARRAY_SIZE(buck2_irqinfo),
+ },
+ .init_ranges = bd96806_buck_init_volts,
+ .num_ranges = ARRAY_SIZE(bd96806_buck_init_volts),
+ },
+ },
+ .num_regulators = 2,
+};
+
+static int initialize_pmic_data(struct platform_device *pdev,
struct bd96801_pmic_data *pdata)
{
+ struct device *dev = &pdev->dev;
int r, i;
/*
@@ -700,7 +1045,7 @@ static int initialize_pmic_data(struct device *dev,
* wish to modify IRQ information independently for each driver
* instance.
*/
- for (r = 0; r < BD96801_NUM_REGULATORS; r++) {
+ for (r = 0; r < pdata->num_regulators; r++) {
const struct bd96801_irqinfo *template;
struct bd96801_irqinfo *new;
int num_infos;
@@ -741,8 +1086,7 @@ static int bd96801_rdev_errb_irqs(struct platform_device *pdev,
int i;
void *retp;
static const char * const single_out_errb_irqs[] = {
- "bd96801-%s-pvin-err", "bd96801-%s-ovp-err",
- "bd96801-%s-uvp-err", "bd96801-%s-shdn-err",
+ "%s-pvin-err", "%s-ovp-err", "%s-uvp-err", "%s-shdn-err",
};
for (i = 0; i < ARRAY_SIZE(single_out_errb_irqs); i++) {
@@ -779,12 +1123,10 @@ static int bd96801_global_errb_irqs(struct platform_device *pdev,
int i, num_irqs;
void *retp;
static const char * const global_errb_irqs[] = {
- "bd96801-otp-err", "bd96801-dbist-err", "bd96801-eep-err",
- "bd96801-abist-err", "bd96801-prstb-err", "bd96801-drmoserr1",
- "bd96801-drmoserr2", "bd96801-slave-err", "bd96801-vref-err",
- "bd96801-tsd", "bd96801-uvlo-err", "bd96801-ovlo-err",
- "bd96801-osc-err", "bd96801-pon-err", "bd96801-poff-err",
- "bd96801-cmd-shdn-err", "bd96801-int-shdn-err"
+ "otp-err", "dbist-err", "eep-err", "abist-err", "prstb-err",
+ "drmoserr1", "drmoserr2", "slave-err", "vref-err", "tsd",
+ "uvlo-err", "ovlo-err", "osc-err", "pon-err", "poff-err",
+ "cmd-shdn-err", "int-shdn-err"
};
num_irqs = ARRAY_SIZE(global_errb_irqs);
@@ -869,6 +1211,7 @@ static int bd96801_probe(struct platform_device *pdev)
{
struct regulator_dev *ldo_errs_rdev_arr[BD96801_NUM_LDOS];
struct regulator_dev *all_rdevs[BD96801_NUM_REGULATORS];
+ struct bd96801_pmic_data *pdata_template;
struct bd96801_regulator_data *rdesc;
struct regulator_config config = {};
int ldo_errs_arr[BD96801_NUM_LDOS];
@@ -881,12 +1224,16 @@ static int bd96801_probe(struct platform_device *pdev)
parent = pdev->dev.parent;
- pdata = devm_kmemdup(&pdev->dev, &bd96801_data, sizeof(bd96801_data),
+ pdata_template = (struct bd96801_pmic_data *)platform_get_device_id(pdev)->driver_data;
+ if (!pdata_template)
+ return -ENODEV;
+
+ pdata = devm_kmemdup(&pdev->dev, pdata_template, sizeof(bd96801_data),
GFP_KERNEL);
if (!pdata)
return -ENOMEM;
- if (initialize_pmic_data(&pdev->dev, pdata))
+ if (initialize_pmic_data(pdev, pdata))
return -ENOMEM;
pdata->regmap = dev_get_regmap(parent, NULL);
@@ -909,11 +1256,11 @@ static int bd96801_probe(struct platform_device *pdev)
use_errb = true;
ret = bd96801_walk_regulator_dt(&pdev->dev, pdata->regmap, rdesc,
- BD96801_NUM_REGULATORS);
+ pdata->num_regulators);
if (ret)
return ret;
- for (i = 0; i < ARRAY_SIZE(pdata->regulator_data); i++) {
+ for (i = 0; i < pdata->num_regulators; i++) {
struct regulator_dev *rdev;
struct bd96801_irq_desc *idesc = &rdesc[i].irq_desc;
int j;
@@ -926,6 +1273,7 @@ static int bd96801_probe(struct platform_device *pdev)
rdesc[i].desc.name);
return PTR_ERR(rdev);
}
+
all_rdevs[i] = rdev;
/*
* LDOs don't have own temperature monitoring. If temperature
@@ -956,12 +1304,12 @@ static int bd96801_probe(struct platform_device *pdev)
if (temp_notif_ldos) {
int irq;
struct regulator_irq_desc tw_desc = {
- .name = "bd96801-core-thermal",
+ .name = "core-thermal",
.irq_off_ms = 500,
.map_event = ldo_map_notif,
};
- irq = platform_get_irq_byname(pdev, "bd96801-core-thermal");
+ irq = platform_get_irq_byname(pdev, "core-thermal");
if (irq < 0)
return irq;
@@ -975,14 +1323,17 @@ static int bd96801_probe(struct platform_device *pdev)
if (use_errb)
return bd96801_global_errb_irqs(pdev, all_rdevs,
- ARRAY_SIZE(all_rdevs));
+ pdata->num_regulators);
return 0;
}
static const struct platform_device_id bd96801_pmic_id[] = {
- { "bd96801-regulator", },
- { }
+ { "bd96801-regulator", (kernel_ulong_t)&bd96801_data },
+ { "bd96802-regulator", (kernel_ulong_t)&bd96802_data },
+ { "bd96805-regulator", (kernel_ulong_t)&bd96805_data },
+ { "bd96806-regulator", (kernel_ulong_t)&bd96806_data },
+ { },
};
MODULE_DEVICE_TABLE(platform, bd96801_pmic_id);