Blame view

drivers/regulator/tps65910-regulator.c 31.9 KB
518fb721d   Graeme Gregory   TPS65910: Add tps...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  /*
   * tps65910.c  --  TI tps65910
   *
   * Copyright 2010 Texas Instruments Inc.
   *
   * Author: Graeme Gregory <gg@slimlogic.co.uk>
   * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
   *
   *  This program is free software; you can redistribute it and/or modify it
   *  under  the terms of the GNU General  Public License as published by the
   *  Free Software Foundation;  either version 2 of the License, or (at your
   *  option) any later version.
   *
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/err.h>
  #include <linux/platform_device.h>
  #include <linux/regulator/driver.h>
  #include <linux/regulator/machine.h>
518fb721d   Graeme Gregory   TPS65910: Add tps...
23
24
25
  #include <linux/slab.h>
  #include <linux/gpio.h>
  #include <linux/mfd/tps65910.h>
6790178f5   Rhyland Klein   regulator: tps659...
26
  #include <linux/regulator/of_regulator.h>
518fb721d   Graeme Gregory   TPS65910: Add tps...
27

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

d9fe28f96   Axel Lin   regulator: tps659...
34
35
36
  /* supported VIO voltages in microvolts */
  static const unsigned int VIO_VSEL_table[] = {
  	1500000, 1800000, 2500000, 3300000,
518fb721d   Graeme Gregory   TPS65910: Add tps...
37
  };
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
38
  /* VSEL tables for TPS65910 specific LDOs and dcdc's */
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
75
76
77
  };
  
  struct tps_info {
  	const char *name;
19228a6a5   Laxman Dewangan   regulator: tps659...
78
  	const char *vin_name;
7d38a3cb9   Laxman Dewangan   regulator: tps659...
79
  	u8 n_voltages;
d9fe28f96   Axel Lin   regulator: tps659...
80
  	const unsigned int *voltage_table;
0651eed5e   Laxman Dewangan   regulator: tps659...
81
  	int enable_time_us;
518fb721d   Graeme Gregory   TPS65910: Add tps...
82
83
84
85
  };
  
  static struct tps_info tps65910_regs[] = {
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
86
  		.name = "vrtc",
19228a6a5   Laxman Dewangan   regulator: tps659...
87
  		.vin_name = "vcc7",
0651eed5e   Laxman Dewangan   regulator: tps659...
88
  		.enable_time_us = 2200,
518fb721d   Graeme Gregory   TPS65910: Add tps...
89
90
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
91
  		.name = "vio",
19228a6a5   Laxman Dewangan   regulator: tps659...
92
  		.vin_name = "vccio",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
93
94
  		.n_voltages = ARRAY_SIZE(VIO_VSEL_table),
  		.voltage_table = VIO_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
95
  		.enable_time_us = 350,
518fb721d   Graeme Gregory   TPS65910: Add tps...
96
97
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
98
  		.name = "vdd1",
19228a6a5   Laxman Dewangan   regulator: tps659...
99
  		.vin_name = "vcc1",
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 = "vdd2",
19228a6a5   Laxman Dewangan   regulator: tps659...
104
  		.vin_name = "vcc2",
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 = "vdd3",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
109
110
  		.n_voltages = ARRAY_SIZE(VDD3_VSEL_table),
  		.voltage_table = VDD3_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
111
  		.enable_time_us = 200,
518fb721d   Graeme Gregory   TPS65910: Add tps...
112
113
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
114
  		.name = "vdig1",
19228a6a5   Laxman Dewangan   regulator: tps659...
115
  		.vin_name = "vcc6",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
116
117
  		.n_voltages = ARRAY_SIZE(VDIG1_VSEL_table),
  		.voltage_table = VDIG1_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
118
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
119
120
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
121
  		.name = "vdig2",
19228a6a5   Laxman Dewangan   regulator: tps659...
122
  		.vin_name = "vcc6",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
123
124
  		.n_voltages = ARRAY_SIZE(VDIG2_VSEL_table),
  		.voltage_table = VDIG2_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
125
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
126
127
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
128
  		.name = "vpll",
19228a6a5   Laxman Dewangan   regulator: tps659...
129
  		.vin_name = "vcc5",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
130
131
  		.n_voltages = ARRAY_SIZE(VPLL_VSEL_table),
  		.voltage_table = VPLL_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
132
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
133
134
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
135
  		.name = "vdac",
19228a6a5   Laxman Dewangan   regulator: tps659...
136
  		.vin_name = "vcc5",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
137
138
  		.n_voltages = ARRAY_SIZE(VDAC_VSEL_table),
  		.voltage_table = VDAC_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
139
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
140
141
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
142
  		.name = "vaux1",
19228a6a5   Laxman Dewangan   regulator: tps659...
143
  		.vin_name = "vcc4",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
144
145
  		.n_voltages = ARRAY_SIZE(VAUX1_VSEL_table),
  		.voltage_table = VAUX1_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
146
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
147
148
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
149
  		.name = "vaux2",
19228a6a5   Laxman Dewangan   regulator: tps659...
150
  		.vin_name = "vcc4",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
151
152
  		.n_voltages = ARRAY_SIZE(VAUX2_VSEL_table),
  		.voltage_table = VAUX2_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
153
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
154
155
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
156
  		.name = "vaux33",
19228a6a5   Laxman Dewangan   regulator: tps659...
157
  		.vin_name = "vcc3",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
158
159
  		.n_voltages = ARRAY_SIZE(VAUX33_VSEL_table),
  		.voltage_table = VAUX33_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
160
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
161
162
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
163
  		.name = "vmmc",
19228a6a5   Laxman Dewangan   regulator: tps659...
164
  		.vin_name = "vcc3",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
165
166
  		.n_voltages = ARRAY_SIZE(VMMC_VSEL_table),
  		.voltage_table = VMMC_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
167
  		.enable_time_us = 100,
518fb721d   Graeme Gregory   TPS65910: Add tps...
168
169
  	},
  };
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
170
171
  static struct tps_info tps65911_regs[] = {
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
172
  		.name = "vrtc",
19228a6a5   Laxman Dewangan   regulator: tps659...
173
  		.vin_name = "vcc7",
0651eed5e   Laxman Dewangan   regulator: tps659...
174
  		.enable_time_us = 2200,
c2f8efd76   Laxman Dewangan   regulator: tps659...
175
176
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
177
  		.name = "vio",
19228a6a5   Laxman Dewangan   regulator: tps659...
178
  		.vin_name = "vccio",
7d38a3cb9   Laxman Dewangan   regulator: tps659...
179
180
  		.n_voltages = ARRAY_SIZE(VIO_VSEL_table),
  		.voltage_table = VIO_VSEL_table,
0651eed5e   Laxman Dewangan   regulator: tps659...
181
  		.enable_time_us = 350,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
182
183
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
184
  		.name = "vdd1",
19228a6a5   Laxman Dewangan   regulator: tps659...
185
  		.vin_name = "vcc1",
7be531883   Laxman Dewangan   regulator: tps659...
186
  		.n_voltages = 0x4C,
0651eed5e   Laxman Dewangan   regulator: tps659...
187
  		.enable_time_us = 350,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
188
189
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
190
  		.name = "vdd2",
19228a6a5   Laxman Dewangan   regulator: tps659...
191
  		.vin_name = "vcc2",
7be531883   Laxman Dewangan   regulator: tps659...
192
  		.n_voltages = 0x4C,
0651eed5e   Laxman Dewangan   regulator: tps659...
193
  		.enable_time_us = 350,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
194
195
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
196
  		.name = "vddctrl",
7be531883   Laxman Dewangan   regulator: tps659...
197
  		.n_voltages = 0x44,
0651eed5e   Laxman Dewangan   regulator: tps659...
198
  		.enable_time_us = 900,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
199
200
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
201
  		.name = "ldo1",
19228a6a5   Laxman Dewangan   regulator: tps659...
202
  		.vin_name = "vcc6",
7be531883   Laxman Dewangan   regulator: tps659...
203
  		.n_voltages = 0x33,
0651eed5e   Laxman Dewangan   regulator: tps659...
204
  		.enable_time_us = 420,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
205
206
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
207
  		.name = "ldo2",
19228a6a5   Laxman Dewangan   regulator: tps659...
208
  		.vin_name = "vcc6",
7be531883   Laxman Dewangan   regulator: tps659...
209
  		.n_voltages = 0x33,
0651eed5e   Laxman Dewangan   regulator: tps659...
210
  		.enable_time_us = 420,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
211
212
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
213
  		.name = "ldo3",
19228a6a5   Laxman Dewangan   regulator: tps659...
214
  		.vin_name = "vcc5",
7be531883   Laxman Dewangan   regulator: tps659...
215
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
216
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
217
218
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
219
  		.name = "ldo4",
19228a6a5   Laxman Dewangan   regulator: tps659...
220
  		.vin_name = "vcc5",
7be531883   Laxman Dewangan   regulator: tps659...
221
  		.n_voltages = 0x33,
0651eed5e   Laxman Dewangan   regulator: tps659...
222
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
223
224
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
225
  		.name = "ldo5",
19228a6a5   Laxman Dewangan   regulator: tps659...
226
  		.vin_name = "vcc4",
7be531883   Laxman Dewangan   regulator: tps659...
227
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
228
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
229
230
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
231
  		.name = "ldo6",
19228a6a5   Laxman Dewangan   regulator: tps659...
232
  		.vin_name = "vcc3",
7be531883   Laxman Dewangan   regulator: tps659...
233
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
234
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
235
236
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
237
  		.name = "ldo7",
19228a6a5   Laxman Dewangan   regulator: tps659...
238
  		.vin_name = "vcc3",
7be531883   Laxman Dewangan   regulator: tps659...
239
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
240
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
241
242
  	},
  	{
33a6943d2   Laxman Dewangan   regulator: tps659...
243
  		.name = "ldo8",
19228a6a5   Laxman Dewangan   regulator: tps659...
244
  		.vin_name = "vcc3",
7be531883   Laxman Dewangan   regulator: tps659...
245
  		.n_voltages = 0x1A,
0651eed5e   Laxman Dewangan   regulator: tps659...
246
  		.enable_time_us = 230,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
247
248
  	},
  };
