xref: /openbmc/linux/drivers/mfd/tps65219.c (revision 3df4c636)
174c17a0aSJerome Neanne // SPDX-License-Identifier: GPL-2.0
274c17a0aSJerome Neanne //
374c17a0aSJerome Neanne // Driver for TPS65219 Integrated Power Management Integrated Chips (PMIC)
474c17a0aSJerome Neanne //
574c17a0aSJerome Neanne // Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
674c17a0aSJerome Neanne 
774c17a0aSJerome Neanne #include <linux/i2c.h>
874c17a0aSJerome Neanne #include <linux/reboot.h>
974c17a0aSJerome Neanne #include <linux/regmap.h>
1074c17a0aSJerome Neanne 
1174c17a0aSJerome Neanne #include <linux/mfd/core.h>
1274c17a0aSJerome Neanne #include <linux/mfd/tps65219.h>
1374c17a0aSJerome Neanne 
tps65219_warm_reset(struct tps65219 * tps)1474c17a0aSJerome Neanne static int tps65219_warm_reset(struct tps65219 *tps)
1574c17a0aSJerome Neanne {
1674c17a0aSJerome Neanne 	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
1774c17a0aSJerome Neanne 				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK,
1874c17a0aSJerome Neanne 				  TPS65219_MFP_WARM_RESET_I2C_CTRL_MASK);
1974c17a0aSJerome Neanne }
2074c17a0aSJerome Neanne 
tps65219_cold_reset(struct tps65219 * tps)2174c17a0aSJerome Neanne static int tps65219_cold_reset(struct tps65219 *tps)
2274c17a0aSJerome Neanne {
2374c17a0aSJerome Neanne 	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
2474c17a0aSJerome Neanne 				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK,
2574c17a0aSJerome Neanne 				  TPS65219_MFP_COLD_RESET_I2C_CTRL_MASK);
2674c17a0aSJerome Neanne }
2774c17a0aSJerome Neanne 
tps65219_soft_shutdown(struct tps65219 * tps)28*3df4c636SJerome Neanne static int tps65219_soft_shutdown(struct tps65219 *tps)
2974c17a0aSJerome Neanne {
30*3df4c636SJerome Neanne 	return regmap_update_bits(tps->regmap, TPS65219_REG_MFP_CTRL,
31*3df4c636SJerome Neanne 				  TPS65219_MFP_I2C_OFF_REQ_MASK,
32*3df4c636SJerome Neanne 				  TPS65219_MFP_I2C_OFF_REQ_MASK);
33*3df4c636SJerome Neanne }
3474c17a0aSJerome Neanne 
tps65219_power_off_handler(struct sys_off_data * data)35*3df4c636SJerome Neanne static int tps65219_power_off_handler(struct sys_off_data *data)
36*3df4c636SJerome Neanne {
37*3df4c636SJerome Neanne 	tps65219_soft_shutdown(data->cb_data);
38*3df4c636SJerome Neanne 	return NOTIFY_DONE;
39*3df4c636SJerome Neanne }
4074c17a0aSJerome Neanne 
tps65219_restart(struct tps65219 * tps,unsigned long reboot_mode)41*3df4c636SJerome Neanne static int tps65219_restart(struct tps65219 *tps, unsigned long reboot_mode)
42*3df4c636SJerome Neanne {
4374c17a0aSJerome Neanne 	if (reboot_mode == REBOOT_WARM)
4474c17a0aSJerome Neanne 		tps65219_warm_reset(tps);
4574c17a0aSJerome Neanne 	else
4674c17a0aSJerome Neanne 		tps65219_cold_reset(tps);
4774c17a0aSJerome Neanne 
4874c17a0aSJerome Neanne 	return NOTIFY_DONE;
4974c17a0aSJerome Neanne }
5074c17a0aSJerome Neanne 
tps65219_restart_handler(struct sys_off_data * data)51*3df4c636SJerome Neanne static int tps65219_restart_handler(struct sys_off_data *data)
52*3df4c636SJerome Neanne {
53*3df4c636SJerome Neanne 	tps65219_restart(data->cb_data, data->mode);
54*3df4c636SJerome Neanne 	return NOTIFY_DONE;
55*3df4c636SJerome Neanne }
5674c17a0aSJerome Neanne 
5774c17a0aSJerome Neanne static const struct resource tps65219_pwrbutton_resources[] = {
5874c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_FALLING_EDGE_DETECT, "falling"),
5974c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_RISING_EDGE_DETECT, "rising"),
6074c17a0aSJerome Neanne };
6174c17a0aSJerome Neanne 
6274c17a0aSJerome Neanne static const struct resource tps65219_regulator_resources[] = {
6374c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_SCG, "LDO3_SCG"),
6474c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_OC, "LDO3_OC"),
6574c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_UV, "LDO3_UV"),
6674c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_SCG, "LDO4_SCG"),
6774c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_OC, "LDO4_OC"),
6874c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_UV, "LDO4_UV"),
6974c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_SCG, "LDO1_SCG"),
7074c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_OC, "LDO1_OC"),
7174c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_UV, "LDO1_UV"),
7274c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_SCG, "LDO2_SCG"),
7374c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_OC, "LDO2_OC"),
7474c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_UV, "LDO2_UV"),
7574c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
7674c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
7774c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
7874c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
7974c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
8074c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
8174c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
8274c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
8374c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
8474c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
8574c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
8674c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
8774c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
8874c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
8974c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
9074c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
9174c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV, "LDO2_RV"),
9274c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV, "LDO3_RV"),
9374c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV, "LDO4_RV"),
9474c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
9574c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
9674c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
9774c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV_SD, "LDO1_RV_SD"),
9874c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV_SD, "LDO2_RV_SD"),
9974c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_RV_SD, "LDO3_RV_SD"),
10074c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO4_RV_SD, "LDO4_RV_SD"),
10174c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
10274c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_WARM, "SENSOR_3_WARM"),
10374c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
10474c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
10574c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
10674c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_HOT, "SENSOR_3_HOT"),
10774c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
10874c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
10974c17a0aSJerome Neanne 	DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
11074c17a0aSJerome Neanne };
11174c17a0aSJerome Neanne 
11274c17a0aSJerome Neanne static const struct mfd_cell tps65219_cells[] = {
11374c17a0aSJerome Neanne 	{
11474c17a0aSJerome Neanne 		.name = "tps65219-regulator",
11574c17a0aSJerome Neanne 		.resources = tps65219_regulator_resources,
11674c17a0aSJerome Neanne 		.num_resources = ARRAY_SIZE(tps65219_regulator_resources),
11774c17a0aSJerome Neanne 	},
11829e92d8eSJerome Neanne 	{ .name = "tps65219-gpio", },
11974c17a0aSJerome Neanne };
12074c17a0aSJerome Neanne 
12174c17a0aSJerome Neanne static const struct mfd_cell tps65219_pwrbutton_cell = {
12274c17a0aSJerome Neanne 	.name = "tps65219-pwrbutton",
12374c17a0aSJerome Neanne 	.resources = tps65219_pwrbutton_resources,
12474c17a0aSJerome Neanne 	.num_resources = ARRAY_SIZE(tps65219_pwrbutton_resources),
12574c17a0aSJerome Neanne };
12674c17a0aSJerome Neanne 
12774c17a0aSJerome Neanne static const struct regmap_config tps65219_regmap_config = {
12874c17a0aSJerome Neanne 	.reg_bits = 8,
12974c17a0aSJerome Neanne 	.val_bits = 8,
13074c17a0aSJerome Neanne 	.max_register = TPS65219_REG_FACTORY_CONFIG_2,
13174c17a0aSJerome Neanne };
13274c17a0aSJerome Neanne 
13374c17a0aSJerome Neanne /*
13474c17a0aSJerome Neanne  * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can
13574c17a0aSJerome Neanne  * access corect sub-IRQ registers based on bits that are set in main IRQ
13674c17a0aSJerome Neanne  * register.
13774c17a0aSJerome Neanne  */
13874c17a0aSJerome Neanne /* Timeout Residual Voltage Shutdown */
13974c17a0aSJerome Neanne static unsigned int bit0_offsets[] = { TPS65219_REG_INT_TO_RV_POS };
14074c17a0aSJerome Neanne static unsigned int bit1_offsets[] = { TPS65219_REG_INT_RV_POS };	/* Residual Voltage */
14174c17a0aSJerome Neanne static unsigned int bit2_offsets[] = { TPS65219_REG_INT_SYS_POS };	/* System */
14274c17a0aSJerome Neanne static unsigned int bit3_offsets[] = { TPS65219_REG_INT_BUCK_1_2_POS };	/* Buck 1-2 */
14374c17a0aSJerome Neanne static unsigned int bit4_offsets[] = { TPS65219_REG_INT_BUCK_3_POS };	/* Buck 3 */
14474c17a0aSJerome Neanne static unsigned int bit5_offsets[] = { TPS65219_REG_INT_LDO_1_2_POS };	/* LDO 1-2 */
14574c17a0aSJerome Neanne static unsigned int bit6_offsets[] = { TPS65219_REG_INT_LDO_3_4_POS };	/* LDO 3-4 */
14674c17a0aSJerome Neanne static unsigned int bit7_offsets[] = { TPS65219_REG_INT_PB_POS };	/* Power Button */
14774c17a0aSJerome Neanne 
14874c17a0aSJerome Neanne static struct regmap_irq_sub_irq_map tps65219_sub_irq_offsets[] = {
14974c17a0aSJerome Neanne 	REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
15074c17a0aSJerome Neanne 	REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
15174c17a0aSJerome Neanne 	REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
15274c17a0aSJerome Neanne 	REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
15374c17a0aSJerome Neanne 	REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
15474c17a0aSJerome Neanne 	REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
15574c17a0aSJerome Neanne 	REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
15674c17a0aSJerome Neanne 	REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
15774c17a0aSJerome Neanne };
15874c17a0aSJerome Neanne 
15974c17a0aSJerome Neanne #define TPS65219_REGMAP_IRQ_REG(int_name, register_position) \
16074c17a0aSJerome Neanne 	REGMAP_IRQ_REG(int_name, register_position, int_name##_MASK)
16174c17a0aSJerome Neanne 
16274c17a0aSJerome Neanne static struct regmap_irq tps65219_irqs[] = {
16374c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_SCG, TPS65219_REG_INT_LDO_3_4_POS),
16474c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_OC, TPS65219_REG_INT_LDO_3_4_POS),
16574c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_UV, TPS65219_REG_INT_LDO_3_4_POS),
16674c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_SCG, TPS65219_REG_INT_LDO_3_4_POS),
16774c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_OC, TPS65219_REG_INT_LDO_3_4_POS),
16874c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_UV, TPS65219_REG_INT_LDO_3_4_POS),
16974c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_SCG, TPS65219_REG_INT_LDO_1_2_POS),
17074c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_OC, TPS65219_REG_INT_LDO_1_2_POS),
17174c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_UV, TPS65219_REG_INT_LDO_1_2_POS),
17274c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_SCG, TPS65219_REG_INT_LDO_1_2_POS),
17374c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_OC, TPS65219_REG_INT_LDO_1_2_POS),
17474c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_UV, TPS65219_REG_INT_LDO_1_2_POS),
17574c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65219_REG_INT_BUCK_3_POS),
17674c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65219_REG_INT_BUCK_3_POS),
17774c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65219_REG_INT_BUCK_3_POS),
17874c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65219_REG_INT_BUCK_3_POS),
17974c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65219_REG_INT_BUCK_1_2_POS),
18074c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65219_REG_INT_BUCK_1_2_POS),
18174c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65219_REG_INT_BUCK_1_2_POS),
18274c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65219_REG_INT_BUCK_1_2_POS),
18374c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65219_REG_INT_BUCK_1_2_POS),
18474c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65219_REG_INT_BUCK_1_2_POS),
18574c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65219_REG_INT_BUCK_1_2_POS),
18674c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65219_REG_INT_BUCK_1_2_POS),
18774c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_WARM, TPS65219_REG_INT_SYS_POS),
18874c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65219_REG_INT_SYS_POS),
18974c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65219_REG_INT_SYS_POS),
19074c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65219_REG_INT_SYS_POS),
19174c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_HOT, TPS65219_REG_INT_SYS_POS),
19274c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65219_REG_INT_SYS_POS),
19374c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65219_REG_INT_SYS_POS),
19474c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65219_REG_INT_SYS_POS),
19574c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65219_REG_INT_RV_POS),
19674c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65219_REG_INT_RV_POS),
19774c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65219_REG_INT_RV_POS),
19874c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65219_REG_INT_RV_POS),
19974c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV, TPS65219_REG_INT_RV_POS),
20074c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV, TPS65219_REG_INT_RV_POS),
20174c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV, TPS65219_REG_INT_RV_POS),
20274c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD, TPS65219_REG_INT_TO_RV_POS),
20374c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD, TPS65219_REG_INT_TO_RV_POS),
20474c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65219_REG_INT_TO_RV_POS),
20574c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV_SD, TPS65219_REG_INT_TO_RV_POS),
20674c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV_SD, TPS65219_REG_INT_TO_RV_POS),
20774c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_RV_SD, TPS65219_REG_INT_TO_RV_POS),
20874c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO4_RV_SD, TPS65219_REG_INT_TO_RV_POS),
20974c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65219_REG_INT_TO_RV_POS),
21074c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
21174c17a0aSJerome Neanne 	TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
21274c17a0aSJerome Neanne };
21374c17a0aSJerome Neanne 
21474c17a0aSJerome Neanne static struct regmap_irq_chip tps65219_irq_chip = {
21574c17a0aSJerome Neanne 	.name = "tps65219_irq",
21674c17a0aSJerome Neanne 	.main_status = TPS65219_REG_INT_SOURCE,
21774c17a0aSJerome Neanne 	.num_main_regs = 1,
21874c17a0aSJerome Neanne 	.num_main_status_bits = 8,
21974c17a0aSJerome Neanne 	.irqs = tps65219_irqs,
22074c17a0aSJerome Neanne 	.num_irqs = ARRAY_SIZE(tps65219_irqs),
22174c17a0aSJerome Neanne 	.status_base = TPS65219_REG_INT_LDO_3_4,
22274c17a0aSJerome Neanne 	.ack_base = TPS65219_REG_INT_LDO_3_4,
22374c17a0aSJerome Neanne 	.clear_ack = 1,
22474c17a0aSJerome Neanne 	.num_regs = 8,
22574c17a0aSJerome Neanne 	.sub_reg_offsets = tps65219_sub_irq_offsets,
22674c17a0aSJerome Neanne };
22774c17a0aSJerome Neanne 
tps65219_probe(struct i2c_client * client)22874c17a0aSJerome Neanne static int tps65219_probe(struct i2c_client *client)
22974c17a0aSJerome Neanne {
23074c17a0aSJerome Neanne 	struct tps65219 *tps;
23174c17a0aSJerome Neanne 	unsigned int chipid;
23274c17a0aSJerome Neanne 	bool pwr_button;
23374c17a0aSJerome Neanne 	int ret;
23474c17a0aSJerome Neanne 
23574c17a0aSJerome Neanne 	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
23674c17a0aSJerome Neanne 	if (!tps)
23774c17a0aSJerome Neanne 		return -ENOMEM;
23874c17a0aSJerome Neanne 
23974c17a0aSJerome Neanne 	i2c_set_clientdata(client, tps);
24074c17a0aSJerome Neanne 
24174c17a0aSJerome Neanne 	tps->dev = &client->dev;
24274c17a0aSJerome Neanne 
24374c17a0aSJerome Neanne 	tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
24474c17a0aSJerome Neanne 	if (IS_ERR(tps->regmap)) {
24574c17a0aSJerome Neanne 		ret = PTR_ERR(tps->regmap);
24674c17a0aSJerome Neanne 		dev_err(tps->dev, "Failed to allocate register map: %d\n", ret);
24774c17a0aSJerome Neanne 		return ret;
24874c17a0aSJerome Neanne 	}
24974c17a0aSJerome Neanne 
25074c17a0aSJerome Neanne 	ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, client->irq,
25174c17a0aSJerome Neanne 				       IRQF_ONESHOT, 0, &tps65219_irq_chip,
25274c17a0aSJerome Neanne 				       &tps->irq_data);
25374c17a0aSJerome Neanne 	if (ret)
25474c17a0aSJerome Neanne 		return ret;
25574c17a0aSJerome Neanne 
25674c17a0aSJerome Neanne 	ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
25774c17a0aSJerome Neanne 	if (ret) {
25874c17a0aSJerome Neanne 		dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
25974c17a0aSJerome Neanne 		return ret;
26074c17a0aSJerome Neanne 	}
26174c17a0aSJerome Neanne 
26274c17a0aSJerome Neanne 	ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO,
26374c17a0aSJerome Neanne 				   tps65219_cells, ARRAY_SIZE(tps65219_cells),
26474c17a0aSJerome Neanne 				   NULL, 0, regmap_irq_get_domain(tps->irq_data));
26574c17a0aSJerome Neanne 	if (ret) {
26674c17a0aSJerome Neanne 		dev_err(tps->dev, "Failed to add child devices: %d\n", ret);
26774c17a0aSJerome Neanne 		return ret;
26874c17a0aSJerome Neanne 	}
26974c17a0aSJerome Neanne 
27074c17a0aSJerome Neanne 	pwr_button = of_property_read_bool(tps->dev->of_node, "ti,power-button");
27174c17a0aSJerome Neanne 	if (pwr_button) {
27274c17a0aSJerome Neanne 		ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO,
27374c17a0aSJerome Neanne 					   &tps65219_pwrbutton_cell, 1, NULL, 0,
27474c17a0aSJerome Neanne 					   regmap_irq_get_domain(tps->irq_data));
27574c17a0aSJerome Neanne 		if (ret) {
27674c17a0aSJerome Neanne 			dev_err(tps->dev, "Failed to add power-button: %d\n", ret);
27774c17a0aSJerome Neanne 			return ret;
27874c17a0aSJerome Neanne 		}
27974c17a0aSJerome Neanne 	}
28074c17a0aSJerome Neanne 
281*3df4c636SJerome Neanne 	ret = devm_register_restart_handler(tps->dev,
282*3df4c636SJerome Neanne 					    tps65219_restart_handler,
283*3df4c636SJerome Neanne 					    tps);
284*3df4c636SJerome Neanne 
28574c17a0aSJerome Neanne 	if (ret) {
28674c17a0aSJerome Neanne 		dev_err(tps->dev, "cannot register restart handler, %d\n", ret);
28774c17a0aSJerome Neanne 		return ret;
28874c17a0aSJerome Neanne 	}
28974c17a0aSJerome Neanne 
290*3df4c636SJerome Neanne 	ret = devm_register_power_off_handler(tps->dev,
291*3df4c636SJerome Neanne 					      tps65219_power_off_handler,
292*3df4c636SJerome Neanne 					      tps);
293*3df4c636SJerome Neanne 	if (ret) {
294*3df4c636SJerome Neanne 		dev_err(tps->dev, "failed to register power-off handler: %d\n", ret);
295*3df4c636SJerome Neanne 		return ret;
296*3df4c636SJerome Neanne 	}
29774c17a0aSJerome Neanne 	return 0;
29874c17a0aSJerome Neanne }
29974c17a0aSJerome Neanne 
30074c17a0aSJerome Neanne static const struct of_device_id of_tps65219_match_table[] = {
30174c17a0aSJerome Neanne 	{ .compatible = "ti,tps65219", },
30274c17a0aSJerome Neanne 	{}
30374c17a0aSJerome Neanne };
30474c17a0aSJerome Neanne MODULE_DEVICE_TABLE(of, of_tps65219_match_table);
30574c17a0aSJerome Neanne 
30674c17a0aSJerome Neanne static struct i2c_driver tps65219_driver = {
30774c17a0aSJerome Neanne 	.driver		= {
30874c17a0aSJerome Neanne 		.name	= "tps65219",
30974c17a0aSJerome Neanne 		.of_match_table = of_tps65219_match_table,
31074c17a0aSJerome Neanne 	},
3119816d859SUwe Kleine-König 	.probe		= tps65219_probe,
31274c17a0aSJerome Neanne };
31374c17a0aSJerome Neanne module_i2c_driver(tps65219_driver);
31474c17a0aSJerome Neanne 
31574c17a0aSJerome Neanne MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
31674c17a0aSJerome Neanne MODULE_DESCRIPTION("TPS65219 power management IC driver");
31774c17a0aSJerome Neanne MODULE_LICENSE("GPL");
318