12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2518fb721SGraeme Gregory /*
3518fb721SGraeme Gregory  * tps65910.c  --  TI tps65910
4518fb721SGraeme Gregory  *
5518fb721SGraeme Gregory  * Copyright 2010 Texas Instruments Inc.
6518fb721SGraeme Gregory  *
7518fb721SGraeme Gregory  * Author: Graeme Gregory <gg@slimlogic.co.uk>
8518fb721SGraeme Gregory  * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
9518fb721SGraeme Gregory  */
10518fb721SGraeme Gregory 
11518fb721SGraeme Gregory #include <linux/kernel.h>
12518fb721SGraeme Gregory #include <linux/module.h>
13518fb721SGraeme Gregory #include <linux/init.h>
14518fb721SGraeme Gregory #include <linux/err.h>
15d16da513SGeert Uytterhoeven #include <linux/of.h>
16518fb721SGraeme Gregory #include <linux/platform_device.h>
17518fb721SGraeme Gregory #include <linux/regulator/driver.h>
18518fb721SGraeme Gregory #include <linux/regulator/machine.h>
19518fb721SGraeme Gregory #include <linux/slab.h>
20518fb721SGraeme Gregory #include <linux/mfd/tps65910.h>
216790178fSRhyland Klein #include <linux/regulator/of_regulator.h>
22518fb721SGraeme Gregory 
23518fb721SGraeme Gregory #define TPS65910_SUPPLY_STATE_ENABLED	0x1
241e0c66f4SLaxman Dewangan #define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 |	\
251e0c66f4SLaxman Dewangan 			TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 |		\
26f30b0716SLaxman Dewangan 			TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 |		\
27f30b0716SLaxman Dewangan 			TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP)
28518fb721SGraeme Gregory 
29d9fe28f9SAxel Lin /* supported VIO voltages in microvolts */
30d9fe28f9SAxel Lin static const unsigned int VIO_VSEL_table[] = {
31d9fe28f9SAxel Lin 	1500000, 1800000, 2500000, 3300000,
32518fb721SGraeme Gregory };
33518fb721SGraeme Gregory 
34a320e3c3SJorge Eduardo Candelaria /* VSEL tables for TPS65910 specific LDOs and dcdc's */
35a320e3c3SJorge Eduardo Candelaria 
36a9a5659aSAnilKumar Ch /* supported VRTC voltages in microvolts */
37a9a5659aSAnilKumar Ch static const unsigned int VRTC_VSEL_table[] = {
38a9a5659aSAnilKumar Ch 	1800000,
39a9a5659aSAnilKumar Ch };
40a9a5659aSAnilKumar Ch 
41d9fe28f9SAxel Lin /* supported VDD3 voltages in microvolts */
42d9fe28f9SAxel Lin static const unsigned int VDD3_VSEL_table[] = {
43d9fe28f9SAxel Lin 	5000000,
44518fb721SGraeme Gregory };
45518fb721SGraeme Gregory 
46d9fe28f9SAxel Lin /* supported VDIG1 voltages in microvolts */
47d9fe28f9SAxel Lin static const unsigned int VDIG1_VSEL_table[] = {
48d9fe28f9SAxel Lin 	1200000, 1500000, 1800000, 2700000,
49518fb721SGraeme Gregory };
50518fb721SGraeme Gregory 
51d9fe28f9SAxel Lin /* supported VDIG2 voltages in microvolts */
52d9fe28f9SAxel Lin static const unsigned int VDIG2_VSEL_table[] = {
53d9fe28f9SAxel Lin 	1000000, 1100000, 1200000, 1800000,
54518fb721SGraeme Gregory };
55518fb721SGraeme Gregory 
56d9fe28f9SAxel Lin /* supported VPLL voltages in microvolts */
57d9fe28f9SAxel Lin static const unsigned int VPLL_VSEL_table[] = {
58d9fe28f9SAxel Lin 	1000000, 1100000, 1800000, 2500000,
59518fb721SGraeme Gregory };
60518fb721SGraeme Gregory 
61d9fe28f9SAxel Lin /* supported VDAC voltages in microvolts */
62d9fe28f9SAxel Lin static const unsigned int VDAC_VSEL_table[] = {
63d9fe28f9SAxel Lin 	1800000, 2600000, 2800000, 2850000,
64518fb721SGraeme Gregory };
65518fb721SGraeme Gregory 
66d9fe28f9SAxel Lin /* supported VAUX1 voltages in microvolts */
67d9fe28f9SAxel Lin static const unsigned int VAUX1_VSEL_table[] = {
68d9fe28f9SAxel Lin 	1800000, 2500000, 2800000, 2850000,
69518fb721SGraeme Gregory };
70518fb721SGraeme Gregory 
71d9fe28f9SAxel Lin /* supported VAUX2 voltages in microvolts */
72d9fe28f9SAxel Lin static const unsigned int VAUX2_VSEL_table[] = {
73d9fe28f9SAxel Lin 	1800000, 2800000, 2900000, 3300000,
74518fb721SGraeme Gregory };
75518fb721SGraeme Gregory 
76d9fe28f9SAxel Lin /* supported VAUX33 voltages in microvolts */
77d9fe28f9SAxel Lin static const unsigned int VAUX33_VSEL_table[] = {
78d9fe28f9SAxel Lin 	1800000, 2000000, 2800000, 3300000,
79518fb721SGraeme Gregory };
80518fb721SGraeme Gregory 
81d9fe28f9SAxel Lin /* supported VMMC voltages in microvolts */
82d9fe28f9SAxel Lin static const unsigned int VMMC_VSEL_table[] = {
83d9fe28f9SAxel Lin 	1800000, 2800000, 3000000, 3300000,
84518fb721SGraeme Gregory };
85518fb721SGraeme Gregory 
8603746dcbSMarkus Pargmann /* supported BBCH voltages in microvolts */
8703746dcbSMarkus Pargmann static const unsigned int VBB_VSEL_table[] = {
8803746dcbSMarkus Pargmann 	3000000, 2520000, 3150000, 5000000,
8903746dcbSMarkus Pargmann };
9003746dcbSMarkus Pargmann 
91518fb721SGraeme Gregory struct tps_info {
92518fb721SGraeme Gregory 	const char *name;
9319228a6aSLaxman Dewangan 	const char *vin_name;
947d38a3cbSLaxman Dewangan 	u8 n_voltages;
95d9fe28f9SAxel Lin 	const unsigned int *voltage_table;
960651eed5SLaxman Dewangan 	int enable_time_us;
97518fb721SGraeme Gregory };
98518fb721SGraeme Gregory 
99518fb721SGraeme Gregory static struct tps_info tps65910_regs[] = {
100518fb721SGraeme Gregory 	{
10133a6943dSLaxman Dewangan 		.name = "vrtc",
10219228a6aSLaxman Dewangan 		.vin_name = "vcc7",
103a9a5659aSAnilKumar Ch 		.n_voltages = ARRAY_SIZE(VRTC_VSEL_table),
104a9a5659aSAnilKumar Ch 		.voltage_table = VRTC_VSEL_table,
1050651eed5SLaxman Dewangan 		.enable_time_us = 2200,
106518fb721SGraeme Gregory 	},
107518fb721SGraeme Gregory 	{
10833a6943dSLaxman Dewangan 		.name = "vio",
10919228a6aSLaxman Dewangan 		.vin_name = "vccio",
1107d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VIO_VSEL_table),
1117d38a3cbSLaxman Dewangan 		.voltage_table = VIO_VSEL_table,
1120651eed5SLaxman Dewangan 		.enable_time_us = 350,
113518fb721SGraeme Gregory 	},
114518fb721SGraeme Gregory 	{
11533a6943dSLaxman Dewangan 		.name = "vdd1",
11619228a6aSLaxman Dewangan 		.vin_name = "vcc1",
1170651eed5SLaxman Dewangan 		.enable_time_us = 350,
118518fb721SGraeme Gregory 	},
119518fb721SGraeme Gregory 	{
12033a6943dSLaxman Dewangan 		.name = "vdd2",
12119228a6aSLaxman Dewangan 		.vin_name = "vcc2",
1220651eed5SLaxman Dewangan 		.enable_time_us = 350,
123518fb721SGraeme Gregory 	},
124518fb721SGraeme Gregory 	{
12533a6943dSLaxman Dewangan 		.name = "vdd3",
1267d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VDD3_VSEL_table),
1277d38a3cbSLaxman Dewangan 		.voltage_table = VDD3_VSEL_table,
1280651eed5SLaxman Dewangan 		.enable_time_us = 200,
129518fb721SGraeme Gregory 	},
130518fb721SGraeme Gregory 	{
13133a6943dSLaxman Dewangan 		.name = "vdig1",
13219228a6aSLaxman Dewangan 		.vin_name = "vcc6",
1337d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VDIG1_VSEL_table),
1347d38a3cbSLaxman Dewangan 		.voltage_table = VDIG1_VSEL_table,
1350651eed5SLaxman Dewangan 		.enable_time_us = 100,
136518fb721SGraeme Gregory 	},
137518fb721SGraeme Gregory 	{
13833a6943dSLaxman Dewangan 		.name = "vdig2",
13919228a6aSLaxman Dewangan 		.vin_name = "vcc6",
1407d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VDIG2_VSEL_table),
1417d38a3cbSLaxman Dewangan 		.voltage_table = VDIG2_VSEL_table,
1420651eed5SLaxman Dewangan 		.enable_time_us = 100,
143518fb721SGraeme Gregory 	},
144518fb721SGraeme Gregory 	{
14533a6943dSLaxman Dewangan 		.name = "vpll",
14619228a6aSLaxman Dewangan 		.vin_name = "vcc5",
1477d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VPLL_VSEL_table),
1487d38a3cbSLaxman Dewangan 		.voltage_table = VPLL_VSEL_table,
1490651eed5SLaxman Dewangan 		.enable_time_us = 100,
150518fb721SGraeme Gregory 	},
151518fb721SGraeme Gregory 	{
15233a6943dSLaxman Dewangan 		.name = "vdac",
15319228a6aSLaxman Dewangan 		.vin_name = "vcc5",
1547d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VDAC_VSEL_table),
1557d38a3cbSLaxman Dewangan 		.voltage_table = VDAC_VSEL_table,
1560651eed5SLaxman Dewangan 		.enable_time_us = 100,
157518fb721SGraeme Gregory 	},
158518fb721SGraeme Gregory 	{
15933a6943dSLaxman Dewangan 		.name = "vaux1",
16019228a6aSLaxman Dewangan 		.vin_name = "vcc4",
1617d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VAUX1_VSEL_table),
1627d38a3cbSLaxman Dewangan 		.voltage_table = VAUX1_VSEL_table,
1630651eed5SLaxman Dewangan 		.enable_time_us = 100,
164518fb721SGraeme Gregory 	},
165518fb721SGraeme Gregory 	{
16633a6943dSLaxman Dewangan 		.name = "vaux2",
16719228a6aSLaxman Dewangan 		.vin_name = "vcc4",
1687d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VAUX2_VSEL_table),
1697d38a3cbSLaxman Dewangan 		.voltage_table = VAUX2_VSEL_table,
1700651eed5SLaxman Dewangan 		.enable_time_us = 100,
171518fb721SGraeme Gregory 	},
172518fb721SGraeme Gregory 	{
17333a6943dSLaxman Dewangan 		.name = "vaux33",
17419228a6aSLaxman Dewangan 		.vin_name = "vcc3",
1757d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VAUX33_VSEL_table),
1767d38a3cbSLaxman Dewangan 		.voltage_table = VAUX33_VSEL_table,
1770651eed5SLaxman Dewangan 		.enable_time_us = 100,
178518fb721SGraeme Gregory 	},
179518fb721SGraeme Gregory 	{
18033a6943dSLaxman Dewangan 		.name = "vmmc",
18119228a6aSLaxman Dewangan 		.vin_name = "vcc3",
1827d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VMMC_VSEL_table),
1837d38a3cbSLaxman Dewangan 		.voltage_table = VMMC_VSEL_table,
1840651eed5SLaxman Dewangan 		.enable_time_us = 100,
185518fb721SGraeme Gregory 	},
18603746dcbSMarkus Pargmann 	{
18703746dcbSMarkus Pargmann 		.name = "vbb",
18803746dcbSMarkus Pargmann 		.vin_name = "vcc7",
18903746dcbSMarkus Pargmann 		.n_voltages = ARRAY_SIZE(VBB_VSEL_table),
19003746dcbSMarkus Pargmann 		.voltage_table = VBB_VSEL_table,
19103746dcbSMarkus Pargmann 	},
192518fb721SGraeme Gregory };
193518fb721SGraeme Gregory 
194a320e3c3SJorge Eduardo Candelaria static struct tps_info tps65911_regs[] = {
195a320e3c3SJorge Eduardo Candelaria 	{
19633a6943dSLaxman Dewangan 		.name = "vrtc",
19719228a6aSLaxman Dewangan 		.vin_name = "vcc7",
1980651eed5SLaxman Dewangan 		.enable_time_us = 2200,
199c2f8efd7SLaxman Dewangan 	},
200c2f8efd7SLaxman Dewangan 	{
20133a6943dSLaxman Dewangan 		.name = "vio",
20219228a6aSLaxman Dewangan 		.vin_name = "vccio",
2037d38a3cbSLaxman Dewangan 		.n_voltages = ARRAY_SIZE(VIO_VSEL_table),
2047d38a3cbSLaxman Dewangan 		.voltage_table = VIO_VSEL_table,
2050651eed5SLaxman Dewangan 		.enable_time_us = 350,
206a320e3c3SJorge Eduardo Candelaria 	},
207a320e3c3SJorge Eduardo Candelaria 	{
20833a6943dSLaxman Dewangan 		.name = "vdd1",
20919228a6aSLaxman Dewangan 		.vin_name = "vcc1",
2107be53188SLaxman Dewangan 		.n_voltages = 0x4C,
2110651eed5SLaxman Dewangan 		.enable_time_us = 350,
212a320e3c3SJorge Eduardo Candelaria 	},
213a320e3c3SJorge Eduardo Candelaria 	{
21433a6943dSLaxman Dewangan 		.name = "vdd2",
21519228a6aSLaxman Dewangan 		.vin_name = "vcc2",
2167be53188SLaxman Dewangan 		.n_voltages = 0x4C,
2170651eed5SLaxman Dewangan 		.enable_time_us = 350,
218a320e3c3SJorge Eduardo Candelaria 	},
219a320e3c3SJorge Eduardo Candelaria 	{
22033a6943dSLaxman Dewangan 		.name = "vddctrl",
2217be53188SLaxman Dewangan 		.n_voltages = 0x44,
2220651eed5SLaxman Dewangan 		.enable_time_us = 900,
223a320e3c3SJorge Eduardo Candelaria 	},
224a320e3c3SJorge Eduardo Candelaria 	{
22533a6943dSLaxman Dewangan 		.name = "ldo1",
22619228a6aSLaxman Dewangan 		.vin_name = "vcc6",
2277be53188SLaxman Dewangan 		.n_voltages = 0x33,
2280651eed5SLaxman Dewangan 		.enable_time_us = 420,
229a320e3c3SJorge Eduardo Candelaria 	},
230a320e3c3SJorge Eduardo Candelaria 	{
23133a6943dSLaxman Dewangan 		.name = "ldo2",
23219228a6aSLaxman Dewangan 		.vin_name = "vcc6",
2337be53188SLaxman Dewangan 		.n_voltages = 0x33,
2340651eed5SLaxman Dewangan 		.enable_time_us = 420,
235a320e3c3SJorge Eduardo Candelaria 	},
236a320e3c3SJorge Eduardo Candelaria 	{
23733a6943dSLaxman Dewangan 		.name = "ldo3",
23819228a6aSLaxman Dewangan 		.vin_name = "vcc5",
2397be53188SLaxman Dewangan 		.n_voltages = 0x1A,
2400651eed5SLaxman Dewangan 		.enable_time_us = 230,
241a320e3c3SJorge Eduardo Candelaria 	},
242a320e3c3SJorge Eduardo Candelaria 	{
24333a6943dSLaxman Dewangan 		.name = "ldo4",
24419228a6aSLaxman Dewangan 		.vin_name = "vcc5",
2457be53188SLaxman Dewangan 		.n_voltages = 0x33,
2460651eed5SLaxman Dewangan 		.enable_time_us = 230,
247a320e3c3SJorge Eduardo Candelaria 	},
248a320e3c3SJorge Eduardo Candelaria 	{
24933a6943dSLaxman Dewangan 		.name = "ldo5",
25019228a6aSLaxman Dewangan 		.vin_name = "vcc4",
2517be53188SLaxman Dewangan 		.n_voltages = 0x1A,
2520651eed5SLaxman Dewangan 		.enable_time_us = 230,
253a320e3c3SJorge Eduardo Candelaria 	},
254a320e3c3SJorge Eduardo Candelaria 	{
25533a6943dSLaxman Dewangan 		.name = "ldo6",
25619228a6aSLaxman Dewangan 		.vin_name = "vcc3",
2577be53188SLaxman Dewangan 		.n_voltages = 0x1A,
2580651eed5SLaxman Dewangan 		.enable_time_us = 230,
259a320e3c3SJorge Eduardo Candelaria 	},
260a320e3c3SJorge Eduardo Candelaria 	{
26133a6943dSLaxman Dewangan 		.name = "ldo7",
26219228a6aSLaxman Dewangan 		.vin_name = "vcc3",
2637be53188SLaxman Dewangan 		.n_voltages = 0x1A,
2640651eed5SLaxman Dewangan 		.enable_time_us = 230,
265a320e3c3SJorge Eduardo Candelaria 	},
266a320e3c3SJorge Eduardo Candelaria 	{
26733a6943dSLaxman Dewangan 		.name = "ldo8",
26819228a6aSLaxman Dewangan 		.vin_name = "vcc3",
2697be53188SLaxman Dewangan 		.n_voltages = 0x1A,
2700651eed5SLaxman Dewangan 		.enable_time_us = 230,
271a320e3c3SJorge Eduardo Candelaria 	},
272a320e3c3SJorge Eduardo Candelaria };
273a320e3c3SJorge Eduardo Candelaria 
2741e0c66f4SLaxman Dewangan #define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits))
2751e0c66f4SLaxman Dewangan static unsigned int tps65910_ext_sleep_control[] = {
2761e0c66f4SLaxman Dewangan 	0,
2771e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VIO,    1, 0),
2781e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VDD1,   1, 1),
2791e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VDD2,   1, 2),
2801e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VDD3,   1, 3),
2811e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VDIG1,  0, 1),
2821e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VDIG2,  0, 2),
2831e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VPLL,   0, 6),
2841e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VDAC,   0, 7),
2851e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VAUX1,  0, 3),
2861e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VAUX2,  0, 4),
2871e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VAUX33, 0, 5),
2881e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VMMC,   0, 0),
2891e0c66f4SLaxman Dewangan };
2901e0c66f4SLaxman Dewangan 
2911e0c66f4SLaxman Dewangan static unsigned int tps65911_ext_sleep_control[] = {
2921e0c66f4SLaxman Dewangan 	0,
2931e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VIO,     1, 0),
2941e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VDD1,    1, 1),
2951e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VDD2,    1, 2),
2961e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3),
2971e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(LDO1,    0, 1),
2981e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(LDO2,    0, 2),
2991e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(LDO3,    0, 7),
3001e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(LDO4,    0, 6),
3011e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(LDO5,    0, 3),
3021e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(LDO6,    0, 0),
3031e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(LDO7,    0, 5),
3041e0c66f4SLaxman Dewangan 	EXT_CONTROL_REG_BITS(LDO8,    0, 4),
3051e0c66f4SLaxman Dewangan };
3061e0c66f4SLaxman Dewangan 
307518fb721SGraeme Gregory struct tps65910_reg {
30839aa9b6eSAxel Lin 	struct regulator_desc *desc;
309518fb721SGraeme Gregory 	struct tps65910 *mfd;
31039aa9b6eSAxel Lin 	struct regulator_dev **rdev;
31139aa9b6eSAxel Lin 	struct tps_info **info;
31239aa9b6eSAxel Lin 	int num_regulators;
313518fb721SGraeme Gregory 	int mode;
314a320e3c3SJorge Eduardo Candelaria 	int  (*get_ctrl_reg)(int);
3151e0c66f4SLaxman Dewangan 	unsigned int *ext_sleep_control;
3161e0c66f4SLaxman Dewangan 	unsigned int board_ext_control[TPS65910_NUM_REGS];
317518fb721SGraeme Gregory };
318518fb721SGraeme Gregory 
tps65910_get_ctrl_register(int id)319518fb721SGraeme Gregory static int tps65910_get_ctrl_register(int id)
320518fb721SGraeme Gregory {
321518fb721SGraeme Gregory 	switch (id) {
322518fb721SGraeme Gregory 	case TPS65910_REG_VRTC:
323518fb721SGraeme Gregory 		return TPS65910_VRTC;
324518fb721SGraeme Gregory 	case TPS65910_REG_VIO:
325518fb721SGraeme Gregory 		return TPS65910_VIO;
326518fb721SGraeme Gregory 	case TPS65910_REG_VDD1:
327518fb721SGraeme Gregory 		return TPS65910_VDD1;
328518fb721SGraeme Gregory 	case TPS65910_REG_VDD2:
329518fb721SGraeme Gregory 		return TPS65910_VDD2;
330518fb721SGraeme Gregory 	case TPS65910_REG_VDD3:
331518fb721SGraeme Gregory 		return TPS65910_VDD3;
332518fb721SGraeme Gregory 	case TPS65910_REG_VDIG1:
333518fb721SGraeme Gregory 		return TPS65910_VDIG1;
334518fb721SGraeme Gregory 	case TPS65910_REG_VDIG2:
335518fb721SGraeme Gregory 		return TPS65910_VDIG2;
336518fb721SGraeme Gregory 	case TPS65910_REG_VPLL:
337518fb721SGraeme Gregory 		return TPS65910_VPLL;
338518fb721SGraeme Gregory 	case TPS65910_REG_VDAC:
339518fb721SGraeme Gregory 		return TPS65910_VDAC;
340518fb721SGraeme Gregory 	case TPS65910_REG_VAUX1:
341518fb721SGraeme Gregory 		return TPS65910_VAUX1;
342518fb721SGraeme Gregory 	case TPS65910_REG_VAUX2:
343518fb721SGraeme Gregory 		return TPS65910_VAUX2;
344518fb721SGraeme Gregory 	case TPS65910_REG_VAUX33:
345518fb721SGraeme Gregory 		return TPS65910_VAUX33;
346518fb721SGraeme Gregory 	case TPS65910_REG_VMMC:
347518fb721SGraeme Gregory 		return TPS65910_VMMC;
34803746dcbSMarkus Pargmann 	case TPS65910_REG_VBB:
34903746dcbSMarkus Pargmann 		return TPS65910_BBCH;
350518fb721SGraeme Gregory 	default:
351518fb721SGraeme Gregory 		return -EINVAL;
352518fb721SGraeme Gregory 	}
353518fb721SGraeme Gregory }
354518fb721SGraeme Gregory 
tps65911_get_ctrl_register(int id)355a320e3c3SJorge Eduardo Candelaria static int tps65911_get_ctrl_register(int id)
356a320e3c3SJorge Eduardo Candelaria {
357a320e3c3SJorge Eduardo Candelaria 	switch (id) {
358a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VRTC:
359a320e3c3SJorge Eduardo Candelaria 		return TPS65910_VRTC;
360a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VIO:
361a320e3c3SJorge Eduardo Candelaria 		return TPS65910_VIO;
362a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VDD1:
363a320e3c3SJorge Eduardo Candelaria 		return TPS65910_VDD1;
364a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VDD2:
365a320e3c3SJorge Eduardo Candelaria 		return TPS65910_VDD2;
366a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_VDDCTRL:
367a320e3c3SJorge Eduardo Candelaria 		return TPS65911_VDDCTRL;
368a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO1:
369a320e3c3SJorge Eduardo Candelaria 		return TPS65911_LDO1;
370a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO2:
371a320e3c3SJorge Eduardo Candelaria 		return TPS65911_LDO2;
372a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO3:
373a320e3c3SJorge Eduardo Candelaria 		return TPS65911_LDO3;
374a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO4:
375a320e3c3SJorge Eduardo Candelaria 		return TPS65911_LDO4;
376a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO5:
377a320e3c3SJorge Eduardo Candelaria 		return TPS65911_LDO5;
378a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO6:
379a320e3c3SJorge Eduardo Candelaria 		return TPS65911_LDO6;
380a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO7:
381a320e3c3SJorge Eduardo Candelaria 		return TPS65911_LDO7;
382a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO8:
383a320e3c3SJorge Eduardo Candelaria 		return TPS65911_LDO8;
384a320e3c3SJorge Eduardo Candelaria 	default:
385a320e3c3SJorge Eduardo Candelaria 		return -EINVAL;
386a320e3c3SJorge Eduardo Candelaria 	}
387a320e3c3SJorge Eduardo Candelaria }
388a320e3c3SJorge Eduardo Candelaria 
tps65910_set_mode(struct regulator_dev * dev,unsigned int mode)389518fb721SGraeme Gregory static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
390518fb721SGraeme Gregory {
391518fb721SGraeme Gregory 	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
392bd8e2cadSMichał Mirosław 	struct regmap *regmap = rdev_get_regmap(dev);
393bd8e2cadSMichał Mirosław 	int reg, id = rdev_get_id(dev);
394a320e3c3SJorge Eduardo Candelaria 
395a320e3c3SJorge Eduardo Candelaria 	reg = pmic->get_ctrl_reg(id);
396518fb721SGraeme Gregory 	if (reg < 0)
397518fb721SGraeme Gregory 		return reg;
398518fb721SGraeme Gregory 
399518fb721SGraeme Gregory 	switch (mode) {
400518fb721SGraeme Gregory 	case REGULATOR_MODE_NORMAL:
401bd8e2cadSMichał Mirosław 		return regmap_update_bits(regmap, reg,
402faa95fdeSAxel Lin 					  LDO_ST_MODE_BIT | LDO_ST_ON_BIT,
403faa95fdeSAxel Lin 					  LDO_ST_ON_BIT);
404518fb721SGraeme Gregory 	case REGULATOR_MODE_IDLE:
405bd8e2cadSMichał Mirosław 		return regmap_set_bits(regmap, reg,
406bd8e2cadSMichał Mirosław 				       LDO_ST_ON_BIT | LDO_ST_MODE_BIT);
407518fb721SGraeme Gregory 	case REGULATOR_MODE_STANDBY:
408bd8e2cadSMichał Mirosław 		return regmap_clear_bits(regmap, reg, LDO_ST_ON_BIT);
409518fb721SGraeme Gregory 	}
410518fb721SGraeme Gregory 
411518fb721SGraeme Gregory 	return -EINVAL;
412518fb721SGraeme Gregory }
413518fb721SGraeme Gregory 
tps65910_get_mode(struct regulator_dev * dev)414518fb721SGraeme Gregory static unsigned int tps65910_get_mode(struct regulator_dev *dev)
415518fb721SGraeme Gregory {
416518fb721SGraeme Gregory 	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
417bd8e2cadSMichał Mirosław 	struct regmap *regmap = rdev_get_regmap(dev);
418faa95fdeSAxel Lin 	int ret, reg, value, id = rdev_get_id(dev);
419518fb721SGraeme Gregory 
420a320e3c3SJorge Eduardo Candelaria 	reg = pmic->get_ctrl_reg(id);
421518fb721SGraeme Gregory 	if (reg < 0)
422518fb721SGraeme Gregory 		return reg;
423518fb721SGraeme Gregory 
424bd8e2cadSMichał Mirosław 	ret = regmap_read(regmap, reg, &value);
425faa95fdeSAxel Lin 	if (ret < 0)
426faa95fdeSAxel Lin 		return ret;
427518fb721SGraeme Gregory 
42858599393SAxel Lin 	if (!(value & LDO_ST_ON_BIT))
429518fb721SGraeme Gregory 		return REGULATOR_MODE_STANDBY;
430518fb721SGraeme Gregory 	else if (value & LDO_ST_MODE_BIT)
431518fb721SGraeme Gregory 		return REGULATOR_MODE_IDLE;
432518fb721SGraeme Gregory 	else
433518fb721SGraeme Gregory 		return REGULATOR_MODE_NORMAL;
434518fb721SGraeme Gregory }
435518fb721SGraeme Gregory 
tps65910_get_voltage_dcdc_sel(struct regulator_dev * dev)43618039e0fSLaxman Dewangan static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev)
437518fb721SGraeme Gregory {
438bd8e2cadSMichał Mirosław 	struct regmap *regmap = rdev_get_regmap(dev);
439faa95fdeSAxel Lin 	int ret, id = rdev_get_id(dev);
440a320e3c3SJorge Eduardo Candelaria 	int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0;
441518fb721SGraeme Gregory 
442518fb721SGraeme Gregory 	switch (id) {
443518fb721SGraeme Gregory 	case TPS65910_REG_VDD1:
444bd8e2cadSMichał Mirosław 		ret = regmap_read(regmap, TPS65910_VDD1_OP, &opvsel);
445faa95fdeSAxel Lin 		if (ret < 0)
446faa95fdeSAxel Lin 			return ret;
447bd8e2cadSMichał Mirosław 		ret = regmap_read(regmap, TPS65910_VDD1, &mult);
448faa95fdeSAxel Lin 		if (ret < 0)
449faa95fdeSAxel Lin 			return ret;
450518fb721SGraeme Gregory 		mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT;
451bd8e2cadSMichał Mirosław 		ret = regmap_read(regmap, TPS65910_VDD1_SR, &srvsel);
452faa95fdeSAxel Lin 		if (ret < 0)
453faa95fdeSAxel Lin 			return ret;
454518fb721SGraeme Gregory 		sr = opvsel & VDD1_OP_CMD_MASK;
455518fb721SGraeme Gregory 		opvsel &= VDD1_OP_SEL_MASK;
456518fb721SGraeme Gregory 		srvsel &= VDD1_SR_SEL_MASK;
457a320e3c3SJorge Eduardo Candelaria 		vselmax = 75;
458518fb721SGraeme Gregory 		break;
459518fb721SGraeme Gregory 	case TPS65910_REG_VDD2:
460bd8e2cadSMichał Mirosław 		ret = regmap_read(regmap, TPS65910_VDD2_OP, &opvsel);
461faa95fdeSAxel Lin 		if (ret < 0)
462faa95fdeSAxel Lin 			return ret;
463bd8e2cadSMichał Mirosław 		ret = regmap_read(regmap, TPS65910_VDD2, &mult);
464faa95fdeSAxel Lin 		if (ret < 0)
465faa95fdeSAxel Lin 			return ret;
466518fb721SGraeme Gregory 		mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT;
467bd8e2cadSMichał Mirosław 		ret = regmap_read(regmap, TPS65910_VDD2_SR, &srvsel);
468faa95fdeSAxel Lin 		if (ret < 0)
469faa95fdeSAxel Lin 			return ret;
470518fb721SGraeme Gregory 		sr = opvsel & VDD2_OP_CMD_MASK;
471518fb721SGraeme Gregory 		opvsel &= VDD2_OP_SEL_MASK;
472518fb721SGraeme Gregory 		srvsel &= VDD2_SR_SEL_MASK;
473a320e3c3SJorge Eduardo Candelaria 		vselmax = 75;
474a320e3c3SJorge Eduardo Candelaria 		break;
475a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_VDDCTRL:
476bd8e2cadSMichał Mirosław 		ret = regmap_read(regmap, TPS65911_VDDCTRL_OP, &opvsel);
477faa95fdeSAxel Lin 		if (ret < 0)
478faa95fdeSAxel Lin 			return ret;
479bd8e2cadSMichał Mirosław 		ret = regmap_read(regmap, TPS65911_VDDCTRL_SR, &srvsel);
480faa95fdeSAxel Lin 		if (ret < 0)
481faa95fdeSAxel Lin 			return ret;
482a320e3c3SJorge Eduardo Candelaria 		sr = opvsel & VDDCTRL_OP_CMD_MASK;
483a320e3c3SJorge Eduardo Candelaria 		opvsel &= VDDCTRL_OP_SEL_MASK;
484a320e3c3SJorge Eduardo Candelaria 		srvsel &= VDDCTRL_SR_SEL_MASK;
485a320e3c3SJorge Eduardo Candelaria 		vselmax = 64;
486518fb721SGraeme Gregory 		break;
487518fb721SGraeme Gregory 	}
488518fb721SGraeme Gregory 
489518fb721SGraeme Gregory 	/* multiplier 0 == 1 but 2,3 normal */
490518fb721SGraeme Gregory 	if (!mult)
491518fb721SGraeme Gregory 		mult = 1;
492518fb721SGraeme Gregory 
493518fb721SGraeme Gregory 	if (sr) {
494a320e3c3SJorge Eduardo Candelaria 		/* normalise to valid range */
495a320e3c3SJorge Eduardo Candelaria 		if (srvsel < 3)
496a320e3c3SJorge Eduardo Candelaria 			srvsel = 3;
497a320e3c3SJorge Eduardo Candelaria 		if (srvsel > vselmax)
498a320e3c3SJorge Eduardo Candelaria 			srvsel = vselmax;
49918039e0fSLaxman Dewangan 		return srvsel - 3;
500518fb721SGraeme Gregory 	} else {
501518fb721SGraeme Gregory 
502a320e3c3SJorge Eduardo Candelaria 		/* normalise to valid range*/
503a320e3c3SJorge Eduardo Candelaria 		if (opvsel < 3)
504a320e3c3SJorge Eduardo Candelaria 			opvsel = 3;
505a320e3c3SJorge Eduardo Candelaria 		if (opvsel > vselmax)
506a320e3c3SJorge Eduardo Candelaria 			opvsel = vselmax;
50718039e0fSLaxman Dewangan 		return opvsel - 3;
508518fb721SGraeme Gregory 	}
50918039e0fSLaxman Dewangan 	return -EINVAL;
510518fb721SGraeme Gregory }
511518fb721SGraeme Gregory 
tps65910_get_voltage_sel(struct regulator_dev * dev)5121f904fd1SAxel Lin static int tps65910_get_voltage_sel(struct regulator_dev *dev)
513518fb721SGraeme Gregory {
514518fb721SGraeme Gregory 	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
515bd8e2cadSMichał Mirosław 	struct regmap *regmap = rdev_get_regmap(dev);
516faa95fdeSAxel Lin 	int ret, reg, value, id = rdev_get_id(dev);
517518fb721SGraeme Gregory 
518a320e3c3SJorge Eduardo Candelaria 	reg = pmic->get_ctrl_reg(id);
519518fb721SGraeme Gregory 	if (reg < 0)
520518fb721SGraeme Gregory 		return reg;
521518fb721SGraeme Gregory 
522bd8e2cadSMichał Mirosław 	ret = regmap_read(regmap, reg, &value);
523faa95fdeSAxel Lin 	if (ret < 0)
524faa95fdeSAxel Lin 		return ret;
525518fb721SGraeme Gregory 
526518fb721SGraeme Gregory 	switch (id) {
527518fb721SGraeme Gregory 	case TPS65910_REG_VIO:
528518fb721SGraeme Gregory 	case TPS65910_REG_VDIG1:
529518fb721SGraeme Gregory 	case TPS65910_REG_VDIG2:
530518fb721SGraeme Gregory 	case TPS65910_REG_VPLL:
531518fb721SGraeme Gregory 	case TPS65910_REG_VDAC:
532518fb721SGraeme Gregory 	case TPS65910_REG_VAUX1:
533518fb721SGraeme Gregory 	case TPS65910_REG_VAUX2:
534518fb721SGraeme Gregory 	case TPS65910_REG_VAUX33:
535518fb721SGraeme Gregory 	case TPS65910_REG_VMMC:
536518fb721SGraeme Gregory 		value &= LDO_SEL_MASK;
537518fb721SGraeme Gregory 		value >>= LDO_SEL_SHIFT;
538518fb721SGraeme Gregory 		break;
53903746dcbSMarkus Pargmann 	case TPS65910_REG_VBB:
54003746dcbSMarkus Pargmann 		value &= BBCH_BBSEL_MASK;
54103746dcbSMarkus Pargmann 		value >>= BBCH_BBSEL_SHIFT;
54203746dcbSMarkus Pargmann 		break;
543518fb721SGraeme Gregory 	default:
544518fb721SGraeme Gregory 		return -EINVAL;
545518fb721SGraeme Gregory 	}
546518fb721SGraeme Gregory 
5471f904fd1SAxel Lin 	return value;
548518fb721SGraeme Gregory }
549518fb721SGraeme Gregory 
tps65910_get_voltage_vdd3(struct regulator_dev * dev)550518fb721SGraeme Gregory static int tps65910_get_voltage_vdd3(struct regulator_dev *dev)
551518fb721SGraeme Gregory {
552d9fe28f9SAxel Lin 	return dev->desc->volt_table[0];
553518fb721SGraeme Gregory }
554518fb721SGraeme Gregory 
tps65911_get_voltage_sel(struct regulator_dev * dev)5551f904fd1SAxel Lin static int tps65911_get_voltage_sel(struct regulator_dev *dev)
556a320e3c3SJorge Eduardo Candelaria {
557a320e3c3SJorge Eduardo Candelaria 	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
558bd8e2cadSMichał Mirosław 	struct regmap *regmap = rdev_get_regmap(dev);
559faa95fdeSAxel Lin 	int ret, id = rdev_get_id(dev);
560faa95fdeSAxel Lin 	unsigned int value, reg;
561a320e3c3SJorge Eduardo Candelaria 
562a320e3c3SJorge Eduardo Candelaria 	reg = pmic->get_ctrl_reg(id);
563a320e3c3SJorge Eduardo Candelaria 
564bd8e2cadSMichał Mirosław 	ret = regmap_read(regmap, reg, &value);
565faa95fdeSAxel Lin 	if (ret < 0)
566faa95fdeSAxel Lin 		return ret;
567a320e3c3SJorge Eduardo Candelaria 
568a320e3c3SJorge Eduardo Candelaria 	switch (id) {
569a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO1:
570a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO2:
571a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO4:
572a320e3c3SJorge Eduardo Candelaria 		value &= LDO1_SEL_MASK;
573a320e3c3SJorge Eduardo Candelaria 		value >>= LDO_SEL_SHIFT;
574a320e3c3SJorge Eduardo Candelaria 		break;
575a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO3:
576a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO5:
577a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO6:
578a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO7:
579a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO8:
580a320e3c3SJorge Eduardo Candelaria 		value &= LDO3_SEL_MASK;
581a320e3c3SJorge Eduardo Candelaria 		value >>= LDO_SEL_SHIFT;
582a320e3c3SJorge Eduardo Candelaria 		break;
583a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VIO:
584e882eae8SLaxman Dewangan 		value &= LDO_SEL_MASK;
585e882eae8SLaxman Dewangan 		value >>= LDO_SEL_SHIFT;
5861f904fd1SAxel Lin 		break;
587a320e3c3SJorge Eduardo Candelaria 	default:
588a320e3c3SJorge Eduardo Candelaria 		return -EINVAL;
589a320e3c3SJorge Eduardo Candelaria 	}
590a320e3c3SJorge Eduardo Candelaria 
5911f904fd1SAxel Lin 	return value;
592a320e3c3SJorge Eduardo Candelaria }
593a320e3c3SJorge Eduardo Candelaria 
tps65910_set_voltage_dcdc_sel(struct regulator_dev * dev,unsigned selector)59494732b97SAxel Lin static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev,
595518fb721SGraeme Gregory 					 unsigned selector)
596518fb721SGraeme Gregory {
597bd8e2cadSMichał Mirosław 	struct regmap *regmap = rdev_get_regmap(dev);
598518fb721SGraeme Gregory 	int id = rdev_get_id(dev), vsel;
599a320e3c3SJorge Eduardo Candelaria 	int dcdc_mult = 0;
600518fb721SGraeme Gregory 
601a320e3c3SJorge Eduardo Candelaria 	switch (id) {
602a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VDD1:
603780dc9baSAfzal Mohammed 		dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
604a320e3c3SJorge Eduardo Candelaria 		if (dcdc_mult == 1)
605a320e3c3SJorge Eduardo Candelaria 			dcdc_mult--;
606780dc9baSAfzal Mohammed 		vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
607518fb721SGraeme Gregory 
608bd8e2cadSMichał Mirosław 		regmap_update_bits(regmap, TPS65910_VDD1, VDD1_VGAIN_SEL_MASK,
609faa95fdeSAxel Lin 				   dcdc_mult << VDD1_VGAIN_SEL_SHIFT);
610bd8e2cadSMichał Mirosław 		regmap_write(regmap, TPS65910_VDD1_OP, vsel);
611a320e3c3SJorge Eduardo Candelaria 		break;
612a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VDD2:
613780dc9baSAfzal Mohammed 		dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
614a320e3c3SJorge Eduardo Candelaria 		if (dcdc_mult == 1)
615a320e3c3SJorge Eduardo Candelaria 			dcdc_mult--;
616780dc9baSAfzal Mohammed 		vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
617a320e3c3SJorge Eduardo Candelaria 
618bd8e2cadSMichał Mirosław 		regmap_update_bits(regmap, TPS65910_VDD2, VDD1_VGAIN_SEL_MASK,
619faa95fdeSAxel Lin 				   dcdc_mult << VDD2_VGAIN_SEL_SHIFT);
620bd8e2cadSMichał Mirosław 		regmap_write(regmap, TPS65910_VDD2_OP, vsel);
621a320e3c3SJorge Eduardo Candelaria 		break;
622a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_VDDCTRL:
623c4632aedSLaxman Dewangan 		vsel = selector + 3;
624bd8e2cadSMichał Mirosław 		regmap_write(regmap, TPS65911_VDDCTRL_OP, vsel);
625bd8e2cadSMichał Mirosław 		break;
626518fb721SGraeme Gregory 	}
627518fb721SGraeme Gregory 
628518fb721SGraeme Gregory 	return 0;
629518fb721SGraeme Gregory }
630518fb721SGraeme Gregory 
tps65910_set_voltage_sel(struct regulator_dev * dev,unsigned selector)63194732b97SAxel Lin static int tps65910_set_voltage_sel(struct regulator_dev *dev,
63294732b97SAxel Lin 				    unsigned selector)
633518fb721SGraeme Gregory {
634518fb721SGraeme Gregory 	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
635bd8e2cadSMichał Mirosław 	struct regmap *regmap = rdev_get_regmap(dev);
636518fb721SGraeme Gregory 	int reg, id = rdev_get_id(dev);
637518fb721SGraeme Gregory 
638a320e3c3SJorge Eduardo Candelaria 	reg = pmic->get_ctrl_reg(id);
639518fb721SGraeme Gregory 	if (reg < 0)
640518fb721SGraeme Gregory 		return reg;
641518fb721SGraeme Gregory 
642518fb721SGraeme Gregory 	switch (id) {
643518fb721SGraeme Gregory 	case TPS65910_REG_VIO:
644518fb721SGraeme Gregory 	case TPS65910_REG_VDIG1:
645518fb721SGraeme Gregory 	case TPS65910_REG_VDIG2:
646518fb721SGraeme Gregory 	case TPS65910_REG_VPLL:
647518fb721SGraeme Gregory 	case TPS65910_REG_VDAC:
648518fb721SGraeme Gregory 	case TPS65910_REG_VAUX1:
649518fb721SGraeme Gregory 	case TPS65910_REG_VAUX2:
650518fb721SGraeme Gregory 	case TPS65910_REG_VAUX33:
651518fb721SGraeme Gregory 	case TPS65910_REG_VMMC:
652bd8e2cadSMichał Mirosław 		return regmap_update_bits(regmap, reg, LDO_SEL_MASK,
653faa95fdeSAxel Lin 					  selector << LDO_SEL_SHIFT);
65403746dcbSMarkus Pargmann 	case TPS65910_REG_VBB:
655bd8e2cadSMichał Mirosław 		return regmap_update_bits(regmap, reg, BBCH_BBSEL_MASK,
65603746dcbSMarkus Pargmann 					  selector << BBCH_BBSEL_SHIFT);
657518fb721SGraeme Gregory 	}
658518fb721SGraeme Gregory 
659518fb721SGraeme Gregory 	return -EINVAL;
660518fb721SGraeme Gregory }
661518fb721SGraeme Gregory 
tps65911_set_voltage_sel(struct regulator_dev * dev,unsigned selector)66294732b97SAxel Lin static int tps65911_set_voltage_sel(struct regulator_dev *dev,
66394732b97SAxel Lin 				    unsigned selector)
664a320e3c3SJorge Eduardo Candelaria {
665a320e3c3SJorge Eduardo Candelaria 	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
666bd8e2cadSMichał Mirosław 	struct regmap *regmap = rdev_get_regmap(dev);
667a320e3c3SJorge Eduardo Candelaria 	int reg, id = rdev_get_id(dev);
668a320e3c3SJorge Eduardo Candelaria 
669a320e3c3SJorge Eduardo Candelaria 	reg = pmic->get_ctrl_reg(id);
670a320e3c3SJorge Eduardo Candelaria 	if (reg < 0)
671a320e3c3SJorge Eduardo Candelaria 		return reg;
672a320e3c3SJorge Eduardo Candelaria 
673a320e3c3SJorge Eduardo Candelaria 	switch (id) {
674a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO1:
675a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO2:
676a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO4:
677bd8e2cadSMichał Mirosław 		return regmap_update_bits(regmap, reg, LDO1_SEL_MASK,
678faa95fdeSAxel Lin 					  selector << LDO_SEL_SHIFT);
679a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO3:
680a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO5:
681a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO6:
682a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO7:
683a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO8:
684bd8e2cadSMichał Mirosław 		return regmap_update_bits(regmap, reg, LDO3_SEL_MASK,
685faa95fdeSAxel Lin 					  selector << LDO_SEL_SHIFT);
686e882eae8SLaxman Dewangan 	case TPS65910_REG_VIO:
687bd8e2cadSMichał Mirosław 		return regmap_update_bits(regmap, reg, LDO_SEL_MASK,
688faa95fdeSAxel Lin 					  selector << LDO_SEL_SHIFT);
68903746dcbSMarkus Pargmann 	case TPS65910_REG_VBB:
690bd8e2cadSMichał Mirosław 		return regmap_update_bits(regmap, reg, BBCH_BBSEL_MASK,
69103746dcbSMarkus Pargmann 					  selector << BBCH_BBSEL_SHIFT);
692a320e3c3SJorge Eduardo Candelaria 	}
693a320e3c3SJorge Eduardo Candelaria 
694a320e3c3SJorge Eduardo Candelaria 	return -EINVAL;
695a320e3c3SJorge Eduardo Candelaria }
696a320e3c3SJorge Eduardo Candelaria 
697a320e3c3SJorge Eduardo Candelaria 
tps65910_list_voltage_dcdc(struct regulator_dev * dev,unsigned selector)698518fb721SGraeme Gregory static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
699518fb721SGraeme Gregory 					unsigned selector)
700518fb721SGraeme Gregory {
701a320e3c3SJorge Eduardo Candelaria 	int volt, mult = 1, id = rdev_get_id(dev);
702518fb721SGraeme Gregory 
703a320e3c3SJorge Eduardo Candelaria 	switch (id) {
704a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VDD1:
705a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VDD2:
706780dc9baSAfzal Mohammed 		mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
707a320e3c3SJorge Eduardo Candelaria 		volt = VDD1_2_MIN_VOLT +
708780dc9baSAfzal Mohammed 			(selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;
709d04156bcSAxel Lin 		break;
710a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_VDDCTRL:
711a320e3c3SJorge Eduardo Candelaria 		volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
712d04156bcSAxel Lin 		break;
713d04156bcSAxel Lin 	default:
714d04156bcSAxel Lin 		BUG();
715d04156bcSAxel Lin 		return -EINVAL;
716a320e3c3SJorge Eduardo Candelaria 	}
717518fb721SGraeme Gregory 
718518fb721SGraeme Gregory 	return  volt * 100 * mult;
719518fb721SGraeme Gregory }
720518fb721SGraeme Gregory 
tps65911_list_voltage(struct regulator_dev * dev,unsigned selector)721a320e3c3SJorge Eduardo Candelaria static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
722a320e3c3SJorge Eduardo Candelaria {
723a320e3c3SJorge Eduardo Candelaria 	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
724a320e3c3SJorge Eduardo Candelaria 	int step_mv = 0, id = rdev_get_id(dev);
725a320e3c3SJorge Eduardo Candelaria 
726a320e3c3SJorge Eduardo Candelaria 	switch (id) {
727a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO1:
728a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO2:
729a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO4:
730a320e3c3SJorge Eduardo Candelaria 		/* The first 5 values of the selector correspond to 1V */
731a320e3c3SJorge Eduardo Candelaria 		if (selector < 5)
732a320e3c3SJorge Eduardo Candelaria 			selector = 0;
733a320e3c3SJorge Eduardo Candelaria 		else
734a320e3c3SJorge Eduardo Candelaria 			selector -= 4;
735a320e3c3SJorge Eduardo Candelaria 
736a320e3c3SJorge Eduardo Candelaria 		step_mv = 50;
737a320e3c3SJorge Eduardo Candelaria 		break;
738a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO3:
739a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO5:
740a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO6:
741a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO7:
742a320e3c3SJorge Eduardo Candelaria 	case TPS65911_REG_LDO8:
743a320e3c3SJorge Eduardo Candelaria 		/* The first 3 values of the selector correspond to 1V */
744a320e3c3SJorge Eduardo Candelaria 		if (selector < 3)
745a320e3c3SJorge Eduardo Candelaria 			selector = 0;
746a320e3c3SJorge Eduardo Candelaria 		else
747a320e3c3SJorge Eduardo Candelaria 			selector -= 2;
748a320e3c3SJorge Eduardo Candelaria 
749a320e3c3SJorge Eduardo Candelaria 		step_mv = 100;
750a320e3c3SJorge Eduardo Candelaria 		break;
751a320e3c3SJorge Eduardo Candelaria 	case TPS65910_REG_VIO:
752d9fe28f9SAxel Lin 		return pmic->info[id]->voltage_table[selector];
753a320e3c3SJorge Eduardo Candelaria 	default:
754a320e3c3SJorge Eduardo Candelaria 		return -EINVAL;
755a320e3c3SJorge Eduardo Candelaria 	}
756a320e3c3SJorge Eduardo Candelaria 
757a320e3c3SJorge Eduardo Candelaria 	return (LDO_MIN_VOLT + selector * step_mv) * 1000;
758a320e3c3SJorge Eduardo Candelaria }
759a320e3c3SJorge Eduardo Candelaria 
760518fb721SGraeme Gregory /* Regulator ops (except VRTC) */
761385d41d7SRikard Falkeborn static const struct regulator_ops tps65910_ops_dcdc = {
762a40a9c43SAxel Lin 	.is_enabled		= regulator_is_enabled_regmap,
763a40a9c43SAxel Lin 	.enable			= regulator_enable_regmap,
764a40a9c43SAxel Lin 	.disable		= regulator_disable_regmap,
765518fb721SGraeme Gregory 	.set_mode		= tps65910_set_mode,
766518fb721SGraeme Gregory 	.get_mode		= tps65910_get_mode,
76718039e0fSLaxman Dewangan 	.get_voltage_sel	= tps65910_get_voltage_dcdc_sel,
76894732b97SAxel Lin 	.set_voltage_sel	= tps65910_set_voltage_dcdc_sel,
76901bc3a14SAxel Lin 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
770518fb721SGraeme Gregory 	.list_voltage		= tps65910_list_voltage_dcdc,
7719fa8175fSAxel Lin 	.map_voltage		= regulator_map_voltage_ascend,
772518fb721SGraeme Gregory };
773518fb721SGraeme Gregory 
774385d41d7SRikard Falkeborn static const struct regulator_ops tps65910_ops_vdd3 = {
775a40a9c43SAxel Lin 	.is_enabled		= regulator_is_enabled_regmap,
776a40a9c43SAxel Lin 	.enable			= regulator_enable_regmap,
777a40a9c43SAxel Lin 	.disable		= regulator_disable_regmap,
778518fb721SGraeme Gregory 	.set_mode		= tps65910_set_mode,
779518fb721SGraeme Gregory 	.get_mode		= tps65910_get_mode,
780518fb721SGraeme Gregory 	.get_voltage		= tps65910_get_voltage_vdd3,
781d9fe28f9SAxel Lin 	.list_voltage		= regulator_list_voltage_table,
7829fa8175fSAxel Lin 	.map_voltage		= regulator_map_voltage_ascend,
783518fb721SGraeme Gregory };
784518fb721SGraeme Gregory 
785385d41d7SRikard Falkeborn static const struct regulator_ops tps65910_ops_vbb = {
78603746dcbSMarkus Pargmann 	.is_enabled		= regulator_is_enabled_regmap,
78703746dcbSMarkus Pargmann 	.enable			= regulator_enable_regmap,
78803746dcbSMarkus Pargmann 	.disable		= regulator_disable_regmap,
78903746dcbSMarkus Pargmann 	.set_mode		= tps65910_set_mode,
79003746dcbSMarkus Pargmann 	.get_mode		= tps65910_get_mode,
79103746dcbSMarkus Pargmann 	.get_voltage_sel	= tps65910_get_voltage_sel,
79203746dcbSMarkus Pargmann 	.set_voltage_sel	= tps65910_set_voltage_sel,
79303746dcbSMarkus Pargmann 	.list_voltage		= regulator_list_voltage_table,
79403746dcbSMarkus Pargmann 	.map_voltage		= regulator_map_voltage_iterate,
79503746dcbSMarkus Pargmann };
79603746dcbSMarkus Pargmann 
797385d41d7SRikard Falkeborn static const struct regulator_ops tps65910_ops = {
798a40a9c43SAxel Lin 	.is_enabled		= regulator_is_enabled_regmap,
799a40a9c43SAxel Lin 	.enable			= regulator_enable_regmap,
800a40a9c43SAxel Lin 	.disable		= regulator_disable_regmap,
801518fb721SGraeme Gregory 	.set_mode		= tps65910_set_mode,
802518fb721SGraeme Gregory 	.get_mode		= tps65910_get_mode,
8031f904fd1SAxel Lin 	.get_voltage_sel	= tps65910_get_voltage_sel,
80494732b97SAxel Lin 	.set_voltage_sel	= tps65910_set_voltage_sel,
805d9fe28f9SAxel Lin 	.list_voltage		= regulator_list_voltage_table,
8069fa8175fSAxel Lin 	.map_voltage		= regulator_map_voltage_ascend,
807518fb721SGraeme Gregory };
808518fb721SGraeme Gregory 
809385d41d7SRikard Falkeborn static const struct regulator_ops tps65911_ops = {
810a40a9c43SAxel Lin 	.is_enabled		= regulator_is_enabled_regmap,
811a40a9c43SAxel Lin 	.enable			= regulator_enable_regmap,
812a40a9c43SAxel Lin 	.disable		= regulator_disable_regmap,
813a320e3c3SJorge Eduardo Candelaria 	.set_mode		= tps65910_set_mode,
814a320e3c3SJorge Eduardo Candelaria 	.get_mode		= tps65910_get_mode,
8151f904fd1SAxel Lin 	.get_voltage_sel	= tps65911_get_voltage_sel,
81694732b97SAxel Lin 	.set_voltage_sel	= tps65911_set_voltage_sel,
817a320e3c3SJorge Eduardo Candelaria 	.list_voltage		= tps65911_list_voltage,
8189fa8175fSAxel Lin 	.map_voltage		= regulator_map_voltage_ascend,
819a320e3c3SJorge Eduardo Candelaria };
820a320e3c3SJorge Eduardo Candelaria 
tps65910_set_ext_sleep_config(struct tps65910_reg * pmic,int id,int ext_sleep_config)8211e0c66f4SLaxman Dewangan static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
8221e0c66f4SLaxman Dewangan 		int id, int ext_sleep_config)
8231e0c66f4SLaxman Dewangan {
8241e0c66f4SLaxman Dewangan 	struct tps65910 *mfd = pmic->mfd;
8251e0c66f4SLaxman Dewangan 	u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF;
8261e0c66f4SLaxman Dewangan 	u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF);
8271e0c66f4SLaxman Dewangan 	int ret;
8281e0c66f4SLaxman Dewangan 
8291e0c66f4SLaxman Dewangan 	/*
8301e0c66f4SLaxman Dewangan 	 * Regulator can not be control from multiple external input EN1, EN2
8311e0c66f4SLaxman Dewangan 	 * and EN3 together.
8321e0c66f4SLaxman Dewangan 	 */
8331e0c66f4SLaxman Dewangan 	if (ext_sleep_config & EXT_SLEEP_CONTROL) {
8341e0c66f4SLaxman Dewangan 		int en_count;
8351e0c66f4SLaxman Dewangan 		en_count = ((ext_sleep_config &
8361e0c66f4SLaxman Dewangan 				TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0);
8371e0c66f4SLaxman Dewangan 		en_count += ((ext_sleep_config &
8381e0c66f4SLaxman Dewangan 				TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0);
8391e0c66f4SLaxman Dewangan 		en_count += ((ext_sleep_config &
8401e0c66f4SLaxman Dewangan 				TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0);
841f30b0716SLaxman Dewangan 		en_count += ((ext_sleep_config &
842f30b0716SLaxman Dewangan 				TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) != 0);
8431e0c66f4SLaxman Dewangan 		if (en_count > 1) {
8441e0c66f4SLaxman Dewangan 			dev_err(mfd->dev,
8451e0c66f4SLaxman Dewangan 				"External sleep control flag is not proper\n");
8461e0c66f4SLaxman Dewangan 			return -EINVAL;
8471e0c66f4SLaxman Dewangan 		}
8481e0c66f4SLaxman Dewangan 	}
8491e0c66f4SLaxman Dewangan 
8501e0c66f4SLaxman Dewangan 	pmic->board_ext_control[id] = ext_sleep_config;
8511e0c66f4SLaxman Dewangan 
8521e0c66f4SLaxman Dewangan 	/* External EN1 control */
8531e0c66f4SLaxman Dewangan 	if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1)
854bd8e2cadSMichał Mirosław 		ret = regmap_set_bits(mfd->regmap,
8551e0c66f4SLaxman Dewangan 				TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
8561e0c66f4SLaxman Dewangan 	else
857bd8e2cadSMichał Mirosław 		ret = regmap_clear_bits(mfd->regmap,
8581e0c66f4SLaxman Dewangan 				TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
8591e0c66f4SLaxman Dewangan 	if (ret < 0) {
8601e0c66f4SLaxman Dewangan 		dev_err(mfd->dev,
8611e0c66f4SLaxman Dewangan 			"Error in configuring external control EN1\n");
8621e0c66f4SLaxman Dewangan 		return ret;
8631e0c66f4SLaxman Dewangan 	}
8641e0c66f4SLaxman Dewangan 
8651e0c66f4SLaxman Dewangan 	/* External EN2 control */
8661e0c66f4SLaxman Dewangan 	if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2)
867bd8e2cadSMichał Mirosław 		ret = regmap_set_bits(mfd->regmap,
8681e0c66f4SLaxman Dewangan 				TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
8691e0c66f4SLaxman Dewangan 	else
870bd8e2cadSMichał Mirosław 		ret = regmap_clear_bits(mfd->regmap,
8711e0c66f4SLaxman Dewangan 				TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
8721e0c66f4SLaxman Dewangan 	if (ret < 0) {
8731e0c66f4SLaxman Dewangan 		dev_err(mfd->dev,
8741e0c66f4SLaxman Dewangan 			"Error in configuring external control EN2\n");
8751e0c66f4SLaxman Dewangan 		return ret;
8761e0c66f4SLaxman Dewangan 	}
8771e0c66f4SLaxman Dewangan 
8781e0c66f4SLaxman Dewangan 	/* External EN3 control for TPS65910 LDO only */
8791e0c66f4SLaxman Dewangan 	if ((tps65910_chip_id(mfd) == TPS65910) &&
8801e0c66f4SLaxman Dewangan 			(id >= TPS65910_REG_VDIG1)) {
8811e0c66f4SLaxman Dewangan 		if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3)
882bd8e2cadSMichał Mirosław 			ret = regmap_set_bits(mfd->regmap,
8831e0c66f4SLaxman Dewangan 				TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
8841e0c66f4SLaxman Dewangan 		else
885bd8e2cadSMichał Mirosław 			ret = regmap_clear_bits(mfd->regmap,
8861e0c66f4SLaxman Dewangan 				TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
8871e0c66f4SLaxman Dewangan 		if (ret < 0) {
8881e0c66f4SLaxman Dewangan 			dev_err(mfd->dev,
8891e0c66f4SLaxman Dewangan 				"Error in configuring external control EN3\n");
8901e0c66f4SLaxman Dewangan 			return ret;
8911e0c66f4SLaxman Dewangan 		}
8921e0c66f4SLaxman Dewangan 	}
8931e0c66f4SLaxman Dewangan 
8941e0c66f4SLaxman Dewangan 	/* Return if no external control is selected */
8951e0c66f4SLaxman Dewangan 	if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) {
8961e0c66f4SLaxman Dewangan 		/* Clear all sleep controls */
897bd8e2cadSMichał Mirosław 		ret = regmap_clear_bits(mfd->regmap,
8981e0c66f4SLaxman Dewangan 			TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
8991e0c66f4SLaxman Dewangan 		if (!ret)
900bd8e2cadSMichał Mirosław 			ret = regmap_clear_bits(mfd->regmap,
9011e0c66f4SLaxman Dewangan 				TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
9021e0c66f4SLaxman Dewangan 		if (ret < 0)
9031e0c66f4SLaxman Dewangan 			dev_err(mfd->dev,
9041e0c66f4SLaxman Dewangan 				"Error in configuring SLEEP register\n");
9051e0c66f4SLaxman Dewangan 		return ret;
9061e0c66f4SLaxman Dewangan 	}
9071e0c66f4SLaxman Dewangan 
9081e0c66f4SLaxman Dewangan 	/*
9091e0c66f4SLaxman Dewangan 	 * For regulator that has separate operational and sleep register make
9101e0c66f4SLaxman Dewangan 	 * sure that operational is used and clear sleep register to turn
9111e0c66f4SLaxman Dewangan 	 * regulator off when external control is inactive
9121e0c66f4SLaxman Dewangan 	 */
9131e0c66f4SLaxman Dewangan 	if ((id == TPS65910_REG_VDD1) ||
9141e0c66f4SLaxman Dewangan 		(id == TPS65910_REG_VDD2) ||
9151e0c66f4SLaxman Dewangan 			((id == TPS65911_REG_VDDCTRL) &&
9161e0c66f4SLaxman Dewangan 				(tps65910_chip_id(mfd) == TPS65911))) {
9171e0c66f4SLaxman Dewangan 		int op_reg_add = pmic->get_ctrl_reg(id) + 1;
9181e0c66f4SLaxman Dewangan 		int sr_reg_add = pmic->get_ctrl_reg(id) + 2;
919faa95fdeSAxel Lin 		int opvsel, srvsel;
920faa95fdeSAxel Lin 
921bd8e2cadSMichał Mirosław 		ret = regmap_read(mfd->regmap, op_reg_add, &opvsel);
922faa95fdeSAxel Lin 		if (ret < 0)
923faa95fdeSAxel Lin 			return ret;
924bd8e2cadSMichał Mirosław 		ret = regmap_read(mfd->regmap, sr_reg_add, &srvsel);
925faa95fdeSAxel Lin 		if (ret < 0)
926faa95fdeSAxel Lin 			return ret;
927faa95fdeSAxel Lin 
9281e0c66f4SLaxman Dewangan 		if (opvsel & VDD1_OP_CMD_MASK) {
9291e0c66f4SLaxman Dewangan 			u8 reg_val = srvsel & VDD1_OP_SEL_MASK;
930faa95fdeSAxel Lin 
931bd8e2cadSMichał Mirosław 			ret = regmap_write(mfd->regmap, op_reg_add, reg_val);
9321e0c66f4SLaxman Dewangan 			if (ret < 0) {
9331e0c66f4SLaxman Dewangan 				dev_err(mfd->dev,
9341e0c66f4SLaxman Dewangan 					"Error in configuring op register\n");
9351e0c66f4SLaxman Dewangan 				return ret;
9361e0c66f4SLaxman Dewangan 			}
9371e0c66f4SLaxman Dewangan 		}
938bd8e2cadSMichał Mirosław 		ret = regmap_write(mfd->regmap, sr_reg_add, 0);
9391e0c66f4SLaxman Dewangan 		if (ret < 0) {
9406d3be300SMasanari Iida 			dev_err(mfd->dev, "Error in setting sr register\n");
9411e0c66f4SLaxman Dewangan 			return ret;
9421e0c66f4SLaxman Dewangan 		}
9431e0c66f4SLaxman Dewangan 	}
9441e0c66f4SLaxman Dewangan 
945bd8e2cadSMichał Mirosław 	ret = regmap_clear_bits(mfd->regmap,
9461e0c66f4SLaxman Dewangan 			TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
947f30b0716SLaxman Dewangan 	if (!ret) {
948f30b0716SLaxman Dewangan 		if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP)
949bd8e2cadSMichał Mirosław 			ret = regmap_set_bits(mfd->regmap,
9501e0c66f4SLaxman Dewangan 				TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
951f30b0716SLaxman Dewangan 		else
952bd8e2cadSMichał Mirosław 			ret = regmap_clear_bits(mfd->regmap,
953f30b0716SLaxman Dewangan 				TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
954f30b0716SLaxman Dewangan 	}
9551e0c66f4SLaxman Dewangan 	if (ret < 0)
9561e0c66f4SLaxman Dewangan 		dev_err(mfd->dev,
9571e0c66f4SLaxman Dewangan 			"Error in configuring SLEEP register\n");
958f30b0716SLaxman Dewangan 
9591e0c66f4SLaxman Dewangan 	return ret;
9601e0c66f4SLaxman Dewangan }
9611e0c66f4SLaxman Dewangan 
9626790178fSRhyland Klein #ifdef CONFIG_OF
9636790178fSRhyland Klein 
9646790178fSRhyland Klein static struct of_regulator_match tps65910_matches[] = {
96533a6943dSLaxman Dewangan 	{ .name = "vrtc",	.driver_data = (void *) &tps65910_regs[0] },
96633a6943dSLaxman Dewangan 	{ .name = "vio",	.driver_data = (void *) &tps65910_regs[1] },
96733a6943dSLaxman Dewangan 	{ .name = "vdd1",	.driver_data = (void *) &tps65910_regs[2] },
96833a6943dSLaxman Dewangan 	{ .name = "vdd2",	.driver_data = (void *) &tps65910_regs[3] },
96933a6943dSLaxman Dewangan 	{ .name = "vdd3",	.driver_data = (void *) &tps65910_regs[4] },
97033a6943dSLaxman Dewangan 	{ .name = "vdig1",	.driver_data = (void *) &tps65910_regs[5] },
97133a6943dSLaxman Dewangan 	{ .name = "vdig2",	.driver_data = (void *) &tps65910_regs[6] },
97233a6943dSLaxman Dewangan 	{ .name = "vpll",	.driver_data = (void *) &tps65910_regs[7] },
97333a6943dSLaxman Dewangan 	{ .name = "vdac",	.driver_data = (void *) &tps65910_regs[8] },
97433a6943dSLaxman Dewangan 	{ .name = "vaux1",	.driver_data = (void *) &tps65910_regs[9] },
97533a6943dSLaxman Dewangan 	{ .name = "vaux2",	.driver_data = (void *) &tps65910_regs[10] },
97633a6943dSLaxman Dewangan 	{ .name = "vaux33",	.driver_data = (void *) &tps65910_regs[11] },
97733a6943dSLaxman Dewangan 	{ .name = "vmmc",	.driver_data = (void *) &tps65910_regs[12] },
97803746dcbSMarkus Pargmann 	{ .name = "vbb",	.driver_data = (void *) &tps65910_regs[13] },
9796790178fSRhyland Klein };
9806790178fSRhyland Klein 
9816790178fSRhyland Klein static struct of_regulator_match tps65911_matches[] = {
98233a6943dSLaxman Dewangan 	{ .name = "vrtc",	.driver_data = (void *) &tps65911_regs[0] },
98333a6943dSLaxman Dewangan 	{ .name = "vio",	.driver_data = (void *) &tps65911_regs[1] },
98433a6943dSLaxman Dewangan 	{ .name = "vdd1",	.driver_data = (void *) &tps65911_regs[2] },
98533a6943dSLaxman Dewangan 	{ .name = "vdd2",	.driver_data = (void *) &tps65911_regs[3] },
98633a6943dSLaxman Dewangan 	{ .name = "vddctrl",	.driver_data = (void *) &tps65911_regs[4] },
98733a6943dSLaxman Dewangan 	{ .name = "ldo1",	.driver_data = (void *) &tps65911_regs[5] },
98833a6943dSLaxman Dewangan 	{ .name = "ldo2",	.driver_data = (void *) &tps65911_regs[6] },
98933a6943dSLaxman Dewangan 	{ .name = "ldo3",	.driver_data = (void *) &tps65911_regs[7] },
99033a6943dSLaxman Dewangan 	{ .name = "ldo4",	.driver_data = (void *) &tps65911_regs[8] },
99133a6943dSLaxman Dewangan 	{ .name = "ldo5",	.driver_data = (void *) &tps65911_regs[9] },
99233a6943dSLaxman Dewangan 	{ .name = "ldo6",	.driver_data = (void *) &tps65911_regs[10] },
99333a6943dSLaxman Dewangan 	{ .name = "ldo7",	.driver_data = (void *) &tps65911_regs[11] },
99433a6943dSLaxman Dewangan 	{ .name = "ldo8",	.driver_data = (void *) &tps65911_regs[12] },
9956790178fSRhyland Klein };
9966790178fSRhyland Klein 
tps65910_parse_dt_reg_data(struct platform_device * pdev,struct of_regulator_match ** tps65910_reg_matches)9976790178fSRhyland Klein static struct tps65910_board *tps65910_parse_dt_reg_data(
99884df8c12SLaxman Dewangan 		struct platform_device *pdev,
99984df8c12SLaxman Dewangan 		struct of_regulator_match **tps65910_reg_matches)
10006790178fSRhyland Klein {
10016790178fSRhyland Klein 	struct tps65910_board *pmic_plat_data;
10026790178fSRhyland Klein 	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
1003c92f5dd2SAxel Lin 	struct device_node *np, *regulators;
10046790178fSRhyland Klein 	struct of_regulator_match *matches;
10056790178fSRhyland Klein 	unsigned int prop;
10066790178fSRhyland Klein 	int idx = 0, ret, count;
10076790178fSRhyland Klein 
10086790178fSRhyland Klein 	pmic_plat_data = devm_kzalloc(&pdev->dev, sizeof(*pmic_plat_data),
10096790178fSRhyland Klein 					GFP_KERNEL);
1010bcb2c0d6SSachin Kamat 	if (!pmic_plat_data)
10116790178fSRhyland Klein 		return NULL;
10126790178fSRhyland Klein 
1013b8b27a44SGuodong Xu 	np = pdev->dev.parent->of_node;
10144ae1ff7fSLaxman Dewangan 	regulators = of_get_child_by_name(np, "regulators");
101592ab953bSLaxman Dewangan 	if (!regulators) {
101692ab953bSLaxman Dewangan 		dev_err(&pdev->dev, "regulator node not found\n");
101792ab953bSLaxman Dewangan 		return NULL;
101892ab953bSLaxman Dewangan 	}
10196790178fSRhyland Klein 
10206790178fSRhyland Klein 	switch (tps65910_chip_id(tps65910)) {
10216790178fSRhyland Klein 	case TPS65910:
10226790178fSRhyland Klein 		count = ARRAY_SIZE(tps65910_matches);
10236790178fSRhyland Klein 		matches = tps65910_matches;
10246790178fSRhyland Klein 		break;
10256790178fSRhyland Klein 	case TPS65911:
10266790178fSRhyland Klein 		count = ARRAY_SIZE(tps65911_matches);
10276790178fSRhyland Klein 		matches = tps65911_matches;
10286790178fSRhyland Klein 		break;
10296790178fSRhyland Klein 	default:
1030c92f5dd2SAxel Lin 		of_node_put(regulators);
10317e9a57e6SLaxman Dewangan 		dev_err(&pdev->dev, "Invalid tps chip version\n");
10326790178fSRhyland Klein 		return NULL;
10336790178fSRhyland Klein 	}
10346790178fSRhyland Klein 
103508337fdaSAxel Lin 	ret = of_regulator_match(&pdev->dev, regulators, matches, count);
1036c92f5dd2SAxel Lin 	of_node_put(regulators);
10376790178fSRhyland Klein 	if (ret < 0) {
10386790178fSRhyland Klein 		dev_err(&pdev->dev, "Error parsing regulator init data: %d\n",
10396790178fSRhyland Klein 			ret);
10406790178fSRhyland Klein 		return NULL;
10416790178fSRhyland Klein 	}
10426790178fSRhyland Klein 
104384df8c12SLaxman Dewangan 	*tps65910_reg_matches = matches;
104484df8c12SLaxman Dewangan 
10456790178fSRhyland Klein 	for (idx = 0; idx < count; idx++) {
104623b11348SAxel Lin 		if (!matches[idx].of_node)
10476790178fSRhyland Klein 			continue;
10486790178fSRhyland Klein 
10496790178fSRhyland Klein 		pmic_plat_data->tps65910_pmic_init_data[idx] =
10506790178fSRhyland Klein 							matches[idx].init_data;
10516790178fSRhyland Klein 
10526790178fSRhyland Klein 		ret = of_property_read_u32(matches[idx].of_node,
10536790178fSRhyland Klein 				"ti,regulator-ext-sleep-control", &prop);
10546790178fSRhyland Klein 		if (!ret)
10556790178fSRhyland Klein 			pmic_plat_data->regulator_ext_sleep_control[idx] = prop;
105619228a6aSLaxman Dewangan 
10576790178fSRhyland Klein 	}
10586790178fSRhyland Klein 
10596790178fSRhyland Klein 	return pmic_plat_data;
10606790178fSRhyland Klein }
10616790178fSRhyland Klein #else
tps65910_parse_dt_reg_data(struct platform_device * pdev,struct of_regulator_match ** tps65910_reg_matches)10626790178fSRhyland Klein static inline struct tps65910_board *tps65910_parse_dt_reg_data(
106384df8c12SLaxman Dewangan 			struct platform_device *pdev,
106484df8c12SLaxman Dewangan 			struct of_regulator_match **tps65910_reg_matches)
10656790178fSRhyland Klein {
106684df8c12SLaxman Dewangan 	*tps65910_reg_matches = NULL;
106774ea0e59SMark Brown 	return NULL;
10686790178fSRhyland Klein }
10696790178fSRhyland Klein #endif
10706790178fSRhyland Klein 
tps65910_probe(struct platform_device * pdev)1071a5023574SBill Pemberton static int tps65910_probe(struct platform_device *pdev)
1072518fb721SGraeme Gregory {
1073518fb721SGraeme Gregory 	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
1074c172708dSMark Brown 	struct regulator_config config = { };
1075a320e3c3SJorge Eduardo Candelaria 	struct tps_info *info;
1076518fb721SGraeme Gregory 	struct regulator_dev *rdev;
1077518fb721SGraeme Gregory 	struct tps65910_reg *pmic;
1078518fb721SGraeme Gregory 	struct tps65910_board *pmic_plat_data;
107984df8c12SLaxman Dewangan 	struct of_regulator_match *tps65910_reg_matches = NULL;
1080518fb721SGraeme Gregory 	int i, err;
1081518fb721SGraeme Gregory 
1082518fb721SGraeme Gregory 	pmic_plat_data = dev_get_platdata(tps65910->dev);
10836790178fSRhyland Klein 	if (!pmic_plat_data && tps65910->dev->of_node)
108484df8c12SLaxman Dewangan 		pmic_plat_data = tps65910_parse_dt_reg_data(pdev,
108584df8c12SLaxman Dewangan 						&tps65910_reg_matches);
10866790178fSRhyland Klein 
10877e9a57e6SLaxman Dewangan 	if (!pmic_plat_data) {
10887e9a57e6SLaxman Dewangan 		dev_err(&pdev->dev, "Platform data not found\n");
1089518fb721SGraeme Gregory 		return -EINVAL;
10907e9a57e6SLaxman Dewangan 	}
1091518fb721SGraeme Gregory 
10929eb0c421SAxel Lin 	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
1093bcb2c0d6SSachin Kamat 	if (!pmic)
1094518fb721SGraeme Gregory 		return -ENOMEM;
1095518fb721SGraeme Gregory 
1096518fb721SGraeme Gregory 	pmic->mfd = tps65910;
1097518fb721SGraeme Gregory 	platform_set_drvdata(pdev, pmic);
1098518fb721SGraeme Gregory 
1099518fb721SGraeme Gregory 	/* Give control of all register to control port */
1100bd8e2cadSMichał Mirosław 	err = regmap_set_bits(pmic->mfd->regmap, TPS65910_DEVCTRL,
1101518fb721SGraeme Gregory 				DEVCTRL_SR_CTL_I2C_SEL_MASK);
1102cd07e370SKangjie Lu 	if (err < 0)
1103cd07e370SKangjie Lu 		return err;
1104518fb721SGraeme Gregory 
1105a320e3c3SJorge Eduardo Candelaria 	switch (tps65910_chip_id(tps65910)) {
1106a320e3c3SJorge Eduardo Candelaria 	case TPS65910:
1107fe953904SMichał Mirosław 		BUILD_BUG_ON(TPS65910_NUM_REGS < ARRAY_SIZE(tps65910_regs));
1108a320e3c3SJorge Eduardo Candelaria 		pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
110939aa9b6eSAxel Lin 		pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
11101e0c66f4SLaxman Dewangan 		pmic->ext_sleep_control = tps65910_ext_sleep_control;
1111a320e3c3SJorge Eduardo Candelaria 		info = tps65910_regs;
11128f9165c9SJan Remmet 		/* Work around silicon erratum SWCZ010: output programmed
11138f9165c9SJan Remmet 		 * voltage level can go higher than expected or crash
11148f9165c9SJan Remmet 		 * Workaround: use no synchronization of DCDC clocks
11158f9165c9SJan Remmet 		 */
1116bd8e2cadSMichał Mirosław 		regmap_clear_bits(pmic->mfd->regmap, TPS65910_DCDCCTRL,
11178f9165c9SJan Remmet 					DCDCCTRL_DCDCCKSYNC_MASK);
1118d04156bcSAxel Lin 		break;
1119a320e3c3SJorge Eduardo Candelaria 	case TPS65911:
1120fe953904SMichał Mirosław 		BUILD_BUG_ON(TPS65910_NUM_REGS < ARRAY_SIZE(tps65911_regs));
1121a320e3c3SJorge Eduardo Candelaria 		pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
112239aa9b6eSAxel Lin 		pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
11231e0c66f4SLaxman Dewangan 		pmic->ext_sleep_control = tps65911_ext_sleep_control;
1124a320e3c3SJorge Eduardo Candelaria 		info = tps65911_regs;
1125d04156bcSAxel Lin 		break;
1126a320e3c3SJorge Eduardo Candelaria 	default:
11277e9a57e6SLaxman Dewangan 		dev_err(&pdev->dev, "Invalid tps chip version\n");
1128a320e3c3SJorge Eduardo Candelaria 		return -ENODEV;
1129a320e3c3SJorge Eduardo Candelaria 	}
1130a320e3c3SJorge Eduardo Candelaria 
1131a86854d0SKees Cook 	pmic->desc = devm_kcalloc(&pdev->dev,
1132a86854d0SKees Cook 				  pmic->num_regulators,
1133a86854d0SKees Cook 				  sizeof(struct regulator_desc),
1134a86854d0SKees Cook 				  GFP_KERNEL);
1135bcb2c0d6SSachin Kamat 	if (!pmic->desc)
113668d8c1cdSLaxman Dewangan 		return -ENOMEM;
113739aa9b6eSAxel Lin 
1138a86854d0SKees Cook 	pmic->info = devm_kcalloc(&pdev->dev,
1139a86854d0SKees Cook 				  pmic->num_regulators,
1140a86854d0SKees Cook 				  sizeof(struct tps_info *),
1141a86854d0SKees Cook 				  GFP_KERNEL);
1142bcb2c0d6SSachin Kamat 	if (!pmic->info)
114368d8c1cdSLaxman Dewangan 		return -ENOMEM;
114439aa9b6eSAxel Lin 
1145a86854d0SKees Cook 	pmic->rdev = devm_kcalloc(&pdev->dev,
1146a86854d0SKees Cook 				  pmic->num_regulators,
1147a86854d0SKees Cook 				  sizeof(struct regulator_dev *),
1148a86854d0SKees Cook 				  GFP_KERNEL);
1149bcb2c0d6SSachin Kamat 	if (!pmic->rdev)
115068d8c1cdSLaxman Dewangan 		return -ENOMEM;
115139aa9b6eSAxel Lin 
1152fe953904SMichał Mirosław 	for (i = 0; i < pmic->num_regulators; i++, info++) {
1153518fb721SGraeme Gregory 		/* Register the regulators */
1154518fb721SGraeme Gregory 		pmic->info[i] = info;
1155518fb721SGraeme Gregory 
1156518fb721SGraeme Gregory 		pmic->desc[i].name = info->name;
1157d2cfdb05SLaxman Dewangan 		pmic->desc[i].supply_name = info->vin_name;
115877fa44d0SAxel Lin 		pmic->desc[i].id = i;
11597d38a3cbSLaxman Dewangan 		pmic->desc[i].n_voltages = info->n_voltages;
116094f48ab3SAxel Lin 		pmic->desc[i].enable_time = info->enable_time_us;
1161518fb721SGraeme Gregory 
1162a320e3c3SJorge Eduardo Candelaria 		if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
1163518fb721SGraeme Gregory 			pmic->desc[i].ops = &tps65910_ops_dcdc;
1164780dc9baSAfzal Mohammed 			pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE *
1165780dc9baSAfzal Mohammed 							VDD1_2_NUM_VOLT_COARSE;
116601bc3a14SAxel Lin 			pmic->desc[i].ramp_delay = 12500;
1167a320e3c3SJorge Eduardo Candelaria 		} else if (i == TPS65910_REG_VDD3) {
116801bc3a14SAxel Lin 			if (tps65910_chip_id(tps65910) == TPS65910) {
1169518fb721SGraeme Gregory 				pmic->desc[i].ops = &tps65910_ops_vdd3;
1170d9fe28f9SAxel Lin 				pmic->desc[i].volt_table = info->voltage_table;
117101bc3a14SAxel Lin 			} else {
1172a320e3c3SJorge Eduardo Candelaria 				pmic->desc[i].ops = &tps65910_ops_dcdc;
117301bc3a14SAxel Lin 				pmic->desc[i].ramp_delay = 5000;
117401bc3a14SAxel Lin 			}
117503746dcbSMarkus Pargmann 		} else if (i == TPS65910_REG_VBB &&
117603746dcbSMarkus Pargmann 				tps65910_chip_id(tps65910) == TPS65910) {
117703746dcbSMarkus Pargmann 			pmic->desc[i].ops = &tps65910_ops_vbb;
117803746dcbSMarkus Pargmann 			pmic->desc[i].volt_table = info->voltage_table;
1179a320e3c3SJorge Eduardo Candelaria 		} else {
1180d9fe28f9SAxel Lin 			if (tps65910_chip_id(tps65910) == TPS65910) {
1181518fb721SGraeme Gregory 				pmic->desc[i].ops = &tps65910_ops;
1182d9fe28f9SAxel Lin 				pmic->desc[i].volt_table = info->voltage_table;
1183d9fe28f9SAxel Lin 			} else {
1184a320e3c3SJorge Eduardo Candelaria 				pmic->desc[i].ops = &tps65911_ops;
1185a320e3c3SJorge Eduardo Candelaria 			}
1186d9fe28f9SAxel Lin 		}
1187518fb721SGraeme Gregory 
11881e0c66f4SLaxman Dewangan 		err = tps65910_set_ext_sleep_config(pmic, i,
11891e0c66f4SLaxman Dewangan 				pmic_plat_data->regulator_ext_sleep_control[i]);
11901e0c66f4SLaxman Dewangan 		/*
11911e0c66f4SLaxman Dewangan 		 * Failing on regulator for configuring externally control
11921e0c66f4SLaxman Dewangan 		 * is not a serious issue, just throw warning.
11931e0c66f4SLaxman Dewangan 		 */
11941e0c66f4SLaxman Dewangan 		if (err < 0)
11951e0c66f4SLaxman Dewangan 			dev_warn(tps65910->dev,
11961e0c66f4SLaxman Dewangan 				"Failed to initialise ext control config\n");
11971e0c66f4SLaxman Dewangan 
1198518fb721SGraeme Gregory 		pmic->desc[i].type = REGULATOR_VOLTAGE;
1199518fb721SGraeme Gregory 		pmic->desc[i].owner = THIS_MODULE;
1200a40a9c43SAxel Lin 		pmic->desc[i].enable_reg = pmic->get_ctrl_reg(i);
1201b8903eb9SAxel Lin 		pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED;
1202518fb721SGraeme Gregory 
1203c172708dSMark Brown 		config.dev = tps65910->dev;
120423b11348SAxel Lin 		config.init_data = pmic_plat_data->tps65910_pmic_init_data[i];
1205c172708dSMark Brown 		config.driver_data = pmic;
1206a40a9c43SAxel Lin 		config.regmap = tps65910->regmap;
1207c172708dSMark Brown 
120884df8c12SLaxman Dewangan 		if (tps65910_reg_matches)
120984df8c12SLaxman Dewangan 			config.of_node = tps65910_reg_matches[i].of_node;
12106790178fSRhyland Klein 
121195095e42SSachin Kamat 		rdev = devm_regulator_register(&pdev->dev, &pmic->desc[i],
121295095e42SSachin Kamat 					       &config);
1213e301df76SDmitry Osipenko 		if (IS_ERR(rdev))
1214e301df76SDmitry Osipenko 			return dev_err_probe(tps65910->dev, PTR_ERR(rdev),
1215518fb721SGraeme Gregory 					     "failed to register %s regulator\n",
1216518fb721SGraeme Gregory 					     pdev->name);
1217518fb721SGraeme Gregory 
1218518fb721SGraeme Gregory 		/* Save regulator for cleanup */
1219518fb721SGraeme Gregory 		pmic->rdev[i] = rdev;
1220518fb721SGraeme Gregory 	}
1221518fb721SGraeme Gregory 	return 0;
1222518fb721SGraeme Gregory }
1223518fb721SGraeme Gregory 
tps65910_shutdown(struct platform_device * pdev)12241e0c66f4SLaxman Dewangan static void tps65910_shutdown(struct platform_device *pdev)
12251e0c66f4SLaxman Dewangan {
12261e0c66f4SLaxman Dewangan 	struct tps65910_reg *pmic = platform_get_drvdata(pdev);
12271e0c66f4SLaxman Dewangan 	int i;
12281e0c66f4SLaxman Dewangan 
12291e0c66f4SLaxman Dewangan 	/*
12301e0c66f4SLaxman Dewangan 	 * Before bootloader jumps to kernel, it makes sure that required
12311e0c66f4SLaxman Dewangan 	 * external control signals are in desired state so that given rails
12321e0c66f4SLaxman Dewangan 	 * can be configure accordingly.
12331e0c66f4SLaxman Dewangan 	 * If rails are configured to be controlled from external control
12341e0c66f4SLaxman Dewangan 	 * then before shutting down/rebooting the system, the external
12351e0c66f4SLaxman Dewangan 	 * control configuration need to be remove from the rails so that
12361e0c66f4SLaxman Dewangan 	 * its output will be available as per register programming even
12371e0c66f4SLaxman Dewangan 	 * if external controls are removed. This is require when the POR
12381e0c66f4SLaxman Dewangan 	 * value of the control signals are not in active state and before
12391e0c66f4SLaxman Dewangan 	 * bootloader initializes it, the system requires the rail output
12401e0c66f4SLaxman Dewangan 	 * to be active for booting.
12411e0c66f4SLaxman Dewangan 	 */
12421e0c66f4SLaxman Dewangan 	for (i = 0; i < pmic->num_regulators; i++) {
12431e0c66f4SLaxman Dewangan 		int err;
12441e0c66f4SLaxman Dewangan 		if (!pmic->rdev[i])
12451e0c66f4SLaxman Dewangan 			continue;
12461e0c66f4SLaxman Dewangan 
12471e0c66f4SLaxman Dewangan 		err = tps65910_set_ext_sleep_config(pmic, i, 0);
12481e0c66f4SLaxman Dewangan 		if (err < 0)
12491e0c66f4SLaxman Dewangan 			dev_err(&pdev->dev,
12501e0c66f4SLaxman Dewangan 				"Error in clearing external control\n");
12511e0c66f4SLaxman Dewangan 	}
12521e0c66f4SLaxman Dewangan }
12531e0c66f4SLaxman Dewangan 
1254518fb721SGraeme Gregory static struct platform_driver tps65910_driver = {
1255518fb721SGraeme Gregory 	.driver = {
1256518fb721SGraeme Gregory 		.name = "tps65910-pmic",
1257*259b93b2SDouglas Anderson 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
1258518fb721SGraeme Gregory 	},
1259518fb721SGraeme Gregory 	.probe = tps65910_probe,
12601e0c66f4SLaxman Dewangan 	.shutdown = tps65910_shutdown,
1261518fb721SGraeme Gregory };
1262518fb721SGraeme Gregory 
tps65910_init(void)1263518fb721SGraeme Gregory static int __init tps65910_init(void)
1264518fb721SGraeme Gregory {
1265518fb721SGraeme Gregory 	return platform_driver_register(&tps65910_driver);
1266518fb721SGraeme Gregory }
1267518fb721SGraeme Gregory subsys_initcall(tps65910_init);
1268518fb721SGraeme Gregory 
tps65910_cleanup(void)1269518fb721SGraeme Gregory static void __exit tps65910_cleanup(void)
1270518fb721SGraeme Gregory {
1271518fb721SGraeme Gregory 	platform_driver_unregister(&tps65910_driver);
1272518fb721SGraeme Gregory }
1273518fb721SGraeme Gregory module_exit(tps65910_cleanup);
1274518fb721SGraeme Gregory 
1275518fb721SGraeme Gregory MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
1276ae0e6544SAxel Lin MODULE_DESCRIPTION("TPS65910/TPS65911 voltage regulator driver");
1277518fb721SGraeme Gregory MODULE_LICENSE("GPL v2");
1278518fb721SGraeme Gregory MODULE_ALIAS("platform:tps65910-pmic");
1279