Blame view

drivers/regulator/mc13783-regulator.c 13.1 KB
295c08bc6   Sascha Hauer   regulator: Add Fr...
1
2
3
  /*
   * Regulator Driver for Freescale MC13783 PMIC
   *
167e3d8af   Yong Shen   make mc13783 regu...
4
   * Copyright 2010 Yong Shen <yong.shen@linaro.org>
295c08bc6   Sascha Hauer   regulator: Add Fr...
5
   * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
1bd588fd9   Alberto Panizzo   regulator: add vo...
6
   * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
295c08bc6   Sascha Hauer   regulator: Add Fr...
7
8
9
10
11
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
a10099bc8   Uwe Kleine-König   regulator/mc13783...
12
  #include <linux/mfd/mc13783.h>
295c08bc6   Sascha Hauer   regulator: Add Fr...
13
14
15
  #include <linux/regulator/machine.h>
  #include <linux/regulator/driver.h>
  #include <linux/platform_device.h>
295c08bc6   Sascha Hauer   regulator: Add Fr...
16
  #include <linux/kernel.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
17
  #include <linux/slab.h>
295c08bc6   Sascha Hauer   regulator: Add Fr...
18
19
  #include <linux/init.h>
  #include <linux/err.h>
65602c32e   Paul Gortmaker   regulator: Add mo...
20
  #include <linux/module.h>
167e3d8af   Yong Shen   make mc13783 regu...
21
  #include "mc13xxx.h"
295c08bc6   Sascha Hauer   regulator: Add Fr...
22

a10099bc8   Uwe Kleine-König   regulator/mc13783...
23
24
  #define MC13783_REG_SWITCHERS5			29
  #define MC13783_REG_SWITCHERS5_SW3EN			(1 << 20)
1bd588fd9   Alberto Panizzo   regulator: add vo...
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
  #define MC13783_REG_SWITCHERS5_SW3VSEL			18
  #define MC13783_REG_SWITCHERS5_SW3VSEL_M		(3 << 18)
  
  #define MC13783_REG_REGULATORSETTING0		30
  #define MC13783_REG_REGULATORSETTING0_VIOLOVSEL		2
  #define MC13783_REG_REGULATORSETTING0_VDIGVSEL		4
  #define MC13783_REG_REGULATORSETTING0_VGENVSEL		6
  #define MC13783_REG_REGULATORSETTING0_VRFDIGVSEL	9
  #define MC13783_REG_REGULATORSETTING0_VRFREFVSEL	11
  #define MC13783_REG_REGULATORSETTING0_VRFCPVSEL		13
  #define MC13783_REG_REGULATORSETTING0_VSIMVSEL		14
  #define MC13783_REG_REGULATORSETTING0_VESIMVSEL		15
  #define MC13783_REG_REGULATORSETTING0_VCAMVSEL		16
  
  #define MC13783_REG_REGULATORSETTING0_VIOLOVSEL_M	(3 << 2)
  #define MC13783_REG_REGULATORSETTING0_VDIGVSEL_M	(3 << 4)
  #define MC13783_REG_REGULATORSETTING0_VGENVSEL_M	(7 << 6)
  #define MC13783_REG_REGULATORSETTING0_VRFDIGVSEL_M	(3 << 9)
  #define MC13783_REG_REGULATORSETTING0_VRFREFVSEL_M	(3 << 11)
  #define MC13783_REG_REGULATORSETTING0_VRFCPVSEL_M	(1 << 13)
  #define MC13783_REG_REGULATORSETTING0_VSIMVSEL_M	(1 << 14)
  #define MC13783_REG_REGULATORSETTING0_VESIMVSEL_M	(1 << 15)
  #define MC13783_REG_REGULATORSETTING0_VCAMVSEL_M	(7 << 16)
  
  #define MC13783_REG_REGULATORSETTING1		31
  #define MC13783_REG_REGULATORSETTING1_VVIBVSEL		0
  #define MC13783_REG_REGULATORSETTING1_VRF1VSEL		2
  #define MC13783_REG_REGULATORSETTING1_VRF2VSEL		4
  #define MC13783_REG_REGULATORSETTING1_VMMC1VSEL		6
  #define MC13783_REG_REGULATORSETTING1_VMMC2VSEL		9
  
  #define MC13783_REG_REGULATORSETTING1_VVIBVSEL_M	(3 << 0)
  #define MC13783_REG_REGULATORSETTING1_VRF1VSEL_M	(3 << 2)
  #define MC13783_REG_REGULATORSETTING1_VRF2VSEL_M	(3 << 4)
  #define MC13783_REG_REGULATORSETTING1_VMMC1VSEL_M	(7 << 6)
  #define MC13783_REG_REGULATORSETTING1_VMMC2VSEL_M	(7 << 9)
a10099bc8   Uwe Kleine-König   regulator/mc13783...
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  
  #define MC13783_REG_REGULATORMODE0		32
  #define MC13783_REG_REGULATORMODE0_VAUDIOEN		(1 << 0)
  #define MC13783_REG_REGULATORMODE0_VIOHIEN		(1 << 3)
  #define MC13783_REG_REGULATORMODE0_VIOLOEN		(1 << 6)
  #define MC13783_REG_REGULATORMODE0_VDIGEN		(1 << 9)
  #define MC13783_REG_REGULATORMODE0_VGENEN		(1 << 12)
  #define MC13783_REG_REGULATORMODE0_VRFDIGEN		(1 << 15)
  #define MC13783_REG_REGULATORMODE0_VRFREFEN		(1 << 18)
  #define MC13783_REG_REGULATORMODE0_VRFCPEN		(1 << 21)
  
  #define MC13783_REG_REGULATORMODE1		33
  #define MC13783_REG_REGULATORMODE1_VSIMEN		(1 << 0)
  #define MC13783_REG_REGULATORMODE1_VESIMEN		(1 << 3)
  #define MC13783_REG_REGULATORMODE1_VCAMEN		(1 << 6)
  #define MC13783_REG_REGULATORMODE1_VRFBGEN		(1 << 9)
  #define MC13783_REG_REGULATORMODE1_VVIBEN		(1 << 11)
  #define MC13783_REG_REGULATORMODE1_VRF1EN		(1 << 12)
  #define MC13783_REG_REGULATORMODE1_VRF2EN		(1 << 15)
  #define MC13783_REG_REGULATORMODE1_VMMC1EN		(1 << 18)
  #define MC13783_REG_REGULATORMODE1_VMMC2EN		(1 << 21)
  
  #define MC13783_REG_POWERMISC			34
  #define MC13783_REG_POWERMISC_GPO1EN			(1 << 6)
  #define MC13783_REG_POWERMISC_GPO2EN			(1 << 8)
  #define MC13783_REG_POWERMISC_GPO3EN			(1 << 10)
  #define MC13783_REG_POWERMISC_GPO4EN			(1 << 12)
f4b97b36b   Alberto Panizzo   regulator: mc1378...
88
89
90
91
  #define MC13783_REG_POWERMISC_PWGT1SPIEN		(1 << 15)
  #define MC13783_REG_POWERMISC_PWGT2SPIEN		(1 << 16)
  
  #define MC13783_REG_POWERMISC_PWGTSPI_M			(3 << 15)
a10099bc8   Uwe Kleine-König   regulator/mc13783...
92

1bd588fd9   Alberto Panizzo   regulator: add vo...
93
  /* Voltage Values */
