Blame view

drivers/regulator/da903x-regulator.c 14.7 KB
fd2f02f97   Axel Lin   regulator: da9xxx...
1
2
3
4
5
6
  // SPDX-License-Identifier: GPL-2.0
  //
  // Regulators driver for Dialog Semiconductor DA903x
  //
  // Copyright (C) 2006-2008 Marvell International Ltd.
  // Copyright (C) 2008 Compulab Ltd.
129eef96c   Eric Miao   da903x: add regul...
7
8
9
10
  
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/err.h>
65602c32e   Paul Gortmaker   regulator: Add mo...
11
  #include <linux/module.h>
129eef96c   Eric Miao   da903x: add regul...
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  #include <linux/platform_device.h>
  #include <linux/regulator/driver.h>
  #include <linux/regulator/machine.h>
  #include <linux/mfd/da903x.h>
  
  /* DA9030 Registers */
  #define DA9030_INVAL		(-1)
  #define DA9030_LDO1011		(0x10)
  #define DA9030_LDO15		(0x11)
  #define DA9030_LDO1416		(0x12)
  #define DA9030_LDO1819		(0x13)
  #define DA9030_LDO17		(0x14)
  #define DA9030_BUCK2DVM1	(0x15)
  #define DA9030_BUCK2DVM2	(0x16)
  #define DA9030_RCTL11		(0x17)
  #define DA9030_RCTL21		(0x18)
  #define DA9030_LDO1		(0x90)
  #define DA9030_LDO23		(0x91)
  #define DA9030_LDO45		(0x92)
  #define DA9030_LDO6		(0x93)
  #define DA9030_LDO78		(0x94)
  #define DA9030_LDO912		(0x95)
  #define DA9030_BUCK		(0x96)
  #define DA9030_RCTL12		(0x97)
  #define DA9030_RCTL22		(0x98)
  #define DA9030_LDO_UNLOCK	(0xa0)
  #define DA9030_LDO_UNLOCK_MASK	(0xe0)
  #define DA9034_OVER1		(0x10)
  
  /* DA9034 Registers */
  #define DA9034_INVAL		(-1)
  #define DA9034_OVER2		(0x11)
  #define DA9034_OVER3		(0x12)
  #define DA9034_LDO643		(0x13)
  #define DA9034_LDO987		(0x14)
  #define DA9034_LDO1110		(0x15)
  #define DA9034_LDO1312		(0x16)
  #define DA9034_LDO1514		(0x17)
  #define DA9034_VCC1		(0x20)
  #define DA9034_ADTV1		(0x23)
  #define DA9034_ADTV2		(0x24)
  #define DA9034_AVRC		(0x25)
  #define DA9034_CDTV1		(0x26)
  #define DA9034_CDTV2		(0x27)
  #define DA9034_CVRC		(0x28)
  #define DA9034_SDTV1		(0x29)
  #define DA9034_SDTV2		(0x2a)
  #define DA9034_SVRC		(0x2b)
  #define DA9034_MDTV1		(0x32)
  #define DA9034_MDTV2		(0x33)
  #define DA9034_MVRC		(0x34)
0198d1163   Haojian Zhuang   regulator: add bu...
63
64
65
66
67
68
69
  /* DA9035 Registers. DA9034 Registers are comptabile to DA9035. */
  #define DA9035_OVER3		(0x12)
  #define DA9035_VCC2		(0x1f)
  #define DA9035_3DTV1		(0x2c)
  #define DA9035_3DTV2		(0x2d)
  #define DA9035_3VRC		(0x2e)
  #define DA9035_AUTOSKIP		(0x2f)
129eef96c   Eric Miao   da903x: add regul...
70
71
  struct da903x_regulator_info {
  	struct regulator_desc desc;
129eef96c   Eric Miao   da903x: add regul...
72
  	int	max_uV;
129eef96c   Eric Miao   da903x: add regul...
73
74
75
76
77
78
79
80
  	int	vol_reg;
  	int	vol_shift;
  	int	vol_nbits;
  	int	update_reg;
  	int	update_bit;
  	int	enable_reg;
  	int	enable_bit;
  };
1841c0f2b   Jonathan Cameron   regulator: da903x...
81
82
83
84
  static inline struct device *to_da903x_dev(struct regulator_dev *rdev)
  {
  	return rdev_get_dev(rdev)->parent->parent;
  }
