0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/init.h>
0016 #include <linux/module.h>
0017 #include <linux/device.h>
0018 #include <linux/component.h>
0019 #include <linux/hrtimer.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/delay.h>
0022 #include <linux/slab.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/power_supply.h>
0025 #include <linux/completion.h>
0026 #include <linux/workqueue.h>
0027 #include <linux/kobject.h>
0028 #include <linux/of.h>
0029 #include <linux/mfd/core.h>
0030 #include <linux/mfd/abx500.h>
0031 #include <linux/mfd/abx500/ab8500.h>
0032 #include <linux/notifier.h>
0033
0034 #include "ab8500-bm.h"
0035 #include "ab8500-chargalg.h"
0036
0037
0038 #define CHG_WD_INTERVAL (6 * HZ)
0039
0040
0041 #define EOC_COND_CNT 10
0042
0043
0044 #define ONE_HOUR_IN_SECONDS 3600
0045
0046
0047 #define FIVE_MINUTES_IN_SECONDS 300
0048
0049
0050
0051
0052
0053
0054 #define AB8500_RECHARGE_CAP 95
0055
0056 enum ab8500_chargers {
0057 NO_CHG,
0058 AC_CHG,
0059 USB_CHG,
0060 };
0061
0062 struct ab8500_chargalg_charger_info {
0063 enum ab8500_chargers conn_chg;
0064 enum ab8500_chargers prev_conn_chg;
0065 enum ab8500_chargers online_chg;
0066 enum ab8500_chargers prev_online_chg;
0067 enum ab8500_chargers charger_type;
0068 bool usb_chg_ok;
0069 bool ac_chg_ok;
0070 int usb_volt_uv;
0071 int usb_curr_ua;
0072 int ac_volt_uv;
0073 int ac_curr_ua;
0074 int usb_vset_uv;
0075 int usb_iset_ua;
0076 int ac_vset_uv;
0077 int ac_iset_ua;
0078 };
0079
0080 struct ab8500_chargalg_battery_data {
0081 int temp;
0082 int volt_uv;
0083 int avg_curr_ua;
0084 int inst_curr_ua;
0085 int percent;
0086 };
0087
0088 enum ab8500_chargalg_states {
0089 STATE_HANDHELD_INIT,
0090 STATE_HANDHELD,
0091 STATE_CHG_NOT_OK_INIT,
0092 STATE_CHG_NOT_OK,
0093 STATE_HW_TEMP_PROTECT_INIT,
0094 STATE_HW_TEMP_PROTECT,
0095 STATE_NORMAL_INIT,
0096 STATE_NORMAL,
0097 STATE_WAIT_FOR_RECHARGE_INIT,
0098 STATE_WAIT_FOR_RECHARGE,
0099 STATE_MAINTENANCE_A_INIT,
0100 STATE_MAINTENANCE_A,
0101 STATE_MAINTENANCE_B_INIT,
0102 STATE_MAINTENANCE_B,
0103 STATE_TEMP_UNDEROVER_INIT,
0104 STATE_TEMP_UNDEROVER,
0105 STATE_TEMP_LOWHIGH_INIT,
0106 STATE_TEMP_LOWHIGH,
0107 STATE_OVV_PROTECT_INIT,
0108 STATE_OVV_PROTECT,
0109 STATE_SAFETY_TIMER_EXPIRED_INIT,
0110 STATE_SAFETY_TIMER_EXPIRED,
0111 STATE_BATT_REMOVED_INIT,
0112 STATE_BATT_REMOVED,
0113 STATE_WD_EXPIRED_INIT,
0114 STATE_WD_EXPIRED,
0115 };
0116
0117 static const char * const states[] = {
0118 "HANDHELD_INIT",
0119 "HANDHELD",
0120 "CHG_NOT_OK_INIT",
0121 "CHG_NOT_OK",
0122 "HW_TEMP_PROTECT_INIT",
0123 "HW_TEMP_PROTECT",
0124 "NORMAL_INIT",
0125 "NORMAL",
0126 "WAIT_FOR_RECHARGE_INIT",
0127 "WAIT_FOR_RECHARGE",
0128 "MAINTENANCE_A_INIT",
0129 "MAINTENANCE_A",
0130 "MAINTENANCE_B_INIT",
0131 "MAINTENANCE_B",
0132 "TEMP_UNDEROVER_INIT",
0133 "TEMP_UNDEROVER",
0134 "TEMP_LOWHIGH_INIT",
0135 "TEMP_LOWHIGH",
0136 "OVV_PROTECT_INIT",
0137 "OVV_PROTECT",
0138 "SAFETY_TIMER_EXPIRED_INIT",
0139 "SAFETY_TIMER_EXPIRED",
0140 "BATT_REMOVED_INIT",
0141 "BATT_REMOVED",
0142 "WD_EXPIRED_INIT",
0143 "WD_EXPIRED",
0144 };
0145
0146 struct ab8500_chargalg_events {
0147 bool batt_unknown;
0148 bool mainextchnotok;
0149 bool batt_ovv;
0150 bool batt_rem;
0151 bool btemp_underover;
0152 bool btemp_low;
0153 bool btemp_high;
0154 bool main_thermal_prot;
0155 bool usb_thermal_prot;
0156 bool main_ovv;
0157 bool vbus_ovv;
0158 bool usbchargernotok;
0159 bool safety_timer_expired;
0160 bool maintenance_timer_expired;
0161 bool ac_wd_expired;
0162 bool usb_wd_expired;
0163 bool ac_cv_active;
0164 bool usb_cv_active;
0165 bool vbus_collapsed;
0166 };
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 struct ab8500_charge_curr_maximization {
0182 int original_iset_ua;
0183 int current_iset_ua;
0184 int condition_cnt;
0185 int max_current_ua;
0186 int wait_cnt;
0187 u8 level;
0188 };
0189
0190 enum maxim_ret {
0191 MAXIM_RET_NOACTION,
0192 MAXIM_RET_CHANGE,
0193 MAXIM_RET_IBAT_TOO_HIGH,
0194 };
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223 struct ab8500_chargalg {
0224 struct device *dev;
0225 int charge_status;
0226 int eoc_cnt;
0227 bool maintenance_chg;
0228 int t_hyst_norm;
0229 int t_hyst_lowhigh;
0230 enum ab8500_chargalg_states charge_state;
0231 struct ab8500_charge_curr_maximization ccm;
0232 struct ab8500_chargalg_charger_info chg_info;
0233 struct ab8500_chargalg_battery_data batt_data;
0234 struct ab8500 *parent;
0235 struct ab8500_bm_data *bm;
0236 struct power_supply *chargalg_psy;
0237 struct ux500_charger *ac_chg;
0238 struct ux500_charger *usb_chg;
0239 struct ab8500_chargalg_events events;
0240 struct workqueue_struct *chargalg_wq;
0241 struct delayed_work chargalg_periodic_work;
0242 struct delayed_work chargalg_wd_work;
0243 struct work_struct chargalg_work;
0244 struct hrtimer safety_timer;
0245 struct hrtimer maintenance_timer;
0246 struct kobject chargalg_kobject;
0247 };
0248
0249
0250 static enum power_supply_property ab8500_chargalg_props[] = {
0251 POWER_SUPPLY_PROP_STATUS,
0252 POWER_SUPPLY_PROP_HEALTH,
0253 };
0254
0255 struct ab8500_chargalg_sysfs_entry {
0256 struct attribute attr;
0257 ssize_t (*show)(struct ab8500_chargalg *di, char *buf);
0258 ssize_t (*store)(struct ab8500_chargalg *di, const char *buf, size_t length);
0259 };
0260
0261
0262
0263
0264
0265
0266
0267
0268 static enum hrtimer_restart
0269 ab8500_chargalg_safety_timer_expired(struct hrtimer *timer)
0270 {
0271 struct ab8500_chargalg *di = container_of(timer, struct ab8500_chargalg,
0272 safety_timer);
0273 dev_err(di->dev, "Safety timer expired\n");
0274 di->events.safety_timer_expired = true;
0275
0276
0277 queue_work(di->chargalg_wq, &di->chargalg_work);
0278
0279 return HRTIMER_NORESTART;
0280 }
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290 static enum hrtimer_restart
0291 ab8500_chargalg_maintenance_timer_expired(struct hrtimer *timer)
0292 {
0293
0294 struct ab8500_chargalg *di = container_of(timer, struct ab8500_chargalg,
0295 maintenance_timer);
0296
0297 dev_dbg(di->dev, "Maintenance timer expired\n");
0298 di->events.maintenance_timer_expired = true;
0299
0300
0301 queue_work(di->chargalg_wq, &di->chargalg_work);
0302
0303 return HRTIMER_NORESTART;
0304 }
0305
0306
0307
0308
0309
0310
0311
0312 static void ab8500_chargalg_state_to(struct ab8500_chargalg *di,
0313 enum ab8500_chargalg_states state)
0314 {
0315 dev_dbg(di->dev,
0316 "State changed: %s (From state: [%d] %s =to=> [%d] %s )\n",
0317 di->charge_state == state ? "NO" : "YES",
0318 di->charge_state,
0319 states[di->charge_state],
0320 state,
0321 states[state]);
0322
0323 di->charge_state = state;
0324 }
0325
0326 static int ab8500_chargalg_check_charger_enable(struct ab8500_chargalg *di)
0327 {
0328 struct power_supply_battery_info *bi = di->bm->bi;
0329
0330 switch (di->charge_state) {
0331 case STATE_NORMAL:
0332 case STATE_MAINTENANCE_A:
0333 case STATE_MAINTENANCE_B:
0334 break;
0335 default:
0336 return 0;
0337 }
0338
0339 if (di->chg_info.charger_type & USB_CHG) {
0340 return di->usb_chg->ops.check_enable(di->usb_chg,
0341 bi->constant_charge_voltage_max_uv,
0342 bi->constant_charge_current_max_ua);
0343 } else if (di->chg_info.charger_type & AC_CHG) {
0344 return di->ac_chg->ops.check_enable(di->ac_chg,
0345 bi->constant_charge_voltage_max_uv,
0346 bi->constant_charge_current_max_ua);
0347 }
0348 return 0;
0349 }
0350
0351
0352
0353
0354
0355
0356
0357
0358 static int ab8500_chargalg_check_charger_connection(struct ab8500_chargalg *di)
0359 {
0360 if (di->chg_info.conn_chg != di->chg_info.prev_conn_chg) {
0361
0362 if (di->chg_info.conn_chg & AC_CHG) {
0363 dev_info(di->dev, "Charging source is AC\n");
0364 if (di->chg_info.charger_type != AC_CHG) {
0365 di->chg_info.charger_type = AC_CHG;
0366 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
0367 }
0368 } else if (di->chg_info.conn_chg & USB_CHG) {
0369 dev_info(di->dev, "Charging source is USB\n");
0370 di->chg_info.charger_type = USB_CHG;
0371 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
0372 } else {
0373 dev_dbg(di->dev, "Charging source is OFF\n");
0374 di->chg_info.charger_type = NO_CHG;
0375 ab8500_chargalg_state_to(di, STATE_HANDHELD_INIT);
0376 }
0377 di->chg_info.prev_conn_chg = di->chg_info.conn_chg;
0378 }
0379 return di->chg_info.conn_chg;
0380 }
0381
0382
0383
0384
0385
0386
0387
0388
0389 static void ab8500_chargalg_start_safety_timer(struct ab8500_chargalg *di)
0390 {
0391
0392 int timer_expiration = 0;
0393
0394 switch (di->chg_info.charger_type) {
0395 case AC_CHG:
0396 timer_expiration = di->bm->main_safety_tmr_h;
0397 break;
0398
0399 case USB_CHG:
0400 timer_expiration = di->bm->usb_safety_tmr_h;
0401 break;
0402
0403 default:
0404 dev_err(di->dev, "Unknown charger to charge from\n");
0405 break;
0406 }
0407
0408 di->events.safety_timer_expired = false;
0409 hrtimer_set_expires_range(&di->safety_timer,
0410 ktime_set(timer_expiration * ONE_HOUR_IN_SECONDS, 0),
0411 ktime_set(FIVE_MINUTES_IN_SECONDS, 0));
0412 hrtimer_start_expires(&di->safety_timer, HRTIMER_MODE_REL);
0413 }
0414
0415
0416
0417
0418
0419
0420
0421 static void ab8500_chargalg_stop_safety_timer(struct ab8500_chargalg *di)
0422 {
0423 if (hrtimer_try_to_cancel(&di->safety_timer) >= 0)
0424 di->events.safety_timer_expired = false;
0425 }
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 static void ab8500_chargalg_start_maintenance_timer(struct ab8500_chargalg *di,
0437 int duration)
0438 {
0439
0440 hrtimer_set_expires_range(&di->maintenance_timer,
0441 ktime_set(duration * 60, 0),
0442 ktime_set(30, 0));
0443 di->events.maintenance_timer_expired = false;
0444 hrtimer_start_expires(&di->maintenance_timer, HRTIMER_MODE_REL);
0445 }
0446
0447
0448
0449
0450
0451
0452
0453
0454 static void ab8500_chargalg_stop_maintenance_timer(struct ab8500_chargalg *di)
0455 {
0456 if (hrtimer_try_to_cancel(&di->maintenance_timer) >= 0)
0457 di->events.maintenance_timer_expired = false;
0458 }
0459
0460
0461
0462
0463
0464
0465
0466
0467 static int ab8500_chargalg_kick_watchdog(struct ab8500_chargalg *di)
0468 {
0469
0470 if (di->ac_chg && di->ac_chg->ops.kick_wd &&
0471 di->chg_info.online_chg & AC_CHG) {
0472 return di->ac_chg->ops.kick_wd(di->ac_chg);
0473 } else if (di->usb_chg && di->usb_chg->ops.kick_wd &&
0474 di->chg_info.online_chg & USB_CHG)
0475 return di->usb_chg->ops.kick_wd(di->usb_chg);
0476
0477 return -ENXIO;
0478 }
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490 static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable,
0491 int vset_uv, int iset_ua)
0492 {
0493 static int ab8500_chargalg_ex_ac_enable_toggle;
0494
0495 if (!di->ac_chg || !di->ac_chg->ops.enable)
0496 return -ENXIO;
0497
0498
0499 if (di->ac_chg->max_out_volt_uv)
0500 vset_uv = min(vset_uv, di->ac_chg->max_out_volt_uv);
0501 if (di->ac_chg->max_out_curr_ua)
0502 iset_ua = min(iset_ua, di->ac_chg->max_out_curr_ua);
0503
0504 di->chg_info.ac_iset_ua = iset_ua;
0505 di->chg_info.ac_vset_uv = vset_uv;
0506
0507 return di->ac_chg->ops.enable(di->ac_chg, enable, vset_uv, iset_ua);
0508 }
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520 static int ab8500_chargalg_usb_en(struct ab8500_chargalg *di, int enable,
0521 int vset_uv, int iset_ua)
0522 {
0523 if (!di->usb_chg || !di->usb_chg->ops.enable)
0524 return -ENXIO;
0525
0526
0527 if (di->usb_chg->max_out_volt_uv)
0528 vset_uv = min(vset_uv, di->usb_chg->max_out_volt_uv);
0529 if (di->usb_chg->max_out_curr_ua)
0530 iset_ua = min(iset_ua, di->usb_chg->max_out_curr_ua);
0531
0532 di->chg_info.usb_iset_ua = iset_ua;
0533 di->chg_info.usb_vset_uv = vset_uv;
0534
0535 return di->usb_chg->ops.enable(di->usb_chg, enable, vset_uv, iset_ua);
0536 }
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546 static int ab8500_chargalg_update_chg_curr(struct ab8500_chargalg *di,
0547 int iset_ua)
0548 {
0549
0550 if (di->ac_chg && di->ac_chg->ops.update_curr &&
0551 di->chg_info.charger_type & AC_CHG) {
0552
0553
0554
0555
0556 if (di->ac_chg->max_out_curr_ua)
0557 iset_ua = min(iset_ua, di->ac_chg->max_out_curr_ua);
0558
0559 di->chg_info.ac_iset_ua = iset_ua;
0560
0561 return di->ac_chg->ops.update_curr(di->ac_chg, iset_ua);
0562 } else if (di->usb_chg && di->usb_chg->ops.update_curr &&
0563 di->chg_info.charger_type & USB_CHG) {
0564
0565
0566
0567
0568 if (di->usb_chg->max_out_curr_ua)
0569 iset_ua = min(iset_ua, di->usb_chg->max_out_curr_ua);
0570
0571 di->chg_info.usb_iset_ua = iset_ua;
0572
0573 return di->usb_chg->ops.update_curr(di->usb_chg, iset_ua);
0574 }
0575
0576 return -ENXIO;
0577 }
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587 static void ab8500_chargalg_stop_charging(struct ab8500_chargalg *di)
0588 {
0589 ab8500_chargalg_ac_en(di, false, 0, 0);
0590 ab8500_chargalg_usb_en(di, false, 0, 0);
0591 ab8500_chargalg_stop_safety_timer(di);
0592 ab8500_chargalg_stop_maintenance_timer(di);
0593 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
0594 di->maintenance_chg = false;
0595 cancel_delayed_work(&di->chargalg_wd_work);
0596 power_supply_changed(di->chargalg_psy);
0597 }
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607 static void ab8500_chargalg_hold_charging(struct ab8500_chargalg *di)
0608 {
0609 ab8500_chargalg_ac_en(di, false, 0, 0);
0610 ab8500_chargalg_usb_en(di, false, 0, 0);
0611 ab8500_chargalg_stop_safety_timer(di);
0612 ab8500_chargalg_stop_maintenance_timer(di);
0613 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
0614 di->maintenance_chg = false;
0615 cancel_delayed_work(&di->chargalg_wd_work);
0616 power_supply_changed(di->chargalg_psy);
0617 }
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628 static void ab8500_chargalg_start_charging(struct ab8500_chargalg *di,
0629 int vset_uv, int iset_ua)
0630 {
0631 switch (di->chg_info.charger_type) {
0632 case AC_CHG:
0633 dev_dbg(di->dev,
0634 "AC parameters: Vset %d, Ich %d\n", vset_uv, iset_ua);
0635 ab8500_chargalg_usb_en(di, false, 0, 0);
0636 ab8500_chargalg_ac_en(di, true, vset_uv, iset_ua);
0637 break;
0638
0639 case USB_CHG:
0640 dev_dbg(di->dev,
0641 "USB parameters: Vset %d, Ich %d\n", vset_uv, iset_ua);
0642 ab8500_chargalg_ac_en(di, false, 0, 0);
0643 ab8500_chargalg_usb_en(di, true, vset_uv, iset_ua);
0644 break;
0645
0646 default:
0647 dev_err(di->dev, "Unknown charger to charge from\n");
0648 break;
0649 }
0650 }
0651
0652
0653
0654
0655
0656
0657
0658
0659 static void ab8500_chargalg_check_temp(struct ab8500_chargalg *di)
0660 {
0661 struct power_supply_battery_info *bi = di->bm->bi;
0662
0663 if (di->batt_data.temp > (bi->temp_alert_min + di->t_hyst_norm) &&
0664 di->batt_data.temp < (bi->temp_alert_max - di->t_hyst_norm)) {
0665
0666 di->events.btemp_underover = false;
0667 di->events.btemp_low = false;
0668 di->events.btemp_high = false;
0669 di->t_hyst_norm = 0;
0670 di->t_hyst_lowhigh = 0;
0671 } else {
0672 if ((di->batt_data.temp >= bi->temp_alert_max) &&
0673 (di->batt_data.temp < (bi->temp_max - di->t_hyst_lowhigh))) {
0674
0675 di->events.btemp_underover = false;
0676 di->events.btemp_high = true;
0677 di->t_hyst_norm = di->bm->temp_hysteresis;
0678 di->t_hyst_lowhigh = 0;
0679 } else if ((di->batt_data.temp > (bi->temp_min + di->t_hyst_lowhigh)) &&
0680 (di->batt_data.temp <= bi->temp_alert_min)) {
0681
0682 di->events.btemp_underover = false;
0683 di->events.btemp_low = true;
0684 di->t_hyst_norm = di->bm->temp_hysteresis;
0685 di->t_hyst_lowhigh = 0;
0686 } else if (di->batt_data.temp <= bi->temp_min ||
0687 di->batt_data.temp >= bi->temp_max) {
0688
0689 di->events.btemp_underover = true;
0690 di->events.btemp_low = false;
0691 di->events.btemp_high = false;
0692 di->t_hyst_norm = 0;
0693 di->t_hyst_lowhigh = di->bm->temp_hysteresis;
0694 } else {
0695
0696 dev_dbg(di->dev, "Within hysteresis limit temp: %d "
0697 "hyst_lowhigh %d, hyst normal %d\n",
0698 di->batt_data.temp, di->t_hyst_lowhigh,
0699 di->t_hyst_norm);
0700 }
0701 }
0702 }
0703
0704
0705
0706
0707
0708
0709
0710 static void ab8500_chargalg_check_charger_voltage(struct ab8500_chargalg *di)
0711 {
0712 if (di->chg_info.usb_volt_uv > di->bm->chg_params->usb_volt_max_uv)
0713 di->chg_info.usb_chg_ok = false;
0714 else
0715 di->chg_info.usb_chg_ok = true;
0716
0717 if (di->chg_info.ac_volt_uv > di->bm->chg_params->ac_volt_max_uv)
0718 di->chg_info.ac_chg_ok = false;
0719 else
0720 di->chg_info.ac_chg_ok = true;
0721
0722 }
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732 static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di)
0733 {
0734 if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING &&
0735 di->charge_state == STATE_NORMAL &&
0736 !di->maintenance_chg && (di->batt_data.volt_uv >=
0737 di->bm->bi->voltage_max_design_uv ||
0738 di->events.usb_cv_active || di->events.ac_cv_active) &&
0739 di->batt_data.avg_curr_ua <
0740 di->bm->bi->charge_term_current_ua &&
0741 di->batt_data.avg_curr_ua > 0) {
0742 if (++di->eoc_cnt >= EOC_COND_CNT) {
0743 di->eoc_cnt = 0;
0744 di->charge_status = POWER_SUPPLY_STATUS_FULL;
0745 di->maintenance_chg = true;
0746 dev_dbg(di->dev, "EOC reached!\n");
0747 power_supply_changed(di->chargalg_psy);
0748 } else {
0749 dev_dbg(di->dev,
0750 " EOC limit reached for the %d"
0751 " time, out of %d before EOC\n",
0752 di->eoc_cnt,
0753 EOC_COND_CNT);
0754 }
0755 } else {
0756 di->eoc_cnt = 0;
0757 }
0758 }
0759
0760 static void init_maxim_chg_curr(struct ab8500_chargalg *di)
0761 {
0762 struct power_supply_battery_info *bi = di->bm->bi;
0763
0764 di->ccm.original_iset_ua = bi->constant_charge_current_max_ua;
0765 di->ccm.current_iset_ua = bi->constant_charge_current_max_ua;
0766 di->ccm.max_current_ua = di->bm->maxi->chg_curr_ua;
0767 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
0768 di->ccm.level = 0;
0769 }
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780 static enum maxim_ret ab8500_chargalg_chg_curr_maxim(struct ab8500_chargalg *di)
0781 {
0782
0783 if (!di->bm->maxi->ena_maxi)
0784 return MAXIM_RET_NOACTION;
0785
0786 if (di->events.vbus_collapsed) {
0787 dev_dbg(di->dev, "Charger voltage has collapsed %d\n",
0788 di->ccm.wait_cnt);
0789 if (di->ccm.wait_cnt == 0) {
0790 dev_dbg(di->dev, "lowering current\n");
0791 di->ccm.wait_cnt++;
0792 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
0793 di->ccm.max_current_ua = di->ccm.current_iset_ua;
0794 di->ccm.current_iset_ua = di->ccm.max_current_ua;
0795 di->ccm.level--;
0796 return MAXIM_RET_CHANGE;
0797 } else {
0798 dev_dbg(di->dev, "waiting\n");
0799
0800 di->ccm.wait_cnt = (di->ccm.wait_cnt + 1) % 3;
0801 return MAXIM_RET_NOACTION;
0802 }
0803 }
0804
0805 di->ccm.wait_cnt = 0;
0806
0807 if (di->batt_data.inst_curr_ua > di->ccm.original_iset_ua) {
0808 dev_dbg(di->dev, " Maximization Ibat (%duA) too high"
0809 " (limit %duA) (current iset: %duA)!\n",
0810 di->batt_data.inst_curr_ua, di->ccm.original_iset_ua,
0811 di->ccm.current_iset_ua);
0812
0813 if (di->ccm.current_iset_ua == di->ccm.original_iset_ua)
0814 return MAXIM_RET_NOACTION;
0815
0816 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
0817 di->ccm.current_iset_ua = di->ccm.original_iset_ua;
0818 di->ccm.level = 0;
0819
0820 return MAXIM_RET_IBAT_TOO_HIGH;
0821 }
0822
0823 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
0824 return MAXIM_RET_NOACTION;
0825 }
0826
0827 static void handle_maxim_chg_curr(struct ab8500_chargalg *di)
0828 {
0829 struct power_supply_battery_info *bi = di->bm->bi;
0830 enum maxim_ret ret;
0831 int result;
0832
0833 ret = ab8500_chargalg_chg_curr_maxim(di);
0834 switch (ret) {
0835 case MAXIM_RET_CHANGE:
0836 result = ab8500_chargalg_update_chg_curr(di,
0837 di->ccm.current_iset_ua);
0838 if (result)
0839 dev_err(di->dev, "failed to set chg curr\n");
0840 break;
0841 case MAXIM_RET_IBAT_TOO_HIGH:
0842 result = ab8500_chargalg_update_chg_curr(di,
0843 bi->constant_charge_current_max_ua);
0844 if (result)
0845 dev_err(di->dev, "failed to set chg curr\n");
0846 break;
0847
0848 case MAXIM_RET_NOACTION:
0849 default:
0850
0851 break;
0852 }
0853 }
0854
0855 static int ab8500_chargalg_get_ext_psy_data(struct device *dev, void *data)
0856 {
0857 struct power_supply *psy;
0858 struct power_supply *ext = dev_get_drvdata(dev);
0859 const char **supplicants = (const char **)ext->supplied_to;
0860 struct ab8500_chargalg *di;
0861 union power_supply_propval ret;
0862 int j;
0863 bool capacity_updated = false;
0864
0865 psy = (struct power_supply *)data;
0866 di = power_supply_get_drvdata(psy);
0867
0868 j = match_string(supplicants, ext->num_supplicants, psy->desc->name);
0869 if (j < 0)
0870 return 0;
0871
0872
0873
0874
0875
0876
0877 if (!power_supply_get_property(ext, POWER_SUPPLY_PROP_CAPACITY, &ret)) {
0878 di->batt_data.percent = ret.intval;
0879 capacity_updated = true;
0880 }
0881
0882
0883 for (j = 0; j < ext->desc->num_properties; j++) {
0884 enum power_supply_property prop;
0885 prop = ext->desc->properties[j];
0886
0887
0888
0889
0890 if (!di->ac_chg &&
0891 ext->desc->type == POWER_SUPPLY_TYPE_MAINS)
0892 di->ac_chg = psy_to_ux500_charger(ext);
0893 else if (!di->usb_chg &&
0894 ext->desc->type == POWER_SUPPLY_TYPE_USB)
0895 di->usb_chg = psy_to_ux500_charger(ext);
0896
0897 if (power_supply_get_property(ext, prop, &ret))
0898 continue;
0899 switch (prop) {
0900 case POWER_SUPPLY_PROP_PRESENT:
0901 switch (ext->desc->type) {
0902 case POWER_SUPPLY_TYPE_BATTERY:
0903
0904 if (ret.intval)
0905 di->events.batt_rem = false;
0906
0907 else
0908 di->events.batt_rem = true;
0909 break;
0910 case POWER_SUPPLY_TYPE_MAINS:
0911
0912 if (!ret.intval &&
0913 (di->chg_info.conn_chg & AC_CHG)) {
0914 di->chg_info.prev_conn_chg =
0915 di->chg_info.conn_chg;
0916 di->chg_info.conn_chg &= ~AC_CHG;
0917 }
0918
0919 else if (ret.intval &&
0920 !(di->chg_info.conn_chg & AC_CHG)) {
0921 di->chg_info.prev_conn_chg =
0922 di->chg_info.conn_chg;
0923 di->chg_info.conn_chg |= AC_CHG;
0924 }
0925 break;
0926 case POWER_SUPPLY_TYPE_USB:
0927
0928 if (!ret.intval &&
0929 (di->chg_info.conn_chg & USB_CHG)) {
0930 di->chg_info.prev_conn_chg =
0931 di->chg_info.conn_chg;
0932 di->chg_info.conn_chg &= ~USB_CHG;
0933 }
0934
0935 else if (ret.intval &&
0936 !(di->chg_info.conn_chg & USB_CHG)) {
0937 di->chg_info.prev_conn_chg =
0938 di->chg_info.conn_chg;
0939 di->chg_info.conn_chg |= USB_CHG;
0940 }
0941 break;
0942 default:
0943 break;
0944 }
0945 break;
0946
0947 case POWER_SUPPLY_PROP_ONLINE:
0948 switch (ext->desc->type) {
0949 case POWER_SUPPLY_TYPE_BATTERY:
0950 break;
0951 case POWER_SUPPLY_TYPE_MAINS:
0952
0953 if (!ret.intval &&
0954 (di->chg_info.online_chg & AC_CHG)) {
0955 di->chg_info.prev_online_chg =
0956 di->chg_info.online_chg;
0957 di->chg_info.online_chg &= ~AC_CHG;
0958 }
0959
0960 else if (ret.intval &&
0961 !(di->chg_info.online_chg & AC_CHG)) {
0962 di->chg_info.prev_online_chg =
0963 di->chg_info.online_chg;
0964 di->chg_info.online_chg |= AC_CHG;
0965 queue_delayed_work(di->chargalg_wq,
0966 &di->chargalg_wd_work, 0);
0967 }
0968 break;
0969 case POWER_SUPPLY_TYPE_USB:
0970
0971 if (!ret.intval &&
0972 (di->chg_info.online_chg & USB_CHG)) {
0973 di->chg_info.prev_online_chg =
0974 di->chg_info.online_chg;
0975 di->chg_info.online_chg &= ~USB_CHG;
0976 }
0977
0978 else if (ret.intval &&
0979 !(di->chg_info.online_chg & USB_CHG)) {
0980 di->chg_info.prev_online_chg =
0981 di->chg_info.online_chg;
0982 di->chg_info.online_chg |= USB_CHG;
0983 queue_delayed_work(di->chargalg_wq,
0984 &di->chargalg_wd_work, 0);
0985 }
0986 break;
0987 default:
0988 break;
0989 }
0990 break;
0991
0992 case POWER_SUPPLY_PROP_HEALTH:
0993 switch (ext->desc->type) {
0994 case POWER_SUPPLY_TYPE_BATTERY:
0995 break;
0996 case POWER_SUPPLY_TYPE_MAINS:
0997 switch (ret.intval) {
0998 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
0999 di->events.mainextchnotok = true;
1000 di->events.main_thermal_prot = false;
1001 di->events.main_ovv = false;
1002 di->events.ac_wd_expired = false;
1003 break;
1004 case POWER_SUPPLY_HEALTH_DEAD:
1005 di->events.ac_wd_expired = true;
1006 di->events.mainextchnotok = false;
1007 di->events.main_ovv = false;
1008 di->events.main_thermal_prot = false;
1009 break;
1010 case POWER_SUPPLY_HEALTH_COLD:
1011 case POWER_SUPPLY_HEALTH_OVERHEAT:
1012 di->events.main_thermal_prot = true;
1013 di->events.mainextchnotok = false;
1014 di->events.main_ovv = false;
1015 di->events.ac_wd_expired = false;
1016 break;
1017 case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1018 di->events.main_ovv = true;
1019 di->events.mainextchnotok = false;
1020 di->events.main_thermal_prot = false;
1021 di->events.ac_wd_expired = false;
1022 break;
1023 case POWER_SUPPLY_HEALTH_GOOD:
1024 di->events.main_thermal_prot = false;
1025 di->events.mainextchnotok = false;
1026 di->events.main_ovv = false;
1027 di->events.ac_wd_expired = false;
1028 break;
1029 default:
1030 break;
1031 }
1032 break;
1033
1034 case POWER_SUPPLY_TYPE_USB:
1035 switch (ret.intval) {
1036 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
1037 di->events.usbchargernotok = true;
1038 di->events.usb_thermal_prot = false;
1039 di->events.vbus_ovv = false;
1040 di->events.usb_wd_expired = false;
1041 break;
1042 case POWER_SUPPLY_HEALTH_DEAD:
1043 di->events.usb_wd_expired = true;
1044 di->events.usbchargernotok = false;
1045 di->events.usb_thermal_prot = false;
1046 di->events.vbus_ovv = false;
1047 break;
1048 case POWER_SUPPLY_HEALTH_COLD:
1049 case POWER_SUPPLY_HEALTH_OVERHEAT:
1050 di->events.usb_thermal_prot = true;
1051 di->events.usbchargernotok = false;
1052 di->events.vbus_ovv = false;
1053 di->events.usb_wd_expired = false;
1054 break;
1055 case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1056 di->events.vbus_ovv = true;
1057 di->events.usbchargernotok = false;
1058 di->events.usb_thermal_prot = false;
1059 di->events.usb_wd_expired = false;
1060 break;
1061 case POWER_SUPPLY_HEALTH_GOOD:
1062 di->events.usbchargernotok = false;
1063 di->events.usb_thermal_prot = false;
1064 di->events.vbus_ovv = false;
1065 di->events.usb_wd_expired = false;
1066 break;
1067 default:
1068 break;
1069 }
1070 break;
1071 default:
1072 break;
1073 }
1074 break;
1075
1076 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1077 switch (ext->desc->type) {
1078 case POWER_SUPPLY_TYPE_BATTERY:
1079 di->batt_data.volt_uv = ret.intval;
1080 break;
1081 case POWER_SUPPLY_TYPE_MAINS:
1082 di->chg_info.ac_volt_uv = ret.intval;
1083 break;
1084 case POWER_SUPPLY_TYPE_USB:
1085 di->chg_info.usb_volt_uv = ret.intval;
1086 break;
1087 default:
1088 break;
1089 }
1090 break;
1091
1092 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
1093 switch (ext->desc->type) {
1094 case POWER_SUPPLY_TYPE_MAINS:
1095
1096
1097 if (ret.intval)
1098 di->events.ac_cv_active = true;
1099 else
1100 di->events.ac_cv_active = false;
1101
1102 break;
1103 case POWER_SUPPLY_TYPE_USB:
1104
1105
1106 if (ret.intval)
1107 di->events.usb_cv_active = true;
1108 else
1109 di->events.usb_cv_active = false;
1110
1111 break;
1112 default:
1113 break;
1114 }
1115 break;
1116
1117 case POWER_SUPPLY_PROP_TECHNOLOGY:
1118 switch (ext->desc->type) {
1119 case POWER_SUPPLY_TYPE_BATTERY:
1120 if (ret.intval)
1121 di->events.batt_unknown = false;
1122 else
1123 di->events.batt_unknown = true;
1124
1125 break;
1126 default:
1127 break;
1128 }
1129 break;
1130
1131 case POWER_SUPPLY_PROP_TEMP:
1132 di->batt_data.temp = ret.intval / 10;
1133 break;
1134
1135 case POWER_SUPPLY_PROP_CURRENT_NOW:
1136 switch (ext->desc->type) {
1137 case POWER_SUPPLY_TYPE_MAINS:
1138 di->chg_info.ac_curr_ua = ret.intval;
1139 break;
1140 case POWER_SUPPLY_TYPE_USB:
1141 di->chg_info.usb_curr_ua = ret.intval;
1142 break;
1143 case POWER_SUPPLY_TYPE_BATTERY:
1144 di->batt_data.inst_curr_ua = ret.intval;
1145 break;
1146 default:
1147 break;
1148 }
1149 break;
1150
1151 case POWER_SUPPLY_PROP_CURRENT_AVG:
1152 switch (ext->desc->type) {
1153 case POWER_SUPPLY_TYPE_BATTERY:
1154 di->batt_data.avg_curr_ua = ret.intval;
1155 break;
1156 case POWER_SUPPLY_TYPE_USB:
1157 if (ret.intval)
1158 di->events.vbus_collapsed = true;
1159 else
1160 di->events.vbus_collapsed = false;
1161 break;
1162 default:
1163 break;
1164 }
1165 break;
1166 case POWER_SUPPLY_PROP_CAPACITY:
1167 if (!capacity_updated)
1168 di->batt_data.percent = ret.intval;
1169 break;
1170 default:
1171 break;
1172 }
1173 }
1174 return 0;
1175 }
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186 static void ab8500_chargalg_external_power_changed(struct power_supply *psy)
1187 {
1188 struct ab8500_chargalg *di = power_supply_get_drvdata(psy);
1189
1190
1191
1192
1193
1194 if (di->chargalg_wq)
1195 queue_work(di->chargalg_wq, &di->chargalg_work);
1196 }
1197
1198
1199
1200
1201
1202
1203
1204
1205 static bool ab8500_chargalg_time_to_restart(struct ab8500_chargalg *di)
1206 {
1207 struct power_supply_battery_info *bi = di->bm->bi;
1208
1209
1210 if (!di->batt_data.volt_uv || !di->batt_data.percent)
1211 return false;
1212
1213
1214 if (bi->charge_restart_voltage_uv > 0) {
1215 if (di->batt_data.volt_uv <= bi->charge_restart_voltage_uv)
1216 return true;
1217
1218 } else {
1219 if (di->batt_data.percent <= AB8500_RECHARGE_CAP)
1220 return true;
1221 }
1222
1223 return false;
1224 }
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234 static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di)
1235 {
1236 struct power_supply_battery_info *bi = di->bm->bi;
1237 struct power_supply_maintenance_charge_table *mt;
1238 int charger_status;
1239 int ret;
1240
1241
1242 class_for_each_device(power_supply_class, NULL,
1243 di->chargalg_psy, ab8500_chargalg_get_ext_psy_data);
1244
1245 ab8500_chargalg_end_of_charge(di);
1246 ab8500_chargalg_check_temp(di);
1247 ab8500_chargalg_check_charger_voltage(di);
1248
1249 charger_status = ab8500_chargalg_check_charger_connection(di);
1250
1251 if (is_ab8500(di->parent)) {
1252 ret = ab8500_chargalg_check_charger_enable(di);
1253 if (ret < 0)
1254 dev_err(di->dev, "Checking charger is enabled error"
1255 ": Returned Value %d\n", ret);
1256 }
1257
1258
1259
1260
1261
1262
1263 if (!charger_status ||
1264 (di->events.batt_unknown && !di->bm->chg_unknown_bat)) {
1265 if (di->charge_state != STATE_HANDHELD) {
1266 di->events.safety_timer_expired = false;
1267 ab8500_chargalg_state_to(di, STATE_HANDHELD_INIT);
1268 }
1269 }
1270
1271
1272 else if (di->events.safety_timer_expired) {
1273 if (di->charge_state != STATE_SAFETY_TIMER_EXPIRED)
1274 ab8500_chargalg_state_to(di,
1275 STATE_SAFETY_TIMER_EXPIRED_INIT);
1276 }
1277
1278
1279
1280
1281
1282
1283 else if (di->events.batt_rem) {
1284 if (di->charge_state != STATE_BATT_REMOVED)
1285 ab8500_chargalg_state_to(di, STATE_BATT_REMOVED_INIT);
1286 }
1287
1288 else if (di->events.mainextchnotok || di->events.usbchargernotok) {
1289
1290
1291
1292
1293 if (di->charge_state != STATE_CHG_NOT_OK &&
1294 !di->events.vbus_collapsed)
1295 ab8500_chargalg_state_to(di, STATE_CHG_NOT_OK_INIT);
1296 }
1297
1298 else if (di->events.vbus_ovv ||
1299 di->events.main_ovv ||
1300 di->events.batt_ovv ||
1301 !di->chg_info.usb_chg_ok ||
1302 !di->chg_info.ac_chg_ok) {
1303 if (di->charge_state != STATE_OVV_PROTECT)
1304 ab8500_chargalg_state_to(di, STATE_OVV_PROTECT_INIT);
1305 }
1306
1307 else if (di->events.main_thermal_prot ||
1308 di->events.usb_thermal_prot) {
1309 if (di->charge_state != STATE_HW_TEMP_PROTECT)
1310 ab8500_chargalg_state_to(di,
1311 STATE_HW_TEMP_PROTECT_INIT);
1312 }
1313
1314 else if (di->events.btemp_underover) {
1315 if (di->charge_state != STATE_TEMP_UNDEROVER)
1316 ab8500_chargalg_state_to(di,
1317 STATE_TEMP_UNDEROVER_INIT);
1318 }
1319
1320 else if (di->events.ac_wd_expired ||
1321 di->events.usb_wd_expired) {
1322 if (di->charge_state != STATE_WD_EXPIRED)
1323 ab8500_chargalg_state_to(di, STATE_WD_EXPIRED_INIT);
1324 }
1325
1326 else if (di->events.btemp_low || di->events.btemp_high) {
1327 if (di->charge_state != STATE_TEMP_LOWHIGH)
1328 ab8500_chargalg_state_to(di, STATE_TEMP_LOWHIGH_INIT);
1329 }
1330
1331 dev_dbg(di->dev,
1332 "[CHARGALG] Vb %d Ib_avg %d Ib_inst %d Tb %d Cap %d Maint %d "
1333 "State %s Active_chg %d Chg_status %d AC %d USB %d "
1334 "AC_online %d USB_online %d AC_CV %d USB_CV %d AC_I %d "
1335 "USB_I %d AC_Vset %d AC_Iset %d USB_Vset %d USB_Iset %d\n",
1336 di->batt_data.volt_uv,
1337 di->batt_data.avg_curr_ua,
1338 di->batt_data.inst_curr_ua,
1339 di->batt_data.temp,
1340 di->batt_data.percent,
1341 di->maintenance_chg,
1342 states[di->charge_state],
1343 di->chg_info.charger_type,
1344 di->charge_status,
1345 di->chg_info.conn_chg & AC_CHG,
1346 di->chg_info.conn_chg & USB_CHG,
1347 di->chg_info.online_chg & AC_CHG,
1348 di->chg_info.online_chg & USB_CHG,
1349 di->events.ac_cv_active,
1350 di->events.usb_cv_active,
1351 di->chg_info.ac_curr_ua,
1352 di->chg_info.usb_curr_ua,
1353 di->chg_info.ac_vset_uv,
1354 di->chg_info.ac_iset_ua,
1355 di->chg_info.usb_vset_uv,
1356 di->chg_info.usb_iset_ua);
1357
1358 switch (di->charge_state) {
1359 case STATE_HANDHELD_INIT:
1360 ab8500_chargalg_stop_charging(di);
1361 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
1362 ab8500_chargalg_state_to(di, STATE_HANDHELD);
1363 fallthrough;
1364
1365 case STATE_HANDHELD:
1366 break;
1367
1368 case STATE_BATT_REMOVED_INIT:
1369 ab8500_chargalg_stop_charging(di);
1370 ab8500_chargalg_state_to(di, STATE_BATT_REMOVED);
1371 fallthrough;
1372
1373 case STATE_BATT_REMOVED:
1374 if (!di->events.batt_rem)
1375 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1376 break;
1377
1378 case STATE_HW_TEMP_PROTECT_INIT:
1379 ab8500_chargalg_stop_charging(di);
1380 ab8500_chargalg_state_to(di, STATE_HW_TEMP_PROTECT);
1381 fallthrough;
1382
1383 case STATE_HW_TEMP_PROTECT:
1384 if (!di->events.main_thermal_prot &&
1385 !di->events.usb_thermal_prot)
1386 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1387 break;
1388
1389 case STATE_OVV_PROTECT_INIT:
1390 ab8500_chargalg_stop_charging(di);
1391 ab8500_chargalg_state_to(di, STATE_OVV_PROTECT);
1392 fallthrough;
1393
1394 case STATE_OVV_PROTECT:
1395 if (!di->events.vbus_ovv &&
1396 !di->events.main_ovv &&
1397 !di->events.batt_ovv &&
1398 di->chg_info.usb_chg_ok &&
1399 di->chg_info.ac_chg_ok)
1400 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1401 break;
1402
1403 case STATE_CHG_NOT_OK_INIT:
1404 ab8500_chargalg_stop_charging(di);
1405 ab8500_chargalg_state_to(di, STATE_CHG_NOT_OK);
1406 fallthrough;
1407
1408 case STATE_CHG_NOT_OK:
1409 if (!di->events.mainextchnotok &&
1410 !di->events.usbchargernotok)
1411 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1412 break;
1413
1414 case STATE_SAFETY_TIMER_EXPIRED_INIT:
1415 ab8500_chargalg_stop_charging(di);
1416 ab8500_chargalg_state_to(di, STATE_SAFETY_TIMER_EXPIRED);
1417 fallthrough;
1418
1419 case STATE_SAFETY_TIMER_EXPIRED:
1420
1421 break;
1422
1423 case STATE_NORMAL_INIT:
1424 if (bi->constant_charge_current_max_ua == 0)
1425
1426 ab8500_chargalg_stop_charging(di);
1427 else {
1428 ab8500_chargalg_start_charging(di,
1429 bi->constant_charge_voltage_max_uv,
1430 bi->constant_charge_current_max_ua);
1431 }
1432
1433 ab8500_chargalg_state_to(di, STATE_NORMAL);
1434 ab8500_chargalg_start_safety_timer(di);
1435 ab8500_chargalg_stop_maintenance_timer(di);
1436 init_maxim_chg_curr(di);
1437 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
1438 di->eoc_cnt = 0;
1439 di->maintenance_chg = false;
1440 power_supply_changed(di->chargalg_psy);
1441
1442 break;
1443
1444 case STATE_NORMAL:
1445 handle_maxim_chg_curr(di);
1446 if (di->charge_status == POWER_SUPPLY_STATUS_FULL &&
1447 di->maintenance_chg) {
1448
1449
1450
1451
1452
1453 if (!power_supply_supports_maintenance_charging(bi))
1454 ab8500_chargalg_state_to(di,
1455 STATE_WAIT_FOR_RECHARGE_INIT);
1456 else
1457 ab8500_chargalg_state_to(di,
1458 STATE_MAINTENANCE_A_INIT);
1459 }
1460 break;
1461
1462
1463 case STATE_WAIT_FOR_RECHARGE_INIT:
1464 ab8500_chargalg_hold_charging(di);
1465 ab8500_chargalg_state_to(di, STATE_WAIT_FOR_RECHARGE);
1466 fallthrough;
1467
1468 case STATE_WAIT_FOR_RECHARGE:
1469 if (ab8500_chargalg_time_to_restart(di))
1470 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1471 break;
1472
1473 case STATE_MAINTENANCE_A_INIT:
1474 mt = power_supply_get_maintenance_charging_setting(bi, 0);
1475 if (!mt) {
1476
1477 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1478 power_supply_changed(di->chargalg_psy);
1479 break;
1480 }
1481 ab8500_chargalg_stop_safety_timer(di);
1482 ab8500_chargalg_start_maintenance_timer(di,
1483 mt->charge_safety_timer_minutes);
1484 ab8500_chargalg_start_charging(di,
1485 mt->charge_voltage_max_uv,
1486 mt->charge_current_max_ua);
1487 ab8500_chargalg_state_to(di, STATE_MAINTENANCE_A);
1488 power_supply_changed(di->chargalg_psy);
1489 fallthrough;
1490
1491 case STATE_MAINTENANCE_A:
1492 if (di->events.maintenance_timer_expired) {
1493 ab8500_chargalg_stop_maintenance_timer(di);
1494 ab8500_chargalg_state_to(di, STATE_MAINTENANCE_B_INIT);
1495 }
1496
1497
1498
1499
1500 if (ab8500_chargalg_time_to_restart(di)) {
1501 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1502 dev_info(di->dev, "restarted charging from maintenance state A - battery getting old?\n");
1503 }
1504 break;
1505
1506 case STATE_MAINTENANCE_B_INIT:
1507 mt = power_supply_get_maintenance_charging_setting(bi, 1);
1508 if (!mt) {
1509
1510 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1511 power_supply_changed(di->chargalg_psy);
1512 break;
1513 }
1514 ab8500_chargalg_start_maintenance_timer(di,
1515 mt->charge_safety_timer_minutes);
1516 ab8500_chargalg_start_charging(di,
1517 mt->charge_voltage_max_uv,
1518 mt->charge_current_max_ua);
1519 ab8500_chargalg_state_to(di, STATE_MAINTENANCE_B);
1520 power_supply_changed(di->chargalg_psy);
1521 fallthrough;
1522
1523 case STATE_MAINTENANCE_B:
1524 if (di->events.maintenance_timer_expired) {
1525 ab8500_chargalg_stop_maintenance_timer(di);
1526 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1527 }
1528
1529
1530
1531
1532 if (ab8500_chargalg_time_to_restart(di)) {
1533 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1534 dev_info(di->dev, "restarted charging from maintenance state B - battery getting old?\n");
1535 }
1536 break;
1537
1538 case STATE_TEMP_LOWHIGH_INIT:
1539 if (di->events.btemp_low) {
1540 ab8500_chargalg_start_charging(di,
1541 bi->alert_low_temp_charge_voltage_uv,
1542 bi->alert_low_temp_charge_current_ua);
1543 } else if (di->events.btemp_high) {
1544 ab8500_chargalg_start_charging(di,
1545 bi->alert_high_temp_charge_voltage_uv,
1546 bi->alert_high_temp_charge_current_ua);
1547 } else {
1548 dev_err(di->dev, "neither low or high temp event occurred\n");
1549 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1550 break;
1551 }
1552 ab8500_chargalg_stop_maintenance_timer(di);
1553 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
1554 ab8500_chargalg_state_to(di, STATE_TEMP_LOWHIGH);
1555 power_supply_changed(di->chargalg_psy);
1556 fallthrough;
1557
1558 case STATE_TEMP_LOWHIGH:
1559 if (!di->events.btemp_low && !di->events.btemp_high)
1560 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1561 break;
1562
1563 case STATE_WD_EXPIRED_INIT:
1564 ab8500_chargalg_stop_charging(di);
1565 ab8500_chargalg_state_to(di, STATE_WD_EXPIRED);
1566 fallthrough;
1567
1568 case STATE_WD_EXPIRED:
1569 if (!di->events.ac_wd_expired &&
1570 !di->events.usb_wd_expired)
1571 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1572 break;
1573
1574 case STATE_TEMP_UNDEROVER_INIT:
1575 ab8500_chargalg_stop_charging(di);
1576 ab8500_chargalg_state_to(di, STATE_TEMP_UNDEROVER);
1577 fallthrough;
1578
1579 case STATE_TEMP_UNDEROVER:
1580 if (!di->events.btemp_underover)
1581 ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1582 break;
1583 }
1584
1585
1586 if (di->charge_state == STATE_NORMAL_INIT ||
1587 di->charge_state == STATE_MAINTENANCE_A_INIT ||
1588 di->charge_state == STATE_MAINTENANCE_B_INIT)
1589 queue_work(di->chargalg_wq, &di->chargalg_work);
1590 }
1591
1592
1593
1594
1595
1596
1597
1598 static void ab8500_chargalg_periodic_work(struct work_struct *work)
1599 {
1600 struct ab8500_chargalg *di = container_of(work,
1601 struct ab8500_chargalg, chargalg_periodic_work.work);
1602
1603 ab8500_chargalg_algorithm(di);
1604
1605
1606
1607
1608
1609 if (di->chg_info.conn_chg)
1610 queue_delayed_work(di->chargalg_wq,
1611 &di->chargalg_periodic_work,
1612 di->bm->interval_charging * HZ);
1613 else
1614 queue_delayed_work(di->chargalg_wq,
1615 &di->chargalg_periodic_work,
1616 di->bm->interval_not_charging * HZ);
1617 }
1618
1619
1620
1621
1622
1623
1624
1625 static void ab8500_chargalg_wd_work(struct work_struct *work)
1626 {
1627 int ret;
1628 struct ab8500_chargalg *di = container_of(work,
1629 struct ab8500_chargalg, chargalg_wd_work.work);
1630
1631 ret = ab8500_chargalg_kick_watchdog(di);
1632 if (ret < 0)
1633 dev_err(di->dev, "failed to kick watchdog\n");
1634
1635 queue_delayed_work(di->chargalg_wq,
1636 &di->chargalg_wd_work, CHG_WD_INTERVAL);
1637 }
1638
1639
1640
1641
1642
1643
1644
1645 static void ab8500_chargalg_work(struct work_struct *work)
1646 {
1647 struct ab8500_chargalg *di = container_of(work,
1648 struct ab8500_chargalg, chargalg_work);
1649
1650 ab8500_chargalg_algorithm(di);
1651 }
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665 static int ab8500_chargalg_get_property(struct power_supply *psy,
1666 enum power_supply_property psp,
1667 union power_supply_propval *val)
1668 {
1669 struct ab8500_chargalg *di = power_supply_get_drvdata(psy);
1670
1671 switch (psp) {
1672 case POWER_SUPPLY_PROP_STATUS:
1673 val->intval = di->charge_status;
1674 break;
1675 case POWER_SUPPLY_PROP_HEALTH:
1676 if (di->events.batt_ovv) {
1677 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1678 } else if (di->events.btemp_underover) {
1679 if (di->batt_data.temp <= di->bm->bi->temp_min)
1680 val->intval = POWER_SUPPLY_HEALTH_COLD;
1681 else
1682 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
1683 } else if (di->charge_state == STATE_SAFETY_TIMER_EXPIRED ||
1684 di->charge_state == STATE_SAFETY_TIMER_EXPIRED_INIT) {
1685 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
1686 } else {
1687 val->intval = POWER_SUPPLY_HEALTH_GOOD;
1688 }
1689 break;
1690 default:
1691 return -EINVAL;
1692 }
1693 return 0;
1694 }
1695
1696 static int __maybe_unused ab8500_chargalg_resume(struct device *dev)
1697 {
1698 struct ab8500_chargalg *di = dev_get_drvdata(dev);
1699
1700
1701 if (di->chg_info.online_chg)
1702 queue_delayed_work(di->chargalg_wq, &di->chargalg_wd_work, 0);
1703
1704
1705
1706
1707
1708 queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1709
1710 return 0;
1711 }
1712
1713 static int __maybe_unused ab8500_chargalg_suspend(struct device *dev)
1714 {
1715 struct ab8500_chargalg *di = dev_get_drvdata(dev);
1716
1717 if (di->chg_info.online_chg)
1718 cancel_delayed_work_sync(&di->chargalg_wd_work);
1719
1720 cancel_delayed_work_sync(&di->chargalg_periodic_work);
1721
1722 return 0;
1723 }
1724
1725 static char *supply_interface[] = {
1726 "ab8500_fg",
1727 };
1728
1729 static const struct power_supply_desc ab8500_chargalg_desc = {
1730 .name = "ab8500_chargalg",
1731 .type = POWER_SUPPLY_TYPE_BATTERY,
1732 .properties = ab8500_chargalg_props,
1733 .num_properties = ARRAY_SIZE(ab8500_chargalg_props),
1734 .get_property = ab8500_chargalg_get_property,
1735 .external_power_changed = ab8500_chargalg_external_power_changed,
1736 };
1737
1738 static int ab8500_chargalg_bind(struct device *dev, struct device *master,
1739 void *data)
1740 {
1741 struct ab8500_chargalg *di = dev_get_drvdata(dev);
1742
1743
1744 di->chargalg_wq = alloc_ordered_workqueue("ab8500_chargalg_wq",
1745 WQ_MEM_RECLAIM);
1746 if (di->chargalg_wq == NULL) {
1747 dev_err(di->dev, "failed to create work queue\n");
1748 return -ENOMEM;
1749 }
1750
1751
1752 queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1753
1754 return 0;
1755 }
1756
1757 static void ab8500_chargalg_unbind(struct device *dev, struct device *master,
1758 void *data)
1759 {
1760 struct ab8500_chargalg *di = dev_get_drvdata(dev);
1761
1762
1763 hrtimer_cancel(&di->safety_timer);
1764 hrtimer_cancel(&di->maintenance_timer);
1765
1766 cancel_delayed_work_sync(&di->chargalg_periodic_work);
1767 cancel_delayed_work_sync(&di->chargalg_wd_work);
1768 cancel_work_sync(&di->chargalg_work);
1769
1770
1771 destroy_workqueue(di->chargalg_wq);
1772 }
1773
1774 static const struct component_ops ab8500_chargalg_component_ops = {
1775 .bind = ab8500_chargalg_bind,
1776 .unbind = ab8500_chargalg_unbind,
1777 };
1778
1779 static int ab8500_chargalg_probe(struct platform_device *pdev)
1780 {
1781 struct device *dev = &pdev->dev;
1782 struct power_supply_config psy_cfg = {};
1783 struct ab8500_chargalg *di;
1784
1785 di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL);
1786 if (!di)
1787 return -ENOMEM;
1788
1789 di->bm = &ab8500_bm_data;
1790
1791
1792 di->dev = dev;
1793 di->parent = dev_get_drvdata(pdev->dev.parent);
1794
1795 psy_cfg.supplied_to = supply_interface;
1796 psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface);
1797 psy_cfg.drv_data = di;
1798
1799
1800 hrtimer_init(&di->safety_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1801 di->safety_timer.function = ab8500_chargalg_safety_timer_expired;
1802
1803
1804 hrtimer_init(&di->maintenance_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1805 di->maintenance_timer.function =
1806 ab8500_chargalg_maintenance_timer_expired;
1807
1808
1809 INIT_DEFERRABLE_WORK(&di->chargalg_periodic_work,
1810 ab8500_chargalg_periodic_work);
1811 INIT_DEFERRABLE_WORK(&di->chargalg_wd_work,
1812 ab8500_chargalg_wd_work);
1813
1814
1815 INIT_WORK(&di->chargalg_work, ab8500_chargalg_work);
1816
1817
1818 di->chg_info.prev_conn_chg = -1;
1819
1820
1821 di->chargalg_psy = devm_power_supply_register(di->dev,
1822 &ab8500_chargalg_desc,
1823 &psy_cfg);
1824 if (IS_ERR(di->chargalg_psy)) {
1825 dev_err(di->dev, "failed to register chargalg psy\n");
1826 return PTR_ERR(di->chargalg_psy);
1827 }
1828
1829 platform_set_drvdata(pdev, di);
1830
1831 dev_info(di->dev, "probe success\n");
1832 return component_add(dev, &ab8500_chargalg_component_ops);
1833 }
1834
1835 static int ab8500_chargalg_remove(struct platform_device *pdev)
1836 {
1837 component_del(&pdev->dev, &ab8500_chargalg_component_ops);
1838
1839 return 0;
1840 }
1841
1842 static SIMPLE_DEV_PM_OPS(ab8500_chargalg_pm_ops, ab8500_chargalg_suspend, ab8500_chargalg_resume);
1843
1844 static const struct of_device_id ab8500_chargalg_match[] = {
1845 { .compatible = "stericsson,ab8500-chargalg", },
1846 { },
1847 };
1848
1849 struct platform_driver ab8500_chargalg_driver = {
1850 .probe = ab8500_chargalg_probe,
1851 .remove = ab8500_chargalg_remove,
1852 .driver = {
1853 .name = "ab8500_chargalg",
1854 .of_match_table = ab8500_chargalg_match,
1855 .pm = &ab8500_chargalg_pm_ops,
1856 },
1857 };
1858 MODULE_LICENSE("GPL v2");
1859 MODULE_AUTHOR("Johan Palsson, Karl Komierowski");
1860 MODULE_ALIAS("platform:ab8500-chargalg");
1861 MODULE_DESCRIPTION("ab8500 battery charging algorithm");