6220b87bf   Mark Brown   regulator: Remove...
94
  static const int mc13783_sw3_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
95
96
  	5000000, 5000000, 5000000, 5500000,
  };
6220b87bf   Mark Brown   regulator: Remove...
97
  static const int mc13783_vaudio_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
98
99
  	2775000,
  };
6220b87bf   Mark Brown   regulator: Remove...
100
  static const int mc13783_viohi_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
101
102
  	2775000,
  };
6220b87bf   Mark Brown   regulator: Remove...
103
  static const int mc13783_violo_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
104
105
  	1200000, 1300000, 1500000, 1800000,
  };
6220b87bf   Mark Brown   regulator: Remove...
106
  static const int mc13783_vdig_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
107
108
  	1200000, 1300000, 1500000, 1800000,
  };
6220b87bf   Mark Brown   regulator: Remove...
109
  static const int mc13783_vgen_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
110
111
112
  	1200000, 1300000, 1500000, 1800000,
  	1100000, 2000000, 2775000, 2400000,
  };
6220b87bf   Mark Brown   regulator: Remove...
113
  static const int mc13783_vrfdig_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
114
115
  	1200000, 1500000, 1800000, 1875000,
  };
6220b87bf   Mark Brown   regulator: Remove...
116
  static const int mc13783_vrfref_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