129eef96c   Eric Miao   da903x: add regul...
85
86
87
  static inline int check_range(struct da903x_regulator_info *info,
  				int min_uV, int max_uV)
  {
70b4e7862   Axel Lin   regulator: da903x...
88
  	if (min_uV < info->desc.min_uV || min_uV > info->max_uV)
129eef96c   Eric Miao   da903x: add regul...
89
90
91
92
93
94
  		return -EINVAL;
  
  	return 0;
  }
  
  /* DA9030/DA9034 common operations */
bae5e9c33   Axel Lin   regulator: da903x...
95
  static int da903x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
129eef96c   Eric Miao   da903x: add regul...
96
97
  {
  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
1841c0f2b   Jonathan Cameron   regulator: da903x...
98
  	struct device *da9034_dev = to_da903x_dev(rdev);
129eef96c   Eric Miao   da903x: add regul...
99
  	uint8_t val, mask;
ee3ed6eff   Axel Lin   regulator: da903x...
100
101
  	if (rdev->desc->n_voltages == 1)
  		return -EINVAL;
c972a0294   Axel Lin   regulator: da903x...
102
  	val = selector << info->vol_shift;
129eef96c   Eric Miao   da903x: add regul...
103
104
105
106
  	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
  
  	return da903x_update(da9034_dev, info->vol_reg, val, mask);
  }
9447f35a1   Axel Lin   regulator: da903x...
107
  static int da903x_get_voltage_sel(struct regulator_dev *rdev)
129eef96c   Eric Miao   da903x: add regul...
108
109
  {
  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
1841c0f2b   Jonathan Cameron   regulator: da903x...
110
  	struct device *da9034_dev = to_da903x_dev(rdev);
129eef96c   Eric Miao   da903x: add regul...
111
112
  	uint8_t val, mask;
  	int ret;
ee3ed6eff   Axel Lin   regulator: da903x...
113
114
  	if (rdev->desc->n_voltages == 1)
  		return 0;
129eef96c   Eric Miao   da903x: add regul...
115
116
117
118
119
120
  	ret = da903x_read(da9034_dev, info->vol_reg, &val);
  	if (ret)
  		return ret;
  
  	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
  	val = (val & mask) >> info->vol_shift;
9447f35a1   Axel Lin   regulator: da903x...
121
  	return val;
129eef96c   Eric Miao   da903x: add regul...
122
123
124
125
126
  }
  
  static int da903x_enable(struct regulator_dev *rdev)
  {
  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
1841c0f2b   Jonathan Cameron   regulator: da903x...
127
  	struct device *da9034_dev = to_da903x_dev(rdev);
129eef96c   Eric Miao   da903x: add regul...
128
129
130
131
132
133
134
135
  
  	return da903x_set_bits(da9034_dev, info->enable_reg,
  					1 << info->enable_bit);
  }
  
  static int da903x_disable(struct regulator_dev *rdev)
  {
  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
1841c0f2b   Jonathan Cameron   regulator: da903x...
136
  	struct device *da9034_dev = to_da903x_dev(rdev);
129eef96c   Eric Miao   da903x: add regul...
137
138
139
140
141
142
143
144
  
  	return da903x_clr_bits(da9034_dev, info->enable_reg,
  					1 << info->enable_bit);
  }
  
  static int da903x_is_enabled(struct regulator_dev *rdev)
  {
  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
1841c0f2b   Jonathan Cameron   regulator: da903x...
145
  	struct device *da9034_dev = to_da903x_dev(rdev);
129eef96c   Eric Miao   da903x: add regul...
146
147
148
149
150
151
  	uint8_t reg_val;
  	int ret;
  
  	ret = da903x_read(da9034_dev, info->enable_reg, &reg_val);
  	if (ret)
  		return ret;
961869048   Mike Rapoport   regulator: da903x...
152
  	return !!(reg_val & (1 << info->enable_bit));
129eef96c   Eric Miao   da903x: add regul...
153
154
155
  }
  
  /* DA9030 specific operations */
c972a0294   Axel Lin   regulator: da903x...
156
157
  static int da9030_set_ldo1_15_voltage_sel(struct regulator_dev *rdev,
  					  unsigned selector)
