]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/power/supply/cpcap-charger.c
543a1bd21ab9c74ab15a2a16898fa477ed021818
[karo-tx-linux.git] / drivers / power / supply / cpcap-charger.c
1 /*
2  * Motorola CPCAP PMIC battery charger driver
3  *
4  * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
5  *
6  * Rewritten for Linux power framework with some parts based on
7  * on earlier driver found in the Motorola Linux kernel:
8  *
9  * Copyright (C) 2009-2010 Motorola, Inc.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  */
20
21 #include <linux/atomic.h>
22 #include <linux/init.h>
23 #include <linux/module.h>
24 #include <linux/slab.h>
25 #include <linux/err.h>
26 #include <linux/interrupt.h>
27 #include <linux/notifier.h>
28 #include <linux/of.h>
29 #include <linux/of_platform.h>
30 #include <linux/platform_device.h>
31 #include <linux/power_supply.h>
32 #include <linux/regmap.h>
33
34 #include <linux/gpio/consumer.h>
35 #include <linux/usb/phy_companion.h>
36 #include <linux/phy/omap_usb.h>
37 #include <linux/usb/otg.h>
38 #include <linux/iio/consumer.h>
39 #include <linux/mfd/motorola-cpcap.h>
40
41 /* CPCAP_REG_CRM register bits */
42 #define CPCAP_REG_CRM_UNUSED_641_15     BIT(15) /* 641 = register number */
43 #define CPCAP_REG_CRM_UNUSED_641_14     BIT(14) /* 641 = register number */
44 #define CPCAP_REG_CRM_CHRG_LED_EN       BIT(13)
45 #define CPCAP_REG_CRM_RVRSMODE          BIT(12)
46 #define CPCAP_REG_CRM_ICHRG_TR1         BIT(11)
47 #define CPCAP_REG_CRM_ICHRG_TR0         BIT(10)
48 #define CPCAP_REG_CRM_FET_OVRD          BIT(9)
49 #define CPCAP_REG_CRM_FET_CTRL          BIT(8)
50 #define CPCAP_REG_CRM_VCHRG3            BIT(7)
51 #define CPCAP_REG_CRM_VCHRG2            BIT(6)
52 #define CPCAP_REG_CRM_VCHRG1            BIT(5)
53 #define CPCAP_REG_CRM_VCHRG0            BIT(4)
54 #define CPCAP_REG_CRM_ICHRG3            BIT(3)
55 #define CPCAP_REG_CRM_ICHRG2            BIT(2)
56 #define CPCAP_REG_CRM_ICHRG1            BIT(1)
57 #define CPCAP_REG_CRM_ICHRG0            BIT(0)
58
59 /* CPCAP_REG_CRM trickle charge voltages */
60 #define CPCAP_REG_CRM_TR(val)           (((val) & 0x3) << 10)
61 #define CPCAP_REG_CRM_TR_0A00           CPCAP_REG_CRM_TR(0x0)
62 #define CPCAP_REG_CRM_TR_0A24           CPCAP_REG_CRM_TR(0x1)
63 #define CPCAP_REG_CRM_TR_0A48           CPCAP_REG_CRM_TR(0x2)
64 #define CPCAP_REG_CRM_TR_0A72           CPCAP_REG_CRM_TR(0x4)
65
66 /* CPCAP_REG_CRM charge voltages */
67 #define CPCAP_REG_CRM_VCHRG(val)        (((val) & 0xf) << 4)
68 #define CPCAP_REG_CRM_VCHRG_3V80        CPCAP_REG_CRM_VCHRG(0x0)
69 #define CPCAP_REG_CRM_VCHRG_4V10        CPCAP_REG_CRM_VCHRG(0x1)
70 #define CPCAP_REG_CRM_VCHRG_4V15        CPCAP_REG_CRM_VCHRG(0x2)
71 #define CPCAP_REG_CRM_VCHRG_4V20        CPCAP_REG_CRM_VCHRG(0x3)
72 #define CPCAP_REG_CRM_VCHRG_4V22        CPCAP_REG_CRM_VCHRG(0x4)
73 #define CPCAP_REG_CRM_VCHRG_4V24        CPCAP_REG_CRM_VCHRG(0x5)
74 #define CPCAP_REG_CRM_VCHRG_4V26        CPCAP_REG_CRM_VCHRG(0x6)
75 #define CPCAP_REG_CRM_VCHRG_4V28        CPCAP_REG_CRM_VCHRG(0x7)
76 #define CPCAP_REG_CRM_VCHRG_4V30        CPCAP_REG_CRM_VCHRG(0x8)
77 #define CPCAP_REG_CRM_VCHRG_4V32        CPCAP_REG_CRM_VCHRG(0x9)
78 #define CPCAP_REG_CRM_VCHRG_4V34        CPCAP_REG_CRM_VCHRG(0xa)
79 #define CPCAP_REG_CRM_VCHRG_4V36        CPCAP_REG_CRM_VCHRG(0xb)
80 #define CPCAP_REG_CRM_VCHRG_4V38        CPCAP_REG_CRM_VCHRG(0xc)
81 #define CPCAP_REG_CRM_VCHRG_4V40        CPCAP_REG_CRM_VCHRG(0xd)
82 #define CPCAP_REG_CRM_VCHRG_4V42        CPCAP_REG_CRM_VCHRG(0xe)
83 #define CPCAP_REG_CRM_VCHRG_4V44        CPCAP_REG_CRM_VCHRG(0xf)
84
85 /* CPCAP_REG_CRM charge currents */
86 #define CPCAP_REG_CRM_ICHRG(val)        (((val) & 0xf) << 0)
87 #define CPCAP_REG_CRM_ICHRG_0A000       CPCAP_REG_CRM_ICHRG(0x0)
88 #define CPCAP_REG_CRM_ICHRG_0A070       CPCAP_REG_CRM_ICHRG(0x1)
89 #define CPCAP_REG_CRM_ICHRG_0A176       CPCAP_REG_CRM_ICHRG(0x2)
90 #define CPCAP_REG_CRM_ICHRG_0A264       CPCAP_REG_CRM_ICHRG(0x3)
91 #define CPCAP_REG_CRM_ICHRG_0A352       CPCAP_REG_CRM_ICHRG(0x4)
92 #define CPCAP_REG_CRM_ICHRG_0A440       CPCAP_REG_CRM_ICHRG(0x5)
93 #define CPCAP_REG_CRM_ICHRG_0A528       CPCAP_REG_CRM_ICHRG(0x6)
94 #define CPCAP_REG_CRM_ICHRG_0A616       CPCAP_REG_CRM_ICHRG(0x7)
95 #define CPCAP_REG_CRM_ICHRG_0A704       CPCAP_REG_CRM_ICHRG(0x8)
96 #define CPCAP_REG_CRM_ICHRG_0A792       CPCAP_REG_CRM_ICHRG(0x9)
97 #define CPCAP_REG_CRM_ICHRG_0A880       CPCAP_REG_CRM_ICHRG(0xa)
98 #define CPCAP_REG_CRM_ICHRG_0A968       CPCAP_REG_CRM_ICHRG(0xb)
99 #define CPCAP_REG_CRM_ICHRG_1A056       CPCAP_REG_CRM_ICHRG(0xc)
100 #define CPCAP_REG_CRM_ICHRG_1A144       CPCAP_REG_CRM_ICHRG(0xd)
101 #define CPCAP_REG_CRM_ICHRG_1A584       CPCAP_REG_CRM_ICHRG(0xe)
102 #define CPCAP_REG_CRM_ICHRG_NO_LIMIT    CPCAP_REG_CRM_ICHRG(0xf)
103
104 enum {
105         CPCAP_CHARGER_IIO_BATTDET,
106         CPCAP_CHARGER_IIO_VOLTAGE,
107         CPCAP_CHARGER_IIO_VBUS,
108         CPCAP_CHARGER_IIO_CHRG_CURRENT,
109         CPCAP_CHARGER_IIO_BATT_CURRENT,
110         CPCAP_CHARGER_IIO_NR,
111 };
112
113 struct cpcap_charger_ddata {
114         struct device *dev;
115         struct regmap *reg;
116         struct list_head irq_list;
117         struct delayed_work detect_work;
118         struct delayed_work vbus_work;
119         struct gpio_desc *gpio[2];              /* gpio_reven0 & 1 */
120
121         struct iio_channel *channels[CPCAP_CHARGER_IIO_NR];
122
123         struct power_supply *usb;
124
125         struct phy_companion comparator;        /* For USB VBUS */
126         bool vbus_enabled;
127         atomic_t active;
128
129         int status;
130 };
131
132 struct cpcap_interrupt_desc {
133         int irq;
134         struct list_head node;
135         const char *name;
136 };
137
138 struct cpcap_charger_ints_state {
139         bool chrg_det;
140         bool rvrs_chrg;
141         bool vbusov;
142
143         bool chrg_se1b;
144         bool rvrs_mode;
145         bool chrgcurr1;
146         bool vbusvld;
147
148         bool battdetb;
149 };
150
151 static enum power_supply_property cpcap_charger_props[] = {
152         POWER_SUPPLY_PROP_STATUS,
153         POWER_SUPPLY_PROP_ONLINE,
154         POWER_SUPPLY_PROP_VOLTAGE_NOW,
155         POWER_SUPPLY_PROP_CURRENT_NOW,
156 };
157
158 static bool cpcap_charger_battery_found(struct cpcap_charger_ddata *ddata)
159 {
160         struct iio_channel *channel;
161         int error, value;
162
163         channel = ddata->channels[CPCAP_CHARGER_IIO_BATTDET];
164         error = iio_read_channel_raw(channel, &value);
165         if (error < 0) {
166                 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
167
168                 return false;
169         }
170
171         return value == 1;
172 }
173
174 static int cpcap_charger_get_charge_voltage(struct cpcap_charger_ddata *ddata)
175 {
176         struct iio_channel *channel;
177         int error, value = 0;
178
179         channel = ddata->channels[CPCAP_CHARGER_IIO_VOLTAGE];
180         error = iio_read_channel_processed(channel, &value);
181         if (error < 0) {
182                 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
183
184                 return 0;
185         }
186
187         return value;
188 }
189
190 static int cpcap_charger_get_charge_current(struct cpcap_charger_ddata *ddata)
191 {
192         struct iio_channel *channel;
193         int error, value = 0;
194
195         channel = ddata->channels[CPCAP_CHARGER_IIO_CHRG_CURRENT];
196         error = iio_read_channel_processed(channel, &value);
197         if (error < 0) {
198                 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
199
200                 return 0;
201         }
202
203         return value;
204 }
205
206 static int cpcap_charger_get_property(struct power_supply *psy,
207                                       enum power_supply_property psp,
208                                       union power_supply_propval *val)
209 {
210         struct cpcap_charger_ddata *ddata = dev_get_drvdata(psy->dev.parent);
211
212         switch (psp) {
213         case POWER_SUPPLY_PROP_STATUS:
214                 val->intval = ddata->status;
215                 break;
216         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
217                 if (ddata->status == POWER_SUPPLY_STATUS_CHARGING)
218                         val->intval = cpcap_charger_get_charge_voltage(ddata) *
219                                 1000;
220                 else
221                         val->intval = 0;
222                 break;
223         case POWER_SUPPLY_PROP_CURRENT_NOW:
224                 if (ddata->status == POWER_SUPPLY_STATUS_CHARGING)
225                         val->intval = cpcap_charger_get_charge_current(ddata) *
226                                 1000;
227                 else
228                         val->intval = 0;
229                 break;
230         case POWER_SUPPLY_PROP_ONLINE:
231                 val->intval = ddata->status == POWER_SUPPLY_STATUS_CHARGING;
232                 break;
233         default:
234                 return -EINVAL;
235         }
236
237         return 0;
238 }
239
240 static void cpcap_charger_set_cable_path(struct cpcap_charger_ddata *ddata,
241                                          bool enabled)
242 {
243         if (!ddata->gpio[0])
244                 return;
245
246         gpiod_set_value(ddata->gpio[0], enabled);
247 }
248
249 static void cpcap_charger_set_inductive_path(struct cpcap_charger_ddata *ddata,
250                                              bool enabled)
251 {
252         if (!ddata->gpio[1])
253                 return;
254
255         gpiod_set_value(ddata->gpio[1], enabled);
256 }
257
258 static int cpcap_charger_set_state(struct cpcap_charger_ddata *ddata,
259                                    int max_voltage, int charge_current,
260                                    int trickle_current)
261 {
262         bool enable;
263         int error;
264
265         enable = max_voltage && (charge_current || trickle_current);
266         dev_dbg(ddata->dev, "%s enable: %i\n", __func__, enable);
267
268         if (!enable) {
269                 error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
270                                            0x3fff,
271                                            CPCAP_REG_CRM_FET_OVRD |
272                                            CPCAP_REG_CRM_FET_CTRL);
273                 if (error) {
274                         ddata->status = POWER_SUPPLY_STATUS_UNKNOWN;
275                         goto out_err;
276                 }
277
278                 ddata->status = POWER_SUPPLY_STATUS_DISCHARGING;
279
280                 return 0;
281         }
282
283         error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, 0x3fff,
284                                    CPCAP_REG_CRM_CHRG_LED_EN |
285                                    trickle_current |
286                                    CPCAP_REG_CRM_FET_OVRD |
287                                    CPCAP_REG_CRM_FET_CTRL |
288                                    max_voltage |
289                                    charge_current);
290         if (error) {
291                 ddata->status = POWER_SUPPLY_STATUS_UNKNOWN;
292                 goto out_err;
293         }
294
295         ddata->status = POWER_SUPPLY_STATUS_CHARGING;
296
297         return 0;
298
299 out_err:
300         dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
301
302         return error;
303 }
304
305 static bool cpcap_charger_vbus_valid(struct cpcap_charger_ddata *ddata)
306 {
307         int error, value = 0;
308         struct iio_channel *channel =
309                 ddata->channels[CPCAP_CHARGER_IIO_VBUS];
310
311         error = iio_read_channel_processed(channel, &value);
312         if (error >= 0)
313                 return value > 3900 ? true : false;
314
315         dev_err(ddata->dev, "error reading VBUS: %i\n", error);
316
317         return false;
318 }
319
320 /* VBUS control functions for the USB PHY companion */
321
322 static void cpcap_charger_vbus_work(struct work_struct *work)
323 {
324         struct cpcap_charger_ddata *ddata;
325         bool vbus = false;
326         int error;
327
328         ddata = container_of(work, struct cpcap_charger_ddata,
329                              vbus_work.work);
330
331         if (ddata->vbus_enabled) {
332                 vbus = cpcap_charger_vbus_valid(ddata);
333                 if (vbus) {
334                         dev_info(ddata->dev, "VBUS already provided\n");
335
336                         return;
337                 }
338
339                 cpcap_charger_set_cable_path(ddata, false);
340                 cpcap_charger_set_inductive_path(ddata, false);
341
342                 error = cpcap_charger_set_state(ddata, 0, 0, 0);
343                 if (error)
344                         goto out_err;
345
346                 error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
347                                            CPCAP_REG_CRM_RVRSMODE,
348                                            CPCAP_REG_CRM_RVRSMODE);
349                 if (error)
350                         goto out_err;
351         } else {
352                 error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
353                                            CPCAP_REG_CRM_RVRSMODE, 0);
354                 if (error)
355                         goto out_err;
356
357                 cpcap_charger_set_cable_path(ddata, true);
358                 cpcap_charger_set_inductive_path(ddata, true);
359         }
360
361         return;
362
363 out_err:
364         dev_err(ddata->dev, "%s could not %s vbus: %i\n", __func__,
365                 ddata->vbus_enabled ? "enable" : "disable", error);
366 }
367
368 static int cpcap_charger_set_vbus(struct phy_companion *comparator,
369                                   bool enabled)
370 {
371         struct cpcap_charger_ddata *ddata =
372                 container_of(comparator, struct cpcap_charger_ddata,
373                              comparator);
374
375         ddata->vbus_enabled = enabled;
376         schedule_delayed_work(&ddata->vbus_work, 0);
377
378         return 0;
379 }
380
381 /* Charger interrupt handling functions */
382
383 static int cpcap_charger_get_ints_state(struct cpcap_charger_ddata *ddata,
384                                         struct cpcap_charger_ints_state *s)
385 {
386         int val, error;
387
388         error = regmap_read(ddata->reg, CPCAP_REG_INTS1, &val);
389         if (error)
390                 return error;
391
392         s->chrg_det = val & BIT(13);
393         s->rvrs_chrg = val & BIT(12);
394         s->vbusov = val & BIT(11);
395
396         error = regmap_read(ddata->reg, CPCAP_REG_INTS2, &val);
397         if (error)
398                 return error;
399
400         s->chrg_se1b = val & BIT(13);
401         s->rvrs_mode = val & BIT(6);
402         s->chrgcurr1 = val & BIT(4);
403         s->vbusvld = val & BIT(3);
404
405         error = regmap_read(ddata->reg, CPCAP_REG_INTS4, &val);
406         if (error)
407                 return error;
408
409         s->battdetb = val & BIT(6);
410
411         return 0;
412 }
413
414 static void cpcap_usb_detect(struct work_struct *work)
415 {
416         struct cpcap_charger_ddata *ddata;
417         struct cpcap_charger_ints_state s;
418         int error;
419
420         ddata = container_of(work, struct cpcap_charger_ddata,
421                              detect_work.work);
422
423         error = cpcap_charger_get_ints_state(ddata, &s);
424         if (error)
425                 return;
426
427         if (cpcap_charger_vbus_valid(ddata) && s.chrgcurr1) {
428                 int max_current;
429
430                 if (cpcap_charger_battery_found(ddata))
431                         max_current = CPCAP_REG_CRM_ICHRG_1A584;
432                 else
433                         max_current = CPCAP_REG_CRM_ICHRG_0A528;
434
435                 error = cpcap_charger_set_state(ddata,
436                                                 CPCAP_REG_CRM_VCHRG_4V20,
437                                                 max_current,
438                                                 CPCAP_REG_CRM_TR_0A72);
439                 if (error)
440                         goto out_err;
441         } else {
442                 error = cpcap_charger_set_state(ddata, 0, 0, 0);
443                 if (error)
444                         goto out_err;
445         }
446
447         return;
448
449 out_err:
450         dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
451 }
452
453 static irqreturn_t cpcap_charger_irq_thread(int irq, void *data)
454 {
455         struct cpcap_charger_ddata *ddata = data;
456
457         if (!atomic_read(&ddata->active))
458                 return IRQ_NONE;
459
460         schedule_delayed_work(&ddata->detect_work, 0);
461
462         return IRQ_HANDLED;
463 }
464
465 static int cpcap_usb_init_irq(struct platform_device *pdev,
466                               struct cpcap_charger_ddata *ddata,
467                               const char *name)
468 {
469         struct cpcap_interrupt_desc *d;
470         int irq, error;
471
472         irq = platform_get_irq_byname(pdev, name);
473         if (!irq)
474                 return -ENODEV;
475
476         error = devm_request_threaded_irq(ddata->dev, irq, NULL,
477                                           cpcap_charger_irq_thread,
478                                           IRQF_SHARED,
479                                           name, ddata);
480         if (error) {
481                 dev_err(ddata->dev, "could not get irq %s: %i\n",
482                         name, error);
483
484                 return error;
485         }
486
487         d = devm_kzalloc(ddata->dev, sizeof(*d), GFP_KERNEL);
488         if (!d)
489                 return -ENOMEM;
490
491         d->name = name;
492         d->irq = irq;
493         list_add(&d->node, &ddata->irq_list);
494
495         return 0;
496 }
497
498 static const char * const cpcap_charger_irqs[] = {
499         /* REG_INT_0 */
500         "chrg_det", "rvrs_chrg",
501
502         /* REG_INT1 */
503         "chrg_se1b", "se0conn", "rvrs_mode", "chrgcurr1", "vbusvld",
504
505         /* REG_INT_3 */
506         "battdetb",
507 };
508
509 static int cpcap_usb_init_interrupts(struct platform_device *pdev,
510                                      struct cpcap_charger_ddata *ddata)
511 {
512         int i, error;
513
514         for (i = 0; i < ARRAY_SIZE(cpcap_charger_irqs); i++) {
515                 error = cpcap_usb_init_irq(pdev, ddata, cpcap_charger_irqs[i]);
516                 if (error)
517                         return error;
518         }
519
520         return 0;
521 }
522
523 static void cpcap_charger_init_optional_gpios(struct cpcap_charger_ddata *ddata)
524 {
525         int i;
526
527         for (i = 0; i < 2; i++) {
528                 ddata->gpio[i] = devm_gpiod_get_index(ddata->dev, "mode",
529                                                       i, GPIOD_OUT_HIGH);
530                 if (IS_ERR(ddata->gpio[i])) {
531                         dev_info(ddata->dev, "no mode change GPIO%i: %li\n",
532                                  i, PTR_ERR(ddata->gpio[i]));
533                                  ddata->gpio[i] = NULL;
534                 }
535         }
536 }
537
538 static int cpcap_charger_init_iio(struct cpcap_charger_ddata *ddata)
539 {
540         const char * const names[CPCAP_CHARGER_IIO_NR] = {
541                 "battdetb", "battp", "vbus", "chg_isense", "batti",
542         };
543         int error, i;
544
545         for (i = 0; i < CPCAP_CHARGER_IIO_NR; i++) {
546                 ddata->channels[i] = devm_iio_channel_get(ddata->dev,
547                                                           names[i]);
548                 if (IS_ERR(ddata->channels[i])) {
549                         error = PTR_ERR(ddata->channels[i]);
550                         goto out_err;
551                 }
552
553                 if (!ddata->channels[i]->indio_dev) {
554                         error = -ENXIO;
555                         goto out_err;
556                 }
557         }
558
559         return 0;
560
561 out_err:
562         dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n",
563                 error);
564
565         return error;
566 }
567
568 static const struct power_supply_desc cpcap_charger_usb_desc = {
569         .name           = "cpcap_usb",
570         .type           = POWER_SUPPLY_TYPE_USB,
571         .properties     = cpcap_charger_props,
572         .num_properties = ARRAY_SIZE(cpcap_charger_props),
573         .get_property   = cpcap_charger_get_property,
574 };
575
576 #ifdef CONFIG_OF
577 static const struct of_device_id cpcap_charger_id_table[] = {
578         {
579                 .compatible = "motorola,mapphone-cpcap-charger",
580         },
581         {},
582 };
583 MODULE_DEVICE_TABLE(of, cpcap_charger_id_table);
584 #endif
585
586 static int cpcap_charger_probe(struct platform_device *pdev)
587 {
588         struct cpcap_charger_ddata *ddata;
589         const struct of_device_id *of_id;
590         int error;
591
592         of_id = of_match_device(of_match_ptr(cpcap_charger_id_table),
593                                 &pdev->dev);
594         if (!of_id)
595                 return -EINVAL;
596
597         ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
598         if (!ddata)
599                 return -ENOMEM;
600
601         ddata->dev = &pdev->dev;
602
603         ddata->reg = dev_get_regmap(ddata->dev->parent, NULL);
604         if (!ddata->reg)
605                 return -ENODEV;
606
607         INIT_LIST_HEAD(&ddata->irq_list);
608         INIT_DELAYED_WORK(&ddata->detect_work, cpcap_usb_detect);
609         INIT_DELAYED_WORK(&ddata->vbus_work, cpcap_charger_vbus_work);
610         platform_set_drvdata(pdev, ddata);
611
612         error = cpcap_charger_init_iio(ddata);
613         if (error)
614                 return error;
615
616         atomic_set(&ddata->active, 1);
617
618         ddata->usb = devm_power_supply_register(ddata->dev,
619                                                 &cpcap_charger_usb_desc,
620                                                 NULL);
621         if (IS_ERR(ddata->usb)) {
622                 error = PTR_ERR(ddata->usb);
623                 dev_err(ddata->dev, "failed to register USB charger: %i\n",
624                         error);
625
626                 return error;
627         }
628
629         error = cpcap_usb_init_interrupts(pdev, ddata);
630         if (error)
631                 return error;
632
633         ddata->comparator.set_vbus = cpcap_charger_set_vbus;
634         error = omap_usb2_set_comparator(&ddata->comparator);
635         if (error == -ENODEV) {
636                 dev_info(ddata->dev, "charger needs phy, deferring probe\n");
637                 return -EPROBE_DEFER;
638         }
639
640         cpcap_charger_init_optional_gpios(ddata);
641
642         schedule_delayed_work(&ddata->detect_work, 0);
643
644         return 0;
645 }
646
647 static int cpcap_charger_remove(struct platform_device *pdev)
648 {
649         struct cpcap_charger_ddata *ddata = platform_get_drvdata(pdev);
650         int error;
651
652         atomic_set(&ddata->active, 0);
653         error = omap_usb2_set_comparator(NULL);
654         if (error)
655                 dev_warn(ddata->dev, "could not clear USB comparator: %i\n",
656                          error);
657
658         error = cpcap_charger_set_state(ddata, 0, 0, 0);
659         if (error)
660                 dev_warn(ddata->dev, "could not clear charger: %i\n",
661                          error);
662         cancel_delayed_work_sync(&ddata->vbus_work);
663         cancel_delayed_work_sync(&ddata->detect_work);
664
665         return 0;
666 }
667
668 static struct platform_driver cpcap_charger_driver = {
669         .probe = cpcap_charger_probe,
670         .driver = {
671                 .name   = "cpcap-charger",
672                 .of_match_table = of_match_ptr(cpcap_charger_id_table),
673         },
674         .remove = cpcap_charger_remove,
675 };
676 module_platform_driver(cpcap_charger_driver);
677
678 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
679 MODULE_DESCRIPTION("CPCAP Battery Charger Interface driver");
680 MODULE_LICENSE("GPL v2");
681 MODULE_ALIAS("platform:cpcap-charger");