117
118
  	2475000, 2600000, 2700000, 2775000,
  };
6220b87bf   Mark Brown   regulator: Remove...
119
  static const int mc13783_vrfcp_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
120
121
  	2700000, 2775000,
  };
6220b87bf   Mark Brown   regulator: Remove...
122
  static const int mc13783_vsim_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
123
124
  	1800000, 2900000, 3000000,
  };
6220b87bf   Mark Brown   regulator: Remove...
125
  static const int mc13783_vesim_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
126
127
  	1800000, 2900000,
  };
6220b87bf   Mark Brown   regulator: Remove...
128
  static const int mc13783_vcam_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
129
130
131
  	1500000, 1800000, 2500000, 2550000,
  	2600000, 2750000, 2800000, 3000000,
  };
6220b87bf   Mark Brown   regulator: Remove...
132
  static const int mc13783_vrfbg_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
133
134
  	1250000,
  };
6220b87bf   Mark Brown   regulator: Remove...
135
  static const int mc13783_vvib_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
136
137
  	1300000, 1800000, 2000000, 3000000,
  };
6220b87bf   Mark Brown   regulator: Remove...
138
  static const int mc13783_vmmc_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
139
140
141
  	1600000, 1800000, 2000000, 2600000,
  	2700000, 2800000, 2900000, 3000000,
  };
6220b87bf   Mark Brown   regulator: Remove...
142
  static const int mc13783_vrf_val[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
143
  	1500000, 1875000, 2700000, 2775000,
295c08bc6   Sascha Hauer   regulator: Add Fr...
144
  };
6220b87bf   Mark Brown   regulator: Remove...
145
  static const int mc13783_gpo_val[] = {
f4b97b36b   Alberto Panizzo   regulator: mc1378...
146
147
  	3100000,
  };
6220b87bf   Mark Brown   regulator: Remove...
148
  static const int mc13783_pwgtdrv_val[] = {
f4b97b36b   Alberto Panizzo   regulator: mc1378...
149
150
  	5500000,
  };
f4b97b36b   Alberto Panizzo   regulator: mc1378...
151
  static struct regulator_ops mc13783_gpo_regulator_ops;
1bd588fd9   Alberto Panizzo   regulator: add vo...
152

167e3d8af   Yong Shen   make mc13783 regu...
153
154
155
  #define MC13783_DEFINE(prefix, name, reg, vsel_reg, voltages)	\
  	MC13xxx_DEFINE(MC13783_REG_, name, reg, vsel_reg, voltages, \
  			mc13xxx_regulator_ops)
295c08bc6   Sascha Hauer   regulator: Add Fr...
156

167e3d8af   Yong Shen   make mc13783 regu...
157
158
159
  #define MC13783_FIXED_DEFINE(prefix, name, reg, voltages)		\
  	MC13xxx_FIXED_DEFINE(MC13783_REG_, name, reg, voltages, \
  			mc13xxx_fixed_regulator_ops)
1bd588fd9   Alberto Panizzo   regulator: add vo...
160

