arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / drivers / power / supply / act8945a_charger.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Power supply driver for the Active-semi ACT8945A PMIC
4  *
5  * Copyright (C) 2015 Atmel Corporation
6  *
7  * Author: Wenyou Yang <wenyou.yang@atmel.com>
8  */
9 #include <linux/interrupt.h>
10 #include <linux/module.h>
11 #include <linux/of.h>
12 #include <linux/of_irq.h>
13 #include <linux/platform_device.h>
14 #include <linux/power_supply.h>
15 #include <linux/regmap.h>
16 #include <linux/gpio/consumer.h>
17
18 static const char *act8945a_charger_model = "ACT8945A";
19 static const char *act8945a_charger_manufacturer = "Active-semi";
20
21 /*
22  * ACT8945A Charger Register Map
23  */
24
25 /* 0x70: Reserved */
26 #define ACT8945A_APCH_CFG               0x71
27 #define ACT8945A_APCH_STATUS            0x78
28 #define ACT8945A_APCH_CTRL              0x79
29 #define ACT8945A_APCH_STATE             0x7A
30
31 /* ACT8945A_APCH_CFG */
32 #define APCH_CFG_OVPSET                 (0x3 << 0)
33 #define APCH_CFG_OVPSET_6V6             (0x0 << 0)
34 #define APCH_CFG_OVPSET_7V              (0x1 << 0)
35 #define APCH_CFG_OVPSET_7V5             (0x2 << 0)
36 #define APCH_CFG_OVPSET_8V              (0x3 << 0)
37 #define APCH_CFG_PRETIMO                (0x3 << 2)
38 #define APCH_CFG_PRETIMO_40_MIN         (0x0 << 2)
39 #define APCH_CFG_PRETIMO_60_MIN         (0x1 << 2)
40 #define APCH_CFG_PRETIMO_80_MIN         (0x2 << 2)
41 #define APCH_CFG_PRETIMO_DISABLED       (0x3 << 2)
42 #define APCH_CFG_TOTTIMO                (0x3 << 4)
43 #define APCH_CFG_TOTTIMO_3_HOUR         (0x0 << 4)
44 #define APCH_CFG_TOTTIMO_4_HOUR         (0x1 << 4)
45 #define APCH_CFG_TOTTIMO_5_HOUR         (0x2 << 4)
46 #define APCH_CFG_TOTTIMO_DISABLED       (0x3 << 4)
47 #define APCH_CFG_SUSCHG                 (0x1 << 7)
48
49 #define APCH_STATUS_CHGDAT              BIT(0)
50 #define APCH_STATUS_INDAT               BIT(1)
51 #define APCH_STATUS_TEMPDAT             BIT(2)
52 #define APCH_STATUS_TIMRDAT             BIT(3)
53 #define APCH_STATUS_CHGSTAT             BIT(4)
54 #define APCH_STATUS_INSTAT              BIT(5)
55 #define APCH_STATUS_TEMPSTAT            BIT(6)
56 #define APCH_STATUS_TIMRSTAT            BIT(7)
57
58 #define APCH_CTRL_CHGEOCOUT             BIT(0)
59 #define APCH_CTRL_INDIS                 BIT(1)
60 #define APCH_CTRL_TEMPOUT               BIT(2)
61 #define APCH_CTRL_TIMRPRE               BIT(3)
62 #define APCH_CTRL_CHGEOCIN              BIT(4)
63 #define APCH_CTRL_INCON                 BIT(5)
64 #define APCH_CTRL_TEMPIN                BIT(6)
65 #define APCH_CTRL_TIMRTOT               BIT(7)
66
67 #define APCH_STATE_ACINSTAT             (0x1 << 1)
68 #define APCH_STATE_CSTATE               (0x3 << 4)
69 #define APCH_STATE_CSTATE_SHIFT         4
70 #define APCH_STATE_CSTATE_DISABLED      0x00
71 #define APCH_STATE_CSTATE_EOC           0x01
72 #define APCH_STATE_CSTATE_FAST          0x02
73 #define APCH_STATE_CSTATE_PRE           0x03
74
75 struct act8945a_charger {
76         struct power_supply *psy;
77         struct power_supply_desc desc;
78         struct regmap *regmap;
79         struct work_struct work;
80
81         bool init_done;
82         struct gpio_desc *lbo_gpio;
83         struct gpio_desc *chglev_gpio;
84 };
85
86 static int act8945a_get_charger_state(struct regmap *regmap, int *val)
87 {
88         int ret;
89         unsigned int status, state;
90
91         ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
92         if (ret < 0)
93                 return ret;
94
95         ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
96         if (ret < 0)
97                 return ret;
98
99         state &= APCH_STATE_CSTATE;
100         state >>= APCH_STATE_CSTATE_SHIFT;
101
102         switch (state) {
103         case APCH_STATE_CSTATE_PRE:
104         case APCH_STATE_CSTATE_FAST:
105                 *val = POWER_SUPPLY_STATUS_CHARGING;
106                 break;
107         case APCH_STATE_CSTATE_EOC:
108                 if (status & APCH_STATUS_CHGDAT)
109                         *val = POWER_SUPPLY_STATUS_FULL;
110                 else
111                         *val = POWER_SUPPLY_STATUS_CHARGING;
112                 break;
113         case APCH_STATE_CSTATE_DISABLED:
114         default:
115                 if (!(status & APCH_STATUS_INDAT))
116                         *val = POWER_SUPPLY_STATUS_DISCHARGING;
117                 else
118                         *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
119                 break;
120         }
121
122         return 0;
123 }
124
125 static int act8945a_get_charge_type(struct regmap *regmap, int *val)
126 {
127         int ret;
128         unsigned int status, state;
129
130         ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
131         if (ret < 0)
132                 return ret;
133
134         ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
135         if (ret < 0)
136                 return ret;
137
138         state &= APCH_STATE_CSTATE;
139         state >>= APCH_STATE_CSTATE_SHIFT;
140
141         switch (state) {
142         case APCH_STATE_CSTATE_PRE:
143                 *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
144                 break;
145         case APCH_STATE_CSTATE_FAST:
146                 *val = POWER_SUPPLY_CHARGE_TYPE_FAST;
147                 break;
148         case APCH_STATE_CSTATE_EOC:
149                 *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
150                 break;
151         case APCH_STATE_CSTATE_DISABLED:
152         default:
153                 if (!(status & APCH_STATUS_INDAT))
154                         *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
155                 else
156                         *val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
157                 break;
158         }
159
160         return 0;
161 }
162
163 static int act8945a_get_battery_health(struct regmap *regmap, int *val)
164 {
165         int ret;
166         unsigned int status, state, config;
167
168         ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
169         if (ret < 0)
170                 return ret;
171
172         ret = regmap_read(regmap, ACT8945A_APCH_CFG, &config);
173         if (ret < 0)
174                 return ret;
175
176         ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
177         if (ret < 0)
178                 return ret;
179
180         state &= APCH_STATE_CSTATE;
181         state >>= APCH_STATE_CSTATE_SHIFT;
182
183         switch (state) {
184         case APCH_STATE_CSTATE_DISABLED:
185                 if (config & APCH_CFG_SUSCHG) {
186                         *val = POWER_SUPPLY_HEALTH_UNKNOWN;
187                 } else if (status & APCH_STATUS_INDAT) {
188                         if (!(status & APCH_STATUS_TEMPDAT))
189                                 *val = POWER_SUPPLY_HEALTH_OVERHEAT;
190                         else if (status & APCH_STATUS_TIMRDAT)
191                                 *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
192                         else
193                                 *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
194                 } else {
195                         *val = POWER_SUPPLY_HEALTH_GOOD;
196                 }
197                 break;
198         case APCH_STATE_CSTATE_PRE:
199         case APCH_STATE_CSTATE_FAST:
200         case APCH_STATE_CSTATE_EOC:
201         default:
202                 *val = POWER_SUPPLY_HEALTH_GOOD;
203                 break;
204         }
205
206         return 0;
207 }
208
209 static int act8945a_get_capacity_level(struct act8945a_charger *charger,
210                                        struct regmap *regmap, int *val)
211 {
212         int ret;
213         unsigned int status, state, config;
214         int lbo_level = gpiod_get_value(charger->lbo_gpio);
215
216         ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
217         if (ret < 0)
218                 return ret;
219
220         ret = regmap_read(regmap, ACT8945A_APCH_CFG, &config);
221         if (ret < 0)
222                 return ret;
223
224         ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
225         if (ret < 0)
226                 return ret;
227
228         state &= APCH_STATE_CSTATE;
229         state >>= APCH_STATE_CSTATE_SHIFT;
230
231         switch (state) {
232         case APCH_STATE_CSTATE_PRE:
233                 *val = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
234                 break;
235         case APCH_STATE_CSTATE_FAST:
236                 if (lbo_level)
237                         *val = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
238                 else
239                         *val = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
240                 break;
241         case APCH_STATE_CSTATE_EOC:
242                 if (status & APCH_STATUS_CHGDAT)
243                         *val = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
244                 else
245                         *val = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
246                 break;
247         case APCH_STATE_CSTATE_DISABLED:
248         default:
249                 if (config & APCH_CFG_SUSCHG) {
250                         *val = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
251                 } else {
252                         *val = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
253                         if (!(status & APCH_STATUS_INDAT)) {
254                                 if (!lbo_level)
255                                         *val = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
256                         }
257                 }
258                 break;
259         }
260
261         return 0;
262 }
263
264 #define MAX_CURRENT_USB_HIGH    450000
265 #define MAX_CURRENT_USB_LOW     90000
266 #define MAX_CURRENT_USB_PRE     45000
267 /*
268  * Riset(K) = 2336 * (1V/Ichg(mA)) - 0.205
269  * Riset = 2.43K
270  */
271 #define MAX_CURRENT_AC_HIGH             886527
272 #define MAX_CURRENT_AC_LOW              117305
273 #define MAX_CURRENT_AC_HIGH_PRE         88653
274 #define MAX_CURRENT_AC_LOW_PRE          11731
275
276 static int act8945a_get_current_max(struct act8945a_charger *charger,
277                                     struct regmap *regmap, int *val)
278 {
279         int ret;
280         unsigned int status, state;
281         unsigned int acin_state;
282         int chgin_level = gpiod_get_value(charger->chglev_gpio);
283
284         ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
285         if (ret < 0)
286                 return ret;
287
288         ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
289         if (ret < 0)
290                 return ret;
291
292         acin_state = (state & APCH_STATE_ACINSTAT) >> 1;
293
294         state &= APCH_STATE_CSTATE;
295         state >>= APCH_STATE_CSTATE_SHIFT;
296
297         switch (state) {
298         case APCH_STATE_CSTATE_PRE:
299                 if (acin_state) {
300                         if (chgin_level)
301                                 *val = MAX_CURRENT_AC_HIGH_PRE;
302                         else
303                                 *val = MAX_CURRENT_AC_LOW_PRE;
304                 } else {
305                         *val = MAX_CURRENT_USB_PRE;
306                 }
307                 break;
308         case APCH_STATE_CSTATE_FAST:
309                 if (acin_state) {
310                         if (chgin_level)
311                                 *val = MAX_CURRENT_AC_HIGH;
312                         else
313                                 *val = MAX_CURRENT_AC_LOW;
314                 } else {
315                         if (chgin_level)
316                                 *val = MAX_CURRENT_USB_HIGH;
317                         else
318                                 *val = MAX_CURRENT_USB_LOW;
319                 }
320                 break;
321         case APCH_STATE_CSTATE_EOC:
322         case APCH_STATE_CSTATE_DISABLED:
323         default:
324                 *val = 0;
325                 break;
326         }
327
328         return 0;
329 }
330
331 static enum power_supply_property act8945a_charger_props[] = {
332         POWER_SUPPLY_PROP_STATUS,
333         POWER_SUPPLY_PROP_CHARGE_TYPE,
334         POWER_SUPPLY_PROP_TECHNOLOGY,
335         POWER_SUPPLY_PROP_HEALTH,
336         POWER_SUPPLY_PROP_CAPACITY_LEVEL,
337         POWER_SUPPLY_PROP_CURRENT_MAX,
338         POWER_SUPPLY_PROP_MODEL_NAME,
339         POWER_SUPPLY_PROP_MANUFACTURER
340 };
341
342 static int act8945a_charger_get_property(struct power_supply *psy,
343                                          enum power_supply_property prop,
344                                          union power_supply_propval *val)
345 {
346         struct act8945a_charger *charger = power_supply_get_drvdata(psy);
347         struct regmap *regmap = charger->regmap;
348         int ret = 0;
349
350         switch (prop) {
351         case POWER_SUPPLY_PROP_STATUS:
352                 ret = act8945a_get_charger_state(regmap, &val->intval);
353                 break;
354         case POWER_SUPPLY_PROP_CHARGE_TYPE:
355                 ret = act8945a_get_charge_type(regmap, &val->intval);
356                 break;
357         case POWER_SUPPLY_PROP_TECHNOLOGY:
358                 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
359                 break;
360         case POWER_SUPPLY_PROP_HEALTH:
361                 ret = act8945a_get_battery_health(regmap, &val->intval);
362                 break;
363         case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
364                 ret = act8945a_get_capacity_level(charger,
365                                                   regmap, &val->intval);
366                 break;
367         case POWER_SUPPLY_PROP_CURRENT_MAX:
368                 ret = act8945a_get_current_max(charger,
369                                                regmap, &val->intval);
370                 break;
371         case POWER_SUPPLY_PROP_MODEL_NAME:
372                 val->strval = act8945a_charger_model;
373                 break;
374         case POWER_SUPPLY_PROP_MANUFACTURER:
375                 val->strval = act8945a_charger_manufacturer;
376                 break;
377         default:
378                 return -EINVAL;
379         }
380
381         return ret;
382 }
383
384 static int act8945a_enable_interrupt(struct act8945a_charger *charger)
385 {
386         struct regmap *regmap = charger->regmap;
387         unsigned char ctrl;
388         int ret;
389
390         ctrl = APCH_CTRL_CHGEOCOUT | APCH_CTRL_CHGEOCIN |
391                APCH_CTRL_INDIS | APCH_CTRL_INCON |
392                APCH_CTRL_TEMPOUT | APCH_CTRL_TEMPIN |
393                APCH_CTRL_TIMRPRE | APCH_CTRL_TIMRTOT;
394         ret = regmap_write(regmap, ACT8945A_APCH_CTRL, ctrl);
395         if (ret)
396                 return ret;
397
398         ctrl = APCH_STATUS_CHGSTAT | APCH_STATUS_INSTAT |
399                APCH_STATUS_TEMPSTAT | APCH_STATUS_TIMRSTAT;
400         ret = regmap_write(regmap, ACT8945A_APCH_STATUS, ctrl);
401         if (ret)
402                 return ret;
403
404         return 0;
405 }
406
407 static unsigned int act8945a_set_supply_type(struct act8945a_charger *charger,
408                                              unsigned int *type)
409 {
410         unsigned int status, state;
411         int ret;
412
413         ret = regmap_read(charger->regmap, ACT8945A_APCH_STATUS, &status);
414         if (ret < 0)
415                 return ret;
416
417         ret = regmap_read(charger->regmap, ACT8945A_APCH_STATE, &state);
418         if (ret < 0)
419                 return ret;
420
421         if (status & APCH_STATUS_INDAT) {
422                 if (state & APCH_STATE_ACINSTAT)
423                         *type = POWER_SUPPLY_TYPE_MAINS;
424                 else
425                         *type = POWER_SUPPLY_TYPE_USB;
426         } else {
427                 *type = POWER_SUPPLY_TYPE_BATTERY;
428         }
429
430         return 0;
431 }
432
433 static void act8945a_work(struct work_struct *work)
434 {
435         struct act8945a_charger *charger =
436                         container_of(work, struct act8945a_charger, work);
437
438         act8945a_set_supply_type(charger, &charger->desc.type);
439
440         power_supply_changed(charger->psy);
441 }
442
443 static irqreturn_t act8945a_status_changed(int irq, void *dev_id)
444 {
445         struct act8945a_charger *charger = dev_id;
446
447         if (charger->init_done)
448                 schedule_work(&charger->work);
449
450         return IRQ_HANDLED;
451 }
452
453 #define DEFAULT_TOTAL_TIME_OUT          3
454 #define DEFAULT_PRE_TIME_OUT            40
455 #define DEFAULT_INPUT_OVP_THRESHOLD     6600
456
457 static int act8945a_charger_config(struct device *dev,
458                                    struct act8945a_charger *charger)
459 {
460         struct device_node *np = dev->of_node;
461         struct regmap *regmap = charger->regmap;
462
463         u32 total_time_out;
464         u32 pre_time_out;
465         u32 input_voltage_threshold;
466         int err, ret;
467
468         unsigned int tmp;
469         unsigned int value = 0;
470
471         if (!np) {
472                 dev_err(dev, "no charger of node\n");
473                 return -EINVAL;
474         }
475
476         ret = regmap_read(regmap, ACT8945A_APCH_CFG, &tmp);
477         if (ret)
478                 return ret;
479
480         if (tmp & APCH_CFG_SUSCHG) {
481                 value |= APCH_CFG_SUSCHG;
482                 dev_info(dev, "have been suspended\n");
483         }
484
485         charger->lbo_gpio = devm_gpiod_get_optional(dev, "active-semi,lbo",
486                                                     GPIOD_IN);
487         if (IS_ERR(charger->lbo_gpio)) {
488                 err = PTR_ERR(charger->lbo_gpio);
489                 dev_err(dev, "unable to claim gpio \"lbo\": %d\n", err);
490                 return err;
491         }
492
493         ret = devm_request_irq(dev, gpiod_to_irq(charger->lbo_gpio),
494                                act8945a_status_changed,
495                                (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING),
496                                "act8945a_lbo_detect", charger);
497         if (ret)
498                 dev_info(dev, "failed to request gpio \"lbo\" IRQ\n");
499
500         charger->chglev_gpio = devm_gpiod_get_optional(dev,
501                                                        "active-semi,chglev",
502                                                        GPIOD_IN);
503         if (IS_ERR(charger->chglev_gpio)) {
504                 err = PTR_ERR(charger->chglev_gpio);
505                 dev_err(dev, "unable to claim gpio \"chglev\": %d\n", err);
506                 return err;
507         }
508
509         if (of_property_read_u32(np,
510                                  "active-semi,input-voltage-threshold-microvolt",
511                                  &input_voltage_threshold))
512                 input_voltage_threshold = DEFAULT_INPUT_OVP_THRESHOLD;
513
514         if (of_property_read_u32(np,
515                                  "active-semi,precondition-timeout",
516                                  &pre_time_out))
517                 pre_time_out = DEFAULT_PRE_TIME_OUT;
518
519         if (of_property_read_u32(np, "active-semi,total-timeout",
520                                  &total_time_out))
521                 total_time_out = DEFAULT_TOTAL_TIME_OUT;
522
523         switch (input_voltage_threshold) {
524         case 8000:
525                 value |= APCH_CFG_OVPSET_8V;
526                 break;
527         case 7500:
528                 value |= APCH_CFG_OVPSET_7V5;
529                 break;
530         case 7000:
531                 value |= APCH_CFG_OVPSET_7V;
532                 break;
533         case 6600:
534         default:
535                 value |= APCH_CFG_OVPSET_6V6;
536                 break;
537         }
538
539         switch (pre_time_out) {
540         case 60:
541                 value |= APCH_CFG_PRETIMO_60_MIN;
542                 break;
543         case 80:
544                 value |= APCH_CFG_PRETIMO_80_MIN;
545                 break;
546         case 0:
547                 value |= APCH_CFG_PRETIMO_DISABLED;
548                 break;
549         case 40:
550         default:
551                 value |= APCH_CFG_PRETIMO_40_MIN;
552                 break;
553         }
554
555         switch (total_time_out) {
556         case 4:
557                 value |= APCH_CFG_TOTTIMO_4_HOUR;
558                 break;
559         case 5:
560                 value |= APCH_CFG_TOTTIMO_5_HOUR;
561                 break;
562         case 0:
563                 value |= APCH_CFG_TOTTIMO_DISABLED;
564                 break;
565         case 3:
566         default:
567                 value |= APCH_CFG_TOTTIMO_3_HOUR;
568                 break;
569         }
570
571         return regmap_write(regmap, ACT8945A_APCH_CFG, value);
572 }
573
574 static int act8945a_charger_probe(struct platform_device *pdev)
575 {
576         struct act8945a_charger *charger;
577         struct power_supply_config psy_cfg = {};
578         int irq, ret;
579
580         charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
581         if (!charger)
582                 return -ENOMEM;
583
584         charger->regmap = dev_get_regmap(pdev->dev.parent, NULL);
585         if (!charger->regmap) {
586                 dev_err(&pdev->dev, "Parent did not provide regmap\n");
587                 return -EINVAL;
588         }
589
590         ret = act8945a_charger_config(&pdev->dev, charger);
591         if (ret)
592                 return ret;
593
594         irq = of_irq_get(pdev->dev.of_node, 0);
595         if (irq <= 0) {
596                 dev_err(&pdev->dev, "failed to find IRQ number\n");
597                 return irq ?: -ENXIO;
598         }
599
600         ret = devm_request_irq(&pdev->dev, irq, act8945a_status_changed,
601                                IRQF_TRIGGER_FALLING, "act8945a_interrupt",
602                                charger);
603         if (ret) {
604                 dev_err(&pdev->dev, "failed to request nIRQ pin IRQ\n");
605                 return ret;
606         }
607
608         charger->desc.name = "act8945a-charger";
609         charger->desc.get_property = act8945a_charger_get_property;
610         charger->desc.properties = act8945a_charger_props;
611         charger->desc.num_properties = ARRAY_SIZE(act8945a_charger_props);
612
613         ret = act8945a_set_supply_type(charger, &charger->desc.type);
614         if (ret)
615                 return -EINVAL;
616
617         psy_cfg.of_node = pdev->dev.of_node;
618         psy_cfg.drv_data = charger;
619
620         charger->psy = devm_power_supply_register(&pdev->dev,
621                                                   &charger->desc,
622                                                   &psy_cfg);
623         if (IS_ERR(charger->psy)) {
624                 dev_err(&pdev->dev, "failed to register power supply\n");
625                 return PTR_ERR(charger->psy);
626         }
627
628         platform_set_drvdata(pdev, charger);
629
630         INIT_WORK(&charger->work, act8945a_work);
631
632         ret = act8945a_enable_interrupt(charger);
633         if (ret)
634                 return -EIO;
635
636         charger->init_done = true;
637
638         return 0;
639 }
640
641 static void act8945a_charger_remove(struct platform_device *pdev)
642 {
643         struct act8945a_charger *charger = platform_get_drvdata(pdev);
644
645         charger->init_done = false;
646         cancel_work_sync(&charger->work);
647 }
648
649 static struct platform_driver act8945a_charger_driver = {
650         .driver = {
651                 .name = "act8945a-charger",
652         },
653         .probe  = act8945a_charger_probe,
654         .remove_new = act8945a_charger_remove,
655 };
656 module_platform_driver(act8945a_charger_driver);
657
658 MODULE_DESCRIPTION("Active-semi ACT8945A ActivePath charger driver");
659 MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
660 MODULE_LICENSE("GPL");