1e0c66f49   Laxman Dewangan   regulator: tps659...
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  #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...
281
  struct tps65910_reg {
39aa9b6e3   Axel Lin   regulator: tps659...
282
  	struct regulator_desc *desc;
518fb721d   Graeme Gregory   TPS65910: Add tps...
283
  	struct tps65910 *mfd;
39aa9b6e3   Axel Lin   regulator: tps659...
284
285
  	struct regulator_dev **rdev;
  	struct tps_info **info;
39aa9b6e3   Axel Lin   regulator: tps659...
286
  	int num_regulators;
518fb721d   Graeme Gregory   TPS65910: Add tps...
287
  	int mode;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
288
  	int  (*get_ctrl_reg)(int);
1e0c66f49   Laxman Dewangan   regulator: tps659...
289
290
  	unsigned int *ext_sleep_control;
  	unsigned int board_ext_control[TPS65910_NUM_REGS];
518fb721d   Graeme Gregory   TPS65910: Add tps...
291
  };
518fb721d   Graeme Gregory   TPS65910: Add tps...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  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;
  	default:
  		return -EINVAL;
  	}
  }
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
  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...
358
359
360
361
362
  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...
363
364
  
  	reg = pmic->get_ctrl_reg(id);
518fb721d   Graeme Gregory   TPS65910: Add tps...
365
366
367
368
369
  	if (reg < 0)
  		return reg;
  
  	switch (mode) {
  	case REGULATOR_MODE_NORMAL:
faa95fde4   Axel Lin   regulator: tps659...
370
371
372
  		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...
373
374
  	case REGULATOR_MODE_IDLE:
  		value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT;
3f7e82759   Rhyland Klein   mfd: Commonize tp...
375
  		return tps65910_reg_set_bits(mfd, reg, value);
518fb721d   Graeme Gregory   TPS65910: Add tps...
376
  	case REGULATOR_MODE_STANDBY:
3f7e82759   Rhyland Klein   mfd: Commonize tp...
377
  		return tps65910_reg_clear_bits(mfd, reg, LDO_ST_ON_BIT);
518fb721d   Graeme Gregory   TPS65910: Add tps...
378
379
380
381
382
383
384
385
  	}
  
  	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...
386
  	int ret, reg, value, id = rdev_get_id(dev);
518fb721d   Graeme Gregory   TPS65910: Add tps...
387

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
388
  	reg = pmic->get_ctrl_reg(id);
518fb721d   Graeme Gregory   TPS65910: Add tps...
389
390
  	if (reg < 0)
  		return reg;
faa95fde4   Axel Lin   regulator: tps659...
391
392
393
  	ret = tps65910_reg_read(pmic->mfd, reg, &value);
  	if (ret < 0)
  		return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
394

585993932   Axel Lin   regulator: Fix th...
395
  	if (!(value & LDO_ST_ON_BIT))
518fb721d   Graeme Gregory   TPS65910: Add tps...
396
397
398
399
400
401
  		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...
402
  static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev)
518fb721d   Graeme Gregory   TPS65910: Add tps...
403
404
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
faa95fde4   Axel Lin   regulator: tps659...
405
  	int ret, id = rdev_get_id(dev);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
406
  	int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0;
518fb721d   Graeme Gregory   TPS65910: Add tps...
407
408
409
  
  	switch (id) {
  	case TPS65910_REG_VDD1:
faa95fde4   Axel Lin   regulator: tps659...
410
411
412
413
414
415
  		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...
416
  		mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT;
faa95fde4   Axel Lin   regulator: tps659...
417
418
419
  		ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_SR, &srvsel);
  		if (ret < 0)
  			return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
420
421
422
  		sr = opvsel & VDD1_OP_CMD_MASK;
  		opvsel &= VDD1_OP_SEL_MASK;
  		srvsel &= VDD1_SR_SEL_MASK;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
423
  		vselmax = 75;
518fb721d   Graeme Gregory   TPS65910: Add tps...
424
425
  		break;
  	case TPS65910_REG_VDD2:
faa95fde4   Axel Lin   regulator: tps659...
426
427
428
429
430
431
  		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...
432
  		mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT;
faa95fde4   Axel Lin   regulator: tps659...
433
434
435
  		ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_SR, &srvsel);
  		if (ret < 0)
  			return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
436
437
438
  		sr = opvsel & VDD2_OP_CMD_MASK;
  		opvsel &= VDD2_OP_SEL_MASK;
  		srvsel &= VDD2_SR_SEL_MASK;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
439
440
441
  		vselmax = 75;
  		break;
  	case TPS65911_REG_VDDCTRL:
faa95fde4   Axel Lin   regulator: tps659...
442
443
444
445
446
447
448
449
  		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...
450
451
452
453
  		sr = opvsel & VDDCTRL_OP_CMD_MASK;
  		opvsel &= VDDCTRL_OP_SEL_MASK;
  		srvsel &= VDDCTRL_SR_SEL_MASK;
  		vselmax = 64;
518fb721d   Graeme Gregory   TPS65910: Add tps...
454
455
456
457
458
459
460
461
  		break;
  	}
  
  	/* multiplier 0 == 1 but 2,3 normal */
  	if (!mult)
  		mult=1;
  
  	if (sr) {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
462
463
464
465
466
  		/* normalise to valid range */
  		if (srvsel < 3)
  			srvsel = 3;
  		if (srvsel > vselmax)
  			srvsel = vselmax;
18039e0f1   Laxman Dewangan   regulator: tps659...
467
  		return srvsel - 3;
518fb721d   Graeme Gregory   TPS65910: Add tps...
468
  	} else {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
469
470
471
472
473
  		/* normalise to valid range*/
  		if (opvsel < 3)
  			opvsel = 3;
  		if (opvsel > vselmax)
  			opvsel = vselmax;
18039e0f1   Laxman Dewangan   regulator: tps659...
474
  		return opvsel - 3;
518fb721d   Graeme Gregory   TPS65910: Add tps...
475
  	}
18039e0f1   Laxman Dewangan   regulator: tps659...
476
  	return -EINVAL;
518fb721d   Graeme Gregory   TPS65910: Add tps...
477
  }
1f904fd1c   Axel Lin   regulator: tps659...
478
  static int tps65910_get_voltage_sel(struct regulator_dev *dev)
518fb721d   Graeme Gregory   TPS65910: Add tps...
479
480
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
faa95fde4   Axel Lin   regulator: tps659...
481
  	int ret, reg, value, id = rdev_get_id(dev);
518fb721d   Graeme Gregory   TPS65910: Add tps...
482

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
483
  	reg = pmic->get_ctrl_reg(id);
518fb721d   Graeme Gregory   TPS65910: Add tps...
484
485
  	if (reg < 0)
  		return reg;
faa95fde4   Axel Lin   regulator: tps659...
486
487
488
  	ret = tps65910_reg_read(pmic->mfd, reg, &value);
  	if (ret < 0)
  		return ret;