167e3d8af   Yong Shen   make mc13783 regu...
161
162
163
  #define MC13783_GPO_DEFINE(prefix, name, reg, voltages)		\
  	MC13xxx_GPO_DEFINE(MC13783_REG_, name, reg, voltages, \
  			mc13783_gpo_regulator_ops)
a10099bc8   Uwe Kleine-König   regulator/mc13783...
164

1bd588fd9   Alberto Panizzo   regulator: add vo...
165
  #define MC13783_DEFINE_SW(_name, _reg, _vsel_reg, _voltages)		\
57c78e359   Yong Shen   Change the regist...
166
  	MC13783_DEFINE(REG, _name, _reg, _vsel_reg, _voltages)
1bd588fd9   Alberto Panizzo   regulator: add vo...
167
  #define MC13783_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages)		\
57c78e359   Yong Shen   Change the regist...
168
  	MC13783_DEFINE(REG, _name, _reg, _vsel_reg, _voltages)
a10099bc8   Uwe Kleine-König   regulator/mc13783...
169

167e3d8af   Yong Shen   make mc13783 regu...
170
  static struct mc13xxx_regulator mc13783_regulators[] = {
1bd588fd9   Alberto Panizzo   regulator: add vo...
171
  	MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val),
57c78e359   Yong Shen   Change the regist...
172
173
  	MC13783_FIXED_DEFINE(REG, VAUDIO, REGULATORMODE0, mc13783_vaudio_val),
  	MC13783_FIXED_DEFINE(REG, VIOHI, REGULATORMODE0, mc13783_viohi_val),
1bd588fd9   Alberto Panizzo   regulator: add vo...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
  	MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0, REGULATORSETTING0,	\
  			    mc13783_violo_val),
  	MC13783_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0,	\
  			    mc13783_vdig_val),
  	MC13783_DEFINE_REGU(VGEN, REGULATORMODE0, REGULATORSETTING0,	\
  			    mc13783_vgen_val),
  	MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0, REGULATORSETTING0,	\
  			    mc13783_vrfdig_val),
  	MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0, REGULATORSETTING0,	\
  			    mc13783_vrfref_val),
  	MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0, REGULATORSETTING0,	\
  			    mc13783_vrfcp_val),
  	MC13783_DEFINE_REGU(VSIM, REGULATORMODE1, REGULATORSETTING0,	\
  			    mc13783_vsim_val),
  	MC13783_DEFINE_REGU(VESIM, REGULATORMODE1, REGULATORSETTING0,	\
  			    mc13783_vesim_val),
  	MC13783_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0,	\
  			    mc13783_vcam_val),
57c78e359   Yong Shen   Change the regist...
192
  	MC13783_FIXED_DEFINE(REG, VRFBG, REGULATORMODE1, mc13783_vrfbg_val),
1bd588fd9   Alberto Panizzo   regulator: add vo...
193
194
195
196
197
198
199
200
201
202
  	MC13783_DEFINE_REGU(VVIB, REGULATORMODE1, REGULATORSETTING1,	\
  			    mc13783_vvib_val),
  	MC13783_DEFINE_REGU(VRF1, REGULATORMODE1, REGULATORSETTING1,	\
  			    mc13783_vrf_val),
  	MC13783_DEFINE_REGU(VRF2, REGULATORMODE1, REGULATORSETTING1,	\
  			    mc13783_vrf_val),
  	MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1, REGULATORSETTING1,	\
  			    mc13783_vmmc_val),
  	MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1,	\
  			    mc13783_vmmc_val),
57c78e359   Yong Shen   Change the regist...
203
204
205
206
207
208
  	MC13783_GPO_DEFINE(REG, GPO1, POWERMISC, mc13783_gpo_val),
  	MC13783_GPO_DEFINE(REG, GPO2, POWERMISC, mc13783_gpo_val),
  	MC13783_GPO_DEFINE(REG, GPO3, POWERMISC, mc13783_gpo_val),
  	MC13783_GPO_DEFINE(REG, GPO4, POWERMISC, mc13783_gpo_val),
  	MC13783_GPO_DEFINE(REG, PWGT1SPI, POWERMISC, mc13783_pwgtdrv_val),
  	MC13783_GPO_DEFINE(REG, PWGT2SPI, POWERMISC, mc13783_pwgtdrv_val),
