regulator: palmas: fix build warnings
[linux-2.6.git] / drivers / regulator / bq2419x-regulator.c
1 /*
2  * bq2419x-regulator.c --  bq2419x
3  *
4  * Regulator driver for BQ2419X charger.
5  *
6  * Copyright (c) 2012-2013, NVIDIA CORPORATION.  All rights reserved.
7  *
8  * Author: Laxman Dewangan <ldewangan@nvidia.com>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation version 2.
13  *
14  * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
15  * whether express or implied; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22  * 02111-1307, USA
23  */
24
25 #include <linux/err.h>
26 #include <linux/gpio.h>
27 #include <linux/i2c.h>
28 #include <linux/init.h>
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/platform_device.h>
32 #include <linux/regmap.h>
33 #include <linux/regulator/driver.h>
34 #include <linux/regulator/machine.h>
35 #include <linux/mfd/bq2419x.h>
36 #include <linux/slab.h>
37
38 struct bq2419x_regulator_info {
39         struct device *dev;
40         struct regulator_desc desc;
41         struct regulator_dev *rdev;
42         struct bq2419x_chip *chip;
43         int gpio_otg_iusb;
44         bool power_off_on_suspend;
45         struct mutex mutex;
46         int shutdown_complete;
47 };
48
49 static int bq2419x_regulator_enable_time(struct regulator_dev *rdev)
50 {
51         return 500000;
52 }
53
54 static int bq2419x_dcdc_enable(struct regulator_dev *rdev)
55 {
56         struct bq2419x_regulator_info *bq = rdev_get_drvdata(rdev);
57         int ret;
58
59         dev_info(bq->dev, "%s called\n", __func__);
60         if (gpio_is_valid(bq->gpio_otg_iusb))
61                 gpio_set_value(bq->gpio_otg_iusb, 1);
62
63         mutex_lock(&bq->mutex);
64         if (bq && bq->shutdown_complete) {
65                 mutex_unlock(&bq->mutex);
66                 return -ENODEV;
67         }
68
69         /* Clear EN_HIZ */
70         ret = regmap_update_bits(bq->chip->regmap,
71                         BQ2419X_INPUT_SRC_REG, BQ2419X_EN_HIZ, 0);
72         if (ret < 0) {
73                 dev_err(bq->dev, "error reading reg: 0x%x\n",
74                         BQ2419X_INPUT_SRC_REG);
75                 return ret;
76         }
77
78         ret = regmap_update_bits(bq->chip->regmap, BQ2419X_OTG,
79                         BQ2419X_OTG_ENABLE_MASK, BQ2419X_OTG_ENABLE);
80         if (ret < 0) {
81                 dev_err(bq->dev, "register %d update failed with err %d",
82                          BQ2419X_OTG, ret);
83                 mutex_unlock(&bq->mutex);
84                 return ret;
85         }
86         mutex_unlock(&bq->mutex);
87         return ret;
88 }
89
90 static int bq2419x_dcdc_disable(struct regulator_dev *rdev)
91 {
92         struct bq2419x_regulator_info *bq = rdev_get_drvdata(rdev);
93         int ret = 0;
94
95         dev_info(bq->dev, "%s called\n", __func__);
96         mutex_lock(&bq->mutex);
97         if (bq && bq->shutdown_complete) {
98                 mutex_unlock(&bq->mutex);
99                 return -ENODEV;
100         }
101
102         ret = regmap_update_bits(bq->chip->regmap, BQ2419X_OTG,
103                                         BQ2419X_OTG_ENABLE_MASK, 0x10);
104         if (ret < 0) {
105                 dev_err(bq->dev, "register %d update failed with err %d",
106                         BQ2419X_OTG, ret);
107                 mutex_unlock(&bq->mutex);
108                 return ret;
109         }
110
111         if (gpio_is_valid(bq->gpio_otg_iusb))
112                 gpio_set_value(bq->gpio_otg_iusb, 0);
113
114         mutex_unlock(&bq->mutex);
115         return ret;
116 }
117
118 static int bq2419x_dcdc_is_enabled(struct regulator_dev *rdev)
119 {
120         struct bq2419x_regulator_info *bq = rdev_get_drvdata(rdev);
121         int ret;
122         unsigned int data;
123
124         mutex_lock(&bq->mutex);
125         if (bq && bq->shutdown_complete) {
126                 mutex_unlock(&bq->mutex);
127                 return -ENODEV;
128         }
129         ret = regmap_read(bq->chip->regmap, BQ2419X_OTG, &data);
130         if (ret < 0) {
131                 dev_err(bq->dev, "register %d read failed with err %d",
132                         BQ2419X_OTG, ret);
133                 mutex_unlock(&bq->mutex);
134                 return ret;
135         }
136         mutex_unlock(&bq->mutex);
137         return (data & BQ2419X_OTG_ENABLE_MASK) == BQ2419X_OTG_ENABLE;
138 }
139
140 static struct regulator_ops bq2419x_dcdc_ops = {
141         .enable                 = bq2419x_dcdc_enable,
142         .disable                = bq2419x_dcdc_disable,
143         .is_enabled             = bq2419x_dcdc_is_enabled,
144         .enable_time            = bq2419x_regulator_enable_time,
145 };
146
147 static void bq2419x_regulator_shutdown(struct platform_device *pdev)
148 {
149         struct bq2419x_regulator_info *bq = platform_get_drvdata(pdev);
150
151         mutex_lock(&bq->mutex);
152         bq->shutdown_complete = 1;
153         mutex_unlock(&bq->mutex);
154 }
155
156 static int __devinit bq2419x_regulator_probe(struct platform_device *pdev)
157 {
158         struct bq2419x_regulator_platform_data *pdata = NULL;
159         struct bq2419x_platform_data *chip_pdata;
160         struct regulator_dev *rdev;
161         struct bq2419x_regulator_info *bq;
162         int ret;
163
164         chip_pdata = dev_get_platdata(pdev->dev.parent);
165         if (chip_pdata)
166                 pdata = chip_pdata->reg_pdata;
167
168         if (!pdata) {
169                 dev_err(&pdev->dev, "No Platform data");
170                 return -EIO;
171         }
172
173         bq = devm_kzalloc(&pdev->dev, sizeof(*bq), GFP_KERNEL);
174         if (!bq) {
175                 dev_err(&pdev->dev, "Memory allocation failed\n");
176                 return -ENOMEM;
177         }
178
179         bq->dev = &pdev->dev;
180         bq->chip = dev_get_drvdata(pdev->dev.parent);
181
182         bq->gpio_otg_iusb = pdata->gpio_otg_iusb;
183         bq->power_off_on_suspend = pdata->power_off_on_suspend;
184         bq->desc.name = "bq2419x-vbus";
185         bq->desc.id = 0;
186         bq->desc.ops = &bq2419x_dcdc_ops;
187         bq->desc.type = REGULATOR_VOLTAGE;
188         bq->desc.owner = THIS_MODULE;
189         bq->shutdown_complete = 0;
190         mutex_init(&bq->mutex);
191
192         platform_set_drvdata(pdev, bq);
193
194         if (gpio_is_valid(bq->gpio_otg_iusb)) {
195                 ret = gpio_request(bq->gpio_otg_iusb, dev_name(&pdev->dev));
196                 if (ret < 0) {
197                         dev_err(&pdev->dev,
198                                 "gpio request failed, err = %d\n", ret);
199                         return ret;
200                 }
201                 gpio_direction_output(bq->gpio_otg_iusb, 0);
202         }
203
204         /* Register the regulators */
205         rdev = regulator_register(&bq->desc, &pdev->dev,
206                         pdata->reg_init_data, bq, NULL);
207         if (IS_ERR(rdev)) {
208                 ret = PTR_ERR(rdev);
209                 dev_err(bq->dev, "regulator register failed, err %d\n", ret);
210                 goto err_init;
211         }
212
213         bq->rdev = rdev;
214
215         ret = regmap_update_bits(bq->chip->regmap, BQ2419X_OTG,
216                                         BQ2419X_OTG_ENABLE_MASK, 0x10);
217         if (ret < 0) {
218                 dev_err(bq->dev, "register %d update failed with err %d",
219                         BQ2419X_OTG, ret);
220                 goto err_reg_update;
221         }
222         return 0;
223
224 err_reg_update:
225         regulator_unregister(bq->rdev);
226 err_init:
227         if (gpio_is_valid(bq->gpio_otg_iusb))
228                 gpio_free(bq->gpio_otg_iusb);
229         mutex_destroy(&bq->mutex);
230         return ret;
231 }
232
233 static int __devexit bq2419x_regulator_remove(struct platform_device *pdev)
234 {
235         struct bq2419x_regulator_info *bq = platform_get_drvdata(pdev);
236
237         mutex_destroy(&bq->mutex);
238         regulator_unregister(bq->rdev);
239         if (gpio_is_valid(bq->gpio_otg_iusb))
240                 gpio_free(bq->gpio_otg_iusb);
241         return 0;
242 }
243
244 #ifdef CONFIG_PM_SLEEP
245 static int bq2419x_reg_suspend(struct device *dev)
246 {
247         struct bq2419x_regulator_info *bq = dev_get_drvdata(dev);
248
249         if (bq->power_off_on_suspend && bq2419x_dcdc_is_enabled(bq->rdev) > 0)
250                 bq2419x_dcdc_disable(bq->rdev);
251         return 0;
252 }
253
254 static int bq2419x_reg_resume(struct device *dev)
255 {
256         struct bq2419x_regulator_info *bq = dev_get_drvdata(dev);
257
258         /* Turn on regulator that might be turned off by bq2419x_reg_suspend()
259          * and that should be turned on according to the regulators properties.
260          */
261         if (bq->power_off_on_suspend &&
262                 (bq->rdev->use_count > 0 || bq->rdev->constraints->always_on))
263                 bq2419x_dcdc_enable(bq->rdev);
264         return 0;
265 }
266
267 static const struct dev_pm_ops bq2419x_reg_pm_ops = {
268         SET_SYSTEM_SLEEP_PM_OPS(bq2419x_reg_suspend, bq2419x_reg_resume)
269 };
270 #endif
271
272 static struct platform_driver bq2419x_regulator_driver = {
273         .driver = {
274                 .name = "bq2419x-pmic",
275                 .owner = THIS_MODULE,
276 #ifdef CONFIG_PM_SLEEP
277                 .pm = &bq2419x_reg_pm_ops,
278 #endif
279         },
280         .probe = bq2419x_regulator_probe,
281         .shutdown = bq2419x_regulator_shutdown,
282         .remove = __devexit_p(bq2419x_regulator_remove),
283 };
284
285 static int __init bq2419x_init(void)
286 {
287         return platform_driver_register(&bq2419x_regulator_driver);
288 }
289 subsys_initcall(bq2419x_init);
290
291 static void __exit bq2419x_cleanup(void)
292 {
293         platform_driver_unregister(&bq2419x_regulator_driver);
294 }
295 module_exit(bq2419x_cleanup);
296
297 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
298 MODULE_DESCRIPTION("BQ2419X voltage regulator driver");
299 MODULE_LICENSE("GPL v2");