]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/power/supply/bq24735-charger.c
power: supply: bq24735: move down bq24735_{en,dis}able_charging
[linux.git] / drivers / power / supply / 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/gpio/consumer.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 power_supply_desc        charger_desc;
49         struct i2c_client               *client;
50         struct bq24735_platform         *pdata;
51         struct mutex                    lock;
52         struct gpio_desc                *status_gpio;
53         struct delayed_work             poll;
54         u32                             poll_interval;
55         bool                            charging;
56 };
57
58 static inline struct bq24735 *to_bq24735(struct power_supply *psy)
59 {
60         return power_supply_get_drvdata(psy);
61 }
62
63 static enum power_supply_property bq24735_charger_properties[] = {
64         POWER_SUPPLY_PROP_STATUS,
65         POWER_SUPPLY_PROP_ONLINE,
66 };
67
68 static int bq24735_charger_property_is_writeable(struct power_supply *psy,
69                                                  enum power_supply_property psp)
70 {
71         switch (psp) {
72         case POWER_SUPPLY_PROP_STATUS:
73                 return 1;
74         default:
75                 break;
76         }
77
78         return 0;
79 }
80
81 static inline int bq24735_write_word(struct i2c_client *client, u8 reg,
82                                      u16 value)
83 {
84         return i2c_smbus_write_word_data(client, reg, le16_to_cpu(value));
85 }
86
87 static inline int bq24735_read_word(struct i2c_client *client, u8 reg)
88 {
89         s32 ret = i2c_smbus_read_word_data(client, reg);
90
91         return ret < 0 ? ret : le16_to_cpu(ret);
92 }
93
94 static int bq24735_update_word(struct i2c_client *client, u8 reg,
95                                u16 mask, u16 value)
96 {
97         unsigned int tmp;
98         int ret;
99
100         ret = bq24735_read_word(client, reg);
101         if (ret < 0)
102                 return ret;
103
104         tmp = ret & ~mask;
105         tmp |= value & mask;
106
107         return bq24735_write_word(client, reg, tmp);
108 }
109
110 static int bq24735_config_charger(struct bq24735 *charger)
111 {
112         struct bq24735_platform *pdata = charger->pdata;
113         int ret;
114         u16 value;
115
116         if (pdata->ext_control)
117                 return 0;
118
119         if (pdata->charge_current) {
120                 value = pdata->charge_current & BQ24735_CHARGE_CURRENT_MASK;
121
122                 ret = bq24735_write_word(charger->client,
123                                          BQ24735_CHARGE_CURRENT, value);
124                 if (ret < 0) {
125                         dev_err(&charger->client->dev,
126                                 "Failed to write charger current : %d\n",
127                                 ret);
128                         return ret;
129                 }
130         }
131
132         if (pdata->charge_voltage) {
133                 value = pdata->charge_voltage & BQ24735_CHARGE_VOLTAGE_MASK;
134
135                 ret = bq24735_write_word(charger->client,
136                                          BQ24735_CHARGE_VOLTAGE, value);
137                 if (ret < 0) {
138                         dev_err(&charger->client->dev,
139                                 "Failed to write charger voltage : %d\n",
140                                 ret);
141                         return ret;
142                 }
143         }
144
145         if (pdata->input_current) {
146                 value = pdata->input_current & BQ24735_INPUT_CURRENT_MASK;
147
148                 ret = bq24735_write_word(charger->client,
149                                          BQ24735_INPUT_CURRENT, value);
150                 if (ret < 0) {
151                         dev_err(&charger->client->dev,
152                                 "Failed to write input current : %d\n",
153                                 ret);
154                         return ret;
155                 }
156         }
157
158         return 0;
159 }
160
161 static inline int bq24735_enable_charging(struct bq24735 *charger)
162 {
163         if (charger->pdata->ext_control)
164                 return 0;
165
166         return bq24735_update_word(charger->client, BQ24735_CHG_OPT,
167                                    BQ24735_CHG_OPT_CHARGE_DISABLE, 0);
168 }
169
170 static inline int bq24735_disable_charging(struct bq24735 *charger)
171 {
172         if (charger->pdata->ext_control)
173                 return 0;
174
175         return bq24735_update_word(charger->client, BQ24735_CHG_OPT,
176                                    BQ24735_CHG_OPT_CHARGE_DISABLE,
177                                    BQ24735_CHG_OPT_CHARGE_DISABLE);
178 }
179
180 static bool bq24735_charger_is_present(struct bq24735 *charger)
181 {
182         if (charger->status_gpio) {
183                 return !gpiod_get_value_cansleep(charger->status_gpio);
184         } else {
185                 int ac = 0;
186
187                 ac = bq24735_read_word(charger->client, BQ24735_CHG_OPT);
188                 if (ac < 0) {
189                         dev_err(&charger->client->dev,
190                                 "Failed to read charger options : %d\n",
191                                 ac);
192                         return false;
193                 }
194                 return (ac & BQ24735_CHG_OPT_AC_PRESENT) ? true : false;
195         }
196
197         return false;
198 }
199
200 static int bq24735_charger_is_charging(struct bq24735 *charger)
201 {
202         int ret;
203
204         if (!bq24735_charger_is_present(charger))
205                 return 0;
206
207         ret  = bq24735_read_word(charger->client, BQ24735_CHG_OPT);
208         if (ret < 0)
209                 return ret;
210
211         return !(ret & BQ24735_CHG_OPT_CHARGE_DISABLE);
212 }
213
214 static void bq24735_update(struct bq24735 *charger)
215 {
216         mutex_lock(&charger->lock);
217
218         if (charger->charging && bq24735_charger_is_present(charger))
219                 bq24735_enable_charging(charger);
220         else
221                 bq24735_disable_charging(charger);
222
223         mutex_unlock(&charger->lock);
224
225         power_supply_changed(charger->charger);
226 }
227
228 static irqreturn_t bq24735_charger_isr(int irq, void *devid)
229 {
230         struct power_supply *psy = devid;
231         struct bq24735 *charger = to_bq24735(psy);
232
233         bq24735_update(charger);
234
235         return IRQ_HANDLED;
236 }
237
238 static void bq24735_poll(struct work_struct *work)
239 {
240         struct bq24735 *charger = container_of(work, struct bq24735, poll.work);
241
242         bq24735_update(charger);
243
244         schedule_delayed_work(&charger->poll,
245                               msecs_to_jiffies(charger->poll_interval));
246 }
247
248 static int bq24735_charger_get_property(struct power_supply *psy,
249                                         enum power_supply_property psp,
250                                         union power_supply_propval *val)
251 {
252         struct bq24735 *charger = to_bq24735(psy);
253
254         switch (psp) {
255         case POWER_SUPPLY_PROP_ONLINE:
256                 val->intval = bq24735_charger_is_present(charger) ? 1 : 0;
257                 break;
258         case POWER_SUPPLY_PROP_STATUS:
259                 switch (bq24735_charger_is_charging(charger)) {
260                 case 1:
261                         val->intval = POWER_SUPPLY_STATUS_CHARGING;
262                         break;
263                 case 0:
264                         val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
265                         break;
266                 default:
267                         val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
268                         break;
269                 }
270                 break;
271         default:
272                 return -EINVAL;
273         }
274
275         return 0;
276 }
277
278 static int bq24735_charger_set_property(struct power_supply *psy,
279                                         enum power_supply_property psp,
280                                         const union power_supply_propval *val)
281 {
282         struct bq24735 *charger = to_bq24735(psy);
283         int ret;
284
285         switch (psp) {
286         case POWER_SUPPLY_PROP_STATUS:
287                 switch (val->intval) {
288                 case POWER_SUPPLY_STATUS_CHARGING:
289                         mutex_lock(&charger->lock);
290                         charger->charging = true;
291                         ret = bq24735_enable_charging(charger);
292                         mutex_unlock(&charger->lock);
293                         if (ret)
294                                 return ret;
295                         bq24735_config_charger(charger);
296                         break;
297                 case POWER_SUPPLY_STATUS_DISCHARGING:
298                 case POWER_SUPPLY_STATUS_NOT_CHARGING:
299                         mutex_lock(&charger->lock);
300                         charger->charging = false;
301                         ret = bq24735_disable_charging(charger);
302                         mutex_unlock(&charger->lock);
303                         if (ret)
304                                 return ret;
305                         break;
306                 default:
307                         return -EINVAL;
308                 }
309                 power_supply_changed(psy);
310                 break;
311         default:
312                 return -EPERM;
313         }
314
315         return 0;
316 }
317
318 static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
319 {
320         struct bq24735_platform *pdata;
321         struct device_node *np = client->dev.of_node;
322         u32 val;
323         int ret;
324
325         pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
326         if (!pdata) {
327                 dev_err(&client->dev,
328                         "Memory alloc for bq24735 pdata failed\n");
329                 return NULL;
330         }
331
332         ret = of_property_read_u32(np, "ti,charge-current", &val);
333         if (!ret)
334                 pdata->charge_current = val;
335
336         ret = of_property_read_u32(np, "ti,charge-voltage", &val);
337         if (!ret)
338                 pdata->charge_voltage = val;
339
340         ret = of_property_read_u32(np, "ti,input-current", &val);
341         if (!ret)
342                 pdata->input_current = val;
343
344         pdata->ext_control = of_property_read_bool(np, "ti,external-control");
345
346         return pdata;
347 }
348
349 static int bq24735_charger_probe(struct i2c_client *client,
350                                  const struct i2c_device_id *id)
351 {
352         int ret;
353         struct bq24735 *charger;
354         struct power_supply_desc *supply_desc;
355         struct power_supply_config psy_cfg = {};
356         char *name;
357
358         charger = devm_kzalloc(&client->dev, sizeof(*charger), GFP_KERNEL);
359         if (!charger)
360                 return -ENOMEM;
361
362         mutex_init(&charger->lock);
363         charger->charging = true;
364         charger->pdata = client->dev.platform_data;
365
366         if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node)
367                 charger->pdata = bq24735_parse_dt_data(client);
368
369         if (!charger->pdata) {
370                 dev_err(&client->dev, "no platform data provided\n");
371                 return -EINVAL;
372         }
373
374         name = (char *)charger->pdata->name;
375         if (!name) {
376                 name = devm_kasprintf(&client->dev, GFP_KERNEL,
377                                       "bq24735@%s",
378                                       dev_name(&client->dev));
379                 if (!name) {
380                         dev_err(&client->dev, "Failed to alloc device name\n");
381                         return -ENOMEM;
382                 }
383         }
384
385         charger->client = client;
386
387         supply_desc = &charger->charger_desc;
388
389         supply_desc->name = name;
390         supply_desc->type = POWER_SUPPLY_TYPE_MAINS;
391         supply_desc->properties = bq24735_charger_properties;
392         supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties);
393         supply_desc->get_property = bq24735_charger_get_property;
394         supply_desc->set_property = bq24735_charger_set_property;
395         supply_desc->property_is_writeable =
396                                 bq24735_charger_property_is_writeable;
397
398         psy_cfg.supplied_to = charger->pdata->supplied_to;
399         psy_cfg.num_supplicants = charger->pdata->num_supplicants;
400         psy_cfg.of_node = client->dev.of_node;
401         psy_cfg.drv_data = charger;
402
403         i2c_set_clientdata(client, charger);
404
405         charger->status_gpio = devm_gpiod_get_optional(&client->dev,
406                                                        "ti,ac-detect",
407                                                        GPIOD_IN);
408         if (IS_ERR(charger->status_gpio)) {
409                 ret = PTR_ERR(charger->status_gpio);
410                 dev_err(&client->dev, "Getting gpio failed: %d\n", ret);
411                 return ret;
412         }
413
414         if (!charger->status_gpio || bq24735_charger_is_present(charger)) {
415                 ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID);
416                 if (ret < 0) {
417                         dev_err(&client->dev, "Failed to read manufacturer id : %d\n",
418                                 ret);
419                         return ret;
420                 } else if (ret != 0x0040) {
421                         dev_err(&client->dev,
422                                 "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret);
423                         return -ENODEV;
424                 }
425
426                 ret = bq24735_read_word(client, BQ24735_DEVICE_ID);
427                 if (ret < 0) {
428                         dev_err(&client->dev, "Failed to read device id : %d\n", ret);
429                         return ret;
430                 } else if (ret != 0x000B) {
431                         dev_err(&client->dev,
432                                 "device id mismatch. 0x000b != 0x%04x\n", ret);
433                         return -ENODEV;
434                 }
435         }
436
437         ret = bq24735_config_charger(charger);
438         if (ret < 0) {
439                 dev_err(&client->dev, "failed in configuring charger");
440                 return ret;
441         }
442
443         /* check for AC adapter presence */
444         if (bq24735_charger_is_present(charger)) {
445                 ret = bq24735_enable_charging(charger);
446                 if (ret < 0) {
447                         dev_err(&client->dev, "Failed to enable charging\n");
448                         return ret;
449                 }
450         }
451
452         charger->charger = devm_power_supply_register(&client->dev, supply_desc,
453                                                       &psy_cfg);
454         if (IS_ERR(charger->charger)) {
455                 ret = PTR_ERR(charger->charger);
456                 dev_err(&client->dev, "Failed to register power supply: %d\n",
457                         ret);
458                 return ret;
459         }
460
461         if (client->irq) {
462                 ret = devm_request_threaded_irq(&client->dev, client->irq,
463                                                 NULL, bq24735_charger_isr,
464                                                 IRQF_TRIGGER_RISING |
465                                                 IRQF_TRIGGER_FALLING |
466                                                 IRQF_ONESHOT,
467                                                 supply_desc->name,
468                                                 charger->charger);
469                 if (ret) {
470                         dev_err(&client->dev,
471                                 "Unable to register IRQ %d err %d\n",
472                                 client->irq, ret);
473                         return ret;
474                 }
475         } else if (charger->status_gpio) {
476                 ret = device_property_read_u32(&client->dev, "poll-interval",
477                                                &charger->poll_interval);
478                 if (ret)
479                         return 0;
480                 if (!charger->poll_interval)
481                         return 0;
482
483                 INIT_DELAYED_WORK(&charger->poll, bq24735_poll);
484                 schedule_delayed_work(&charger->poll,
485                                       msecs_to_jiffies(charger->poll_interval));
486         }
487
488         return 0;
489 }
490
491 static int bq24735_charger_remove(struct i2c_client *client)
492 {
493         struct bq24735 *charger = i2c_get_clientdata(client);
494
495         if (charger->poll_interval)
496                 cancel_delayed_work_sync(&charger->poll);
497
498         return 0;
499 }
500
501 static const struct i2c_device_id bq24735_charger_id[] = {
502         { "bq24735-charger", 0 },
503         {}
504 };
505 MODULE_DEVICE_TABLE(i2c, bq24735_charger_id);
506
507 static const struct of_device_id bq24735_match_ids[] = {
508         { .compatible = "ti,bq24735", },
509         { /* end */ }
510 };
511 MODULE_DEVICE_TABLE(of, bq24735_match_ids);
512
513 static struct i2c_driver bq24735_charger_driver = {
514         .driver = {
515                 .name = "bq24735-charger",
516                 .of_match_table = bq24735_match_ids,
517         },
518         .probe = bq24735_charger_probe,
519         .remove = bq24735_charger_remove,
520         .id_table = bq24735_charger_id,
521 };
522
523 module_i2c_driver(bq24735_charger_driver);
524
525 MODULE_DESCRIPTION("bq24735 battery charging driver");
526 MODULE_AUTHOR("Darbha Sriharsha <dsriharsha@nvidia.com>");
527 MODULE_LICENSE("GPL v2");