• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Regulator driver for xz3216 DCDC chip for rk32xx
3  *
4  * Copyright (C) 2010, 2011 ROCKCHIP, Inc.
5 
6  * Based on xz3216.c that is work by zhangqing<zhangqing@rock-chips.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  */
13 
14 #include <linux/bug.h>
15 #include <linux/err.h>
16 #include <linux/i2c.h>
17 #include <linux/kernel.h>
18 #include <linux/regulator/driver.h>
19 #include <linux/delay.h>
20 #include <linux/slab.h>
21 #include <linux/mutex.h>
22 #include <linux/mfd/core.h>
23 
24 #include <linux/interrupt.h>
25 #include <linux/module.h>
26 #include <linux/of_irq.h>
27 #include <linux/of_gpio.h>
28 #include <linux/of.h>
29 #include <linux/of_device.h>
30 #include <linux/regulator/of_regulator.h>
31 #include <linux/regulator/driver.h>
32 #include <linux/regulator/machine.h>
33 #include <linux/regmap.h>
34 
35 #define DBG(x...) pr_info(x)
36 #define DBG_ERR(x...) pr_err(x)
37 
38 #define XZ3216_NUM_REGULATORS 1
39 
40 #define XZ3216_BUCK1_SET_VOL_BASE 0x00
41 #define XZ3216_BUCK1_SLP_VOL_BASE 0x01
42 #define XZ3216_CONTR_REG1 0x02
43 #define XZ3216_ID1_REG 0x03
44 #define BUCK_VOL_MASK 0x3f
45 #define VOL_MIN_IDX 0x00
46 #define VOL_MAX_IDX 0x3
47 
48 /* VSEL bit definitions */
49 #define VSEL_BUCK_EN BIT(7)
50 #define VSEL_MODE BIT(6)
51 #define VSEL_NSEL_MASK 0x3F
52 
53 /* Control bit definitions */
54 #define CTL_OUTPUT_DISCHG BIT(7)
55 #define CTL_SLEW_MASK (0x7 << 4)
56 #define CTL_SLEW_SHIFT 4
57 #define CTL_RESET BIT(2)
58 
59 struct xz3216 {
60     struct device *dev;
61     struct i2c_client *i2c;
62     int num_regulators;
63     struct regulator_dev *rdev;
64     struct regulator_init_data *regulator;
65     struct regmap *regmap;
66     /* Voltage setting register */
67     unsigned int vol_reg;
68     unsigned int sleep_reg;
69     /* Voltage range and step(linear) */
70     unsigned int vsel_min;
71     unsigned int vsel_step;
72     unsigned int sleep_vol_cache;
73 };
74 
75 struct xz3216_regulator {
76     struct device *dev;
77     struct regulator_desc *desc;
78     struct regulator_dev *rdev;
79 };
80 
81 struct xz3216_board {
82     struct regulator_init_data *xz3216_init_data;
83     struct device_node *of_node;
84 };
85 
xz3216_dcdc_get_mode(struct regulator_dev * dev)86 static unsigned int xz3216_dcdc_get_mode(struct regulator_dev *dev)
87 {
88     struct xz3216 *xz3216 = rdev_get_drvdata(dev);
89     unsigned int val;
90     int ret = 0;
91 
92     ret = regmap_read(xz3216->regmap, xz3216->vol_reg, &val);
93     if (ret < 0) {
94         return ret;
95     }
96     if (val & VSEL_MODE) {
97         return REGULATOR_MODE_FAST;
98     } else {
99         return REGULATOR_MODE_NORMAL;
100     }
101 }
102 
xz3216_dcdc_set_mode(struct regulator_dev * dev,unsigned int mode)103 static int xz3216_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
104 {
105     struct xz3216 *xz3216 = rdev_get_drvdata(dev);
106 
107     switch (mode) {
108         case REGULATOR_MODE_FAST:
109             return regmap_update_bits(xz3216->regmap, xz3216->vol_reg, VSEL_MODE, VSEL_MODE);
110         case REGULATOR_MODE_NORMAL:
111             return regmap_update_bits(xz3216->regmap, xz3216->vol_reg, VSEL_MODE, 0);
112         default:
113             DBG("error:dcdc_xz3216 only auto and pwm mode\n");
114             return -EINVAL;
115     }
116 }
117 
xz3216_dcdc_suspend_enable(struct regulator_dev * dev)118 static int xz3216_dcdc_suspend_enable(struct regulator_dev *dev)
119 {
120     struct xz3216 *xz3216 = rdev_get_drvdata(dev);
121     return regmap_update_bits(xz3216->regmap, XZ3216_BUCK1_SLP_VOL_BASE, VSEL_BUCK_EN, VSEL_BUCK_EN);
122 }
123 
xz3216_dcdc_suspend_disable(struct regulator_dev * dev)124 static int xz3216_dcdc_suspend_disable(struct regulator_dev *dev)
125 {
126     struct xz3216 *xz3216 = rdev_get_drvdata(dev);
127     return regmap_update_bits(xz3216->regmap, XZ3216_BUCK1_SLP_VOL_BASE, VSEL_BUCK_EN, 0);
128 }
129 
xz3216_dcdc_set_sleep_voltage(struct regulator_dev * dev,int uV)130 static int xz3216_dcdc_set_sleep_voltage(struct regulator_dev *dev, int uV)
131 {
132     struct xz3216 *xz3216 = rdev_get_drvdata(dev);
133     int ret;
134 
135     if (xz3216->sleep_vol_cache == uV) {
136         return 0;
137     }
138     ret = regulator_map_voltage_linear(dev, uV, uV);
139     if (ret < 0) {
140         return ret;
141     }
142     ret = regmap_update_bits(xz3216->regmap, XZ3216_BUCK1_SLP_VOL_BASE, VSEL_NSEL_MASK, ret);
143     if (ret < 0) {
144         return ret;
145     }
146     xz3216->sleep_vol_cache = uV;
147     return 0;
148 }
149 
xz3216_dcdc_set_suspend_mode(struct regulator_dev * dev,unsigned int mode)150 static int xz3216_dcdc_set_suspend_mode(struct regulator_dev *dev, unsigned int mode)
151 {
152     struct xz3216 *xz3216 = rdev_get_drvdata(dev);
153 
154     switch (mode) {
155         case REGULATOR_MODE_FAST:
156             return regmap_update_bits(xz3216->regmap, xz3216->vol_reg, VSEL_MODE, VSEL_MODE);
157         case REGULATOR_MODE_NORMAL:
158             return regmap_update_bits(xz3216->regmap, xz3216->vol_reg, VSEL_MODE, 0);
159         default:
160             DBG_ERR("error:dcdc_xz3216 only auto and pwm mode\n");
161             return -EINVAL;
162     }
163 }
164 
165 static const int slew_rates[] = {
166     64000, 32000, 16000, 8000, 4000, 2000, 1000, 500,
167 };
168 
xz3216_set_ramp(struct regulator_dev * rdev,int ramp)169 static int xz3216_set_ramp(struct regulator_dev *rdev, int ramp)
170 {
171     struct xz3216 *xz3216 = rdev_get_drvdata(rdev);
172     int regval = -1, i;
173 
174     for (i = 0; i < ARRAY_SIZE(slew_rates); i++) {
175         if (ramp <= slew_rates[i]) {
176             regval = i;
177         } else {
178             break;
179         }
180     }
181     if (regval < 0) {
182         dev_err(xz3216->dev, "unsupported ramp value %d\n", ramp);
183         return -EINVAL;
184     }
185 
186     return regmap_update_bits(xz3216->regmap, XZ3216_CONTR_REG1, CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT);
187 }
188 
189 static struct regulator_ops xz3216_dcdc_ops = {
190     .set_voltage_sel = regulator_set_voltage_sel_regmap,
191     .get_voltage_sel = regulator_get_voltage_sel_regmap,
192     .list_voltage = regulator_list_voltage_linear,
193     .map_voltage = regulator_map_voltage_linear,
194     .is_enabled = regulator_is_enabled_regmap,
195     .enable = regulator_enable_regmap,
196     .disable = regulator_disable_regmap,
197     .get_mode = xz3216_dcdc_get_mode,
198     .set_mode = xz3216_dcdc_set_mode,
199     .set_suspend_voltage = xz3216_dcdc_set_sleep_voltage,
200     .set_suspend_enable = xz3216_dcdc_suspend_enable,
201     .set_suspend_disable = xz3216_dcdc_suspend_disable,
202     .set_suspend_mode = xz3216_dcdc_set_suspend_mode,
203     .set_ramp_delay = xz3216_set_ramp,
204     .set_voltage_time_sel = regulator_set_voltage_time_sel,
205 };
206 
207 static struct regulator_desc regulators[] = {
208     {
209         .name = "XZ_DCDC1",
210         .supply_name = "vin",
211         .id = 0,
212         .ops = &xz3216_dcdc_ops,
213         .n_voltages = 64,
214         .type = REGULATOR_VOLTAGE,
215         .enable_time = 400,
216         .enable_reg = XZ3216_BUCK1_SET_VOL_BASE,
217         .enable_mask = VSEL_BUCK_EN,
218         .min_uV = 600000,
219         .uV_step = 12500,
220         .vsel_reg = XZ3216_BUCK1_SET_VOL_BASE,
221         .vsel_mask = VSEL_NSEL_MASK,
222         .owner = THIS_MODULE,
223     },
224 };
225 
226 static const struct regmap_config xz3216_regmap_config = {
227     .reg_bits = 8,
228     .val_bits = 8,
229 };
230 
231 #ifdef CONFIG_OF
232 static struct of_device_id xz3216_of_match[] = {
233     {.compatible = "xz3216"},
234     {},
235 };
236 MODULE_DEVICE_TABLE(of, xz3216_of_match);
237 #endif
238 
239 #ifdef CONFIG_OF
240 static struct of_regulator_match xz3216_reg_matches[] = {
241     {.name = "xz_dcdc1", .driver_data = (void *)0},
242 };
243 
xz3216_parse_dt(struct xz3216 * xz3216)244 static struct xz3216_board *xz3216_parse_dt(struct xz3216 *xz3216)
245 {
246     struct xz3216_board *pdata;
247     struct device_node *regs;
248     struct device_node *xz3216_np;
249     int count;
250 
251     xz3216_np = of_node_get(xz3216->dev->of_node);
252     if (!xz3216_np) {
253         DBG_ERR("could not find pmic sub-node\n");
254         return NULL;
255     }
256     regs = of_find_node_by_name(xz3216_np, "regulators");
257     if (!regs) {
258         return NULL;
259     }
260     count = of_regulator_match(xz3216->dev, regs, xz3216_reg_matches, XZ3216_NUM_REGULATORS);
261     of_node_put(regs);
262     pdata = devm_kzalloc(xz3216->dev, sizeof(*pdata), GFP_KERNEL);
263     if (!pdata) {
264         return NULL;
265     }
266     pdata->xz3216_init_data = xz3216_reg_matches[0].init_data;
267     pdata->of_node = xz3216_reg_matches[0].of_node;
268     return pdata;
269 }
270 
271 #else
xz3216_parse_dt(struct i2c_client * i2c)272 static struct xz3216_board *xz3216_parse_dt(struct i2c_client *i2c)
273 {
274     return NULL;
275 }
276 #endif
277 
xz3216_i2c_probe(struct i2c_client * i2c,const struct i2c_device_id * id)278 static int xz3216_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
279 {
280     struct xz3216 *xz3216;
281     struct xz3216_board *pdev;
282     const struct of_device_id *match;
283     struct regulator_config config = {};
284     int ret;
285     DBG("%s, line=%d\n", __func__, __LINE__);
286     xz3216 = devm_kzalloc(&i2c->dev, sizeof(struct xz3216), GFP_KERNEL);
287     if (!xz3216) {
288         ret = -ENOMEM;
289         goto err;
290     }
291 
292     if (i2c->dev.of_node) {
293         match = of_match_device(xz3216_of_match, &i2c->dev);
294         if (!match) {
295             DBG_ERR("Failed to find matching dt id\n");
296             return -EINVAL;
297         }
298     }
299 
300     xz3216->regmap = devm_regmap_init_i2c(i2c, &xz3216_regmap_config);
301     if (IS_ERR(xz3216->regmap)) {
302         dev_err(&i2c->dev, "Failed to allocate regmap!\n");
303         return PTR_ERR(xz3216->regmap);
304     }
305 
306     xz3216->i2c = i2c;
307     xz3216->dev = &i2c->dev;
308     i2c_set_clientdata(i2c, xz3216);
309     pdev = dev_get_platdata(&i2c->dev);
310     if (!pdev) {
311         pdev = xz3216_parse_dt(xz3216);
312     }
313     if (pdev) {
314         xz3216->num_regulators = XZ3216_NUM_REGULATORS;
315         xz3216->rdev = kcalloc(XZ3216_NUM_REGULATORS, sizeof(struct regulator_dev), GFP_KERNEL);
316         if (!xz3216->rdev) {
317             return -ENOMEM;
318         }
319         /* Instantiate the regulators */
320         xz3216->regulator = pdev->xz3216_init_data;
321         if (xz3216->dev->of_node) {
322             config.of_node = pdev->of_node;
323         }
324         config.dev = xz3216->dev;
325         config.driver_data = xz3216;
326         config.init_data = xz3216->regulator;
327         xz3216->rdev = devm_regulator_register(xz3216->dev, &regulators[0], &config);
328         ret = PTR_ERR_OR_ZERO(xz3216->rdev);
329         if (ret < 0) {
330             dev_err(&i2c->dev, "Failed to register regulator!\n");
331         }
332         return ret;
333     }
334     return 0;
335 err:
336     return ret;
337 }
338 
xz3216_i2c_remove(struct i2c_client * i2c)339 static int xz3216_i2c_remove(struct i2c_client *i2c)
340 {
341     struct xz3216 *xz3216 = i2c_get_clientdata(i2c);
342 
343     if (xz3216->rdev) {
344         regulator_unregister(xz3216->rdev);
345     }
346     i2c_set_clientdata(i2c, NULL);
347     return 0;
348 }
349 
350 static const struct i2c_device_id xz3216_i2c_id[] = {{"xz3216", 0}, {}};
351 
352 MODULE_DEVICE_TABLE(i2c, xz3216_i2c_id);
353 
354 static struct i2c_driver xz3216_i2c_driver = {
355     .driver =
356         {
357             .name = "xz3216",
358             .owner = THIS_MODULE,
359             .of_match_table = of_match_ptr(xz3216_of_match),
360         },
361     .probe = xz3216_i2c_probe,
362     .remove = xz3216_i2c_remove,
363     .id_table = xz3216_i2c_id,
364 };
365 
xz3216_module_init(void)366 static int __init xz3216_module_init(void)
367 {
368     int ret;
369 
370     ret = i2c_add_driver(&xz3216_i2c_driver);
371     if (ret != 0) {
372         pr_err("Failed to register I2C driver: %d\n", ret);
373     }
374     return ret;
375 }
376 subsys_initcall_sync(xz3216_module_init);
377 
xz3216_module_exit(void)378 static void __exit xz3216_module_exit(void)
379 {
380     i2c_del_driver(&xz3216_i2c_driver);
381 }
382 module_exit(xz3216_module_exit);
383 
384 MODULE_LICENSE("GPL");
385 MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
386 MODULE_DESCRIPTION("xz3216 PMIC driver");
387