Commit 00c82652 authored by Nirmala Devi Mal Nadar's avatar Nirmala Devi Mal Nadar Committed by Lee Jones

regulator: tps6594-regulator: Add TI TPS65224 PMIC regulators

Add support for TPS65224 regulators (bucks and LDOs) to TPS6594 driver as
they have significant functional overlap. TPS65224 PMIC has 4 buck
regulators and 3 LDOs. BUCK12 can operate in dual phase.
The output voltages are configurable and are meant to supply power to the
main processor and other components.
Signed-off-by: default avatarNirmala Devi Mal Nadar <m.nirmaladevi@ltts.com>
Signed-off-by: default avatarBhargav Raviprakash <bhargav.r@ltts.com>
Reviewed-by: default avatarMark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/0109018f2fdcc305-3b817569-21b6-42a7-942c-8edbff3848f2-000000@ap-south-1.amazonses.comSigned-off-by: default avatarLee Jones <lee@kernel.org>
parent 91020aec
...@@ -1563,13 +1563,15 @@ config REGULATOR_TPS6594 ...@@ -1563,13 +1563,15 @@ config REGULATOR_TPS6594
depends on MFD_TPS6594 && OF depends on MFD_TPS6594 && OF
default MFD_TPS6594 default MFD_TPS6594
help help
This driver supports TPS6594 voltage regulator chips. This driver supports TPS6594 series and TPS65224 voltage regulator chips.
TPS6594 series of PMICs have 5 BUCKs and 4 LDOs TPS6594 series of PMICs have 5 BUCKs and 4 LDOs
voltage regulators. voltage regulators.
BUCKs 1,2,3,4 can be used in single phase or multiphase mode. BUCKs 1,2,3,4 can be used in single phase or multiphase mode.
Part number defines which single or multiphase mode is i used. Part number defines which single or multiphase mode is i used.
It supports software based voltage control It supports software based voltage control
for different voltage domains. for different voltage domains.
TPS65224 PMIC has 4 BUCKs and 3 LDOs. BUCK12 can be used in dual phase.
All BUCKs and LDOs volatge can be controlled through software.
config REGULATOR_TPS6524X config REGULATOR_TPS6524X
tristate "TI TPS6524X Power regulators" tristate "TI TPS6524X Power regulators"
......
...@@ -18,10 +18,13 @@ ...@@ -18,10 +18,13 @@
#include <linux/mfd/tps6594.h> #include <linux/mfd/tps6594.h>
#define BUCK_NB 5 #define BUCK_NB 5
#define LDO_NB 4 #define LDO_NB 4
#define MULTI_PHASE_NB 4 #define MULTI_PHASE_NB 4
#define REGS_INT_NB 4 /* TPS6593 and LP8764 supports OV, UV, SC, ILIM */
#define REGS_INT_NB 4
/* TPS65224 supports OV or UV */
#define TPS65224_REGS_INT_NB 1
enum tps6594_regulator_id { enum tps6594_regulator_id {
/* DCDC's */ /* DCDC's */
...@@ -66,6 +69,15 @@ static struct tps6594_regulator_irq_type tps6594_ext_regulator_irq_types[] = { ...@@ -66,6 +69,15 @@ static struct tps6594_regulator_irq_type tps6594_ext_regulator_irq_types[] = {
REGULATOR_EVENT_OVER_VOLTAGE_WARN }, REGULATOR_EVENT_OVER_VOLTAGE_WARN },
}; };
static struct tps6594_regulator_irq_type tps65224_ext_regulator_irq_types[] = {
{ TPS65224_IRQ_NAME_VCCA_UVOV, "VCCA", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
{ TPS65224_IRQ_NAME_VMON1_UVOV, "VMON1", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
{ TPS65224_IRQ_NAME_VMON2_UVOV, "VMON2", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
};
struct tps6594_regulator_irq_data { struct tps6594_regulator_irq_data {
struct device *dev; struct device *dev;
struct tps6594_regulator_irq_type *type; struct tps6594_regulator_irq_type *type;
...@@ -122,6 +134,27 @@ static const struct linear_range ldos_4_ranges[] = { ...@@ -122,6 +134,27 @@ static const struct linear_range ldos_4_ranges[] = {
REGULATOR_LINEAR_RANGE(1200000, 0x20, 0x74, 25000), REGULATOR_LINEAR_RANGE(1200000, 0x20, 0x74, 25000),
}; };
/* Voltage range for TPS65224 Bucks and LDOs */
static const struct linear_range tps65224_bucks_1_ranges[] = {
REGULATOR_LINEAR_RANGE(500000, 0x0a, 0x0e, 20000),
REGULATOR_LINEAR_RANGE(600000, 0x0f, 0x72, 5000),
REGULATOR_LINEAR_RANGE(1100000, 0x73, 0xaa, 10000),
REGULATOR_LINEAR_RANGE(1660000, 0xab, 0xfd, 20000),
};
static const struct linear_range tps65224_bucks_2_3_4_ranges[] = {
REGULATOR_LINEAR_RANGE(500000, 0x0, 0x1a, 25000),
REGULATOR_LINEAR_RANGE(1200000, 0x1b, 0x45, 50000),
};
static const struct linear_range tps65224_ldos_1_ranges[] = {
REGULATOR_LINEAR_RANGE(1200000, 0xC, 0x36, 50000),
};
static const struct linear_range tps65224_ldos_2_3_ranges[] = {
REGULATOR_LINEAR_RANGE(600000, 0x0, 0x38, 50000),
};
/* Operations permitted on BUCK1/2/3/4/5 */ /* Operations permitted on BUCK1/2/3/4/5 */
static const struct regulator_ops tps6594_bucks_ops = { static const struct regulator_ops tps6594_bucks_ops = {
.is_enabled = regulator_is_enabled_regmap, .is_enabled = regulator_is_enabled_regmap,
...@@ -197,6 +230,38 @@ static const struct regulator_desc buck_regs[] = { ...@@ -197,6 +230,38 @@ static const struct regulator_desc buck_regs[] = {
4, 0, 0, NULL, 0, 0), 4, 0, 0, NULL, 0, 0),
}; };
/* Buck configuration for TPS65224 */
static const struct regulator_desc tps65224_buck_regs[] = {
TPS6594_REGULATOR("BUCK1", "buck1", TPS6594_BUCK_1,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,
TPS6594_REG_BUCKX_VOUT_1(0),
TPS65224_MASK_BUCK1_VSET,
TPS6594_REG_BUCKX_CTRL(0),
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,
4, 0, 0, NULL, 0, 0),
TPS6594_REGULATOR("BUCK2", "buck2", TPS6594_BUCK_2,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_VOUT_1(1),
TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_CTRL(1),
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
4, 0, 0, NULL, 0, 0),
TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_VOUT_1(2),
TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_CTRL(2),
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
4, 0, 0, NULL, 0, 0),
TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_VOUT_1(3),
TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_CTRL(3),
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
4, 0, 0, NULL, 0, 0),
};
static struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = { static struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = {
{ TPS6594_IRQ_NAME_BUCK1_OV, "BUCK1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN }, { TPS6594_IRQ_NAME_BUCK1_OV, "BUCK1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
{ TPS6594_IRQ_NAME_BUCK1_UV, "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE }, { TPS6594_IRQ_NAME_BUCK1_UV, "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
...@@ -269,6 +334,41 @@ static struct tps6594_regulator_irq_type tps6594_ldo4_irq_types[] = { ...@@ -269,6 +334,41 @@ static struct tps6594_regulator_irq_type tps6594_ldo4_irq_types[] = {
REGULATOR_EVENT_OVER_CURRENT }, REGULATOR_EVENT_OVER_CURRENT },
}; };
static struct tps6594_regulator_irq_type tps65224_buck1_irq_types[] = {
{ TPS65224_IRQ_NAME_BUCK1_UVOV, "BUCK1", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
};
static struct tps6594_regulator_irq_type tps65224_buck2_irq_types[] = {
{ TPS65224_IRQ_NAME_BUCK2_UVOV, "BUCK2", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
};
static struct tps6594_regulator_irq_type tps65224_buck3_irq_types[] = {
{ TPS65224_IRQ_NAME_BUCK3_UVOV, "BUCK3", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
};
static struct tps6594_regulator_irq_type tps65224_buck4_irq_types[] = {
{ TPS65224_IRQ_NAME_BUCK4_UVOV, "BUCK4", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
};
static struct tps6594_regulator_irq_type tps65224_ldo1_irq_types[] = {
{ TPS65224_IRQ_NAME_LDO1_UVOV, "LDO1", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
};
static struct tps6594_regulator_irq_type tps65224_ldo2_irq_types[] = {
{ TPS65224_IRQ_NAME_LDO2_UVOV, "LDO2", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
};
static struct tps6594_regulator_irq_type tps65224_ldo3_irq_types[] = {
{ TPS65224_IRQ_NAME_LDO3_UVOV, "LDO3", "voltage out of range",
REGULATOR_EVENT_REGULATION_OUT },
};
static struct tps6594_regulator_irq_type *tps6594_bucks_irq_types[] = { static struct tps6594_regulator_irq_type *tps6594_bucks_irq_types[] = {
tps6594_buck1_irq_types, tps6594_buck1_irq_types,
tps6594_buck2_irq_types, tps6594_buck2_irq_types,
...@@ -284,7 +384,20 @@ static struct tps6594_regulator_irq_type *tps6594_ldos_irq_types[] = { ...@@ -284,7 +384,20 @@ static struct tps6594_regulator_irq_type *tps6594_ldos_irq_types[] = {
tps6594_ldo4_irq_types, tps6594_ldo4_irq_types,
}; };
static const struct regulator_desc multi_regs[] = { static struct tps6594_regulator_irq_type *tps65224_bucks_irq_types[] = {
tps65224_buck1_irq_types,
tps65224_buck2_irq_types,
tps65224_buck3_irq_types,
tps65224_buck4_irq_types,
};
static struct tps6594_regulator_irq_type *tps65224_ldos_irq_types[] = {
tps65224_ldo1_irq_types,
tps65224_ldo2_irq_types,
tps65224_ldo3_irq_types,
};
static const struct regulator_desc tps6594_multi_regs[] = {
TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1, TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET, REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_VOUT_1(1), TPS6594_REG_BUCKX_VOUT_1(1),
...@@ -315,7 +428,17 @@ static const struct regulator_desc multi_regs[] = { ...@@ -315,7 +428,17 @@ static const struct regulator_desc multi_regs[] = {
4, 4000, 0, NULL, 0, 0), 4, 4000, 0, NULL, 0, 0),
}; };
static const struct regulator_desc ldo_regs[] = { static const struct regulator_desc tps65224_multi_regs[] = {
TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,
TPS6594_REG_BUCKX_VOUT_1(0),
TPS65224_MASK_BUCK1_VSET,
TPS6594_REG_BUCKX_CTRL(0),
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,
4, 4000, 0, NULL, 0, 0),
};
static const struct regulator_desc tps6594_ldo_regs[] = {
TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1, TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET, REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
TPS6594_REG_LDOX_VOUT(0), TPS6594_REG_LDOX_VOUT(0),
...@@ -346,6 +469,30 @@ static const struct regulator_desc ldo_regs[] = { ...@@ -346,6 +469,30 @@ static const struct regulator_desc ldo_regs[] = {
1, 0, 0, NULL, 0, 0), 1, 0, 0, NULL, 0, 0),
}; };
static const struct regulator_desc tps65224_ldo_regs[] = {
TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
TPS6594_REG_LDOX_VOUT(0),
TPS6594_MASK_LDO123_VSET,
TPS6594_REG_LDOX_CTRL(0),
TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_1_ranges,
1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
TPS6594_REGULATOR("LDO2", "ldo2", TPS6594_LDO_2,
REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
TPS6594_REG_LDOX_VOUT(1),
TPS6594_MASK_LDO123_VSET,
TPS6594_REG_LDOX_CTRL(1),
TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,
1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
TPS6594_REGULATOR("LDO3", "ldo3", TPS6594_LDO_3,
REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
TPS6594_REG_LDOX_VOUT(2),
TPS6594_MASK_LDO123_VSET,
TPS6594_REG_LDOX_CTRL(2),
TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,
1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
};
static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data) static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data)
{ {
struct tps6594_regulator_irq_data *irq_data = data; struct tps6594_regulator_irq_data *irq_data = data;
...@@ -369,17 +516,18 @@ static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data) ...@@ -369,17 +516,18 @@ static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data)
static int tps6594_request_reg_irqs(struct platform_device *pdev, static int tps6594_request_reg_irqs(struct platform_device *pdev,
struct regulator_dev *rdev, struct regulator_dev *rdev,
struct tps6594_regulator_irq_data *irq_data, struct tps6594_regulator_irq_data *irq_data,
struct tps6594_regulator_irq_type *tps6594_regs_irq_types, struct tps6594_regulator_irq_type *regs_irq_types,
size_t interrupt_cnt,
int *irq_idx) int *irq_idx)
{ {
struct tps6594_regulator_irq_type *irq_type; struct tps6594_regulator_irq_type *irq_type;
struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent); struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
int j; size_t j;
int irq; int irq;
int error; int error;
for (j = 0; j < REGS_INT_NB; j++) { for (j = 0; j < interrupt_cnt; j++) {
irq_type = &tps6594_regs_irq_types[j]; irq_type = &regs_irq_types[j];
irq = platform_get_irq_byname(pdev, irq_type->irq_name); irq = platform_get_irq_byname(pdev, irq_type->irq_name);
if (irq < 0) if (irq < 0)
return -EINVAL; return -EINVAL;
...@@ -411,23 +559,47 @@ static int tps6594_regulator_probe(struct platform_device *pdev) ...@@ -411,23 +559,47 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
struct tps6594_regulator_irq_data *irq_data; struct tps6594_regulator_irq_data *irq_data;
struct tps6594_ext_regulator_irq_data *irq_ext_reg_data; struct tps6594_ext_regulator_irq_data *irq_ext_reg_data;
struct tps6594_regulator_irq_type *irq_type; struct tps6594_regulator_irq_type *irq_type;
u8 buck_configured[BUCK_NB] = { 0 }; struct tps6594_regulator_irq_type *irq_types;
u8 buck_multi[MULTI_PHASE_NB] = { 0 }; bool buck_configured[BUCK_NB] = { false };
static const char * const multiphases[] = {"buck12", "buck123", "buck1234", "buck34"}; bool buck_multi[MULTI_PHASE_NB] = { false };
static const char *npname; static const char *npname;
int error, i, irq, multi, delta; int error, i, irq, multi;
int irq_idx = 0; int irq_idx = 0;
int buck_idx = 0; int buck_idx = 0;
size_t ext_reg_irq_nb = 2; int nr_ldo;
int nr_buck;
int nr_types;
unsigned int irq_count;
unsigned int multi_phase_cnt;
size_t reg_irq_nb; size_t reg_irq_nb;
struct tps6594_regulator_irq_type **bucks_irq_types;
const struct regulator_desc *multi_regs;
struct tps6594_regulator_irq_type **ldos_irq_types;
const struct regulator_desc *ldo_regs;
size_t interrupt_count;
if (tps->chip_id == TPS65224) {
bucks_irq_types = tps65224_bucks_irq_types;
interrupt_count = ARRAY_SIZE(tps65224_buck1_irq_types);
multi_regs = tps65224_multi_regs;
ldos_irq_types = tps65224_ldos_irq_types;
ldo_regs = tps65224_ldo_regs;
multi_phase_cnt = ARRAY_SIZE(tps65224_multi_regs);
} else {
bucks_irq_types = tps6594_bucks_irq_types;
interrupt_count = ARRAY_SIZE(tps6594_buck1_irq_types);
multi_regs = tps6594_multi_regs;
ldos_irq_types = tps6594_ldos_irq_types;
ldo_regs = tps6594_ldo_regs;
multi_phase_cnt = ARRAY_SIZE(tps6594_multi_regs);
}
enum { enum {
MULTI_BUCK12, MULTI_BUCK12,
MULTI_BUCK12_34,
MULTI_BUCK123, MULTI_BUCK123,
MULTI_BUCK1234, MULTI_BUCK1234,
MULTI_BUCK12_34,
MULTI_FIRST = MULTI_BUCK12,
MULTI_LAST = MULTI_BUCK12_34,
MULTI_NUM = MULTI_LAST - MULTI_FIRST + 1
}; };
config.dev = tps->dev; config.dev = tps->dev;
...@@ -442,61 +614,68 @@ static int tps6594_regulator_probe(struct platform_device *pdev) ...@@ -442,61 +614,68 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
* In case of Multiphase configuration, value should be defined for * In case of Multiphase configuration, value should be defined for
* buck_configured to avoid creating bucks for every buck in multiphase * buck_configured to avoid creating bucks for every buck in multiphase
*/ */
for (multi = MULTI_FIRST; multi < MULTI_NUM; multi++) { for (multi = 0; multi < multi_phase_cnt; multi++) {
np = of_find_node_by_name(tps->dev->of_node, multiphases[multi]); np = of_find_node_by_name(tps->dev->of_node, multi_regs[multi].supply_name);
npname = of_node_full_name(np); npname = of_node_full_name(np);
np_pmic_parent = of_get_parent(of_get_parent(np)); np_pmic_parent = of_get_parent(of_get_parent(np));
if (of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name)) if (of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name))
continue; continue;
delta = strcmp(npname, multiphases[multi]); if (strcmp(npname, multi_regs[multi].supply_name) == 0) {
if (!delta) {
switch (multi) { switch (multi) {
case MULTI_BUCK12: case MULTI_BUCK12:
buck_multi[0] = 1; buck_multi[0] = true;
buck_configured[0] = 1; buck_configured[0] = true;
buck_configured[1] = 1; buck_configured[1] = true;
break; break;
/* multiphase buck34 is supported only with buck12 */ /* multiphase buck34 is supported only with buck12 */
case MULTI_BUCK12_34: case MULTI_BUCK12_34:
buck_multi[0] = 1; buck_multi[0] = true;
buck_multi[1] = 1; buck_multi[1] = true;
buck_configured[0] = 1; buck_configured[0] = true;
buck_configured[1] = 1; buck_configured[1] = true;
buck_configured[2] = 1; buck_configured[2] = true;
buck_configured[3] = 1; buck_configured[3] = true;
break; break;
case MULTI_BUCK123: case MULTI_BUCK123:
buck_multi[2] = 1; buck_multi[2] = true;
buck_configured[0] = 1; buck_configured[0] = true;
buck_configured[1] = 1; buck_configured[1] = true;
buck_configured[2] = 1; buck_configured[2] = true;
break; break;
case MULTI_BUCK1234: case MULTI_BUCK1234:
buck_multi[3] = 1; buck_multi[3] = true;
buck_configured[0] = 1; buck_configured[0] = true;
buck_configured[1] = 1; buck_configured[1] = true;
buck_configured[2] = 1; buck_configured[2] = true;
buck_configured[3] = 1; buck_configured[3] = true;
break; break;
} }
} }
} }
if (tps->chip_id == LP8764) { if (tps->chip_id == LP8764) {
/* There is only 4 buck on LP8764 */ nr_buck = ARRAY_SIZE(buck_regs);
buck_configured[4] = 1; nr_ldo = 0;
reg_irq_nb = size_mul(REGS_INT_NB, (BUCK_NB - 1)); nr_types = REGS_INT_NB;
} else if (tps->chip_id == TPS65224) {
nr_buck = ARRAY_SIZE(tps65224_buck_regs);
nr_ldo = ARRAY_SIZE(tps65224_ldo_regs);
nr_types = REGS_INT_NB;
} else { } else {
reg_irq_nb = size_mul(REGS_INT_NB, (size_add(BUCK_NB, LDO_NB))); nr_buck = ARRAY_SIZE(buck_regs);
nr_ldo = ARRAY_SIZE(tps6594_ldo_regs);
nr_types = TPS65224_REGS_INT_NB;
} }
reg_irq_nb = nr_types * (nr_buck + nr_ldo);
irq_data = devm_kmalloc_array(tps->dev, reg_irq_nb, irq_data = devm_kmalloc_array(tps->dev, reg_irq_nb,
sizeof(struct tps6594_regulator_irq_data), GFP_KERNEL); sizeof(struct tps6594_regulator_irq_data), GFP_KERNEL);
if (!irq_data) if (!irq_data)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < MULTI_PHASE_NB; i++) { for (i = 0; i < multi_phase_cnt; i++) {
if (buck_multi[i] == 0) if (!buck_multi[i])
continue; continue;
rdev = devm_regulator_register(&pdev->dev, &multi_regs[i], &config); rdev = devm_regulator_register(&pdev->dev, &multi_regs[i], &config);
...@@ -506,52 +685,60 @@ static int tps6594_regulator_probe(struct platform_device *pdev) ...@@ -506,52 +685,60 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
pdev->name); pdev->name);
/* config multiphase buck12+buck34 */ /* config multiphase buck12+buck34 */
if (i == 1) if (i == MULTI_BUCK12_34)
buck_idx = 2; buck_idx = 2;
error = tps6594_request_reg_irqs(pdev, rdev, irq_data, error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
tps6594_bucks_irq_types[buck_idx], &irq_idx); bucks_irq_types[buck_idx],
interrupt_count, &irq_idx);
if (error) if (error)
return error; return error;
error = tps6594_request_reg_irqs(pdev, rdev, irq_data, error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
tps6594_bucks_irq_types[buck_idx + 1], &irq_idx); bucks_irq_types[buck_idx + 1],
interrupt_count, &irq_idx);
if (error) if (error)
return error; return error;
if (i == 2 || i == 3) { if (i == MULTI_BUCK123 || i == MULTI_BUCK1234) {
error = tps6594_request_reg_irqs(pdev, rdev, irq_data, error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
tps6594_bucks_irq_types[buck_idx + 2], tps6594_bucks_irq_types[buck_idx + 2],
interrupt_count,
&irq_idx); &irq_idx);
if (error) if (error)
return error; return error;
} }
if (i == 3) { if (i == MULTI_BUCK1234) {
error = tps6594_request_reg_irqs(pdev, rdev, irq_data, error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
tps6594_bucks_irq_types[buck_idx + 3], tps6594_bucks_irq_types[buck_idx + 3],
interrupt_count,
&irq_idx); &irq_idx);
if (error) if (error)
return error; return error;
} }
} }
for (i = 0; i < BUCK_NB; i++) { for (i = 0; i < nr_buck; i++) {
if (buck_configured[i] == 1) if (buck_configured[i])
continue; continue;
rdev = devm_regulator_register(&pdev->dev, &buck_regs[i], &config); const struct regulator_desc *buck_cfg = (tps->chip_id == TPS65224) ?
tps65224_buck_regs : buck_regs;
rdev = devm_regulator_register(&pdev->dev, &buck_cfg[i], &config);
if (IS_ERR(rdev)) if (IS_ERR(rdev))
return dev_err_probe(tps->dev, PTR_ERR(rdev), return dev_err_probe(tps->dev, PTR_ERR(rdev),
"failed to register %s regulator\n", "failed to register %s regulator\n", pdev->name);
pdev->name);
error = tps6594_request_reg_irqs(pdev, rdev, irq_data, error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
tps6594_bucks_irq_types[i], &irq_idx); bucks_irq_types[i], interrupt_count, &irq_idx);
if (error) if (error)
return error; return error;
} }
/* LP8764 dosen't have LDO */ /* LP8764 doesn't have LDO */
if (tps->chip_id != LP8764) { if (tps->chip_id != LP8764) {
for (i = 0; i < ARRAY_SIZE(ldo_regs); i++) { for (i = 0; i < nr_ldo; i++) {
rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config); rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config);
if (IS_ERR(rdev)) if (IS_ERR(rdev))
return dev_err_probe(tps->dev, PTR_ERR(rdev), return dev_err_probe(tps->dev, PTR_ERR(rdev),
...@@ -559,26 +746,34 @@ static int tps6594_regulator_probe(struct platform_device *pdev) ...@@ -559,26 +746,34 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
pdev->name); pdev->name);
error = tps6594_request_reg_irqs(pdev, rdev, irq_data, error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
tps6594_ldos_irq_types[i], ldos_irq_types[i], interrupt_count,
&irq_idx); &irq_idx);
if (error) if (error)
return error; return error;
} }
} }
if (tps->chip_id == LP8764) if (tps->chip_id == TPS65224) {
ext_reg_irq_nb = ARRAY_SIZE(tps6594_ext_regulator_irq_types); irq_types = tps65224_ext_regulator_irq_types;
irq_count = ARRAY_SIZE(tps65224_ext_regulator_irq_types);
} else {
irq_types = tps6594_ext_regulator_irq_types;
if (tps->chip_id == LP8764)
irq_count = ARRAY_SIZE(tps6594_ext_regulator_irq_types);
else
/* TPS6593 supports only VCCA OV and UV */
irq_count = 2;
}
irq_ext_reg_data = devm_kmalloc_array(tps->dev, irq_ext_reg_data = devm_kmalloc_array(tps->dev,
ext_reg_irq_nb, irq_count,
sizeof(struct tps6594_ext_regulator_irq_data), sizeof(struct tps6594_ext_regulator_irq_data),
GFP_KERNEL); GFP_KERNEL);
if (!irq_ext_reg_data) if (!irq_ext_reg_data)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < ext_reg_irq_nb; ++i) { for (i = 0; i < irq_count; ++i) {
irq_type = &tps6594_ext_regulator_irq_types[i]; irq_type = &irq_types[i];
irq = platform_get_irq_byname(pdev, irq_type->irq_name); irq = platform_get_irq_byname(pdev, irq_type->irq_name);
if (irq < 0) if (irq < 0)
return -EINVAL; return -EINVAL;
...@@ -610,5 +805,6 @@ module_platform_driver(tps6594_regulator_driver); ...@@ -610,5 +805,6 @@ module_platform_driver(tps6594_regulator_driver);
MODULE_ALIAS("platform:tps6594-regulator"); MODULE_ALIAS("platform:tps6594-regulator");
MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>"); MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
MODULE_AUTHOR("Nirmala Devi Mal Nadar <m.nirmaladevi@ltts.com>");
MODULE_DESCRIPTION("TPS6594 voltage regulator driver"); MODULE_DESCRIPTION("TPS6594 voltage regulator driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment