Blame view

drivers/regulator/tps65910-regulator.c 32.9 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
518fb721d   Graeme Gregory   TPS65910: Add tps...
2
3
4
5
6
7
8
  /*
   * tps65910.c  --  TI tps65910
   *
   * Copyright 2010 Texas Instruments Inc.
   *
   * Author: Graeme Gregory <gg@slimlogic.co.uk>
   * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
518fb721d   Graeme Gregory   TPS65910: Add tps...
9
10
11
12
13
14
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/err.h>
d16da513c   Geert Uytterhoeven   regulator: tps659...
15
  #include <linux/of.h>
518fb721d   Graeme Gregory   TPS65910: Add tps...
16
17
18
  #include <linux/platform_device.h>
  #include <linux/regulator/driver.h>
  #include <linux/regulator/machine.h>
518fb721d   Graeme Gregory   TPS65910: Add tps...
19
20
21
  #include <linux/slab.h>
  #include <linux/gpio.h>
  #include <linux/mfd/tps65910.h>
6790178f5   Rhyland Klein   regulator: tps659...
22
  #include <linux/regulator/of_regulator.h>
518fb721d   Graeme Gregory   TPS65910: Add tps...
23

518fb721d   Graeme Gregory   TPS65910: Add tps...
24
  #define TPS65910_SUPPLY_STATE_ENABLED	0x1
1e0c66f49   Laxman Dewangan   regulator: tps659...
25
26
  #define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 |	\
  			TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 |		\
f30b0716f   Laxman Dewangan   regulator: tps659...
27
28
  			TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 |		\
  			TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP)
518fb721d   Graeme Gregory   TPS65910: Add tps...
29

d9fe28f96   Axel Lin   regulator: tps659...
30
31
32
  /* supported VIO voltages in microvolts */
  static const unsigned int VIO_VSEL_table[] = {
  	1500000, 1800000, 2500000, 3300000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
33
  };
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
34
  /* VSEL tables for TPS65910 specific LDOs and dcdc's */
a9a5659ac   AnilKumar Ch   regulator: tps659...
35
36
37
38
  /* supported VRTC voltages in microvolts */
  static const unsigned int VRTC_VSEL_table[] = {
  	1800000,
  };
d9fe28f96   Axel Lin   regulator: tps659...
39
40
41
  /* supported VDD3 voltages in microvolts */
  static const unsigned int VDD3_VSEL_table[] = {
  	5000000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
42
  };
d9fe28f96   Axel Lin   regulator: tps659...
43
44
45
  /* supported VDIG1 voltages in microvolts */
  static const unsigned int VDIG1_VSEL_table[] = {
  	1200000, 1500000, 1800000, 2700000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
46
  };
d9fe28f96   Axel Lin   regulator: tps659...
47
48
49
  /* supported VDIG2 voltages in microvolts */
  static const unsigned int VDIG2_VSEL_table[] = {
  	1000000, 1100000, 1200000, 1800000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
50
  };
d9fe28f96   Axel Lin   regulator: tps659...
51
52
53
  /* supported VPLL voltages in microvolts */
  static const unsigned int VPLL_VSEL_table[] = {
  	1000000, 1100000, 1800000, 2500000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
54
  };
d9fe28f96   Axel Lin   regulator: tps659...
55
56
57
  /* supported VDAC voltages in microvolts */
  static const unsigned int VDAC_VSEL_table[] = {
  	1800000, 2600000, 2800000, 2850000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
58
  };
d9fe28f96   Axel Lin   regulator: tps659...
59
60
61
  /* supported VAUX1 voltages in microvolts */
  static const unsigned int VAUX1_VSEL_table[] = {
  	1800000, 2500000, 2800000, 2850000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
62
  };
d9fe28f96   Axel Lin   regulator: tps659...
63
64
65
  /* supported VAUX2 voltages in microvolts */
  static const unsigned int VAUX2_VSEL_table[] = {
  	1800000, 2800000, 2900000, 3300000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
66
  };
d9fe28f96   Axel Lin   regulator: tps659...
67
68
69
  /* supported VAUX33 voltages in microvolts */
  static const unsigned int VAUX33_VSEL_table[] = {
  	1800000, 2000000, 2800000, 3300000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
70
  };
d9fe28f96   Axel Lin   regulator: tps659...
71
72
73
  /* supported VMMC voltages in microvolts */
  static const unsigned int VMMC_VSEL_table[] = {
  	1800000, 2800000, 3000000, 3300000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
74
  };
03746dcbd   Markus Pargmann   regulator: tps659...
75
76
77
78
  /* supported BBCH voltages in microvolts */
  static const unsigned int VBB_VSEL_table[] = {
  	3000000, 2520000, 3150000, 5000000,
  };
518fb721d   Graeme Gregory   TPS65910: Add tps...
79
80
  struct tps_info {
  	const char *name;
19228a6a5   Laxman Dewangan   regulator: tps659...
81
  	const char *vin_name;
7d38a3cb9   Laxman Dewangan   regulator: tps659...
82
  	u8 n_voltages;
d9fe28f96   Axel Lin   regulator: tps659...
83
  	const unsigned int *voltage_table;
0651eed5e   Laxman Dewangan   regulator: tps659...
84
  	int enable_time_us;
518fb721d   Graeme Gregory   TPS65910: Add tps...
85
86
87
88
  };
  
  static struct tps_info tps65910_regs[] = {
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
89
  		.name = "vrtc",
19228a6a5   Laxman Dewangan   regulator: tps659...
90
  		.vin_name = "vcc7",
a9a5659ac   AnilKumar Ch   regulator: tps659...
91
92
  		.n_voltages = ARRAY_SIZE(VRTC_VSEL_table),
  		.voltage_table = VRTC_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
93
  		.enable_time_us = 2200,
518fb721d   Graeme Gregory   TPS65910: Add tps...
94
95
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
96
  		.name = "vio",
19228a6a5   Laxman Dewangan   regulator: tps659...
97
  		.vin_name = "vccio",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
98
99
  		.n_voltages = ARRAY_SIZE(VIO_VSEL_table),
  		.voltage_table = VIO_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
100
  		.enable_time_us = 350,
518fb721d   Graeme Gregory   TPS65910: Add tps...
101
102
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
103
  		.name = "vdd1",
19228a6a5   Laxman Dewangan   regulator: tps659...
104
  		.vin_name = "vcc1",
0651eed5e   Laxman Dewangan   regulator: tps659...
105
  		.enable_time_us = 350,
518fb721d   Graeme Gregory   TPS65910: Add tps...
106
107
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
108
  		.name = "vdd2",
19228a6a5   Laxman Dewangan   regulator: tps659...
109
  		.vin_name = "vcc2",
0651eed5e   Laxman Dewangan   regulator: tps659...
110
  		.enable_time_us = 350,
518fb721d   Graeme Gregory   TPS65910: Add tps...
111
112
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
113
  		.name = "vdd3",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
114
115
  		.n_voltages = ARRAY_SIZE(VDD3_VSEL_table),
  		.voltage_table = VDD3_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
116
  		.enable_time_us = 200,
518fb721d   Graeme Gregory   TPS65910: Add tps...
117
118
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
119
  		.name = "vdig1",
19228a6a5   Laxman Dewangan   regulator: tps659...
120
  		.vin_name = "vcc6",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
121
122
  		.n_voltages = ARRAY_SIZE(VDIG1_VSEL_table),
  		.voltage_table = VDIG1_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
123
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
124
125
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
126
  		.name = "vdig2",
19228a6a5   Laxman Dewangan   regulator: tps659...
127
  		.vin_name = "vcc6",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
128
129
  		.n_voltages = ARRAY_SIZE(VDIG2_VSEL_table),
  		.voltage_table = VDIG2_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
130
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
131
132
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
133
  		.name = "vpll",
19228a6a5   Laxman Dewangan   regulator: tps659...
134
  		.vin_name = "vcc5",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
135
136
  		.n_voltages = ARRAY_SIZE(VPLL_VSEL_table),
  		.voltage_table = VPLL_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
137
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
138
139
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
140
  		.name = "vdac",
19228a6a5   Laxman Dewangan   regulator: tps659...
141
  		.vin_name = "vcc5",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
142
143
  		.n_voltages = ARRAY_SIZE(VDAC_VSEL_table),
  		.voltage_table = VDAC_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
144
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
145
146
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
147
  		.name = "vaux1",
19228a6a5   Laxman Dewangan   regulator: tps659...
148
  		.vin_name = "vcc4",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
149
150
  		.n_voltages = ARRAY_SIZE(VAUX1_VSEL_table),
  		.voltage_table = VAUX1_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
151
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
152
153
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
154
  		.name = "vaux2",
19228a6a5   Laxman Dewangan   regulator: tps659...
155
  		.vin_name = "vcc4",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
156
157
  		.n_voltages = ARRAY_SIZE(VAUX2_VSEL_table),
  		.voltage_table = VAUX2_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
158
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
159
160
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
161
  		.name = "vaux33",
19228a6a5   Laxman Dewangan   regulator: tps659...
162
  		.vin_name = "vcc3",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
163
164
  		.n_voltages = ARRAY_SIZE(VAUX33_VSEL_table),
  		.voltage_table = VAUX33_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
165
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
166
167
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
168
  		.name = "vmmc",
19228a6a5   Laxman Dewangan   regulator: tps659...
169
  		.vin_name = "vcc3",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
170
171
  		.n_voltages = ARRAY_SIZE(VMMC_VSEL_table),
  		.voltage_table = VMMC_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
172
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
173
  	},