129eef96c   Eric Miao   da903x: add regul...
158
159
  {
  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
1841c0f2b   Jonathan Cameron   regulator: da903x...
160
  	struct device *da903x_dev = to_da903x_dev(rdev);
129eef96c   Eric Miao   da903x: add regul...
161
162
  	uint8_t val, mask;
  	int ret;
c972a0294   Axel Lin   regulator: da903x...
163
  	val = selector << info->vol_shift;
129eef96c   Eric Miao   da903x: add regul...
164
165
166
167
168
169
170
171
172
173
174
  	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
  	val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */
  	mask |= DA9030_LDO_UNLOCK_MASK;
  
  	/* write twice */
  	ret = da903x_update(da903x_dev, info->vol_reg, val, mask);
  	if (ret)
  		return ret;
  
  	return da903x_update(da903x_dev, info->vol_reg, val, mask);
  }
c972a0294   Axel Lin   regulator: da903x...
175
176
177
178
179
  static int da9030_map_ldo14_voltage(struct regulator_dev *rdev,
  				    int min_uV, int max_uV)
  {
  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
  	int thresh, sel;
129eef96c   Eric Miao   da903x: add regul...
180
181
  
  	if (check_range(info, min_uV, max_uV)) {
471d8d49a   Mike Rapoport   regulator: da903x...
182
183
  		pr_err("invalid voltage range (%d, %d) uV
  ", min_uV, max_uV);
129eef96c   Eric Miao   da903x: add regul...
184
185
  		return -EINVAL;
  	}
70b4e7862   Axel Lin   regulator: da903x...
186
  	thresh = (info->max_uV + info->desc.min_uV) / 2;
129eef96c   Eric Miao   da903x: add regul...
187
  	if (min_uV < thresh) {
c972a0294   Axel Lin   regulator: da903x...
188
189
  		sel = DIV_ROUND_UP(thresh - min_uV, info->desc.uV_step);
  		sel |= 0x4;
129eef96c   Eric Miao   da903x: add regul...
190
  	} else {
c972a0294   Axel Lin   regulator: da903x...
191
  		sel = DIV_ROUND_UP(min_uV - thresh, info->desc.uV_step);
129eef96c   Eric Miao   da903x: add regul...
192
  	}
c972a0294   Axel Lin   regulator: da903x...
193
  	return sel;
129eef96c   Eric Miao   da903x: add regul...
194
  }
d4eb56a16   Axel Lin   regulator: da903x...
195
196
197
198
199
200
201
  static int da9030_list_ldo14_voltage(struct regulator_dev *rdev,
  				     unsigned selector)
  {
  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
  	int volt;
  
  	if (selector & 0x4)
70b4e7862   Axel Lin   regulator: da903x...
202
203
  		volt = rdev->desc->min_uV +
  		       rdev->desc->uV_step * (3 - (selector & ~0x4));
d4eb56a16   Axel Lin   regulator: da903x...
204
  	else
70b4e7862   Axel Lin   regulator: da903x...
205
206
  		volt = (info->max_uV + rdev->desc->min_uV) / 2 +
  		       rdev->desc->uV_step * (selector & ~0x4);
d4eb56a16   Axel Lin   regulator: da903x...
207
208
209
210
211
212
  
  	if (volt > info->max_uV)
  		return -EINVAL;
  
  	return volt;
  }
129eef96c   Eric Miao   da903x: add regul...
213
  /* DA9034 specific operations */
c972a0294   Axel Lin   regulator: da903x...
214
215
  static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev,
  				      unsigned selector)
129eef96c   Eric Miao   da903x: add regul...
216
217
  {
  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
1841c0f2b   Jonathan Cameron   regulator: da903x...
218
  	struct device *da9034_dev = to_da903x_dev(rdev);
129eef96c   Eric Miao   da903x: add regul...
219
220
  	uint8_t val, mask;
  	int ret;
c972a0294   Axel Lin   regulator: da903x...
221
  	val = selector << info->vol_shift;
129eef96c   Eric Miao   da903x: add regul...
222
223
224
225
226
227
228
229
230
231
  	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
  
  	ret = da903x_update(da9034_dev, info->vol_reg, val, mask);
  	if (ret)
  		return ret;
  
  	ret = da903x_set_bits(da9034_dev, info->update_reg,
  					1 << info->update_bit);
  	return ret;
  }
60ab7f415   Matti Vaittinen   regulator: use li...
232
  static const struct linear_range da9034_ldo12_ranges[] = {
8828bae46   Axel Lin   regulator: Add RE...
233
234
  	REGULATOR_LINEAR_RANGE(1700000, 0, 7, 50000),
  	REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000),
