35
35
36
36
#define MP8859_GO_BIT 0x01
37
37
38
+ #define MP8859_IOUT_LIM_MASK 0x7f
39
+
40
+ #define MP8859_ENABLE_MASK 0x80
41
+ #define MP8859_DISCHG_EN_MASK 0x10
42
+ #define MP8859_MODE_MASK 0x08
43
+
44
+ #define MP8859_PG_MASK 0x80
45
+ #define MP8859_OTP_MASK 0x40
46
+ #define MP8859_OTW_MASK 0x20
47
+ #define MP8859_CC_CV_MASK 0x10
38
48
39
49
static int mp8859_set_voltage_sel (struct regulator_dev * rdev , unsigned int sel )
40
50
{
@@ -73,21 +83,221 @@ static int mp8859_get_voltage_sel(struct regulator_dev *rdev)
73
83
return val ;
74
84
}
75
85
86
+ static int mp8859_set_voltage_time_sel (struct regulator_dev * rdev ,
87
+ unsigned int from , unsigned int to )
88
+ {
89
+ int change ;
90
+
91
+ /* The voltage ramps at 1mV/uS, selectors are 10mV */
92
+ if (from > to )
93
+ change = from - to ;
94
+ else
95
+ change = to - from ;
96
+
97
+ return change * 10 * 1000 ;
98
+ }
99
+
100
+ static unsigned int mp8859_get_mode (struct regulator_dev * rdev )
101
+ {
102
+ unsigned int val ;
103
+ int ret ;
104
+
105
+ ret = regmap_read (rdev -> regmap , MP8859_CTL1_REG , & val );
106
+ if (ret != 0 ) {
107
+ dev_err (& rdev -> dev , "Failed to read mode: %d\n" , ret );
108
+ return 0 ;
109
+ }
110
+
111
+ if (val & MP8859_MODE_MASK )
112
+ return REGULATOR_MODE_FAST ;
113
+ else
114
+ return REGULATOR_MODE_NORMAL ;
115
+ }
116
+
117
+ static int mp8859_set_mode (struct regulator_dev * rdev , unsigned int mode )
118
+ {
119
+ unsigned int val ;
120
+
121
+ switch (mode ) {
122
+ case REGULATOR_MODE_FAST :
123
+ val = MP8859_MODE_MASK ;
124
+ break ;
125
+ case REGULATOR_MODE_NORMAL :
126
+ val = 0 ;
127
+ break ;
128
+ default :
129
+ return - EINVAL ;
130
+ }
131
+
132
+ return regmap_update_bits (rdev -> regmap , MP8859_CTL1_REG ,
133
+ MP8859_MODE_MASK , val );
134
+ }
135
+
136
+ static int mp8859_set_current_limit (struct regulator_dev * rdev ,
137
+ int min_uA , int max_uA )
138
+ {
139
+ unsigned int cur_val , new_val ;
140
+ int ret , i ;
141
+
142
+ /* Steps of 50mA */
143
+ new_val = max_uA / 50000 ;
144
+ if (new_val > MP8859_IOUT_LIM_MASK )
145
+ return - EINVAL ;
146
+ if (new_val == 0 )
147
+ return - EINVAL ;
148
+
149
+ /*
150
+ * If the regulator is limiting then ramp gradually as per
151
+ * datasheet, otherwise just set the value directly.
152
+ */
153
+ ret = regmap_read (rdev -> regmap , MP8859_STATUS_REG , & cur_val );
154
+ if (ret != 0 )
155
+ return ret ;
156
+ if (!(cur_val & MP8859_CC_CV_MASK )) {
157
+ return regmap_update_bits (rdev -> regmap , MP8859_IOUT_LIM_REG ,
158
+ MP8859_IOUT_LIM_MASK , new_val );
159
+ }
160
+
161
+ ret = regmap_read (rdev -> regmap , MP8859_IOUT_LIM_REG , & cur_val );
162
+ if (ret != 0 )
163
+ return ret ;
164
+
165
+ if (cur_val >= new_val ) {
166
+ for (i = cur_val ; i >= new_val ; i -- ) {
167
+ ret = regmap_update_bits (rdev -> regmap ,
168
+ MP8859_IOUT_LIM_REG ,
169
+ MP8859_IOUT_LIM_MASK ,
170
+ cur_val - i );
171
+ if (ret != 0 )
172
+ return ret ;
173
+ }
174
+ } else {
175
+ for (i = cur_val ; i <= new_val ; i ++ ) {
176
+ ret = regmap_update_bits (rdev -> regmap ,
177
+ MP8859_IOUT_LIM_REG ,
178
+ MP8859_IOUT_LIM_MASK ,
179
+ cur_val + i );
180
+ if (ret != 0 )
181
+ return ret ;
182
+ }
183
+ }
184
+
185
+ return 0 ;
186
+ }
187
+
188
+ static int mp8859_get_status (struct regulator_dev * rdev )
189
+ {
190
+ unsigned int val ;
191
+ int ret ;
192
+
193
+ /* Output status is only meaingful when enabled */
194
+ ret = regmap_read (rdev -> regmap , MP8859_CTL1_REG , & val );
195
+ if (ret != 0 )
196
+ return ret ;
197
+ if (!(val & MP8859_ENABLE_MASK ))
198
+ return REGULATOR_STATUS_UNDEFINED ;
199
+
200
+ ret = regmap_read (rdev -> regmap , MP8859_STATUS_REG , & val );
201
+ if (ret != 0 )
202
+ return ret ;
203
+
204
+ if (val & MP8859_PG_MASK )
205
+ return REGULATOR_STATUS_ON ;
206
+ else
207
+ return REGULATOR_STATUS_ERROR ;
208
+ }
209
+
210
+ static int mp8859_get_error_flags (struct regulator_dev * rdev ,
211
+ unsigned int * flags )
212
+ {
213
+ unsigned int status , enabled ;
214
+ int ret ;
215
+
216
+ * flags = 0 ;
217
+
218
+ /* Output status is only meaingful when enabled */
219
+ ret = regmap_read (rdev -> regmap , MP8859_CTL1_REG , & enabled );
220
+ if (ret != 0 )
221
+ return ret ;
222
+ enabled &= MP8859_ENABLE_MASK ;
223
+
224
+ ret = regmap_read (rdev -> regmap , MP8859_STATUS_REG , & status );
225
+ if (ret != 0 )
226
+ return ret ;
227
+
228
+ if (enabled && !(status & MP8859_PG_MASK ))
229
+ status |= REGULATOR_ERROR_FAIL ;
230
+ if (status & MP8859_OTP_MASK )
231
+ status |= REGULATOR_ERROR_OVER_TEMP ;
232
+ if (status & MP8859_OTW_MASK )
233
+ status |= REGULATOR_ERROR_OVER_TEMP_WARN ;
234
+ if (status & MP8859_CC_CV_MASK )
235
+ status |= REGULATOR_ERROR_OVER_CURRENT ;
236
+
237
+ return 0 ;
238
+ }
239
+
76
240
static const struct linear_range mp8859_dcdc_ranges [] = {
77
241
REGULATOR_LINEAR_RANGE (0 , VOL_MIN_IDX , VOL_MAX_IDX , 10000 ),
78
242
};
79
243
244
+ static bool mp8859_readable (struct device * dev , unsigned int reg )
245
+ {
246
+ switch (reg ) {
247
+ case MP8859_VOUT_L_REG :
248
+ case MP8859_VOUT_H_REG :
249
+ case MP8859_VOUT_GO_REG :
250
+ case MP8859_IOUT_LIM_REG :
251
+ case MP8859_CTL1_REG :
252
+ case MP8859_CTL2_REG :
253
+ case MP8859_STATUS_REG :
254
+ case MP8859_INTERRUPT_REG :
255
+ case MP8859_MASK_REG :
256
+ case MP8859_ID1_REG :
257
+ case MP8859_MFR_ID_REG :
258
+ case MP8859_DEV_ID_REG :
259
+ case MP8859_IC_REV_REG :
260
+ return true;
261
+ default :
262
+ return false;
263
+ }
264
+ }
265
+
266
+ static bool mp8859_volatile (struct device * dev , unsigned int reg )
267
+ {
268
+ switch (reg ) {
269
+ case MP8859_VOUT_GO_REG :
270
+ case MP8859_STATUS_REG :
271
+ case MP8859_INTERRUPT_REG :
272
+ return true;
273
+ default :
274
+ return false;
275
+ }
276
+ }
277
+
80
278
static const struct regmap_config mp8859_regmap = {
81
279
.reg_bits = 8 ,
82
280
.val_bits = 8 ,
83
281
.max_register = MP8859_MAX_REG ,
84
- .cache_type = REGCACHE_RBTREE ,
282
+ .cache_type = REGCACHE_MAPLE ,
283
+ .readable_reg = mp8859_readable ,
284
+ .volatile_reg = mp8859_volatile ,
85
285
};
86
286
87
287
static const struct regulator_ops mp8859_ops = {
88
288
.set_voltage_sel = mp8859_set_voltage_sel ,
89
289
.get_voltage_sel = mp8859_get_voltage_sel ,
90
290
.list_voltage = regulator_list_voltage_linear_range ,
291
+ .set_voltage_time_sel = mp8859_set_voltage_time_sel ,
292
+ .enable = regulator_enable_regmap ,
293
+ .disable = regulator_disable_regmap ,
294
+ .is_enabled = regulator_is_enabled_regmap ,
295
+ .set_mode = mp8859_set_mode ,
296
+ .get_mode = mp8859_get_mode ,
297
+ .set_active_discharge = regulator_set_active_discharge_regmap ,
298
+ .set_current_limit = mp8859_set_current_limit ,
299
+ .get_status = mp8859_get_status ,
300
+ .get_error_flags = mp8859_get_error_flags ,
91
301
};
92
302
93
303
static const struct regulator_desc mp8859_regulators [] = {
@@ -100,6 +310,12 @@ static const struct regulator_desc mp8859_regulators[] = {
100
310
.n_voltages = VOL_MAX_IDX + 1 ,
101
311
.linear_ranges = mp8859_dcdc_ranges ,
102
312
.n_linear_ranges = 1 ,
313
+ .enable_reg = MP8859_CTL1_REG ,
314
+ .enable_mask = MP8859_ENABLE_MASK ,
315
+ .enable_val = MP8859_ENABLE_MASK ,
316
+ .active_discharge_reg = MP8859_CTL1_REG ,
317
+ .active_discharge_on = MP8859_DISCHG_EN_MASK ,
318
+ .active_discharge_mask = MP8859_DISCHG_EN_MASK ,
103
319
.ops = & mp8859_ops ,
104
320
.owner = THIS_MODULE ,
105
321
},
@@ -111,12 +327,46 @@ static int mp8859_i2c_probe(struct i2c_client *i2c)
111
327
struct regulator_config config = {.dev = & i2c -> dev };
112
328
struct regmap * regmap = devm_regmap_init_i2c (i2c , & mp8859_regmap );
113
329
struct regulator_dev * rdev ;
330
+ unsigned int val , rev ;
114
331
115
332
if (IS_ERR (regmap )) {
116
333
ret = PTR_ERR (regmap );
117
334
dev_err (& i2c -> dev , "regmap init failed: %d\n" , ret );
118
335
return ret ;
119
336
}
337
+
338
+ ret = regmap_read (regmap , MP8859_MFR_ID_REG , & val );
339
+ if (ret != 0 ) {
340
+ dev_err (& i2c -> dev , "Failed to read manufacturer ID: %d\n" , ret );
341
+ return ret ;
342
+ }
343
+ if (val != 0x9 ) {
344
+ dev_err (& i2c -> dev , "Manufacturer ID %x != 9\n" , val );
345
+ return - EINVAL ;
346
+ }
347
+
348
+ ret = regmap_read (regmap , MP8859_DEV_ID_REG , & val );
349
+ if (ret != 0 ) {
350
+ dev_err (& i2c -> dev , "Failed to read device ID: %d\n" , ret );
351
+ return ret ;
352
+ }
353
+ if (val != 0x58 ) {
354
+ dev_err (& i2c -> dev , "Manufacturer ID %x != 0x58\n" , val );
355
+ return - EINVAL ;
356
+ }
357
+
358
+ ret = regmap_read (regmap , MP8859_IC_REV_REG , & rev );
359
+ if (ret != 0 ) {
360
+ dev_err (& i2c -> dev , "Failed to read device revision: %d\n" , ret );
361
+ return ret ;
362
+ }
363
+ ret = regmap_read (regmap , MP8859_ID1_REG , & val );
364
+ if (ret != 0 ) {
365
+ dev_err (& i2c -> dev , "Failed to read device ID1: %d\n" , ret );
366
+ return ret ;
367
+ }
368
+ dev_info (& i2c -> dev , "MP8859-%04d revision %d\n" , val , rev );
369
+
120
370
rdev = devm_regulator_register (& i2c -> dev , & mp8859_regulators [0 ],
121
371
& config );
122
372
0 commit comments