295c08bc6   Sascha Hauer   regulator: Add Fr...
209
  };
167e3d8af   Yong Shen   make mc13783 regu...
210
211
  static int mc13783_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask,
  		u32 val)
f4b97b36b   Alberto Panizzo   regulator: mc1378...
212
  {
167e3d8af   Yong Shen   make mc13783 regu...
213
  	struct mc13xxx *mc13783 = priv->mc13xxx;
f4b97b36b   Alberto Panizzo   regulator: mc1378...
214
215
216
217
  	int ret;
  	u32 valread;
  
  	BUG_ON(val & ~mask);
167e3d8af   Yong Shen   make mc13783 regu...
218
  	ret = mc13xxx_reg_read(mc13783, MC13783_REG_POWERMISC, &valread);
f4b97b36b   Alberto Panizzo   regulator: mc1378...
219
220
221
222
223
224
225
226
227
228
229
230
231
  	if (ret)
  		return ret;
  
  	/* Update the stored state for Power Gates. */
  	priv->powermisc_pwgt_state =
  				(priv->powermisc_pwgt_state & ~mask) | val;
  	priv->powermisc_pwgt_state &= MC13783_REG_POWERMISC_PWGTSPI_M;
  
  	/* Construct the new register value */
  	valread = (valread & ~mask) | val;
  	/* Overwrite the PWGTxEN with the stored version */
  	valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
  						priv->powermisc_pwgt_state;
167e3d8af   Yong Shen   make mc13783 regu...
232
  	return mc13xxx_reg_write(mc13783, MC13783_REG_POWERMISC, valread);
f4b97b36b   Alberto Panizzo   regulator: mc1378...
233
234
235
236
  }
  
  static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev)
  {
167e3d8af   Yong Shen   make mc13783 regu...
237
238
  	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
  	struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
f4b97b36b   Alberto Panizzo   regulator: mc1378...
239
240
  	int id = rdev_get_id(rdev);
  	int ret;
167e3d8af   Yong Shen   make mc13783 regu...
241
  	u32 en_val = mc13xxx_regulators[id].enable_bit;
f4b97b36b   Alberto Panizzo   regulator: mc1378...
242
243
244
245
246
  
  	dev_dbg(rdev_get_dev(rdev), "%s id: %d
  ", __func__, id);
  
  	/* Power Gate enable value is 0 */
57c78e359   Yong Shen   Change the regist...
247
248
  	if (id == MC13783_REG_PWGT1SPI ||
  	    id == MC13783_REG_PWGT2SPI)
f4b97b36b   Alberto Panizzo   regulator: mc1378...
249
  		en_val = 0;
167e3d8af   Yong Shen   make mc13783 regu...
250
251
  	mc13xxx_lock(priv->mc13xxx);
  	ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit,
f4b97b36b   Alberto Panizzo   regulator: mc1378...
252
  					en_val);
167e3d8af   Yong Shen   make mc13783 regu...
253
  	mc13xxx_unlock(priv->mc13xxx);
f4b97b36b   Alberto Panizzo   regulator: mc1378...
254
255
256
257
258
259
  
  	return ret;
  }
  
  static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev)
  {
167e3d8af   Yong Shen   make mc13783 regu...
260
261
  	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
  	struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
f4b97b36b   Alberto Panizzo   regulator: mc1378...
262
263
264
265
266
267
268
269
  	int id = rdev_get_id(rdev);
  	int ret;
  	u32 dis_val = 0;
  
  	dev_dbg(rdev_get_dev(rdev), "%s id: %d
  ", __func__, id);
  
  	/* Power Gate disable value is 1 */
57c78e359   Yong Shen   Change the regist...
270
271
  	if (id == MC13783_REG_PWGT1SPI ||
  	    id == MC13783_REG_PWGT2SPI)
167e3d8af   Yong Shen   make mc13783 regu...
272
  		dis_val = mc13xxx_regulators[id].enable_bit;
f4b97b36b   Alberto Panizzo   regulator: mc1378...
273

167e3d8af   Yong Shen   make mc13783 regu...
274
275
  	mc13xxx_lock(priv->mc13xxx);
  	ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit,
f4b97b36b   Alberto Panizzo   regulator: mc1378...
276
  					dis_val);
167e3d8af   Yong Shen   make mc13783 regu...
277
  	mc13xxx_unlock(priv->mc13xxx);
f4b97b36b   Alberto Panizzo   regulator: mc1378...
278
279
280
281
282
283
  
  	return ret;
  }
  
  static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev)
  {
167e3d8af   Yong Shen   make mc13783 regu...
284
285
  	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
  	struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
f4b97b36b   Alberto Panizzo   regulator: mc1378...
286
287
  	int ret, id = rdev_get_id(rdev);
  	unsigned int val;
167e3d8af   Yong Shen   make mc13783 regu...
288
289
290
  	mc13xxx_lock(priv->mc13xxx);
  	ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val);
  	mc13xxx_unlock(priv->mc13xxx);
