brintos

brintos / linux-shallow public Read only

0
0
Text · 27.3 KiB · ac53792 Raw
807 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// Regulator driver for tps6594 PMIC4//5// Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/6 7#include <linux/device.h>8#include <linux/err.h>9#include <linux/init.h>10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/of.h>13#include <linux/platform_device.h>14#include <linux/regmap.h>15#include <linux/regulator/driver.h>16#include <linux/regulator/machine.h>17#include <linux/regulator/of_regulator.h>18 19#include <linux/mfd/tps6594.h>20 21#define BUCK_NB			522#define LDO_NB			423#define MULTI_PHASE_NB		424/* TPS6593 and LP8764 supports OV, UV, SC, ILIM */25#define REGS_INT_NB		426/* TPS65224 supports OV or UV */27#define TPS65224_REGS_INT_NB	128 29enum tps6594_regulator_id {30	/* DCDC's */31	TPS6594_BUCK_1,32	TPS6594_BUCK_2,33	TPS6594_BUCK_3,34	TPS6594_BUCK_4,35	TPS6594_BUCK_5,36 37	/* LDOs */38	TPS6594_LDO_1,39	TPS6594_LDO_2,40	TPS6594_LDO_3,41	TPS6594_LDO_4,42};43 44enum tps6594_multi_regulator_id {45	/* Multi-phase DCDC's */46	TPS6594_BUCK_12,47	TPS6594_BUCK_34,48	TPS6594_BUCK_123,49	TPS6594_BUCK_1234,50};51 52struct tps6594_regulator_irq_type {53	const char *irq_name;54	const char *regulator_name;55	const char *event_name;56	unsigned long event;57};58 59static struct tps6594_regulator_irq_type tps6594_ext_regulator_irq_types[] = {60	{ TPS6594_IRQ_NAME_VCCA_OV, "VCCA", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },61	{ TPS6594_IRQ_NAME_VCCA_UV, "VCCA", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },62	{ TPS6594_IRQ_NAME_VMON1_OV, "VMON1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },63	{ TPS6594_IRQ_NAME_VMON1_UV, "VMON1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },64	{ TPS6594_IRQ_NAME_VMON1_RV, "VMON1", "residual voltage",65	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },66	{ TPS6594_IRQ_NAME_VMON2_OV, "VMON2", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },67	{ TPS6594_IRQ_NAME_VMON2_UV, "VMON2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },68	{ TPS6594_IRQ_NAME_VMON2_RV, "VMON2", "residual voltage",69	  REGULATOR_EVENT_OVER_VOLTAGE_WARN },70};71 72static struct tps6594_regulator_irq_type tps65224_ext_regulator_irq_types[] = {73	{ TPS65224_IRQ_NAME_VCCA_UVOV, "VCCA", "voltage out of range",74	  REGULATOR_EVENT_REGULATION_OUT },75	{ TPS65224_IRQ_NAME_VMON1_UVOV, "VMON1", "voltage out of range",76	  REGULATOR_EVENT_REGULATION_OUT },77	{ TPS65224_IRQ_NAME_VMON2_UVOV, "VMON2", "voltage out of range",78	  REGULATOR_EVENT_REGULATION_OUT },79};80 81struct tps6594_regulator_irq_data {82	struct device *dev;83	struct tps6594_regulator_irq_type *type;84	struct regulator_dev *rdev;85};86 87struct tps6594_ext_regulator_irq_data {88	struct device *dev;89	struct tps6594_regulator_irq_type *type;90};91 92#define TPS6594_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \93			   _em, _cr, _cm, _lr, _nlr, _delay, _fuv, \94			   _ct, _ncl, _bpm) \95	{								\96		.name			= _name,			\97		.of_match		= _of,				\98		.regulators_node	= of_match_ptr("regulators"),	\99		.supply_name		= _of,				\100		.id			= _id,				\101		.ops			= &(_ops),			\102		.n_voltages		= _n,				\103		.type			= _type,			\104		.owner			= THIS_MODULE,			\105		.vsel_reg		= _vr,				\106		.vsel_mask		= _vm,				\107		.csel_reg		= _cr,				\108		.csel_mask		= _cm,				\109		.curr_table		= _ct,				\110		.n_current_limits	= _ncl,				\111		.enable_reg		= _er,				\112		.enable_mask		= _em,				\113		.volt_table		= NULL,				\114		.linear_ranges		= _lr,				\115		.n_linear_ranges	= _nlr,				\116		.ramp_delay		= _delay,			\117		.fixed_uV		= _fuv,				\118		.bypass_reg		= _vr,				\119		.bypass_mask		= _bpm,				\120	}								\121 122static const struct linear_range bucks_ranges[] = {123	REGULATOR_LINEAR_RANGE(300000, 0x0, 0xe, 20000),124	REGULATOR_LINEAR_RANGE(600000, 0xf, 0x72, 5000),125	REGULATOR_LINEAR_RANGE(1100000, 0x73, 0xaa, 10000),126	REGULATOR_LINEAR_RANGE(1660000, 0xab, 0xff, 20000),127};128 129static const struct linear_range ldos_1_2_3_ranges[] = {130	REGULATOR_LINEAR_RANGE(600000, 0x4, 0x3a, 50000),131};132 133static const struct linear_range ldos_4_ranges[] = {134	REGULATOR_LINEAR_RANGE(1200000, 0x20, 0x74, 25000),135};136 137/* Voltage range for TPS65224 Bucks and LDOs */138static const struct linear_range tps65224_bucks_1_ranges[] = {139	REGULATOR_LINEAR_RANGE(500000, 0x0a, 0x0e, 20000),140	REGULATOR_LINEAR_RANGE(600000, 0x0f, 0x72, 5000),141	REGULATOR_LINEAR_RANGE(1100000, 0x73, 0xaa, 10000),142	REGULATOR_LINEAR_RANGE(1660000, 0xab, 0xfd, 20000),143};144 145static const struct linear_range tps65224_bucks_2_3_4_ranges[] = {146	REGULATOR_LINEAR_RANGE(500000, 0x0, 0x1a, 25000),147	REGULATOR_LINEAR_RANGE(1200000, 0x1b, 0x45, 50000),148};149 150static const struct linear_range tps65224_ldos_1_ranges[] = {151	REGULATOR_LINEAR_RANGE(1200000, 0xC, 0x36, 50000),152};153 154static const struct linear_range tps65224_ldos_2_3_ranges[] = {155	REGULATOR_LINEAR_RANGE(600000, 0x0, 0x38, 50000),156};157 158/* Operations permitted on BUCK1/2/3/4/5 */159static const struct regulator_ops tps6594_bucks_ops = {160	.is_enabled		= regulator_is_enabled_regmap,161	.enable			= regulator_enable_regmap,162	.disable		= regulator_disable_regmap,163	.get_voltage_sel	= regulator_get_voltage_sel_regmap,164	.set_voltage_sel	= regulator_set_voltage_sel_regmap,165	.list_voltage		= regulator_list_voltage_linear_range,166	.map_voltage		= regulator_map_voltage_linear_range,167	.set_voltage_time_sel	= regulator_set_voltage_time_sel,168 169};170 171/* Operations permitted on LDO1/2/3 */172static const struct regulator_ops tps6594_ldos_1_2_3_ops = {173	.is_enabled		= regulator_is_enabled_regmap,174	.enable			= regulator_enable_regmap,175	.disable		= regulator_disable_regmap,176	.get_voltage_sel	= regulator_get_voltage_sel_regmap,177	.set_voltage_sel	= regulator_set_voltage_sel_regmap,178	.list_voltage		= regulator_list_voltage_linear_range,179	.map_voltage		= regulator_map_voltage_linear_range,180	.set_bypass		= regulator_set_bypass_regmap,181	.get_bypass		= regulator_get_bypass_regmap,182};183 184/* Operations permitted on LDO4 */185static const struct regulator_ops tps6594_ldos_4_ops = {186	.is_enabled		= regulator_is_enabled_regmap,187	.enable			= regulator_enable_regmap,188	.disable		= regulator_disable_regmap,189	.get_voltage_sel	= regulator_get_voltage_sel_regmap,190	.set_voltage_sel	= regulator_set_voltage_sel_regmap,191	.list_voltage		= regulator_list_voltage_linear_range,192	.map_voltage		= regulator_map_voltage_linear_range,193};194 195static const struct regulator_desc buck_regs[] = {196	TPS6594_REGULATOR("BUCK1", "buck1", TPS6594_BUCK_1,197			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,198			  TPS6594_REG_BUCKX_VOUT_1(0),199			  TPS6594_MASK_BUCKS_VSET,200			  TPS6594_REG_BUCKX_CTRL(0),201			  TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,202			  4, 0, 0, NULL, 0, 0),203	TPS6594_REGULATOR("BUCK2", "buck2", TPS6594_BUCK_2,204			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,205			  TPS6594_REG_BUCKX_VOUT_1(1),206			  TPS6594_MASK_BUCKS_VSET,207			  TPS6594_REG_BUCKX_CTRL(1),208			  TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,209			  4, 0, 0, NULL, 0, 0),210	TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,211			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,212			  TPS6594_REG_BUCKX_VOUT_1(2),213			  TPS6594_MASK_BUCKS_VSET,214			  TPS6594_REG_BUCKX_CTRL(2),215			  TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,216			  4, 0, 0, NULL, 0, 0),217	TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,218			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,219			  TPS6594_REG_BUCKX_VOUT_1(3),220			  TPS6594_MASK_BUCKS_VSET,221			  TPS6594_REG_BUCKX_CTRL(3),222			  TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,223			  4, 0, 0, NULL, 0, 0),224	TPS6594_REGULATOR("BUCK5", "buck5", TPS6594_BUCK_5,225			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,226			  TPS6594_REG_BUCKX_VOUT_1(4),227			  TPS6594_MASK_BUCKS_VSET,228			  TPS6594_REG_BUCKX_CTRL(4),229			  TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,230			  4, 0, 0, NULL, 0, 0),231};232 233/* Buck configuration for TPS65224 */234static const struct regulator_desc tps65224_buck_regs[] = {235	TPS6594_REGULATOR("BUCK1", "buck1", TPS6594_BUCK_1,236			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,237			  TPS6594_REG_BUCKX_VOUT_1(0),238			  TPS65224_MASK_BUCK1_VSET,239			  TPS6594_REG_BUCKX_CTRL(0),240			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,241			  4, 0, 0, NULL, 0, 0),242	TPS6594_REGULATOR("BUCK2", "buck2", TPS6594_BUCK_2,243			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,244			  TPS6594_REG_BUCKX_VOUT_1(1),245			  TPS65224_MASK_BUCKS_VSET,246			  TPS6594_REG_BUCKX_CTRL(1),247			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,248			  4, 0, 0, NULL, 0, 0),249	TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,250			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,251			  TPS6594_REG_BUCKX_VOUT_1(2),252			  TPS65224_MASK_BUCKS_VSET,253			  TPS6594_REG_BUCKX_CTRL(2),254			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,255			  4, 0, 0, NULL, 0, 0),256	TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,257			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,258			  TPS6594_REG_BUCKX_VOUT_1(3),259			  TPS65224_MASK_BUCKS_VSET,260			  TPS6594_REG_BUCKX_CTRL(3),261			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,262			  4, 0, 0, NULL, 0, 0),263};264 265static struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = {266	{ TPS6594_IRQ_NAME_BUCK1_OV, "BUCK1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },267	{ TPS6594_IRQ_NAME_BUCK1_UV, "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },268	{ TPS6594_IRQ_NAME_BUCK1_SC, "BUCK1", "short circuit", REGULATOR_EVENT_REGULATION_OUT },269	{ TPS6594_IRQ_NAME_BUCK1_ILIM, "BUCK1", "reach ilim, overcurrent",270	  REGULATOR_EVENT_OVER_CURRENT },271};272 273static struct tps6594_regulator_irq_type tps6594_buck2_irq_types[] = {274	{ TPS6594_IRQ_NAME_BUCK2_OV, "BUCK2", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },275	{ TPS6594_IRQ_NAME_BUCK2_UV, "BUCK2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },276	{ TPS6594_IRQ_NAME_BUCK2_SC, "BUCK2", "short circuit", REGULATOR_EVENT_REGULATION_OUT },277	{ TPS6594_IRQ_NAME_BUCK2_ILIM, "BUCK2", "reach ilim, overcurrent",278	  REGULATOR_EVENT_OVER_CURRENT },279};280 281static struct tps6594_regulator_irq_type tps6594_buck3_irq_types[] = {282	{ TPS6594_IRQ_NAME_BUCK3_OV, "BUCK3", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },283	{ TPS6594_IRQ_NAME_BUCK3_UV, "BUCK3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },284	{ TPS6594_IRQ_NAME_BUCK3_SC, "BUCK3", "short circuit", REGULATOR_EVENT_REGULATION_OUT },285	{ TPS6594_IRQ_NAME_BUCK3_ILIM, "BUCK3", "reach ilim, overcurrent",286	  REGULATOR_EVENT_OVER_CURRENT },287};288 289static struct tps6594_regulator_irq_type tps6594_buck4_irq_types[] = {290	{ TPS6594_IRQ_NAME_BUCK4_OV, "BUCK4", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },291	{ TPS6594_IRQ_NAME_BUCK4_UV, "BUCK4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },292	{ TPS6594_IRQ_NAME_BUCK4_SC, "BUCK4", "short circuit", REGULATOR_EVENT_REGULATION_OUT },293	{ TPS6594_IRQ_NAME_BUCK4_ILIM, "BUCK4", "reach ilim, overcurrent",294	  REGULATOR_EVENT_OVER_CURRENT },295};296 297static struct tps6594_regulator_irq_type tps6594_buck5_irq_types[] = {298	{ TPS6594_IRQ_NAME_BUCK5_OV, "BUCK5", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },299	{ TPS6594_IRQ_NAME_BUCK5_UV, "BUCK5", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },300	{ TPS6594_IRQ_NAME_BUCK5_SC, "BUCK5", "short circuit", REGULATOR_EVENT_REGULATION_OUT },301	{ TPS6594_IRQ_NAME_BUCK5_ILIM, "BUCK5", "reach ilim, overcurrent",302	  REGULATOR_EVENT_OVER_CURRENT },303};304 305static struct tps6594_regulator_irq_type tps6594_ldo1_irq_types[] = {306	{ TPS6594_IRQ_NAME_LDO1_OV, "LDO1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },307	{ TPS6594_IRQ_NAME_LDO1_UV, "LDO1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },308	{ TPS6594_IRQ_NAME_LDO1_SC, "LDO1", "short circuit", REGULATOR_EVENT_REGULATION_OUT },309	{ TPS6594_IRQ_NAME_LDO1_ILIM, "LDO1", "reach ilim, overcurrent",310	  REGULATOR_EVENT_OVER_CURRENT },311};312 313static struct tps6594_regulator_irq_type tps6594_ldo2_irq_types[] = {314	{ TPS6594_IRQ_NAME_LDO2_OV, "LDO2", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },315	{ TPS6594_IRQ_NAME_LDO2_UV, "LDO2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },316	{ TPS6594_IRQ_NAME_LDO2_SC, "LDO2", "short circuit", REGULATOR_EVENT_REGULATION_OUT },317	{ TPS6594_IRQ_NAME_LDO2_ILIM, "LDO2", "reach ilim, overcurrent",318	  REGULATOR_EVENT_OVER_CURRENT },319};320 321static struct tps6594_regulator_irq_type tps6594_ldo3_irq_types[] = {322	{ TPS6594_IRQ_NAME_LDO3_OV, "LDO3", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },323	{ TPS6594_IRQ_NAME_LDO3_UV, "LDO3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },324	{ TPS6594_IRQ_NAME_LDO3_SC, "LDO3", "short circuit", REGULATOR_EVENT_REGULATION_OUT },325	{ TPS6594_IRQ_NAME_LDO3_ILIM, "LDO3", "reach ilim, overcurrent",326	  REGULATOR_EVENT_OVER_CURRENT },327};328 329static struct tps6594_regulator_irq_type tps6594_ldo4_irq_types[] = {330	{ TPS6594_IRQ_NAME_LDO4_OV, "LDO4", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },331	{ TPS6594_IRQ_NAME_LDO4_UV, "LDO4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },332	{ TPS6594_IRQ_NAME_LDO4_SC, "LDO4", "short circuit", REGULATOR_EVENT_REGULATION_OUT },333	{ TPS6594_IRQ_NAME_LDO4_ILIM, "LDO4", "reach ilim, overcurrent",334	  REGULATOR_EVENT_OVER_CURRENT },335};336 337static struct tps6594_regulator_irq_type tps65224_buck1_irq_types[] = {338	{ TPS65224_IRQ_NAME_BUCK1_UVOV, "BUCK1", "voltage out of range",339	  REGULATOR_EVENT_REGULATION_OUT },340};341 342static struct tps6594_regulator_irq_type tps65224_buck2_irq_types[] = {343	{ TPS65224_IRQ_NAME_BUCK2_UVOV, "BUCK2", "voltage out of range",344	  REGULATOR_EVENT_REGULATION_OUT },345};346 347static struct tps6594_regulator_irq_type tps65224_buck3_irq_types[] = {348	{ TPS65224_IRQ_NAME_BUCK3_UVOV, "BUCK3", "voltage out of range",349	  REGULATOR_EVENT_REGULATION_OUT },350};351 352static struct tps6594_regulator_irq_type tps65224_buck4_irq_types[] = {353	{ TPS65224_IRQ_NAME_BUCK4_UVOV, "BUCK4", "voltage out of range",354	  REGULATOR_EVENT_REGULATION_OUT },355};356 357static struct tps6594_regulator_irq_type tps65224_ldo1_irq_types[] = {358	{ TPS65224_IRQ_NAME_LDO1_UVOV, "LDO1", "voltage out of range",359	  REGULATOR_EVENT_REGULATION_OUT },360};361 362static struct tps6594_regulator_irq_type tps65224_ldo2_irq_types[] = {363	{ TPS65224_IRQ_NAME_LDO2_UVOV, "LDO2", "voltage out of range",364	  REGULATOR_EVENT_REGULATION_OUT },365};366 367static struct tps6594_regulator_irq_type tps65224_ldo3_irq_types[] = {368	{ TPS65224_IRQ_NAME_LDO3_UVOV, "LDO3", "voltage out of range",369	  REGULATOR_EVENT_REGULATION_OUT },370};371 372static struct tps6594_regulator_irq_type *tps6594_bucks_irq_types[] = {373	tps6594_buck1_irq_types,374	tps6594_buck2_irq_types,375	tps6594_buck3_irq_types,376	tps6594_buck4_irq_types,377	tps6594_buck5_irq_types,378};379 380static struct tps6594_regulator_irq_type *tps6594_ldos_irq_types[] = {381	tps6594_ldo1_irq_types,382	tps6594_ldo2_irq_types,383	tps6594_ldo3_irq_types,384	tps6594_ldo4_irq_types,385};386 387static struct tps6594_regulator_irq_type *tps65224_bucks_irq_types[] = {388	tps65224_buck1_irq_types,389	tps65224_buck2_irq_types,390	tps65224_buck3_irq_types,391	tps65224_buck4_irq_types,392};393 394static struct tps6594_regulator_irq_type *tps65224_ldos_irq_types[] = {395	tps65224_ldo1_irq_types,396	tps65224_ldo2_irq_types,397	tps65224_ldo3_irq_types,398};399 400static const struct regulator_desc tps6594_multi_regs[] = {401	TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,402			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,403			  TPS6594_REG_BUCKX_VOUT_1(0),404			  TPS6594_MASK_BUCKS_VSET,405			  TPS6594_REG_BUCKX_CTRL(0),406			  TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,407			  4, 4000, 0, NULL, 0, 0),408	TPS6594_REGULATOR("BUCK34", "buck34", TPS6594_BUCK_3,409			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,410			  TPS6594_REG_BUCKX_VOUT_1(2),411			  TPS6594_MASK_BUCKS_VSET,412			  TPS6594_REG_BUCKX_CTRL(2),413			  TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,414			  4, 0, 0, NULL, 0, 0),415	TPS6594_REGULATOR("BUCK123", "buck123", TPS6594_BUCK_1,416			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,417			  TPS6594_REG_BUCKX_VOUT_1(0),418			  TPS6594_MASK_BUCKS_VSET,419			  TPS6594_REG_BUCKX_CTRL(0),420			  TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,421			  4, 4000, 0, NULL, 0, 0),422	TPS6594_REGULATOR("BUCK1234", "buck1234", TPS6594_BUCK_1,423			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,424			  TPS6594_REG_BUCKX_VOUT_1(0),425			  TPS6594_MASK_BUCKS_VSET,426			  TPS6594_REG_BUCKX_CTRL(0),427			  TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,428			  4, 4000, 0, NULL, 0, 0),429};430 431static const struct regulator_desc tps65224_multi_regs[] = {432	TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,433			  REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,434			  TPS6594_REG_BUCKX_VOUT_1(0),435			  TPS65224_MASK_BUCK1_VSET,436			  TPS6594_REG_BUCKX_CTRL(0),437			  TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,438			  4, 4000, 0, NULL, 0, 0),439};440 441static const struct regulator_desc tps6594_ldo_regs[] = {442	TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,443			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,444			  TPS6594_REG_LDOX_VOUT(0),445			  TPS6594_MASK_LDO123_VSET,446			  TPS6594_REG_LDOX_CTRL(0),447			  TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,448			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),449	TPS6594_REGULATOR("LDO2", "ldo2", TPS6594_LDO_2,450			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,451			  TPS6594_REG_LDOX_VOUT(1),452			  TPS6594_MASK_LDO123_VSET,453			  TPS6594_REG_LDOX_CTRL(1),454			  TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,455			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),456	TPS6594_REGULATOR("LDO3", "ldo3", TPS6594_LDO_3,457			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,458			  TPS6594_REG_LDOX_VOUT(2),459			  TPS6594_MASK_LDO123_VSET,460			  TPS6594_REG_LDOX_CTRL(2),461			  TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,462			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),463	TPS6594_REGULATOR("LDO4", "ldo4", TPS6594_LDO_4,464			  REGULATOR_VOLTAGE, tps6594_ldos_4_ops, TPS6594_MASK_LDO4_VSET >> 1,465			  TPS6594_REG_LDOX_VOUT(3),466			  TPS6594_MASK_LDO4_VSET,467			  TPS6594_REG_LDOX_CTRL(3),468			  TPS6594_BIT_LDO_EN, 0, 0, ldos_4_ranges,469			  1, 0, 0, NULL, 0, 0),470};471 472static const struct regulator_desc tps65224_ldo_regs[] = {473	TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,474			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,475			  TPS6594_REG_LDOX_VOUT(0),476			  TPS6594_MASK_LDO123_VSET,477			  TPS6594_REG_LDOX_CTRL(0),478			  TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_1_ranges,479			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),480	TPS6594_REGULATOR("LDO2", "ldo2", TPS6594_LDO_2,481			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,482			  TPS6594_REG_LDOX_VOUT(1),483			  TPS6594_MASK_LDO123_VSET,484			  TPS6594_REG_LDOX_CTRL(1),485			  TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,486			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),487	TPS6594_REGULATOR("LDO3", "ldo3", TPS6594_LDO_3,488			  REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,489			  TPS6594_REG_LDOX_VOUT(2),490			  TPS6594_MASK_LDO123_VSET,491			  TPS6594_REG_LDOX_CTRL(2),492			  TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,493			  1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),494};495 496static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data)497{498	struct tps6594_regulator_irq_data *irq_data = data;499 500	if (irq_data->type->event_name[0] == '\0') {501		/* This is the timeout interrupt no specific regulator */502		dev_err(irq_data->dev,503			"System was put in shutdown due to timeout during an active or standby transition.\n");504		return IRQ_HANDLED;505	}506 507	dev_err(irq_data->dev, "Error IRQ trap %s for %s\n",508		irq_data->type->event_name, irq_data->type->regulator_name);509 510	regulator_notifier_call_chain(irq_data->rdev,511				      irq_data->type->event, NULL);512 513	return IRQ_HANDLED;514}515 516static int tps6594_request_reg_irqs(struct platform_device *pdev,517				    struct regulator_dev *rdev,518				    struct tps6594_regulator_irq_data *irq_data,519				    struct tps6594_regulator_irq_type *regs_irq_types,520				    size_t interrupt_cnt,521				    int *irq_idx)522{523	struct tps6594_regulator_irq_type *irq_type;524	struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);525	size_t j;526	int irq;527	int error;528 529	for (j = 0; j < interrupt_cnt; j++) {530		irq_type = &regs_irq_types[j];531		irq = platform_get_irq_byname(pdev, irq_type->irq_name);532		if (irq < 0)533			return -EINVAL;534 535		irq_data[*irq_idx].dev = tps->dev;536		irq_data[*irq_idx].type = irq_type;537		irq_data[*irq_idx].rdev = rdev;538 539		error = devm_request_threaded_irq(tps->dev, irq, NULL,540						  tps6594_regulator_irq_handler, IRQF_ONESHOT,541						  irq_type->irq_name, &irq_data[*irq_idx]);542		if (error) {543			dev_err(tps->dev, "tps6594 failed to request %s IRQ %d: %d\n",544				irq_type->irq_name, irq, error);545			return error;546		}547		(*irq_idx)++;548	}549	return 0;550}551 552static int tps6594_regulator_probe(struct platform_device *pdev)553{554	struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);555	struct regulator_dev *rdev;556	struct device_node *np = NULL;557	struct device_node *np_pmic_parent = NULL;558	struct regulator_config config = {};559	struct tps6594_regulator_irq_data *irq_data;560	struct tps6594_ext_regulator_irq_data *irq_ext_reg_data;561	struct tps6594_regulator_irq_type *irq_type;562	struct tps6594_regulator_irq_type *irq_types;563	bool buck_configured[BUCK_NB] = { false };564	bool buck_multi[MULTI_PHASE_NB] = { false };565 566	static const char *npname;567	int error, i, irq, multi;568	int irq_idx = 0;569	int buck_idx = 0;570	int nr_ldo;571	int nr_buck;572	int nr_types;573	unsigned int irq_count;574	unsigned int multi_phase_cnt;575	size_t reg_irq_nb;576	struct tps6594_regulator_irq_type **bucks_irq_types;577	const struct regulator_desc *multi_regs;578	struct tps6594_regulator_irq_type **ldos_irq_types;579	const struct regulator_desc *ldo_regs;580	size_t interrupt_count;581 582	if (tps->chip_id == TPS65224) {583		bucks_irq_types = tps65224_bucks_irq_types;584		interrupt_count = ARRAY_SIZE(tps65224_buck1_irq_types);585		multi_regs = tps65224_multi_regs;586		ldos_irq_types = tps65224_ldos_irq_types;587		ldo_regs = tps65224_ldo_regs;588		multi_phase_cnt = ARRAY_SIZE(tps65224_multi_regs);589	} else {590		bucks_irq_types = tps6594_bucks_irq_types;591		interrupt_count = ARRAY_SIZE(tps6594_buck1_irq_types);592		multi_regs = tps6594_multi_regs;593		ldos_irq_types = tps6594_ldos_irq_types;594		ldo_regs = tps6594_ldo_regs;595		multi_phase_cnt = ARRAY_SIZE(tps6594_multi_regs);596	}597 598	enum {599		MULTI_BUCK12,600		MULTI_BUCK12_34,601		MULTI_BUCK123,602		MULTI_BUCK1234,603	};604 605	config.dev = tps->dev;606	config.driver_data = tps;607	config.regmap = tps->regmap;608 609	/*610	 * Switch case defines different possible multi phase config611	 * This is based on dts buck node name.612	 * Buck node name must be chosen accordingly.613	 * Default case is no Multiphase buck.614	 * In case of Multiphase configuration, value should be defined for615	 * buck_configured to avoid creating bucks for every buck in multiphase616	 */617	for (multi = 0; multi < multi_phase_cnt; multi++) {618		np = of_find_node_by_name(tps->dev->of_node, multi_regs[multi].supply_name);619		npname = of_node_full_name(np);620		np_pmic_parent = of_get_parent(of_get_parent(np));621		if (of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name))622			continue;623		if (strcmp(npname, multi_regs[multi].supply_name) == 0) {624			switch (multi) {625			case MULTI_BUCK12:626				buck_multi[0] = true;627				buck_configured[0] = true;628				buck_configured[1] = true;629				break;630			/* multiphase buck34 is supported only with buck12 */631			case MULTI_BUCK12_34:632				buck_multi[0] = true;633				buck_multi[1] = true;634				buck_configured[0] = true;635				buck_configured[1] = true;636				buck_configured[2] = true;637				buck_configured[3] = true;638				break;639			case MULTI_BUCK123:640				buck_multi[2] = true;641				buck_configured[0] = true;642				buck_configured[1] = true;643				buck_configured[2] = true;644				break;645			case MULTI_BUCK1234:646				buck_multi[3] = true;647				buck_configured[0] = true;648				buck_configured[1] = true;649				buck_configured[2] = true;650				buck_configured[3] = true;651				break;652			}653		}654	}655 656	if (tps->chip_id == TPS65224) {657		nr_buck = ARRAY_SIZE(tps65224_buck_regs);658		nr_ldo = ARRAY_SIZE(tps65224_ldo_regs);659		nr_types = TPS65224_REGS_INT_NB;660	} else {661		nr_buck = ARRAY_SIZE(buck_regs);662		nr_ldo = (tps->chip_id == LP8764) ? 0 : ARRAY_SIZE(tps6594_ldo_regs);663		nr_types = REGS_INT_NB;664	}665 666	reg_irq_nb = nr_types * (nr_buck + nr_ldo);667 668	irq_data = devm_kmalloc_array(tps->dev, reg_irq_nb,669				      sizeof(struct tps6594_regulator_irq_data), GFP_KERNEL);670	if (!irq_data)671		return -ENOMEM;672 673	for (i = 0; i < multi_phase_cnt; i++) {674		if (!buck_multi[i])675			continue;676 677		rdev = devm_regulator_register(&pdev->dev, &multi_regs[i], &config);678		if (IS_ERR(rdev))679			return dev_err_probe(tps->dev, PTR_ERR(rdev),680					     "failed to register %s regulator\n",681					     pdev->name);682 683		/* config multiphase buck12+buck34 */684		if (i == MULTI_BUCK12_34)685			buck_idx = 2;686 687		error = tps6594_request_reg_irqs(pdev, rdev, irq_data,688						 bucks_irq_types[buck_idx],689						 interrupt_count, &irq_idx);690		if (error)691			return error;692 693		error = tps6594_request_reg_irqs(pdev, rdev, irq_data,694						 bucks_irq_types[buck_idx + 1],695						 interrupt_count, &irq_idx);696		if (error)697			return error;698 699		if (i == MULTI_BUCK123 || i == MULTI_BUCK1234) {700			error = tps6594_request_reg_irqs(pdev, rdev, irq_data,701							 tps6594_bucks_irq_types[buck_idx + 2],702							 interrupt_count,703							 &irq_idx);704			if (error)705				return error;706		}707		if (i == MULTI_BUCK1234) {708			error = tps6594_request_reg_irqs(pdev, rdev, irq_data,709							 tps6594_bucks_irq_types[buck_idx + 3],710							 interrupt_count,711							 &irq_idx);712			if (error)713				return error;714		}715	}716 717	for (i = 0; i < nr_buck; i++) {718		if (buck_configured[i])719			continue;720 721		const struct regulator_desc *buck_cfg = (tps->chip_id == TPS65224) ?722							 tps65224_buck_regs : buck_regs;723 724		rdev = devm_regulator_register(&pdev->dev, &buck_cfg[i], &config);725		if (IS_ERR(rdev))726			return dev_err_probe(tps->dev, PTR_ERR(rdev),727					     "failed to register %s regulator\n", pdev->name);728 729		error = tps6594_request_reg_irqs(pdev, rdev, irq_data,730						 bucks_irq_types[i], interrupt_count, &irq_idx);731		if (error)732			return error;733	}734 735	/* LP8764 doesn't have LDO */736	if (tps->chip_id != LP8764) {737		for (i = 0; i < nr_ldo; i++) {738			rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config);739			if (IS_ERR(rdev))740				return dev_err_probe(tps->dev, PTR_ERR(rdev),741						     "failed to register %s regulator\n",742						     pdev->name);743 744			error = tps6594_request_reg_irqs(pdev, rdev, irq_data,745							 ldos_irq_types[i], interrupt_count,746							 &irq_idx);747			if (error)748				return error;749		}750	}751 752	if (tps->chip_id == TPS65224) {753		irq_types = tps65224_ext_regulator_irq_types;754		irq_count = ARRAY_SIZE(tps65224_ext_regulator_irq_types);755	} else {756		irq_types = tps6594_ext_regulator_irq_types;757		if (tps->chip_id == LP8764)758			irq_count = ARRAY_SIZE(tps6594_ext_regulator_irq_types);759		else760			/* TPS6593 supports only VCCA OV and UV */761			irq_count = 2;762	}763 764	irq_ext_reg_data = devm_kmalloc_array(tps->dev,765					      irq_count,766					      sizeof(struct tps6594_ext_regulator_irq_data),767					      GFP_KERNEL);768	if (!irq_ext_reg_data)769		return -ENOMEM;770 771	for (i = 0; i < irq_count; ++i) {772		irq_type = &irq_types[i];773		irq = platform_get_irq_byname(pdev, irq_type->irq_name);774		if (irq < 0)775			return -EINVAL;776 777		irq_ext_reg_data[i].dev = tps->dev;778		irq_ext_reg_data[i].type = irq_type;779 780		error = devm_request_threaded_irq(tps->dev, irq, NULL,781						  tps6594_regulator_irq_handler,782						  IRQF_ONESHOT,783						  irq_type->irq_name,784						  &irq_ext_reg_data[i]);785		if (error)786			return dev_err_probe(tps->dev, error,787					     "failed to request %s IRQ %d\n",788					     irq_type->irq_name, irq);789	}790	return 0;791}792 793static struct platform_driver tps6594_regulator_driver = {794	.driver = {795		.name = "tps6594-regulator",796	},797	.probe = tps6594_regulator_probe,798};799 800module_platform_driver(tps6594_regulator_driver);801 802MODULE_ALIAS("platform:tps6594-regulator");803MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");804MODULE_AUTHOR("Nirmala Devi Mal Nadar <m.nirmaladevi@ltts.com>");805MODULE_DESCRIPTION("TPS6594 voltage regulator driver");806MODULE_LICENSE("GPL");807