Merge branch 'i2c/for-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
[linux-drm-fsl-dcu.git] / drivers / power / bq24735-charger.c
1 /*
2  * Battery charger driver for TI BQ24735
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #include <linux/err.h>
21 #include <linux/gpio.h>
22 #include <linux/i2c.h>
23 #include <linux/init.h>
24 #include <linux/interrupt.h>
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/of.h>
28 #include <linux/of_gpio.h>
29 #include <linux/power_supply.h>
30 #include <linux/slab.h>
31
32 #include <linux/power/bq24735-charger.h>
33
34 #define BQ24735_CHG_OPT                 0x12
35 #define BQ24735_CHG_OPT_CHARGE_DISABLE  (1 << 0)
36 #define BQ24735_CHG_OPT_AC_PRESENT      (1 << 4)
37 #define BQ24735_CHARGE_CURRENT          0x14
38 #define BQ24735_CHARGE_CURRENT_MASK     0x1fc0
39 #define BQ24735_CHARGE_VOLTAGE          0x15
40 #define BQ24735_CHARGE_VOLTAGE_MASK     0x7ff0
41 #define BQ24735_INPUT_CURRENT           0x3f
42 #define BQ24735_INPUT_CURRENT_MASK      0x1f80
43 #define BQ24735_MANUFACTURER_ID         0xfe
44 #define BQ24735_DEVICE_ID               0xff
45
46 struct bq24735 {
47         struct power_supply     charger;
48         struct i2c_client       *client;
49         struct bq24735_platform *pdata;
50 };
51
52 static inline struct bq24735 *to_bq24735(struct power_supply *psy)
53 {
54         return container_of(psy, struct bq24735, charger);
55 }
56
57 static enum power_supply_property bq24735_charger_properties[] = {
58         POWER_SUPPLY_PROP_ONLINE,
59 };
60
61 static inline int bq24735_write_word(struct i2c_client *client, u8 reg,
62                                      u16 value)
63 {
64         return i2c_smbus_write_word_data(client, reg, le16_to_cpu(value));
65 }
66
67 static inline int bq24735_read_word(struct i2c_client *client, u8 reg)
68 {
69         s32 ret = i2c_smbus_read_word_data(client, reg);
70
71         return ret < 0 ? ret : le16_to_cpu(ret);
72 }
73
74 static int bq24735_update_word(struct i2c_client *client, u8 reg,
75                                u16 mask, u16 value)
76 {
77         unsigned int tmp;
78         int ret;
79
80         ret = bq24735_read_word(client, reg);
81         if (ret < 0)
82                 return ret;
83
84         tmp = ret & ~mask;
85         tmp |= value & mask;
86
87         return bq24735_write_word(client, reg, tmp);
88 }
89
90 static inline int bq24735_enable_charging(struct bq24735 *charger)
91 {
92         return bq24735_update_word(charger->client, BQ24735_CHG_OPT,
93                                    BQ24735_CHG_OPT_CHARGE_DISABLE,
94                                    ~BQ24735_CHG_OPT_CHARGE_DISABLE);
95 }
96
97 static inline int bq24735_disable_charging(struct bq24735 *charger)
98 {
99         return bq24735_update_word(charger->client, BQ24735_CHG_OPT,
100                                    BQ24735_CHG_OPT_CHARGE_DISABLE,
101                                    BQ24735_CHG_OPT_CHARGE_DISABLE);
102 }
103
104 static int bq24735_config_charger(struct bq24735 *charger)
105 {
106         struct bq24735_platform *pdata = charger->pdata;
107         int ret;
108         u16 value;
109
110         if (pdata->charge_current) {
111                 value = pdata->charge_current & BQ24735_CHARGE_CURRENT_MASK;
112
113                 ret = bq24735_write_word(charger->client,
114                                          BQ24735_CHARGE_CURRENT, value);
115                 if (ret < 0) {
116                         dev_err(&charger->client->dev,
117                                 "Failed to write charger current : %d\n",
118                                 ret);
119                         return ret;
120                 }
121         }
122
123         if (pdata->charge_voltage) {
124                 value = pdata->charge_voltage & BQ24735_CHARGE_VOLTAGE_MASK;
125
126                 ret = bq24735_write_word(charger->client,
127                                          BQ24735_CHARGE_VOLTAGE, value);
128                 if (ret < 0) {
129                         dev_err(&charger->client->dev,
130                                 "Failed to write charger voltage : %d\n",
131                                 ret);
132                         return ret;
133                 }
134         }
135
136         if (pdata->input_current) {
137                 value = pdata->input_current & BQ24735_INPUT_CURRENT_MASK;
138
139                 ret = bq24735_write_word(charger->client,
140                                          BQ24735_INPUT_CURRENT, value);
141                 if (ret < 0) {
142                         dev_err(&charger->client->dev,
143                                 "Failed to write input current : %d\n",
144                                 ret);
145                         return ret;
146                 }
147         }
148
149         return 0;
150 }
151
152 static bool bq24735_charger_is_present(struct bq24735 *charger)
153 {
154         struct bq24735_platform *pdata = charger->pdata;
155         int ret;
156
157         if (pdata->status_gpio_valid) {
158                 ret = gpio_get_value_cansleep(pdata->status_gpio);
159                 return ret ^= pdata->status_gpio_active_low == 0;
160         } else {
161                 int ac = 0;
162
163                 ac = bq24735_read_word(charger->client, BQ24735_CHG_OPT);
164                 if (ac < 0) {
165                         dev_err(&charger->client->dev,
166                                 "Failed to read charger options : %d\n",
167                                 ac);
168                         return false;
169                 }
170                 return (ac & BQ24735_CHG_OPT_AC_PRESENT) ? true : false;
171         }
172
173         return false;
174 }
175
176 static irqreturn_t bq24735_charger_isr(int irq, void *devid)
177 {
178         struct power_supply *psy = devid;
179         struct bq24735 *charger = to_bq24735(psy);
180
181         if (bq24735_charger_is_present(charger))
182                 bq24735_enable_charging(charger);
183         else
184                 bq24735_disable_charging(charger);
185
186         power_supply_changed(psy);
187
188         return IRQ_HANDLED;
189 }
190
191 static int bq24735_charger_get_property(struct power_supply *psy,
192                                         enum power_supply_property psp,
193                                         union power_supply_propval *val)
194 {
195         struct bq24735 *charger;
196
197         charger = container_of(psy, struct bq24735, charger);
198
199         switch (psp) {
200         case POWER_SUPPLY_PROP_ONLINE:
201                 val->intval = bq24735_charger_is_present(charger) ? 1 : 0;
202                 break;
203         default:
204                 return -EINVAL;
205         }
206
207         return 0;
208 }
209
210 static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
211 {
212         struct bq24735_platform *pdata;
213         struct device_node *np = client->dev.of_node;
214         u32 val;
215         int ret;
216         enum of_gpio_flags flags;
217
218         pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
219         if (!pdata) {
220                 dev_err(&client->dev,
221                         "Memory alloc for bq24735 pdata failed\n");
222                 return NULL;
223         }
224
225         pdata->status_gpio = of_get_named_gpio_flags(np, "ti,ac-detect-gpios",
226                                                      0, &flags);
227
228         if (flags & OF_GPIO_ACTIVE_LOW)
229                 pdata->status_gpio_active_low = 1;
230
231         ret = of_property_read_u32(np, "ti,charge-current", &val);
232         if (!ret)
233                 pdata->charge_current = val;
234
235         ret = of_property_read_u32(np, "ti,charge-voltage", &val);
236         if (!ret)
237                 pdata->charge_voltage = val;
238
239         ret = of_property_read_u32(np, "ti,input-current", &val);
240         if (!ret)
241                 pdata->input_current = val;
242
243         return pdata;
244 }
245
246 static int bq24735_charger_probe(struct i2c_client *client,
247                                  const struct i2c_device_id *id)
248 {
249         int ret;
250         struct bq24735 *charger;
251         struct power_supply *supply;
252         char *name;
253
254         charger = devm_kzalloc(&client->dev, sizeof(*charger), GFP_KERNEL);
255         if (!charger)
256                 return -ENOMEM;
257
258         charger->pdata = client->dev.platform_data;
259
260         if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node)
261                 charger->pdata = bq24735_parse_dt_data(client);
262
263         if (!charger->pdata) {
264                 dev_err(&client->dev, "no platform data provided\n");
265                 return -EINVAL;
266         }
267
268         name = (char *)charger->pdata->name;
269         if (!name) {
270                 name = kasprintf(GFP_KERNEL, "bq24735@%s",
271                                  dev_name(&client->dev));
272                 if (!name) {
273                         dev_err(&client->dev, "Failed to alloc device name\n");
274                         return -ENOMEM;
275                 }
276         }
277
278         charger->client = client;
279
280         supply = &charger->charger;
281
282         supply->name = name;
283         supply->type = POWER_SUPPLY_TYPE_MAINS;
284         supply->properties = bq24735_charger_properties;
285         supply->num_properties = ARRAY_SIZE(bq24735_charger_properties);
286         supply->get_property = bq24735_charger_get_property;
287         supply->supplied_to = charger->pdata->supplied_to;
288         supply->num_supplicants = charger->pdata->num_supplicants;
289         supply->of_node = client->dev.of_node;
290
291         i2c_set_clientdata(client, charger);
292
293         ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID);
294         if (ret < 0) {
295                 dev_err(&client->dev, "Failed to read manufacturer id : %d\n",
296                         ret);
297                 goto err_free_name;
298         } else if (ret != 0x0040) {
299                 dev_err(&client->dev,
300                         "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret);
301                 ret = -ENODEV;
302                 goto err_free_name;
303         }
304
305         ret = bq24735_read_word(client, BQ24735_DEVICE_ID);
306         if (ret < 0) {
307                 dev_err(&client->dev, "Failed to read device id : %d\n", ret);
308                 goto err_free_name;
309         } else if (ret != 0x000B) {
310                 dev_err(&client->dev,
311                         "device id mismatch. 0x000b != 0x%04x\n", ret);
312                 ret = -ENODEV;
313                 goto err_free_name;
314         }
315
316         if (gpio_is_valid(charger->pdata->status_gpio)) {
317                 ret = devm_gpio_request(&client->dev,
318                                         charger->pdata->status_gpio,
319                                         name);
320                 if (ret) {
321                         dev_err(&client->dev,
322                                 "Failed GPIO request for GPIO %d: %d\n",
323                                 charger->pdata->status_gpio, ret);
324                 }
325
326                 charger->pdata->status_gpio_valid = !ret;
327         }
328
329         ret = bq24735_config_charger(charger);
330         if (ret < 0) {
331                 dev_err(&client->dev, "failed in configuring charger");
332                 goto err_free_name;
333         }
334
335         /* check for AC adapter presence */
336         if (bq24735_charger_is_present(charger)) {
337                 ret = bq24735_enable_charging(charger);
338                 if (ret < 0) {
339                         dev_err(&client->dev, "Failed to enable charging\n");
340                         goto err_free_name;
341                 }
342         }
343
344         ret = power_supply_register(&client->dev, supply);
345         if (ret < 0) {
346                 dev_err(&client->dev, "Failed to register power supply: %d\n",
347                         ret);
348                 goto err_free_name;
349         }
350
351         if (client->irq) {
352                 ret = devm_request_threaded_irq(&client->dev, client->irq,
353                                                 NULL, bq24735_charger_isr,
354                                                 IRQF_TRIGGER_RISING |
355                                                 IRQF_TRIGGER_FALLING |
356                                                 IRQF_ONESHOT,
357                                                 supply->name, supply);
358                 if (ret) {
359                         dev_err(&client->dev,
360                                 "Unable to register IRQ %d err %d\n",
361                                 client->irq, ret);
362                         goto err_unregister_supply;
363                 }
364         }
365
366         return 0;
367 err_unregister_supply:
368         power_supply_unregister(supply);
369 err_free_name:
370         if (name != charger->pdata->name)
371                 kfree(name);
372
373         return ret;
374 }
375
376 static int bq24735_charger_remove(struct i2c_client *client)
377 {
378         struct bq24735 *charger = i2c_get_clientdata(client);
379
380         if (charger->client->irq)
381                 devm_free_irq(&charger->client->dev, charger->client->irq,
382                               &charger->charger);
383
384         power_supply_unregister(&charger->charger);
385
386         if (charger->charger.name != charger->pdata->name)
387                 kfree(charger->charger.name);
388
389         return 0;
390 }
391
392 static const struct i2c_device_id bq24735_charger_id[] = {
393         { "bq24735-charger", 0 },
394         {}
395 };
396 MODULE_DEVICE_TABLE(i2c, bq24735_charger_id);
397
398 static const struct of_device_id bq24735_match_ids[] = {
399         { .compatible = "ti,bq24735", },
400         { /* end */ }
401 };
402 MODULE_DEVICE_TABLE(of, bq24735_match_ids);
403
404 static struct i2c_driver bq24735_charger_driver = {
405         .driver = {
406                 .name = "bq24735-charger",
407                 .owner = THIS_MODULE,
408                 .of_match_table = bq24735_match_ids,
409         },
410         .probe = bq24735_charger_probe,
411         .remove = bq24735_charger_remove,
412         .id_table = bq24735_charger_id,
413 };
414
415 module_i2c_driver(bq24735_charger_driver);
416
417 MODULE_DESCRIPTION("bq24735 battery charging driver");
418 MODULE_AUTHOR("Darbha Sriharsha <dsriharsha@nvidia.com>");
419 MODULE_LICENSE("GPL v2");