03746dcbd   Markus Pargmann   regulator: tps659...
174
175
176
177
178
179
  	{
  		.name = "vbb",
  		.vin_name = "vcc7",
  		.n_voltages = ARRAY_SIZE(VBB_VSEL_table),
  		.voltage_table = VBB_VSEL_table,
  	},
518fb721d   Graeme Gregory   TPS65910: Add tps...
180
  };
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
181
182
  static struct tps_info tps65911_regs[] = {
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
183
  		.name = "vrtc",
19228a6a5   Laxman Dewangan   regulator: tps659...
184
  		.vin_name = "vcc7",
0651eed5e   Laxman Dewangan   regulator: tps659...
185
  		.enable_time_us = 2200,
c2f8efd76   Laxman Dewangan   regulator: tps659...
186
187
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
188
  		.name = "vio",
19228a6a5   Laxman Dewangan   regulator: tps659...
189
  		.vin_name = "vccio",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
190
191
  		.n_voltages = ARRAY_SIZE(VIO_VSEL_table),
  		.voltage_table = VIO_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
192
  		.enable_time_us = 350,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
193
194
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
195
  		.name = "vdd1",
19228a6a5   Laxman Dewangan   regulator: tps659...
196
  		.vin_name = "vcc1",
7be531883   Laxman Dewangan   regulator: tps659...
197
  		.n_voltages = 0x4C,
0651eed5e   Laxman Dewangan   regulator: tps659...
198
  		.enable_time_us = 350,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
199
200
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
201
  		.name = "vdd2",
19228a6a5   Laxman Dewangan   regulator: tps659...
202
  		.vin_name = "vcc2",
7be531883   Laxman Dewangan   regulator: tps659...
203
  		.n_voltages = 0x4C,
0651eed5e   Laxman Dewangan   regulator: tps659...
204
  		.enable_time_us = 350,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
205
206
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
207
  		.name = "vddctrl",
7be531883   Laxman Dewangan   regulator: tps659...
208
  		.n_voltages = 0x44,
0651eed5e   Laxman Dewangan   regulator: tps659...
209
  		.enable_time_us = 900,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
210
211
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
212
  		.name = "ldo1",
19228a6a5   Laxman Dewangan   regulator: tps659...
213
  		.vin_name = "vcc6",
7be531883   Laxman Dewangan   regulator: tps659...
214
  		.n_voltages = 0x33,
0651eed5e   Laxman Dewangan   regulator: tps659...
215
  		.enable_time_us = 420,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
216
217
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
218
  		.name = "ldo2",
19228a6a5   Laxman Dewangan   regulator: tps659...
219
  		.vin_name = "vcc6",
7be531883   Laxman Dewangan   regulator: tps659...
220
  		.n_voltages = 0x33,
0651eed5e   Laxman Dewangan   regulator: tps659...
221
  		.enable_time_us = 420,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
222
223
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
224
  		.name = "ldo3",
19228a6a5   Laxman Dewangan   regulator: tps659...
225
  		.vin_name = "vcc5",
7be531883   Laxman Dewangan   regulator: tps659...
226
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
227
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
228
229
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
230
  		.name = "ldo4",
19228a6a5   Laxman Dewangan   regulator: tps659...
231
  		.vin_name = "vcc5",
7be531883   Laxman Dewangan   regulator: tps659...
232
  		.n_voltages = 0x33,
0651eed5e   Laxman Dewangan   regulator: tps659...
233
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
234
235
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
236
  		.name = "ldo5",
19228a6a5   Laxman Dewangan   regulator: tps659...
237
  		.vin_name = "vcc4",
7be531883   Laxman Dewangan   regulator: tps659...
238
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
239
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
240
241
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
242
  		.name = "ldo6",
19228a6a5   Laxman Dewangan   regulator: tps659...
243
  		.vin_name = "vcc3",
7be531883   Laxman Dewangan   regulator: tps659...
244
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
245
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
246
247
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
248
  		.name = "ldo7",
19228a6a5   Laxman Dewangan   regulator: tps659...
249
  		.vin_name = "vcc3",
7be531883   Laxman Dewangan   regulator: tps659...
250
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
251
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
252
253
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
254
  		.name = "ldo8",
19228a6a5   Laxman Dewangan   regulator: tps659...
255
  		.vin_name = "vcc3",
7be531883   Laxman Dewangan   regulator: tps659...
256
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
257
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
258
259
  	},
  };
1e0c66f49   Laxman Dewangan   regulator: tps659...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
  #define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits))
  static unsigned int tps65910_ext_sleep_control[] = {
  	0,
  	EXT_CONTROL_REG_BITS(VIO,    1, 0),
  	EXT_CONTROL_REG_BITS(VDD1,   1, 1),
  	EXT_CONTROL_REG_BITS(VDD2,   1, 2),
  	EXT_CONTROL_REG_BITS(VDD3,   1, 3),
  	EXT_CONTROL_REG_BITS(VDIG1,  0, 1),
  	EXT_CONTROL_REG_BITS(VDIG2,  0, 2),
  	EXT_CONTROL_REG_BITS(VPLL,   0, 6),
  	EXT_CONTROL_REG_BITS(VDAC,   0, 7),
  	EXT_CONTROL_REG_BITS(VAUX1,  0, 3),
  	EXT_CONTROL_REG_BITS(VAUX2,  0, 4),
  	EXT_CONTROL_REG_BITS(VAUX33, 0, 5),
  	EXT_CONTROL_REG_BITS(VMMC,   0, 0),
  };
  
  static unsigned int tps65911_ext_sleep_control[] = {
  	0,
  	EXT_CONTROL_REG_BITS(VIO,     1, 0),
  	EXT_CONTROL_REG_BITS(VDD1,    1, 1),
  	EXT_CONTROL_REG_BITS(VDD2,    1, 2),
  	EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3),
  	EXT_CONTROL_REG_BITS(LDO1,    0, 1),
  	EXT_CONTROL_REG_BITS(LDO2,    0, 2),
  	EXT_CONTROL_REG_BITS(LDO3,    0, 7),
  	EXT_CONTROL_REG_BITS(LDO4,    0, 6),
  	EXT_CONTROL_REG_BITS(LDO5,    0, 3),
  	EXT_CONTROL_REG_BITS(LDO6,    0, 0),
  	EXT_CONTROL_REG_BITS(LDO7,    0, 5),
  	EXT_CONTROL_REG_BITS(LDO8,    0, 4),
  };
518fb721d   Graeme Gregory   TPS65910: Add tps...
292
  struct tps65910_reg {
39aa9b6e3   Axel Lin   regulator: tps659...
293
  	struct regulator_desc *desc;
518fb721d   Graeme Gregory   TPS65910: Add tps...
294
  	struct tps65910 *mfd;
39aa9b6e3   Axel Lin   regulator: tps659...
295
296
  	struct regulator_dev **rdev;
  	struct tps_info **info;
39aa9b6e3   Axel Lin   regulator: tps659...
297
  	int num_regulators;
518fb721d   Graeme Gregory   TPS65910: Add tps...
298
  	int mode;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
299
  	int  (*get_ctrl_reg)(int);
1e0c66f49   Laxman Dewangan   regulator: tps659...
300
301
  	unsigned int *ext_sleep_control;
  	unsigned int board_ext_control[TPS65910_NUM_REGS];
518fb721d   Graeme Gregory   TPS65910: Add tps...
302
  };