518fb721d   Graeme Gregory   TPS65910: Add tps...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
  
  	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;
  	default:
  		return -EINVAL;
  	}
1f904fd1c   Axel Lin   regulator: tps659...
506
  	return value;
518fb721d   Graeme Gregory   TPS65910: Add tps...
507
508
509
510
  }
  
  static int tps65910_get_voltage_vdd3(struct regulator_dev *dev)
  {
d9fe28f96   Axel Lin   regulator: tps659...
511
  	return dev->desc->volt_table[0];
518fb721d   Graeme Gregory   TPS65910: Add tps...
512
  }
1f904fd1c   Axel Lin   regulator: tps659...
513
  static int tps65911_get_voltage_sel(struct regulator_dev *dev)
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
514
515
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
faa95fde4   Axel Lin   regulator: tps659...
516
517
  	int ret, id = rdev_get_id(dev);
  	unsigned int value, reg;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
518
519
  
  	reg = pmic->get_ctrl_reg(id);
faa95fde4   Axel Lin   regulator: tps659...
520
521
522
  	ret = tps65910_reg_read(pmic->mfd, reg, &value);
  	if (ret < 0)
  		return ret;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
523
524
525
526
527
528
529
  
  	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...
530
531
532
533
534
535
536
537
  		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...
538
539
  		break;
  	case TPS65910_REG_VIO:
e882eae80   Laxman Dewangan   regulator: tps659...
540
541
  		value &= LDO_SEL_MASK;
  		value >>= LDO_SEL_SHIFT;
1f904fd1c   Axel Lin   regulator: tps659...
542
  		break;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
543
544
545
  	default:
  		return -EINVAL;
  	}
1f904fd1c   Axel Lin   regulator: tps659...
546
  	return value;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
547
  }
94732b97c   Axel Lin   regulator: Rename...
548
549
  static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev,
  					 unsigned selector)
518fb721d   Graeme Gregory   TPS65910: Add tps...
550
551
552
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
  	int id = rdev_get_id(dev), vsel;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
553
  	int dcdc_mult = 0;
518fb721d   Graeme Gregory   TPS65910: Add tps...
554

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
555
556
  	switch (id) {
  	case TPS65910_REG_VDD1:
780dc9ba4   Afzal Mohammed   regulator: TPS659...
557
  		dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
558
559
  		if (dcdc_mult == 1)
  			dcdc_mult--;
780dc9ba4   Afzal Mohammed   regulator: TPS659...
560
  		vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
518fb721d   Graeme Gregory   TPS65910: Add tps...
561

faa95fde4   Axel Lin   regulator: tps659...
562
563
564
565
  		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...
566
567
  		break;
  	case TPS65910_REG_VDD2:
780dc9ba4   Afzal Mohammed   regulator: TPS659...
568
  		dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
569
570
  		if (dcdc_mult == 1)
  			dcdc_mult--;
780dc9ba4   Afzal Mohammed   regulator: TPS659...
571
  		vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
572

faa95fde4   Axel Lin   regulator: tps659...
573
574
575
576
  		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...
577
578
  		break;
  	case TPS65911_REG_VDDCTRL:
c4632aed3   Laxman Dewangan   regulator: tps659...
579
  		vsel = selector + 3;
faa95fde4   Axel Lin   regulator: tps659...
580
  		tps65910_reg_write(pmic->mfd, TPS65911_VDDCTRL_OP, vsel);
518fb721d   Graeme Gregory   TPS65910: Add tps...
581
582
583
584
  	}
  
  	return 0;
  }
94732b97c   Axel Lin   regulator: Rename...
585
586
  static int tps65910_set_voltage_sel(struct regulator_dev *dev,
  				    unsigned selector)
518fb721d   Graeme Gregory   TPS65910: Add tps...
587
588
589
  {
  	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
  	int reg, id = rdev_get_id(dev);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
590
  	reg = pmic->get_ctrl_reg(id);
518fb721d   Graeme Gregory   TPS65910: Add tps...
591
592
593
594
595
596
597
598
599
600
601
602
603
  	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...
604
605
  		return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
  						selector << LDO_SEL_SHIFT);
518fb721d   Graeme Gregory   TPS65910: Add tps...
606
607
608
609
  	}
  
  	return -EINVAL;
  }
94732b97c   Axel Lin   regulator: Rename...
610
611
  static int tps65911_set_voltage_sel(struct regulator_dev *dev,
  				    unsigned selector)
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
612
613
614
615
616
617
618
619
620
621
622
623
  {
  	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...
624
625
  		return tps65910_reg_update_bits(pmic->mfd, reg, LDO1_SEL_MASK,
  						selector << LDO_SEL_SHIFT);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
626
627
628
629
630
  	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...
631
632
  		return tps65910_reg_update_bits(pmic->mfd, reg, LDO3_SEL_MASK,
  						selector << LDO_SEL_SHIFT);
e882eae80   Laxman Dewangan   regulator: tps659...
633
  	case TPS65910_REG_VIO:
faa95fde4   Axel Lin   regulator: tps659...
634
635
  		return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
  						selector << LDO_SEL_SHIFT);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
636
637
638
639
  	}
  
  	return -EINVAL;
  }