f4b97b36b   Alberto Panizzo   regulator: mc1378...
291
292
293
294
295
296
297
298
  
  	if (ret)
  		return ret;
  
  	/* Power Gates state is stored in powermisc_pwgt_state
  	 * where the meaning of bits is negated */
  	val = (val & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
  	      (priv->powermisc_pwgt_state ^ MC13783_REG_POWERMISC_PWGTSPI_M);
167e3d8af   Yong Shen   make mc13783 regu...
299
  	return (val & mc13xxx_regulators[id].enable_bit) != 0;
f4b97b36b   Alberto Panizzo   regulator: mc1378...
300
301
302
303
304
305
  }
  
  static struct regulator_ops mc13783_gpo_regulator_ops = {
  	.enable = mc13783_gpo_regulator_enable,
  	.disable = mc13783_gpo_regulator_disable,
  	.is_enabled = mc13783_gpo_regulator_is_enabled,
167e3d8af   Yong Shen   make mc13783 regu...
306
307
308
  	.list_voltage = mc13xxx_regulator_list_voltage,
  	.set_voltage = mc13xxx_fixed_regulator_set_voltage,
  	.get_voltage = mc13xxx_fixed_regulator_get_voltage,
f4b97b36b   Alberto Panizzo   regulator: mc1378...
309
  };
