Merge tag 'rtc-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
[linux-2.6-microblaze.git] / drivers / power / supply / da9150-charger.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * DA9150 Charger Driver
4  *
5  * Copyright (c) 2014 Dialog Semiconductor
6  *
7  * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/of.h>
15 #include <linux/of_platform.h>
16 #include <linux/interrupt.h>
17 #include <linux/power_supply.h>
18 #include <linux/notifier.h>
19 #include <linux/usb/phy.h>
20 #include <linux/iio/consumer.h>
21 #include <linux/mfd/da9150/core.h>
22 #include <linux/mfd/da9150/registers.h>
23
24 /* Private data */
25 struct da9150_charger {
26         struct da9150 *da9150;
27         struct device *dev;
28
29         struct power_supply *usb;
30         struct power_supply *battery;
31         struct power_supply *supply_online;
32
33         struct usb_phy *usb_phy;
34         struct notifier_block otg_nb;
35         struct work_struct otg_work;
36         unsigned long usb_event;
37
38         struct iio_channel *ibus_chan;
39         struct iio_channel *vbus_chan;
40         struct iio_channel *tjunc_chan;
41         struct iio_channel *vbat_chan;
42 };
43
44 static inline int da9150_charger_supply_online(struct da9150_charger *charger,
45                                                struct power_supply *psy,
46                                                union power_supply_propval *val)
47 {
48         val->intval = (psy == charger->supply_online) ? 1 : 0;
49
50         return 0;
51 }
52
53 /* Charger Properties */
54 static int da9150_charger_vbus_voltage_now(struct da9150_charger *charger,
55                                            union power_supply_propval *val)
56 {
57         int v_val, ret;
58
59         /* Read processed value - mV units */
60         ret = iio_read_channel_processed(charger->vbus_chan, &v_val);
61         if (ret < 0)
62                 return ret;
63
64         /* Convert voltage to expected uV units */
65         val->intval = v_val * 1000;
66
67         return 0;
68 }
69
70 static int da9150_charger_ibus_current_avg(struct da9150_charger *charger,
71                                            union power_supply_propval *val)
72 {
73         int i_val, ret;
74
75         /* Read processed value - mA units */
76         ret = iio_read_channel_processed(charger->ibus_chan, &i_val);
77         if (ret < 0)
78                 return ret;
79
80         /* Convert current to expected uA units */
81         val->intval = i_val * 1000;
82
83         return 0;
84 }
85
86 static int da9150_charger_tjunc_temp(struct da9150_charger *charger,
87                                      union power_supply_propval *val)
88 {
89         int t_val, ret;
90
91         /* Read processed value - 0.001 degrees C units */
92         ret = iio_read_channel_processed(charger->tjunc_chan, &t_val);
93         if (ret < 0)
94                 return ret;
95
96         /* Convert temp to expect 0.1 degrees C units */
97         val->intval = t_val / 100;
98
99         return 0;
100 }
101
102 static enum power_supply_property da9150_charger_props[] = {
103         POWER_SUPPLY_PROP_ONLINE,
104         POWER_SUPPLY_PROP_VOLTAGE_NOW,
105         POWER_SUPPLY_PROP_CURRENT_AVG,
106         POWER_SUPPLY_PROP_TEMP,
107 };
108
109 static int da9150_charger_get_prop(struct power_supply *psy,
110                                    enum power_supply_property psp,
111                                    union power_supply_propval *val)
112 {
113         struct da9150_charger *charger = dev_get_drvdata(psy->dev.parent);
114         int ret;
115
116         switch (psp) {
117         case POWER_SUPPLY_PROP_ONLINE:
118                 ret = da9150_charger_supply_online(charger, psy, val);
119                 break;
120         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
121                 ret = da9150_charger_vbus_voltage_now(charger, val);
122                 break;
123         case POWER_SUPPLY_PROP_CURRENT_AVG:
124                 ret = da9150_charger_ibus_current_avg(charger, val);
125                 break;
126         case POWER_SUPPLY_PROP_TEMP:
127                 ret = da9150_charger_tjunc_temp(charger, val);
128                 break;
129         default:
130                 ret = -EINVAL;
131                 break;
132         }
133
134         return ret;
135 }
136
137 /* Battery Properties */
138 static int da9150_charger_battery_status(struct da9150_charger *charger,
139                                          union power_supply_propval *val)
140 {
141         u8 reg;
142
143         /* Check to see if battery is discharging */
144         reg = da9150_reg_read(charger->da9150, DA9150_STATUS_H);
145
146         if (((reg & DA9150_VBUS_STAT_MASK) == DA9150_VBUS_STAT_OFF) ||
147             ((reg & DA9150_VBUS_STAT_MASK) == DA9150_VBUS_STAT_WAIT)) {
148                 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
149
150                 return 0;
151         }
152
153         reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J);
154
155         /* Now check for other states */
156         switch (reg & DA9150_CHG_STAT_MASK) {
157         case DA9150_CHG_STAT_ACT:
158         case DA9150_CHG_STAT_PRE:
159         case DA9150_CHG_STAT_CC:
160         case DA9150_CHG_STAT_CV:
161                 val->intval = POWER_SUPPLY_STATUS_CHARGING;
162                 break;
163         case DA9150_CHG_STAT_OFF:
164         case DA9150_CHG_STAT_SUSP:
165         case DA9150_CHG_STAT_TEMP:
166         case DA9150_CHG_STAT_TIME:
167         case DA9150_CHG_STAT_BAT:
168                 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
169                 break;
170         case DA9150_CHG_STAT_FULL:
171                 val->intval = POWER_SUPPLY_STATUS_FULL;
172                 break;
173         default:
174                 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
175                 break;
176         }
177
178         return 0;
179 }
180
181 static int da9150_charger_battery_health(struct da9150_charger *charger,
182                                          union power_supply_propval *val)
183 {
184         u8 reg;
185
186         reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J);
187
188         /* Check if temperature limit reached */
189         switch (reg & DA9150_CHG_TEMP_MASK) {
190         case DA9150_CHG_TEMP_UNDER:
191                 val->intval = POWER_SUPPLY_HEALTH_COLD;
192                 return 0;
193         case DA9150_CHG_TEMP_OVER:
194                 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
195                 return 0;
196         default:
197                 break;
198         }
199
200         /* Check for other health states */
201         switch (reg & DA9150_CHG_STAT_MASK) {
202         case DA9150_CHG_STAT_ACT:
203         case DA9150_CHG_STAT_PRE:
204                 val->intval = POWER_SUPPLY_HEALTH_DEAD;
205                 break;
206         case DA9150_CHG_STAT_TIME:
207                 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
208                 break;
209         default:
210                 val->intval = POWER_SUPPLY_HEALTH_GOOD;
211                 break;
212         }
213
214         return 0;
215 }
216
217 static int da9150_charger_battery_present(struct da9150_charger *charger,
218                                           union power_supply_propval *val)
219 {
220         u8 reg;
221
222         /* Check if battery present or removed */
223         reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J);
224         if ((reg & DA9150_CHG_STAT_MASK) == DA9150_CHG_STAT_BAT)
225                 val->intval = 0;
226         else
227                 val->intval = 1;
228
229         return 0;
230 }
231
232 static int da9150_charger_battery_charge_type(struct da9150_charger *charger,
233                                               union power_supply_propval *val)
234 {
235         u8 reg;
236
237         reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J);
238
239         switch (reg & DA9150_CHG_STAT_MASK) {
240         case DA9150_CHG_STAT_CC:
241                 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
242                 break;
243         case DA9150_CHG_STAT_ACT:
244         case DA9150_CHG_STAT_PRE:
245         case DA9150_CHG_STAT_CV:
246                 val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
247                 break;
248         default:
249                 val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
250                 break;
251         }
252
253         return 0;
254 }
255
256 static int da9150_charger_battery_voltage_min(struct da9150_charger *charger,
257                                               union power_supply_propval *val)
258 {
259         u8 reg;
260
261         reg = da9150_reg_read(charger->da9150, DA9150_PPR_CHGCTRL_C);
262
263         /* Value starts at 2500 mV, 50 mV increments, presented in uV */
264         val->intval = ((reg & DA9150_CHG_VFAULT_MASK) * 50000) + 2500000;
265
266         return 0;
267 }
268
269 static int da9150_charger_battery_voltage_now(struct da9150_charger *charger,
270                                               union power_supply_propval *val)
271 {
272         int v_val, ret;
273
274         /* Read processed value - mV units */
275         ret = iio_read_channel_processed(charger->vbat_chan, &v_val);
276         if (ret < 0)
277                 return ret;
278
279         val->intval = v_val * 1000;
280
281         return 0;
282 }
283
284 static int da9150_charger_battery_current_max(struct da9150_charger *charger,
285                                               union power_supply_propval *val)
286 {
287         int reg;
288
289         reg = da9150_reg_read(charger->da9150, DA9150_PPR_CHGCTRL_D);
290
291         /* 25mA increments */
292         val->intval = reg * 25000;
293
294         return 0;
295 }
296
297 static int da9150_charger_battery_voltage_max(struct da9150_charger *charger,
298                                               union power_supply_propval *val)
299 {
300         u8 reg;
301
302         reg = da9150_reg_read(charger->da9150, DA9150_PPR_CHGCTRL_B);
303
304         /* Value starts at 3650 mV, 25 mV increments, presented in uV */
305         val->intval = ((reg & DA9150_CHG_VBAT_MASK) * 25000) + 3650000;
306         return 0;
307 }
308
309 static enum power_supply_property da9150_charger_bat_props[] = {
310         POWER_SUPPLY_PROP_STATUS,
311         POWER_SUPPLY_PROP_ONLINE,
312         POWER_SUPPLY_PROP_HEALTH,
313         POWER_SUPPLY_PROP_PRESENT,
314         POWER_SUPPLY_PROP_CHARGE_TYPE,
315         POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
316         POWER_SUPPLY_PROP_VOLTAGE_NOW,
317         POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
318         POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
319 };
320
321 static int da9150_charger_battery_get_prop(struct power_supply *psy,
322                                            enum power_supply_property psp,
323                                            union power_supply_propval *val)
324 {
325         struct da9150_charger *charger = dev_get_drvdata(psy->dev.parent);
326         int ret;
327
328         switch (psp) {
329         case POWER_SUPPLY_PROP_STATUS:
330                 ret = da9150_charger_battery_status(charger, val);
331                 break;
332         case POWER_SUPPLY_PROP_ONLINE:
333                 ret = da9150_charger_supply_online(charger, psy, val);
334                 break;
335         case POWER_SUPPLY_PROP_HEALTH:
336                 ret = da9150_charger_battery_health(charger, val);
337                 break;
338         case POWER_SUPPLY_PROP_PRESENT:
339                 ret = da9150_charger_battery_present(charger, val);
340                 break;
341         case POWER_SUPPLY_PROP_CHARGE_TYPE:
342                 ret = da9150_charger_battery_charge_type(charger, val);
343                 break;
344         case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
345                 ret = da9150_charger_battery_voltage_min(charger, val);
346                 break;
347         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
348                 ret = da9150_charger_battery_voltage_now(charger, val);
349                 break;
350         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
351                 ret = da9150_charger_battery_current_max(charger, val);
352                 break;
353         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
354                 ret = da9150_charger_battery_voltage_max(charger, val);
355                 break;
356         default:
357                 ret = -EINVAL;
358                 break;
359         }
360
361         return ret;
362 }
363
364 static irqreturn_t da9150_charger_chg_irq(int irq, void *data)
365 {
366         struct da9150_charger *charger = data;
367
368         power_supply_changed(charger->battery);
369
370         return IRQ_HANDLED;
371 }
372
373 static irqreturn_t da9150_charger_tjunc_irq(int irq, void *data)
374 {
375         struct da9150_charger *charger = data;
376
377         /* Nothing we can really do except report this. */
378         dev_crit(charger->dev, "TJunc over temperature!!!\n");
379         power_supply_changed(charger->usb);
380
381         return IRQ_HANDLED;
382 }
383
384 static irqreturn_t da9150_charger_vfault_irq(int irq, void *data)
385 {
386         struct da9150_charger *charger = data;
387
388         /* Nothing we can really do except report this. */
389         dev_crit(charger->dev, "VSYS under voltage!!!\n");
390         power_supply_changed(charger->usb);
391         power_supply_changed(charger->battery);
392
393         return IRQ_HANDLED;
394 }
395
396 static irqreturn_t da9150_charger_vbus_irq(int irq, void *data)
397 {
398         struct da9150_charger *charger = data;
399         u8 reg;
400
401         reg = da9150_reg_read(charger->da9150, DA9150_STATUS_H);
402
403         /* Charger plugged in or battery only */
404         switch (reg & DA9150_VBUS_STAT_MASK) {
405         case DA9150_VBUS_STAT_OFF:
406         case DA9150_VBUS_STAT_WAIT:
407                 charger->supply_online = charger->battery;
408                 break;
409         case DA9150_VBUS_STAT_CHG:
410                 charger->supply_online = charger->usb;
411                 break;
412         default:
413                 dev_warn(charger->dev, "Unknown VBUS state - reg = 0x%x\n",
414                          reg);
415                 charger->supply_online = NULL;
416                 break;
417         }
418
419         power_supply_changed(charger->usb);
420         power_supply_changed(charger->battery);
421
422         return IRQ_HANDLED;
423 }
424
425 static void da9150_charger_otg_work(struct work_struct *data)
426 {
427         struct da9150_charger *charger =
428                 container_of(data, struct da9150_charger, otg_work);
429
430         switch (charger->usb_event) {
431         case USB_EVENT_ID:
432                 /* Enable OTG Boost */
433                 da9150_set_bits(charger->da9150, DA9150_PPR_BKCTRL_A,
434                                 DA9150_VBUS_MODE_MASK, DA9150_VBUS_MODE_OTG);
435                 break;
436         case USB_EVENT_NONE:
437                 /* Revert to charge mode */
438                 power_supply_changed(charger->usb);
439                 power_supply_changed(charger->battery);
440                 da9150_set_bits(charger->da9150, DA9150_PPR_BKCTRL_A,
441                                 DA9150_VBUS_MODE_MASK, DA9150_VBUS_MODE_CHG);
442                 break;
443         }
444 }
445
446 static int da9150_charger_otg_ncb(struct notifier_block *nb, unsigned long val,
447                                   void *priv)
448 {
449         struct da9150_charger *charger =
450                 container_of(nb, struct da9150_charger, otg_nb);
451
452         dev_dbg(charger->dev, "DA9150 OTG notify %lu\n", val);
453
454         charger->usb_event = val;
455         schedule_work(&charger->otg_work);
456
457         return NOTIFY_OK;
458 }
459
460 static int da9150_charger_register_irq(struct platform_device *pdev,
461                                        irq_handler_t handler,
462                                        const char *irq_name)
463 {
464         struct device *dev = &pdev->dev;
465         struct da9150_charger *charger = platform_get_drvdata(pdev);
466         int irq, ret;
467
468         irq = platform_get_irq_byname(pdev, irq_name);
469         if (irq < 0) {
470                 dev_err(dev, "Failed to get IRQ CHG_STATUS: %d\n", irq);
471                 return irq;
472         }
473
474         ret = request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, irq_name,
475                                    charger);
476         if (ret)
477                 dev_err(dev, "Failed to request IRQ %d: %d\n", irq, ret);
478
479         return ret;
480 }
481
482 static void da9150_charger_unregister_irq(struct platform_device *pdev,
483                                           const char *irq_name)
484 {
485         struct device *dev = &pdev->dev;
486         struct da9150_charger *charger = platform_get_drvdata(pdev);
487         int irq;
488
489         irq = platform_get_irq_byname(pdev, irq_name);
490         if (irq < 0) {
491                 dev_err(dev, "Failed to get IRQ CHG_STATUS: %d\n", irq);
492                 return;
493         }
494
495         free_irq(irq, charger);
496 }
497
498 static const struct power_supply_desc usb_desc = {
499         .name           = "da9150-usb",
500         .type           = POWER_SUPPLY_TYPE_USB,
501         .properties     = da9150_charger_props,
502         .num_properties = ARRAY_SIZE(da9150_charger_props),
503         .get_property   = da9150_charger_get_prop,
504 };
505
506 static const struct power_supply_desc battery_desc = {
507         .name           = "da9150-battery",
508         .type           = POWER_SUPPLY_TYPE_BATTERY,
509         .properties     = da9150_charger_bat_props,
510         .num_properties = ARRAY_SIZE(da9150_charger_bat_props),
511         .get_property   = da9150_charger_battery_get_prop,
512 };
513
514 static int da9150_charger_probe(struct platform_device *pdev)
515 {
516         struct device *dev = &pdev->dev;
517         struct da9150 *da9150 = dev_get_drvdata(dev->parent);
518         struct da9150_charger *charger;
519         u8 reg;
520         int ret;
521
522         charger = devm_kzalloc(dev, sizeof(struct da9150_charger), GFP_KERNEL);
523         if (!charger)
524                 return -ENOMEM;
525
526         platform_set_drvdata(pdev, charger);
527         charger->da9150 = da9150;
528         charger->dev = dev;
529
530         /* Acquire ADC channels */
531         charger->ibus_chan = iio_channel_get(dev, "CHAN_IBUS");
532         if (IS_ERR(charger->ibus_chan)) {
533                 ret = PTR_ERR(charger->ibus_chan);
534                 goto ibus_chan_fail;
535         }
536
537         charger->vbus_chan = iio_channel_get(dev, "CHAN_VBUS");
538         if (IS_ERR(charger->vbus_chan)) {
539                 ret = PTR_ERR(charger->vbus_chan);
540                 goto vbus_chan_fail;
541         }
542
543         charger->tjunc_chan = iio_channel_get(dev, "CHAN_TJUNC");
544         if (IS_ERR(charger->tjunc_chan)) {
545                 ret = PTR_ERR(charger->tjunc_chan);
546                 goto tjunc_chan_fail;
547         }
548
549         charger->vbat_chan = iio_channel_get(dev, "CHAN_VBAT");
550         if (IS_ERR(charger->vbat_chan)) {
551                 ret = PTR_ERR(charger->vbat_chan);
552                 goto vbat_chan_fail;
553         }
554
555         /* Register power supplies */
556         charger->usb = power_supply_register(dev, &usb_desc, NULL);
557         if (IS_ERR(charger->usb)) {
558                 ret = PTR_ERR(charger->usb);
559                 goto usb_fail;
560         }
561
562         charger->battery = power_supply_register(dev, &battery_desc, NULL);
563         if (IS_ERR(charger->battery)) {
564                 ret = PTR_ERR(charger->battery);
565                 goto battery_fail;
566         }
567
568         /* Get initial online supply */
569         reg = da9150_reg_read(da9150, DA9150_STATUS_H);
570
571         switch (reg & DA9150_VBUS_STAT_MASK) {
572         case DA9150_VBUS_STAT_OFF:
573         case DA9150_VBUS_STAT_WAIT:
574                 charger->supply_online = charger->battery;
575                 break;
576         case DA9150_VBUS_STAT_CHG:
577                 charger->supply_online = charger->usb;
578                 break;
579         default:
580                 dev_warn(dev, "Unknown VBUS state - reg = 0x%x\n", reg);
581                 charger->supply_online = NULL;
582                 break;
583         }
584
585         /* Setup OTG reporting & configuration */
586         charger->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
587         if (!IS_ERR_OR_NULL(charger->usb_phy)) {
588                 INIT_WORK(&charger->otg_work, da9150_charger_otg_work);
589                 charger->otg_nb.notifier_call = da9150_charger_otg_ncb;
590                 usb_register_notifier(charger->usb_phy, &charger->otg_nb);
591         }
592
593         /* Register IRQs */
594         ret = da9150_charger_register_irq(pdev, da9150_charger_chg_irq,
595                                           "CHG_STATUS");
596         if (ret < 0)
597                 goto chg_irq_fail;
598
599         ret = da9150_charger_register_irq(pdev, da9150_charger_tjunc_irq,
600                                           "CHG_TJUNC");
601         if (ret < 0)
602                 goto tjunc_irq_fail;
603
604         ret = da9150_charger_register_irq(pdev, da9150_charger_vfault_irq,
605                                           "CHG_VFAULT");
606         if (ret < 0)
607                 goto vfault_irq_fail;
608
609         ret = da9150_charger_register_irq(pdev, da9150_charger_vbus_irq,
610                                           "CHG_VBUS");
611         if (ret < 0)
612                 goto vbus_irq_fail;
613
614         return 0;
615
616
617 vbus_irq_fail:
618         da9150_charger_unregister_irq(pdev, "CHG_VFAULT");
619 vfault_irq_fail:
620         da9150_charger_unregister_irq(pdev, "CHG_TJUNC");
621 tjunc_irq_fail:
622         da9150_charger_unregister_irq(pdev, "CHG_STATUS");
623 chg_irq_fail:
624         if (!IS_ERR_OR_NULL(charger->usb_phy))
625                 usb_unregister_notifier(charger->usb_phy, &charger->otg_nb);
626 battery_fail:
627         power_supply_unregister(charger->usb);
628
629 usb_fail:
630         iio_channel_release(charger->vbat_chan);
631
632 vbat_chan_fail:
633         iio_channel_release(charger->tjunc_chan);
634
635 tjunc_chan_fail:
636         iio_channel_release(charger->vbus_chan);
637
638 vbus_chan_fail:
639         iio_channel_release(charger->ibus_chan);
640
641 ibus_chan_fail:
642         return ret;
643 }
644
645 static int da9150_charger_remove(struct platform_device *pdev)
646 {
647         struct da9150_charger *charger = platform_get_drvdata(pdev);
648         int irq;
649
650         /* Make sure IRQs are released before unregistering power supplies */
651         irq = platform_get_irq_byname(pdev, "CHG_VBUS");
652         free_irq(irq, charger);
653
654         irq = platform_get_irq_byname(pdev, "CHG_VFAULT");
655         free_irq(irq, charger);
656
657         irq = platform_get_irq_byname(pdev, "CHG_TJUNC");
658         free_irq(irq, charger);
659
660         irq = platform_get_irq_byname(pdev, "CHG_STATUS");
661         free_irq(irq, charger);
662
663         if (!IS_ERR_OR_NULL(charger->usb_phy))
664                 usb_unregister_notifier(charger->usb_phy, &charger->otg_nb);
665
666         power_supply_unregister(charger->battery);
667         power_supply_unregister(charger->usb);
668
669         /* Release ADC channels */
670         iio_channel_release(charger->ibus_chan);
671         iio_channel_release(charger->vbus_chan);
672         iio_channel_release(charger->tjunc_chan);
673         iio_channel_release(charger->vbat_chan);
674
675         return 0;
676 }
677
678 static struct platform_driver da9150_charger_driver = {
679         .driver = {
680                 .name = "da9150-charger",
681         },
682         .probe = da9150_charger_probe,
683         .remove = da9150_charger_remove,
684 };
685
686 module_platform_driver(da9150_charger_driver);
687
688 MODULE_DESCRIPTION("Charger Driver for DA9150");
689 MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
690 MODULE_LICENSE("GPL");