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