518fb721d   Graeme Gregory   TPS65910: Add tps...
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
  static int tps65910_get_ctrl_register(int id)
  {
  	switch (id) {
  	case TPS65910_REG_VRTC:
  		return TPS65910_VRTC;
  	case TPS65910_REG_VIO:
  		return TPS65910_VIO;
  	case TPS65910_REG_VDD1:
  		return TPS65910_VDD1;
  	case TPS65910_REG_VDD2:
  		return TPS65910_VDD2;
  	case TPS65910_REG_VDD3:
  		return TPS65910_VDD3;
  	case TPS65910_REG_VDIG1:
  		return TPS65910_VDIG1;
  	case TPS65910_REG_VDIG2:
  		return TPS65910_VDIG2;
  	case TPS65910_REG_VPLL:
  		return TPS65910_VPLL;
  	case TPS65910_REG_VDAC:
  		return TPS65910_VDAC;
  	case TPS65910_REG_VAUX1:
  		return TPS65910_VAUX1;
  	case TPS65910_REG_VAUX2:
  		return TPS65910_VAUX2;
  	case TPS65910_REG_VAUX33:
  		return TPS65910_VAUX33;
  	case TPS65910_REG_VMMC:
  		return TPS65910_VMMC;
03746dcbd   Markus Pargmann   regulator: tps659...
332
333
  	case TPS65910_REG_VBB:
  		return TPS65910_BBCH;
518fb721d   Graeme Gregory   TPS65910: Add tps...
334
335
336
337
  	default:
  		return -EINVAL;
  	}
  }
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
  static int tps65911_get_ctrl_register(int id)
  {
  	switch (id) {
  	case TPS65910_REG_VRTC:
  		return TPS65910_VRTC;
  	case TPS65910_REG_VIO:
  		return TPS65910_VIO;
  	case TPS65910_REG_VDD1:
  		return TPS65910_VDD1;
  	case TPS65910_REG_VDD2:
  		return TPS65910_VDD2;
  	case TPS65911_REG_VDDCTRL:
  		return TPS65911_VDDCTRL;
  	case TPS65911_REG_LDO1:
  		return TPS65911_LDO1;
  	case TPS65911_REG_LDO2:
  		return TPS65911_LDO2;
  	case TPS65911_REG_LDO3:
  		return TPS65911_LDO3;
  	case TPS65911_REG_LDO4:
  		return TPS65911_LDO4;
  	case TPS65911_REG_LDO5:
  		return TPS65911_LDO5;
  	case TPS65911_REG_LDO6:
  		return TPS65911_LDO6;
  	case TPS65911_REG_LDO7:
  		return TPS65911_LDO7;
  	case TPS65911_REG_LDO8:
  		return TPS65911_LDO8;
  	default:
  		return -EINVAL;
  	}
  }
518fb721d   Graeme Gregory   TPS65910: Add tps...
371
372
373
374
375
  static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
  	struct tps65910 *mfd = pmic->mfd;
  	int reg, value, id = rdev_get_id(dev);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
376
377
  
  	reg = pmic->get_ctrl_reg(id);
518fb721d   Graeme Gregory   TPS65910: Add tps...
378
379
380
381
382
  	if (reg < 0)
  		return reg;
  
  	switch (mode) {
  	case REGULATOR_MODE_NORMAL:
faa95fde4   Axel Lin   regulator: tps659...
383
384
385
  		return tps65910_reg_update_bits(pmic->mfd, reg,
  						LDO_ST_MODE_BIT | LDO_ST_ON_BIT,
  						LDO_ST_ON_BIT);
518fb721d   Graeme Gregory   TPS65910: Add tps...
386
387
  	case REGULATOR_MODE_IDLE:
  		value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT;
3f7e82759   Rhyland Klein   mfd: Commonize tp...
388
  		return tps65910_reg_set_bits(mfd, reg, value);
518fb721d   Graeme Gregory   TPS65910: Add tps...
389
  	case REGULATOR_MODE_STANDBY:
3f7e82759   Rhyland Klein   mfd: Commonize tp...
390
  		return tps65910_reg_clear_bits(mfd, reg, LDO_ST_ON_BIT);
518fb721d   Graeme Gregory   TPS65910: Add tps...
391
392
393
394
395
396
397
398
  	}
  
  	return -EINVAL;
  }
  
  static unsigned int tps65910_get_mode(struct regulator_dev *dev)
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
faa95fde4   Axel Lin   regulator: tps659...
399
  	int ret, reg, value, id = rdev_get_id(dev);
518fb721d   Graeme Gregory   TPS65910: Add tps...
400

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
401
  	reg = pmic->get_ctrl_reg(id);
518fb721d   Graeme Gregory   TPS65910: Add tps...
402
403
  	if (reg < 0)
  		return reg;
faa95fde4   Axel Lin   regulator: tps659...
404
405
406
  	ret = tps65910_reg_read(pmic->mfd, reg, &value);
  	if (ret < 0)
  		return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
407

585993932   Axel Lin   regulator: Fix th...
408
  	if (!(value & LDO_ST_ON_BIT))
518fb721d   Graeme Gregory   TPS65910: Add tps...
409
410
411
412
413
414
  		return REGULATOR_MODE_STANDBY;
  	else if (value & LDO_ST_MODE_BIT)
  		return REGULATOR_MODE_IDLE;
  	else
  		return REGULATOR_MODE_NORMAL;
  }
18039e0f1   Laxman Dewangan   regulator: tps659...
415
  static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev)
518fb721d   Graeme Gregory   TPS65910: Add tps...
416
417
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
faa95fde4   Axel Lin   regulator: tps659...
418
  	int ret, id = rdev_get_id(dev);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
419
  	int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0;
518fb721d   Graeme Gregory   TPS65910: Add tps...
420
421
422
  
  	switch (id) {
  	case TPS65910_REG_VDD1:
faa95fde4   Axel Lin   regulator: tps659...
423
424
425
426
427
428
  		ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_OP, &opvsel);
  		if (ret < 0)
  			return ret;
  		ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1, &mult);
  		if (ret < 0)
  			return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
429
  		mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT;
faa95fde4   Axel Lin   regulator: tps659...
430
431
432
  		ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_SR, &srvsel);
  		if (ret < 0)
  			return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
433
434
435
  		sr = opvsel & VDD1_OP_CMD_MASK;
  		opvsel &= VDD1_OP_SEL_MASK;
  		srvsel &= VDD1_SR_SEL_MASK;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
436
  		vselmax = 75;
518fb721d   Graeme Gregory   TPS65910: Add tps...
437
438
  		break;
  	case TPS65910_REG_VDD2:
faa95fde4   Axel Lin   regulator: tps659...
439
440
441
442
443
444
  		ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_OP, &opvsel);
  		if (ret < 0)
  			return ret;
  		ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2, &mult);
  		if (ret < 0)
  			return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
445
  		mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT;
faa95fde4   Axel Lin   regulator: tps659...
446
447
448
  		ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_SR, &srvsel);
  		if (ret < 0)
  			return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
449
450
451
  		sr = opvsel & VDD2_OP_CMD_MASK;
  		opvsel &= VDD2_OP_SEL_MASK;
  		srvsel &= VDD2_SR_SEL_MASK;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
452
453
454
  		vselmax = 75;
  		break;
  	case TPS65911_REG_VDDCTRL:
faa95fde4   Axel Lin   regulator: tps659...
455
456
457
458
459
460
461
462
  		ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_OP,
  					&opvsel);
  		if (ret < 0)
  			return ret;
  		ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_SR,
  					&srvsel);
  		if (ret < 0)
  			return ret;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
463
464
465
466
  		sr = opvsel & VDDCTRL_OP_CMD_MASK;
  		opvsel &= VDDCTRL_OP_SEL_MASK;
  		srvsel &= VDDCTRL_SR_SEL_MASK;
  		vselmax = 64;
518fb721d   Graeme Gregory   TPS65910: Add tps...
467
468
469
470
471
  		break;
  	}
  
  	/* multiplier 0 == 1 but 2,3 normal */
  	if (!mult)
4b5792704   Jingoo Han   regulator: tps659...
472
  		mult = 1;
518fb721d   Graeme Gregory   TPS65910: Add tps...
473
474
  
  	if (sr) {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
475
476
477
478
479
  		/* normalise to valid range */
  		if (srvsel < 3)
  			srvsel = 3;
  		if (srvsel > vselmax)
  			srvsel = vselmax;
18039e0f1   Laxman Dewangan   regulator: tps659...
480
  		return srvsel - 3;
518fb721d   Graeme Gregory   TPS65910: Add tps...
481
  	} else {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
482
483
484
485
486
  		/* normalise to valid range*/
  		if (opvsel < 3)
  			opvsel = 3;
  		if (opvsel > vselmax)
  			opvsel = vselmax;
18039e0f1   Laxman Dewangan   regulator: tps659...
487
  		return opvsel - 3;
518fb721d   Graeme Gregory   TPS65910: Add tps...
488
  	}
18039e0f1   Laxman Dewangan   regulator: tps659...
489
  	return -EINVAL;
518fb721d   Graeme Gregory   TPS65910: Add tps...
490
  }
1f904fd1c   Axel Lin   regulator: tps659...
491
  static int tps65910_get_voltage_sel(struct regulator_dev *dev)
518fb721d   Graeme Gregory   TPS65910: Add tps...
492
493
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
faa95fde4   Axel Lin   regulator: tps659...
494
  	int ret, reg, value, id = rdev_get_id(dev);
518fb721d   Graeme Gregory   TPS65910: Add tps...
495

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
496
  	reg = pmic->get_ctrl_reg(id);