518fb721d   Graeme Gregory   TPS65910: Add tps...
640
641
642
  static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
  					unsigned selector)
  {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
643
  	int volt, mult = 1, id = rdev_get_id(dev);
518fb721d   Graeme Gregory   TPS65910: Add tps...
644

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
645
646
647
  	switch (id) {
  	case TPS65910_REG_VDD1:
  	case TPS65910_REG_VDD2:
780dc9ba4   Afzal Mohammed   regulator: TPS659...
648
  		mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
649
  		volt = VDD1_2_MIN_VOLT +
780dc9ba4   Afzal Mohammed   regulator: TPS659...
650
  				(selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;
d04156bca   Axel Lin   regulator: tps659...
651
  		break;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
652
653
  	case TPS65911_REG_VDDCTRL:
  		volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
d04156bca   Axel Lin   regulator: tps659...
654
655
656
657
  		break;
  	default:
  		BUG();
  		return -EINVAL;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
658
  	}
518fb721d   Graeme Gregory   TPS65910: Add tps...
659
660
661
  
  	return  volt * 100 * mult;
  }
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
  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);
  
  	switch(id) {
  	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...
693
  		return pmic->info[id]->voltage_table[selector];
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
694
695
696
697
698
699
  	default:
  		return -EINVAL;
  	}
  
  	return (LDO_MIN_VOLT + selector * step_mv) * 1000;
  }
518fb721d   Graeme Gregory   TPS65910: Add tps...
700
701
  /* Regulator ops (except VRTC) */
  static struct regulator_ops tps65910_ops_dcdc = {
a40a9c436   Axel Lin   regulator: tps659...
702
703
704
  	.is_enabled		= regulator_is_enabled_regmap,
  	.enable			= regulator_enable_regmap,
  	.disable		= regulator_disable_regmap,
518fb721d   Graeme Gregory   TPS65910: Add tps...
705
706
  	.set_mode		= tps65910_set_mode,
  	.get_mode		= tps65910_get_mode,
18039e0f1   Laxman Dewangan   regulator: tps659...
707
  	.get_voltage_sel	= tps65910_get_voltage_dcdc_sel,
94732b97c   Axel Lin   regulator: Rename...
708
  	.set_voltage_sel	= tps65910_set_voltage_dcdc_sel,
01bc3a140   Axel Lin   regulator: tps659...
709
  	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
518fb721d   Graeme Gregory   TPS65910: Add tps...
710
711
712
713
  	.list_voltage		= tps65910_list_voltage_dcdc,
  };
  
  static struct regulator_ops tps65910_ops_vdd3 = {
a40a9c436   Axel Lin   regulator: tps659...
714
715
716
  	.is_enabled		= regulator_is_enabled_regmap,
  	.enable			= regulator_enable_regmap,
  	.disable		= regulator_disable_regmap,
518fb721d   Graeme Gregory   TPS65910: Add tps...
717
718
719
  	.set_mode		= tps65910_set_mode,
  	.get_mode		= tps65910_get_mode,
  	.get_voltage		= tps65910_get_voltage_vdd3,
d9fe28f96   Axel Lin   regulator: tps659...
720
  	.list_voltage		= regulator_list_voltage_table,
518fb721d   Graeme Gregory   TPS65910: Add tps...
721
722
723
  };
  
  static struct regulator_ops tps65910_ops = {
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,
1f904fd1c   Axel Lin   regulator: tps659...
729
  	.get_voltage_sel	= tps65910_get_voltage_sel,
94732b97c   Axel Lin   regulator: Rename...
730
  	.set_voltage_sel	= tps65910_set_voltage_sel,
d9fe28f96   Axel Lin   regulator: tps659...
731
  	.list_voltage		= regulator_list_voltage_table,
518fb721d   Graeme Gregory   TPS65910: Add tps...
732
  };
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
733
  static struct regulator_ops tps65911_ops = {
a40a9c436   Axel Lin   regulator: tps659...
734
735
736
  	.is_enabled		= regulator_is_enabled_regmap,
  	.enable			= regulator_enable_regmap,
  	.disable		= regulator_disable_regmap,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
737
738
  	.set_mode		= tps65910_set_mode,
  	.get_mode		= tps65910_get_mode,
1f904fd1c   Axel Lin   regulator: tps659...
739
  	.get_voltage_sel	= tps65911_get_voltage_sel,
94732b97c   Axel Lin   regulator: Rename...
740
  	.set_voltage_sel	= tps65911_set_voltage_sel,
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
741
742
  	.list_voltage		= tps65911_list_voltage,
  };
1e0c66f49   Laxman Dewangan   regulator: tps659...
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
  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...
763
764
  		en_count += ((ext_sleep_config &
  				TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) != 0);
1e0c66f49   Laxman Dewangan   regulator: tps659...
765
766
767
768
769
770
771
772
773
774
775
776
  		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...
777
  		ret = tps65910_reg_set_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
778
779
  				TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
  	else
3f7e82759   Rhyland Klein   mfd: Commonize tp...
780
  		ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
781
782
783
784
785
786
787
788
789
790
  				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...
791
  		ret = tps65910_reg_set_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
792
793
  				TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
  	else
3f7e82759   Rhyland Klein   mfd: Commonize tp...
794
  		ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
795
796
797
798
799
800
801
802
803
804
805
806
  				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...
807
  			ret = tps65910_reg_set_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
808
809
  				TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
  		else
3f7e82759   Rhyland Klein   mfd: Commonize tp...
810
  			ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
811
812
813
814
815
816
817
818
819
820
821
822
  				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...
823
  		ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
824
825
  			TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
  		if (!ret)
3f7e82759   Rhyland Klein   mfd: Commonize tp...
826
  			ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
  				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...
846
847
848
849
850
851
852
853
  		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...