550bf8936   Axel Lin   regulator: da903x...
235
  };
c1b60873c   Haojian Zhuang   regulator: suppor...
236

71242b49a   Julia Lawall   regulator: da9*: ...
237
  static const struct regulator_ops da903x_regulator_ldo_ops = {
bae5e9c33   Axel Lin   regulator: da903x...
238
  	.set_voltage_sel = da903x_set_voltage_sel,
9447f35a1   Axel Lin   regulator: da903x...
239
  	.get_voltage_sel = da903x_get_voltage_sel,
70b4e7862   Axel Lin   regulator: da903x...
240
  	.list_voltage	= regulator_list_voltage_linear,
c972a0294   Axel Lin   regulator: da903x...
241
  	.map_voltage	= regulator_map_voltage_linear,
129eef96c   Eric Miao   da903x: add regul...
242
243
244
245
246
247
  	.enable		= da903x_enable,
  	.disable	= da903x_disable,
  	.is_enabled	= da903x_is_enabled,
  };
  
  /* NOTE: this is dedicated for the insane DA9030 LDO14 */
71242b49a   Julia Lawall   regulator: da9*: ...
248
  static const struct regulator_ops da9030_regulator_ldo14_ops = {
bae5e9c33   Axel Lin   regulator: da903x...
249
250
  	.set_voltage_sel = da903x_set_voltage_sel,
  	.get_voltage_sel = da903x_get_voltage_sel,
d4eb56a16   Axel Lin   regulator: da903x...
251
  	.list_voltage	= da9030_list_ldo14_voltage,
c972a0294   Axel Lin   regulator: da903x...
252
  	.map_voltage	= da9030_map_ldo14_voltage,
129eef96c   Eric Miao   da903x: add regul...
253
254
255
256
257
258
  	.enable		= da903x_enable,
  	.disable	= da903x_disable,
  	.is_enabled	= da903x_is_enabled,
  };
  
  /* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks  */
71242b49a   Julia Lawall   regulator: da9*: ...
259
  static const struct regulator_ops da9030_regulator_ldo1_15_ops = {
c972a0294   Axel Lin   regulator: da903x...
260
  	.set_voltage_sel = da9030_set_ldo1_15_voltage_sel,
9447f35a1   Axel Lin   regulator: da903x...
261
  	.get_voltage_sel = da903x_get_voltage_sel,
70b4e7862   Axel Lin   regulator: da903x...
262
  	.list_voltage	= regulator_list_voltage_linear,
c972a0294   Axel Lin   regulator: da903x...
263
  	.map_voltage	= regulator_map_voltage_linear,
129eef96c   Eric Miao   da903x: add regul...
264
265
266
267
  	.enable		= da903x_enable,
  	.disable	= da903x_disable,
  	.is_enabled	= da903x_is_enabled,
  };
71242b49a   Julia Lawall   regulator: da9*: ...
268
  static const struct regulator_ops da9034_regulator_dvc_ops = {
c972a0294   Axel Lin   regulator: da903x...
269
  	.set_voltage_sel = da9034_set_dvc_voltage_sel,
9447f35a1   Axel Lin   regulator: da903x...
270
  	.get_voltage_sel = da903x_get_voltage_sel,
70b4e7862   Axel Lin   regulator: da903x...
271
  	.list_voltage	= regulator_list_voltage_linear,
c972a0294   Axel Lin   regulator: da903x...
272
  	.map_voltage	= regulator_map_voltage_linear,
129eef96c   Eric Miao   da903x: add regul...
273
274
275
276
277
278
  	.enable		= da903x_enable,
  	.disable	= da903x_disable,
  	.is_enabled	= da903x_is_enabled,
  };
  
  /* NOTE: this is dedicated for the insane LDO12 */