518fb721d   Graeme Gregory   TPS65910: Add tps...
497
498
  	if (reg < 0)
  		return reg;
faa95fde4   Axel Lin   regulator: tps659...
499
500
501
  	ret = tps65910_reg_read(pmic->mfd, reg, &value);
  	if (ret < 0)
  		return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
502
503
504
505
506
507
508
509
510
511
512
513
514
515
  
  	switch (id) {
  	case TPS65910_REG_VIO:
  	case TPS65910_REG_VDIG1:
  	case TPS65910_REG_VDIG2:
  	case TPS65910_REG_VPLL:
  	case TPS65910_REG_VDAC:
  	case TPS65910_REG_VAUX1:
  	case TPS65910_REG_VAUX2:
  	case TPS65910_REG_VAUX33:
  	case TPS65910_REG_VMMC:
  		value &= LDO_SEL_MASK;
  		value >>= LDO_SEL_SHIFT;
  		break;
03746dcbd   Markus Pargmann   regulator: tps659...
516
517
518
519
  	case TPS65910_REG_VBB:
  		value &= BBCH_BBSEL_MASK;
  		value >>= BBCH_BBSEL_SHIFT;
  		break;
518fb721d   Graeme Gregory   TPS65910: Add tps...
520
521
522
  	default:
  		return -EINVAL;
  	}
1f904fd1c   Axel Lin   regulator: tps659...
523
  	return value;
518fb721d   Graeme Gregory   TPS65910: Add tps...
524
525
526
527
  }
  
  static int tps65910_get_voltage_vdd3(struct regulator_dev *dev)
  {
d9fe28f96   Axel Lin   regulator: tps659...
528
  	return dev->desc->volt_table[0];
518fb721d   Graeme Gregory   TPS65910: Add tps...
529
  }
1f904fd1c   Axel Lin   regulator: tps659...
530
  static int tps65911_get_voltage_sel(struct regulator_dev *dev)
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
531
532
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
faa95fde4   Axel Lin   regulator: tps659...
533
534
  	int ret, id = rdev_get_id(dev);
  	unsigned int value, reg;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
535
536
  
  	reg = pmic->get_ctrl_reg(id);
faa95fde4   Axel Lin   regulator: tps659...
537
538
539
  	ret = tps65910_reg_read(pmic->mfd, reg, &value);
  	if (ret < 0)
  		return ret;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
540
541
542
543
544
545
546
  
  	switch (id) {
  	case TPS65911_REG_LDO1:
  	case TPS65911_REG_LDO2:
  	case TPS65911_REG_LDO4:
  		value &= LDO1_SEL_MASK;
  		value >>= LDO_SEL_SHIFT;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
547
548
549
550
551
552
553
554
  		break;
  	case TPS65911_REG_LDO3:
  	case TPS65911_REG_LDO5:
  	case TPS65911_REG_LDO6:
  	case TPS65911_REG_LDO7:
  	case TPS65911_REG_LDO8:
  		value &= LDO3_SEL_MASK;
  		value >>= LDO_SEL_SHIFT;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
555
556
  		break;
  	case TPS65910_REG_VIO:
e882eae80   Laxman Dewangan   regulator: tps659...
557
558
  		value &= LDO_SEL_MASK;
  		value >>= LDO_SEL_SHIFT;
1f904fd1c   Axel Lin   regulator: tps659...
559
  		break;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
560
561
562
  	default:
  		return -EINVAL;
  	}
1f904fd1c   Axel Lin   regulator: tps659...
563
  	return value;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
564
  }
94732b97c   Axel Lin   regulator: Rename...
565
566
  static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev,
  					 unsigned selector)
518fb721d   Graeme Gregory   TPS65910: Add tps...
567
568
569
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
  	int id = rdev_get_id(dev), vsel;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
570
  	int dcdc_mult = 0;
518fb721d   Graeme Gregory   TPS65910: Add tps...
571

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
572
573
  	switch (id) {
  	case TPS65910_REG_VDD1:
780dc9ba4   Afzal Mohammed   regulator: TPS659...
574
  		dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
575
576
  		if (dcdc_mult == 1)
  			dcdc_mult--;
780dc9ba4   Afzal Mohammed   regulator: TPS659...
577
  		vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
518fb721d   Graeme Gregory   TPS65910: Add tps...
578

faa95fde4   Axel Lin   regulator: tps659...
579
580
581
582
  		tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD1,
  					 VDD1_VGAIN_SEL_MASK,
  					 dcdc_mult << VDD1_VGAIN_SEL_SHIFT);
  		tps65910_reg_write(pmic->mfd, TPS65910_VDD1_OP, vsel);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
583
584
  		break;
  	case TPS65910_REG_VDD2:
780dc9ba4   Afzal Mohammed   regulator: TPS659...
585
  		dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
586
587
  		if (dcdc_mult == 1)
  			dcdc_mult--;
780dc9ba4   Afzal Mohammed   regulator: TPS659...
588
  		vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
589

faa95fde4   Axel Lin   regulator: tps659...
590
591
592
593
  		tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD2,
  					 VDD1_VGAIN_SEL_MASK,
  					 dcdc_mult << VDD2_VGAIN_SEL_SHIFT);
  		tps65910_reg_write(pmic->mfd, TPS65910_VDD2_OP, vsel);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
594
595
  		break;
  	case TPS65911_REG_VDDCTRL:
c4632aed3   Laxman Dewangan   regulator: tps659...
596
  		vsel = selector + 3;
faa95fde4   Axel Lin   regulator: tps659...
597
  		tps65910_reg_write(pmic->mfd, TPS65911_VDDCTRL_OP, vsel);
518fb721d   Graeme Gregory   TPS65910: Add tps...
598
599
600
601
  	}
  
  	return 0;
  }
94732b97c   Axel Lin   regulator: Rename...
602
603
  static int tps65910_set_voltage_sel(struct regulator_dev *dev,
  				    unsigned selector)
518fb721d   Graeme Gregory   TPS65910: Add tps...
604
605
606
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
  	int reg, id = rdev_get_id(dev);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
607
  	reg = pmic->get_ctrl_reg(id);
518fb721d   Graeme Gregory   TPS65910: Add tps...
608
609
610
611
612
613
614
615
616
617
618
619
620
  	if (reg < 0)
  		return reg;
  
  	switch (id) {
  	case TPS65910_REG_VIO:
  	case TPS65910_REG_VDIG1:
  	case TPS65910_REG_VDIG2:
  	case TPS65910_REG_VPLL:
  	case TPS65910_REG_VDAC:
  	case TPS65910_REG_VAUX1:
  	case TPS65910_REG_VAUX2:
  	case TPS65910_REG_VAUX33:
  	case TPS65910_REG_VMMC:
faa95fde4   Axel Lin   regulator: tps659...
621
622
  		return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
  						selector << LDO_SEL_SHIFT);
03746dcbd   Markus Pargmann   regulator: tps659...
623
624
625
  	case TPS65910_REG_VBB:
  		return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK,
  						selector << BBCH_BBSEL_SHIFT);
518fb721d   Graeme Gregory   TPS65910: Add tps...
626
627
628
629
  	}
  
  	return -EINVAL;
  }
94732b97c   Axel Lin   regulator: Rename...
630
631
  static int tps65911_set_voltage_sel(struct regulator_dev *dev,
  				    unsigned selector)
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
632
633
634
635
636
637
638
639
640
641
642
643
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
  	int reg, id = rdev_get_id(dev);
  
  	reg = pmic->get_ctrl_reg(id);
  	if (reg < 0)
  		return reg;
  
  	switch (id) {
  	case TPS65911_REG_LDO1:
  	case TPS65911_REG_LDO2:
  	case TPS65911_REG_LDO4:
faa95fde4   Axel Lin   regulator: tps659...
644
645
  		return tps65910_reg_update_bits(pmic->mfd, reg, LDO1_SEL_MASK,
  						selector << LDO_SEL_SHIFT);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
646
647
648
649
650
  	case TPS65911_REG_LDO3:
  	case TPS65911_REG_LDO5:
  	case TPS65911_REG_LDO6:
  	case TPS65911_REG_LDO7:
  	case TPS65911_REG_LDO8:
faa95fde4   Axel Lin   regulator: tps659...
651
652
  		return tps65910_reg_update_bits(pmic->mfd, reg, LDO3_SEL_MASK,
  						selector << LDO_SEL_SHIFT);
e882eae80   Laxman Dewangan   regulator: tps659...
653
  	case TPS65910_REG_VIO:
faa95fde4   Axel Lin   regulator: tps659...
654
655
  		return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
  						selector << LDO_SEL_SHIFT);
03746dcbd   Markus Pargmann   regulator: tps659...
656
657
658
  	case TPS65910_REG_VBB:
  		return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK,
  						selector << BBCH_BBSEL_SHIFT);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