295c08bc6   Sascha Hauer   regulator: Add Fr...
310
311
  static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
  {
167e3d8af   Yong Shen   make mc13783 regu...
312
313
  	struct mc13xxx_regulator_priv *priv;
  	struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
8f1585aa7   Samuel Ortiz   regulator: Finish...
314
  	struct mc13xxx_regulator_platform_data *pdata =
c8a03c96b   Samuel Ortiz   mfd: Use mfd cell...
315
  		dev_get_platdata(&pdev->dev);
8f1585aa7   Samuel Ortiz   regulator: Finish...
316
  	struct mc13xxx_regulator_init_data *init_data;
295c08bc6   Sascha Hauer   regulator: Add Fr...
317
  	int i, ret;
c719864f1   Wanlong Gao   regulator: change...
318
319
  	dev_dbg(&pdev->dev, "%s id %d
  ", __func__, pdev->id);
295c08bc6   Sascha Hauer   regulator: Add Fr...
320

cbe10a367   Fabio Estevam   regulator: mc1378...
321
  	priv = devm_kzalloc(&pdev->dev, sizeof(*priv) +
a10099bc8   Uwe Kleine-König   regulator/mc13783...
322
  			pdata->num_regulators * sizeof(priv->regulators[0]),
295c08bc6   Sascha Hauer   regulator: Add Fr...
323
324
325
  			GFP_KERNEL);
  	if (!priv)
  		return -ENOMEM;
167e3d8af   Yong Shen   make mc13783 regu...
326
327
  	priv->mc13xxx_regulators = mc13783_regulators;
  	priv->mc13xxx = mc13783;
295c08bc6   Sascha Hauer   regulator: Add Fr...
328

a10099bc8   Uwe Kleine-König   regulator/mc13783...
329
330
  	for (i = 0; i < pdata->num_regulators; i++) {
  		init_data = &pdata->regulators[i];
295c08bc6   Sascha Hauer   regulator: Add Fr...
331
332
  		priv->regulators[i] = regulator_register(
  				&mc13783_regulators[init_data->id].desc,
2c043bcbf   Rajendra Nayak   regulator: pass a...
333
  				&pdev->dev, init_data->init_data, priv, NULL);
295c08bc6   Sascha Hauer   regulator: Add Fr...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
  
  		if (IS_ERR(priv->regulators[i])) {
  			dev_err(&pdev->dev, "failed to register regulator %s
  ",
  				mc13783_regulators[i].desc.name);
  			ret = PTR_ERR(priv->regulators[i]);
  			goto err;
  		}
  	}
  
  	platform_set_drvdata(pdev, priv);
  
  	return 0;
  err:
  	while (--i >= 0)
  		regulator_unregister(priv->regulators[i]);
295c08bc6   Sascha Hauer   regulator: Add Fr...
350
351
352
353
354
  	return ret;
  }
  
  static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
  {
167e3d8af   Yong Shen   make mc13783 regu...
355
  	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
8f1585aa7   Samuel Ortiz   regulator: Finish...
356
  	struct mc13xxx_regulator_platform_data *pdata =
c8a03c96b   Samuel Ortiz   mfd: Use mfd cell...
357
  		dev_get_platdata(&pdev->dev);
295c08bc6   Sascha Hauer   regulator: Add Fr...
358
  	int i;
58d576588   Axel Lin   mc13783-regulator...
359
  	platform_set_drvdata(pdev, NULL);
a10099bc8   Uwe Kleine-König   regulator/mc13783...
360
  	for (i = 0; i < pdata->num_regulators; i++)
295c08bc6   Sascha Hauer   regulator: Add Fr...
361
362
363
364
365
366
367
368
369
370
371
  		regulator_unregister(priv->regulators[i]);
  
  	return 0;
  }
  
  static struct platform_driver mc13783_regulator_driver = {
  	.driver	= {
  		.name	= "mc13783-regulator",
  		.owner	= THIS_MODULE,
  	},
  	.remove		= __devexit_p(mc13783_regulator_remove),
735eb93ae   Alberto Panizzo   regulator: mc1378...
372
  	.probe		= mc13783_regulator_probe,
295c08bc6   Sascha Hauer   regulator: Add Fr...
373
374
375
376
  };
  
  static int __init mc13783_regulator_init(void)
  {
735eb93ae   Alberto Panizzo   regulator: mc1378...
377
  	return platform_driver_register(&mc13783_regulator_driver);
295c08bc6   Sascha Hauer   regulator: Add Fr...
378
379
380
381
382
383
384
385
  }
  subsys_initcall(mc13783_regulator_init);
  
  static void __exit mc13783_regulator_exit(void)
  {
  	platform_driver_unregister(&mc13783_regulator_driver);
  }
  module_exit(mc13783_regulator_exit);
a10099bc8   Uwe Kleine-König   regulator/mc13783...
386
  MODULE_LICENSE("GPL v2");
1dcc434b5   Axel Lin   mc13783-regulator...
387
  MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
295c08bc6   Sascha Hauer   regulator: Add Fr...
388
389
  MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC");
  MODULE_ALIAS("platform:mc13783-regulator");