File Index
Files and directories
Sign in
FILE

ab8500_chargalg.c

File preview with syntax highlighting.

linux-6.19.14/drivers/power/supply/ab8500_chargalg.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) ST-Ericsson SA 2012
   4 * Copyright (c) 2012 Sony Mobile Communications AB
   5 *
   6 * Charging algorithm driver for AB8500
   7 *
   8 * Authors:
   9 *	Johan Palsson <johan.palsson@stericsson.com>
  10 *	Karl Komierowski <karl.komierowski@stericsson.com>
  11 *	Arun R Murthy <arun.murthy@stericsson.com>
  12 *	Author: Imre Sunyi <imre.sunyi@sonymobile.com>
  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/* Watchdog kick interval */
  38#define CHG_WD_INTERVAL			(6 * HZ)
  39
  40/* End-of-charge criteria counter */
  41#define EOC_COND_CNT			10
  42
  43/* One hour expressed in seconds */
  44#define ONE_HOUR_IN_SECONDS            3600
  45
  46/* Five minutes expressed in seconds */
  47#define FIVE_MINUTES_IN_SECONDS        300
  48
  49/*
  50 * This is the battery capacity limit that will trigger a new
  51 * full charging cycle in the case where maintenance charging
  52 * has been disabled
  53 */
  54#define AB8500_RECHARGE_CAP		95
  55
  56enum ab8500_chargers {
  57	NO_CHG,
  58	AC_CHG,
  59	USB_CHG,
  60};
  61
  62struct ab8500_chargalg_charger_info {
  63	enum ab8500_chargers conn_chg;
  64	enum ab8500_chargers prev_conn_chg;
  65	enum ab8500_chargers online_chg;
  66	enum ab8500_chargers prev_online_chg;
  67	enum ab8500_chargers charger_type;
  68	bool usb_chg_ok;
  69	bool ac_chg_ok;
  70	int usb_volt_uv;
  71	int usb_curr_ua;
  72	int ac_volt_uv;
  73	int ac_curr_ua;
  74	int usb_vset_uv;
  75	int usb_iset_ua;
  76	int ac_vset_uv;
  77	int ac_iset_ua;
  78};
  79
  80struct ab8500_chargalg_battery_data {
  81	int temp;
  82	int volt_uv;
  83	int avg_curr_ua;
  84	int inst_curr_ua;
  85	int percent;
  86};
  87
  88enum ab8500_chargalg_states {
  89	STATE_HANDHELD_INIT,
  90	STATE_HANDHELD,
  91	STATE_CHG_NOT_OK_INIT,
  92	STATE_CHG_NOT_OK,
  93	STATE_HW_TEMP_PROTECT_INIT,
  94	STATE_HW_TEMP_PROTECT,
  95	STATE_NORMAL_INIT,
  96	STATE_NORMAL,
  97	STATE_WAIT_FOR_RECHARGE_INIT,
  98	STATE_WAIT_FOR_RECHARGE,
  99	STATE_MAINTENANCE_A_INIT,
 100	STATE_MAINTENANCE_A,
 101	STATE_MAINTENANCE_B_INIT,
 102	STATE_MAINTENANCE_B,
 103	STATE_TEMP_UNDEROVER_INIT,
 104	STATE_TEMP_UNDEROVER,
 105	STATE_TEMP_LOWHIGH_INIT,
 106	STATE_TEMP_LOWHIGH,
 107	STATE_OVV_PROTECT_INIT,
 108	STATE_OVV_PROTECT,
 109	STATE_SAFETY_TIMER_EXPIRED_INIT,
 110	STATE_SAFETY_TIMER_EXPIRED,
 111	STATE_BATT_REMOVED_INIT,
 112	STATE_BATT_REMOVED,
 113	STATE_WD_EXPIRED_INIT,
 114	STATE_WD_EXPIRED,
 115};
 116
 117static const char * const states[] = {
 118	"HANDHELD_INIT",
 119	"HANDHELD",
 120	"CHG_NOT_OK_INIT",
 121	"CHG_NOT_OK",
 122	"HW_TEMP_PROTECT_INIT",
 123	"HW_TEMP_PROTECT",
 124	"NORMAL_INIT",
 125	"NORMAL",
 126	"WAIT_FOR_RECHARGE_INIT",
 127	"WAIT_FOR_RECHARGE",
 128	"MAINTENANCE_A_INIT",
 129	"MAINTENANCE_A",
 130	"MAINTENANCE_B_INIT",
 131	"MAINTENANCE_B",
 132	"TEMP_UNDEROVER_INIT",
 133	"TEMP_UNDEROVER",
 134	"TEMP_LOWHIGH_INIT",
 135	"TEMP_LOWHIGH",
 136	"OVV_PROTECT_INIT",
 137	"OVV_PROTECT",
 138	"SAFETY_TIMER_EXPIRED_INIT",
 139	"SAFETY_TIMER_EXPIRED",
 140	"BATT_REMOVED_INIT",
 141	"BATT_REMOVED",
 142	"WD_EXPIRED_INIT",
 143	"WD_EXPIRED",
 144};
 145
 146struct ab8500_chargalg_events {
 147	bool batt_unknown;
 148	bool mainextchnotok;
 149	bool batt_ovv;
 150	bool batt_rem;
 151	bool btemp_underover;
 152	bool btemp_low;
 153	bool btemp_high;
 154	bool main_thermal_prot;
 155	bool usb_thermal_prot;
 156	bool main_ovv;
 157	bool vbus_ovv;
 158	bool usbchargernotok;
 159	bool safety_timer_expired;
 160	bool maintenance_timer_expired;
 161	bool ac_wd_expired;
 162	bool usb_wd_expired;
 163	bool ac_cv_active;
 164	bool usb_cv_active;
 165	bool vbus_collapsed;
 166};
 167
 168/**
 169 * struct ab8500_charge_curr_maximization - Charger maximization parameters
 170 * @original_iset_ua:	the non optimized/maximised charger current
 171 * @current_iset_ua:	the charging current used at this moment
 172 * @condition_cnt:	number of iterations needed before a new charger current
 173			is set
 174 * @max_current_ua:	maximum charger current
 175 * @wait_cnt:		to avoid too fast current step down in case of charger
 176 *			voltage collapse, we insert this delay between step
 177 *			down
 178 * @level:		tells in how many steps the charging current has been
 179			increased
 180 */
 181struct ab8500_charge_curr_maximization {
 182	int original_iset_ua;
 183	int current_iset_ua;
 184	int condition_cnt;
 185	int max_current_ua;
 186	int wait_cnt;
 187	u8 level;
 188};
 189
 190enum maxim_ret {
 191	MAXIM_RET_NOACTION,
 192	MAXIM_RET_CHANGE,
 193	MAXIM_RET_IBAT_TOO_HIGH,
 194};
 195
 196/**
 197 * struct ab8500_chargalg - ab8500 Charging algorithm device information
 198 * @dev:		pointer to the structure device
 199 * @charge_status:	battery operating status
 200 * @eoc_cnt:		counter used to determine end-of_charge
 201 * @maintenance_chg:	indicate if maintenance charge is active
 202 * @t_hyst_norm		temperature hysteresis when the temperature has been
 203 *			over or under normal limits
 204 * @t_hyst_lowhigh	temperature hysteresis when the temperature has been
 205 *			over or under the high or low limits
 206 * @charge_state:	current state of the charging algorithm
 207 * @ccm			charging current maximization parameters
 208 * @chg_info:		information about connected charger types
 209 * @batt_data:		data of the battery
 210 * @bm:           	Platform specific battery management information
 211 * @parent:		pointer to the struct ab8500
 212 * @chargalg_psy:	structure that holds the battery properties exposed by
 213 *			the charging algorithm
 214 * @events:		structure for information about events triggered
 215 * @chargalg_wq:		work queue for running the charging algorithm
 216 * @chargalg_periodic_work:	work to run the charging algorithm periodically
 217 * @chargalg_wd_work:		work to kick the charger watchdog periodically
 218 * @chargalg_work:		work to run the charging algorithm instantly
 219 * @safety_timer:		charging safety timer
 220 * @maintenance_timer:		maintenance charging timer
 221 * @chargalg_kobject:		structure of type kobject
 222 */
 223struct ab8500_chargalg {
 224	struct device *dev;
 225	int charge_status;
 226	int eoc_cnt;
 227	bool maintenance_chg;
 228	int t_hyst_norm;
 229	int t_hyst_lowhigh;
 230	enum ab8500_chargalg_states charge_state;
 231	struct ab8500_charge_curr_maximization ccm;
 232	struct ab8500_chargalg_charger_info chg_info;
 233	struct ab8500_chargalg_battery_data batt_data;
 234	struct ab8500 *parent;
 235	struct ab8500_bm_data *bm;
 236	struct power_supply *chargalg_psy;
 237	struct ux500_charger *ac_chg;
 238	struct ux500_charger *usb_chg;
 239	struct ab8500_chargalg_events events;
 240	struct workqueue_struct *chargalg_wq;
 241	struct delayed_work chargalg_periodic_work;
 242	struct delayed_work chargalg_wd_work;
 243	struct work_struct chargalg_work;
 244	struct hrtimer safety_timer;
 245	struct hrtimer maintenance_timer;
 246	struct kobject chargalg_kobject;
 247};
 248
 249/* Main battery properties */
 250static enum power_supply_property ab8500_chargalg_props[] = {
 251	POWER_SUPPLY_PROP_STATUS,
 252	POWER_SUPPLY_PROP_HEALTH,
 253};
 254
 255/**
 256 * ab8500_chargalg_safety_timer_expired() - Expiration of the safety timer
 257 * @timer:     pointer to the hrtimer structure
 258 *
 259 * This function gets called when the safety timer for the charger
 260 * expires
 261 */
 262static enum hrtimer_restart
 263ab8500_chargalg_safety_timer_expired(struct hrtimer *timer)
 264{
 265	struct ab8500_chargalg *di = container_of(timer, struct ab8500_chargalg,
 266						  safety_timer);
 267	dev_err(di->dev, "Safety timer expired\n");
 268	di->events.safety_timer_expired = true;
 269
 270	/* Trigger execution of the algorithm instantly */
 271	queue_work(di->chargalg_wq, &di->chargalg_work);
 272
 273	return HRTIMER_NORESTART;
 274}
 275
 276/**
 277 * ab8500_chargalg_maintenance_timer_expired() - Expiration of
 278 * the maintenance timer
 279 * @timer:     pointer to the timer structure
 280 *
 281 * This function gets called when the maintenance timer
 282 * expires
 283 */
 284static enum hrtimer_restart
 285ab8500_chargalg_maintenance_timer_expired(struct hrtimer *timer)
 286{
 287
 288	struct ab8500_chargalg *di = container_of(timer, struct ab8500_chargalg,
 289						  maintenance_timer);
 290
 291	dev_dbg(di->dev, "Maintenance timer expired\n");
 292	di->events.maintenance_timer_expired = true;
 293
 294	/* Trigger execution of the algorithm instantly */
 295	queue_work(di->chargalg_wq, &di->chargalg_work);
 296
 297	return HRTIMER_NORESTART;
 298}
 299
 300/**
 301 * ab8500_chargalg_state_to() - Change charge state
 302 * @di:		pointer to the ab8500_chargalg structure
 303 *
 304 * This function gets called when a charge state change should occur
 305 */
 306static void ab8500_chargalg_state_to(struct ab8500_chargalg *di,
 307	enum ab8500_chargalg_states state)
 308{
 309	dev_dbg(di->dev,
 310		"State changed: %s (From state: [%d] %s =to=> [%d] %s )\n",
 311		di->charge_state == state ? "NO" : "YES",
 312		di->charge_state,
 313		states[di->charge_state],
 314		state,
 315		states[state]);
 316
 317	di->charge_state = state;
 318}
 319
 320static int ab8500_chargalg_check_charger_enable(struct ab8500_chargalg *di)
 321{
 322	struct power_supply_battery_info *bi = di->bm->bi;
 323
 324	switch (di->charge_state) {
 325	case STATE_NORMAL:
 326	case STATE_MAINTENANCE_A:
 327	case STATE_MAINTENANCE_B:
 328		break;
 329	default:
 330		return 0;
 331	}
 332
 333	if (di->chg_info.charger_type & USB_CHG) {
 334		return di->usb_chg->ops.check_enable(di->usb_chg,
 335			bi->constant_charge_voltage_max_uv,
 336			bi->constant_charge_current_max_ua);
 337	} else if (di->chg_info.charger_type & AC_CHG) {
 338		return di->ac_chg->ops.check_enable(di->ac_chg,
 339			bi->constant_charge_voltage_max_uv,
 340			bi->constant_charge_current_max_ua);
 341	}
 342	return 0;
 343}
 344
 345/**
 346 * ab8500_chargalg_check_charger_connection() - Check charger connection change
 347 * @di:		pointer to the ab8500_chargalg structure
 348 *
 349 * This function will check if there is a change in the charger connection
 350 * and change charge state accordingly. AC has precedence over USB.
 351 */
 352static int ab8500_chargalg_check_charger_connection(struct ab8500_chargalg *di)
 353{
 354	if (di->chg_info.conn_chg != di->chg_info.prev_conn_chg) {
 355		/* Charger state changed since last update */
 356		if (di->chg_info.conn_chg & AC_CHG) {
 357			dev_info(di->dev, "Charging source is AC\n");
 358			if (di->chg_info.charger_type != AC_CHG) {
 359				di->chg_info.charger_type = AC_CHG;
 360				ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
 361			}
 362		} else if (di->chg_info.conn_chg & USB_CHG) {
 363			dev_info(di->dev, "Charging source is USB\n");
 364			di->chg_info.charger_type = USB_CHG;
 365			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
 366		} else {
 367			dev_dbg(di->dev, "Charging source is OFF\n");
 368			di->chg_info.charger_type = NO_CHG;
 369			ab8500_chargalg_state_to(di, STATE_HANDHELD_INIT);
 370		}
 371		di->chg_info.prev_conn_chg = di->chg_info.conn_chg;
 372	}
 373	return di->chg_info.conn_chg;
 374}
 375
 376/**
 377 * ab8500_chargalg_start_safety_timer() - Start charging safety timer
 378 * @di:		pointer to the ab8500_chargalg structure
 379 *
 380 * The safety timer is used to avoid overcharging of old or bad batteries.
 381 * There are different timers for AC and USB
 382 */
 383static void ab8500_chargalg_start_safety_timer(struct ab8500_chargalg *di)
 384{
 385	/* Charger-dependent expiration time in hours*/
 386	int timer_expiration = 0;
 387
 388	switch (di->chg_info.charger_type) {
 389	case AC_CHG:
 390		timer_expiration = di->bm->main_safety_tmr_h;
 391		break;
 392
 393	case USB_CHG:
 394		timer_expiration = di->bm->usb_safety_tmr_h;
 395		break;
 396
 397	default:
 398		dev_err(di->dev, "Unknown charger to charge from\n");
 399		break;
 400	}
 401
 402	di->events.safety_timer_expired = false;
 403	hrtimer_set_expires_range(&di->safety_timer,
 404		ktime_set(timer_expiration * ONE_HOUR_IN_SECONDS, 0),
 405		ktime_set(FIVE_MINUTES_IN_SECONDS, 0));
 406	hrtimer_start_expires(&di->safety_timer, HRTIMER_MODE_REL);
 407}
 408
 409/**
 410 * ab8500_chargalg_stop_safety_timer() - Stop charging safety timer
 411 * @di:		pointer to the ab8500_chargalg structure
 412 *
 413 * The safety timer is stopped whenever the NORMAL state is exited
 414 */
 415static void ab8500_chargalg_stop_safety_timer(struct ab8500_chargalg *di)
 416{
 417	if (hrtimer_try_to_cancel(&di->safety_timer) >= 0)
 418		di->events.safety_timer_expired = false;
 419}
 420
 421/**
 422 * ab8500_chargalg_start_maintenance_timer() - Start charging maintenance timer
 423 * @di:		pointer to the ab8500_chargalg structure
 424 * @duration:	duration of the maintenance timer in minutes
 425 *
 426 * The maintenance timer is used to maintain the charge in the battery once
 427 * the battery is considered full. These timers are chosen to match the
 428 * discharge curve of the battery
 429 */
 430static void ab8500_chargalg_start_maintenance_timer(struct ab8500_chargalg *di,
 431	int duration)
 432{
 433	/* Set a timer in minutes with a 30 second range */
 434	hrtimer_set_expires_range(&di->maintenance_timer,
 435		ktime_set(duration * 60, 0),
 436		ktime_set(30, 0));
 437	di->events.maintenance_timer_expired = false;
 438	hrtimer_start_expires(&di->maintenance_timer, HRTIMER_MODE_REL);
 439}
 440
 441/**
 442 * ab8500_chargalg_stop_maintenance_timer() - Stop maintenance timer
 443 * @di:		pointer to the ab8500_chargalg structure
 444 *
 445 * The maintenance timer is stopped whenever maintenance ends or when another
 446 * state is entered
 447 */
 448static void ab8500_chargalg_stop_maintenance_timer(struct ab8500_chargalg *di)
 449{
 450	if (hrtimer_try_to_cancel(&di->maintenance_timer) >= 0)
 451		di->events.maintenance_timer_expired = false;
 452}
 453
 454/**
 455 * ab8500_chargalg_kick_watchdog() - Kick charger watchdog
 456 * @di:		pointer to the ab8500_chargalg structure
 457 *
 458 * The charger watchdog have to be kicked periodically whenever the charger is
 459 * on, else the ABB will reset the system
 460 */
 461static int ab8500_chargalg_kick_watchdog(struct ab8500_chargalg *di)
 462{
 463	/* Check if charger exists and kick watchdog if charging */
 464	if (di->ac_chg && di->ac_chg->ops.kick_wd &&
 465	    di->chg_info.online_chg & AC_CHG) {
 466		return di->ac_chg->ops.kick_wd(di->ac_chg);
 467	} else if (di->usb_chg && di->usb_chg->ops.kick_wd &&
 468			di->chg_info.online_chg & USB_CHG)
 469		return di->usb_chg->ops.kick_wd(di->usb_chg);
 470
 471	return -ENXIO;
 472}
 473
 474/**
 475 * ab8500_chargalg_ac_en() - Turn on/off the AC charger
 476 * @di:		pointer to the ab8500_chargalg structure
 477 * @enable:	charger on/off
 478 * @vset_uv:	requested charger output voltage in microvolt
 479 * @iset_ua:	requested charger output current in microampere
 480 *
 481 * The AC charger will be turned on/off with the requested charge voltage and
 482 * current
 483 */
 484static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable,
 485	int vset_uv, int iset_ua)
 486{
 487	if (!di->ac_chg || !di->ac_chg->ops.enable)
 488		return -ENXIO;
 489
 490	/* Select maximum of what both the charger and the battery supports */
 491	if (di->ac_chg->max_out_volt_uv)
 492		vset_uv = min(vset_uv, di->ac_chg->max_out_volt_uv);
 493	if (di->ac_chg->max_out_curr_ua)
 494		iset_ua = min(iset_ua, di->ac_chg->max_out_curr_ua);
 495
 496	di->chg_info.ac_iset_ua = iset_ua;
 497	di->chg_info.ac_vset_uv = vset_uv;
 498
 499	return di->ac_chg->ops.enable(di->ac_chg, enable, vset_uv, iset_ua);
 500}
 501
 502/**
 503 * ab8500_chargalg_usb_en() - Turn on/off the USB charger
 504 * @di:		pointer to the ab8500_chargalg structure
 505 * @enable:	charger on/off
 506 * @vset_uv:	requested charger output voltage in microvolt
 507 * @iset_ua:	requested charger output current in microampere
 508 *
 509 * The USB charger will be turned on/off with the requested charge voltage and
 510 * current
 511 */
 512static int ab8500_chargalg_usb_en(struct ab8500_chargalg *di, int enable,
 513	int vset_uv, int iset_ua)
 514{
 515	if (!di->usb_chg || !di->usb_chg->ops.enable)
 516		return -ENXIO;
 517
 518	/* Select maximum of what both the charger and the battery supports */
 519	if (di->usb_chg->max_out_volt_uv)
 520		vset_uv = min(vset_uv, di->usb_chg->max_out_volt_uv);
 521	if (di->usb_chg->max_out_curr_ua)
 522		iset_ua = min(iset_ua, di->usb_chg->max_out_curr_ua);
 523
 524	di->chg_info.usb_iset_ua = iset_ua;
 525	di->chg_info.usb_vset_uv = vset_uv;
 526
 527	return di->usb_chg->ops.enable(di->usb_chg, enable, vset_uv, iset_ua);
 528}
 529
 530/**
 531 * ab8500_chargalg_update_chg_curr() - Update charger current
 532 * @di:		pointer to the ab8500_chargalg structure
 533 * @iset_ua:	requested charger output current in microampere
 534 *
 535 * The charger output current will be updated for the charger
 536 * that is currently in use
 537 */
 538static int ab8500_chargalg_update_chg_curr(struct ab8500_chargalg *di,
 539		int iset_ua)
 540{
 541	/* Check if charger exists and update current if charging */
 542	if (di->ac_chg && di->ac_chg->ops.update_curr &&
 543			di->chg_info.charger_type & AC_CHG) {
 544		/*
 545		 * Select maximum of what both the charger
 546		 * and the battery supports
 547		 */
 548		if (di->ac_chg->max_out_curr_ua)
 549			iset_ua = min(iset_ua, di->ac_chg->max_out_curr_ua);
 550
 551		di->chg_info.ac_iset_ua = iset_ua;
 552
 553		return di->ac_chg->ops.update_curr(di->ac_chg, iset_ua);
 554	} else if (di->usb_chg && di->usb_chg->ops.update_curr &&
 555			di->chg_info.charger_type & USB_CHG) {
 556		/*
 557		 * Select maximum of what both the charger
 558		 * and the battery supports
 559		 */
 560		if (di->usb_chg->max_out_curr_ua)
 561			iset_ua = min(iset_ua, di->usb_chg->max_out_curr_ua);
 562
 563		di->chg_info.usb_iset_ua = iset_ua;
 564
 565		return di->usb_chg->ops.update_curr(di->usb_chg, iset_ua);
 566	}
 567
 568	return -ENXIO;
 569}
 570
 571/**
 572 * ab8500_chargalg_stop_charging() - Stop charging
 573 * @di:		pointer to the ab8500_chargalg structure
 574 *
 575 * This function is called from any state where charging should be stopped.
 576 * All charging is disabled and all status parameters and timers are changed
 577 * accordingly
 578 */
 579static void ab8500_chargalg_stop_charging(struct ab8500_chargalg *di)
 580{
 581	ab8500_chargalg_ac_en(di, false, 0, 0);
 582	ab8500_chargalg_usb_en(di, false, 0, 0);
 583	ab8500_chargalg_stop_safety_timer(di);
 584	ab8500_chargalg_stop_maintenance_timer(di);
 585	di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 586	di->maintenance_chg = false;
 587	cancel_delayed_work(&di->chargalg_wd_work);
 588	power_supply_changed(di->chargalg_psy);
 589}
 590
 591/**
 592 * ab8500_chargalg_hold_charging() - Pauses charging
 593 * @di:		pointer to the ab8500_chargalg structure
 594 *
 595 * This function is called in the case where maintenance charging has been
 596 * disabled and instead a battery voltage mode is entered to check when the
 597 * battery voltage has reached a certain recharge voltage
 598 */
 599static void ab8500_chargalg_hold_charging(struct ab8500_chargalg *di)
 600{
 601	ab8500_chargalg_ac_en(di, false, 0, 0);
 602	ab8500_chargalg_usb_en(di, false, 0, 0);
 603	ab8500_chargalg_stop_safety_timer(di);
 604	ab8500_chargalg_stop_maintenance_timer(di);
 605	di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
 606	di->maintenance_chg = false;
 607	cancel_delayed_work(&di->chargalg_wd_work);
 608	power_supply_changed(di->chargalg_psy);
 609}
 610
 611/**
 612 * ab8500_chargalg_start_charging() - Start the charger
 613 * @di:		pointer to the ab8500_chargalg structure
 614 * @vset_uv:	requested charger output voltage in microvolt
 615 * @iset_ua:	requested charger output current in microampere
 616 *
 617 * A charger will be enabled depending on the requested charger type that was
 618 * detected previously.
 619 */
 620static void ab8500_chargalg_start_charging(struct ab8500_chargalg *di,
 621	int vset_uv, int iset_ua)
 622{
 623	switch (di->chg_info.charger_type) {
 624	case AC_CHG:
 625		dev_dbg(di->dev,
 626			"AC parameters: Vset %d, Ich %d\n", vset_uv, iset_ua);
 627		ab8500_chargalg_usb_en(di, false, 0, 0);
 628		ab8500_chargalg_ac_en(di, true, vset_uv, iset_ua);
 629		break;
 630
 631	case USB_CHG:
 632		dev_dbg(di->dev,
 633			"USB parameters: Vset %d, Ich %d\n", vset_uv, iset_ua);
 634		ab8500_chargalg_ac_en(di, false, 0, 0);
 635		ab8500_chargalg_usb_en(di, true, vset_uv, iset_ua);
 636		break;
 637
 638	default:
 639		dev_err(di->dev, "Unknown charger to charge from\n");
 640		break;
 641	}
 642}
 643
 644/**
 645 * ab8500_chargalg_check_temp() - Check battery temperature ranges
 646 * @di:		pointer to the ab8500_chargalg structure
 647 *
 648 * The battery temperature is checked against the predefined limits and the
 649 * charge state is changed accordingly
 650 */
 651static void ab8500_chargalg_check_temp(struct ab8500_chargalg *di)
 652{
 653	struct power_supply_battery_info *bi = di->bm->bi;
 654
 655	if (di->batt_data.temp > (bi->temp_alert_min + di->t_hyst_norm) &&
 656		di->batt_data.temp < (bi->temp_alert_max - di->t_hyst_norm)) {
 657		/* Temp OK! */
 658		di->events.btemp_underover = false;
 659		di->events.btemp_low = false;
 660		di->events.btemp_high = false;
 661		di->t_hyst_norm = 0;
 662		di->t_hyst_lowhigh = 0;
 663	} else {
 664		if ((di->batt_data.temp >= bi->temp_alert_max) &&
 665		    (di->batt_data.temp < (bi->temp_max - di->t_hyst_lowhigh))) {
 666			/* Alert zone for high temperature */
 667			di->events.btemp_underover = false;
 668			di->events.btemp_high = true;
 669			di->t_hyst_norm = di->bm->temp_hysteresis;
 670			di->t_hyst_lowhigh = 0;
 671		} else if ((di->batt_data.temp > (bi->temp_min + di->t_hyst_lowhigh)) &&
 672			   (di->batt_data.temp <= bi->temp_alert_min)) {
 673			/* Alert zone for low temperature */
 674			di->events.btemp_underover = false;
 675			di->events.btemp_low = true;
 676			di->t_hyst_norm = di->bm->temp_hysteresis;
 677			di->t_hyst_lowhigh = 0;
 678		} else if (di->batt_data.temp <= bi->temp_min ||
 679			di->batt_data.temp >= bi->temp_max) {
 680			/* TEMP major!!!!! */
 681			di->events.btemp_underover = true;
 682			di->events.btemp_low = false;
 683			di->events.btemp_high = false;
 684			di->t_hyst_norm = 0;
 685			di->t_hyst_lowhigh = di->bm->temp_hysteresis;
 686		} else {
 687			/* Within hysteresis */
 688			dev_dbg(di->dev, "Within hysteresis limit temp: %d "
 689				"hyst_lowhigh %d, hyst normal %d\n",
 690				di->batt_data.temp, di->t_hyst_lowhigh,
 691				di->t_hyst_norm);
 692		}
 693	}
 694}
 695
 696/**
 697 * ab8500_chargalg_check_charger_voltage() - Check charger voltage
 698 * @di:		pointer to the ab8500_chargalg structure
 699 *
 700 * Charger voltage is checked against maximum limit
 701 */
 702static void ab8500_chargalg_check_charger_voltage(struct ab8500_chargalg *di)
 703{
 704	if (di->chg_info.usb_volt_uv > di->bm->chg_params->usb_volt_max_uv)
 705		di->chg_info.usb_chg_ok = false;
 706	else
 707		di->chg_info.usb_chg_ok = true;
 708
 709	if (di->chg_info.ac_volt_uv > di->bm->chg_params->ac_volt_max_uv)
 710		di->chg_info.ac_chg_ok = false;
 711	else
 712		di->chg_info.ac_chg_ok = true;
 713
 714}
 715
 716/**
 717 * ab8500_chargalg_end_of_charge() - Check if end-of-charge criteria is fulfilled
 718 * @di:		pointer to the ab8500_chargalg structure
 719 *
 720 * End-of-charge criteria is fulfilled when the battery voltage is above a
 721 * certain limit and the battery current is below a certain limit for a
 722 * predefined number of consecutive seconds. If true, the battery is full
 723 */
 724static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di)
 725{
 726	if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING &&
 727		di->charge_state == STATE_NORMAL &&
 728		!di->maintenance_chg && (di->batt_data.volt_uv >=
 729		di->bm->bi->voltage_max_design_uv ||
 730		di->events.usb_cv_active || di->events.ac_cv_active) &&
 731		di->batt_data.avg_curr_ua <
 732		di->bm->bi->charge_term_current_ua &&
 733		di->batt_data.avg_curr_ua > 0) {
 734		if (++di->eoc_cnt >= EOC_COND_CNT) {
 735			di->eoc_cnt = 0;
 736			di->charge_status = POWER_SUPPLY_STATUS_FULL;
 737			di->maintenance_chg = true;
 738			dev_dbg(di->dev, "EOC reached!\n");
 739			power_supply_changed(di->chargalg_psy);
 740		} else {
 741			dev_dbg(di->dev,
 742				" EOC limit reached for the %d"
 743				" time, out of %d before EOC\n",
 744				di->eoc_cnt,
 745				EOC_COND_CNT);
 746		}
 747	} else {
 748		di->eoc_cnt = 0;
 749	}
 750}
 751
 752static void init_maxim_chg_curr(struct ab8500_chargalg *di)
 753{
 754	struct power_supply_battery_info *bi = di->bm->bi;
 755
 756	di->ccm.original_iset_ua = bi->constant_charge_current_max_ua;
 757	di->ccm.current_iset_ua = bi->constant_charge_current_max_ua;
 758	di->ccm.max_current_ua = di->bm->maxi->chg_curr_ua;
 759	di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
 760	di->ccm.level = 0;
 761}
 762
 763/**
 764 * ab8500_chargalg_chg_curr_maxim - increases the charger current to
 765 *			compensate for the system load
 766 * @di		pointer to the ab8500_chargalg structure
 767 *
 768 * This maximization function is used to raise the charger current to get the
 769 * battery current as close to the optimal value as possible. The battery
 770 * current during charging is affected by the system load
 771 */
 772static enum maxim_ret ab8500_chargalg_chg_curr_maxim(struct ab8500_chargalg *di)
 773{
 774
 775	if (!di->bm->maxi->ena_maxi)
 776		return MAXIM_RET_NOACTION;
 777
 778	if (di->events.vbus_collapsed) {
 779		dev_dbg(di->dev, "Charger voltage has collapsed %d\n",
 780				di->ccm.wait_cnt);
 781		if (di->ccm.wait_cnt == 0) {
 782			dev_dbg(di->dev, "lowering current\n");
 783			di->ccm.wait_cnt++;
 784			di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
 785			di->ccm.max_current_ua = di->ccm.current_iset_ua;
 786			di->ccm.current_iset_ua = di->ccm.max_current_ua;
 787			di->ccm.level--;
 788			return MAXIM_RET_CHANGE;
 789		} else {
 790			dev_dbg(di->dev, "waiting\n");
 791			/* Let's go in here twice before lowering curr again */
 792			di->ccm.wait_cnt = (di->ccm.wait_cnt + 1) % 3;
 793			return MAXIM_RET_NOACTION;
 794		}
 795	}
 796
 797	di->ccm.wait_cnt = 0;
 798
 799	if (di->batt_data.inst_curr_ua > di->ccm.original_iset_ua) {
 800		dev_dbg(di->dev, " Maximization Ibat (%duA) too high"
 801			" (limit %duA) (current iset: %duA)!\n",
 802			di->batt_data.inst_curr_ua, di->ccm.original_iset_ua,
 803			di->ccm.current_iset_ua);
 804
 805		if (di->ccm.current_iset_ua == di->ccm.original_iset_ua)
 806			return MAXIM_RET_NOACTION;
 807
 808		di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
 809		di->ccm.current_iset_ua = di->ccm.original_iset_ua;
 810		di->ccm.level = 0;
 811
 812		return MAXIM_RET_IBAT_TOO_HIGH;
 813	}
 814
 815	di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
 816	return MAXIM_RET_NOACTION;
 817}
 818
 819static void handle_maxim_chg_curr(struct ab8500_chargalg *di)
 820{
 821	struct power_supply_battery_info *bi = di->bm->bi;
 822	enum maxim_ret ret;
 823	int result;
 824
 825	ret = ab8500_chargalg_chg_curr_maxim(di);
 826	switch (ret) {
 827	case MAXIM_RET_CHANGE:
 828		result = ab8500_chargalg_update_chg_curr(di,
 829			di->ccm.current_iset_ua);
 830		if (result)
 831			dev_err(di->dev, "failed to set chg curr\n");
 832		break;
 833	case MAXIM_RET_IBAT_TOO_HIGH:
 834		result = ab8500_chargalg_update_chg_curr(di,
 835			bi->constant_charge_current_max_ua);
 836		if (result)
 837			dev_err(di->dev, "failed to set chg curr\n");
 838		break;
 839
 840	case MAXIM_RET_NOACTION:
 841	default:
 842		/* Do nothing..*/
 843		break;
 844	}
 845}
 846
 847static int ab8500_chargalg_get_ext_psy_data(struct power_supply *ext, void *data)
 848{
 849	struct power_supply *psy;
 850	const char **supplicants = (const char **)ext->supplied_to;
 851	struct ab8500_chargalg *di;
 852	union power_supply_propval ret;
 853	int j;
 854	bool capacity_updated = false;
 855
 856	psy = (struct power_supply *)data;
 857	di = power_supply_get_drvdata(psy);
 858	/* For all psy where the driver name appears in any supplied_to */
 859	j = match_string(supplicants, ext->num_supplicants, psy->desc->name);
 860	if (j < 0)
 861		return 0;
 862
 863	/*
 864	 *  If external is not registering 'POWER_SUPPLY_PROP_CAPACITY' to its
 865	 * property because of handling that sysfs entry on its own, this is
 866	 * the place to get the battery capacity.
 867	 */
 868	if (!power_supply_get_property(ext, POWER_SUPPLY_PROP_CAPACITY, &ret)) {
 869		di->batt_data.percent = ret.intval;
 870		capacity_updated = true;
 871	}
 872
 873	/* Go through all properties for the psy */
 874	for (j = 0; j < ext->desc->num_properties; j++) {
 875		enum power_supply_property prop;
 876		prop = ext->desc->properties[j];
 877
 878		/*
 879		 * Initialize chargers if not already done.
 880		 * The ab8500_charger*/
 881		if (!di->ac_chg &&
 882			ext->desc->type == POWER_SUPPLY_TYPE_MAINS)
 883			di->ac_chg = psy_to_ux500_charger(ext);
 884		else if (!di->usb_chg &&
 885			ext->desc->type == POWER_SUPPLY_TYPE_USB)
 886			di->usb_chg = psy_to_ux500_charger(ext);
 887
 888		if (power_supply_get_property(ext, prop, &ret))
 889			continue;
 890		switch (prop) {
 891		case POWER_SUPPLY_PROP_PRESENT:
 892			switch (ext->desc->type) {
 893			case POWER_SUPPLY_TYPE_BATTERY:
 894				/* Battery present */
 895				if (ret.intval)
 896					di->events.batt_rem = false;
 897				/* Battery removed */
 898				else
 899					di->events.batt_rem = true;
 900				break;
 901			case POWER_SUPPLY_TYPE_MAINS:
 902				/* AC disconnected */
 903				if (!ret.intval &&
 904					(di->chg_info.conn_chg & AC_CHG)) {
 905					di->chg_info.prev_conn_chg =
 906						di->chg_info.conn_chg;
 907					di->chg_info.conn_chg &= ~AC_CHG;
 908				}
 909				/* AC connected */
 910				else if (ret.intval &&
 911					!(di->chg_info.conn_chg & AC_CHG)) {
 912					di->chg_info.prev_conn_chg =
 913						di->chg_info.conn_chg;
 914					di->chg_info.conn_chg |= AC_CHG;
 915				}
 916				break;
 917			case POWER_SUPPLY_TYPE_USB:
 918				/* USB disconnected */
 919				if (!ret.intval &&
 920					(di->chg_info.conn_chg & USB_CHG)) {
 921					di->chg_info.prev_conn_chg =
 922						di->chg_info.conn_chg;
 923					di->chg_info.conn_chg &= ~USB_CHG;
 924				}
 925				/* USB connected */
 926				else if (ret.intval &&
 927					!(di->chg_info.conn_chg & USB_CHG)) {
 928					di->chg_info.prev_conn_chg =
 929						di->chg_info.conn_chg;
 930					di->chg_info.conn_chg |= USB_CHG;
 931				}
 932				break;
 933			default:
 934				break;
 935			}
 936			break;
 937
 938		case POWER_SUPPLY_PROP_ONLINE:
 939			switch (ext->desc->type) {
 940			case POWER_SUPPLY_TYPE_BATTERY:
 941				break;
 942			case POWER_SUPPLY_TYPE_MAINS:
 943				/* AC offline */
 944				if (!ret.intval &&
 945					(di->chg_info.online_chg & AC_CHG)) {
 946					di->chg_info.prev_online_chg =
 947						di->chg_info.online_chg;
 948					di->chg_info.online_chg &= ~AC_CHG;
 949				}
 950				/* AC online */
 951				else if (ret.intval &&
 952					!(di->chg_info.online_chg & AC_CHG)) {
 953					di->chg_info.prev_online_chg =
 954						di->chg_info.online_chg;
 955					di->chg_info.online_chg |= AC_CHG;
 956					queue_delayed_work(di->chargalg_wq,
 957						&di->chargalg_wd_work, 0);
 958				}
 959				break;
 960			case POWER_SUPPLY_TYPE_USB:
 961				/* USB offline */
 962				if (!ret.intval &&
 963					(di->chg_info.online_chg & USB_CHG)) {
 964					di->chg_info.prev_online_chg =
 965						di->chg_info.online_chg;
 966					di->chg_info.online_chg &= ~USB_CHG;
 967				}
 968				/* USB online */
 969				else if (ret.intval &&
 970					!(di->chg_info.online_chg & USB_CHG)) {
 971					di->chg_info.prev_online_chg =
 972						di->chg_info.online_chg;
 973					di->chg_info.online_chg |= USB_CHG;
 974					queue_delayed_work(di->chargalg_wq,
 975						&di->chargalg_wd_work, 0);
 976				}
 977				break;
 978			default:
 979				break;
 980			}
 981			break;
 982
 983		case POWER_SUPPLY_PROP_HEALTH:
 984			switch (ext->desc->type) {
 985			case POWER_SUPPLY_TYPE_BATTERY:
 986				break;
 987			case POWER_SUPPLY_TYPE_MAINS:
 988				switch (ret.intval) {
 989				case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
 990					di->events.mainextchnotok = true;
 991					di->events.main_thermal_prot = false;
 992					di->events.main_ovv = false;
 993					di->events.ac_wd_expired = false;
 994					break;
 995				case POWER_SUPPLY_HEALTH_DEAD:
 996					di->events.ac_wd_expired = true;
 997					di->events.mainextchnotok = false;
 998					di->events.main_ovv = false;
 999					di->events.main_thermal_prot = false;
1000					break;
1001				case POWER_SUPPLY_HEALTH_COLD:
1002				case POWER_SUPPLY_HEALTH_OVERHEAT:
1003					di->events.main_thermal_prot = true;
1004					di->events.mainextchnotok = false;
1005					di->events.main_ovv = false;
1006					di->events.ac_wd_expired = false;
1007					break;
1008				case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1009					di->events.main_ovv = true;
1010					di->events.mainextchnotok = false;
1011					di->events.main_thermal_prot = false;
1012					di->events.ac_wd_expired = false;
1013					break;
1014				case POWER_SUPPLY_HEALTH_GOOD:
1015					di->events.main_thermal_prot = false;
1016					di->events.mainextchnotok = false;
1017					di->events.main_ovv = false;
1018					di->events.ac_wd_expired = false;
1019					break;
1020				default:
1021					break;
1022				}
1023				break;
1024
1025			case POWER_SUPPLY_TYPE_USB:
1026				switch (ret.intval) {
1027				case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
1028					di->events.usbchargernotok = true;
1029					di->events.usb_thermal_prot = false;
1030					di->events.vbus_ovv = false;
1031					di->events.usb_wd_expired = false;
1032					break;
1033				case POWER_SUPPLY_HEALTH_DEAD:
1034					di->events.usb_wd_expired = true;
1035					di->events.usbchargernotok = false;
1036					di->events.usb_thermal_prot = false;
1037					di->events.vbus_ovv = false;
1038					break;
1039				case POWER_SUPPLY_HEALTH_COLD:
1040				case POWER_SUPPLY_HEALTH_OVERHEAT:
1041					di->events.usb_thermal_prot = true;
1042					di->events.usbchargernotok = false;
1043					di->events.vbus_ovv = false;
1044					di->events.usb_wd_expired = false;
1045					break;
1046				case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1047					di->events.vbus_ovv = true;
1048					di->events.usbchargernotok = false;
1049					di->events.usb_thermal_prot = false;
1050					di->events.usb_wd_expired = false;
1051					break;
1052				case POWER_SUPPLY_HEALTH_GOOD:
1053					di->events.usbchargernotok = false;
1054					di->events.usb_thermal_prot = false;
1055					di->events.vbus_ovv = false;
1056					di->events.usb_wd_expired = false;
1057					break;
1058				default:
1059					break;
1060				}
1061				break;
1062			default:
1063				break;
1064			}
1065			break;
1066
1067		case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1068			switch (ext->desc->type) {
1069			case POWER_SUPPLY_TYPE_BATTERY:
1070				di->batt_data.volt_uv = ret.intval;
1071				break;
1072			case POWER_SUPPLY_TYPE_MAINS:
1073				di->chg_info.ac_volt_uv = ret.intval;
1074				break;
1075			case POWER_SUPPLY_TYPE_USB:
1076				di->chg_info.usb_volt_uv = ret.intval;
1077				break;
1078			default:
1079				break;
1080			}
1081			break;
1082
1083		case POWER_SUPPLY_PROP_VOLTAGE_AVG:
1084			switch (ext->desc->type) {
1085			case POWER_SUPPLY_TYPE_MAINS:
1086				/* AVG is used to indicate when we are
1087				 * in CV mode */
1088				if (ret.intval)
1089					di->events.ac_cv_active = true;
1090				else
1091					di->events.ac_cv_active = false;
1092
1093				break;
1094			case POWER_SUPPLY_TYPE_USB:
1095				/* AVG is used to indicate when we are
1096				 * in CV mode */
1097				if (ret.intval)
1098					di->events.usb_cv_active = true;
1099				else
1100					di->events.usb_cv_active = false;
1101
1102				break;
1103			default:
1104				break;
1105			}
1106			break;
1107
1108		case POWER_SUPPLY_PROP_TECHNOLOGY:
1109			switch (ext->desc->type) {
1110			case POWER_SUPPLY_TYPE_BATTERY:
1111				if (ret.intval)
1112					di->events.batt_unknown = false;
1113				else
1114					di->events.batt_unknown = true;
1115
1116				break;
1117			default:
1118				break;
1119			}
1120			break;
1121
1122		case POWER_SUPPLY_PROP_TEMP:
1123			di->batt_data.temp = ret.intval / 10;
1124			break;
1125
1126		case POWER_SUPPLY_PROP_CURRENT_NOW:
1127			switch (ext->desc->type) {
1128			case POWER_SUPPLY_TYPE_MAINS:
1129				di->chg_info.ac_curr_ua = ret.intval;
1130				break;
1131			case POWER_SUPPLY_TYPE_USB:
1132				di->chg_info.usb_curr_ua = ret.intval;
1133				break;
1134			case POWER_SUPPLY_TYPE_BATTERY:
1135				di->batt_data.inst_curr_ua = ret.intval;
1136				break;
1137			default:
1138				break;
1139			}
1140			break;
1141
1142		case POWER_SUPPLY_PROP_CURRENT_AVG:
1143			switch (ext->desc->type) {
1144			case POWER_SUPPLY_TYPE_BATTERY:
1145				di->batt_data.avg_curr_ua = ret.intval;
1146				break;
1147			case POWER_SUPPLY_TYPE_USB:
1148				if (ret.intval)
1149					di->events.vbus_collapsed = true;
1150				else
1151					di->events.vbus_collapsed = false;
1152				break;
1153			default:
1154				break;
1155			}
1156			break;
1157		case POWER_SUPPLY_PROP_CAPACITY:
1158			if (!capacity_updated)
1159				di->batt_data.percent = ret.intval;
1160			break;
1161		default:
1162			break;
1163		}
1164	}
1165	return 0;
1166}
1167
1168/**
1169 * ab8500_chargalg_external_power_changed() - callback for power supply changes
1170 * @psy:       pointer to the structure power_supply
1171 *
1172 * This function is the entry point of the pointer external_power_changed
1173 * of the structure power_supply.
1174 * This function gets executed when there is a change in any external power
1175 * supply that this driver needs to be notified of.
1176 */
1177static void ab8500_chargalg_external_power_changed(struct power_supply *psy)
1178{
1179	struct ab8500_chargalg *di = power_supply_get_drvdata(psy);
1180
1181	/*
1182	 * Trigger execution of the algorithm instantly and read
1183	 * all power_supply properties there instead
1184	 */
1185	if (di->chargalg_wq)
1186		queue_work(di->chargalg_wq, &di->chargalg_work);
1187}
1188
1189/**
1190 * ab8500_chargalg_time_to_restart() - time to restart CC/CV charging?
1191 * @di: charging algorithm state
1192 *
1193 * This checks if the voltage or capacity of the battery has fallen so
1194 * low that we need to restart the CC/CV charge cycle.
1195 */
1196static bool ab8500_chargalg_time_to_restart(struct ab8500_chargalg *di)
1197{
1198	struct power_supply_battery_info *bi = di->bm->bi;
1199
1200	/* Sanity check - these need to have some reasonable values */
1201	if (!di->batt_data.volt_uv || !di->batt_data.percent)
1202		return false;
1203
1204	/* Some batteries tell us at which voltage we should restart charging */
1205	if (bi->charge_restart_voltage_uv > 0) {
1206		if (di->batt_data.volt_uv <= bi->charge_restart_voltage_uv)
1207			return true;
1208		/* Else we restart as we reach a certain capacity */
1209	} else {
1210		if (di->batt_data.percent <= AB8500_RECHARGE_CAP)
1211			return true;
1212	}
1213
1214	return false;
1215}
1216
1217/**
1218 * ab8500_chargalg_algorithm() - Main function for the algorithm
1219 * @di:		pointer to the ab8500_chargalg structure
1220 *
1221 * This is the main control function for the charging algorithm.
1222 * It is called periodically or when something happens that will
1223 * trigger a state change
1224 */
1225static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di)
1226{
1227	const struct power_supply_maintenance_charge_table *mt;
1228	struct power_supply_battery_info *bi = di->bm->bi;
1229	int charger_status;
1230	int ret;
1231
1232	/* Collect data from all power_supply class devices */
1233	power_supply_for_each_psy(di->chargalg_psy, ab8500_chargalg_get_ext_psy_data);
1234
1235	ab8500_chargalg_end_of_charge(di);
1236	ab8500_chargalg_check_temp(di);
1237	ab8500_chargalg_check_charger_voltage(di);
1238
1239	charger_status = ab8500_chargalg_check_charger_connection(di);
1240
1241	if (is_ab8500(di->parent)) {
1242		ret = ab8500_chargalg_check_charger_enable(di);
1243		if (ret < 0)
1244			dev_err(di->dev, "Checking charger is enabled error"
1245					": Returned Value %d\n", ret);
1246	}
1247
1248	/*
1249	 * First check if we have a charger connected.
1250	 * Also we don't allow charging of unknown batteries if configured
1251	 * this way
1252	 */
1253	if (!charger_status ||
1254		(di->events.batt_unknown && !di->bm->chg_unknown_bat)) {
1255		if (di->charge_state != STATE_HANDHELD) {
1256			di->events.safety_timer_expired = false;
1257			ab8500_chargalg_state_to(di, STATE_HANDHELD_INIT);
1258		}
1259	}
1260
1261	/* Safety timer expiration */
1262	else if (di->events.safety_timer_expired) {
1263		if (di->charge_state != STATE_SAFETY_TIMER_EXPIRED)
1264			ab8500_chargalg_state_to(di,
1265				STATE_SAFETY_TIMER_EXPIRED_INIT);
1266	}
1267	/*
1268	 * Check if any interrupts has occurred
1269	 * that will prevent us from charging
1270	 */
1271
1272	/* Battery removed */
1273	else if (di->events.batt_rem) {
1274		if (di->charge_state != STATE_BATT_REMOVED)
1275			ab8500_chargalg_state_to(di, STATE_BATT_REMOVED_INIT);
1276	}
1277	/* Main or USB charger not ok. */
1278	else if (di->events.mainextchnotok || di->events.usbchargernotok) {
1279		/*
1280		 * If vbus_collapsed is set, we have to lower the charger
1281		 * current, which is done in the normal state below
1282		 */
1283		if (di->charge_state != STATE_CHG_NOT_OK &&
1284				!di->events.vbus_collapsed)
1285			ab8500_chargalg_state_to(di, STATE_CHG_NOT_OK_INIT);
1286	}
1287	/* VBUS, Main or VBAT OVV. */
1288	else if (di->events.vbus_ovv ||
1289			di->events.main_ovv ||
1290			di->events.batt_ovv ||
1291			!di->chg_info.usb_chg_ok ||
1292			!di->chg_info.ac_chg_ok) {
1293		if (di->charge_state != STATE_OVV_PROTECT)
1294			ab8500_chargalg_state_to(di, STATE_OVV_PROTECT_INIT);
1295	}
1296	/* USB Thermal, stop charging */
1297	else if (di->events.main_thermal_prot ||
1298		di->events.usb_thermal_prot) {
1299		if (di->charge_state != STATE_HW_TEMP_PROTECT)
1300			ab8500_chargalg_state_to(di,
1301				STATE_HW_TEMP_PROTECT_INIT);
1302	}
1303	/* Battery temp over/under */
1304	else if (di->events.btemp_underover) {
1305		if (di->charge_state != STATE_TEMP_UNDEROVER)
1306			ab8500_chargalg_state_to(di,
1307				STATE_TEMP_UNDEROVER_INIT);
1308	}
1309	/* Watchdog expired */
1310	else if (di->events.ac_wd_expired ||
1311		di->events.usb_wd_expired) {
1312		if (di->charge_state != STATE_WD_EXPIRED)
1313			ab8500_chargalg_state_to(di, STATE_WD_EXPIRED_INIT);
1314	}
1315	/* Battery temp high/low */
1316	else if (di->events.btemp_low || di->events.btemp_high) {
1317		if (di->charge_state != STATE_TEMP_LOWHIGH)
1318			ab8500_chargalg_state_to(di, STATE_TEMP_LOWHIGH_INIT);
1319	}
1320
1321	dev_dbg(di->dev,
1322		"[CHARGALG] Vb %d Ib_avg %d Ib_inst %d Tb %d Cap %d Maint %d "
1323		"State %s Active_chg %d Chg_status %d AC %d USB %d "
1324		"AC_online %d USB_online %d AC_CV %d USB_CV %d AC_I %d "
1325		"USB_I %d AC_Vset %d AC_Iset %d USB_Vset %d USB_Iset %d\n",
1326		di->batt_data.volt_uv,
1327		di->batt_data.avg_curr_ua,
1328		di->batt_data.inst_curr_ua,
1329		di->batt_data.temp,
1330		di->batt_data.percent,
1331		di->maintenance_chg,
1332		states[di->charge_state],
1333		di->chg_info.charger_type,
1334		di->charge_status,
1335		di->chg_info.conn_chg & AC_CHG,
1336		di->chg_info.conn_chg & USB_CHG,
1337		di->chg_info.online_chg & AC_CHG,
1338		di->chg_info.online_chg & USB_CHG,
1339		di->events.ac_cv_active,
1340		di->events.usb_cv_active,
1341		di->chg_info.ac_curr_ua,
1342		di->chg_info.usb_curr_ua,
1343		di->chg_info.ac_vset_uv,
1344		di->chg_info.ac_iset_ua,
1345		di->chg_info.usb_vset_uv,
1346		di->chg_info.usb_iset_ua);
1347
1348	switch (di->charge_state) {
1349	case STATE_HANDHELD_INIT:
1350		ab8500_chargalg_stop_charging(di);
1351		di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
1352		ab8500_chargalg_state_to(di, STATE_HANDHELD);
1353		fallthrough;
1354
1355	case STATE_HANDHELD:
1356		break;
1357
1358	case STATE_BATT_REMOVED_INIT:
1359		ab8500_chargalg_stop_charging(di);
1360		ab8500_chargalg_state_to(di, STATE_BATT_REMOVED);
1361		fallthrough;
1362
1363	case STATE_BATT_REMOVED:
1364		if (!di->events.batt_rem)
1365			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1366		break;
1367
1368	case STATE_HW_TEMP_PROTECT_INIT:
1369		ab8500_chargalg_stop_charging(di);
1370		ab8500_chargalg_state_to(di, STATE_HW_TEMP_PROTECT);
1371		fallthrough;
1372
1373	case STATE_HW_TEMP_PROTECT:
1374		if (!di->events.main_thermal_prot &&
1375				!di->events.usb_thermal_prot)
1376			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1377		break;
1378
1379	case STATE_OVV_PROTECT_INIT:
1380		ab8500_chargalg_stop_charging(di);
1381		ab8500_chargalg_state_to(di, STATE_OVV_PROTECT);
1382		fallthrough;
1383
1384	case STATE_OVV_PROTECT:
1385		if (!di->events.vbus_ovv &&
1386				!di->events.main_ovv &&
1387				!di->events.batt_ovv &&
1388				di->chg_info.usb_chg_ok &&
1389				di->chg_info.ac_chg_ok)
1390			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1391		break;
1392
1393	case STATE_CHG_NOT_OK_INIT:
1394		ab8500_chargalg_stop_charging(di);
1395		ab8500_chargalg_state_to(di, STATE_CHG_NOT_OK);
1396		fallthrough;
1397
1398	case STATE_CHG_NOT_OK:
1399		if (!di->events.mainextchnotok &&
1400				!di->events.usbchargernotok)
1401			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1402		break;
1403
1404	case STATE_SAFETY_TIMER_EXPIRED_INIT:
1405		ab8500_chargalg_stop_charging(di);
1406		ab8500_chargalg_state_to(di, STATE_SAFETY_TIMER_EXPIRED);
1407		fallthrough;
1408
1409	case STATE_SAFETY_TIMER_EXPIRED:
1410		/* We exit this state when charger is removed */
1411		break;
1412
1413	case STATE_NORMAL_INIT:
1414		if (bi->constant_charge_current_max_ua == 0)
1415			/* "charging" with 0 uA */
1416			ab8500_chargalg_stop_charging(di);
1417		else {
1418			ab8500_chargalg_start_charging(di,
1419				bi->constant_charge_voltage_max_uv,
1420				bi->constant_charge_current_max_ua);
1421		}
1422
1423		ab8500_chargalg_state_to(di, STATE_NORMAL);
1424		ab8500_chargalg_start_safety_timer(di);
1425		ab8500_chargalg_stop_maintenance_timer(di);
1426		init_maxim_chg_curr(di);
1427		di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
1428		di->eoc_cnt = 0;
1429		di->maintenance_chg = false;
1430		power_supply_changed(di->chargalg_psy);
1431
1432		break;
1433
1434	case STATE_NORMAL:
1435		handle_maxim_chg_curr(di);
1436		if (di->charge_status == POWER_SUPPLY_STATUS_FULL &&
1437			di->maintenance_chg) {
1438			/*
1439			 * The battery is fully charged, check if we support
1440			 * maintenance charging else go back to waiting for
1441			 * the recharge voltage limit.
1442			 */
1443			if (!power_supply_supports_maintenance_charging(bi))
1444				ab8500_chargalg_state_to(di,
1445					STATE_WAIT_FOR_RECHARGE_INIT);
1446			else
1447				ab8500_chargalg_state_to(di,
1448					STATE_MAINTENANCE_A_INIT);
1449		}
1450		break;
1451
1452	/* This state will be used when the maintenance state is disabled */
1453	case STATE_WAIT_FOR_RECHARGE_INIT:
1454		ab8500_chargalg_hold_charging(di);
1455		ab8500_chargalg_state_to(di, STATE_WAIT_FOR_RECHARGE);
1456		fallthrough;
1457
1458	case STATE_WAIT_FOR_RECHARGE:
1459		if (ab8500_chargalg_time_to_restart(di))
1460			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1461		break;
1462
1463	case STATE_MAINTENANCE_A_INIT:
1464		mt = power_supply_get_maintenance_charging_setting(bi, 0);
1465		if (!mt) {
1466			/* No maintenance A state, go back to normal */
1467			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1468			power_supply_changed(di->chargalg_psy);
1469			break;
1470		}
1471		ab8500_chargalg_stop_safety_timer(di);
1472		ab8500_chargalg_start_maintenance_timer(di,
1473			mt->charge_safety_timer_minutes);
1474		ab8500_chargalg_start_charging(di,
1475			mt->charge_voltage_max_uv,
1476			mt->charge_current_max_ua);
1477		ab8500_chargalg_state_to(di, STATE_MAINTENANCE_A);
1478		power_supply_changed(di->chargalg_psy);
1479		fallthrough;
1480
1481	case STATE_MAINTENANCE_A:
1482		if (di->events.maintenance_timer_expired) {
1483			ab8500_chargalg_stop_maintenance_timer(di);
1484			ab8500_chargalg_state_to(di, STATE_MAINTENANCE_B_INIT);
1485		}
1486		/*
1487		 * This happens if the voltage drops too quickly during
1488		 * maintenance charging, especially in older batteries.
1489		 */
1490		if (ab8500_chargalg_time_to_restart(di)) {
1491			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1492			dev_info(di->dev, "restarted charging from maintenance state A - battery getting old?\n");
1493		}
1494		break;
1495
1496	case STATE_MAINTENANCE_B_INIT:
1497		mt = power_supply_get_maintenance_charging_setting(bi, 1);
1498		if (!mt) {
1499			/* No maintenance B state, go back to normal */
1500			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1501			power_supply_changed(di->chargalg_psy);
1502			break;
1503		}
1504		ab8500_chargalg_start_maintenance_timer(di,
1505			mt->charge_safety_timer_minutes);
1506		ab8500_chargalg_start_charging(di,
1507			mt->charge_voltage_max_uv,
1508			mt->charge_current_max_ua);
1509		ab8500_chargalg_state_to(di, STATE_MAINTENANCE_B);
1510		power_supply_changed(di->chargalg_psy);
1511		fallthrough;
1512
1513	case STATE_MAINTENANCE_B:
1514		if (di->events.maintenance_timer_expired) {
1515			ab8500_chargalg_stop_maintenance_timer(di);
1516			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1517		}
1518		/*
1519		 * This happens if the voltage drops too quickly during
1520		 * maintenance charging, especially in older batteries.
1521		 */
1522		if (ab8500_chargalg_time_to_restart(di)) {
1523			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1524			dev_info(di->dev, "restarted charging from maintenance state B - battery getting old?\n");
1525		}
1526		break;
1527
1528	case STATE_TEMP_LOWHIGH_INIT:
1529		if (di->events.btemp_low) {
1530			ab8500_chargalg_start_charging(di,
1531				       bi->alert_low_temp_charge_voltage_uv,
1532				       bi->alert_low_temp_charge_current_ua);
1533		} else if (di->events.btemp_high) {
1534			ab8500_chargalg_start_charging(di,
1535				       bi->alert_high_temp_charge_voltage_uv,
1536				       bi->alert_high_temp_charge_current_ua);
1537		} else {
1538			dev_err(di->dev, "neither low or high temp event occurred\n");
1539			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1540			break;
1541		}
1542		ab8500_chargalg_stop_maintenance_timer(di);
1543		di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
1544		ab8500_chargalg_state_to(di, STATE_TEMP_LOWHIGH);
1545		power_supply_changed(di->chargalg_psy);
1546		fallthrough;
1547
1548	case STATE_TEMP_LOWHIGH:
1549		if (!di->events.btemp_low && !di->events.btemp_high)
1550			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1551		break;
1552
1553	case STATE_WD_EXPIRED_INIT:
1554		ab8500_chargalg_stop_charging(di);
1555		ab8500_chargalg_state_to(di, STATE_WD_EXPIRED);
1556		fallthrough;
1557
1558	case STATE_WD_EXPIRED:
1559		if (!di->events.ac_wd_expired &&
1560				!di->events.usb_wd_expired)
1561			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1562		break;
1563
1564	case STATE_TEMP_UNDEROVER_INIT:
1565		ab8500_chargalg_stop_charging(di);
1566		ab8500_chargalg_state_to(di, STATE_TEMP_UNDEROVER);
1567		fallthrough;
1568
1569	case STATE_TEMP_UNDEROVER:
1570		if (!di->events.btemp_underover)
1571			ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
1572		break;
1573	}
1574
1575	/* Start charging directly if the new state is a charge state */
1576	if (di->charge_state == STATE_NORMAL_INIT ||
1577			di->charge_state == STATE_MAINTENANCE_A_INIT ||
1578			di->charge_state == STATE_MAINTENANCE_B_INIT)
1579		queue_work(di->chargalg_wq, &di->chargalg_work);
1580}
1581
1582/**
1583 * ab8500_chargalg_periodic_work() - Periodic work for the algorithm
1584 * @work:	pointer to the work_struct structure
1585 *
1586 * Work queue function for the charging algorithm
1587 */
1588static void ab8500_chargalg_periodic_work(struct work_struct *work)
1589{
1590	struct ab8500_chargalg *di = container_of(work,
1591		struct ab8500_chargalg, chargalg_periodic_work.work);
1592
1593	ab8500_chargalg_algorithm(di);
1594
1595	/*
1596	 * If a charger is connected then the battery has to be monitored
1597	 * frequently, else the work can be delayed.
1598	 */
1599	if (di->chg_info.conn_chg)
1600		queue_delayed_work(di->chargalg_wq,
1601			&di->chargalg_periodic_work,
1602			di->bm->interval_charging * HZ);
1603	else
1604		queue_delayed_work(di->chargalg_wq,
1605			&di->chargalg_periodic_work,
1606			di->bm->interval_not_charging * HZ);
1607}
1608
1609/**
1610 * ab8500_chargalg_wd_work() - periodic work to kick the charger watchdog
1611 * @work:	pointer to the work_struct structure
1612 *
1613 * Work queue function for kicking the charger watchdog
1614 */
1615static void ab8500_chargalg_wd_work(struct work_struct *work)
1616{
1617	int ret;
1618	struct ab8500_chargalg *di = container_of(work,
1619		struct ab8500_chargalg, chargalg_wd_work.work);
1620
1621	ret = ab8500_chargalg_kick_watchdog(di);
1622	if (ret < 0)
1623		dev_err(di->dev, "failed to kick watchdog\n");
1624
1625	queue_delayed_work(di->chargalg_wq,
1626		&di->chargalg_wd_work, CHG_WD_INTERVAL);
1627}
1628
1629/**
1630 * ab8500_chargalg_work() - Work to run the charging algorithm instantly
1631 * @work:	pointer to the work_struct structure
1632 *
1633 * Work queue function for calling the charging algorithm
1634 */
1635static void ab8500_chargalg_work(struct work_struct *work)
1636{
1637	struct ab8500_chargalg *di = container_of(work,
1638		struct ab8500_chargalg, chargalg_work);
1639
1640	ab8500_chargalg_algorithm(di);
1641}
1642
1643/**
1644 * ab8500_chargalg_get_property() - get the chargalg properties
1645 * @psy:	pointer to the power_supply structure
1646 * @psp:	pointer to the power_supply_property structure
1647 * @val:	pointer to the power_supply_propval union
1648 *
1649 * This function gets called when an application tries to get the
1650 * chargalg properties by reading the sysfs files.
1651 * status:     charging/discharging/full/unknown
1652 * health:     health of the battery
1653 * Returns error code in case of failure else 0 on success
1654 */
1655static int ab8500_chargalg_get_property(struct power_supply *psy,
1656	enum power_supply_property psp,
1657	union power_supply_propval *val)
1658{
1659	struct ab8500_chargalg *di = power_supply_get_drvdata(psy);
1660
1661	switch (psp) {
1662	case POWER_SUPPLY_PROP_STATUS:
1663		val->intval = di->charge_status;
1664		break;
1665	case POWER_SUPPLY_PROP_HEALTH:
1666		if (di->events.batt_ovv) {
1667			val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1668		} else if (di->events.btemp_underover) {
1669			if (di->batt_data.temp <= di->bm->bi->temp_min)
1670				val->intval = POWER_SUPPLY_HEALTH_COLD;
1671			else
1672				val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
1673		} else if (di->charge_state == STATE_SAFETY_TIMER_EXPIRED ||
1674			   di->charge_state == STATE_SAFETY_TIMER_EXPIRED_INIT) {
1675			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
1676		} else {
1677			val->intval = POWER_SUPPLY_HEALTH_GOOD;
1678		}
1679		break;
1680	default:
1681		return -EINVAL;
1682	}
1683	return 0;
1684}
1685
1686static int __maybe_unused ab8500_chargalg_resume(struct device *dev)
1687{
1688	struct ab8500_chargalg *di = dev_get_drvdata(dev);
1689
1690	/* Kick charger watchdog if charging (any charger online) */
1691	if (di->chg_info.online_chg)
1692		queue_delayed_work(di->chargalg_wq, &di->chargalg_wd_work, 0);
1693
1694	/*
1695	 * Run the charging algorithm directly to be sure we don't
1696	 * do it too seldom
1697	 */
1698	queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1699
1700	return 0;
1701}
1702
1703static int __maybe_unused ab8500_chargalg_suspend(struct device *dev)
1704{
1705	struct ab8500_chargalg *di = dev_get_drvdata(dev);
1706
1707	if (di->chg_info.online_chg)
1708		cancel_delayed_work_sync(&di->chargalg_wd_work);
1709
1710	cancel_delayed_work_sync(&di->chargalg_periodic_work);
1711
1712	return 0;
1713}
1714
1715static char *supply_interface[] = {
1716	"ab8500_fg",
1717};
1718
1719static const struct power_supply_desc ab8500_chargalg_desc = {
1720	.name			= "ab8500_chargalg",
1721	.type			= POWER_SUPPLY_TYPE_UNKNOWN,
1722	.properties		= ab8500_chargalg_props,
1723	.num_properties		= ARRAY_SIZE(ab8500_chargalg_props),
1724	.get_property		= ab8500_chargalg_get_property,
1725	.external_power_changed	= ab8500_chargalg_external_power_changed,
1726};
1727
1728static int ab8500_chargalg_bind(struct device *dev, struct device *master,
1729				void *data)
1730{
1731	struct ab8500_chargalg *di = dev_get_drvdata(dev);
1732
1733	/* Create a work queue for the chargalg */
1734	di->chargalg_wq = alloc_ordered_workqueue("ab8500_chargalg_wq",
1735						  WQ_MEM_RECLAIM);
1736	if (di->chargalg_wq == NULL) {
1737		dev_err(di->dev, "failed to create work queue\n");
1738		return -ENOMEM;
1739	}
1740
1741	/* Run the charging algorithm */
1742	queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1743
1744	return 0;
1745}
1746
1747static void ab8500_chargalg_unbind(struct device *dev, struct device *master,
1748				   void *data)
1749{
1750	struct ab8500_chargalg *di = dev_get_drvdata(dev);
1751
1752	/* Stop all timers and work */
1753	hrtimer_cancel(&di->safety_timer);
1754	hrtimer_cancel(&di->maintenance_timer);
1755
1756	cancel_delayed_work_sync(&di->chargalg_periodic_work);
1757	cancel_delayed_work_sync(&di->chargalg_wd_work);
1758	cancel_work_sync(&di->chargalg_work);
1759
1760	/* Delete the work queue */
1761	destroy_workqueue(di->chargalg_wq);
1762}
1763
1764static const struct component_ops ab8500_chargalg_component_ops = {
1765	.bind = ab8500_chargalg_bind,
1766	.unbind = ab8500_chargalg_unbind,
1767};
1768
1769static int ab8500_chargalg_probe(struct platform_device *pdev)
1770{
1771	struct device *dev = &pdev->dev;
1772	struct power_supply_config psy_cfg = {};
1773	struct ab8500_chargalg *di;
1774
1775	di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL);
1776	if (!di)
1777		return -ENOMEM;
1778
1779	di->bm = &ab8500_bm_data;
1780
1781	/* get device struct and parent */
1782	di->dev = dev;
1783	di->parent = dev_get_drvdata(pdev->dev.parent);
1784
1785	psy_cfg.supplied_to = supply_interface;
1786	psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface);
1787	psy_cfg.drv_data = di;
1788
1789	/* Initilialize safety timer */
1790	hrtimer_setup(&di->safety_timer, ab8500_chargalg_safety_timer_expired, CLOCK_MONOTONIC,
1791		      HRTIMER_MODE_REL);
1792
1793	/* Initilialize maintenance timer */
1794	hrtimer_setup(&di->maintenance_timer, ab8500_chargalg_maintenance_timer_expired,
1795		      CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1796
1797	/* Init work for chargalg */
1798	INIT_DEFERRABLE_WORK(&di->chargalg_periodic_work,
1799		ab8500_chargalg_periodic_work);
1800	INIT_DEFERRABLE_WORK(&di->chargalg_wd_work,
1801		ab8500_chargalg_wd_work);
1802
1803	/* Init work for chargalg */
1804	INIT_WORK(&di->chargalg_work, ab8500_chargalg_work);
1805
1806	/* To detect charger at startup */
1807	di->chg_info.prev_conn_chg = -1;
1808
1809	/* Register chargalg power supply class */
1810	di->chargalg_psy = devm_power_supply_register(di->dev,
1811						 &ab8500_chargalg_desc,
1812						 &psy_cfg);
1813	if (IS_ERR(di->chargalg_psy)) {
1814		dev_err(di->dev, "failed to register chargalg psy\n");
1815		return PTR_ERR(di->chargalg_psy);
1816	}
1817
1818	platform_set_drvdata(pdev, di);
1819
1820	dev_info(di->dev, "probe success\n");
1821	return component_add(dev, &ab8500_chargalg_component_ops);
1822}
1823
1824static void ab8500_chargalg_remove(struct platform_device *pdev)
1825{
1826	component_del(&pdev->dev, &ab8500_chargalg_component_ops);
1827}
1828
1829static SIMPLE_DEV_PM_OPS(ab8500_chargalg_pm_ops, ab8500_chargalg_suspend, ab8500_chargalg_resume);
1830
1831static const struct of_device_id ab8500_chargalg_match[] = {
1832	{ .compatible = "stericsson,ab8500-chargalg", },
1833	{ },
1834};
1835
1836struct platform_driver ab8500_chargalg_driver = {
1837	.probe = ab8500_chargalg_probe,
1838	.remove = ab8500_chargalg_remove,
1839	.driver = {
1840		.name = "ab8500_chargalg",
1841		.of_match_table = ab8500_chargalg_match,
1842		.pm = &ab8500_chargalg_pm_ops,
1843	},
1844};
1845MODULE_LICENSE("GPL v2");
1846MODULE_AUTHOR("Johan Palsson, Karl Komierowski");
1847MODULE_ALIAS("platform:ab8500-chargalg");
1848MODULE_DESCRIPTION("ab8500 battery charging algorithm");
~/ Read-only file preview.