659
660
661
662
  	}
  
  	return -EINVAL;
  }
518fb721d   Graeme Gregory   TPS65910: Add tps...
663
664
665
  static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
  					unsigned selector)
  {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
666
  	int volt, mult = 1, id = rdev_get_id(dev);
518fb721d   Graeme Gregory   TPS65910: Add tps...
667

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
668
669
670
  	switch (id) {
  	case TPS65910_REG_VDD1:
  	case TPS65910_REG_VDD2:
780dc9ba4   Afzal Mohammed   regulator: TPS659...
671
  		mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
672
  		volt = VDD1_2_MIN_VOLT +
4b5792704   Jingoo Han   regulator: tps659...
673
  			(selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;
d04156bca   Axel Lin   regulator: tps659...
674
  		break;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
675
676
  	case TPS65911_REG_VDDCTRL:
  		volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
d04156bca   Axel Lin   regulator: tps659...
677
678
679
680
  		break;
  	default:
  		BUG();
  		return -EINVAL;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
681
  	}
518fb721d   Graeme Gregory   TPS65910: Add tps...
682
683
684
  
  	return  volt * 100 * mult;
  }
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
685
686
687
688
  static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
  	int step_mv = 0, id = rdev_get_id(dev);
4b5792704   Jingoo Han   regulator: tps659...
689
  	switch (id) {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
  	case TPS65911_REG_LDO1:
  	case TPS65911_REG_LDO2:
  	case TPS65911_REG_LDO4:
  		/* The first 5 values of the selector correspond to 1V */
  		if (selector < 5)
  			selector = 0;
  		else
  			selector -= 4;
  
  		step_mv = 50;
  		break;
  	case TPS65911_REG_LDO3:
  	case TPS65911_REG_LDO5:
  	case TPS65911_REG_LDO6:
  	case TPS65911_REG_LDO7:
  	case TPS65911_REG_LDO8:
  		/* The first 3 values of the selector correspond to 1V */
  		if (selector < 3)
  			selector = 0;
  		else
  			selector -= 2;
  
  		step_mv = 100;
  		break;
  	case TPS65910_REG_VIO:
d9fe28f96   Axel Lin   regulator: tps659...
715
  		return pmic->info[id]->voltage_table[selector];
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
716
717
718
719
720
721
  	default:
  		return -EINVAL;
  	}
  
  	return (LDO_MIN_VOLT + selector * step_mv) * 1000;
  }
518fb721d   Graeme Gregory   TPS65910: Add tps...
722
723
  /* Regulator ops (except VRTC) */
  static struct regulator_ops tps65910_ops_dcdc = {
a40a9c436   Axel Lin   regulator: tps659...
724
725
726
  	.is_enabled		= regulator_is_enabled_regmap,
  	.enable			= regulator_enable_regmap,
  	.disable		= regulator_disable_regmap,
518fb721d   Graeme Gregory   TPS65910: Add tps...
727
728
  	.set_mode		= tps65910_set_mode,
  	.get_mode		= tps65910_get_mode,
18039e0f1   Laxman Dewangan   regulator: tps659...
729
  	.get_voltage_sel	= tps65910_get_voltage_dcdc_sel,
94732b97c   Axel Lin   regulator: Rename...
730
  	.set_voltage_sel	= tps65910_set_voltage_dcdc_sel,
01bc3a140   Axel Lin   regulator: tps659...
731
  	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
518fb721d   Graeme Gregory   TPS65910: Add tps...
732
  	.list_voltage		= tps65910_list_voltage_dcdc,
9fa8175f0   Axel Lin   regulator: tps659...
733
  	.map_voltage		= regulator_map_voltage_ascend,
518fb721d   Graeme Gregory   TPS65910: Add tps...
734
735
736
  };
  
  static struct regulator_ops tps65910_ops_vdd3 = {
a40a9c436   Axel Lin   regulator: tps659...
737
738
739
  	.is_enabled		= regulator_is_enabled_regmap,
  	.enable			= regulator_enable_regmap,
  	.disable		= regulator_disable_regmap,
518fb721d   Graeme Gregory   TPS65910: Add tps...
740
741
742
  	.set_mode		= tps65910_set_mode,
  	.get_mode		= tps65910_get_mode,
  	.get_voltage		= tps65910_get_voltage_vdd3,
d9fe28f96   Axel Lin   regulator: tps659...
743
  	.list_voltage		= regulator_list_voltage_table,
9fa8175f0   Axel Lin   regulator: tps659...
744
  	.map_voltage		= regulator_map_voltage_ascend,
518fb721d   Graeme Gregory   TPS65910: Add tps...
745
  };
03746dcbd   Markus Pargmann   regulator: tps659...
746
747
748
749
750
751
752
753
754
755
756
  static struct regulator_ops tps65910_ops_vbb = {
  	.is_enabled		= regulator_is_enabled_regmap,
  	.enable			= regulator_enable_regmap,
  	.disable		= regulator_disable_regmap,
  	.set_mode		= tps65910_set_mode,
  	.get_mode		= tps65910_get_mode,
  	.get_voltage_sel	= tps65910_get_voltage_sel,
  	.set_voltage_sel	= tps65910_set_voltage_sel,
  	.list_voltage		= regulator_list_voltage_table,
  	.map_voltage		= regulator_map_voltage_iterate,
  };
518fb721d   Graeme Gregory   TPS65910: Add tps...
757
  static struct regulator_ops tps65910_ops = {
a40a9c436   Axel Lin   regulator: tps659...
758
759
760
  	.is_enabled		= regulator_is_enabled_regmap,
  	.enable			= regulator_enable_regmap,
  	.disable		= regulator_disable_regmap,
518fb721d   Graeme Gregory   TPS65910: Add tps...
761
762
  	.set_mode		= tps65910_set_mode,
  	.get_mode		= tps65910_get_mode,
1f904fd1c   Axel Lin   regulator: tps659...
763
  	.get_voltage_sel	= tps65910_get_voltage_sel,
94732b97c   Axel Lin   regulator: Rename...
764
  	.set_voltage_sel	= tps65910_set_voltage_sel,
d9fe28f96   Axel Lin   regulator: tps659...
765
  	.list_voltage		= regulator_list_voltage_table,
9fa8175f0   Axel Lin   regulator: tps659...
766
  	.map_voltage		= regulator_map_voltage_ascend,
518fb721d   Graeme Gregory   TPS65910: Add tps...
767
  };
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
768
  static struct regulator_ops tps65911_ops = {
a40a9c436   Axel Lin   regulator: tps659...
769
770
771
  	.is_enabled		= regulator_is_enabled_regmap,
  	.enable			= regulator_enable_regmap,
  	.disable		= regulator_disable_regmap,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
772
773
  	.set_mode		= tps65910_set_mode,
  	.get_mode		= tps65910_get_mode,
1f904fd1c   Axel Lin   regulator: tps659...
774
  	.get_voltage_sel	= tps65911_get_voltage_sel,
94732b97c   Axel Lin   regulator: Rename...
775
  	.set_voltage_sel	= tps65911_set_voltage_sel,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
776
  	.list_voltage		= tps65911_list_voltage,
9fa8175f0   Axel Lin   regulator: tps659...
777
  	.map_voltage		= regulator_map_voltage_ascend,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
778
  };
