1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/device.h>
16#include <linux/interrupt.h>
17#include <linux/delay.h>
18#include <linux/slab.h>
19#include <linux/platform_device.h>
20#include <linux/power_supply.h>
21#include <linux/completion.h>
22#include <linux/workqueue.h>
23#include <linux/kobject.h>
24#include <linux/mfd/abx500.h>
25#include <linux/mfd/abx500/ux500_chargalg.h>
26#include <linux/mfd/abx500/ab8500-bm.h>
27
28
29#define CHG_WD_INTERVAL (6 * HZ)
30
31
32#define EOC_COND_CNT 10
33
34
35#define RCH_COND_CNT 3
36
37#define to_abx500_chargalg_device_info(x) container_of((x), \
38 struct abx500_chargalg, chargalg_psy);
39
40enum abx500_chargers {
41 NO_CHG,
42 AC_CHG,
43 USB_CHG,
44};
45
46struct abx500_chargalg_charger_info {
47 enum abx500_chargers conn_chg;
48 enum abx500_chargers prev_conn_chg;
49 enum abx500_chargers online_chg;
50 enum abx500_chargers prev_online_chg;
51 enum abx500_chargers charger_type;
52 bool usb_chg_ok;
53 bool ac_chg_ok;
54 int usb_volt;
55 int usb_curr;
56 int ac_volt;
57 int ac_curr;
58 int usb_vset;
59 int usb_iset;
60 int ac_vset;
61 int ac_iset;
62};
63
64struct abx500_chargalg_suspension_status {
65 bool suspended_change;
66 bool ac_suspended;
67 bool usb_suspended;
68};
69
70struct abx500_chargalg_battery_data {
71 int temp;
72 int volt;
73 int avg_curr;
74 int inst_curr;
75 int percent;
76};
77
78enum abx500_chargalg_states {
79 STATE_HANDHELD_INIT,
80 STATE_HANDHELD,
81 STATE_CHG_NOT_OK_INIT,
82 STATE_CHG_NOT_OK,
83 STATE_HW_TEMP_PROTECT_INIT,
84 STATE_HW_TEMP_PROTECT,
85 STATE_NORMAL_INIT,
86 STATE_NORMAL,
87 STATE_WAIT_FOR_RECHARGE_INIT,
88 STATE_WAIT_FOR_RECHARGE,
89 STATE_MAINTENANCE_A_INIT,
90 STATE_MAINTENANCE_A,
91 STATE_MAINTENANCE_B_INIT,
92 STATE_MAINTENANCE_B,
93 STATE_TEMP_UNDEROVER_INIT,
94 STATE_TEMP_UNDEROVER,
95 STATE_TEMP_LOWHIGH_INIT,
96 STATE_TEMP_LOWHIGH,
97 STATE_SUSPENDED_INIT,
98 STATE_SUSPENDED,
99 STATE_OVV_PROTECT_INIT,
100 STATE_OVV_PROTECT,
101 STATE_SAFETY_TIMER_EXPIRED_INIT,
102 STATE_SAFETY_TIMER_EXPIRED,
103 STATE_BATT_REMOVED_INIT,
104 STATE_BATT_REMOVED,
105 STATE_WD_EXPIRED_INIT,
106 STATE_WD_EXPIRED,
107};
108
109static const char *states[] = {
110 "HANDHELD_INIT",
111 "HANDHELD",
112 "CHG_NOT_OK_INIT",
113 "CHG_NOT_OK",
114 "HW_TEMP_PROTECT_INIT",
115 "HW_TEMP_PROTECT",
116 "NORMAL_INIT",
117 "NORMAL",
118 "WAIT_FOR_RECHARGE_INIT",
119 "WAIT_FOR_RECHARGE",
120 "MAINTENANCE_A_INIT",
121 "MAINTENANCE_A",
122 "MAINTENANCE_B_INIT",
123 "MAINTENANCE_B",
124 "TEMP_UNDEROVER_INIT",
125 "TEMP_UNDEROVER",
126 "TEMP_LOWHIGH_INIT",
127 "TEMP_LOWHIGH",
128 "SUSPENDED_INIT",
129 "SUSPENDED",
130 "OVV_PROTECT_INIT",
131 "OVV_PROTECT",
132 "SAFETY_TIMER_EXPIRED_INIT",
133 "SAFETY_TIMER_EXPIRED",
134 "BATT_REMOVED_INIT",
135 "BATT_REMOVED",
136 "WD_EXPIRED_INIT",
137 "WD_EXPIRED",
138};
139
140struct abx500_chargalg_events {
141 bool batt_unknown;
142 bool mainextchnotok;
143 bool batt_ovv;
144 bool batt_rem;
145 bool btemp_underover;
146 bool btemp_lowhigh;
147 bool main_thermal_prot;
148 bool usb_thermal_prot;
149 bool main_ovv;
150 bool vbus_ovv;
151 bool usbchargernotok;
152 bool safety_timer_expired;
153 bool maintenance_timer_expired;
154 bool ac_wd_expired;
155 bool usb_wd_expired;
156 bool ac_cv_active;
157 bool usb_cv_active;
158 bool vbus_collapsed;
159};
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176struct abx500_charge_curr_maximization {
177 int original_iset;
178 int current_iset;
179 int test_delta_i;
180 int condition_cnt;
181 int max_current;
182 int wait_cnt;
183 u8 level;
184};
185
186enum maxim_ret {
187 MAXIM_RET_NOACTION,
188 MAXIM_RET_CHANGE,
189 MAXIM_RET_IBAT_TOO_HIGH,
190};
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221struct abx500_chargalg {
222 struct device *dev;
223 int charge_status;
224 int eoc_cnt;
225 int rch_cnt;
226 bool maintenance_chg;
227 int t_hyst_norm;
228 int t_hyst_lowhigh;
229 enum abx500_chargalg_states charge_state;
230 struct abx500_charge_curr_maximization ccm;
231 struct abx500_chargalg_charger_info chg_info;
232 struct abx500_chargalg_battery_data batt_data;
233 struct abx500_chargalg_suspension_status susp_status;
234 struct abx500_chargalg_platform_data *pdata;
235 struct abx500_bm_data *bat;
236 struct power_supply chargalg_psy;
237 struct ux500_charger *ac_chg;
238 struct ux500_charger *usb_chg;
239 struct abx500_chargalg_events events;
240 struct workqueue_struct *chargalg_wq;
241 struct delayed_work chargalg_periodic_work;
242 struct delayed_work chargalg_wd_work;
243 struct work_struct chargalg_work;
244 struct timer_list safety_timer;
245 struct timer_list maintenance_timer;
246 struct kobject chargalg_kobject;
247};
248
249
250static enum power_supply_property abx500_chargalg_props[] = {
251 POWER_SUPPLY_PROP_STATUS,
252 POWER_SUPPLY_PROP_HEALTH,
253};
254
255
256
257
258
259
260
261
262static void abx500_chargalg_safety_timer_expired(unsigned long data)
263{
264 struct abx500_chargalg *di = (struct abx500_chargalg *) data;
265 dev_err(di->dev, "Safety timer expired\n");
266 di->events.safety_timer_expired = true;
267
268
269 queue_work(di->chargalg_wq, &di->chargalg_work);
270}
271
272
273
274
275
276
277
278
279
280static void abx500_chargalg_maintenance_timer_expired(unsigned long data)
281{
282
283 struct abx500_chargalg *di = (struct abx500_chargalg *) data;
284 dev_dbg(di->dev, "Maintenance timer expired\n");
285 di->events.maintenance_timer_expired = true;
286
287
288 queue_work(di->chargalg_wq, &di->chargalg_work);
289}
290
291
292
293
294
295
296
297static void abx500_chargalg_state_to(struct abx500_chargalg *di,
298 enum abx500_chargalg_states state)
299{
300 dev_dbg(di->dev,
301 "State changed: %s (From state: [%d] %s =to=> [%d] %s )\n",
302 di->charge_state == state ? "NO" : "YES",
303 di->charge_state,
304 states[di->charge_state],
305 state,
306 states[state]);
307
308 di->charge_state = state;
309}
310
311
312
313
314
315
316
317
318static int abx500_chargalg_check_charger_connection(struct abx500_chargalg *di)
319{
320 if (di->chg_info.conn_chg != di->chg_info.prev_conn_chg ||
321 di->susp_status.suspended_change) {
322
323
324
325
326 if ((di->chg_info.conn_chg & AC_CHG) &&
327 !di->susp_status.ac_suspended) {
328 dev_dbg(di->dev, "Charging source is AC\n");
329 if (di->chg_info.charger_type != AC_CHG) {
330 di->chg_info.charger_type = AC_CHG;
331 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
332 }
333 } else if ((di->chg_info.conn_chg & USB_CHG) &&
334 !di->susp_status.usb_suspended) {
335 dev_dbg(di->dev, "Charging source is USB\n");
336 di->chg_info.charger_type = USB_CHG;
337 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
338 } else if (di->chg_info.conn_chg &&
339 (di->susp_status.ac_suspended ||
340 di->susp_status.usb_suspended)) {
341 dev_dbg(di->dev, "Charging is suspended\n");
342 di->chg_info.charger_type = NO_CHG;
343 abx500_chargalg_state_to(di, STATE_SUSPENDED_INIT);
344 } else {
345 dev_dbg(di->dev, "Charging source is OFF\n");
346 di->chg_info.charger_type = NO_CHG;
347 abx500_chargalg_state_to(di, STATE_HANDHELD_INIT);
348 }
349 di->chg_info.prev_conn_chg = di->chg_info.conn_chg;
350 di->susp_status.suspended_change = false;
351 }
352 return di->chg_info.conn_chg;
353}
354
355
356
357
358
359
360
361
362static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di)
363{
364 unsigned long timer_expiration = 0;
365
366 switch (di->chg_info.charger_type) {
367 case AC_CHG:
368 timer_expiration =
369 round_jiffies(jiffies +
370 (di->bat->main_safety_tmr_h * 3600 * HZ));
371 break;
372
373 case USB_CHG:
374 timer_expiration =
375 round_jiffies(jiffies +
376 (di->bat->usb_safety_tmr_h * 3600 * HZ));
377 break;
378
379 default:
380 dev_err(di->dev, "Unknown charger to charge from\n");
381 break;
382 }
383
384 di->events.safety_timer_expired = false;
385 di->safety_timer.expires = timer_expiration;
386 if (!timer_pending(&di->safety_timer))
387 add_timer(&di->safety_timer);
388 else
389 mod_timer(&di->safety_timer, timer_expiration);
390}
391
392
393
394
395
396
397
398static void abx500_chargalg_stop_safety_timer(struct abx500_chargalg *di)
399{
400 di->events.safety_timer_expired = false;
401 del_timer(&di->safety_timer);
402}
403
404
405
406
407
408
409
410
411
412
413static void abx500_chargalg_start_maintenance_timer(struct abx500_chargalg *di,
414 int duration)
415{
416 unsigned long timer_expiration;
417
418
419 timer_expiration = round_jiffies(jiffies + (duration * 3600 * HZ));
420
421 di->events.maintenance_timer_expired = false;
422 di->maintenance_timer.expires = timer_expiration;
423 if (!timer_pending(&di->maintenance_timer))
424 add_timer(&di->maintenance_timer);
425 else
426 mod_timer(&di->maintenance_timer, timer_expiration);
427}
428
429
430
431
432
433
434
435
436static void abx500_chargalg_stop_maintenance_timer(struct abx500_chargalg *di)
437{
438 di->events.maintenance_timer_expired = false;
439 del_timer(&di->maintenance_timer);
440}
441
442
443
444
445
446
447
448
449static int abx500_chargalg_kick_watchdog(struct abx500_chargalg *di)
450{
451
452 if (di->ac_chg && di->ac_chg->ops.kick_wd &&
453 di->chg_info.online_chg & AC_CHG)
454 return di->ac_chg->ops.kick_wd(di->ac_chg);
455 else if (di->usb_chg && di->usb_chg->ops.kick_wd &&
456 di->chg_info.online_chg & USB_CHG)
457 return di->usb_chg->ops.kick_wd(di->usb_chg);
458
459 return -ENXIO;
460}
461
462
463
464
465
466
467
468
469
470
471
472static int abx500_chargalg_ac_en(struct abx500_chargalg *di, int enable,
473 int vset, int iset)
474{
475 if (!di->ac_chg || !di->ac_chg->ops.enable)
476 return -ENXIO;
477
478
479 if (di->ac_chg->max_out_volt)
480 vset = min(vset, di->ac_chg->max_out_volt);
481 if (di->ac_chg->max_out_curr)
482 iset = min(iset, di->ac_chg->max_out_curr);
483
484 di->chg_info.ac_iset = iset;
485 di->chg_info.ac_vset = vset;
486
487 return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset);
488}
489
490
491
492
493
494
495
496
497
498
499
500static int abx500_chargalg_usb_en(struct abx500_chargalg *di, int enable,
501 int vset, int iset)
502{
503 if (!di->usb_chg || !di->usb_chg->ops.enable)
504 return -ENXIO;
505
506
507 if (di->usb_chg->max_out_volt)
508 vset = min(vset, di->usb_chg->max_out_volt);
509 if (di->usb_chg->max_out_curr)
510 iset = min(iset, di->usb_chg->max_out_curr);
511
512 di->chg_info.usb_iset = iset;
513 di->chg_info.usb_vset = vset;
514
515 return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset);
516}
517
518
519
520
521
522
523
524
525
526static int abx500_chargalg_update_chg_curr(struct abx500_chargalg *di,
527 int iset)
528{
529
530 if (di->ac_chg && di->ac_chg->ops.update_curr &&
531 di->chg_info.charger_type & AC_CHG) {
532
533
534
535
536 if (di->ac_chg->max_out_curr)
537 iset = min(iset, di->ac_chg->max_out_curr);
538
539 di->chg_info.ac_iset = iset;
540
541 return di->ac_chg->ops.update_curr(di->ac_chg, iset);
542 } else if (di->usb_chg && di->usb_chg->ops.update_curr &&
543 di->chg_info.charger_type & USB_CHG) {
544
545
546
547
548 if (di->usb_chg->max_out_curr)
549 iset = min(iset, di->usb_chg->max_out_curr);
550
551 di->chg_info.usb_iset = iset;
552
553 return di->usb_chg->ops.update_curr(di->usb_chg, iset);
554 }
555
556 return -ENXIO;
557}
558
559
560
561
562
563
564
565
566
567static void abx500_chargalg_stop_charging(struct abx500_chargalg *di)
568{
569 abx500_chargalg_ac_en(di, false, 0, 0);
570 abx500_chargalg_usb_en(di, false, 0, 0);
571 abx500_chargalg_stop_safety_timer(di);
572 abx500_chargalg_stop_maintenance_timer(di);
573 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
574 di->maintenance_chg = false;
575 cancel_delayed_work(&di->chargalg_wd_work);
576 power_supply_changed(&di->chargalg_psy);
577}
578
579
580
581
582
583
584
585
586
587static void abx500_chargalg_hold_charging(struct abx500_chargalg *di)
588{
589 abx500_chargalg_ac_en(di, false, 0, 0);
590 abx500_chargalg_usb_en(di, false, 0, 0);
591 abx500_chargalg_stop_safety_timer(di);
592 abx500_chargalg_stop_maintenance_timer(di);
593 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
594 di->maintenance_chg = false;
595 cancel_delayed_work(&di->chargalg_wd_work);
596 power_supply_changed(&di->chargalg_psy);
597}
598
599
600
601
602
603
604
605
606
607
608static void abx500_chargalg_start_charging(struct abx500_chargalg *di,
609 int vset, int iset)
610{
611 switch (di->chg_info.charger_type) {
612 case AC_CHG:
613 dev_dbg(di->dev,
614 "AC parameters: Vset %d, Ich %d\n", vset, iset);
615 abx500_chargalg_usb_en(di, false, 0, 0);
616 abx500_chargalg_ac_en(di, true, vset, iset);
617 break;
618
619 case USB_CHG:
620 dev_dbg(di->dev,
621 "USB parameters: Vset %d, Ich %d\n", vset, iset);
622 abx500_chargalg_ac_en(di, false, 0, 0);
623 abx500_chargalg_usb_en(di, true, vset, iset);
624 break;
625
626 default:
627 dev_err(di->dev, "Unknown charger to charge from\n");
628 break;
629 }
630}
631
632
633
634
635
636
637
638
639static void abx500_chargalg_check_temp(struct abx500_chargalg *di)
640{
641 if (di->batt_data.temp > (di->bat->temp_low + di->t_hyst_norm) &&
642 di->batt_data.temp < (di->bat->temp_high - di->t_hyst_norm)) {
643
644 di->events.btemp_underover = false;
645 di->events.btemp_lowhigh = false;
646 di->t_hyst_norm = 0;
647 di->t_hyst_lowhigh = 0;
648 } else {
649 if (((di->batt_data.temp >= di->bat->temp_high) &&
650 (di->batt_data.temp <
651 (di->bat->temp_over - di->t_hyst_lowhigh))) ||
652 ((di->batt_data.temp >
653 (di->bat->temp_under + di->t_hyst_lowhigh)) &&
654 (di->batt_data.temp <= di->bat->temp_low))) {
655
656 di->events.btemp_underover = false;
657 di->events.btemp_lowhigh = true;
658 di->t_hyst_norm = di->bat->temp_hysteresis;
659 di->t_hyst_lowhigh = 0;
660 } else if (di->batt_data.temp <= di->bat->temp_under ||
661 di->batt_data.temp >= di->bat->temp_over) {
662
663 di->events.btemp_underover = true;
664 di->events.btemp_lowhigh = false;
665 di->t_hyst_norm = 0;
666 di->t_hyst_lowhigh = di->bat->temp_hysteresis;
667 } else {
668
669 dev_dbg(di->dev, "Within hysteresis limit temp: %d "
670 "hyst_lowhigh %d, hyst normal %d\n",
671 di->batt_data.temp, di->t_hyst_lowhigh,
672 di->t_hyst_norm);
673 }
674 }
675}
676
677
678
679
680
681
682
683static void abx500_chargalg_check_charger_voltage(struct abx500_chargalg *di)
684{
685 if (di->chg_info.usb_volt > di->bat->chg_params->usb_volt_max)
686 di->chg_info.usb_chg_ok = false;
687 else
688 di->chg_info.usb_chg_ok = true;
689
690 if (di->chg_info.ac_volt > di->bat->chg_params->ac_volt_max)
691 di->chg_info.ac_chg_ok = false;
692 else
693 di->chg_info.ac_chg_ok = true;
694
695}
696
697
698
699
700
701
702
703
704
705static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
706{
707 if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING &&
708 di->charge_state == STATE_NORMAL &&
709 !di->maintenance_chg && (di->batt_data.volt >=
710 di->bat->bat_type[di->bat->batt_id].termination_vol ||
711 di->events.usb_cv_active || di->events.ac_cv_active) &&
712 di->batt_data.avg_curr <
713 di->bat->bat_type[di->bat->batt_id].termination_curr &&
714 di->batt_data.avg_curr > 0) {
715 if (++di->eoc_cnt >= EOC_COND_CNT) {
716 di->eoc_cnt = 0;
717 di->charge_status = POWER_SUPPLY_STATUS_FULL;
718 di->maintenance_chg = true;
719 dev_dbg(di->dev, "EOC reached!\n");
720 power_supply_changed(&di->chargalg_psy);
721 } else {
722 dev_dbg(di->dev,
723 " EOC limit reached for the %d"
724 " time, out of %d before EOC\n",
725 di->eoc_cnt,
726 EOC_COND_CNT);
727 }
728 } else {
729 di->eoc_cnt = 0;
730 }
731}
732
733static void init_maxim_chg_curr(struct abx500_chargalg *di)
734{
735 di->ccm.original_iset =
736 di->bat->bat_type[di->bat->batt_id].normal_cur_lvl;
737 di->ccm.current_iset =
738 di->bat->bat_type[di->bat->batt_id].normal_cur_lvl;
739 di->ccm.test_delta_i = di->bat->maxi->charger_curr_step;
740 di->ccm.max_current = di->bat->maxi->chg_curr;
741 di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
742 di->ccm.level = 0;
743}
744
745
746
747
748
749
750
751
752
753
754static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
755{
756 int delta_i;
757
758 if (!di->bat->maxi->ena_maxi)
759 return MAXIM_RET_NOACTION;
760
761 delta_i = di->ccm.original_iset - di->batt_data.inst_curr;
762
763 if (di->events.vbus_collapsed) {
764 dev_dbg(di->dev, "Charger voltage has collapsed %d\n",
765 di->ccm.wait_cnt);
766 if (di->ccm.wait_cnt == 0) {
767 dev_dbg(di->dev, "lowering current\n");
768 di->ccm.wait_cnt++;
769 di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
770 di->ccm.max_current =
771 di->ccm.current_iset - di->ccm.test_delta_i;
772 di->ccm.current_iset = di->ccm.max_current;
773 di->ccm.level--;
774 return MAXIM_RET_CHANGE;
775 } else {
776 dev_dbg(di->dev, "waiting\n");
777
778 di->ccm.wait_cnt = (di->ccm.wait_cnt + 1) % 3;
779 return MAXIM_RET_NOACTION;
780 }
781 }
782
783 di->ccm.wait_cnt = 0;
784
785 if ((di->batt_data.inst_curr > di->ccm.original_iset)) {
786 dev_dbg(di->dev, " Maximization Ibat (%dmA) too high"
787 " (limit %dmA) (current iset: %dmA)!\n",
788 di->batt_data.inst_curr, di->ccm.original_iset,
789 di->ccm.current_iset);
790
791 if (di->ccm.current_iset == di->ccm.original_iset)
792 return MAXIM_RET_NOACTION;
793
794 di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
795 di->ccm.current_iset = di->ccm.original_iset;
796 di->ccm.level = 0;
797
798 return MAXIM_RET_IBAT_TOO_HIGH;
799 }
800
801 if (delta_i > di->ccm.test_delta_i &&
802 (di->ccm.current_iset + di->ccm.test_delta_i) <
803 di->ccm.max_current) {
804 if (di->ccm.condition_cnt-- == 0) {
805
806 di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
807 di->ccm.current_iset += di->ccm.test_delta_i;
808 di->ccm.level++;
809 dev_dbg(di->dev, " Maximization needed, increase"
810 " with %d mA to %dmA (Optimal ibat: %d)"
811 " Level %d\n",
812 di->ccm.test_delta_i,
813 di->ccm.current_iset,
814 di->ccm.original_iset,
815 di->ccm.level);
816 return MAXIM_RET_CHANGE;
817 } else {
818 return MAXIM_RET_NOACTION;
819 }
820 } else {
821 di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
822 return MAXIM_RET_NOACTION;
823 }
824}
825
826static void handle_maxim_chg_curr(struct abx500_chargalg *di)
827{
828 enum maxim_ret ret;
829 int result;
830
831 ret = abx500_chargalg_chg_curr_maxim(di);
832 switch (ret) {
833 case MAXIM_RET_CHANGE:
834 result = abx500_chargalg_update_chg_curr(di,
835 di->ccm.current_iset);
836 if (result)
837 dev_err(di->dev, "failed to set chg curr\n");
838 break;
839 case MAXIM_RET_IBAT_TOO_HIGH:
840 result = abx500_chargalg_update_chg_curr(di,
841 di->bat->bat_type[di->bat->batt_id].normal_cur_lvl);
842 if (result)
843 dev_err(di->dev, "failed to set chg curr\n");
844 break;
845
846 case MAXIM_RET_NOACTION:
847 default:
848
849 break;
850 }
851}
852
853static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data)
854{
855 struct power_supply *psy;
856 struct power_supply *ext;
857 struct abx500_chargalg *di;
858 union power_supply_propval ret;
859 int i, j;
860 bool psy_found = false;
861
862 psy = (struct power_supply *)data;
863 ext = dev_get_drvdata(dev);
864 di = to_abx500_chargalg_device_info(psy);
865
866 for (i = 0; i < ext->num_supplicants; i++) {
867 if (!strcmp(ext->supplied_to[i], psy->name))
868 psy_found = true;
869 }
870 if (!psy_found)
871 return 0;
872
873
874 for (j = 0; j < ext->num_properties; j++) {
875 enum power_supply_property prop;
876 prop = ext->properties[j];
877
878
879 if (!di->ac_chg &&
880 ext->type == POWER_SUPPLY_TYPE_MAINS)
881 di->ac_chg = psy_to_ux500_charger(ext);
882 else if (!di->usb_chg &&
883 ext->type == POWER_SUPPLY_TYPE_USB)
884 di->usb_chg = psy_to_ux500_charger(ext);
885
886 if (ext->get_property(ext, prop, &ret))
887 continue;
888 switch (prop) {
889 case POWER_SUPPLY_PROP_PRESENT:
890 switch (ext->type) {
891 case POWER_SUPPLY_TYPE_BATTERY:
892
893 if (ret.intval)
894 di->events.batt_rem = false;
895
896 else
897 di->events.batt_rem = true;
898 break;
899 case POWER_SUPPLY_TYPE_MAINS:
900
901 if (!ret.intval &&
902 (di->chg_info.conn_chg & AC_CHG)) {
903 di->chg_info.prev_conn_chg =
904 di->chg_info.conn_chg;
905 di->chg_info.conn_chg &= ~AC_CHG;
906 }
907
908 else if (ret.intval &&
909 !(di->chg_info.conn_chg & AC_CHG)) {
910 di->chg_info.prev_conn_chg =
911 di->chg_info.conn_chg;
912 di->chg_info.conn_chg |= AC_CHG;
913 }
914 break;
915 case POWER_SUPPLY_TYPE_USB:
916
917 if (!ret.intval &&
918 (di->chg_info.conn_chg & USB_CHG)) {
919 di->chg_info.prev_conn_chg =
920 di->chg_info.conn_chg;
921 di->chg_info.conn_chg &= ~USB_CHG;
922 }
923
924 else if (ret.intval &&
925 !(di->chg_info.conn_chg & USB_CHG)) {
926 di->chg_info.prev_conn_chg =
927 di->chg_info.conn_chg;
928 di->chg_info.conn_chg |= USB_CHG;
929 }
930 break;
931 default:
932 break;
933 }
934 break;
935
936 case POWER_SUPPLY_PROP_ONLINE:
937 switch (ext->type) {
938 case POWER_SUPPLY_TYPE_BATTERY:
939 break;
940 case POWER_SUPPLY_TYPE_MAINS:
941
942 if (!ret.intval &&
943 (di->chg_info.online_chg & AC_CHG)) {
944 di->chg_info.prev_online_chg =
945 di->chg_info.online_chg;
946 di->chg_info.online_chg &= ~AC_CHG;
947 }
948
949 else if (ret.intval &&
950 !(di->chg_info.online_chg & AC_CHG)) {
951 di->chg_info.prev_online_chg =
952 di->chg_info.online_chg;
953 di->chg_info.online_chg |= AC_CHG;
954 queue_delayed_work(di->chargalg_wq,
955 &di->chargalg_wd_work, 0);
956 }
957 break;
958 case POWER_SUPPLY_TYPE_USB:
959
960 if (!ret.intval &&
961 (di->chg_info.online_chg & USB_CHG)) {
962 di->chg_info.prev_online_chg =
963 di->chg_info.online_chg;
964 di->chg_info.online_chg &= ~USB_CHG;
965 }
966
967 else if (ret.intval &&
968 !(di->chg_info.online_chg & USB_CHG)) {
969 di->chg_info.prev_online_chg =
970 di->chg_info.online_chg;
971 di->chg_info.online_chg |= USB_CHG;
972 queue_delayed_work(di->chargalg_wq,
973 &di->chargalg_wd_work, 0);
974 }
975 break;
976 default:
977 break;
978 }
979 break;
980
981 case POWER_SUPPLY_PROP_HEALTH:
982 switch (ext->type) {
983 case POWER_SUPPLY_TYPE_BATTERY:
984 break;
985 case POWER_SUPPLY_TYPE_MAINS:
986 switch (ret.intval) {
987 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
988 di->events.mainextchnotok = true;
989 di->events.main_thermal_prot = false;
990 di->events.main_ovv = false;
991 di->events.ac_wd_expired = false;
992 break;
993 case POWER_SUPPLY_HEALTH_DEAD:
994 di->events.ac_wd_expired = true;
995 di->events.mainextchnotok = false;
996 di->events.main_ovv = false;
997 di->events.main_thermal_prot = false;
998 break;
999 case POWER_SUPPLY_HEALTH_COLD:
1000 case POWER_SUPPLY_HEALTH_OVERHEAT:
1001 di->events.main_thermal_prot = true;
1002 di->events.mainextchnotok = false;
1003 di->events.main_ovv = false;
1004 di->events.ac_wd_expired = false;
1005 break;
1006 case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1007 di->events.main_ovv = true;
1008 di->events.mainextchnotok = false;
1009 di->events.main_thermal_prot = false;
1010 di->events.ac_wd_expired = false;
1011 break;
1012 case POWER_SUPPLY_HEALTH_GOOD:
1013 di->events.main_thermal_prot = false;
1014 di->events.mainextchnotok = false;
1015 di->events.main_ovv = false;
1016 di->events.ac_wd_expired = false;
1017 break;
1018 default:
1019 break;
1020 }
1021 break;
1022
1023 case POWER_SUPPLY_TYPE_USB:
1024 switch (ret.intval) {
1025 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
1026 di->events.usbchargernotok = true;
1027 di->events.usb_thermal_prot = false;
1028 di->events.vbus_ovv = false;
1029 di->events.usb_wd_expired = false;
1030 break;
1031 case POWER_SUPPLY_HEALTH_DEAD:
1032 di->events.usb_wd_expired = true;
1033 di->events.usbchargernotok = false;
1034 di->events.usb_thermal_prot = false;
1035 di->events.vbus_ovv = false;
1036 break;
1037 case POWER_SUPPLY_HEALTH_COLD:
1038 case POWER_SUPPLY_HEALTH_OVERHEAT:
1039 di->events.usb_thermal_prot = true;
1040 di->events.usbchargernotok = false;
1041 di->events.vbus_ovv = false;
1042 di->events.usb_wd_expired = false;
1043 break;
1044 case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1045 di->events.vbus_ovv = true;
1046 di->events.usbchargernotok = false;
1047 di->events.usb_thermal_prot = false;
1048 di->events.usb_wd_expired = false;
1049 break;
1050 case POWER_SUPPLY_HEALTH_GOOD:
1051 di->events.usbchargernotok = false;
1052 di->events.usb_thermal_prot = false;
1053 di->events.vbus_ovv = false;
1054 di->events.usb_wd_expired = false;
1055 break;
1056 default:
1057 break;
1058 }
1059 default:
1060 break;
1061 }
1062 break;
1063
1064 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1065 switch (ext->type) {
1066 case POWER_SUPPLY_TYPE_BATTERY:
1067 di->batt_data.volt = ret.intval / 1000;
1068 break;
1069 case POWER_SUPPLY_TYPE_MAINS:
1070 di->chg_info.ac_volt = ret.intval / 1000;
1071 break;
1072 case POWER_SUPPLY_TYPE_USB:
1073 di->chg_info.usb_volt = ret.intval / 1000;
1074 break;
1075 default:
1076 break;
1077 }
1078 break;
1079
1080 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
1081 switch (ext->type) {
1082 case POWER_SUPPLY_TYPE_MAINS:
1083
1084
1085 if (ret.intval)
1086 di->events.ac_cv_active = true;
1087 else
1088 di->events.ac_cv_active = false;
1089
1090 break;
1091 case POWER_SUPPLY_TYPE_USB:
1092
1093
1094 if (ret.intval)
1095 di->events.usb_cv_active = true;
1096 else
1097 di->events.usb_cv_active = false;
1098
1099 break;
1100 default:
1101 break;
1102 }
1103 break;
1104
1105 case POWER_SUPPLY_PROP_TECHNOLOGY:
1106 switch (ext->type) {
1107 case POWER_SUPPLY_TYPE_BATTERY:
1108 if (ret.intval)
1109 di->events.batt_unknown = false;
1110 else
1111 di->events.batt_unknown = true;
1112
1113 break;
1114 default:
1115 break;
1116 }
1117 break;
1118
1119 case POWER_SUPPLY_PROP_TEMP:
1120 di->batt_data.temp = ret.intval / 10;
1121 break;
1122
1123 case POWER_SUPPLY_PROP_CURRENT_NOW:
1124 switch (ext->type) {
1125 case POWER_SUPPLY_TYPE_MAINS:
1126 di->chg_info.ac_curr =
1127 ret.intval / 1000;
1128 break;
1129 case POWER_SUPPLY_TYPE_USB:
1130 di->chg_info.usb_curr =
1131 ret.intval / 1000;
1132 break;
1133 case POWER_SUPPLY_TYPE_BATTERY:
1134 di->batt_data.inst_curr = ret.intval / 1000;
1135 break;
1136 default:
1137 break;
1138 }
1139 break;
1140
1141 case POWER_SUPPLY_PROP_CURRENT_AVG:
1142 switch (ext->type) {
1143 case POWER_SUPPLY_TYPE_BATTERY:
1144 di->batt_data.avg_curr = ret.intval / 1000;
1145 break;
1146 case POWER_SUPPLY_TYPE_USB:
1147 if (ret.intval)
1148 di->events.vbus_collapsed = true;
1149 else
1150 di->events.vbus_collapsed = false;
1151 break;
1152 default:
1153 break;
1154 }
1155 break;
1156 case POWER_SUPPLY_PROP_CAPACITY:
1157 di->batt_data.percent = ret.intval;
1158 break;
1159 default:
1160 break;
1161 }
1162 }
1163 return 0;
1164}
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175static void abx500_chargalg_external_power_changed(struct power_supply *psy)
1176{
1177 struct abx500_chargalg *di = to_abx500_chargalg_device_info(psy);
1178
1179
1180
1181
1182
1183 queue_work(di->chargalg_wq, &di->chargalg_work);
1184}
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
1195{
1196 int charger_status;
1197
1198
1199 class_for_each_device(power_supply_class, NULL,
1200 &di->chargalg_psy, abx500_chargalg_get_ext_psy_data);
1201
1202 abx500_chargalg_end_of_charge(di);
1203 abx500_chargalg_check_temp(di);
1204 abx500_chargalg_check_charger_voltage(di);
1205
1206 charger_status = abx500_chargalg_check_charger_connection(di);
1207
1208
1209
1210
1211
1212 if (!charger_status ||
1213 (di->events.batt_unknown && !di->bat->chg_unknown_bat)) {
1214 if (di->charge_state != STATE_HANDHELD) {
1215 di->events.safety_timer_expired = false;
1216 abx500_chargalg_state_to(di, STATE_HANDHELD_INIT);
1217 }
1218 }
1219
1220
1221 else if (di->charge_state == STATE_SUSPENDED_INIT ||
1222 di->charge_state == STATE_SUSPENDED) {
1223
1224 }
1225
1226
1227 else if (di->events.safety_timer_expired) {
1228 if (di->charge_state != STATE_SAFETY_TIMER_EXPIRED)
1229 abx500_chargalg_state_to(di,
1230 STATE_SAFETY_TIMER_EXPIRED_INIT);
1231 }
1232
1233
1234
1235
1236
1237
1238 else if (di->events.batt_rem) {
1239 if (di->charge_state != STATE_BATT_REMOVED)
1240 abx500_chargalg_state_to(di, STATE_BATT_REMOVED_INIT);
1241 }
1242
1243 else if (di->events.mainextchnotok || di->events.usbchargernotok) {
1244
1245
1246
1247
1248 if (di->charge_state != STATE_CHG_NOT_OK &&
1249 !di->events.vbus_collapsed)
1250 abx500_chargalg_state_to(di, STATE_CHG_NOT_OK_INIT);
1251 }
1252
1253 else if (di->events.vbus_ovv ||
1254 di->events.main_ovv ||
1255 di->events.batt_ovv ||
1256 !di->chg_info.usb_chg_ok ||
1257 !di->chg_info.ac_chg_ok) {
1258 if (di->charge_state != STATE_OVV_PROTECT)
1259 abx500_chargalg_state_to(di, STATE_OVV_PROTECT_INIT);
1260 }
1261
1262 else if (di->events.main_thermal_prot ||
1263 di->events.usb_thermal_prot) {
1264 if (di->charge_state != STATE_HW_TEMP_PROTECT)
1265 abx500_chargalg_state_to(di,
1266 STATE_HW_TEMP_PROTECT_INIT);
1267 }
1268
1269 else if (di->events.btemp_underover) {
1270 if (di->charge_state != STATE_TEMP_UNDEROVER)
1271 abx500_chargalg_state_to(di,
1272 STATE_TEMP_UNDEROVER_INIT);
1273 }
1274
1275 else if (di->events.ac_wd_expired ||
1276 di->events.usb_wd_expired) {
1277 if (di->charge_state != STATE_WD_EXPIRED)
1278 abx500_chargalg_state_to(di, STATE_WD_EXPIRED_INIT);
1279 }
1280
1281 else if (di->events.btemp_lowhigh) {
1282 if (di->charge_state != STATE_TEMP_LOWHIGH)
1283 abx500_chargalg_state_to(di, STATE_TEMP_LOWHIGH_INIT);
1284 }
1285
1286 dev_dbg(di->dev,
1287 "[CHARGALG] Vb %d Ib_avg %d Ib_inst %d Tb %d Cap %d Maint %d "
1288 "State %s Active_chg %d Chg_status %d AC %d USB %d "
1289 "AC_online %d USB_online %d AC_CV %d USB_CV %d AC_I %d "
1290 "USB_I %d AC_Vset %d AC_Iset %d USB_Vset %d USB_Iset %d\n",
1291 di->batt_data.volt,
1292 di->batt_data.avg_curr,
1293 di->batt_data.inst_curr,
1294 di->batt_data.temp,
1295 di->batt_data.percent,
1296 di->maintenance_chg,
1297 states[di->charge_state],
1298 di->chg_info.charger_type,
1299 di->charge_status,
1300 di->chg_info.conn_chg & AC_CHG,
1301 di->chg_info.conn_chg & USB_CHG,
1302 di->chg_info.online_chg & AC_CHG,
1303 di->chg_info.online_chg & USB_CHG,
1304 di->events.ac_cv_active,
1305 di->events.usb_cv_active,
1306 di->chg_info.ac_curr,
1307 di->chg_info.usb_curr,
1308 di->chg_info.ac_vset,
1309 di->chg_info.ac_iset,
1310 di->chg_info.usb_vset,
1311 di->chg_info.usb_iset);
1312
1313 switch (di->charge_state) {
1314 case STATE_HANDHELD_INIT:
1315 abx500_chargalg_stop_charging(di);
1316 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
1317 abx500_chargalg_state_to(di, STATE_HANDHELD);
1318
1319
1320 case STATE_HANDHELD:
1321 break;
1322
1323 case STATE_SUSPENDED_INIT:
1324 if (di->susp_status.ac_suspended)
1325 abx500_chargalg_ac_en(di, false, 0, 0);
1326 if (di->susp_status.usb_suspended)
1327 abx500_chargalg_usb_en(di, false, 0, 0);
1328 abx500_chargalg_stop_safety_timer(di);
1329 abx500_chargalg_stop_maintenance_timer(di);
1330 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1331 di->maintenance_chg = false;
1332 abx500_chargalg_state_to(di, STATE_SUSPENDED);
1333 power_supply_changed(&di->chargalg_psy);
1334
1335
1336 case STATE_SUSPENDED:
1337
1338 break;
1339
1340 case STATE_BATT_REMOVED_INIT:
1341 abx500_chargalg_stop_charging(di);
1342 abx500_chargalg_state_to(di, STATE_BATT_REMOVED);
1343
1344
1345 case STATE_BATT_REMOVED:
1346 if (!di->events.batt_rem)
1347 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1348 break;
1349
1350 case STATE_HW_TEMP_PROTECT_INIT:
1351 abx500_chargalg_stop_charging(di);
1352 abx500_chargalg_state_to(di, STATE_HW_TEMP_PROTECT);
1353
1354
1355 case STATE_HW_TEMP_PROTECT:
1356 if (!di->events.main_thermal_prot &&
1357 !di->events.usb_thermal_prot)
1358 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1359 break;
1360
1361 case STATE_OVV_PROTECT_INIT:
1362 abx500_chargalg_stop_charging(di);
1363 abx500_chargalg_state_to(di, STATE_OVV_PROTECT);
1364
1365
1366 case STATE_OVV_PROTECT:
1367 if (!di->events.vbus_ovv &&
1368 !di->events.main_ovv &&
1369 !di->events.batt_ovv &&
1370 di->chg_info.usb_chg_ok &&
1371 di->chg_info.ac_chg_ok)
1372 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1373 break;
1374
1375 case STATE_CHG_NOT_OK_INIT:
1376 abx500_chargalg_stop_charging(di);
1377 abx500_chargalg_state_to(di, STATE_CHG_NOT_OK);
1378
1379
1380 case STATE_CHG_NOT_OK:
1381 if (!di->events.mainextchnotok &&
1382 !di->events.usbchargernotok)
1383 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1384 break;
1385
1386 case STATE_SAFETY_TIMER_EXPIRED_INIT:
1387 abx500_chargalg_stop_charging(di);
1388 abx500_chargalg_state_to(di, STATE_SAFETY_TIMER_EXPIRED);
1389
1390
1391 case STATE_SAFETY_TIMER_EXPIRED:
1392
1393 break;
1394
1395 case STATE_NORMAL_INIT:
1396 abx500_chargalg_start_charging(di,
1397 di->bat->bat_type[di->bat->batt_id].normal_vol_lvl,
1398 di->bat->bat_type[di->bat->batt_id].normal_cur_lvl);
1399 abx500_chargalg_state_to(di, STATE_NORMAL);
1400 abx500_chargalg_start_safety_timer(di);
1401 abx500_chargalg_stop_maintenance_timer(di);
1402 init_maxim_chg_curr(di);
1403 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
1404 di->eoc_cnt = 0;
1405 di->maintenance_chg = false;
1406 power_supply_changed(&di->chargalg_psy);
1407
1408 break;
1409
1410 case STATE_NORMAL:
1411 handle_maxim_chg_curr(di);
1412 if (di->charge_status == POWER_SUPPLY_STATUS_FULL &&
1413 di->maintenance_chg) {
1414 if (di->bat->no_maintenance)
1415 abx500_chargalg_state_to(di,
1416 STATE_WAIT_FOR_RECHARGE_INIT);
1417 else
1418 abx500_chargalg_state_to(di,
1419 STATE_MAINTENANCE_A_INIT);
1420 }
1421 break;
1422
1423
1424 case STATE_WAIT_FOR_RECHARGE_INIT:
1425 abx500_chargalg_hold_charging(di);
1426 abx500_chargalg_state_to(di, STATE_WAIT_FOR_RECHARGE);
1427 di->rch_cnt = RCH_COND_CNT;
1428
1429
1430 case STATE_WAIT_FOR_RECHARGE:
1431 if (di->batt_data.volt <=
1432 di->bat->bat_type[di->bat->batt_id].recharge_vol) {
1433 if (di->rch_cnt-- == 0)
1434 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1435 } else
1436 di->rch_cnt = RCH_COND_CNT;
1437 break;
1438
1439 case STATE_MAINTENANCE_A_INIT:
1440 abx500_chargalg_stop_safety_timer(di);
1441 abx500_chargalg_start_maintenance_timer(di,
1442 di->bat->bat_type[
1443 di->bat->batt_id].maint_a_chg_timer_h);
1444 abx500_chargalg_start_charging(di,
1445 di->bat->bat_type[
1446 di->bat->batt_id].maint_a_vol_lvl,
1447 di->bat->bat_type[
1448 di->bat->batt_id].maint_a_cur_lvl);
1449 abx500_chargalg_state_to(di, STATE_MAINTENANCE_A);
1450 power_supply_changed(&di->chargalg_psy);
1451
1452
1453 case STATE_MAINTENANCE_A:
1454 if (di->events.maintenance_timer_expired) {
1455 abx500_chargalg_stop_maintenance_timer(di);
1456 abx500_chargalg_state_to(di, STATE_MAINTENANCE_B_INIT);
1457 }
1458 break;
1459
1460 case STATE_MAINTENANCE_B_INIT:
1461 abx500_chargalg_start_maintenance_timer(di,
1462 di->bat->bat_type[
1463 di->bat->batt_id].maint_b_chg_timer_h);
1464 abx500_chargalg_start_charging(di,
1465 di->bat->bat_type[
1466 di->bat->batt_id].maint_b_vol_lvl,
1467 di->bat->bat_type[
1468 di->bat->batt_id].maint_b_cur_lvl);
1469 abx500_chargalg_state_to(di, STATE_MAINTENANCE_B);
1470 power_supply_changed(&di->chargalg_psy);
1471
1472
1473 case STATE_MAINTENANCE_B:
1474 if (di->events.maintenance_timer_expired) {
1475 abx500_chargalg_stop_maintenance_timer(di);
1476 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1477 }
1478 break;
1479
1480 case STATE_TEMP_LOWHIGH_INIT:
1481 abx500_chargalg_start_charging(di,
1482 di->bat->bat_type[
1483 di->bat->batt_id].low_high_vol_lvl,
1484 di->bat->bat_type[
1485 di->bat->batt_id].low_high_cur_lvl);
1486 abx500_chargalg_stop_maintenance_timer(di);
1487 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
1488 abx500_chargalg_state_to(di, STATE_TEMP_LOWHIGH);
1489 power_supply_changed(&di->chargalg_psy);
1490
1491
1492 case STATE_TEMP_LOWHIGH:
1493 if (!di->events.btemp_lowhigh)
1494 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1495 break;
1496
1497 case STATE_WD_EXPIRED_INIT:
1498 abx500_chargalg_stop_charging(di);
1499 abx500_chargalg_state_to(di, STATE_WD_EXPIRED);
1500
1501
1502 case STATE_WD_EXPIRED:
1503 if (!di->events.ac_wd_expired &&
1504 !di->events.usb_wd_expired)
1505 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1506 break;
1507
1508 case STATE_TEMP_UNDEROVER_INIT:
1509 abx500_chargalg_stop_charging(di);
1510 abx500_chargalg_state_to(di, STATE_TEMP_UNDEROVER);
1511
1512
1513 case STATE_TEMP_UNDEROVER:
1514 if (!di->events.btemp_underover)
1515 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1516 break;
1517 }
1518
1519
1520 if (di->charge_state == STATE_NORMAL_INIT ||
1521 di->charge_state == STATE_MAINTENANCE_A_INIT ||
1522 di->charge_state == STATE_MAINTENANCE_B_INIT)
1523 queue_work(di->chargalg_wq, &di->chargalg_work);
1524}
1525
1526
1527
1528
1529
1530
1531
1532static void abx500_chargalg_periodic_work(struct work_struct *work)
1533{
1534 struct abx500_chargalg *di = container_of(work,
1535 struct abx500_chargalg, chargalg_periodic_work.work);
1536
1537 abx500_chargalg_algorithm(di);
1538
1539
1540
1541
1542
1543 if (di->chg_info.conn_chg)
1544 queue_delayed_work(di->chargalg_wq,
1545 &di->chargalg_periodic_work,
1546 di->bat->interval_charging * HZ);
1547 else
1548 queue_delayed_work(di->chargalg_wq,
1549 &di->chargalg_periodic_work,
1550 di->bat->interval_not_charging * HZ);
1551}
1552
1553
1554
1555
1556
1557
1558
1559static void abx500_chargalg_wd_work(struct work_struct *work)
1560{
1561 int ret;
1562 struct abx500_chargalg *di = container_of(work,
1563 struct abx500_chargalg, chargalg_wd_work.work);
1564
1565 dev_dbg(di->dev, "abx500_chargalg_wd_work\n");
1566
1567 ret = abx500_chargalg_kick_watchdog(di);
1568 if (ret < 0)
1569 dev_err(di->dev, "failed to kick watchdog\n");
1570
1571 queue_delayed_work(di->chargalg_wq,
1572 &di->chargalg_wd_work, CHG_WD_INTERVAL);
1573}
1574
1575
1576
1577
1578
1579
1580
1581static void abx500_chargalg_work(struct work_struct *work)
1582{
1583 struct abx500_chargalg *di = container_of(work,
1584 struct abx500_chargalg, chargalg_work);
1585
1586 abx500_chargalg_algorithm(di);
1587}
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601static int abx500_chargalg_get_property(struct power_supply *psy,
1602 enum power_supply_property psp,
1603 union power_supply_propval *val)
1604{
1605 struct abx500_chargalg *di;
1606
1607 di = to_abx500_chargalg_device_info(psy);
1608
1609 switch (psp) {
1610 case POWER_SUPPLY_PROP_STATUS:
1611 val->intval = di->charge_status;
1612 break;
1613 case POWER_SUPPLY_PROP_HEALTH:
1614 if (di->events.batt_ovv) {
1615 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1616 } else if (di->events.btemp_underover) {
1617 if (di->batt_data.temp <= di->bat->temp_under)
1618 val->intval = POWER_SUPPLY_HEALTH_COLD;
1619 else
1620 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
1621 } else {
1622 val->intval = POWER_SUPPLY_HEALTH_GOOD;
1623 }
1624 break;
1625 default:
1626 return -EINVAL;
1627 }
1628 return 0;
1629}
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644static ssize_t abx500_chargalg_sysfs_charger(struct kobject *kobj,
1645 struct attribute *attr, const char *buf, size_t length)
1646{
1647 struct abx500_chargalg *di = container_of(kobj,
1648 struct abx500_chargalg, chargalg_kobject);
1649 long int param;
1650 int ac_usb;
1651 int ret;
1652 char entry = *attr->name;
1653
1654 switch (entry) {
1655 case 'c':
1656 ret = strict_strtol(buf, 10, ¶m);
1657 if (ret < 0)
1658 return ret;
1659
1660 ac_usb = param;
1661 switch (ac_usb) {
1662 case 0:
1663
1664 di->susp_status.ac_suspended = true;
1665 di->susp_status.usb_suspended = true;
1666 di->susp_status.suspended_change = true;
1667
1668 queue_work(di->chargalg_wq,
1669 &di->chargalg_work);
1670 break;
1671 case 1:
1672
1673 di->susp_status.ac_suspended = false;
1674 di->susp_status.suspended_change = true;
1675
1676 queue_work(di->chargalg_wq,
1677 &di->chargalg_work);
1678 break;
1679 case 2:
1680
1681 di->susp_status.usb_suspended = false;
1682 di->susp_status.suspended_change = true;
1683
1684 queue_work(di->chargalg_wq,
1685 &di->chargalg_work);
1686 break;
1687 default:
1688 dev_info(di->dev, "Wrong input\n"
1689 "Enter 0. Disable AC/USB Charging\n"
1690 "1. Enable AC charging\n"
1691 "2. Enable USB Charging\n");
1692 };
1693 break;
1694 };
1695 return strlen(buf);
1696}
1697
1698static struct attribute abx500_chargalg_en_charger = \
1699{
1700 .name = "chargalg",
1701 .mode = S_IWUGO,
1702};
1703
1704static struct attribute *abx500_chargalg_chg[] = {
1705 &abx500_chargalg_en_charger,
1706 NULL
1707};
1708
1709static const struct sysfs_ops abx500_chargalg_sysfs_ops = {
1710 .store = abx500_chargalg_sysfs_charger,
1711};
1712
1713static struct kobj_type abx500_chargalg_ktype = {
1714 .sysfs_ops = &abx500_chargalg_sysfs_ops,
1715 .default_attrs = abx500_chargalg_chg,
1716};
1717
1718
1719
1720
1721
1722
1723
1724static void abx500_chargalg_sysfs_exit(struct abx500_chargalg *di)
1725{
1726 kobject_del(&di->chargalg_kobject);
1727}
1728
1729
1730
1731
1732
1733
1734
1735
1736static int abx500_chargalg_sysfs_init(struct abx500_chargalg *di)
1737{
1738 int ret = 0;
1739
1740 ret = kobject_init_and_add(&di->chargalg_kobject,
1741 &abx500_chargalg_ktype,
1742 NULL, "abx500_chargalg");
1743 if (ret < 0)
1744 dev_err(di->dev, "failed to create sysfs entry\n");
1745
1746 return ret;
1747}
1748
1749
1750#if defined(CONFIG_PM)
1751static int abx500_chargalg_resume(struct platform_device *pdev)
1752{
1753 struct abx500_chargalg *di = platform_get_drvdata(pdev);
1754
1755
1756 if (di->chg_info.online_chg)
1757 queue_delayed_work(di->chargalg_wq, &di->chargalg_wd_work, 0);
1758
1759
1760
1761
1762
1763 queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1764
1765 return 0;
1766}
1767
1768static int abx500_chargalg_suspend(struct platform_device *pdev,
1769 pm_message_t state)
1770{
1771 struct abx500_chargalg *di = platform_get_drvdata(pdev);
1772
1773 if (di->chg_info.online_chg)
1774 cancel_delayed_work_sync(&di->chargalg_wd_work);
1775
1776 cancel_delayed_work_sync(&di->chargalg_periodic_work);
1777
1778 return 0;
1779}
1780#else
1781#define abx500_chargalg_suspend NULL
1782#define abx500_chargalg_resume NULL
1783#endif
1784
1785static int __devexit abx500_chargalg_remove(struct platform_device *pdev)
1786{
1787 struct abx500_chargalg *di = platform_get_drvdata(pdev);
1788
1789
1790 abx500_chargalg_sysfs_exit(di);
1791
1792
1793 destroy_workqueue(di->chargalg_wq);
1794
1795 flush_scheduled_work();
1796 power_supply_unregister(&di->chargalg_psy);
1797 platform_set_drvdata(pdev, NULL);
1798 kfree(di);
1799
1800 return 0;
1801}
1802
1803static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
1804{
1805 struct abx500_bm_plat_data *plat_data;
1806 int ret = 0;
1807
1808 struct abx500_chargalg *di =
1809 kzalloc(sizeof(struct abx500_chargalg), GFP_KERNEL);
1810 if (!di)
1811 return -ENOMEM;
1812
1813
1814 di->dev = &pdev->dev;
1815
1816 plat_data = pdev->dev.platform_data;
1817 di->pdata = plat_data->chargalg;
1818 di->bat = plat_data->battery;
1819
1820
1821 di->chargalg_psy.name = "abx500_chargalg";
1822 di->chargalg_psy.type = POWER_SUPPLY_TYPE_BATTERY;
1823 di->chargalg_psy.properties = abx500_chargalg_props;
1824 di->chargalg_psy.num_properties = ARRAY_SIZE(abx500_chargalg_props);
1825 di->chargalg_psy.get_property = abx500_chargalg_get_property;
1826 di->chargalg_psy.supplied_to = di->pdata->supplied_to;
1827 di->chargalg_psy.num_supplicants = di->pdata->num_supplicants;
1828 di->chargalg_psy.external_power_changed =
1829 abx500_chargalg_external_power_changed;
1830
1831
1832 init_timer(&di->safety_timer);
1833 di->safety_timer.function = abx500_chargalg_safety_timer_expired;
1834 di->safety_timer.data = (unsigned long) di;
1835
1836
1837 init_timer(&di->maintenance_timer);
1838 di->maintenance_timer.function =
1839 abx500_chargalg_maintenance_timer_expired;
1840 di->maintenance_timer.data = (unsigned long) di;
1841
1842
1843 di->chargalg_wq =
1844 create_singlethread_workqueue("abx500_chargalg_wq");
1845 if (di->chargalg_wq == NULL) {
1846 dev_err(di->dev, "failed to create work queue\n");
1847 goto free_device_info;
1848 }
1849
1850
1851 INIT_DELAYED_WORK_DEFERRABLE(&di->chargalg_periodic_work,
1852 abx500_chargalg_periodic_work);
1853 INIT_DELAYED_WORK_DEFERRABLE(&di->chargalg_wd_work,
1854 abx500_chargalg_wd_work);
1855
1856
1857 INIT_WORK(&di->chargalg_work, abx500_chargalg_work);
1858
1859
1860 di->chg_info.prev_conn_chg = -1;
1861
1862
1863 ret = power_supply_register(di->dev, &di->chargalg_psy);
1864 if (ret) {
1865 dev_err(di->dev, "failed to register chargalg psy\n");
1866 goto free_chargalg_wq;
1867 }
1868
1869 platform_set_drvdata(pdev, di);
1870
1871
1872 ret = abx500_chargalg_sysfs_init(di);
1873 if (ret) {
1874 dev_err(di->dev, "failed to create sysfs entry\n");
1875 goto free_psy;
1876 }
1877
1878
1879 queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1880
1881 dev_info(di->dev, "probe success\n");
1882 return ret;
1883
1884free_psy:
1885 power_supply_unregister(&di->chargalg_psy);
1886free_chargalg_wq:
1887 destroy_workqueue(di->chargalg_wq);
1888free_device_info:
1889 kfree(di);
1890
1891 return ret;
1892}
1893
1894static struct platform_driver abx500_chargalg_driver = {
1895 .probe = abx500_chargalg_probe,
1896 .remove = __devexit_p(abx500_chargalg_remove),
1897 .suspend = abx500_chargalg_suspend,
1898 .resume = abx500_chargalg_resume,
1899 .driver = {
1900 .name = "abx500-chargalg",
1901 .owner = THIS_MODULE,
1902 },
1903};
1904
1905static int __init abx500_chargalg_init(void)
1906{
1907 return platform_driver_register(&abx500_chargalg_driver);
1908}
1909
1910static void __exit abx500_chargalg_exit(void)
1911{
1912 platform_driver_unregister(&abx500_chargalg_driver);
1913}
1914
1915module_init(abx500_chargalg_init);
1916module_exit(abx500_chargalg_exit);
1917
1918MODULE_LICENSE("GPL v2");
1919MODULE_AUTHOR("Johan Palsson, Karl Komierowski");
1920MODULE_ALIAS("platform:abx500-chargalg");
1921MODULE_DESCRIPTION("abx500 battery charging algorithm");
1922