71242b49a   Julia Lawall   regulator: da9*: ...
279
  static const struct regulator_ops da9034_regulator_ldo12_ops = {
bae5e9c33   Axel Lin   regulator: da903x...
280
281
  	.set_voltage_sel = da903x_set_voltage_sel,
  	.get_voltage_sel = da903x_get_voltage_sel,
550bf8936   Axel Lin   regulator: da903x...
282
283
  	.list_voltage	= regulator_list_voltage_linear_range,
  	.map_voltage	= regulator_map_voltage_linear_range,
129eef96c   Eric Miao   da903x: add regul...
284
285
286
287
288
289
290
291
292
293
294
295
  	.enable		= da903x_enable,
  	.disable	= da903x_disable,
  	.is_enabled	= da903x_is_enabled,
  };
  
  #define DA903x_LDO(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit)	\
  {									\
  	.desc	= {							\
  		.name	= "LDO" #_id,					\
  		.ops	= &da903x_regulator_ldo_ops,			\
  		.type	= REGULATOR_VOLTAGE,				\
  		.id	= _pmic##_ID_LDO##_id,				\
c1b60873c   Haojian Zhuang   regulator: suppor...
296
  		.n_voltages = (step) ? ((max - min) / step + 1) : 1,	\
129eef96c   Eric Miao   da903x: add regul...
297
  		.owner	= THIS_MODULE,					\
70b4e7862   Axel Lin   regulator: da903x...
298
299
  		.min_uV	 = (min) * 1000,				\
  		.uV_step = (step) * 1000,				\
129eef96c   Eric Miao   da903x: add regul...
300
  	},								\
129eef96c   Eric Miao   da903x: add regul...
301
  	.max_uV		= (max) * 1000,					\
129eef96c   Eric Miao   da903x: add regul...
302
303
304
305
306
307
  	.vol_reg	= _pmic##_##vreg,				\
  	.vol_shift	= (shift),					\
  	.vol_nbits	= (nbits),					\
  	.enable_reg	= _pmic##_##ereg,				\
  	.enable_bit	= (ebit),					\
  }
c6db18282   Mike Rapoport   regulator: da903x...
308
  #define DA903x_DVC(_pmic, _id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
fc4f42e7f   Haojian Zhuang   regulator: suppor...
309
310
311
312
313
  {									\
  	.desc	= {							\
  		.name	= #_id,						\
  		.ops	= &da9034_regulator_dvc_ops,			\
  		.type	= REGULATOR_VOLTAGE,				\
c6db18282   Mike Rapoport   regulator: da903x...
314
  		.id	= _pmic##_ID_##_id,				\
c1b60873c   Haojian Zhuang   regulator: suppor...
315
  		.n_voltages = (step) ? ((max - min) / step + 1) : 1,	\
fc4f42e7f   Haojian Zhuang   regulator: suppor...
316
  		.owner	= THIS_MODULE,					\
70b4e7862   Axel Lin   regulator: da903x...
317
318
  		.min_uV = (min) * 1000,					\
  		.uV_step = (step) * 1000,				\
fc4f42e7f   Haojian Zhuang   regulator: suppor...
319
  	},								\
fc4f42e7f   Haojian Zhuang   regulator: suppor...
320
  	.max_uV		= (max) * 1000,					\
c6db18282   Mike Rapoport   regulator: da903x...
321
  	.vol_reg	= _pmic##_##vreg,				\
0198d1163   Haojian Zhuang   regulator: add bu...
322
323
  	.vol_shift	= (0),						\
  	.vol_nbits	= (nbits),					\
c6db18282   Mike Rapoport   regulator: da903x...
324
  	.update_reg	= _pmic##_##ureg,				\
0198d1163   Haojian Zhuang   regulator: add bu...
325
  	.update_bit	= (ubit),					\
c6db18282   Mike Rapoport   regulator: da903x...
326
  	.enable_reg	= _pmic##_##ereg,				\
0198d1163   Haojian Zhuang   regulator: add bu...
327
328
  	.enable_bit	= (ebit),					\
  }
