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 ab8500_chargers {
53 NO_CHG,
54 AC_CHG,
55 USB_CHG,
56};
57
58struct ab8500_chargalg_charger_info {
59 enum ab8500_chargers conn_chg;
60 enum ab8500_chargers prev_conn_chg;
61 enum ab8500_chargers online_chg;
62 enum ab8500_chargers prev_online_chg;
63 enum ab8500_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 ab8500_chargalg_suspension_status {
77 bool suspended_change;
78 bool ac_suspended;
79 bool usb_suspended;
80};
81
82struct ab8500_chargalg_current_step_status {
83 bool curr_step_change;
84 int curr_step;
85};
86
87struct ab8500_chargalg_battery_data {
88 int temp;
89 int volt;
90 int avg_curr;
91 int inst_curr;
92 int percent;
93};
94
95enum ab8500_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 * const 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 ab8500_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 ab8500_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 ab8500_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 ab8500_chargalg_states charge_state;
246 struct ab8500_charge_curr_maximization ccm;
247 struct ab8500_chargalg_charger_info chg_info;
248 struct ab8500_chargalg_battery_data batt_data;
249 struct ab8500_chargalg_suspension_status susp_status;
250 struct ab8500 *parent;
251 struct ab8500_chargalg_current_step_status curr_status;
252 struct ab8500_bm_data *bm;
253 struct power_supply *chargalg_psy;
254 struct ux500_charger *ac_chg;
255 struct ux500_charger *usb_chg;
256 struct ab8500_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 ab8500_chargalg_props[] = {
271 POWER_SUPPLY_PROP_STATUS,
272 POWER_SUPPLY_PROP_HEALTH,
273};
274
275struct ab8500_chargalg_sysfs_entry {
276 struct attribute attr;
277 ssize_t (*show)(struct ab8500_chargalg *di, char *buf);
278 ssize_t (*store)(struct ab8500_chargalg *di, const char *buf, size_t length);
279};
280
281
282
283
284
285
286
287
288static enum hrtimer_restart
289ab8500_chargalg_safety_timer_expired(struct hrtimer *timer)
290{
291 struct ab8500_chargalg *di = container_of(timer, struct ab8500_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
311ab8500_chargalg_maintenance_timer_expired(struct hrtimer *timer)
312{
313
314 struct ab8500_chargalg *di = container_of(timer, struct ab8500_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 ab8500_chargalg_state_to(struct ab8500_chargalg *di,
333 enum ab8500_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 ab8500_chargalg_check_charger_enable(struct ab8500_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 ab8500_chargalg_check_charger_connection(struct ab8500_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 ab8500_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 ab8500_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 ab8500_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 ab8500_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 ab8500_chargalg_check_current_step_status
423 (struct ab8500_chargalg *di)
424{
425 if (di->curr_status.curr_step_change)
426 ab8500_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 ab8500_chargalg_start_safety_timer(struct ab8500_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 ab8500_chargalg_stop_safety_timer(struct ab8500_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 ab8500_chargalg_start_maintenance_timer(struct ab8500_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 ab8500_chargalg_stop_maintenance_timer(struct ab8500_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 ab8500_chargalg_kick_watchdog(struct ab8500_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 } else if (di->usb_chg && di->usb_chg->ops.kick_wd &&
530 di->chg_info.online_chg & USB_CHG)
531 return di->usb_chg->ops.kick_wd(di->usb_chg);
532
533 return -ENXIO;
534}
535
536
537
538
539
540
541
542
543
544
545
546static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable,
547 int vset, int iset)
548{
549 static int ab8500_chargalg_ex_ac_enable_toggle;
550
551 if (!di->ac_chg || !di->ac_chg->ops.enable)
552 return -ENXIO;
553
554
555 if (di->ac_chg->max_out_volt)
556 vset = min(vset, di->ac_chg->max_out_volt);
557 if (di->ac_chg->max_out_curr)
558 iset = min(iset, di->ac_chg->max_out_curr);
559
560 di->chg_info.ac_iset = iset;
561 di->chg_info.ac_vset = vset;
562
563
564 if (enable && di->ac_chg->external &&
565 !ab8500_chargalg_ex_ac_enable_toggle) {
566 blocking_notifier_call_chain(&charger_notifier_list,
567 0, di->dev);
568 ab8500_chargalg_ex_ac_enable_toggle++;
569 }
570
571 return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset);
572}
573
574
575
576
577
578
579
580
581
582
583
584static int ab8500_chargalg_usb_en(struct ab8500_chargalg *di, int enable,
585 int vset, int iset)
586{
587 if (!di->usb_chg || !di->usb_chg->ops.enable)
588 return -ENXIO;
589
590
591 if (di->usb_chg->max_out_volt)
592 vset = min(vset, di->usb_chg->max_out_volt);
593 if (di->usb_chg->max_out_curr)
594 iset = min(iset, di->usb_chg->max_out_curr);
595
596 di->chg_info.usb_iset = iset;
597 di->chg_info.usb_vset = vset;
598
599 return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset);
600}
601
602
603
604
605
606
607
608
609
610static int ab8500_chargalg_update_chg_curr(struct ab8500_chargalg *di,
611 int iset)
612{
613
614 if (di->ac_chg && di->ac_chg->ops.update_curr &&
615 di->chg_info.charger_type & AC_CHG) {
616
617
618
619
620 if (di->ac_chg->max_out_curr)
621 iset = min(iset, di->ac_chg->max_out_curr);
622
623 di->chg_info.ac_iset = iset;
624
625 return di->ac_chg->ops.update_curr(di->ac_chg, iset);
626 } else if (di->usb_chg && di->usb_chg->ops.update_curr &&
627 di->chg_info.charger_type & USB_CHG) {
628
629
630
631
632 if (di->usb_chg->max_out_curr)
633 iset = min(iset, di->usb_chg->max_out_curr);
634
635 di->chg_info.usb_iset = iset;
636
637 return di->usb_chg->ops.update_curr(di->usb_chg, iset);
638 }
639
640 return -ENXIO;
641}
642
643
644
645
646
647
648
649
650
651static void ab8500_chargalg_stop_charging(struct ab8500_chargalg *di)
652{
653 ab8500_chargalg_ac_en(di, false, 0, 0);
654 ab8500_chargalg_usb_en(di, false, 0, 0);
655 ab8500_chargalg_stop_safety_timer(di);
656 ab8500_chargalg_stop_maintenance_timer(di);
657 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
658 di->maintenance_chg = false;
659 cancel_delayed_work(&di->chargalg_wd_work);
660 power_supply_changed(di->chargalg_psy);
661}
662
663
664
665
666
667
668
669
670
671static void ab8500_chargalg_hold_charging(struct ab8500_chargalg *di)
672{
673 ab8500_chargalg_ac_en(di, false, 0, 0);
674 ab8500_chargalg_usb_en(di, false, 0, 0);
675 ab8500_chargalg_stop_safety_timer(di);
676 ab8500_chargalg_stop_maintenance_timer(di);
677 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
678 di->maintenance_chg = false;
679 cancel_delayed_work(&di->chargalg_wd_work);
680 power_supply_changed(di->chargalg_psy);
681}
682
683
684
685
686
687
688
689
690
691
692static void ab8500_chargalg_start_charging(struct ab8500_chargalg *di,
693 int vset, int iset)
694{
695 switch (di->chg_info.charger_type) {
696 case AC_CHG:
697 dev_dbg(di->dev,
698 "AC parameters: Vset %d, Ich %d\n", vset, iset);
699 ab8500_chargalg_usb_en(di, false, 0, 0);
700 ab8500_chargalg_ac_en(di, true, vset, iset);
701 break;
702
703 case USB_CHG:
704 dev_dbg(di->dev,
705 "USB parameters: Vset %d, Ich %d\n", vset, iset);
706 ab8500_chargalg_ac_en(di, false, 0, 0);
707 ab8500_chargalg_usb_en(di, true, vset, iset);
708 break;
709
710 default:
711 dev_err(di->dev, "Unknown charger to charge from\n");
712 break;
713 }
714}
715
716
717
718
719
720
721
722
723static void ab8500_chargalg_check_temp(struct ab8500_chargalg *di)
724{
725 if (di->batt_data.temp > (di->bm->temp_low + di->t_hyst_norm) &&
726 di->batt_data.temp < (di->bm->temp_high - di->t_hyst_norm)) {
727
728 di->events.btemp_underover = false;
729 di->events.btemp_lowhigh = false;
730 di->t_hyst_norm = 0;
731 di->t_hyst_lowhigh = 0;
732 } else {
733 if (((di->batt_data.temp >= di->bm->temp_high) &&
734 (di->batt_data.temp <
735 (di->bm->temp_over - di->t_hyst_lowhigh))) ||
736 ((di->batt_data.temp >
737 (di->bm->temp_under + di->t_hyst_lowhigh)) &&
738 (di->batt_data.temp <= di->bm->temp_low))) {
739
740 di->events.btemp_underover = false;
741 di->events.btemp_lowhigh = true;
742 di->t_hyst_norm = di->bm->temp_hysteresis;
743 di->t_hyst_lowhigh = 0;
744 } else if (di->batt_data.temp <= di->bm->temp_under ||
745 di->batt_data.temp >= di->bm->temp_over) {
746
747 di->events.btemp_underover = true;
748 di->events.btemp_lowhigh = false;
749 di->t_hyst_norm = 0;
750 di->t_hyst_lowhigh = di->bm->temp_hysteresis;
751 } else {
752
753 dev_dbg(di->dev, "Within hysteresis limit temp: %d "
754 "hyst_lowhigh %d, hyst normal %d\n",
755 di->batt_data.temp, di->t_hyst_lowhigh,
756 di->t_hyst_norm);
757 }
758 }
759}
760
761
762
763
764
765
766
767static void ab8500_chargalg_check_charger_voltage(struct ab8500_chargalg *di)
768{
769 if (di->chg_info.usb_volt > di->bm->chg_params->usb_volt_max)
770 di->chg_info.usb_chg_ok = false;
771 else
772 di->chg_info.usb_chg_ok = true;
773
774 if (di->chg_info.ac_volt > di->bm->chg_params->ac_volt_max)
775 di->chg_info.ac_chg_ok = false;
776 else
777 di->chg_info.ac_chg_ok = true;
778
779}
780
781
782
783
784
785
786
787
788
789static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di)
790{
791 if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING &&
792 di->charge_state == STATE_NORMAL &&
793 !di->maintenance_chg && (di->batt_data.volt >=
794 di->bm->bat_type[di->bm->batt_id].termination_vol ||
795 di->events.usb_cv_active || di->events.ac_cv_active) &&
796 di->batt_data.avg_curr <
797 di->bm->bat_type[di->bm->batt_id].termination_curr &&
798 di->batt_data.avg_curr > 0) {
799 if (++di->eoc_cnt >= EOC_COND_CNT) {
800 di->eoc_cnt = 0;
801 di->charge_status = POWER_SUPPLY_STATUS_FULL;
802 di->maintenance_chg = true;
803 dev_dbg(di->dev, "EOC reached!\n");
804 power_supply_changed(di->chargalg_psy);
805 } else {
806 dev_dbg(di->dev,
807 " EOC limit reached for the %d"
808 " time, out of %d before EOC\n",
809 di->eoc_cnt,
810 EOC_COND_CNT);
811 }
812 } else {
813 di->eoc_cnt = 0;
814 }
815}
816
817static void init_maxim_chg_curr(struct ab8500_chargalg *di)
818{
819 di->ccm.original_iset =
820 di->bm->bat_type[di->bm->batt_id].normal_cur_lvl;
821 di->ccm.current_iset =
822 di->bm->bat_type[di->bm->batt_id].normal_cur_lvl;
823 di->ccm.test_delta_i = di->bm->maxi->charger_curr_step;
824 di->ccm.max_current = di->bm->maxi->chg_curr;
825 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
826 di->ccm.level = 0;
827}
828
829
830
831
832
833
834
835
836
837
838static enum maxim_ret ab8500_chargalg_chg_curr_maxim(struct ab8500_chargalg *di)
839{
840 int delta_i;
841
842 if (!di->bm->maxi->ena_maxi)
843 return MAXIM_RET_NOACTION;
844
845 delta_i = di->ccm.original_iset - di->batt_data.inst_curr;
846
847 if (di->events.vbus_collapsed) {
848 dev_dbg(di->dev, "Charger voltage has collapsed %d\n",
849 di->ccm.wait_cnt);
850 if (di->ccm.wait_cnt == 0) {
851 dev_dbg(di->dev, "lowering current\n");
852 di->ccm.wait_cnt++;
853 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
854 di->ccm.max_current =
855 di->ccm.current_iset - di->ccm.test_delta_i;
856 di->ccm.current_iset = di->ccm.max_current;
857 di->ccm.level--;
858 return MAXIM_RET_CHANGE;
859 } else {
860 dev_dbg(di->dev, "waiting\n");
861
862 di->ccm.wait_cnt = (di->ccm.wait_cnt + 1) % 3;
863 return MAXIM_RET_NOACTION;
864 }
865 }
866
867 di->ccm.wait_cnt = 0;
868
869 if (di->batt_data.inst_curr > di->ccm.original_iset) {
870 dev_dbg(di->dev, " Maximization Ibat (%dmA) too high"
871 " (limit %dmA) (current iset: %dmA)!\n",
872 di->batt_data.inst_curr, di->ccm.original_iset,
873 di->ccm.current_iset);
874
875 if (di->ccm.current_iset == di->ccm.original_iset)
876 return MAXIM_RET_NOACTION;
877
878 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
879 di->ccm.current_iset = di->ccm.original_iset;
880 di->ccm.level = 0;
881
882 return MAXIM_RET_IBAT_TOO_HIGH;
883 }
884
885 if (delta_i > di->ccm.test_delta_i &&
886 (di->ccm.current_iset + di->ccm.test_delta_i) <
887 di->ccm.max_current) {
888 if (di->ccm.condition_cnt-- == 0) {
889
890 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
891 di->ccm.current_iset += di->ccm.test_delta_i;
892 di->ccm.level++;
893 dev_dbg(di->dev, " Maximization needed, increase"
894 " with %d mA to %dmA (Optimal ibat: %d)"
895 " Level %d\n",
896 di->ccm.test_delta_i,
897 di->ccm.current_iset,
898 di->ccm.original_iset,
899 di->ccm.level);
900 return MAXIM_RET_CHANGE;
901 } else {
902 return MAXIM_RET_NOACTION;
903 }
904 } else {
905 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
906 return MAXIM_RET_NOACTION;
907 }
908}
909
910static void handle_maxim_chg_curr(struct ab8500_chargalg *di)
911{
912 enum maxim_ret ret;
913 int result;
914
915 ret = ab8500_chargalg_chg_curr_maxim(di);
916 switch (ret) {
917 case MAXIM_RET_CHANGE:
918 result = ab8500_chargalg_update_chg_curr(di,
919 di->ccm.current_iset);
920 if (result)
921 dev_err(di->dev, "failed to set chg curr\n");
922 break;
923 case MAXIM_RET_IBAT_TOO_HIGH:
924 result = ab8500_chargalg_update_chg_curr(di,
925 di->bm->bat_type[di->bm->batt_id].normal_cur_lvl);
926 if (result)
927 dev_err(di->dev, "failed to set chg curr\n");
928 break;
929
930 case MAXIM_RET_NOACTION:
931 default:
932
933 break;
934 }
935}
936
937static int ab8500_chargalg_get_ext_psy_data(struct device *dev, void *data)
938{
939 struct power_supply *psy;
940 struct power_supply *ext = dev_get_drvdata(dev);
941 const char **supplicants = (const char **)ext->supplied_to;
942 struct ab8500_chargalg *di;
943 union power_supply_propval ret;
944 int j;
945 bool capacity_updated = false;
946
947 psy = (struct power_supply *)data;
948 di = power_supply_get_drvdata(psy);
949
950 j = match_string(supplicants, ext->num_supplicants, psy->desc->name);
951 if (j < 0)
952 return 0;
953
954
955
956
957
958
959 if (!power_supply_get_property(ext, POWER_SUPPLY_PROP_CAPACITY, &ret)) {
960 di->batt_data.percent = ret.intval;
961 capacity_updated = true;
962 }
963
964
965 for (j = 0; j < ext->desc->num_properties; j++) {
966 enum power_supply_property prop;
967 prop = ext->desc->properties[j];
968
969
970
971
972 if (!di->ac_chg &&
973 ext->desc->type == POWER_SUPPLY_TYPE_MAINS)
974 di->ac_chg = psy_to_ux500_charger(ext);
975 else if (!di->usb_chg &&
976 ext->desc->type == POWER_SUPPLY_TYPE_USB)
977 di->usb_chg = psy_to_ux500_charger(ext);
978
979 if (power_supply_get_property(ext, prop, &ret))
980 continue;
981 switch (prop) {
982 case POWER_SUPPLY_PROP_PRESENT:
983 switch (ext->desc->type) {
984 case POWER_SUPPLY_TYPE_BATTERY:
985
986 if (ret.intval)
987 di->events.batt_rem = false;
988
989 else
990 di->events.batt_rem = true;
991 break;
992 case POWER_SUPPLY_TYPE_MAINS:
993
994 if (!ret.intval &&
995 (di->chg_info.conn_chg & AC_CHG)) {
996 di->chg_info.prev_conn_chg =
997 di->chg_info.conn_chg;
998 di->chg_info.conn_chg &= ~AC_CHG;
999 }
1000
1001 else if (ret.intval &&
1002 !(di->chg_info.conn_chg & AC_CHG)) {
1003 di->chg_info.prev_conn_chg =
1004 di->chg_info.conn_chg;
1005 di->chg_info.conn_chg |= AC_CHG;
1006 }
1007 break;
1008 case POWER_SUPPLY_TYPE_USB:
1009
1010 if (!ret.intval &&
1011 (di->chg_info.conn_chg & USB_CHG)) {
1012 di->chg_info.prev_conn_chg =
1013 di->chg_info.conn_chg;
1014 di->chg_info.conn_chg &= ~USB_CHG;
1015 }
1016
1017 else if (ret.intval &&
1018 !(di->chg_info.conn_chg & USB_CHG)) {
1019 di->chg_info.prev_conn_chg =
1020 di->chg_info.conn_chg;
1021 di->chg_info.conn_chg |= USB_CHG;
1022 }
1023 break;
1024 default:
1025 break;
1026 }
1027 break;
1028
1029 case POWER_SUPPLY_PROP_ONLINE:
1030 switch (ext->desc->type) {
1031 case POWER_SUPPLY_TYPE_BATTERY:
1032 break;
1033 case POWER_SUPPLY_TYPE_MAINS:
1034
1035 if (!ret.intval &&
1036 (di->chg_info.online_chg & AC_CHG)) {
1037 di->chg_info.prev_online_chg =
1038 di->chg_info.online_chg;
1039 di->chg_info.online_chg &= ~AC_CHG;
1040 }
1041
1042 else if (ret.intval &&
1043 !(di->chg_info.online_chg & AC_CHG)) {
1044 di->chg_info.prev_online_chg =
1045 di->chg_info.online_chg;
1046 di->chg_info.online_chg |= AC_CHG;
1047 queue_delayed_work(di->chargalg_wq,
1048 &di->chargalg_wd_work, 0);
1049 }
1050 break;
1051 case POWER_SUPPLY_TYPE_USB:
1052
1053 if (!ret.intval &&
1054 (di->chg_info.online_chg & USB_CHG)) {
1055 di->chg_info.prev_online_chg =
1056 di->chg_info.online_chg;
1057 di->chg_info.online_chg &= ~USB_CHG;
1058 }
1059
1060 else if (ret.intval &&
1061 !(di->chg_info.online_chg & USB_CHG)) {
1062 di->chg_info.prev_online_chg =
1063 di->chg_info.online_chg;
1064 di->chg_info.online_chg |= USB_CHG;
1065 queue_delayed_work(di->chargalg_wq,
1066 &di->chargalg_wd_work, 0);
1067 }
1068 break;
1069 default:
1070 break;
1071 }
1072 break;
1073
1074 case POWER_SUPPLY_PROP_HEALTH:
1075 switch (ext->desc->type) {
1076 case POWER_SUPPLY_TYPE_BATTERY:
1077 break;
1078 case POWER_SUPPLY_TYPE_MAINS:
1079 switch (ret.intval) {
1080 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
1081 di->events.mainextchnotok = true;
1082 di->events.main_thermal_prot = false;
1083 di->events.main_ovv = false;
1084 di->events.ac_wd_expired = false;
1085 break;
1086 case POWER_SUPPLY_HEALTH_DEAD:
1087 di->events.ac_wd_expired = true;
1088 di->events.mainextchnotok = false;
1089 di->events.main_ovv = false;
1090 di->events.main_thermal_prot = false;
1091 break;
1092 case POWER_SUPPLY_HEALTH_COLD:
1093 case POWER_SUPPLY_HEALTH_OVERHEAT:
1094 di->events.main_thermal_prot = true;
1095 di->events.mainextchnotok = false;
1096 di->events.main_ovv = false;
1097 di->events.ac_wd_expired = false;
1098 break;
1099 case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1100 di->events.main_ovv = true;
1101 di->events.mainextchnotok = false;
1102 di->events.main_thermal_prot = false;
1103 di->events.ac_wd_expired = false;
1104 break;
1105 case POWER_SUPPLY_HEALTH_GOOD:
1106 di->events.main_thermal_prot = false;
1107 di->events.mainextchnotok = false;
1108 di->events.main_ovv = false;
1109 di->events.ac_wd_expired = false;
1110 break;
1111 default:
1112 break;
1113 }
1114 break;
1115
1116 case POWER_SUPPLY_TYPE_USB:
1117 switch (ret.intval) {
1118 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
1119 di->events.usbchargernotok = true;
1120 di->events.usb_thermal_prot = false;
1121 di->events.vbus_ovv = false;
1122 di->events.usb_wd_expired = false;
1123 break;
1124 case POWER_SUPPLY_HEALTH_DEAD:
1125 di->events.usb_wd_expired = true;
1126 di->events.usbchargernotok = false;
1127 di->events.usb_thermal_prot = false;
1128 di->events.vbus_ovv = false;
1129 break;
1130 case POWER_SUPPLY_HEALTH_COLD:
1131 case POWER_SUPPLY_HEALTH_OVERHEAT:
1132 di->events.usb_thermal_prot = true;
1133 di->events.usbchargernotok = false;
1134 di->events.vbus_ovv = false;
1135 di->events.usb_wd_expired = false;
1136 break;
1137 case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1138 di->events.vbus_ovv = true;
1139 di->events.usbchargernotok = false;
1140 di->events.usb_thermal_prot = false;
1141 di->events.usb_wd_expired = false;
1142 break;
1143 case POWER_SUPPLY_HEALTH_GOOD:
1144 di->events.usbchargernotok = false;
1145 di->events.usb_thermal_prot = false;
1146 di->events.vbus_ovv = false;
1147 di->events.usb_wd_expired = false;
1148 break;
1149 default:
1150 break;
1151 }
1152 break;
1153 default:
1154 break;
1155 }
1156 break;
1157
1158 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1159 switch (ext->desc->type) {
1160 case POWER_SUPPLY_TYPE_BATTERY:
1161 di->batt_data.volt = ret.intval / 1000;
1162 break;
1163 case POWER_SUPPLY_TYPE_MAINS:
1164 di->chg_info.ac_volt = ret.intval / 1000;
1165 break;
1166 case POWER_SUPPLY_TYPE_USB:
1167 di->chg_info.usb_volt = ret.intval / 1000;
1168 break;
1169 default:
1170 break;
1171 }
1172 break;
1173
1174 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
1175 switch (ext->desc->type) {
1176 case POWER_SUPPLY_TYPE_MAINS:
1177
1178
1179 if (ret.intval)
1180 di->events.ac_cv_active = true;
1181 else
1182 di->events.ac_cv_active = false;
1183
1184 break;
1185 case POWER_SUPPLY_TYPE_USB:
1186
1187
1188 if (ret.intval)
1189 di->events.usb_cv_active = true;
1190 else
1191 di->events.usb_cv_active = false;
1192
1193 break;
1194 default:
1195 break;
1196 }
1197 break;
1198
1199 case POWER_SUPPLY_PROP_TECHNOLOGY:
1200 switch (ext->desc->type) {
1201 case POWER_SUPPLY_TYPE_BATTERY:
1202 if (ret.intval)
1203 di->events.batt_unknown = false;
1204 else
1205 di->events.batt_unknown = true;
1206
1207 break;
1208 default:
1209 break;
1210 }
1211 break;
1212
1213 case POWER_SUPPLY_PROP_TEMP:
1214 di->batt_data.temp = ret.intval / 10;
1215 break;
1216
1217 case POWER_SUPPLY_PROP_CURRENT_NOW:
1218 switch (ext->desc->type) {
1219 case POWER_SUPPLY_TYPE_MAINS:
1220 di->chg_info.ac_curr =
1221 ret.intval / 1000;
1222 break;
1223 case POWER_SUPPLY_TYPE_USB:
1224 di->chg_info.usb_curr =
1225 ret.intval / 1000;
1226 break;
1227 case POWER_SUPPLY_TYPE_BATTERY:
1228 di->batt_data.inst_curr = ret.intval / 1000;
1229 break;
1230 default:
1231 break;
1232 }
1233 break;
1234
1235 case POWER_SUPPLY_PROP_CURRENT_AVG:
1236 switch (ext->desc->type) {
1237 case POWER_SUPPLY_TYPE_BATTERY:
1238 di->batt_data.avg_curr = ret.intval / 1000;
1239 break;
1240 case POWER_SUPPLY_TYPE_USB:
1241 if (ret.intval)
1242 di->events.vbus_collapsed = true;
1243 else
1244 di->events.vbus_collapsed = false;
1245 break;
1246 default:
1247 break;
1248 }
1249 break;
1250 case POWER_SUPPLY_PROP_CAPACITY:
1251 if (!capacity_updated)
1252 di->batt_data.percent = ret.intval;
1253 break;
1254 default:
1255 break;
1256 }
1257 }
1258 return 0;
1259}
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270static void ab8500_chargalg_external_power_changed(struct power_supply *psy)
1271{
1272 struct ab8500_chargalg *di = power_supply_get_drvdata(psy);
1273
1274
1275
1276
1277
1278 if (di->chargalg_wq)
1279 queue_work(di->chargalg_wq, &di->chargalg_work);
1280}
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290static void ab8500_chargalg_algorithm(struct ab8500_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, ab8500_chargalg_get_ext_psy_data);
1299
1300 ab8500_chargalg_end_of_charge(di);
1301 ab8500_chargalg_check_temp(di);
1302 ab8500_chargalg_check_charger_voltage(di);
1303
1304 charger_status = ab8500_chargalg_check_charger_connection(di);
1305 ab8500_chargalg_check_current_step_status(di);
1306
1307 if (is_ab8500(di->parent)) {
1308 ret = ab8500_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 ab8500_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 ab8500_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 ab8500_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 ab8500_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 ab8500_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 ab8500_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 ab8500_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 ab8500_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 ab8500_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 ab8500_chargalg_stop_charging(di);
1423 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
1424 ab8500_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 ab8500_chargalg_ac_en(di, false, 0, 0);
1433 if (di->susp_status.usb_suspended)
1434 ab8500_chargalg_usb_en(di, false, 0, 0);
1435 ab8500_chargalg_stop_safety_timer(di);
1436 ab8500_chargalg_stop_maintenance_timer(di);
1437 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1438 di->maintenance_chg = false;
1439 ab8500_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 ab8500_chargalg_stop_charging(di);
1449 ab8500_chargalg_state_to(di, STATE_BATT_REMOVED);
1450 fallthrough;
1451
1452 case STATE_BATT_REMOVED:
1453 if (!di->events.batt_rem)
1454 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1455 break;
1456
1457 case STATE_HW_TEMP_PROTECT_INIT:
1458 ab8500_chargalg_stop_charging(di);
1459 ab8500_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 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1466 break;
1467
1468 case STATE_OVV_PROTECT_INIT:
1469 ab8500_chargalg_stop_charging(di);
1470 ab8500_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 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1480 break;
1481
1482 case STATE_CHG_NOT_OK_INIT:
1483 ab8500_chargalg_stop_charging(di);
1484 ab8500_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 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1491 break;
1492
1493 case STATE_SAFETY_TIMER_EXPIRED_INIT:
1494 ab8500_chargalg_stop_charging(di);
1495 ab8500_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 ab8500_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 ab8500_chargalg_start_charging(di,
1511 di->bm->bat_type[di->bm->batt_id]
1512 .normal_vol_lvl, curr_step_lvl);
1513 }
1514
1515 ab8500_chargalg_state_to(di, STATE_NORMAL);
1516 ab8500_chargalg_start_safety_timer(di);
1517 ab8500_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 ab8500_chargalg_state_to(di,
1532 STATE_WAIT_FOR_RECHARGE_INIT);
1533 else
1534 ab8500_chargalg_state_to(di,
1535 STATE_MAINTENANCE_A_INIT);
1536 }
1537 break;
1538
1539
1540 case STATE_WAIT_FOR_RECHARGE_INIT:
1541 ab8500_chargalg_hold_charging(di);
1542 ab8500_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].recharge_cap)
1548 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1549 break;
1550
1551 case STATE_MAINTENANCE_A_INIT:
1552 ab8500_chargalg_stop_safety_timer(di);
1553 ab8500_chargalg_start_maintenance_timer(di,
1554 di->bm->bat_type[
1555 di->bm->batt_id].maint_a_chg_timer_h);
1556 ab8500_chargalg_start_charging(di,
1557 di->bm->bat_type[
1558 di->bm->batt_id].maint_a_vol_lvl,
1559 di->bm->bat_type[
1560 di->bm->batt_id].maint_a_cur_lvl);
1561 ab8500_chargalg_state_to(di, STATE_MAINTENANCE_A);
1562 power_supply_changed(di->chargalg_psy);
1563 fallthrough;
1564
1565 case STATE_MAINTENANCE_A:
1566 if (di->events.maintenance_timer_expired) {
1567 ab8500_chargalg_stop_maintenance_timer(di);
1568 ab8500_chargalg_state_to(di, STATE_MAINTENANCE_B_INIT);
1569 }
1570 break;
1571
1572 case STATE_MAINTENANCE_B_INIT:
1573 ab8500_chargalg_start_maintenance_timer(di,
1574 di->bm->bat_type[
1575 di->bm->batt_id].maint_b_chg_timer_h);
1576 ab8500_chargalg_start_charging(di,
1577 di->bm->bat_type[
1578 di->bm->batt_id].maint_b_vol_lvl,
1579 di->bm->bat_type[
1580 di->bm->batt_id].maint_b_cur_lvl);
1581 ab8500_chargalg_state_to(di, STATE_MAINTENANCE_B);
1582 power_supply_changed(di->chargalg_psy);
1583 fallthrough;
1584
1585 case STATE_MAINTENANCE_B:
1586 if (di->events.maintenance_timer_expired) {
1587 ab8500_chargalg_stop_maintenance_timer(di);
1588 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1589 }
1590 break;
1591
1592 case STATE_TEMP_LOWHIGH_INIT:
1593 ab8500_chargalg_start_charging(di,
1594 di->bm->bat_type[
1595 di->bm->batt_id].low_high_vol_lvl,
1596 di->bm->bat_type[
1597 di->bm->batt_id].low_high_cur_lvl);
1598 ab8500_chargalg_stop_maintenance_timer(di);
1599 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
1600 ab8500_chargalg_state_to(di, STATE_TEMP_LOWHIGH);
1601 power_supply_changed(di->chargalg_psy);
1602 fallthrough;
1603
1604 case STATE_TEMP_LOWHIGH:
1605 if (!di->events.btemp_lowhigh)
1606 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1607 break;
1608
1609 case STATE_WD_EXPIRED_INIT:
1610 ab8500_chargalg_stop_charging(di);
1611 ab8500_chargalg_state_to(di, STATE_WD_EXPIRED);
1612 fallthrough;
1613
1614 case STATE_WD_EXPIRED:
1615 if (!di->events.ac_wd_expired &&
1616 !di->events.usb_wd_expired)
1617 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1618 break;
1619
1620 case STATE_TEMP_UNDEROVER_INIT:
1621 ab8500_chargalg_stop_charging(di);
1622 ab8500_chargalg_state_to(di, STATE_TEMP_UNDEROVER);
1623 fallthrough;
1624
1625 case STATE_TEMP_UNDEROVER:
1626 if (!di->events.btemp_underover)
1627 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1628 break;
1629 }
1630
1631
1632 if (di->charge_state == STATE_NORMAL_INIT ||
1633 di->charge_state == STATE_MAINTENANCE_A_INIT ||
1634 di->charge_state == STATE_MAINTENANCE_B_INIT)
1635 queue_work(di->chargalg_wq, &di->chargalg_work);
1636}
1637
1638
1639
1640
1641
1642
1643
1644static void ab8500_chargalg_periodic_work(struct work_struct *work)
1645{
1646 struct ab8500_chargalg *di = container_of(work,
1647 struct ab8500_chargalg, chargalg_periodic_work.work);
1648
1649 ab8500_chargalg_algorithm(di);
1650
1651
1652
1653
1654
1655 if (di->chg_info.conn_chg)
1656 queue_delayed_work(di->chargalg_wq,
1657 &di->chargalg_periodic_work,
1658 di->bm->interval_charging * HZ);
1659 else
1660 queue_delayed_work(di->chargalg_wq,
1661 &di->chargalg_periodic_work,
1662 di->bm->interval_not_charging * HZ);
1663}
1664
1665
1666
1667
1668
1669
1670
1671static void ab8500_chargalg_wd_work(struct work_struct *work)
1672{
1673 int ret;
1674 struct ab8500_chargalg *di = container_of(work,
1675 struct ab8500_chargalg, chargalg_wd_work.work);
1676
1677 ret = ab8500_chargalg_kick_watchdog(di);
1678 if (ret < 0)
1679 dev_err(di->dev, "failed to kick watchdog\n");
1680
1681 queue_delayed_work(di->chargalg_wq,
1682 &di->chargalg_wd_work, CHG_WD_INTERVAL);
1683}
1684
1685
1686
1687
1688
1689
1690
1691static void ab8500_chargalg_work(struct work_struct *work)
1692{
1693 struct ab8500_chargalg *di = container_of(work,
1694 struct ab8500_chargalg, chargalg_work);
1695
1696 ab8500_chargalg_algorithm(di);
1697}
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711static int ab8500_chargalg_get_property(struct power_supply *psy,
1712 enum power_supply_property psp,
1713 union power_supply_propval *val)
1714{
1715 struct ab8500_chargalg *di = power_supply_get_drvdata(psy);
1716
1717 switch (psp) {
1718 case POWER_SUPPLY_PROP_STATUS:
1719 val->intval = di->charge_status;
1720 break;
1721 case POWER_SUPPLY_PROP_HEALTH:
1722 if (di->events.batt_ovv) {
1723 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1724 } else if (di->events.btemp_underover) {
1725 if (di->batt_data.temp <= di->bm->temp_under)
1726 val->intval = POWER_SUPPLY_HEALTH_COLD;
1727 else
1728 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
1729 } else if (di->charge_state == STATE_SAFETY_TIMER_EXPIRED ||
1730 di->charge_state == STATE_SAFETY_TIMER_EXPIRED_INIT) {
1731 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
1732 } else {
1733 val->intval = POWER_SUPPLY_HEALTH_GOOD;
1734 }
1735 break;
1736 default:
1737 return -EINVAL;
1738 }
1739 return 0;
1740}
1741
1742
1743
1744static ssize_t ab8500_chargalg_curr_step_show(struct ab8500_chargalg *di,
1745 char *buf)
1746{
1747 return sprintf(buf, "%d\n", di->curr_status.curr_step);
1748}
1749
1750static ssize_t ab8500_chargalg_curr_step_store(struct ab8500_chargalg *di,
1751 const char *buf, size_t length)
1752{
1753 long param;
1754 int ret;
1755
1756 ret = kstrtol(buf, 10, ¶m);
1757 if (ret < 0)
1758 return ret;
1759
1760 di->curr_status.curr_step = param;
1761 if (di->curr_status.curr_step >= CHARGALG_CURR_STEP_LOW &&
1762 di->curr_status.curr_step <= CHARGALG_CURR_STEP_HIGH) {
1763 di->curr_status.curr_step_change = true;
1764 queue_work(di->chargalg_wq, &di->chargalg_work);
1765 } else
1766 dev_info(di->dev, "Wrong current step\n"
1767 "Enter 0. Disable AC/USB Charging\n"
1768 "1--100. Set AC/USB charging current step\n"
1769 "100. Enable AC/USB Charging\n");
1770
1771 return strlen(buf);
1772}
1773
1774
1775static ssize_t ab8500_chargalg_en_show(struct ab8500_chargalg *di,
1776 char *buf)
1777{
1778 return sprintf(buf, "%d\n",
1779 di->susp_status.ac_suspended &&
1780 di->susp_status.usb_suspended);
1781}
1782
1783static ssize_t ab8500_chargalg_en_store(struct ab8500_chargalg *di,
1784 const char *buf, size_t length)
1785{
1786 long param;
1787 int ac_usb;
1788 int ret;
1789
1790 ret = kstrtol(buf, 10, ¶m);
1791 if (ret < 0)
1792 return ret;
1793
1794 ac_usb = param;
1795 switch (ac_usb) {
1796 case 0:
1797
1798 di->susp_status.ac_suspended = true;
1799 di->susp_status.usb_suspended = true;
1800 di->susp_status.suspended_change = true;
1801
1802 queue_work(di->chargalg_wq,
1803 &di->chargalg_work);
1804 break;
1805 case 1:
1806
1807 di->susp_status.ac_suspended = false;
1808 di->susp_status.suspended_change = true;
1809
1810 queue_work(di->chargalg_wq,
1811 &di->chargalg_work);
1812 break;
1813 case 2:
1814
1815 di->susp_status.usb_suspended = false;
1816 di->susp_status.suspended_change = true;
1817
1818 queue_work(di->chargalg_wq,
1819 &di->chargalg_work);
1820 break;
1821 default:
1822 dev_info(di->dev, "Wrong input\n"
1823 "Enter 0. Disable AC/USB Charging\n"
1824 "1. Enable AC charging\n"
1825 "2. Enable USB Charging\n");
1826 }
1827 return strlen(buf);
1828}
1829
1830static struct ab8500_chargalg_sysfs_entry ab8500_chargalg_en_charger =
1831 __ATTR(chargalg, 0644, ab8500_chargalg_en_show,
1832 ab8500_chargalg_en_store);
1833
1834static struct ab8500_chargalg_sysfs_entry ab8500_chargalg_curr_step =
1835 __ATTR(chargalg_curr_step, 0644, ab8500_chargalg_curr_step_show,
1836 ab8500_chargalg_curr_step_store);
1837
1838static ssize_t ab8500_chargalg_sysfs_show(struct kobject *kobj,
1839 struct attribute *attr, char *buf)
1840{
1841 struct ab8500_chargalg_sysfs_entry *entry = container_of(attr,
1842 struct ab8500_chargalg_sysfs_entry, attr);
1843
1844 struct ab8500_chargalg *di = container_of(kobj,
1845 struct ab8500_chargalg, chargalg_kobject);
1846
1847 if (!entry->show)
1848 return -EIO;
1849
1850 return entry->show(di, buf);
1851}
1852
1853static ssize_t ab8500_chargalg_sysfs_charger(struct kobject *kobj,
1854 struct attribute *attr, const char *buf, size_t length)
1855{
1856 struct ab8500_chargalg_sysfs_entry *entry = container_of(attr,
1857 struct ab8500_chargalg_sysfs_entry, attr);
1858
1859 struct ab8500_chargalg *di = container_of(kobj,
1860 struct ab8500_chargalg, chargalg_kobject);
1861
1862 if (!entry->store)
1863 return -EIO;
1864
1865 return entry->store(di, buf, length);
1866}
1867
1868static struct attribute *ab8500_chargalg_chg[] = {
1869 &ab8500_chargalg_en_charger.attr,
1870 &ab8500_chargalg_curr_step.attr,
1871 NULL,
1872};
1873
1874static const struct sysfs_ops ab8500_chargalg_sysfs_ops = {
1875 .show = ab8500_chargalg_sysfs_show,
1876 .store = ab8500_chargalg_sysfs_charger,
1877};
1878
1879static struct kobj_type ab8500_chargalg_ktype = {
1880 .sysfs_ops = &ab8500_chargalg_sysfs_ops,
1881 .default_attrs = ab8500_chargalg_chg,
1882};
1883
1884
1885
1886
1887
1888
1889
1890static void ab8500_chargalg_sysfs_exit(struct ab8500_chargalg *di)
1891{
1892 kobject_del(&di->chargalg_kobject);
1893}
1894
1895
1896
1897
1898
1899
1900
1901
1902static int ab8500_chargalg_sysfs_init(struct ab8500_chargalg *di)
1903{
1904 int ret = 0;
1905
1906 ret = kobject_init_and_add(&di->chargalg_kobject,
1907 &ab8500_chargalg_ktype,
1908 NULL, "ab8500_chargalg");
1909 if (ret < 0)
1910 dev_err(di->dev, "failed to create sysfs entry\n");
1911
1912 return ret;
1913}
1914
1915
1916static int __maybe_unused ab8500_chargalg_resume(struct device *dev)
1917{
1918 struct ab8500_chargalg *di = dev_get_drvdata(dev);
1919
1920
1921 if (di->chg_info.online_chg)
1922 queue_delayed_work(di->chargalg_wq, &di->chargalg_wd_work, 0);
1923
1924
1925
1926
1927
1928 queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1929
1930 return 0;
1931}
1932
1933static int __maybe_unused ab8500_chargalg_suspend(struct device *dev)
1934{
1935 struct ab8500_chargalg *di = dev_get_drvdata(dev);
1936
1937 if (di->chg_info.online_chg)
1938 cancel_delayed_work_sync(&di->chargalg_wd_work);
1939
1940 cancel_delayed_work_sync(&di->chargalg_periodic_work);
1941
1942 return 0;
1943}
1944
1945static char *supply_interface[] = {
1946 "ab8500_fg",
1947};
1948
1949static const struct power_supply_desc ab8500_chargalg_desc = {
1950 .name = "ab8500_chargalg",
1951 .type = POWER_SUPPLY_TYPE_BATTERY,
1952 .properties = ab8500_chargalg_props,
1953 .num_properties = ARRAY_SIZE(ab8500_chargalg_props),
1954 .get_property = ab8500_chargalg_get_property,
1955 .external_power_changed = ab8500_chargalg_external_power_changed,
1956};
1957
1958static int ab8500_chargalg_bind(struct device *dev, struct device *master,
1959 void *data)
1960{
1961 struct ab8500_chargalg *di = dev_get_drvdata(dev);
1962
1963
1964 di->chargalg_wq = alloc_ordered_workqueue("ab8500_chargalg_wq",
1965 WQ_MEM_RECLAIM);
1966 if (di->chargalg_wq == NULL) {
1967 dev_err(di->dev, "failed to create work queue\n");
1968 return -ENOMEM;
1969 }
1970
1971
1972 queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1973
1974 return 0;
1975}
1976
1977static void ab8500_chargalg_unbind(struct device *dev, struct device *master,
1978 void *data)
1979{
1980 struct ab8500_chargalg *di = dev_get_drvdata(dev);
1981
1982
1983 hrtimer_cancel(&di->safety_timer);
1984 hrtimer_cancel(&di->maintenance_timer);
1985
1986 cancel_delayed_work_sync(&di->chargalg_periodic_work);
1987 cancel_delayed_work_sync(&di->chargalg_wd_work);
1988 cancel_work_sync(&di->chargalg_work);
1989
1990
1991 destroy_workqueue(di->chargalg_wq);
1992 flush_scheduled_work();
1993}
1994
1995static const struct component_ops ab8500_chargalg_component_ops = {
1996 .bind = ab8500_chargalg_bind,
1997 .unbind = ab8500_chargalg_unbind,
1998};
1999
2000static int ab8500_chargalg_probe(struct platform_device *pdev)
2001{
2002 struct device *dev = &pdev->dev;
2003 struct power_supply_config psy_cfg = {};
2004 struct ab8500_chargalg *di;
2005 int ret = 0;
2006
2007 di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL);
2008 if (!di)
2009 return -ENOMEM;
2010
2011 di->bm = &ab8500_bm_data;
2012
2013
2014 di->dev = dev;
2015 di->parent = dev_get_drvdata(pdev->dev.parent);
2016
2017 psy_cfg.supplied_to = supply_interface;
2018 psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface);
2019 psy_cfg.drv_data = di;
2020
2021
2022 hrtimer_init(&di->safety_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
2023 di->safety_timer.function = ab8500_chargalg_safety_timer_expired;
2024
2025
2026 hrtimer_init(&di->maintenance_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
2027 di->maintenance_timer.function =
2028 ab8500_chargalg_maintenance_timer_expired;
2029
2030
2031 INIT_DEFERRABLE_WORK(&di->chargalg_periodic_work,
2032 ab8500_chargalg_periodic_work);
2033 INIT_DEFERRABLE_WORK(&di->chargalg_wd_work,
2034 ab8500_chargalg_wd_work);
2035
2036
2037 INIT_WORK(&di->chargalg_work, ab8500_chargalg_work);
2038
2039
2040 di->chg_info.prev_conn_chg = -1;
2041
2042
2043 di->chargalg_psy = devm_power_supply_register(di->dev,
2044 &ab8500_chargalg_desc,
2045 &psy_cfg);
2046 if (IS_ERR(di->chargalg_psy)) {
2047 dev_err(di->dev, "failed to register chargalg psy\n");
2048 return PTR_ERR(di->chargalg_psy);
2049 }
2050
2051 platform_set_drvdata(pdev, di);
2052
2053
2054 ret = ab8500_chargalg_sysfs_init(di);
2055 if (ret) {
2056 dev_err(di->dev, "failed to create sysfs entry\n");
2057 return ret;
2058 }
2059 di->curr_status.curr_step = CHARGALG_CURR_STEP_HIGH;
2060
2061 dev_info(di->dev, "probe success\n");
2062 return component_add(dev, &ab8500_chargalg_component_ops);
2063}
2064
2065static int ab8500_chargalg_remove(struct platform_device *pdev)
2066{
2067 struct ab8500_chargalg *di = platform_get_drvdata(pdev);
2068
2069 component_del(&pdev->dev, &ab8500_chargalg_component_ops);
2070
2071
2072 ab8500_chargalg_sysfs_exit(di);
2073
2074 return 0;
2075}
2076
2077static SIMPLE_DEV_PM_OPS(ab8500_chargalg_pm_ops, ab8500_chargalg_suspend, ab8500_chargalg_resume);
2078
2079static const struct of_device_id ab8500_chargalg_match[] = {
2080 { .compatible = "stericsson,ab8500-chargalg", },
2081 { },
2082};
2083
2084struct platform_driver ab8500_chargalg_driver = {
2085 .probe = ab8500_chargalg_probe,
2086 .remove = ab8500_chargalg_remove,
2087 .driver = {
2088 .name = "ab8500_chargalg",
2089 .of_match_table = ab8500_chargalg_match,
2090 .pm = &ab8500_chargalg_pm_ops,
2091 },
2092};
2093MODULE_LICENSE("GPL v2");
2094MODULE_AUTHOR("Johan Palsson, Karl Komierowski");
2095MODULE_ALIAS("platform:ab8500-chargalg");
2096MODULE_DESCRIPTION("ab8500 battery charging algorithm");
2097