blob: d7107566c4294ce5bb184fbba42a8f852b7ec12e [file] [log] [blame]
James Ban99cf3af2016-04-15 13:34:22 +09001/*
2 * pv88080-regulator.c - Regulator device driver for PV88080
3 * Copyright (C) 2016 Powerventure Semiconductor Ltd.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/err.h>
17#include <linux/gpio.h>
18#include <linux/i2c.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/slab.h>
22#include <linux/regulator/driver.h>
23#include <linux/regulator/machine.h>
24#include <linux/regmap.h>
25#include <linux/irq.h>
26#include <linux/interrupt.h>
27#include <linux/regulator/of_regulator.h>
28#include <linux/proc_fs.h>
29#include <linux/uaccess.h>
30#include "pv88080-regulator.h"
31
32#define PV88080_MAX_REGULATORS 3
33
34/* PV88080 REGULATOR IDs */
35enum {
36 /* BUCKs */
37 PV88080_ID_BUCK1,
38 PV88080_ID_BUCK2,
39 PV88080_ID_BUCK3,
40};
41
42struct pv88080_regulator {
43 struct regulator_desc desc;
44 /* Current limiting */
45 unsigned int n_current_limits;
46 const int *current_limits;
47 unsigned int limit_mask;
48 unsigned int conf;
49 unsigned int conf2;
50 unsigned int conf5;
51};
52
53struct pv88080 {
54 struct device *dev;
55 struct regmap *regmap;
56 struct regulator_dev *rdev[PV88080_MAX_REGULATORS];
57};
58
59struct pv88080_buck_voltage {
60 int min_uV;
61 int max_uV;
62 int uV_step;
63};
64
65static const struct regmap_config pv88080_regmap_config = {
66 .reg_bits = 8,
67 .val_bits = 8,
68};
69
70/* Current limits array (in uA) for BUCK1, BUCK2, BUCK3.
71 * Entry indexes corresponds to register values.
72 */
73
74static const int pv88080_buck1_limits[] = {
75 3230000, 5130000, 6960000, 8790000
76};
77
78static const int pv88080_buck23_limits[] = {
79 1496000, 2393000, 3291000, 4189000
80};
81
82static const struct pv88080_buck_voltage pv88080_buck_vol[2] = {
83 {
84 .min_uV = 600000,
85 .max_uV = 1393750,
86 .uV_step = 6250,
87 },
88 {
89 .min_uV = 1400000,
90 .max_uV = 2193750,
91 .uV_step = 6250,
92 },
93};
94
95static unsigned int pv88080_buck_get_mode(struct regulator_dev *rdev)
96{
97 struct pv88080_regulator *info = rdev_get_drvdata(rdev);
98 unsigned int data;
99 int ret, mode = 0;
100
101 ret = regmap_read(rdev->regmap, info->conf, &data);
102 if (ret < 0)
103 return ret;
104
105 switch (data & PV88080_BUCK1_MODE_MASK) {
106 case PV88080_BUCK_MODE_SYNC:
107 mode = REGULATOR_MODE_FAST;
108 break;
109 case PV88080_BUCK_MODE_AUTO:
110 mode = REGULATOR_MODE_NORMAL;
111 break;
112 case PV88080_BUCK_MODE_SLEEP:
113 mode = REGULATOR_MODE_STANDBY;
114 break;
115 default:
116 return -EINVAL;
117 }
118
119 return mode;
120}
121
122static int pv88080_buck_set_mode(struct regulator_dev *rdev,
123 unsigned int mode)
124{
125 struct pv88080_regulator *info = rdev_get_drvdata(rdev);
126 int val = 0;
127
128 switch (mode) {
129 case REGULATOR_MODE_FAST:
130 val = PV88080_BUCK_MODE_SYNC;
131 break;
132 case REGULATOR_MODE_NORMAL:
133 val = PV88080_BUCK_MODE_AUTO;
134 break;
135 case REGULATOR_MODE_STANDBY:
136 val = PV88080_BUCK_MODE_SLEEP;
137 break;
138 default:
139 return -EINVAL;
140 }
141
142 return regmap_update_bits(rdev->regmap, info->conf,
143 PV88080_BUCK1_MODE_MASK, val);
144}
145
146static int pv88080_set_current_limit(struct regulator_dev *rdev, int min,
147 int max)
148{
149 struct pv88080_regulator *info = rdev_get_drvdata(rdev);
150 int i;
151
152 /* search for closest to maximum */
153 for (i = info->n_current_limits; i >= 0; i--) {
154 if (min <= info->current_limits[i]
155 && max >= info->current_limits[i]) {
156 return regmap_update_bits(rdev->regmap,
157 info->conf,
158 info->limit_mask,
159 i << PV88080_BUCK1_ILIM_SHIFT);
160 }
161 }
162
163 return -EINVAL;
164}
165
166static int pv88080_get_current_limit(struct regulator_dev *rdev)
167{
168 struct pv88080_regulator *info = rdev_get_drvdata(rdev);
169 unsigned int data;
170 int ret;
171
172 ret = regmap_read(rdev->regmap, info->conf, &data);
173 if (ret < 0)
174 return ret;
175
176 data = (data & info->limit_mask) >> PV88080_BUCK1_ILIM_SHIFT;
177 return info->current_limits[data];
178}
179
180static struct regulator_ops pv88080_buck_ops = {
181 .get_mode = pv88080_buck_get_mode,
182 .set_mode = pv88080_buck_set_mode,
183 .enable = regulator_enable_regmap,
184 .disable = regulator_disable_regmap,
185 .is_enabled = regulator_is_enabled_regmap,
186 .set_voltage_sel = regulator_set_voltage_sel_regmap,
187 .get_voltage_sel = regulator_get_voltage_sel_regmap,
188 .list_voltage = regulator_list_voltage_linear,
189 .set_current_limit = pv88080_set_current_limit,
190 .get_current_limit = pv88080_get_current_limit,
191};
192
193#define PV88080_BUCK(chip, regl_name, min, step, max, limits_array) \
194{\
195 .desc = {\
196 .id = chip##_ID_##regl_name,\
197 .name = __stringify(chip##_##regl_name),\
198 .of_match = of_match_ptr(#regl_name),\
199 .regulators_node = of_match_ptr("regulators"),\
200 .type = REGULATOR_VOLTAGE,\
201 .owner = THIS_MODULE,\
202 .ops = &pv88080_buck_ops,\
203 .min_uV = min, \
204 .uV_step = step, \
205 .n_voltages = ((max) - (min))/(step) + 1, \
206 .enable_reg = PV88080_REG_##regl_name##_CONF0, \
207 .enable_mask = PV88080_##regl_name##_EN, \
208 .vsel_reg = PV88080_REG_##regl_name##_CONF0, \
209 .vsel_mask = PV88080_V##regl_name##_MASK, \
210 },\
211 .current_limits = limits_array, \
212 .n_current_limits = ARRAY_SIZE(limits_array), \
213 .limit_mask = PV88080_##regl_name##_ILIM_MASK, \
214 .conf = PV88080_REG_##regl_name##_CONF1, \
215 .conf2 = PV88080_REG_##regl_name##_CONF2, \
216 .conf5 = PV88080_REG_##regl_name##_CONF5, \
217}
218
219static struct pv88080_regulator pv88080_regulator_info[] = {
220 PV88080_BUCK(PV88080, BUCK1, 600000, 6250, 1393750,
221 pv88080_buck1_limits),
222 PV88080_BUCK(PV88080, BUCK2, 600000, 6250, 1393750,
223 pv88080_buck23_limits),
224 PV88080_BUCK(PV88080, BUCK3, 600000, 6250, 1393750,
225 pv88080_buck23_limits),
226};
227
228static irqreturn_t pv88080_irq_handler(int irq, void *data)
229{
230 struct pv88080 *chip = data;
231 int i, reg_val, err, ret = IRQ_NONE;
232
233 err = regmap_read(chip->regmap, PV88080_REG_EVENT_A, &reg_val);
234 if (err < 0)
235 goto error_i2c;
236
237 if (reg_val & PV88080_E_VDD_FLT) {
238 for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
239 if (chip->rdev[i] != NULL) {
240 regulator_notifier_call_chain(chip->rdev[i],
241 REGULATOR_EVENT_UNDER_VOLTAGE,
242 NULL);
243 }
244 }
245
246 err = regmap_write(chip->regmap, PV88080_REG_EVENT_A,
247 PV88080_E_VDD_FLT);
248 if (err < 0)
249 goto error_i2c;
250
251 ret = IRQ_HANDLED;
252 }
253
254 if (reg_val & PV88080_E_OVER_TEMP) {
255 for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
256 if (chip->rdev[i] != NULL) {
257 regulator_notifier_call_chain(chip->rdev[i],
258 REGULATOR_EVENT_OVER_TEMP,
259 NULL);
260 }
261 }
262
263 err = regmap_write(chip->regmap, PV88080_REG_EVENT_A,
264 PV88080_E_OVER_TEMP);
265 if (err < 0)
266 goto error_i2c;
267
268 ret = IRQ_HANDLED;
269 }
270
271 return ret;
272
273error_i2c:
274 dev_err(chip->dev, "I2C error : %d\n", err);
275 return IRQ_NONE;
276}
277
278/*
279 * I2C driver interface functions
280 */
281static int pv88080_i2c_probe(struct i2c_client *i2c,
282 const struct i2c_device_id *id)
283{
284 struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
285 struct pv88080 *chip;
286 struct regulator_config config = { };
287 int i, error, ret;
288 unsigned int conf2, conf5;
289
290 chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88080), GFP_KERNEL);
291 if (!chip)
292 return -ENOMEM;
293
294 chip->dev = &i2c->dev;
295 chip->regmap = devm_regmap_init_i2c(i2c, &pv88080_regmap_config);
296 if (IS_ERR(chip->regmap)) {
297 error = PTR_ERR(chip->regmap);
298 dev_err(chip->dev, "Failed to allocate register map: %d\n",
299 error);
300 return error;
301 }
302
303 i2c_set_clientdata(i2c, chip);
304
305 if (i2c->irq != 0) {
306 ret = regmap_write(chip->regmap, PV88080_REG_MASK_A, 0xFF);
307 if (ret < 0) {
308 dev_err(chip->dev,
309 "Failed to mask A reg: %d\n", ret);
310 return ret;
311 }
312 ret = regmap_write(chip->regmap, PV88080_REG_MASK_B, 0xFF);
313 if (ret < 0) {
314 dev_err(chip->dev,
315 "Failed to mask B reg: %d\n", ret);
316 return ret;
317 }
318 ret = regmap_write(chip->regmap, PV88080_REG_MASK_C, 0xFF);
319 if (ret < 0) {
320 dev_err(chip->dev,
321 "Failed to mask C reg: %d\n", ret);
322 return ret;
323 }
324
325 ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
326 pv88080_irq_handler,
327 IRQF_TRIGGER_LOW|IRQF_ONESHOT,
328 "pv88080", chip);
329 if (ret != 0) {
330 dev_err(chip->dev, "Failed to request IRQ: %d\n",
331 i2c->irq);
332 return ret;
333 }
334
335 ret = regmap_update_bits(chip->regmap, PV88080_REG_MASK_A,
336 PV88080_M_VDD_FLT | PV88080_M_OVER_TEMP, 0);
337 if (ret < 0) {
338 dev_err(chip->dev,
339 "Failed to update mask reg: %d\n", ret);
340 return ret;
341 }
342
343 } else {
344 dev_warn(chip->dev, "No IRQ configured\n");
345 }
346
347 config.dev = chip->dev;
348 config.regmap = chip->regmap;
349
350 for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
351 if (init_data)
352 config.init_data = &init_data[i];
353
354 ret = regmap_read(chip->regmap,
355 pv88080_regulator_info[i].conf2, &conf2);
356 if (ret < 0)
357 return ret;
358
359 conf2 = ((conf2 >> PV88080_BUCK_VDAC_RANGE_SHIFT) &
360 PV88080_BUCK_VDAC_RANGE_MASK);
361
362 ret = regmap_read(chip->regmap,
363 pv88080_regulator_info[i].conf5, &conf5);
364 if (ret < 0)
365 return ret;
366
367 conf5 = ((conf5 >> PV88080_BUCK_VRANGE_GAIN_SHIFT) &
368 PV88080_BUCK_VRANGE_GAIN_MASK);
369
370 pv88080_regulator_info[i].desc.min_uV =
371 pv88080_buck_vol[conf2].min_uV * (conf5+1);
372 pv88080_regulator_info[i].desc.uV_step =
373 pv88080_buck_vol[conf2].uV_step * (conf5+1);
374 pv88080_regulator_info[i].desc.n_voltages =
375 ((pv88080_buck_vol[conf2].max_uV * (conf5+1))
376 - (pv88080_regulator_info[i].desc.min_uV))
377 /(pv88080_regulator_info[i].desc.uV_step) + 1;
378
379 config.driver_data = (void *)&pv88080_regulator_info[i];
380 chip->rdev[i] = devm_regulator_register(chip->dev,
381 &pv88080_regulator_info[i].desc, &config);
382 if (IS_ERR(chip->rdev[i])) {
383 dev_err(chip->dev,
384 "Failed to register PV88080 regulator\n");
385 return PTR_ERR(chip->rdev[i]);
386 }
387 }
388
389 return 0;
390}
391
392static const struct i2c_device_id pv88080_i2c_id[] = {
393 {"pv88080", 0},
394 {},
395};
396MODULE_DEVICE_TABLE(i2c, pv88080_i2c_id);
397
398#ifdef CONFIG_OF
399static const struct of_device_id pv88080_dt_ids[] = {
400 { .compatible = "pvs,pv88080", .data = &pv88080_i2c_id[0] },
401 {},
402};
403MODULE_DEVICE_TABLE(of, pv88080_dt_ids);
404#endif
405
406static struct i2c_driver pv88080_regulator_driver = {
407 .driver = {
408 .name = "pv88080",
409 .of_match_table = of_match_ptr(pv88080_dt_ids),
410 },
411 .probe = pv88080_i2c_probe,
412 .id_table = pv88080_i2c_id,
413};
414
415module_i2c_driver(pv88080_regulator_driver);
416
417MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
418MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88080");
419MODULE_LICENSE("GPL");