1e0c66f49   Laxman Dewangan   regulator: tps659...
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
  static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
  		int id, int ext_sleep_config)
  {
  	struct tps65910 *mfd = pmic->mfd;
  	u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF;
  	u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF);
  	int ret;
  
  	/*
  	 * Regulator can not be control from multiple external input EN1, EN2
  	 * and EN3 together.
  	 */
  	if (ext_sleep_config & EXT_SLEEP_CONTROL) {
  		int en_count;
  		en_count = ((ext_sleep_config &
  				TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0);
  		en_count += ((ext_sleep_config &
  				TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0);
  		en_count += ((ext_sleep_config &
  				TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0);
f30b0716f   Laxman Dewangan   regulator: tps659...
799
800
  		en_count += ((ext_sleep_config &
  				TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) != 0);
1e0c66f49   Laxman Dewangan   regulator: tps659...
801
802
803
804
805
806
807
808
809
810
811
812
  		if (en_count > 1) {
  			dev_err(mfd->dev,
  				"External sleep control flag is not proper
  ");
  			return -EINVAL;
  		}
  	}
  
  	pmic->board_ext_control[id] = ext_sleep_config;
  
  	/* External EN1 control */
  	if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1)
3f7e82759   Rhyland Klein   mfd: Commonize tp...
813
  		ret = tps65910_reg_set_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
814
815
  				TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
  	else
3f7e82759   Rhyland Klein   mfd: Commonize tp...
816
  		ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
817
818
819
820
821
822
823
824
825
826
  				TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
  	if (ret < 0) {
  		dev_err(mfd->dev,
  			"Error in configuring external control EN1
  ");
  		return ret;
  	}
  
  	/* External EN2 control */
  	if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2)
3f7e82759   Rhyland Klein   mfd: Commonize tp...
827
  		ret = tps65910_reg_set_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
828
829
  				TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
  	else
3f7e82759   Rhyland Klein   mfd: Commonize tp...
830
  		ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
831
832
833
834
835
836
837
838
839
840
841
842
  				TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
  	if (ret < 0) {
  		dev_err(mfd->dev,
  			"Error in configuring external control EN2
  ");
  		return ret;
  	}
  
  	/* External EN3 control for TPS65910 LDO only */
  	if ((tps65910_chip_id(mfd) == TPS65910) &&
  			(id >= TPS65910_REG_VDIG1)) {
  		if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3)
3f7e82759   Rhyland Klein   mfd: Commonize tp...
843
  			ret = tps65910_reg_set_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
844
845
  				TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
  		else
3f7e82759   Rhyland Klein   mfd: Commonize tp...
846
  			ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
847
848
849
850
851
852
853
854
855
856
857
858
  				TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
  		if (ret < 0) {
  			dev_err(mfd->dev,
  				"Error in configuring external control EN3
  ");
  			return ret;
  		}
  	}
  
  	/* Return if no external control is selected */
  	if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) {
  		/* Clear all sleep controls */
3f7e82759   Rhyland Klein   mfd: Commonize tp...
859
  		ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
860
861
  			TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
  		if (!ret)
3f7e82759   Rhyland Klein   mfd: Commonize tp...
862
  			ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
  				TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
  		if (ret < 0)
  			dev_err(mfd->dev,
  				"Error in configuring SLEEP register
  ");
  		return ret;
  	}
  
  	/*
  	 * For regulator that has separate operational and sleep register make
  	 * sure that operational is used and clear sleep register to turn
  	 * regulator off when external control is inactive
  	 */
  	if ((id == TPS65910_REG_VDD1) ||
  		(id == TPS65910_REG_VDD2) ||
  			((id == TPS65911_REG_VDDCTRL) &&
  				(tps65910_chip_id(mfd) == TPS65911))) {
  		int op_reg_add = pmic->get_ctrl_reg(id) + 1;
  		int sr_reg_add = pmic->get_ctrl_reg(id) + 2;
faa95fde4   Axel Lin   regulator: tps659...
882
883
884
885
886
887
888
889
  		int opvsel, srvsel;
  
  		ret = tps65910_reg_read(pmic->mfd, op_reg_add, &opvsel);
  		if (ret < 0)
  			return ret;
  		ret = tps65910_reg_read(pmic->mfd, sr_reg_add, &srvsel);
  		if (ret < 0)
  			return ret;
1e0c66f49   Laxman Dewangan   regulator: tps659...
890
891
  		if (opvsel & VDD1_OP_CMD_MASK) {
  			u8 reg_val = srvsel & VDD1_OP_SEL_MASK;
faa95fde4   Axel Lin   regulator: tps659...
892
893
894
  
  			ret = tps65910_reg_write(pmic->mfd, op_reg_add,
  						 reg_val);
1e0c66f49   Laxman Dewangan   regulator: tps659...
895
896
897
898
899
900
901
  			if (ret < 0) {
  				dev_err(mfd->dev,
  					"Error in configuring op register
  ");
  				return ret;
  			}
  		}
faa95fde4   Axel Lin   regulator: tps659...
902
  		ret = tps65910_reg_write(pmic->mfd, sr_reg_add, 0);
1e0c66f49   Laxman Dewangan   regulator: tps659...
903
  		if (ret < 0) {
6d3be300c   Masanari Iida   treewide: Fix typ...
904
905
  			dev_err(mfd->dev, "Error in setting sr register
  ");
1e0c66f49   Laxman Dewangan   regulator: tps659...
906
907
908
  			return ret;
  		}
  	}
3f7e82759   Rhyland Klein   mfd: Commonize tp...
909
  	ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
910
  			TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
f30b0716f   Laxman Dewangan   regulator: tps659...
911
912
  	if (!ret) {
  		if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP)
3f7e82759   Rhyland Klein   mfd: Commonize tp...
913
  			ret = tps65910_reg_set_bits(mfd,
f30b0716f   Laxman Dewangan   regulator: tps659...
914
915
  				TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
  		else
3f7e82759   Rhyland Klein   mfd: Commonize tp...
916
  			ret = tps65910_reg_clear_bits(mfd,
f30b0716f   Laxman Dewangan   regulator: tps659...
917
918
  				TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
  	}
1e0c66f49   Laxman Dewangan   regulator: tps659...
919
920
921
922
  	if (ret < 0)
  		dev_err(mfd->dev,
  			"Error in configuring SLEEP register
  ");
f30b0716f   Laxman Dewangan   regulator: tps659...
923

1e0c66f49   Laxman Dewangan   regulator: tps659...
924
925
  	return ret;
  }
6790178f5   Rhyland Klein   regulator: tps659...
926
927
928
  #ifdef CONFIG_OF
  
  static struct of_regulator_match tps65910_matches[] = {
33a6943d2   Laxman Dewangan   regulator: tps659...
929
930
931
932
933
934
935
936
937
938
939
940
941
  	{ .name = "vrtc",	.driver_data = (void *) &tps65910_regs[0] },
  	{ .name = "vio",	.driver_data = (void *) &tps65910_regs[1] },
  	{ .name = "vdd1",	.driver_data = (void *) &tps65910_regs[2] },
  	{ .name = "vdd2",	.driver_data = (void *) &tps65910_regs[3] },
  	{ .name = "vdd3",	.driver_data = (void *) &tps65910_regs[4] },
  	{ .name = "vdig1",	.driver_data = (void *) &tps65910_regs[5] },
  	{ .name = "vdig2",	.driver_data = (void *) &tps65910_regs[6] },
  	{ .name = "vpll",	.driver_data = (void *) &tps65910_regs[7] },
  	{ .name = "vdac",	.driver_data = (void *) &tps65910_regs[8] },
  	{ .name = "vaux1",	.driver_data = (void *) &tps65910_regs[9] },
  	{ .name = "vaux2",	.driver_data = (void *) &tps65910_regs[10] },
  	{ .name = "vaux33",	.driver_data = (void *) &tps65910_regs[11] },
  	{ .name = "vmmc",	.driver_data = (void *) &tps65910_regs[12] },
03746dcbd   Markus Pargmann   regulator: tps659...
942
  	{ .name = "vbb",	.driver_data = (void *) &tps65910_regs[13] },
6790178f5   Rhyland Klein   regulator: tps659...
943
944
945
  };
  
  static struct of_regulator_match tps65911_matches[] = {
33a6943d2   Laxman Dewangan   regulator: tps659...
946
947
948
949
950
951
952
953
954
955
956
957
958
  	{ .name = "vrtc",	.driver_data = (void *) &tps65911_regs[0] },
  	{ .name = "vio",	.driver_data = (void *) &tps65911_regs[1] },
  	{ .name = "vdd1",	.driver_data = (void *) &tps65911_regs[2] },
  	{ .name = "vdd2",	.driver_data = (void *) &tps65911_regs[3] },
  	{ .name = "vddctrl",	.driver_data = (void *) &tps65911_regs[4] },
  	{ .name = "ldo1",	.driver_data = (void *) &tps65911_regs[5] },
  	{ .name = "ldo2",	.driver_data = (void *) &tps65911_regs[6] },
  	{ .name = "ldo3",	.driver_data = (void *) &tps65911_regs[7] },
  	{ .name = "ldo4",	.driver_data = (void *) &tps65911_regs[8] },
  	{ .name = "ldo5",	.driver_data = (void *) &tps65911_regs[9] },
  	{ .name = "ldo6",	.driver_data = (void *) &tps65911_regs[10] },
  	{ .name = "ldo7",	.driver_data = (void *) &tps65911_regs[11] },
  	{ .name = "ldo8",	.driver_data = (void *) &tps65911_regs[12] },
6790178f5   Rhyland Klein   regulator: tps659...
959
960
961
  };
  
  static struct tps65910_board *tps65910_parse_dt_reg_data(
84df8c124   Laxman Dewangan   regulator: tps659...
962
963
  		struct platform_device *pdev,
  		struct of_regulator_match **tps65910_reg_matches)
6790178f5   Rhyland Klein   regulator: tps659...
964
965
966
  {
  	struct tps65910_board *pmic_plat_data;
  	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
c92f5dd2c   Axel Lin   regulator: Add mi...
967
  	struct device_node *np, *regulators;
6790178f5   Rhyland Klein   regulator: tps659...
968
969
970
971
972
973
  	struct of_regulator_match *matches;
  	unsigned int prop;
  	int idx = 0, ret, count;
  
  	pmic_plat_data = devm_kzalloc(&pdev->dev, sizeof(*pmic_plat_data),
  					GFP_KERNEL);
bcb2c0d69   Sachin Kamat   regulator: tps659...
974
  	if (!pmic_plat_data)
6790178f5   Rhyland Klein   regulator: tps659...
975
  		return NULL;
6790178f5   Rhyland Klein   regulator: tps659...
976

b8b27a44d   Guodong Xu   regulator: remove...
977
  	np = pdev->dev.parent->of_node;
4ae1ff7fe   Laxman Dewangan   regulator: tps659...
978
  	regulators = of_get_child_by_name(np, "regulators");
92ab953bd   Laxman Dewangan   regulator: tps659...
979
980
981
982
983
  	if (!regulators) {
  		dev_err(&pdev->dev, "regulator node not found
  ");
  		return NULL;
  	}
6790178f5   Rhyland Klein   regulator: tps659...
984
985
986
987
988
989
990
991
992
993
994
  
  	switch (tps65910_chip_id(tps65910)) {
  	case TPS65910:
  		count = ARRAY_SIZE(tps65910_matches);
  		matches = tps65910_matches;
  		break;
  	case TPS65911:
  		count = ARRAY_SIZE(tps65911_matches);
  		matches = tps65911_matches;
  		break;
  	default:
c92f5dd2c   Axel Lin   regulator: Add mi...
995
  		of_node_put(regulators);
7e9a57e62   Laxman Dewangan   regulator: tps659...
996
997
  		dev_err(&pdev->dev, "Invalid tps chip version
  ");
6790178f5   Rhyland Klein   regulator: tps659...
998
999
  		return NULL;
  	}
08337fdac   Axel Lin   regulator: tps659...
1000
  	ret = of_regulator_match(&pdev->dev, regulators, matches, count);
c92f5dd2c   Axel Lin   regulator: Add mi...
1001
  	of_node_put(regulators);
6790178f5   Rhyland Klein   regulator: tps659...
1002
1003
1004
1005
1006
1007
  	if (ret < 0) {
  		dev_err(&pdev->dev, "Error parsing regulator init data: %d
  ",
  			ret);
  		return NULL;
  	}
84df8c124   Laxman Dewangan   regulator: tps659...
1008
  	*tps65910_reg_matches = matches;
6790178f5   Rhyland Klein   regulator: tps659...
1009
  	for (idx = 0; idx < count; idx++) {
23b113483   Axel Lin   regulator: tps659...
1010
  		if (!matches[idx].of_node)
6790178f5   Rhyland Klein   regulator: tps659...
1011
1012
1013
1014
1015
1016
1017
1018
1019
  			continue;
  
  		pmic_plat_data->tps65910_pmic_init_data[idx] =
  							matches[idx].init_data;
  
  		ret = of_property_read_u32(matches[idx].of_node,
  				"ti,regulator-ext-sleep-control", &prop);
  		if (!ret)
  			pmic_plat_data->regulator_ext_sleep_control[idx] = prop;
19228a6a5   Laxman Dewangan   regulator: tps659...
1020

6790178f5   Rhyland Klein   regulator: tps659...
1021
1022
1023
1024
1025
1026
  	}
  
  	return pmic_plat_data;
  }
  #else
  static inline struct tps65910_board *tps65910_parse_dt_reg_data(
84df8c124   Laxman Dewangan   regulator: tps659...
1027
1028
  			struct platform_device *pdev,
  			struct of_regulator_match **tps65910_reg_matches)
6790178f5   Rhyland Klein   regulator: tps659...
1029
  {
84df8c124   Laxman Dewangan   regulator: tps659...
1030
  	*tps65910_reg_matches = NULL;
74ea0e599   Mark Brown   regulator: tps659...
1031
  	return NULL;
6790178f5   Rhyland Klein   regulator: tps659...
1032
1033
  }
  #endif
a5023574d   Bill Pemberton   regulator: remove...
1034
  static int tps65910_probe(struct platform_device *pdev)
518fb721d   Graeme Gregory   TPS65910: Add tps...
1035
1036
  {
  	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
c172708d3   Mark Brown   regulator: core: ...
1037
  	struct regulator_config config = { };
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1038
  	struct tps_info *info;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1039
1040
1041
  	struct regulator_dev *rdev;
  	struct tps65910_reg *pmic;
  	struct tps65910_board *pmic_plat_data;
84df8c124   Laxman Dewangan   regulator: tps659...
1042
  	struct of_regulator_match *tps65910_reg_matches = NULL;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1043
1044
1045
  	int i, err;
  
  	pmic_plat_data = dev_get_platdata(tps65910->dev);
6790178f5   Rhyland Klein   regulator: tps659...
1046
  	if (!pmic_plat_data && tps65910->dev->of_node)
84df8c124   Laxman Dewangan   regulator: tps659...
1047
1048
  		pmic_plat_data = tps65910_parse_dt_reg_data(pdev,
  						&tps65910_reg_matches);
6790178f5   Rhyland Klein   regulator: tps659...
1049

7e9a57e62   Laxman Dewangan   regulator: tps659...
1050
1051
1052
  	if (!pmic_plat_data) {
  		dev_err(&pdev->dev, "Platform data not found
  ");
518fb721d   Graeme Gregory   TPS65910: Add tps...
1053
  		return -EINVAL;
7e9a57e62   Laxman Dewangan   regulator: tps659...
1054
  	}
518fb721d   Graeme Gregory   TPS65910: Add tps...
1055

9eb0c4218   Axel Lin   regulator: Conver...
1056
  	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
bcb2c0d69   Sachin Kamat   regulator: tps659...
1057
  	if (!pmic)
518fb721d   Graeme Gregory   TPS65910: Add tps...
1058
  		return -ENOMEM;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1059
1060
1061
1062
  	pmic->mfd = tps65910;
  	platform_set_drvdata(pdev, pmic);
  
  	/* Give control of all register to control port */
cd07e3701   Kangjie Lu   regulator: tps659...
1063
  	err = tps65910_reg_set_bits(pmic->mfd, TPS65910_DEVCTRL,
518fb721d   Graeme Gregory   TPS65910: Add tps...
1064
  				DEVCTRL_SR_CTL_I2C_SEL_MASK);
cd07e3701   Kangjie Lu   regulator: tps659...
1065
1066
  	if (err < 0)
  		return err;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1067

4b5792704   Jingoo Han   regulator: tps659...
1068
  	switch (tps65910_chip_id(tps65910)) {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1069
  	case TPS65910:
fe953904f   Michał Mirosław   regulator: tps659...
1070
  		BUILD_BUG_ON(TPS65910_NUM_REGS < ARRAY_SIZE(tps65910_regs));
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1071
  		pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
39aa9b6e3   Axel Lin   regulator: tps659...
1072
  		pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
1e0c66f49   Laxman Dewangan   regulator: tps659...
1073
  		pmic->ext_sleep_control = tps65910_ext_sleep_control;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1074
  		info = tps65910_regs;
8f9165c98   Jan Remmet   regulator: tps659...
1075
1076
1077
1078
1079
1080
  		/* Work around silicon erratum SWCZ010: output programmed
  		 * voltage level can go higher than expected or crash
  		 * Workaround: use no synchronization of DCDC clocks
  		 */
  		tps65910_reg_clear_bits(pmic->mfd, TPS65910_DCDCCTRL,
  					DCDCCTRL_DCDCCKSYNC_MASK);
d04156bca   Axel Lin   regulator: tps659...
1081
  		break;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1082
  	case TPS65911:
fe953904f   Michał Mirosław   regulator: tps659...
1083
  		BUILD_BUG_ON(TPS65910_NUM_REGS < ARRAY_SIZE(tps65911_regs));
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1084
  		pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
39aa9b6e3   Axel Lin   regulator: tps659...
1085
  		pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
1e0c66f49   Laxman Dewangan   regulator: tps659...
1086
  		pmic->ext_sleep_control = tps65911_ext_sleep_control;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1087
  		info = tps65911_regs;
d04156bca   Axel Lin   regulator: tps659...
1088
  		break;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1089
  	default:
7e9a57e62   Laxman Dewangan   regulator: tps659...
1090
1091
  		dev_err(&pdev->dev, "Invalid tps chip version
  ");
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1092
1093
  		return -ENODEV;
  	}
a86854d0c   Kees Cook   treewide: devm_kz...
1094
1095
1096
1097
  	pmic->desc = devm_kcalloc(&pdev->dev,
  				  pmic->num_regulators,
  				  sizeof(struct regulator_desc),
  				  GFP_KERNEL);
bcb2c0d69   Sachin Kamat   regulator: tps659...
1098
  	if (!pmic->desc)
68d8c1cd5   Laxman Dewangan   regulator: tps659...
1099
  		return -ENOMEM;
39aa9b6e3   Axel Lin   regulator: tps659...
1100

a86854d0c   Kees Cook   treewide: devm_kz...
1101
1102
1103
1104
  	pmic->info = devm_kcalloc(&pdev->dev,
  				  pmic->num_regulators,
  				  sizeof(struct tps_info *),
  				  GFP_KERNEL);
bcb2c0d69   Sachin Kamat   regulator: tps659...
1105
  	if (!pmic->info)
68d8c1cd5   Laxman Dewangan   regulator: tps659...
1106
  		return -ENOMEM;
39aa9b6e3   Axel Lin   regulator: tps659...
1107

a86854d0c   Kees Cook   treewide: devm_kz...
1108
1109
1110
1111
  	pmic->rdev = devm_kcalloc(&pdev->dev,
  				  pmic->num_regulators,
  				  sizeof(struct regulator_dev *),
  				  GFP_KERNEL);
bcb2c0d69   Sachin Kamat   regulator: tps659...
1112
  	if (!pmic->rdev)
68d8c1cd5   Laxman Dewangan   regulator: tps659...
1113
  		return -ENOMEM;
39aa9b6e3   Axel Lin   regulator: tps659...
1114

fe953904f   Michał Mirosław   regulator: tps659...
1115
  	for (i = 0; i < pmic->num_regulators; i++, info++) {
518fb721d   Graeme Gregory   TPS65910: Add tps...
1116
1117
1118
1119
  		/* Register the regulators */
  		pmic->info[i] = info;
  
  		pmic->desc[i].name = info->name;
d2cfdb055   Laxman Dewangan   regulator: tps659...
1120
  		pmic->desc[i].supply_name = info->vin_name;
77fa44d0e   Axel Lin   regulator: Fix de...
1121
  		pmic->desc[i].id = i;
7d38a3cb9   Laxman Dewangan   regulator: tps659...
1122
  		pmic->desc[i].n_voltages = info->n_voltages;
94f48ab32   Axel Lin   regulator: tps659...
1123
  		pmic->desc[i].enable_time = info->enable_time_us;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1124

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1125
  		if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
518fb721d   Graeme Gregory   TPS65910: Add tps...
1126
  			pmic->desc[i].ops = &tps65910_ops_dcdc;
780dc9ba4   Afzal Mohammed   regulator: TPS659...
1127
1128
  			pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE *
  							VDD1_2_NUM_VOLT_COARSE;
01bc3a140   Axel Lin   regulator: tps659...
1129
  			pmic->desc[i].ramp_delay = 12500;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1130
  		} else if (i == TPS65910_REG_VDD3) {
01bc3a140   Axel Lin   regulator: tps659...
1131
  			if (tps65910_chip_id(tps65910) == TPS65910) {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1132
  				pmic->desc[i].ops = &tps65910_ops_vdd3;
d9fe28f96   Axel Lin   regulator: tps659...
1133
  				pmic->desc[i].volt_table = info->voltage_table;
01bc3a140   Axel Lin   regulator: tps659...
1134
  			} else {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1135
  				pmic->desc[i].ops = &tps65910_ops_dcdc;
01bc3a140   Axel Lin   regulator: tps659...
1136
1137
  				pmic->desc[i].ramp_delay = 5000;
  			}
03746dcbd   Markus Pargmann   regulator: tps659...
1138
1139
1140
1141
  		} else if (i == TPS65910_REG_VBB &&
  				tps65910_chip_id(tps65910) == TPS65910) {
  			pmic->desc[i].ops = &tps65910_ops_vbb;
  			pmic->desc[i].volt_table = info->voltage_table;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1142
  		} else {
d9fe28f96   Axel Lin   regulator: tps659...
1143
  			if (tps65910_chip_id(tps65910) == TPS65910) {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1144
  				pmic->desc[i].ops = &tps65910_ops;
d9fe28f96   Axel Lin   regulator: tps659...
1145
1146
  				pmic->desc[i].volt_table = info->voltage_table;
  			} else {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1147
  				pmic->desc[i].ops = &tps65911_ops;
d9fe28f96   Axel Lin   regulator: tps659...
1148
  			}
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1149
  		}
518fb721d   Graeme Gregory   TPS65910: Add tps...
1150

1e0c66f49   Laxman Dewangan   regulator: tps659...
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
  		err = tps65910_set_ext_sleep_config(pmic, i,
  				pmic_plat_data->regulator_ext_sleep_control[i]);
  		/*
  		 * Failing on regulator for configuring externally control
  		 * is not a serious issue, just throw warning.
  		 */
  		if (err < 0)
  			dev_warn(tps65910->dev,
  				"Failed to initialise ext control config
  ");
518fb721d   Graeme Gregory   TPS65910: Add tps...
1161
1162
  		pmic->desc[i].type = REGULATOR_VOLTAGE;
  		pmic->desc[i].owner = THIS_MODULE;
a40a9c436   Axel Lin   regulator: tps659...
1163
  		pmic->desc[i].enable_reg = pmic->get_ctrl_reg(i);
b8903eb98   Axel Lin   regulator: tps659...
1164
  		pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1165

c172708d3   Mark Brown   regulator: core: ...
1166
  		config.dev = tps65910->dev;
23b113483   Axel Lin   regulator: tps659...
1167
  		config.init_data = pmic_plat_data->tps65910_pmic_init_data[i];
c172708d3   Mark Brown   regulator: core: ...
1168
  		config.driver_data = pmic;
a40a9c436   Axel Lin   regulator: tps659...
1169
  		config.regmap = tps65910->regmap;
c172708d3   Mark Brown   regulator: core: ...
1170

84df8c124   Laxman Dewangan   regulator: tps659...
1171
1172
  		if (tps65910_reg_matches)
  			config.of_node = tps65910_reg_matches[i].of_node;
6790178f5   Rhyland Klein   regulator: tps659...
1173

95095e422   Sachin Kamat   regulator: tps659...
1174
1175
  		rdev = devm_regulator_register(&pdev->dev, &pmic->desc[i],
  					       &config);
518fb721d   Graeme Gregory   TPS65910: Add tps...
1176
1177
1178
1179
1180
  		if (IS_ERR(rdev)) {
  			dev_err(tps65910->dev,
  				"failed to register %s regulator
  ",
  				pdev->name);
95095e422   Sachin Kamat   regulator: tps659...
1181
  			return PTR_ERR(rdev);
518fb721d   Graeme Gregory   TPS65910: Add tps...
1182
1183
1184
1185
1186
1187
  		}
  
  		/* Save regulator for cleanup */
  		pmic->rdev[i] = rdev;
  	}
  	return 0;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1188
  }
1e0c66f49   Laxman Dewangan   regulator: tps659...
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
  static void tps65910_shutdown(struct platform_device *pdev)
  {
  	struct tps65910_reg *pmic = platform_get_drvdata(pdev);
  	int i;
  
  	/*
  	 * Before bootloader jumps to kernel, it makes sure that required
  	 * external control signals are in desired state so that given rails
  	 * can be configure accordingly.
  	 * If rails are configured to be controlled from external control
  	 * then before shutting down/rebooting the system, the external
  	 * control configuration need to be remove from the rails so that
  	 * its output will be available as per register programming even
  	 * if external controls are removed. This is require when the POR
  	 * value of the control signals are not in active state and before
  	 * bootloader initializes it, the system requires the rail output
  	 * to be active for booting.
  	 */
  	for (i = 0; i < pmic->num_regulators; i++) {
  		int err;
  		if (!pmic->rdev[i])
  			continue;
  
  		err = tps65910_set_ext_sleep_config(pmic, i, 0);
  		if (err < 0)
  			dev_err(&pdev->dev,
  				"Error in clearing external control
  ");
  	}
  }
518fb721d   Graeme Gregory   TPS65910: Add tps...
1219
1220
1221
  static struct platform_driver tps65910_driver = {
  	.driver = {
  		.name = "tps65910-pmic",
518fb721d   Graeme Gregory   TPS65910: Add tps...
1222
1223
  	},
  	.probe = tps65910_probe,
1e0c66f49   Laxman Dewangan   regulator: tps659...
1224
  	.shutdown = tps65910_shutdown,
518fb721d   Graeme Gregory   TPS65910: Add tps...
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
  };
  
  static int __init tps65910_init(void)
  {
  	return platform_driver_register(&tps65910_driver);
  }
  subsys_initcall(tps65910_init);
  
  static void __exit tps65910_cleanup(void)
  {
  	platform_driver_unregister(&tps65910_driver);
  }
  module_exit(tps65910_cleanup);
  
  MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
ae0e65443   Axel Lin   regulator: Fix mo...
1240
  MODULE_DESCRIPTION("TPS65910/TPS65911 voltage regulator driver");
518fb721d   Graeme Gregory   TPS65910: Add tps...
1241
1242
  MODULE_LICENSE("GPL v2");
  MODULE_ALIAS("platform:tps65910-pmic");