129eef96c   Eric Miao   da903x: add regul...
329
330
331
332
333
  #define DA9034_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit)	\
  	DA903x_LDO(DA9034, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
  
  #define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit)	\
  	DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
c6db18282   Mike Rapoport   regulator: da903x...
334
335
336
337
338
339
340
341
342
343
344
  #define DA9030_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
  	DA903x_DVC(DA9030, _id, min, max, step, vreg, nbits, ureg, ubit, \
  		   ereg, ebit)
  
  #define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
  	DA903x_DVC(DA9034, _id, min, max, step, vreg, nbits, ureg, ubit, \
  		   ereg, ebit)
  
  #define DA9035_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
  	DA903x_DVC(DA9035, _id, min, max, step, vreg, nbits, ureg, ubit, \
  		   ereg, ebit)
129eef96c   Eric Miao   da903x: add regul...
345
346
  static struct da903x_regulator_info da903x_regulator_info[] = {
  	/* DA9030 */
fc4f42e7f   Haojian Zhuang   regulator: suppor...
347
  	DA9030_DVC(BUCK2, 850, 1625, 25, BUCK2DVM1, 5, BUCK2DVM1, 7, RCTL11, 0),
129eef96c   Eric Miao   da903x: add regul...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  	DA9030_LDO( 1, 1200, 3200, 100,    LDO1, 0, 5, RCTL12, 1),
  	DA9030_LDO( 2, 1800, 3200, 100,   LDO23, 0, 4, RCTL12, 2),
  	DA9030_LDO( 3, 1800, 3200, 100,   LDO23, 4, 4, RCTL12, 3),
  	DA9030_LDO( 4, 1800, 3200, 100,   LDO45, 0, 4, RCTL12, 4),
  	DA9030_LDO( 5, 1800, 3200, 100,   LDO45, 4, 4, RCTL12, 5),
  	DA9030_LDO( 6, 1800, 3200, 100,    LDO6, 0, 4, RCTL12, 6),
  	DA9030_LDO( 7, 1800, 3200, 100,   LDO78, 0, 4, RCTL12, 7),
  	DA9030_LDO( 8, 1800, 3200, 100,   LDO78, 4, 4, RCTL22, 0),
  	DA9030_LDO( 9, 1800, 3200, 100,  LDO912, 0, 4, RCTL22, 1),
  	DA9030_LDO(10, 1800, 3200, 100, LDO1011, 0, 4, RCTL22, 2),
  	DA9030_LDO(11, 1800, 3200, 100, LDO1011, 4, 4, RCTL22, 3),
  	DA9030_LDO(12, 1800, 3200, 100,  LDO912, 4, 4, RCTL22, 4),
  	DA9030_LDO(14, 2760, 2940,  30, LDO1416, 0, 3, RCTL11, 4),
  	DA9030_LDO(15, 1100, 2650,  50,	  LDO15, 0, 5, RCTL11, 5),
  	DA9030_LDO(16, 1100, 2650,  50, LDO1416, 3, 5, RCTL11, 6),
  	DA9030_LDO(17, 1800, 3200, 100,   LDO17, 0, 4, RCTL11, 7),
  	DA9030_LDO(18, 1800, 3200, 100, LDO1819, 0, 4, RCTL21, 2),
  	DA9030_LDO(19, 1800, 3200, 100, LDO1819, 4, 4, RCTL21, 1),
  	DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */
  
  	/* DA9034 */
e88267e16   Haojian Zhuang   regulator: replac...
369
370
371
  	DA9034_DVC(BUCK1, 725, 1500, 25, ADTV2, 5, VCC1, 0, OVER1, 0),
  	DA9034_DVC(BUCK2, 725, 1500, 25, CDTV2, 5, VCC1, 2, OVER1, 1),
  	DA9034_DVC(LDO2,  725, 1500, 25, SDTV2, 5, VCC1, 4, OVER1, 2),
129eef96c   Eric Miao   da903x: add regul...
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
  	DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4),
  
  	DA9034_LDO( 3, 1800, 3300, 100,  LDO643, 0, 4, OVER3, 5),
  	DA9034_LDO( 4, 1800, 2900,1100,  LDO643, 4, 1, OVER3, 6),
  	DA9034_LDO( 6, 2500, 2850,  50,  LDO643, 5, 3, OVER2, 0),
  	DA9034_LDO( 7, 2700, 3050,  50,  LDO987, 0, 3, OVER2, 1),
  	DA9034_LDO( 8, 2700, 2850,  50,  LDO987, 3, 2, OVER2, 2),
  	DA9034_LDO( 9, 2700, 3050,  50,  LDO987, 5, 3, OVER2, 3),
  	DA9034_LDO(10, 2700, 3050,  50, LDO1110, 0, 3, OVER2, 4),
  	DA9034_LDO(11, 1800, 3300, 100, LDO1110, 4, 4, OVER2, 5),
  	DA9034_LDO(12, 1700, 3050,  50, LDO1312, 0, 4, OVER3, 6),
  	DA9034_LDO(13, 1800, 3300, 100, LDO1312, 4, 4, OVER2, 7),
  	DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0),
  	DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1),
  	DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */
0198d1163   Haojian Zhuang   regulator: add bu...
387
388
389
  
  	/* DA9035 */
  	DA9035_DVC(BUCK3, 1800, 2200, 100, 3DTV1, 3, VCC2, 0, OVER3, 3),