854
855
  		if (opvsel & VDD1_OP_CMD_MASK) {
  			u8 reg_val = srvsel & VDD1_OP_SEL_MASK;
faa95fde4   Axel Lin   regulator: tps659...
856
857
858
  
  			ret = tps65910_reg_write(pmic->mfd, op_reg_add,
  						 reg_val);
1e0c66f49   Laxman Dewangan   regulator: tps659...
859
860
861
862
863
864
865
  			if (ret < 0) {
  				dev_err(mfd->dev,
  					"Error in configuring op register
  ");
  				return ret;
  			}
  		}
faa95fde4   Axel Lin   regulator: tps659...
866
  		ret = tps65910_reg_write(pmic->mfd, sr_reg_add, 0);
1e0c66f49   Laxman Dewangan   regulator: tps659...
867
868
869
870
871
872
  		if (ret < 0) {
  			dev_err(mfd->dev, "Error in settting sr register
  ");
  			return ret;
  		}
  	}
3f7e82759   Rhyland Klein   mfd: Commonize tp...
873
  	ret = tps65910_reg_clear_bits(mfd,
1e0c66f49   Laxman Dewangan   regulator: tps659...
874
  			TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
f30b0716f   Laxman Dewangan   regulator: tps659...
875
876
  	if (!ret) {
  		if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP)
3f7e82759   Rhyland Klein   mfd: Commonize tp...
877
  			ret = tps65910_reg_set_bits(mfd,
f30b0716f   Laxman Dewangan   regulator: tps659...
878
879
  				TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
  		else
3f7e82759   Rhyland Klein   mfd: Commonize tp...
880
  			ret = tps65910_reg_clear_bits(mfd,
f30b0716f   Laxman Dewangan   regulator: tps659...
881
882
  				TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
  	}
1e0c66f49   Laxman Dewangan   regulator: tps659...
883
884
885
886
  	if (ret < 0)
  		dev_err(mfd->dev,
  			"Error in configuring SLEEP register
  ");
f30b0716f   Laxman Dewangan   regulator: tps659...
887

1e0c66f49   Laxman Dewangan   regulator: tps659...
888
889
  	return ret;
  }
6790178f5   Rhyland Klein   regulator: tps659...
890
891
892
  #ifdef CONFIG_OF
  
  static struct of_regulator_match tps65910_matches[] = {
33a6943d2   Laxman Dewangan   regulator: tps659...
893
894
895
896
897
898
899
900
901
902
903
904
905
  	{ .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] },
6790178f5   Rhyland Klein   regulator: tps659...
906
907
908
  };
  
  static struct of_regulator_match tps65911_matches[] = {
33a6943d2   Laxman Dewangan   regulator: tps659...
909
910
911
912
913
914
915
916
917
918
919
920
921
  	{ .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...
922
923
924
  };
  
  static struct tps65910_board *tps65910_parse_dt_reg_data(
84df8c124   Laxman Dewangan   regulator: tps659...
925
926
  		struct platform_device *pdev,
  		struct of_regulator_match **tps65910_reg_matches)
6790178f5   Rhyland Klein   regulator: tps659...
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
  {
  	struct tps65910_board *pmic_plat_data;
  	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
  	struct device_node *np = pdev->dev.parent->of_node;
  	struct device_node *regulators;
  	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);
  
  	if (!pmic_plat_data) {
  		dev_err(&pdev->dev, "Failure to alloc pdata for regulators.
  ");
  		return NULL;
  	}
  
  	regulators = of_find_node_by_name(np, "regulators");
92ab953bd   Laxman Dewangan   regulator: tps659...
946
947
948
949
950
  	if (!regulators) {
  		dev_err(&pdev->dev, "regulator node not found
  ");
  		return NULL;
  	}
6790178f5   Rhyland Klein   regulator: tps659...
951
952
953
954
955
956
957
958
959
960
961
  
  	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:
7e9a57e62   Laxman Dewangan   regulator: tps659...
962
963
  		dev_err(&pdev->dev, "Invalid tps chip version
  ");
6790178f5   Rhyland Klein   regulator: tps659...
964
965
966
967
968
969
970
971
972
973
  		return NULL;
  	}
  
  	ret = of_regulator_match(pdev->dev.parent, regulators, matches, count);
  	if (ret < 0) {
  		dev_err(&pdev->dev, "Error parsing regulator init data: %d
  ",
  			ret);
  		return NULL;
  	}
84df8c124   Laxman Dewangan   regulator: tps659...
974
  	*tps65910_reg_matches = matches;
6790178f5   Rhyland Klein   regulator: tps659...
975
976
977
978
979
980
981
982
983
984
985
  	for (idx = 0; idx < count; idx++) {
  		if (!matches[idx].init_data || !matches[idx].of_node)
  			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...
986

6790178f5   Rhyland Klein   regulator: tps659...
987
988
989
990
991
992
  	}
  
  	return pmic_plat_data;
  }
  #else
  static inline struct tps65910_board *tps65910_parse_dt_reg_data(
84df8c124   Laxman Dewangan   regulator: tps659...
993
994
  			struct platform_device *pdev,
  			struct of_regulator_match **tps65910_reg_matches)
6790178f5   Rhyland Klein   regulator: tps659...
995
  {
84df8c124   Laxman Dewangan   regulator: tps659...
996
  	*tps65910_reg_matches = NULL;
74ea0e599   Mark Brown   regulator: tps659...
997
  	return NULL;
6790178f5   Rhyland Klein   regulator: tps659...
998
999
  }
  #endif
518fb721d   Graeme Gregory   TPS65910: Add tps...
1000
1001
1002
  static __devinit int tps65910_probe(struct platform_device *pdev)
  {
  	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
c172708d3   Mark Brown   regulator: core: ...
1003
  	struct regulator_config config = { };
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1004
  	struct tps_info *info;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1005
1006
1007
1008
  	struct regulator_init_data *reg_data;
  	struct regulator_dev *rdev;
  	struct tps65910_reg *pmic;
  	struct tps65910_board *pmic_plat_data;
84df8c124   Laxman Dewangan   regulator: tps659...
1009
  	struct of_regulator_match *tps65910_reg_matches = NULL;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1010
1011
1012
  	int i, err;
  
  	pmic_plat_data = dev_get_platdata(tps65910->dev);
6790178f5   Rhyland Klein   regulator: tps659...
1013
  	if (!pmic_plat_data && tps65910->dev->of_node)
84df8c124   Laxman Dewangan   regulator: tps659...
1014
1015
  		pmic_plat_data = tps65910_parse_dt_reg_data(pdev,
  						&tps65910_reg_matches);
6790178f5   Rhyland Klein   regulator: tps659...
1016

7e9a57e62   Laxman Dewangan   regulator: tps659...
1017
1018
1019
  	if (!pmic_plat_data) {
  		dev_err(&pdev->dev, "Platform data not found
  ");
518fb721d   Graeme Gregory   TPS65910: Add tps...
1020
  		return -EINVAL;
7e9a57e62   Laxman Dewangan   regulator: tps659...
1021
  	}
518fb721d   Graeme Gregory   TPS65910: Add tps...
1022

9eb0c4218   Axel Lin   regulator: Conver...
1023
  	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
7e9a57e62   Laxman Dewangan   regulator: tps659...
1024
1025
1026
  	if (!pmic) {
  		dev_err(&pdev->dev, "Memory allocation failed for pmic
  ");
518fb721d   Graeme Gregory   TPS65910: Add tps...
1027
  		return -ENOMEM;
7e9a57e62   Laxman Dewangan   regulator: tps659...
1028
  	}
518fb721d   Graeme Gregory   TPS65910: Add tps...
1029

518fb721d   Graeme Gregory   TPS65910: Add tps...
1030
1031
1032
1033
  	pmic->mfd = tps65910;
  	platform_set_drvdata(pdev, pmic);
  
  	/* Give control of all register to control port */
3f7e82759   Rhyland Klein   mfd: Commonize tp...
1034
  	tps65910_reg_set_bits(pmic->mfd, TPS65910_DEVCTRL,
518fb721d   Graeme Gregory   TPS65910: Add tps...
1035
  				DEVCTRL_SR_CTL_I2C_SEL_MASK);
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1036
1037
1038
  	switch(tps65910_chip_id(tps65910)) {
  	case TPS65910:
  		pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
39aa9b6e3   Axel Lin   regulator: tps659...
1039
  		pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
1e0c66f49   Laxman Dewangan   regulator: tps659...
1040
  		pmic->ext_sleep_control = tps65910_ext_sleep_control;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1041
  		info = tps65910_regs;
d04156bca   Axel Lin   regulator: tps659...
1042
  		break;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1043
1044
  	case TPS65911:
  		pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
39aa9b6e3   Axel Lin   regulator: tps659...
1045
  		pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
1e0c66f49   Laxman Dewangan   regulator: tps659...
1046
  		pmic->ext_sleep_control = tps65911_ext_sleep_control;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1047
  		info = tps65911_regs;
d04156bca   Axel Lin   regulator: tps659...
1048
  		break;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1049
  	default:
7e9a57e62   Laxman Dewangan   regulator: tps659...
1050
1051
  		dev_err(&pdev->dev, "Invalid tps chip version
  ");
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1052
1053
  		return -ENODEV;
  	}
68d8c1cd5   Laxman Dewangan   regulator: tps659...
1054
  	pmic->desc = devm_kzalloc(&pdev->dev, pmic->num_regulators *
39aa9b6e3   Axel Lin   regulator: tps659...
1055
1056
  			sizeof(struct regulator_desc), GFP_KERNEL);
  	if (!pmic->desc) {
68d8c1cd5   Laxman Dewangan   regulator: tps659...
1057
1058
1059
  		dev_err(&pdev->dev, "Memory alloc fails for desc
  ");
  		return -ENOMEM;
39aa9b6e3   Axel Lin   regulator: tps659...
1060
  	}
68d8c1cd5   Laxman Dewangan   regulator: tps659...
1061
  	pmic->info = devm_kzalloc(&pdev->dev, pmic->num_regulators *
39aa9b6e3   Axel Lin   regulator: tps659...
1062
1063
  			sizeof(struct tps_info *), GFP_KERNEL);
  	if (!pmic->info) {
68d8c1cd5   Laxman Dewangan   regulator: tps659...
1064
1065
1066
  		dev_err(&pdev->dev, "Memory alloc fails for info
  ");
  		return -ENOMEM;
39aa9b6e3   Axel Lin   regulator: tps659...
1067
  	}
68d8c1cd5   Laxman Dewangan   regulator: tps659...
1068
  	pmic->rdev = devm_kzalloc(&pdev->dev, pmic->num_regulators *
39aa9b6e3   Axel Lin   regulator: tps659...
1069
1070
  			sizeof(struct regulator_dev *), GFP_KERNEL);
  	if (!pmic->rdev) {
68d8c1cd5   Laxman Dewangan   regulator: tps659...
1071
1072
1073
  		dev_err(&pdev->dev, "Memory alloc fails for rdev
  ");
  		return -ENOMEM;
39aa9b6e3   Axel Lin   regulator: tps659...
1074
  	}
c1fc14802   Kyle Manna   regulator: TPS659...
1075
1076
1077
1078
1079
1080
1081
1082
1083
  	for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS;
  			i++, info++) {
  
  		reg_data = pmic_plat_data->tps65910_pmic_init_data[i];
  
  		/* Regulator API handles empty constraints but not NULL
  		 * constraints */
  		if (!reg_data)
  			continue;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1084
1085
1086
1087
  		/* Register the regulators */
  		pmic->info[i] = info;
  
  		pmic->desc[i].name = info->name;
d2cfdb055   Laxman Dewangan   regulator: tps659...
1088
  		pmic->desc[i].supply_name = info->vin_name;
77fa44d0e   Axel Lin   regulator: Fix de...
1089
  		pmic->desc[i].id = i;
7d38a3cb9   Laxman Dewangan   regulator: tps659...
1090
  		pmic->desc[i].n_voltages = info->n_voltages;
94f48ab32   Axel Lin   regulator: tps659...
1091
  		pmic->desc[i].enable_time = info->enable_time_us;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1092

a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1093
  		if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
518fb721d   Graeme Gregory   TPS65910: Add tps...
1094
  			pmic->desc[i].ops = &tps65910_ops_dcdc;
780dc9ba4   Afzal Mohammed   regulator: TPS659...
1095
1096
  			pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE *
  							VDD1_2_NUM_VOLT_COARSE;
01bc3a140   Axel Lin   regulator: tps659...
1097
  			pmic->desc[i].ramp_delay = 12500;
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1098
  		} else if (i == TPS65910_REG_VDD3) {
01bc3a140   Axel Lin   regulator: tps659...
1099
  			if (tps65910_chip_id(tps65910) == TPS65910) {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1100
  				pmic->desc[i].ops = &tps65910_ops_vdd3;
d9fe28f96   Axel Lin   regulator: tps659...
1101
  				pmic->desc[i].volt_table = info->voltage_table;
01bc3a140   Axel Lin   regulator: tps659...
1102
  			} else {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1103
  				pmic->desc[i].ops = &tps65910_ops_dcdc;
01bc3a140   Axel Lin   regulator: tps659...
1104
1105
  				pmic->desc[i].ramp_delay = 5000;
  			}
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1106
  		} else {
d9fe28f96   Axel Lin   regulator: tps659...
1107
  			if (tps65910_chip_id(tps65910) == TPS65910) {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1108
  				pmic->desc[i].ops = &tps65910_ops;
d9fe28f96   Axel Lin   regulator: tps659...
1109
1110
  				pmic->desc[i].volt_table = info->voltage_table;
  			} else {
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1111
  				pmic->desc[i].ops = &tps65911_ops;
d9fe28f96   Axel Lin   regulator: tps659...
1112
  			}
a320e3c3d   Jorge Eduardo Candelaria   regulator: tps659...
1113
  		}
518fb721d   Graeme Gregory   TPS65910: Add tps...
1114

1e0c66f49   Laxman Dewangan   regulator: tps659...
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
  		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...
1125
1126
  		pmic->desc[i].type = REGULATOR_VOLTAGE;
  		pmic->desc[i].owner = THIS_MODULE;
a40a9c436   Axel Lin   regulator: tps659...
1127
1128
  		pmic->desc[i].enable_reg = pmic->get_ctrl_reg(i);
  		pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1129

c172708d3   Mark Brown   regulator: core: ...
1130
1131
1132
  		config.dev = tps65910->dev;
  		config.init_data = reg_data;
  		config.driver_data = pmic;
a40a9c436   Axel Lin   regulator: tps659...
1133
  		config.regmap = tps65910->regmap;
c172708d3   Mark Brown   regulator: core: ...
1134

84df8c124   Laxman Dewangan   regulator: tps659...
1135
1136
  		if (tps65910_reg_matches)
  			config.of_node = tps65910_reg_matches[i].of_node;
6790178f5   Rhyland Klein   regulator: tps659...
1137

c172708d3   Mark Brown   regulator: core: ...
1138
  		rdev = regulator_register(&pmic->desc[i], &config);
518fb721d   Graeme Gregory   TPS65910: Add tps...
1139
1140
1141
1142
1143
1144
  		if (IS_ERR(rdev)) {
  			dev_err(tps65910->dev,
  				"failed to register %s regulator
  ",
  				pdev->name);
  			err = PTR_ERR(rdev);
39aa9b6e3   Axel Lin   regulator: tps659...
1145
  			goto err_unregister_regulator;
518fb721d   Graeme Gregory   TPS65910: Add tps...
1146
1147
1148
1149
1150
1151
  		}
  
  		/* Save regulator for cleanup */
  		pmic->rdev[i] = rdev;
  	}
  	return 0;
39aa9b6e3   Axel Lin   regulator: tps659...
1152
  err_unregister_regulator:
518fb721d   Graeme Gregory   TPS65910: Add tps...
1153
1154
  	while (--i >= 0)
  		regulator_unregister(pmic->rdev[i]);
518fb721d   Graeme Gregory   TPS65910: Add tps...
1155
1156
1157
1158
1159
  	return err;
  }
  
  static int __devexit tps65910_remove(struct platform_device *pdev)
  {
39aa9b6e3   Axel Lin   regulator: tps659...
1160
  	struct tps65910_reg *pmic = platform_get_drvdata(pdev);
518fb721d   Graeme Gregory   TPS65910: Add tps...
1161
  	int i;
39aa9b6e3   Axel Lin   regulator: tps659...
1162
1163
  	for (i = 0; i < pmic->num_regulators; i++)
  		regulator_unregister(pmic->rdev[i]);
518fb721d   Graeme Gregory   TPS65910: Add tps...
1164

518fb721d   Graeme Gregory   TPS65910: Add tps...
1165
1166
  	return 0;
  }
1e0c66f49   Laxman Dewangan   regulator: tps659...
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
  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...
1197
1198
1199
1200
1201
1202
1203
  static struct platform_driver tps65910_driver = {
  	.driver = {
  		.name = "tps65910-pmic",
  		.owner = THIS_MODULE,
  	},
  	.probe = tps65910_probe,
  	.remove = __devexit_p(tps65910_remove),
1e0c66f49   Laxman Dewangan   regulator: tps659...
1204
  	.shutdown = tps65910_shutdown,
518fb721d   Graeme Gregory   TPS65910: Add tps...
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
  };
  
  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...
1220
  MODULE_DESCRIPTION("TPS65910/TPS65911 voltage regulator driver");
518fb721d   Graeme Gregory   TPS65910: Add tps...
1221
1222
  MODULE_LICENSE("GPL v2");
  MODULE_ALIAS("platform:tps65910-pmic");