129eef96c   Eric Miao   da903x: add regul...
390
391
392
393
394
395
396
397
398
399
400
401
402
403
  };
  
  static inline struct da903x_regulator_info *find_regulator_info(int id)
  {
  	struct da903x_regulator_info *ri;
  	int i;
  
  	for (i = 0; i < ARRAY_SIZE(da903x_regulator_info); i++) {
  		ri = &da903x_regulator_info[i];
  		if (ri->desc.id == id)
  			return ri;
  	}
  	return NULL;
  }
a5023574d   Bill Pemberton   regulator: remove...
404
  static int da903x_regulator_probe(struct platform_device *pdev)
129eef96c   Eric Miao   da903x: add regul...
405
406
407
  {
  	struct da903x_regulator_info *ri = NULL;
  	struct regulator_dev *rdev;
c172708d3   Mark Brown   regulator: core: ...
408
  	struct regulator_config config = { };
129eef96c   Eric Miao   da903x: add regul...
409
410
411
412
413
414
415
416
417
  
  	ri = find_regulator_info(pdev->id);
  	if (ri == NULL) {
  		dev_err(&pdev->dev, "invalid regulator ID specified
  ");
  		return -EINVAL;
  	}
  
  	/* Workaround for the weird LDO12 voltage setting */
c1b60873c   Haojian Zhuang   regulator: suppor...
418
  	if (ri->desc.id == DA9034_ID_LDO12) {
129eef96c   Eric Miao   da903x: add regul...
419
  		ri->desc.ops = &da9034_regulator_ldo12_ops;
9447f35a1   Axel Lin   regulator: da903x...
420
  		ri->desc.n_voltages = 16;
550bf8936   Axel Lin   regulator: da903x...
421
422
  		ri->desc.linear_ranges = da9034_ldo12_ranges;
  		ri->desc.n_linear_ranges = ARRAY_SIZE(da9034_ldo12_ranges);
c1b60873c   Haojian Zhuang   regulator: suppor...
423
  	}
129eef96c   Eric Miao   da903x: add regul...
424
425
426
427
428
429
  
  	if (ri->desc.id == DA9030_ID_LDO14)
  		ri->desc.ops = &da9030_regulator_ldo14_ops;
  
  	if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
  		ri->desc.ops = &da9030_regulator_ldo1_15_ops;
c172708d3   Mark Brown   regulator: core: ...
430
  	config.dev = &pdev->dev;
dff91d0b7   Jingoo Han   regulator: use de...
431
  	config.init_data = dev_get_platdata(&pdev->dev);
c172708d3   Mark Brown   regulator: core: ...
432
  	config.driver_data = ri;
4e8d79355   Axel Lin   regulator: da903x...
433
  	rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
129eef96c   Eric Miao   da903x: add regul...
434
435
436
437
438
439
440
441
442
443
  	if (IS_ERR(rdev)) {
  		dev_err(&pdev->dev, "failed to register regulator %s
  ",
  				ri->desc.name);
  		return PTR_ERR(rdev);
  	}
  
  	platform_set_drvdata(pdev, rdev);
  	return 0;
  }
129eef96c   Eric Miao   da903x: add regul...
444
445
446
  static struct platform_driver da903x_regulator_driver = {
  	.driver	= {
  		.name	= "da903x-regulator",
129eef96c   Eric Miao   da903x: add regul...
447
448
  	},
  	.probe		= da903x_regulator_probe,
129eef96c   Eric Miao   da903x: add regul...
449
450
451
452
453
454
  };
  
  static int __init da903x_regulator_init(void)
  {
  	return platform_driver_register(&da903x_regulator_driver);
  }
5a1b22bee   Mark Brown   regulator: Move r...
455
  subsys_initcall(da903x_regulator_init);
129eef96c   Eric Miao   da903x: add regul...
456
457
458
459
460
461
462
463
464
465
466
467
  
  static void __exit da903x_regulator_exit(void)
  {
  	platform_driver_unregister(&da903x_regulator_driver);
  }
  module_exit(da903x_regulator_exit);
  
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
  	      "Mike Rapoport <mike@compulab.co.il>");
  MODULE_DESCRIPTION("Regulator Driver for Dialog Semiconductor DA903X PMIC");
  MODULE_ALIAS("platform:da903x-regulator");