xref: /openbmc/linux/drivers/power/supply/ab8500_charger.c (revision 8c0984e5a75337df513047ec92a6c09d78e3e5cd)
1*8c0984e5SSebastian Reichel /*
2*8c0984e5SSebastian Reichel  * Copyright (C) ST-Ericsson SA 2012
3*8c0984e5SSebastian Reichel  *
4*8c0984e5SSebastian Reichel  * Charger driver for AB8500
5*8c0984e5SSebastian Reichel  *
6*8c0984e5SSebastian Reichel  * License Terms: GNU General Public License v2
7*8c0984e5SSebastian Reichel  * Author:
8*8c0984e5SSebastian Reichel  *	Johan Palsson <johan.palsson@stericsson.com>
9*8c0984e5SSebastian Reichel  *	Karl Komierowski <karl.komierowski@stericsson.com>
10*8c0984e5SSebastian Reichel  *	Arun R Murthy <arun.murthy@stericsson.com>
11*8c0984e5SSebastian Reichel  */
12*8c0984e5SSebastian Reichel 
13*8c0984e5SSebastian Reichel #include <linux/init.h>
14*8c0984e5SSebastian Reichel #include <linux/module.h>
15*8c0984e5SSebastian Reichel #include <linux/device.h>
16*8c0984e5SSebastian Reichel #include <linux/interrupt.h>
17*8c0984e5SSebastian Reichel #include <linux/delay.h>
18*8c0984e5SSebastian Reichel #include <linux/notifier.h>
19*8c0984e5SSebastian Reichel #include <linux/slab.h>
20*8c0984e5SSebastian Reichel #include <linux/platform_device.h>
21*8c0984e5SSebastian Reichel #include <linux/power_supply.h>
22*8c0984e5SSebastian Reichel #include <linux/completion.h>
23*8c0984e5SSebastian Reichel #include <linux/regulator/consumer.h>
24*8c0984e5SSebastian Reichel #include <linux/err.h>
25*8c0984e5SSebastian Reichel #include <linux/workqueue.h>
26*8c0984e5SSebastian Reichel #include <linux/kobject.h>
27*8c0984e5SSebastian Reichel #include <linux/of.h>
28*8c0984e5SSebastian Reichel #include <linux/mfd/core.h>
29*8c0984e5SSebastian Reichel #include <linux/mfd/abx500/ab8500.h>
30*8c0984e5SSebastian Reichel #include <linux/mfd/abx500.h>
31*8c0984e5SSebastian Reichel #include <linux/mfd/abx500/ab8500-bm.h>
32*8c0984e5SSebastian Reichel #include <linux/mfd/abx500/ab8500-gpadc.h>
33*8c0984e5SSebastian Reichel #include <linux/mfd/abx500/ux500_chargalg.h>
34*8c0984e5SSebastian Reichel #include <linux/usb/otg.h>
35*8c0984e5SSebastian Reichel #include <linux/mutex.h>
36*8c0984e5SSebastian Reichel 
37*8c0984e5SSebastian Reichel /* Charger constants */
38*8c0984e5SSebastian Reichel #define NO_PW_CONN			0
39*8c0984e5SSebastian Reichel #define AC_PW_CONN			1
40*8c0984e5SSebastian Reichel #define USB_PW_CONN			2
41*8c0984e5SSebastian Reichel 
42*8c0984e5SSebastian Reichel #define MAIN_WDOG_ENA			0x01
43*8c0984e5SSebastian Reichel #define MAIN_WDOG_KICK			0x02
44*8c0984e5SSebastian Reichel #define MAIN_WDOG_DIS			0x00
45*8c0984e5SSebastian Reichel #define CHARG_WD_KICK			0x01
46*8c0984e5SSebastian Reichel #define MAIN_CH_ENA			0x01
47*8c0984e5SSebastian Reichel #define MAIN_CH_NO_OVERSHOOT_ENA_N	0x02
48*8c0984e5SSebastian Reichel #define USB_CH_ENA			0x01
49*8c0984e5SSebastian Reichel #define USB_CHG_NO_OVERSHOOT_ENA_N	0x02
50*8c0984e5SSebastian Reichel #define MAIN_CH_DET			0x01
51*8c0984e5SSebastian Reichel #define MAIN_CH_CV_ON			0x04
52*8c0984e5SSebastian Reichel #define USB_CH_CV_ON			0x08
53*8c0984e5SSebastian Reichel #define VBUS_DET_DBNC100		0x02
54*8c0984e5SSebastian Reichel #define VBUS_DET_DBNC1			0x01
55*8c0984e5SSebastian Reichel #define OTP_ENABLE_WD			0x01
56*8c0984e5SSebastian Reichel #define DROP_COUNT_RESET		0x01
57*8c0984e5SSebastian Reichel #define USB_CH_DET			0x01
58*8c0984e5SSebastian Reichel 
59*8c0984e5SSebastian Reichel #define MAIN_CH_INPUT_CURR_SHIFT	4
60*8c0984e5SSebastian Reichel #define VBUS_IN_CURR_LIM_SHIFT		4
61*8c0984e5SSebastian Reichel #define AB8540_VBUS_IN_CURR_LIM_SHIFT	2
62*8c0984e5SSebastian Reichel #define AUTO_VBUS_IN_CURR_LIM_SHIFT	4
63*8c0984e5SSebastian Reichel #define AB8540_AUTO_VBUS_IN_CURR_MASK	0x3F
64*8c0984e5SSebastian Reichel #define VBUS_IN_CURR_LIM_RETRY_SET_TIME	30 /* seconds */
65*8c0984e5SSebastian Reichel 
66*8c0984e5SSebastian Reichel #define LED_INDICATOR_PWM_ENA		0x01
67*8c0984e5SSebastian Reichel #define LED_INDICATOR_PWM_DIS		0x00
68*8c0984e5SSebastian Reichel #define LED_IND_CUR_5MA			0x04
69*8c0984e5SSebastian Reichel #define LED_INDICATOR_PWM_DUTY_252_256	0xBF
70*8c0984e5SSebastian Reichel 
71*8c0984e5SSebastian Reichel /* HW failure constants */
72*8c0984e5SSebastian Reichel #define MAIN_CH_TH_PROT			0x02
73*8c0984e5SSebastian Reichel #define VBUS_CH_NOK			0x08
74*8c0984e5SSebastian Reichel #define USB_CH_TH_PROT			0x02
75*8c0984e5SSebastian Reichel #define VBUS_OVV_TH			0x01
76*8c0984e5SSebastian Reichel #define MAIN_CH_NOK			0x01
77*8c0984e5SSebastian Reichel #define VBUS_DET			0x80
78*8c0984e5SSebastian Reichel 
79*8c0984e5SSebastian Reichel #define MAIN_CH_STATUS2_MAINCHGDROP		0x80
80*8c0984e5SSebastian Reichel #define MAIN_CH_STATUS2_MAINCHARGERDETDBNC	0x40
81*8c0984e5SSebastian Reichel #define USB_CH_VBUSDROP				0x40
82*8c0984e5SSebastian Reichel #define USB_CH_VBUSDETDBNC			0x01
83*8c0984e5SSebastian Reichel 
84*8c0984e5SSebastian Reichel /* UsbLineStatus register bit masks */
85*8c0984e5SSebastian Reichel #define AB8500_USB_LINK_STATUS		0x78
86*8c0984e5SSebastian Reichel #define AB8505_USB_LINK_STATUS		0xF8
87*8c0984e5SSebastian Reichel #define AB8500_STD_HOST_SUSP		0x18
88*8c0984e5SSebastian Reichel #define USB_LINK_STATUS_SHIFT		3
89*8c0984e5SSebastian Reichel 
90*8c0984e5SSebastian Reichel /* Watchdog timeout constant */
91*8c0984e5SSebastian Reichel #define WD_TIMER			0x30 /* 4min */
92*8c0984e5SSebastian Reichel #define WD_KICK_INTERVAL		(60 * HZ)
93*8c0984e5SSebastian Reichel 
94*8c0984e5SSebastian Reichel /* Lowest charger voltage is 3.39V -> 0x4E */
95*8c0984e5SSebastian Reichel #define LOW_VOLT_REG			0x4E
96*8c0984e5SSebastian Reichel 
97*8c0984e5SSebastian Reichel /* Step up/down delay in us */
98*8c0984e5SSebastian Reichel #define STEP_UDELAY			1000
99*8c0984e5SSebastian Reichel 
100*8c0984e5SSebastian Reichel #define CHARGER_STATUS_POLL 10 /* in ms */
101*8c0984e5SSebastian Reichel 
102*8c0984e5SSebastian Reichel #define CHG_WD_INTERVAL			(60 * HZ)
103*8c0984e5SSebastian Reichel 
104*8c0984e5SSebastian Reichel #define AB8500_SW_CONTROL_FALLBACK	0x03
105*8c0984e5SSebastian Reichel /* Wait for enumeration before charing in us */
106*8c0984e5SSebastian Reichel #define WAIT_ACA_RID_ENUMERATION	(5 * 1000)
107*8c0984e5SSebastian Reichel /*External charger control*/
108*8c0984e5SSebastian Reichel #define AB8500_SYS_CHARGER_CONTROL_REG		0x52
109*8c0984e5SSebastian Reichel #define EXTERNAL_CHARGER_DISABLE_REG_VAL	0x03
110*8c0984e5SSebastian Reichel #define EXTERNAL_CHARGER_ENABLE_REG_VAL		0x07
111*8c0984e5SSebastian Reichel 
112*8c0984e5SSebastian Reichel /* UsbLineStatus register - usb types */
113*8c0984e5SSebastian Reichel enum ab8500_charger_link_status {
114*8c0984e5SSebastian Reichel 	USB_STAT_NOT_CONFIGURED,
115*8c0984e5SSebastian Reichel 	USB_STAT_STD_HOST_NC,
116*8c0984e5SSebastian Reichel 	USB_STAT_STD_HOST_C_NS,
117*8c0984e5SSebastian Reichel 	USB_STAT_STD_HOST_C_S,
118*8c0984e5SSebastian Reichel 	USB_STAT_HOST_CHG_NM,
119*8c0984e5SSebastian Reichel 	USB_STAT_HOST_CHG_HS,
120*8c0984e5SSebastian Reichel 	USB_STAT_HOST_CHG_HS_CHIRP,
121*8c0984e5SSebastian Reichel 	USB_STAT_DEDICATED_CHG,
122*8c0984e5SSebastian Reichel 	USB_STAT_ACA_RID_A,
123*8c0984e5SSebastian Reichel 	USB_STAT_ACA_RID_B,
124*8c0984e5SSebastian Reichel 	USB_STAT_ACA_RID_C_NM,
125*8c0984e5SSebastian Reichel 	USB_STAT_ACA_RID_C_HS,
126*8c0984e5SSebastian Reichel 	USB_STAT_ACA_RID_C_HS_CHIRP,
127*8c0984e5SSebastian Reichel 	USB_STAT_HM_IDGND,
128*8c0984e5SSebastian Reichel 	USB_STAT_RESERVED,
129*8c0984e5SSebastian Reichel 	USB_STAT_NOT_VALID_LINK,
130*8c0984e5SSebastian Reichel 	USB_STAT_PHY_EN,
131*8c0984e5SSebastian Reichel 	USB_STAT_SUP_NO_IDGND_VBUS,
132*8c0984e5SSebastian Reichel 	USB_STAT_SUP_IDGND_VBUS,
133*8c0984e5SSebastian Reichel 	USB_STAT_CHARGER_LINE_1,
134*8c0984e5SSebastian Reichel 	USB_STAT_CARKIT_1,
135*8c0984e5SSebastian Reichel 	USB_STAT_CARKIT_2,
136*8c0984e5SSebastian Reichel 	USB_STAT_ACA_DOCK_CHARGER,
137*8c0984e5SSebastian Reichel };
138*8c0984e5SSebastian Reichel 
139*8c0984e5SSebastian Reichel enum ab8500_usb_state {
140*8c0984e5SSebastian Reichel 	AB8500_BM_USB_STATE_RESET_HS,	/* HighSpeed Reset */
141*8c0984e5SSebastian Reichel 	AB8500_BM_USB_STATE_RESET_FS,	/* FullSpeed/LowSpeed Reset */
142*8c0984e5SSebastian Reichel 	AB8500_BM_USB_STATE_CONFIGURED,
143*8c0984e5SSebastian Reichel 	AB8500_BM_USB_STATE_SUSPEND,
144*8c0984e5SSebastian Reichel 	AB8500_BM_USB_STATE_RESUME,
145*8c0984e5SSebastian Reichel 	AB8500_BM_USB_STATE_MAX,
146*8c0984e5SSebastian Reichel };
147*8c0984e5SSebastian Reichel 
148*8c0984e5SSebastian Reichel /* VBUS input current limits supported in AB8500 in mA */
149*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P05		50
150*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P09		98
151*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P19		193
152*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P29		290
153*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P38		380
154*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P45		450
155*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P5		500
156*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P6		600
157*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P7		700
158*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P8		800
159*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_0P9		900
160*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_1P0		1000
161*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_1P1		1100
162*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_1P3		1300
163*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_1P4		1400
164*8c0984e5SSebastian Reichel #define USB_CH_IP_CUR_LVL_1P5		1500
165*8c0984e5SSebastian Reichel 
166*8c0984e5SSebastian Reichel #define VBAT_TRESH_IP_CUR_RED		3800
167*8c0984e5SSebastian Reichel 
168*8c0984e5SSebastian Reichel #define to_ab8500_charger_usb_device_info(x) container_of((x), \
169*8c0984e5SSebastian Reichel 	struct ab8500_charger, usb_chg)
170*8c0984e5SSebastian Reichel #define to_ab8500_charger_ac_device_info(x) container_of((x), \
171*8c0984e5SSebastian Reichel 	struct ab8500_charger, ac_chg)
172*8c0984e5SSebastian Reichel 
173*8c0984e5SSebastian Reichel /**
174*8c0984e5SSebastian Reichel  * struct ab8500_charger_interrupts - ab8500 interupts
175*8c0984e5SSebastian Reichel  * @name:	name of the interrupt
176*8c0984e5SSebastian Reichel  * @isr		function pointer to the isr
177*8c0984e5SSebastian Reichel  */
178*8c0984e5SSebastian Reichel struct ab8500_charger_interrupts {
179*8c0984e5SSebastian Reichel 	char *name;
180*8c0984e5SSebastian Reichel 	irqreturn_t (*isr)(int irq, void *data);
181*8c0984e5SSebastian Reichel };
182*8c0984e5SSebastian Reichel 
183*8c0984e5SSebastian Reichel struct ab8500_charger_info {
184*8c0984e5SSebastian Reichel 	int charger_connected;
185*8c0984e5SSebastian Reichel 	int charger_online;
186*8c0984e5SSebastian Reichel 	int charger_voltage;
187*8c0984e5SSebastian Reichel 	int cv_active;
188*8c0984e5SSebastian Reichel 	bool wd_expired;
189*8c0984e5SSebastian Reichel 	int charger_current;
190*8c0984e5SSebastian Reichel };
191*8c0984e5SSebastian Reichel 
192*8c0984e5SSebastian Reichel struct ab8500_charger_event_flags {
193*8c0984e5SSebastian Reichel 	bool mainextchnotok;
194*8c0984e5SSebastian Reichel 	bool main_thermal_prot;
195*8c0984e5SSebastian Reichel 	bool usb_thermal_prot;
196*8c0984e5SSebastian Reichel 	bool vbus_ovv;
197*8c0984e5SSebastian Reichel 	bool usbchargernotok;
198*8c0984e5SSebastian Reichel 	bool chgwdexp;
199*8c0984e5SSebastian Reichel 	bool vbus_collapse;
200*8c0984e5SSebastian Reichel 	bool vbus_drop_end;
201*8c0984e5SSebastian Reichel };
202*8c0984e5SSebastian Reichel 
203*8c0984e5SSebastian Reichel struct ab8500_charger_usb_state {
204*8c0984e5SSebastian Reichel 	int usb_current;
205*8c0984e5SSebastian Reichel 	int usb_current_tmp;
206*8c0984e5SSebastian Reichel 	enum ab8500_usb_state state;
207*8c0984e5SSebastian Reichel 	enum ab8500_usb_state state_tmp;
208*8c0984e5SSebastian Reichel 	spinlock_t usb_lock;
209*8c0984e5SSebastian Reichel };
210*8c0984e5SSebastian Reichel 
211*8c0984e5SSebastian Reichel struct ab8500_charger_max_usb_in_curr {
212*8c0984e5SSebastian Reichel 	int usb_type_max;
213*8c0984e5SSebastian Reichel 	int set_max;
214*8c0984e5SSebastian Reichel 	int calculated_max;
215*8c0984e5SSebastian Reichel };
216*8c0984e5SSebastian Reichel 
217*8c0984e5SSebastian Reichel /**
218*8c0984e5SSebastian Reichel  * struct ab8500_charger - ab8500 Charger device information
219*8c0984e5SSebastian Reichel  * @dev:		Pointer to the structure device
220*8c0984e5SSebastian Reichel  * @vbus_detected:	VBUS detected
221*8c0984e5SSebastian Reichel  * @vbus_detected_start:
222*8c0984e5SSebastian Reichel  *			VBUS detected during startup
223*8c0984e5SSebastian Reichel  * @ac_conn:		This will be true when the AC charger has been plugged
224*8c0984e5SSebastian Reichel  * @vddadc_en_ac:	Indicate if VDD ADC supply is enabled because AC
225*8c0984e5SSebastian Reichel  *			charger is enabled
226*8c0984e5SSebastian Reichel  * @vddadc_en_usb:	Indicate if VDD ADC supply is enabled because USB
227*8c0984e5SSebastian Reichel  *			charger is enabled
228*8c0984e5SSebastian Reichel  * @vbat		Battery voltage
229*8c0984e5SSebastian Reichel  * @old_vbat		Previously measured battery voltage
230*8c0984e5SSebastian Reichel  * @usb_device_is_unrecognised	USB device is unrecognised by the hardware
231*8c0984e5SSebastian Reichel  * @autopower		Indicate if we should have automatic pwron after pwrloss
232*8c0984e5SSebastian Reichel  * @autopower_cfg	platform specific power config support for "pwron after pwrloss"
233*8c0984e5SSebastian Reichel  * @invalid_charger_detect_state State when forcing AB to use invalid charger
234*8c0984e5SSebastian Reichel  * @is_aca_rid:		Incicate if accessory is ACA type
235*8c0984e5SSebastian Reichel  * @current_stepping_sessions:
236*8c0984e5SSebastian Reichel  *			Counter for current stepping sessions
237*8c0984e5SSebastian Reichel  * @parent:		Pointer to the struct ab8500
238*8c0984e5SSebastian Reichel  * @gpadc:		Pointer to the struct gpadc
239*8c0984e5SSebastian Reichel  * @bm:           	Platform specific battery management information
240*8c0984e5SSebastian Reichel  * @flags:		Structure for information about events triggered
241*8c0984e5SSebastian Reichel  * @usb_state:		Structure for usb stack information
242*8c0984e5SSebastian Reichel  * @max_usb_in_curr:	Max USB charger input current
243*8c0984e5SSebastian Reichel  * @ac_chg:		AC charger power supply
244*8c0984e5SSebastian Reichel  * @usb_chg:		USB charger power supply
245*8c0984e5SSebastian Reichel  * @ac:			Structure that holds the AC charger properties
246*8c0984e5SSebastian Reichel  * @usb:		Structure that holds the USB charger properties
247*8c0984e5SSebastian Reichel  * @regu:		Pointer to the struct regulator
248*8c0984e5SSebastian Reichel  * @charger_wq:		Work queue for the IRQs and checking HW state
249*8c0984e5SSebastian Reichel  * @usb_ipt_crnt_lock:	Lock to protect VBUS input current setting from mutuals
250*8c0984e5SSebastian Reichel  * @pm_lock:		Lock to prevent system to suspend
251*8c0984e5SSebastian Reichel  * @check_vbat_work	Work for checking vbat threshold to adjust vbus current
252*8c0984e5SSebastian Reichel  * @check_hw_failure_work:	Work for checking HW state
253*8c0984e5SSebastian Reichel  * @check_usbchgnotok_work:	Work for checking USB charger not ok status
254*8c0984e5SSebastian Reichel  * @kick_wd_work:		Work for kicking the charger watchdog in case
255*8c0984e5SSebastian Reichel  *				of ABB rev 1.* due to the watchog logic bug
256*8c0984e5SSebastian Reichel  * @ac_charger_attached_work:	Work for checking if AC charger is still
257*8c0984e5SSebastian Reichel  *				connected
258*8c0984e5SSebastian Reichel  * @usb_charger_attached_work:	Work for checking if USB charger is still
259*8c0984e5SSebastian Reichel  *				connected
260*8c0984e5SSebastian Reichel  * @ac_work:			Work for checking AC charger connection
261*8c0984e5SSebastian Reichel  * @detect_usb_type_work:	Work for detecting the USB type connected
262*8c0984e5SSebastian Reichel  * @usb_link_status_work:	Work for checking the new USB link status
263*8c0984e5SSebastian Reichel  * @usb_state_changed_work:	Work for checking USB state
264*8c0984e5SSebastian Reichel  * @attach_work:		Work for detecting USB type
265*8c0984e5SSebastian Reichel  * @vbus_drop_end_work:		Work for detecting VBUS drop end
266*8c0984e5SSebastian Reichel  * @check_main_thermal_prot_work:
267*8c0984e5SSebastian Reichel  *				Work for checking Main thermal status
268*8c0984e5SSebastian Reichel  * @check_usb_thermal_prot_work:
269*8c0984e5SSebastian Reichel  *				Work for checking USB thermal status
270*8c0984e5SSebastian Reichel  * @charger_attached_mutex:	For controlling the wakelock
271*8c0984e5SSebastian Reichel  */
272*8c0984e5SSebastian Reichel struct ab8500_charger {
273*8c0984e5SSebastian Reichel 	struct device *dev;
274*8c0984e5SSebastian Reichel 	bool vbus_detected;
275*8c0984e5SSebastian Reichel 	bool vbus_detected_start;
276*8c0984e5SSebastian Reichel 	bool ac_conn;
277*8c0984e5SSebastian Reichel 	bool vddadc_en_ac;
278*8c0984e5SSebastian Reichel 	bool vddadc_en_usb;
279*8c0984e5SSebastian Reichel 	int vbat;
280*8c0984e5SSebastian Reichel 	int old_vbat;
281*8c0984e5SSebastian Reichel 	bool usb_device_is_unrecognised;
282*8c0984e5SSebastian Reichel 	bool autopower;
283*8c0984e5SSebastian Reichel 	bool autopower_cfg;
284*8c0984e5SSebastian Reichel 	int invalid_charger_detect_state;
285*8c0984e5SSebastian Reichel 	int is_aca_rid;
286*8c0984e5SSebastian Reichel 	atomic_t current_stepping_sessions;
287*8c0984e5SSebastian Reichel 	struct ab8500 *parent;
288*8c0984e5SSebastian Reichel 	struct ab8500_gpadc *gpadc;
289*8c0984e5SSebastian Reichel 	struct abx500_bm_data *bm;
290*8c0984e5SSebastian Reichel 	struct ab8500_charger_event_flags flags;
291*8c0984e5SSebastian Reichel 	struct ab8500_charger_usb_state usb_state;
292*8c0984e5SSebastian Reichel 	struct ab8500_charger_max_usb_in_curr max_usb_in_curr;
293*8c0984e5SSebastian Reichel 	struct ux500_charger ac_chg;
294*8c0984e5SSebastian Reichel 	struct ux500_charger usb_chg;
295*8c0984e5SSebastian Reichel 	struct ab8500_charger_info ac;
296*8c0984e5SSebastian Reichel 	struct ab8500_charger_info usb;
297*8c0984e5SSebastian Reichel 	struct regulator *regu;
298*8c0984e5SSebastian Reichel 	struct workqueue_struct *charger_wq;
299*8c0984e5SSebastian Reichel 	struct mutex usb_ipt_crnt_lock;
300*8c0984e5SSebastian Reichel 	struct delayed_work check_vbat_work;
301*8c0984e5SSebastian Reichel 	struct delayed_work check_hw_failure_work;
302*8c0984e5SSebastian Reichel 	struct delayed_work check_usbchgnotok_work;
303*8c0984e5SSebastian Reichel 	struct delayed_work kick_wd_work;
304*8c0984e5SSebastian Reichel 	struct delayed_work usb_state_changed_work;
305*8c0984e5SSebastian Reichel 	struct delayed_work attach_work;
306*8c0984e5SSebastian Reichel 	struct delayed_work ac_charger_attached_work;
307*8c0984e5SSebastian Reichel 	struct delayed_work usb_charger_attached_work;
308*8c0984e5SSebastian Reichel 	struct delayed_work vbus_drop_end_work;
309*8c0984e5SSebastian Reichel 	struct work_struct ac_work;
310*8c0984e5SSebastian Reichel 	struct work_struct detect_usb_type_work;
311*8c0984e5SSebastian Reichel 	struct work_struct usb_link_status_work;
312*8c0984e5SSebastian Reichel 	struct work_struct check_main_thermal_prot_work;
313*8c0984e5SSebastian Reichel 	struct work_struct check_usb_thermal_prot_work;
314*8c0984e5SSebastian Reichel 	struct usb_phy *usb_phy;
315*8c0984e5SSebastian Reichel 	struct notifier_block nb;
316*8c0984e5SSebastian Reichel 	struct mutex charger_attached_mutex;
317*8c0984e5SSebastian Reichel };
318*8c0984e5SSebastian Reichel 
319*8c0984e5SSebastian Reichel /* AC properties */
320*8c0984e5SSebastian Reichel static enum power_supply_property ab8500_charger_ac_props[] = {
321*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_HEALTH,
322*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_PRESENT,
323*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_ONLINE,
324*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
325*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_VOLTAGE_AVG,
326*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_CURRENT_NOW,
327*8c0984e5SSebastian Reichel };
328*8c0984e5SSebastian Reichel 
329*8c0984e5SSebastian Reichel /* USB properties */
330*8c0984e5SSebastian Reichel static enum power_supply_property ab8500_charger_usb_props[] = {
331*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_HEALTH,
332*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_CURRENT_AVG,
333*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_PRESENT,
334*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_ONLINE,
335*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
336*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_VOLTAGE_AVG,
337*8c0984e5SSebastian Reichel 	POWER_SUPPLY_PROP_CURRENT_NOW,
338*8c0984e5SSebastian Reichel };
339*8c0984e5SSebastian Reichel 
340*8c0984e5SSebastian Reichel /*
341*8c0984e5SSebastian Reichel  * Function for enabling and disabling sw fallback mode
342*8c0984e5SSebastian Reichel  * should always be disabled when no charger is connected.
343*8c0984e5SSebastian Reichel  */
344*8c0984e5SSebastian Reichel static void ab8500_enable_disable_sw_fallback(struct ab8500_charger *di,
345*8c0984e5SSebastian Reichel 		bool fallback)
346*8c0984e5SSebastian Reichel {
347*8c0984e5SSebastian Reichel 	u8 val;
348*8c0984e5SSebastian Reichel 	u8 reg;
349*8c0984e5SSebastian Reichel 	u8 bank;
350*8c0984e5SSebastian Reichel 	u8 bit;
351*8c0984e5SSebastian Reichel 	int ret;
352*8c0984e5SSebastian Reichel 
353*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "SW Fallback: %d\n", fallback);
354*8c0984e5SSebastian Reichel 
355*8c0984e5SSebastian Reichel 	if (is_ab8500(di->parent)) {
356*8c0984e5SSebastian Reichel 		bank = 0x15;
357*8c0984e5SSebastian Reichel 		reg = 0x0;
358*8c0984e5SSebastian Reichel 		bit = 3;
359*8c0984e5SSebastian Reichel 	} else {
360*8c0984e5SSebastian Reichel 		bank = AB8500_SYS_CTRL1_BLOCK;
361*8c0984e5SSebastian Reichel 		reg = AB8500_SW_CONTROL_FALLBACK;
362*8c0984e5SSebastian Reichel 		bit = 0;
363*8c0984e5SSebastian Reichel 	}
364*8c0984e5SSebastian Reichel 
365*8c0984e5SSebastian Reichel 	/* read the register containing fallback bit */
366*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev, bank, reg, &val);
367*8c0984e5SSebastian Reichel 	if (ret < 0) {
368*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%d read failed\n", __LINE__);
369*8c0984e5SSebastian Reichel 		return;
370*8c0984e5SSebastian Reichel 	}
371*8c0984e5SSebastian Reichel 
372*8c0984e5SSebastian Reichel 	if (is_ab8500(di->parent)) {
373*8c0984e5SSebastian Reichel 		/* enable the OPT emulation registers */
374*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x2);
375*8c0984e5SSebastian Reichel 		if (ret) {
376*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%d write failed\n", __LINE__);
377*8c0984e5SSebastian Reichel 			goto disable_otp;
378*8c0984e5SSebastian Reichel 		}
379*8c0984e5SSebastian Reichel 	}
380*8c0984e5SSebastian Reichel 
381*8c0984e5SSebastian Reichel 	if (fallback)
382*8c0984e5SSebastian Reichel 		val |= (1 << bit);
383*8c0984e5SSebastian Reichel 	else
384*8c0984e5SSebastian Reichel 		val &= ~(1 << bit);
385*8c0984e5SSebastian Reichel 
386*8c0984e5SSebastian Reichel 	/* write back the changed fallback bit value to register */
387*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev, bank, reg, val);
388*8c0984e5SSebastian Reichel 	if (ret) {
389*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%d write failed\n", __LINE__);
390*8c0984e5SSebastian Reichel 	}
391*8c0984e5SSebastian Reichel 
392*8c0984e5SSebastian Reichel disable_otp:
393*8c0984e5SSebastian Reichel 	if (is_ab8500(di->parent)) {
394*8c0984e5SSebastian Reichel 		/* disable the set OTP registers again */
395*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x0);
396*8c0984e5SSebastian Reichel 		if (ret) {
397*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%d write failed\n", __LINE__);
398*8c0984e5SSebastian Reichel 		}
399*8c0984e5SSebastian Reichel 	}
400*8c0984e5SSebastian Reichel }
401*8c0984e5SSebastian Reichel 
402*8c0984e5SSebastian Reichel /**
403*8c0984e5SSebastian Reichel  * ab8500_power_supply_changed - a wrapper with local extentions for
404*8c0984e5SSebastian Reichel  * power_supply_changed
405*8c0984e5SSebastian Reichel  * @di:	  pointer to the ab8500_charger structure
406*8c0984e5SSebastian Reichel  * @psy:  pointer to power_supply_that have changed.
407*8c0984e5SSebastian Reichel  *
408*8c0984e5SSebastian Reichel  */
409*8c0984e5SSebastian Reichel static void ab8500_power_supply_changed(struct ab8500_charger *di,
410*8c0984e5SSebastian Reichel 					struct power_supply *psy)
411*8c0984e5SSebastian Reichel {
412*8c0984e5SSebastian Reichel 	if (di->autopower_cfg) {
413*8c0984e5SSebastian Reichel 		if (!di->usb.charger_connected &&
414*8c0984e5SSebastian Reichel 		    !di->ac.charger_connected &&
415*8c0984e5SSebastian Reichel 		    di->autopower) {
416*8c0984e5SSebastian Reichel 			di->autopower = false;
417*8c0984e5SSebastian Reichel 			ab8500_enable_disable_sw_fallback(di, false);
418*8c0984e5SSebastian Reichel 		} else if (!di->autopower &&
419*8c0984e5SSebastian Reichel 			   (di->ac.charger_connected ||
420*8c0984e5SSebastian Reichel 			    di->usb.charger_connected)) {
421*8c0984e5SSebastian Reichel 			di->autopower = true;
422*8c0984e5SSebastian Reichel 			ab8500_enable_disable_sw_fallback(di, true);
423*8c0984e5SSebastian Reichel 		}
424*8c0984e5SSebastian Reichel 	}
425*8c0984e5SSebastian Reichel 	power_supply_changed(psy);
426*8c0984e5SSebastian Reichel }
427*8c0984e5SSebastian Reichel 
428*8c0984e5SSebastian Reichel static void ab8500_charger_set_usb_connected(struct ab8500_charger *di,
429*8c0984e5SSebastian Reichel 	bool connected)
430*8c0984e5SSebastian Reichel {
431*8c0984e5SSebastian Reichel 	if (connected != di->usb.charger_connected) {
432*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "USB connected:%i\n", connected);
433*8c0984e5SSebastian Reichel 		di->usb.charger_connected = connected;
434*8c0984e5SSebastian Reichel 
435*8c0984e5SSebastian Reichel 		if (!connected)
436*8c0984e5SSebastian Reichel 			di->flags.vbus_drop_end = false;
437*8c0984e5SSebastian Reichel 
438*8c0984e5SSebastian Reichel 		sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, "present");
439*8c0984e5SSebastian Reichel 
440*8c0984e5SSebastian Reichel 		if (connected) {
441*8c0984e5SSebastian Reichel 			mutex_lock(&di->charger_attached_mutex);
442*8c0984e5SSebastian Reichel 			mutex_unlock(&di->charger_attached_mutex);
443*8c0984e5SSebastian Reichel 
444*8c0984e5SSebastian Reichel 			if (is_ab8500(di->parent))
445*8c0984e5SSebastian Reichel 				queue_delayed_work(di->charger_wq,
446*8c0984e5SSebastian Reichel 					   &di->usb_charger_attached_work,
447*8c0984e5SSebastian Reichel 					   HZ);
448*8c0984e5SSebastian Reichel 		} else {
449*8c0984e5SSebastian Reichel 			cancel_delayed_work_sync(&di->usb_charger_attached_work);
450*8c0984e5SSebastian Reichel 			mutex_lock(&di->charger_attached_mutex);
451*8c0984e5SSebastian Reichel 			mutex_unlock(&di->charger_attached_mutex);
452*8c0984e5SSebastian Reichel 		}
453*8c0984e5SSebastian Reichel 	}
454*8c0984e5SSebastian Reichel }
455*8c0984e5SSebastian Reichel 
456*8c0984e5SSebastian Reichel /**
457*8c0984e5SSebastian Reichel  * ab8500_charger_get_ac_voltage() - get ac charger voltage
458*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
459*8c0984e5SSebastian Reichel  *
460*8c0984e5SSebastian Reichel  * Returns ac charger voltage (on success)
461*8c0984e5SSebastian Reichel  */
462*8c0984e5SSebastian Reichel static int ab8500_charger_get_ac_voltage(struct ab8500_charger *di)
463*8c0984e5SSebastian Reichel {
464*8c0984e5SSebastian Reichel 	int vch;
465*8c0984e5SSebastian Reichel 
466*8c0984e5SSebastian Reichel 	/* Only measure voltage if the charger is connected */
467*8c0984e5SSebastian Reichel 	if (di->ac.charger_connected) {
468*8c0984e5SSebastian Reichel 		vch = ab8500_gpadc_convert(di->gpadc, MAIN_CHARGER_V);
469*8c0984e5SSebastian Reichel 		if (vch < 0)
470*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s gpadc conv failed,\n", __func__);
471*8c0984e5SSebastian Reichel 	} else {
472*8c0984e5SSebastian Reichel 		vch = 0;
473*8c0984e5SSebastian Reichel 	}
474*8c0984e5SSebastian Reichel 	return vch;
475*8c0984e5SSebastian Reichel }
476*8c0984e5SSebastian Reichel 
477*8c0984e5SSebastian Reichel /**
478*8c0984e5SSebastian Reichel  * ab8500_charger_ac_cv() - check if the main charger is in CV mode
479*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
480*8c0984e5SSebastian Reichel  *
481*8c0984e5SSebastian Reichel  * Returns ac charger CV mode (on success) else error code
482*8c0984e5SSebastian Reichel  */
483*8c0984e5SSebastian Reichel static int ab8500_charger_ac_cv(struct ab8500_charger *di)
484*8c0984e5SSebastian Reichel {
485*8c0984e5SSebastian Reichel 	u8 val;
486*8c0984e5SSebastian Reichel 	int ret = 0;
487*8c0984e5SSebastian Reichel 
488*8c0984e5SSebastian Reichel 	/* Only check CV mode if the charger is online */
489*8c0984e5SSebastian Reichel 	if (di->ac.charger_online) {
490*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
491*8c0984e5SSebastian Reichel 			AB8500_CH_STATUS1_REG, &val);
492*8c0984e5SSebastian Reichel 		if (ret < 0) {
493*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s ab8500 read failed\n", __func__);
494*8c0984e5SSebastian Reichel 			return 0;
495*8c0984e5SSebastian Reichel 		}
496*8c0984e5SSebastian Reichel 
497*8c0984e5SSebastian Reichel 		if (val & MAIN_CH_CV_ON)
498*8c0984e5SSebastian Reichel 			ret = 1;
499*8c0984e5SSebastian Reichel 		else
500*8c0984e5SSebastian Reichel 			ret = 0;
501*8c0984e5SSebastian Reichel 	}
502*8c0984e5SSebastian Reichel 
503*8c0984e5SSebastian Reichel 	return ret;
504*8c0984e5SSebastian Reichel }
505*8c0984e5SSebastian Reichel 
506*8c0984e5SSebastian Reichel /**
507*8c0984e5SSebastian Reichel  * ab8500_charger_get_vbus_voltage() - get vbus voltage
508*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
509*8c0984e5SSebastian Reichel  *
510*8c0984e5SSebastian Reichel  * This function returns the vbus voltage.
511*8c0984e5SSebastian Reichel  * Returns vbus voltage (on success)
512*8c0984e5SSebastian Reichel  */
513*8c0984e5SSebastian Reichel static int ab8500_charger_get_vbus_voltage(struct ab8500_charger *di)
514*8c0984e5SSebastian Reichel {
515*8c0984e5SSebastian Reichel 	int vch;
516*8c0984e5SSebastian Reichel 
517*8c0984e5SSebastian Reichel 	/* Only measure voltage if the charger is connected */
518*8c0984e5SSebastian Reichel 	if (di->usb.charger_connected) {
519*8c0984e5SSebastian Reichel 		vch = ab8500_gpadc_convert(di->gpadc, VBUS_V);
520*8c0984e5SSebastian Reichel 		if (vch < 0)
521*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s gpadc conv failed\n", __func__);
522*8c0984e5SSebastian Reichel 	} else {
523*8c0984e5SSebastian Reichel 		vch = 0;
524*8c0984e5SSebastian Reichel 	}
525*8c0984e5SSebastian Reichel 	return vch;
526*8c0984e5SSebastian Reichel }
527*8c0984e5SSebastian Reichel 
528*8c0984e5SSebastian Reichel /**
529*8c0984e5SSebastian Reichel  * ab8500_charger_get_usb_current() - get usb charger current
530*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
531*8c0984e5SSebastian Reichel  *
532*8c0984e5SSebastian Reichel  * This function returns the usb charger current.
533*8c0984e5SSebastian Reichel  * Returns usb current (on success) and error code on failure
534*8c0984e5SSebastian Reichel  */
535*8c0984e5SSebastian Reichel static int ab8500_charger_get_usb_current(struct ab8500_charger *di)
536*8c0984e5SSebastian Reichel {
537*8c0984e5SSebastian Reichel 	int ich;
538*8c0984e5SSebastian Reichel 
539*8c0984e5SSebastian Reichel 	/* Only measure current if the charger is online */
540*8c0984e5SSebastian Reichel 	if (di->usb.charger_online) {
541*8c0984e5SSebastian Reichel 		ich = ab8500_gpadc_convert(di->gpadc, USB_CHARGER_C);
542*8c0984e5SSebastian Reichel 		if (ich < 0)
543*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s gpadc conv failed\n", __func__);
544*8c0984e5SSebastian Reichel 	} else {
545*8c0984e5SSebastian Reichel 		ich = 0;
546*8c0984e5SSebastian Reichel 	}
547*8c0984e5SSebastian Reichel 	return ich;
548*8c0984e5SSebastian Reichel }
549*8c0984e5SSebastian Reichel 
550*8c0984e5SSebastian Reichel /**
551*8c0984e5SSebastian Reichel  * ab8500_charger_get_ac_current() - get ac charger current
552*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
553*8c0984e5SSebastian Reichel  *
554*8c0984e5SSebastian Reichel  * This function returns the ac charger current.
555*8c0984e5SSebastian Reichel  * Returns ac current (on success) and error code on failure.
556*8c0984e5SSebastian Reichel  */
557*8c0984e5SSebastian Reichel static int ab8500_charger_get_ac_current(struct ab8500_charger *di)
558*8c0984e5SSebastian Reichel {
559*8c0984e5SSebastian Reichel 	int ich;
560*8c0984e5SSebastian Reichel 
561*8c0984e5SSebastian Reichel 	/* Only measure current if the charger is online */
562*8c0984e5SSebastian Reichel 	if (di->ac.charger_online) {
563*8c0984e5SSebastian Reichel 		ich = ab8500_gpadc_convert(di->gpadc, MAIN_CHARGER_C);
564*8c0984e5SSebastian Reichel 		if (ich < 0)
565*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s gpadc conv failed\n", __func__);
566*8c0984e5SSebastian Reichel 	} else {
567*8c0984e5SSebastian Reichel 		ich = 0;
568*8c0984e5SSebastian Reichel 	}
569*8c0984e5SSebastian Reichel 	return ich;
570*8c0984e5SSebastian Reichel }
571*8c0984e5SSebastian Reichel 
572*8c0984e5SSebastian Reichel /**
573*8c0984e5SSebastian Reichel  * ab8500_charger_usb_cv() - check if the usb charger is in CV mode
574*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
575*8c0984e5SSebastian Reichel  *
576*8c0984e5SSebastian Reichel  * Returns ac charger CV mode (on success) else error code
577*8c0984e5SSebastian Reichel  */
578*8c0984e5SSebastian Reichel static int ab8500_charger_usb_cv(struct ab8500_charger *di)
579*8c0984e5SSebastian Reichel {
580*8c0984e5SSebastian Reichel 	int ret;
581*8c0984e5SSebastian Reichel 	u8 val;
582*8c0984e5SSebastian Reichel 
583*8c0984e5SSebastian Reichel 	/* Only check CV mode if the charger is online */
584*8c0984e5SSebastian Reichel 	if (di->usb.charger_online) {
585*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
586*8c0984e5SSebastian Reichel 			AB8500_CH_USBCH_STAT1_REG, &val);
587*8c0984e5SSebastian Reichel 		if (ret < 0) {
588*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s ab8500 read failed\n", __func__);
589*8c0984e5SSebastian Reichel 			return 0;
590*8c0984e5SSebastian Reichel 		}
591*8c0984e5SSebastian Reichel 
592*8c0984e5SSebastian Reichel 		if (val & USB_CH_CV_ON)
593*8c0984e5SSebastian Reichel 			ret = 1;
594*8c0984e5SSebastian Reichel 		else
595*8c0984e5SSebastian Reichel 			ret = 0;
596*8c0984e5SSebastian Reichel 	} else {
597*8c0984e5SSebastian Reichel 		ret = 0;
598*8c0984e5SSebastian Reichel 	}
599*8c0984e5SSebastian Reichel 
600*8c0984e5SSebastian Reichel 	return ret;
601*8c0984e5SSebastian Reichel }
602*8c0984e5SSebastian Reichel 
603*8c0984e5SSebastian Reichel /**
604*8c0984e5SSebastian Reichel  * ab8500_charger_detect_chargers() - Detect the connected chargers
605*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
606*8c0984e5SSebastian Reichel  * @probe:	if probe, don't delay and wait for HW
607*8c0984e5SSebastian Reichel  *
608*8c0984e5SSebastian Reichel  * Returns the type of charger connected.
609*8c0984e5SSebastian Reichel  * For USB it will not mean we can actually charge from it
610*8c0984e5SSebastian Reichel  * but that there is a USB cable connected that we have to
611*8c0984e5SSebastian Reichel  * identify. This is used during startup when we don't get
612*8c0984e5SSebastian Reichel  * interrupts of the charger detection
613*8c0984e5SSebastian Reichel  *
614*8c0984e5SSebastian Reichel  * Returns an integer value, that means,
615*8c0984e5SSebastian Reichel  * NO_PW_CONN  no power supply is connected
616*8c0984e5SSebastian Reichel  * AC_PW_CONN  if the AC power supply is connected
617*8c0984e5SSebastian Reichel  * USB_PW_CONN  if the USB power supply is connected
618*8c0984e5SSebastian Reichel  * AC_PW_CONN + USB_PW_CONN if USB and AC power supplies are both connected
619*8c0984e5SSebastian Reichel  */
620*8c0984e5SSebastian Reichel static int ab8500_charger_detect_chargers(struct ab8500_charger *di, bool probe)
621*8c0984e5SSebastian Reichel {
622*8c0984e5SSebastian Reichel 	int result = NO_PW_CONN;
623*8c0984e5SSebastian Reichel 	int ret;
624*8c0984e5SSebastian Reichel 	u8 val;
625*8c0984e5SSebastian Reichel 
626*8c0984e5SSebastian Reichel 	/* Check for AC charger */
627*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
628*8c0984e5SSebastian Reichel 		AB8500_CH_STATUS1_REG, &val);
629*8c0984e5SSebastian Reichel 	if (ret < 0) {
630*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s ab8500 read failed\n", __func__);
631*8c0984e5SSebastian Reichel 		return ret;
632*8c0984e5SSebastian Reichel 	}
633*8c0984e5SSebastian Reichel 
634*8c0984e5SSebastian Reichel 	if (val & MAIN_CH_DET)
635*8c0984e5SSebastian Reichel 		result = AC_PW_CONN;
636*8c0984e5SSebastian Reichel 
637*8c0984e5SSebastian Reichel 	/* Check for USB charger */
638*8c0984e5SSebastian Reichel 
639*8c0984e5SSebastian Reichel 	if (!probe) {
640*8c0984e5SSebastian Reichel 		/*
641*8c0984e5SSebastian Reichel 		 * AB8500 says VBUS_DET_DBNC1 & VBUS_DET_DBNC100
642*8c0984e5SSebastian Reichel 		 * when disconnecting ACA even though no
643*8c0984e5SSebastian Reichel 		 * charger was connected. Try waiting a little
644*8c0984e5SSebastian Reichel 		 * longer than the 100 ms of VBUS_DET_DBNC100...
645*8c0984e5SSebastian Reichel 		 */
646*8c0984e5SSebastian Reichel 		msleep(110);
647*8c0984e5SSebastian Reichel 	}
648*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
649*8c0984e5SSebastian Reichel 		AB8500_CH_USBCH_STAT1_REG, &val);
650*8c0984e5SSebastian Reichel 	if (ret < 0) {
651*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s ab8500 read failed\n", __func__);
652*8c0984e5SSebastian Reichel 		return ret;
653*8c0984e5SSebastian Reichel 	}
654*8c0984e5SSebastian Reichel 	dev_dbg(di->dev,
655*8c0984e5SSebastian Reichel 		"%s AB8500_CH_USBCH_STAT1_REG %x\n", __func__,
656*8c0984e5SSebastian Reichel 		val);
657*8c0984e5SSebastian Reichel 	if ((val & VBUS_DET_DBNC1) && (val & VBUS_DET_DBNC100))
658*8c0984e5SSebastian Reichel 		result |= USB_PW_CONN;
659*8c0984e5SSebastian Reichel 
660*8c0984e5SSebastian Reichel 	return result;
661*8c0984e5SSebastian Reichel }
662*8c0984e5SSebastian Reichel 
663*8c0984e5SSebastian Reichel /**
664*8c0984e5SSebastian Reichel  * ab8500_charger_max_usb_curr() - get the max curr for the USB type
665*8c0984e5SSebastian Reichel  * @di:			pointer to the ab8500_charger structure
666*8c0984e5SSebastian Reichel  * @link_status:	the identified USB type
667*8c0984e5SSebastian Reichel  *
668*8c0984e5SSebastian Reichel  * Get the maximum current that is allowed to be drawn from the host
669*8c0984e5SSebastian Reichel  * based on the USB type.
670*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0 on success
671*8c0984e5SSebastian Reichel  */
672*8c0984e5SSebastian Reichel static int ab8500_charger_max_usb_curr(struct ab8500_charger *di,
673*8c0984e5SSebastian Reichel 		enum ab8500_charger_link_status link_status)
674*8c0984e5SSebastian Reichel {
675*8c0984e5SSebastian Reichel 	int ret = 0;
676*8c0984e5SSebastian Reichel 
677*8c0984e5SSebastian Reichel 	di->usb_device_is_unrecognised = false;
678*8c0984e5SSebastian Reichel 
679*8c0984e5SSebastian Reichel 	/*
680*8c0984e5SSebastian Reichel 	 * Platform only supports USB 2.0.
681*8c0984e5SSebastian Reichel 	 * This means that charging current from USB source
682*8c0984e5SSebastian Reichel 	 * is maximum 500 mA. Every occurence of USB_STAT_*_HOST_*
683*8c0984e5SSebastian Reichel 	 * should set USB_CH_IP_CUR_LVL_0P5.
684*8c0984e5SSebastian Reichel 	 */
685*8c0984e5SSebastian Reichel 
686*8c0984e5SSebastian Reichel 	switch (link_status) {
687*8c0984e5SSebastian Reichel 	case USB_STAT_STD_HOST_NC:
688*8c0984e5SSebastian Reichel 	case USB_STAT_STD_HOST_C_NS:
689*8c0984e5SSebastian Reichel 	case USB_STAT_STD_HOST_C_S:
690*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "USB Type - Standard host is "
691*8c0984e5SSebastian Reichel 			"detected through USB driver\n");
692*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
693*8c0984e5SSebastian Reichel 		di->is_aca_rid = 0;
694*8c0984e5SSebastian Reichel 		break;
695*8c0984e5SSebastian Reichel 	case USB_STAT_HOST_CHG_HS_CHIRP:
696*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
697*8c0984e5SSebastian Reichel 		di->is_aca_rid = 0;
698*8c0984e5SSebastian Reichel 		break;
699*8c0984e5SSebastian Reichel 	case USB_STAT_HOST_CHG_HS:
700*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
701*8c0984e5SSebastian Reichel 		di->is_aca_rid = 0;
702*8c0984e5SSebastian Reichel 		break;
703*8c0984e5SSebastian Reichel 	case USB_STAT_ACA_RID_C_HS:
704*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P9;
705*8c0984e5SSebastian Reichel 		di->is_aca_rid = 0;
706*8c0984e5SSebastian Reichel 		break;
707*8c0984e5SSebastian Reichel 	case USB_STAT_ACA_RID_A:
708*8c0984e5SSebastian Reichel 		/*
709*8c0984e5SSebastian Reichel 		 * Dedicated charger level minus maximum current accessory
710*8c0984e5SSebastian Reichel 		 * can consume (900mA). Closest level is 500mA
711*8c0984e5SSebastian Reichel 		 */
712*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "USB_STAT_ACA_RID_A detected\n");
713*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
714*8c0984e5SSebastian Reichel 		di->is_aca_rid = 1;
715*8c0984e5SSebastian Reichel 		break;
716*8c0984e5SSebastian Reichel 	case USB_STAT_ACA_RID_B:
717*8c0984e5SSebastian Reichel 		/*
718*8c0984e5SSebastian Reichel 		 * Dedicated charger level minus 120mA (20mA for ACA and
719*8c0984e5SSebastian Reichel 		 * 100mA for potential accessory). Closest level is 1300mA
720*8c0984e5SSebastian Reichel 		 */
721*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P3;
722*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status,
723*8c0984e5SSebastian Reichel 				di->max_usb_in_curr.usb_type_max);
724*8c0984e5SSebastian Reichel 		di->is_aca_rid = 1;
725*8c0984e5SSebastian Reichel 		break;
726*8c0984e5SSebastian Reichel 	case USB_STAT_HOST_CHG_NM:
727*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
728*8c0984e5SSebastian Reichel 		di->is_aca_rid = 0;
729*8c0984e5SSebastian Reichel 		break;
730*8c0984e5SSebastian Reichel 	case USB_STAT_DEDICATED_CHG:
731*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5;
732*8c0984e5SSebastian Reichel 		di->is_aca_rid = 0;
733*8c0984e5SSebastian Reichel 		break;
734*8c0984e5SSebastian Reichel 	case USB_STAT_ACA_RID_C_HS_CHIRP:
735*8c0984e5SSebastian Reichel 	case USB_STAT_ACA_RID_C_NM:
736*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5;
737*8c0984e5SSebastian Reichel 		di->is_aca_rid = 1;
738*8c0984e5SSebastian Reichel 		break;
739*8c0984e5SSebastian Reichel 	case USB_STAT_NOT_CONFIGURED:
740*8c0984e5SSebastian Reichel 		if (di->vbus_detected) {
741*8c0984e5SSebastian Reichel 			di->usb_device_is_unrecognised = true;
742*8c0984e5SSebastian Reichel 			dev_dbg(di->dev, "USB Type - Legacy charger.\n");
743*8c0984e5SSebastian Reichel 			di->max_usb_in_curr.usb_type_max =
744*8c0984e5SSebastian Reichel 						USB_CH_IP_CUR_LVL_1P5;
745*8c0984e5SSebastian Reichel 			break;
746*8c0984e5SSebastian Reichel 		}
747*8c0984e5SSebastian Reichel 	case USB_STAT_HM_IDGND:
748*8c0984e5SSebastian Reichel 		dev_err(di->dev, "USB Type - Charging not allowed\n");
749*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05;
750*8c0984e5SSebastian Reichel 		ret = -ENXIO;
751*8c0984e5SSebastian Reichel 		break;
752*8c0984e5SSebastian Reichel 	case USB_STAT_RESERVED:
753*8c0984e5SSebastian Reichel 		if (is_ab8500(di->parent)) {
754*8c0984e5SSebastian Reichel 			di->flags.vbus_collapse = true;
755*8c0984e5SSebastian Reichel 			dev_err(di->dev, "USB Type - USB_STAT_RESERVED "
756*8c0984e5SSebastian Reichel 						"VBUS has collapsed\n");
757*8c0984e5SSebastian Reichel 			ret = -ENXIO;
758*8c0984e5SSebastian Reichel 			break;
759*8c0984e5SSebastian Reichel 		} else {
760*8c0984e5SSebastian Reichel 			dev_dbg(di->dev, "USB Type - Charging not allowed\n");
761*8c0984e5SSebastian Reichel 			di->max_usb_in_curr.usb_type_max =
762*8c0984e5SSebastian Reichel 						USB_CH_IP_CUR_LVL_0P05;
763*8c0984e5SSebastian Reichel 			dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d",
764*8c0984e5SSebastian Reichel 				link_status,
765*8c0984e5SSebastian Reichel 				di->max_usb_in_curr.usb_type_max);
766*8c0984e5SSebastian Reichel 			ret = -ENXIO;
767*8c0984e5SSebastian Reichel 			break;
768*8c0984e5SSebastian Reichel 		}
769*8c0984e5SSebastian Reichel 	case USB_STAT_CARKIT_1:
770*8c0984e5SSebastian Reichel 	case USB_STAT_CARKIT_2:
771*8c0984e5SSebastian Reichel 	case USB_STAT_ACA_DOCK_CHARGER:
772*8c0984e5SSebastian Reichel 	case USB_STAT_CHARGER_LINE_1:
773*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
774*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status,
775*8c0984e5SSebastian Reichel 				di->max_usb_in_curr.usb_type_max);
776*8c0984e5SSebastian Reichel 		break;
777*8c0984e5SSebastian Reichel 	case USB_STAT_NOT_VALID_LINK:
778*8c0984e5SSebastian Reichel 		dev_err(di->dev, "USB Type invalid - try charging anyway\n");
779*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
780*8c0984e5SSebastian Reichel 		break;
781*8c0984e5SSebastian Reichel 
782*8c0984e5SSebastian Reichel 	default:
783*8c0984e5SSebastian Reichel 		dev_err(di->dev, "USB Type - Unknown\n");
784*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05;
785*8c0984e5SSebastian Reichel 		ret = -ENXIO;
786*8c0984e5SSebastian Reichel 		break;
787*8c0984e5SSebastian Reichel 	};
788*8c0984e5SSebastian Reichel 
789*8c0984e5SSebastian Reichel 	di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max;
790*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d",
791*8c0984e5SSebastian Reichel 		link_status, di->max_usb_in_curr.set_max);
792*8c0984e5SSebastian Reichel 
793*8c0984e5SSebastian Reichel 	return ret;
794*8c0984e5SSebastian Reichel }
795*8c0984e5SSebastian Reichel 
796*8c0984e5SSebastian Reichel /**
797*8c0984e5SSebastian Reichel  * ab8500_charger_read_usb_type() - read the type of usb connected
798*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
799*8c0984e5SSebastian Reichel  *
800*8c0984e5SSebastian Reichel  * Detect the type of the plugged USB
801*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0 on success
802*8c0984e5SSebastian Reichel  */
803*8c0984e5SSebastian Reichel static int ab8500_charger_read_usb_type(struct ab8500_charger *di)
804*8c0984e5SSebastian Reichel {
805*8c0984e5SSebastian Reichel 	int ret;
806*8c0984e5SSebastian Reichel 	u8 val;
807*8c0984e5SSebastian Reichel 
808*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev,
809*8c0984e5SSebastian Reichel 		AB8500_INTERRUPT, AB8500_IT_SOURCE21_REG, &val);
810*8c0984e5SSebastian Reichel 	if (ret < 0) {
811*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s ab8500 read failed\n", __func__);
812*8c0984e5SSebastian Reichel 		return ret;
813*8c0984e5SSebastian Reichel 	}
814*8c0984e5SSebastian Reichel 	if (is_ab8500(di->parent))
815*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev, AB8500_USB,
816*8c0984e5SSebastian Reichel 			AB8500_USB_LINE_STAT_REG, &val);
817*8c0984e5SSebastian Reichel 	else
818*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev,
819*8c0984e5SSebastian Reichel 			AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val);
820*8c0984e5SSebastian Reichel 	if (ret < 0) {
821*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s ab8500 read failed\n", __func__);
822*8c0984e5SSebastian Reichel 		return ret;
823*8c0984e5SSebastian Reichel 	}
824*8c0984e5SSebastian Reichel 
825*8c0984e5SSebastian Reichel 	/* get the USB type */
826*8c0984e5SSebastian Reichel 	if (is_ab8500(di->parent))
827*8c0984e5SSebastian Reichel 		val = (val & AB8500_USB_LINK_STATUS) >> USB_LINK_STATUS_SHIFT;
828*8c0984e5SSebastian Reichel 	else
829*8c0984e5SSebastian Reichel 		val = (val & AB8505_USB_LINK_STATUS) >> USB_LINK_STATUS_SHIFT;
830*8c0984e5SSebastian Reichel 	ret = ab8500_charger_max_usb_curr(di,
831*8c0984e5SSebastian Reichel 		(enum ab8500_charger_link_status) val);
832*8c0984e5SSebastian Reichel 
833*8c0984e5SSebastian Reichel 	return ret;
834*8c0984e5SSebastian Reichel }
835*8c0984e5SSebastian Reichel 
836*8c0984e5SSebastian Reichel /**
837*8c0984e5SSebastian Reichel  * ab8500_charger_detect_usb_type() - get the type of usb connected
838*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
839*8c0984e5SSebastian Reichel  *
840*8c0984e5SSebastian Reichel  * Detect the type of the plugged USB
841*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0 on success
842*8c0984e5SSebastian Reichel  */
843*8c0984e5SSebastian Reichel static int ab8500_charger_detect_usb_type(struct ab8500_charger *di)
844*8c0984e5SSebastian Reichel {
845*8c0984e5SSebastian Reichel 	int i, ret;
846*8c0984e5SSebastian Reichel 	u8 val;
847*8c0984e5SSebastian Reichel 
848*8c0984e5SSebastian Reichel 	/*
849*8c0984e5SSebastian Reichel 	 * On getting the VBUS rising edge detect interrupt there
850*8c0984e5SSebastian Reichel 	 * is a 250ms delay after which the register UsbLineStatus
851*8c0984e5SSebastian Reichel 	 * is filled with valid data.
852*8c0984e5SSebastian Reichel 	 */
853*8c0984e5SSebastian Reichel 	for (i = 0; i < 10; i++) {
854*8c0984e5SSebastian Reichel 		msleep(250);
855*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev,
856*8c0984e5SSebastian Reichel 			AB8500_INTERRUPT, AB8500_IT_SOURCE21_REG,
857*8c0984e5SSebastian Reichel 			&val);
858*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "%s AB8500_IT_SOURCE21_REG %x\n",
859*8c0984e5SSebastian Reichel 			__func__, val);
860*8c0984e5SSebastian Reichel 		if (ret < 0) {
861*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s ab8500 read failed\n", __func__);
862*8c0984e5SSebastian Reichel 			return ret;
863*8c0984e5SSebastian Reichel 		}
864*8c0984e5SSebastian Reichel 
865*8c0984e5SSebastian Reichel 		if (is_ab8500(di->parent))
866*8c0984e5SSebastian Reichel 			ret = abx500_get_register_interruptible(di->dev,
867*8c0984e5SSebastian Reichel 				AB8500_USB, AB8500_USB_LINE_STAT_REG, &val);
868*8c0984e5SSebastian Reichel 		else
869*8c0984e5SSebastian Reichel 			ret = abx500_get_register_interruptible(di->dev,
870*8c0984e5SSebastian Reichel 				AB8500_USB, AB8500_USB_LINK1_STAT_REG, &val);
871*8c0984e5SSebastian Reichel 		if (ret < 0) {
872*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s ab8500 read failed\n", __func__);
873*8c0984e5SSebastian Reichel 			return ret;
874*8c0984e5SSebastian Reichel 		}
875*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "%s AB8500_USB_LINE_STAT_REG %x\n", __func__,
876*8c0984e5SSebastian Reichel 			val);
877*8c0984e5SSebastian Reichel 		/*
878*8c0984e5SSebastian Reichel 		 * Until the IT source register is read the UsbLineStatus
879*8c0984e5SSebastian Reichel 		 * register is not updated, hence doing the same
880*8c0984e5SSebastian Reichel 		 * Revisit this:
881*8c0984e5SSebastian Reichel 		 */
882*8c0984e5SSebastian Reichel 
883*8c0984e5SSebastian Reichel 		/* get the USB type */
884*8c0984e5SSebastian Reichel 		if (is_ab8500(di->parent))
885*8c0984e5SSebastian Reichel 			val = (val & AB8500_USB_LINK_STATUS) >>
886*8c0984e5SSebastian Reichel 							USB_LINK_STATUS_SHIFT;
887*8c0984e5SSebastian Reichel 		else
888*8c0984e5SSebastian Reichel 			val = (val & AB8505_USB_LINK_STATUS) >>
889*8c0984e5SSebastian Reichel 							USB_LINK_STATUS_SHIFT;
890*8c0984e5SSebastian Reichel 		if (val)
891*8c0984e5SSebastian Reichel 			break;
892*8c0984e5SSebastian Reichel 	}
893*8c0984e5SSebastian Reichel 	ret = ab8500_charger_max_usb_curr(di,
894*8c0984e5SSebastian Reichel 		(enum ab8500_charger_link_status) val);
895*8c0984e5SSebastian Reichel 
896*8c0984e5SSebastian Reichel 	return ret;
897*8c0984e5SSebastian Reichel }
898*8c0984e5SSebastian Reichel 
899*8c0984e5SSebastian Reichel /*
900*8c0984e5SSebastian Reichel  * This array maps the raw hex value to charger voltage used by the AB8500
901*8c0984e5SSebastian Reichel  * Values taken from the UM0836
902*8c0984e5SSebastian Reichel  */
903*8c0984e5SSebastian Reichel static int ab8500_charger_voltage_map[] = {
904*8c0984e5SSebastian Reichel 	3500 ,
905*8c0984e5SSebastian Reichel 	3525 ,
906*8c0984e5SSebastian Reichel 	3550 ,
907*8c0984e5SSebastian Reichel 	3575 ,
908*8c0984e5SSebastian Reichel 	3600 ,
909*8c0984e5SSebastian Reichel 	3625 ,
910*8c0984e5SSebastian Reichel 	3650 ,
911*8c0984e5SSebastian Reichel 	3675 ,
912*8c0984e5SSebastian Reichel 	3700 ,
913*8c0984e5SSebastian Reichel 	3725 ,
914*8c0984e5SSebastian Reichel 	3750 ,
915*8c0984e5SSebastian Reichel 	3775 ,
916*8c0984e5SSebastian Reichel 	3800 ,
917*8c0984e5SSebastian Reichel 	3825 ,
918*8c0984e5SSebastian Reichel 	3850 ,
919*8c0984e5SSebastian Reichel 	3875 ,
920*8c0984e5SSebastian Reichel 	3900 ,
921*8c0984e5SSebastian Reichel 	3925 ,
922*8c0984e5SSebastian Reichel 	3950 ,
923*8c0984e5SSebastian Reichel 	3975 ,
924*8c0984e5SSebastian Reichel 	4000 ,
925*8c0984e5SSebastian Reichel 	4025 ,
926*8c0984e5SSebastian Reichel 	4050 ,
927*8c0984e5SSebastian Reichel 	4060 ,
928*8c0984e5SSebastian Reichel 	4070 ,
929*8c0984e5SSebastian Reichel 	4080 ,
930*8c0984e5SSebastian Reichel 	4090 ,
931*8c0984e5SSebastian Reichel 	4100 ,
932*8c0984e5SSebastian Reichel 	4110 ,
933*8c0984e5SSebastian Reichel 	4120 ,
934*8c0984e5SSebastian Reichel 	4130 ,
935*8c0984e5SSebastian Reichel 	4140 ,
936*8c0984e5SSebastian Reichel 	4150 ,
937*8c0984e5SSebastian Reichel 	4160 ,
938*8c0984e5SSebastian Reichel 	4170 ,
939*8c0984e5SSebastian Reichel 	4180 ,
940*8c0984e5SSebastian Reichel 	4190 ,
941*8c0984e5SSebastian Reichel 	4200 ,
942*8c0984e5SSebastian Reichel 	4210 ,
943*8c0984e5SSebastian Reichel 	4220 ,
944*8c0984e5SSebastian Reichel 	4230 ,
945*8c0984e5SSebastian Reichel 	4240 ,
946*8c0984e5SSebastian Reichel 	4250 ,
947*8c0984e5SSebastian Reichel 	4260 ,
948*8c0984e5SSebastian Reichel 	4270 ,
949*8c0984e5SSebastian Reichel 	4280 ,
950*8c0984e5SSebastian Reichel 	4290 ,
951*8c0984e5SSebastian Reichel 	4300 ,
952*8c0984e5SSebastian Reichel 	4310 ,
953*8c0984e5SSebastian Reichel 	4320 ,
954*8c0984e5SSebastian Reichel 	4330 ,
955*8c0984e5SSebastian Reichel 	4340 ,
956*8c0984e5SSebastian Reichel 	4350 ,
957*8c0984e5SSebastian Reichel 	4360 ,
958*8c0984e5SSebastian Reichel 	4370 ,
959*8c0984e5SSebastian Reichel 	4380 ,
960*8c0984e5SSebastian Reichel 	4390 ,
961*8c0984e5SSebastian Reichel 	4400 ,
962*8c0984e5SSebastian Reichel 	4410 ,
963*8c0984e5SSebastian Reichel 	4420 ,
964*8c0984e5SSebastian Reichel 	4430 ,
965*8c0984e5SSebastian Reichel 	4440 ,
966*8c0984e5SSebastian Reichel 	4450 ,
967*8c0984e5SSebastian Reichel 	4460 ,
968*8c0984e5SSebastian Reichel 	4470 ,
969*8c0984e5SSebastian Reichel 	4480 ,
970*8c0984e5SSebastian Reichel 	4490 ,
971*8c0984e5SSebastian Reichel 	4500 ,
972*8c0984e5SSebastian Reichel 	4510 ,
973*8c0984e5SSebastian Reichel 	4520 ,
974*8c0984e5SSebastian Reichel 	4530 ,
975*8c0984e5SSebastian Reichel 	4540 ,
976*8c0984e5SSebastian Reichel 	4550 ,
977*8c0984e5SSebastian Reichel 	4560 ,
978*8c0984e5SSebastian Reichel 	4570 ,
979*8c0984e5SSebastian Reichel 	4580 ,
980*8c0984e5SSebastian Reichel 	4590 ,
981*8c0984e5SSebastian Reichel 	4600 ,
982*8c0984e5SSebastian Reichel };
983*8c0984e5SSebastian Reichel 
984*8c0984e5SSebastian Reichel static int ab8500_voltage_to_regval(int voltage)
985*8c0984e5SSebastian Reichel {
986*8c0984e5SSebastian Reichel 	int i;
987*8c0984e5SSebastian Reichel 
988*8c0984e5SSebastian Reichel 	/* Special case for voltage below 3.5V */
989*8c0984e5SSebastian Reichel 	if (voltage < ab8500_charger_voltage_map[0])
990*8c0984e5SSebastian Reichel 		return LOW_VOLT_REG;
991*8c0984e5SSebastian Reichel 
992*8c0984e5SSebastian Reichel 	for (i = 1; i < ARRAY_SIZE(ab8500_charger_voltage_map); i++) {
993*8c0984e5SSebastian Reichel 		if (voltage < ab8500_charger_voltage_map[i])
994*8c0984e5SSebastian Reichel 			return i - 1;
995*8c0984e5SSebastian Reichel 	}
996*8c0984e5SSebastian Reichel 
997*8c0984e5SSebastian Reichel 	/* If not last element, return error */
998*8c0984e5SSebastian Reichel 	i = ARRAY_SIZE(ab8500_charger_voltage_map) - 1;
999*8c0984e5SSebastian Reichel 	if (voltage == ab8500_charger_voltage_map[i])
1000*8c0984e5SSebastian Reichel 		return i;
1001*8c0984e5SSebastian Reichel 	else
1002*8c0984e5SSebastian Reichel 		return -1;
1003*8c0984e5SSebastian Reichel }
1004*8c0984e5SSebastian Reichel 
1005*8c0984e5SSebastian Reichel static int ab8500_current_to_regval(struct ab8500_charger *di, int curr)
1006*8c0984e5SSebastian Reichel {
1007*8c0984e5SSebastian Reichel 	int i;
1008*8c0984e5SSebastian Reichel 
1009*8c0984e5SSebastian Reichel 	if (curr < di->bm->chg_output_curr[0])
1010*8c0984e5SSebastian Reichel 		return 0;
1011*8c0984e5SSebastian Reichel 
1012*8c0984e5SSebastian Reichel 	for (i = 0; i < di->bm->n_chg_out_curr; i++) {
1013*8c0984e5SSebastian Reichel 		if (curr < di->bm->chg_output_curr[i])
1014*8c0984e5SSebastian Reichel 			return i - 1;
1015*8c0984e5SSebastian Reichel 	}
1016*8c0984e5SSebastian Reichel 
1017*8c0984e5SSebastian Reichel 	/* If not last element, return error */
1018*8c0984e5SSebastian Reichel 	i = di->bm->n_chg_out_curr - 1;
1019*8c0984e5SSebastian Reichel 	if (curr == di->bm->chg_output_curr[i])
1020*8c0984e5SSebastian Reichel 		return i;
1021*8c0984e5SSebastian Reichel 	else
1022*8c0984e5SSebastian Reichel 		return -1;
1023*8c0984e5SSebastian Reichel }
1024*8c0984e5SSebastian Reichel 
1025*8c0984e5SSebastian Reichel static int ab8500_vbus_in_curr_to_regval(struct ab8500_charger *di, int curr)
1026*8c0984e5SSebastian Reichel {
1027*8c0984e5SSebastian Reichel 	int i;
1028*8c0984e5SSebastian Reichel 
1029*8c0984e5SSebastian Reichel 	if (curr < di->bm->chg_input_curr[0])
1030*8c0984e5SSebastian Reichel 		return 0;
1031*8c0984e5SSebastian Reichel 
1032*8c0984e5SSebastian Reichel 	for (i = 0; i < di->bm->n_chg_in_curr; i++) {
1033*8c0984e5SSebastian Reichel 		if (curr < di->bm->chg_input_curr[i])
1034*8c0984e5SSebastian Reichel 			return i - 1;
1035*8c0984e5SSebastian Reichel 	}
1036*8c0984e5SSebastian Reichel 
1037*8c0984e5SSebastian Reichel 	/* If not last element, return error */
1038*8c0984e5SSebastian Reichel 	i = di->bm->n_chg_in_curr - 1;
1039*8c0984e5SSebastian Reichel 	if (curr == di->bm->chg_input_curr[i])
1040*8c0984e5SSebastian Reichel 		return i;
1041*8c0984e5SSebastian Reichel 	else
1042*8c0984e5SSebastian Reichel 		return -1;
1043*8c0984e5SSebastian Reichel }
1044*8c0984e5SSebastian Reichel 
1045*8c0984e5SSebastian Reichel /**
1046*8c0984e5SSebastian Reichel  * ab8500_charger_get_usb_cur() - get usb current
1047*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structre
1048*8c0984e5SSebastian Reichel  *
1049*8c0984e5SSebastian Reichel  * The usb stack provides the maximum current that can be drawn from
1050*8c0984e5SSebastian Reichel  * the standard usb host. This will be in mA.
1051*8c0984e5SSebastian Reichel  * This function converts current in mA to a value that can be written
1052*8c0984e5SSebastian Reichel  * to the register. Returns -1 if charging is not allowed
1053*8c0984e5SSebastian Reichel  */
1054*8c0984e5SSebastian Reichel static int ab8500_charger_get_usb_cur(struct ab8500_charger *di)
1055*8c0984e5SSebastian Reichel {
1056*8c0984e5SSebastian Reichel 	int ret = 0;
1057*8c0984e5SSebastian Reichel 	switch (di->usb_state.usb_current) {
1058*8c0984e5SSebastian Reichel 	case 100:
1059*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P09;
1060*8c0984e5SSebastian Reichel 		break;
1061*8c0984e5SSebastian Reichel 	case 200:
1062*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P19;
1063*8c0984e5SSebastian Reichel 		break;
1064*8c0984e5SSebastian Reichel 	case 300:
1065*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P29;
1066*8c0984e5SSebastian Reichel 		break;
1067*8c0984e5SSebastian Reichel 	case 400:
1068*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P38;
1069*8c0984e5SSebastian Reichel 		break;
1070*8c0984e5SSebastian Reichel 	case 500:
1071*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
1072*8c0984e5SSebastian Reichel 		break;
1073*8c0984e5SSebastian Reichel 	default:
1074*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05;
1075*8c0984e5SSebastian Reichel 		ret = -EPERM;
1076*8c0984e5SSebastian Reichel 		break;
1077*8c0984e5SSebastian Reichel 	};
1078*8c0984e5SSebastian Reichel 	di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max;
1079*8c0984e5SSebastian Reichel 	return ret;
1080*8c0984e5SSebastian Reichel }
1081*8c0984e5SSebastian Reichel 
1082*8c0984e5SSebastian Reichel /**
1083*8c0984e5SSebastian Reichel  * ab8500_charger_check_continue_stepping() - Check to allow stepping
1084*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1085*8c0984e5SSebastian Reichel  * @reg:	select what charger register to check
1086*8c0984e5SSebastian Reichel  *
1087*8c0984e5SSebastian Reichel  * Check if current stepping should be allowed to continue.
1088*8c0984e5SSebastian Reichel  * Checks if charger source has not collapsed. If it has, further stepping
1089*8c0984e5SSebastian Reichel  * is not allowed.
1090*8c0984e5SSebastian Reichel  */
1091*8c0984e5SSebastian Reichel static bool ab8500_charger_check_continue_stepping(struct ab8500_charger *di,
1092*8c0984e5SSebastian Reichel 						   int reg)
1093*8c0984e5SSebastian Reichel {
1094*8c0984e5SSebastian Reichel 	if (reg == AB8500_USBCH_IPT_CRNTLVL_REG)
1095*8c0984e5SSebastian Reichel 		return !di->flags.vbus_drop_end;
1096*8c0984e5SSebastian Reichel 	else
1097*8c0984e5SSebastian Reichel 		return true;
1098*8c0984e5SSebastian Reichel }
1099*8c0984e5SSebastian Reichel 
1100*8c0984e5SSebastian Reichel /**
1101*8c0984e5SSebastian Reichel  * ab8500_charger_set_current() - set charger current
1102*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1103*8c0984e5SSebastian Reichel  * @ich:	charger current, in mA
1104*8c0984e5SSebastian Reichel  * @reg:	select what charger register to set
1105*8c0984e5SSebastian Reichel  *
1106*8c0984e5SSebastian Reichel  * Set charger current.
1107*8c0984e5SSebastian Reichel  * There is no state machine in the AB to step up/down the charger
1108*8c0984e5SSebastian Reichel  * current to avoid dips and spikes on MAIN, VBUS and VBAT when
1109*8c0984e5SSebastian Reichel  * charging is started. Instead we need to implement
1110*8c0984e5SSebastian Reichel  * this charger current step-up/down here.
1111*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1112*8c0984e5SSebastian Reichel  */
1113*8c0984e5SSebastian Reichel static int ab8500_charger_set_current(struct ab8500_charger *di,
1114*8c0984e5SSebastian Reichel 	int ich, int reg)
1115*8c0984e5SSebastian Reichel {
1116*8c0984e5SSebastian Reichel 	int ret = 0;
1117*8c0984e5SSebastian Reichel 	int curr_index, prev_curr_index, shift_value, i;
1118*8c0984e5SSebastian Reichel 	u8 reg_value;
1119*8c0984e5SSebastian Reichel 	u32 step_udelay;
1120*8c0984e5SSebastian Reichel 	bool no_stepping = false;
1121*8c0984e5SSebastian Reichel 
1122*8c0984e5SSebastian Reichel 	atomic_inc(&di->current_stepping_sessions);
1123*8c0984e5SSebastian Reichel 
1124*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
1125*8c0984e5SSebastian Reichel 		reg, &reg_value);
1126*8c0984e5SSebastian Reichel 	if (ret < 0) {
1127*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s read failed\n", __func__);
1128*8c0984e5SSebastian Reichel 		goto exit_set_current;
1129*8c0984e5SSebastian Reichel 	}
1130*8c0984e5SSebastian Reichel 
1131*8c0984e5SSebastian Reichel 	switch (reg) {
1132*8c0984e5SSebastian Reichel 	case AB8500_MCH_IPT_CURLVL_REG:
1133*8c0984e5SSebastian Reichel 		shift_value = MAIN_CH_INPUT_CURR_SHIFT;
1134*8c0984e5SSebastian Reichel 		prev_curr_index = (reg_value >> shift_value);
1135*8c0984e5SSebastian Reichel 		curr_index = ab8500_current_to_regval(di, ich);
1136*8c0984e5SSebastian Reichel 		step_udelay = STEP_UDELAY;
1137*8c0984e5SSebastian Reichel 		if (!di->ac.charger_connected)
1138*8c0984e5SSebastian Reichel 			no_stepping = true;
1139*8c0984e5SSebastian Reichel 		break;
1140*8c0984e5SSebastian Reichel 	case AB8500_USBCH_IPT_CRNTLVL_REG:
1141*8c0984e5SSebastian Reichel 		if (is_ab8540(di->parent))
1142*8c0984e5SSebastian Reichel 			shift_value = AB8540_VBUS_IN_CURR_LIM_SHIFT;
1143*8c0984e5SSebastian Reichel 		else
1144*8c0984e5SSebastian Reichel 			shift_value = VBUS_IN_CURR_LIM_SHIFT;
1145*8c0984e5SSebastian Reichel 		prev_curr_index = (reg_value >> shift_value);
1146*8c0984e5SSebastian Reichel 		curr_index = ab8500_vbus_in_curr_to_regval(di, ich);
1147*8c0984e5SSebastian Reichel 		step_udelay = STEP_UDELAY * 100;
1148*8c0984e5SSebastian Reichel 
1149*8c0984e5SSebastian Reichel 		if (!di->usb.charger_connected)
1150*8c0984e5SSebastian Reichel 			no_stepping = true;
1151*8c0984e5SSebastian Reichel 		break;
1152*8c0984e5SSebastian Reichel 	case AB8500_CH_OPT_CRNTLVL_REG:
1153*8c0984e5SSebastian Reichel 		shift_value = 0;
1154*8c0984e5SSebastian Reichel 		prev_curr_index = (reg_value >> shift_value);
1155*8c0984e5SSebastian Reichel 		curr_index = ab8500_current_to_regval(di, ich);
1156*8c0984e5SSebastian Reichel 		step_udelay = STEP_UDELAY;
1157*8c0984e5SSebastian Reichel 		if (curr_index && (curr_index - prev_curr_index) > 1)
1158*8c0984e5SSebastian Reichel 			step_udelay *= 100;
1159*8c0984e5SSebastian Reichel 
1160*8c0984e5SSebastian Reichel 		if (!di->usb.charger_connected && !di->ac.charger_connected)
1161*8c0984e5SSebastian Reichel 			no_stepping = true;
1162*8c0984e5SSebastian Reichel 
1163*8c0984e5SSebastian Reichel 		break;
1164*8c0984e5SSebastian Reichel 	default:
1165*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s current register not valid\n", __func__);
1166*8c0984e5SSebastian Reichel 		ret = -ENXIO;
1167*8c0984e5SSebastian Reichel 		goto exit_set_current;
1168*8c0984e5SSebastian Reichel 	}
1169*8c0984e5SSebastian Reichel 
1170*8c0984e5SSebastian Reichel 	if (curr_index < 0) {
1171*8c0984e5SSebastian Reichel 		dev_err(di->dev, "requested current limit out-of-range\n");
1172*8c0984e5SSebastian Reichel 		ret = -ENXIO;
1173*8c0984e5SSebastian Reichel 		goto exit_set_current;
1174*8c0984e5SSebastian Reichel 	}
1175*8c0984e5SSebastian Reichel 
1176*8c0984e5SSebastian Reichel 	/* only update current if it's been changed */
1177*8c0984e5SSebastian Reichel 	if (prev_curr_index == curr_index) {
1178*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "%s current not changed for reg: 0x%02x\n",
1179*8c0984e5SSebastian Reichel 			__func__, reg);
1180*8c0984e5SSebastian Reichel 		ret = 0;
1181*8c0984e5SSebastian Reichel 		goto exit_set_current;
1182*8c0984e5SSebastian Reichel 	}
1183*8c0984e5SSebastian Reichel 
1184*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "%s set charger current: %d mA for reg: 0x%02x\n",
1185*8c0984e5SSebastian Reichel 		__func__, ich, reg);
1186*8c0984e5SSebastian Reichel 
1187*8c0984e5SSebastian Reichel 	if (no_stepping) {
1188*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1189*8c0984e5SSebastian Reichel 					reg, (u8)curr_index << shift_value);
1190*8c0984e5SSebastian Reichel 		if (ret)
1191*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s write failed\n", __func__);
1192*8c0984e5SSebastian Reichel 	} else if (prev_curr_index > curr_index) {
1193*8c0984e5SSebastian Reichel 		for (i = prev_curr_index - 1; i >= curr_index; i--) {
1194*8c0984e5SSebastian Reichel 			dev_dbg(di->dev, "curr change_1 to: %x for 0x%02x\n",
1195*8c0984e5SSebastian Reichel 				(u8) i << shift_value, reg);
1196*8c0984e5SSebastian Reichel 			ret = abx500_set_register_interruptible(di->dev,
1197*8c0984e5SSebastian Reichel 				AB8500_CHARGER, reg, (u8)i << shift_value);
1198*8c0984e5SSebastian Reichel 			if (ret) {
1199*8c0984e5SSebastian Reichel 				dev_err(di->dev, "%s write failed\n", __func__);
1200*8c0984e5SSebastian Reichel 				goto exit_set_current;
1201*8c0984e5SSebastian Reichel 			}
1202*8c0984e5SSebastian Reichel 			if (i != curr_index)
1203*8c0984e5SSebastian Reichel 				usleep_range(step_udelay, step_udelay * 2);
1204*8c0984e5SSebastian Reichel 		}
1205*8c0984e5SSebastian Reichel 	} else {
1206*8c0984e5SSebastian Reichel 		bool allow = true;
1207*8c0984e5SSebastian Reichel 		for (i = prev_curr_index + 1; i <= curr_index && allow; i++) {
1208*8c0984e5SSebastian Reichel 			dev_dbg(di->dev, "curr change_2 to: %x for 0x%02x\n",
1209*8c0984e5SSebastian Reichel 				(u8)i << shift_value, reg);
1210*8c0984e5SSebastian Reichel 			ret = abx500_set_register_interruptible(di->dev,
1211*8c0984e5SSebastian Reichel 				AB8500_CHARGER, reg, (u8)i << shift_value);
1212*8c0984e5SSebastian Reichel 			if (ret) {
1213*8c0984e5SSebastian Reichel 				dev_err(di->dev, "%s write failed\n", __func__);
1214*8c0984e5SSebastian Reichel 				goto exit_set_current;
1215*8c0984e5SSebastian Reichel 			}
1216*8c0984e5SSebastian Reichel 			if (i != curr_index)
1217*8c0984e5SSebastian Reichel 				usleep_range(step_udelay, step_udelay * 2);
1218*8c0984e5SSebastian Reichel 
1219*8c0984e5SSebastian Reichel 			allow = ab8500_charger_check_continue_stepping(di, reg);
1220*8c0984e5SSebastian Reichel 		}
1221*8c0984e5SSebastian Reichel 	}
1222*8c0984e5SSebastian Reichel 
1223*8c0984e5SSebastian Reichel exit_set_current:
1224*8c0984e5SSebastian Reichel 	atomic_dec(&di->current_stepping_sessions);
1225*8c0984e5SSebastian Reichel 
1226*8c0984e5SSebastian Reichel 	return ret;
1227*8c0984e5SSebastian Reichel }
1228*8c0984e5SSebastian Reichel 
1229*8c0984e5SSebastian Reichel /**
1230*8c0984e5SSebastian Reichel  * ab8500_charger_set_vbus_in_curr() - set VBUS input current limit
1231*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1232*8c0984e5SSebastian Reichel  * @ich_in:	charger input current limit
1233*8c0984e5SSebastian Reichel  *
1234*8c0984e5SSebastian Reichel  * Sets the current that can be drawn from the USB host
1235*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1236*8c0984e5SSebastian Reichel  */
1237*8c0984e5SSebastian Reichel static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di,
1238*8c0984e5SSebastian Reichel 		int ich_in)
1239*8c0984e5SSebastian Reichel {
1240*8c0984e5SSebastian Reichel 	int min_value;
1241*8c0984e5SSebastian Reichel 	int ret;
1242*8c0984e5SSebastian Reichel 
1243*8c0984e5SSebastian Reichel 	/* We should always use to lowest current limit */
1244*8c0984e5SSebastian Reichel 	min_value = min(di->bm->chg_params->usb_curr_max, ich_in);
1245*8c0984e5SSebastian Reichel 	if (di->max_usb_in_curr.set_max > 0)
1246*8c0984e5SSebastian Reichel 		min_value = min(di->max_usb_in_curr.set_max, min_value);
1247*8c0984e5SSebastian Reichel 
1248*8c0984e5SSebastian Reichel 	if (di->usb_state.usb_current >= 0)
1249*8c0984e5SSebastian Reichel 		min_value = min(di->usb_state.usb_current, min_value);
1250*8c0984e5SSebastian Reichel 
1251*8c0984e5SSebastian Reichel 	switch (min_value) {
1252*8c0984e5SSebastian Reichel 	case 100:
1253*8c0984e5SSebastian Reichel 		if (di->vbat < VBAT_TRESH_IP_CUR_RED)
1254*8c0984e5SSebastian Reichel 			min_value = USB_CH_IP_CUR_LVL_0P05;
1255*8c0984e5SSebastian Reichel 		break;
1256*8c0984e5SSebastian Reichel 	case 500:
1257*8c0984e5SSebastian Reichel 		if (di->vbat < VBAT_TRESH_IP_CUR_RED)
1258*8c0984e5SSebastian Reichel 			min_value = USB_CH_IP_CUR_LVL_0P45;
1259*8c0984e5SSebastian Reichel 		break;
1260*8c0984e5SSebastian Reichel 	default:
1261*8c0984e5SSebastian Reichel 		break;
1262*8c0984e5SSebastian Reichel 	}
1263*8c0984e5SSebastian Reichel 
1264*8c0984e5SSebastian Reichel 	dev_info(di->dev, "VBUS input current limit set to %d mA\n", min_value);
1265*8c0984e5SSebastian Reichel 
1266*8c0984e5SSebastian Reichel 	mutex_lock(&di->usb_ipt_crnt_lock);
1267*8c0984e5SSebastian Reichel 	ret = ab8500_charger_set_current(di, min_value,
1268*8c0984e5SSebastian Reichel 		AB8500_USBCH_IPT_CRNTLVL_REG);
1269*8c0984e5SSebastian Reichel 	mutex_unlock(&di->usb_ipt_crnt_lock);
1270*8c0984e5SSebastian Reichel 
1271*8c0984e5SSebastian Reichel 	return ret;
1272*8c0984e5SSebastian Reichel }
1273*8c0984e5SSebastian Reichel 
1274*8c0984e5SSebastian Reichel /**
1275*8c0984e5SSebastian Reichel  * ab8500_charger_set_main_in_curr() - set main charger input current
1276*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1277*8c0984e5SSebastian Reichel  * @ich_in:	input charger current, in mA
1278*8c0984e5SSebastian Reichel  *
1279*8c0984e5SSebastian Reichel  * Set main charger input current.
1280*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1281*8c0984e5SSebastian Reichel  */
1282*8c0984e5SSebastian Reichel static int ab8500_charger_set_main_in_curr(struct ab8500_charger *di,
1283*8c0984e5SSebastian Reichel 	int ich_in)
1284*8c0984e5SSebastian Reichel {
1285*8c0984e5SSebastian Reichel 	return ab8500_charger_set_current(di, ich_in,
1286*8c0984e5SSebastian Reichel 		AB8500_MCH_IPT_CURLVL_REG);
1287*8c0984e5SSebastian Reichel }
1288*8c0984e5SSebastian Reichel 
1289*8c0984e5SSebastian Reichel /**
1290*8c0984e5SSebastian Reichel  * ab8500_charger_set_output_curr() - set charger output current
1291*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1292*8c0984e5SSebastian Reichel  * @ich_out:	output charger current, in mA
1293*8c0984e5SSebastian Reichel  *
1294*8c0984e5SSebastian Reichel  * Set charger output current.
1295*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1296*8c0984e5SSebastian Reichel  */
1297*8c0984e5SSebastian Reichel static int ab8500_charger_set_output_curr(struct ab8500_charger *di,
1298*8c0984e5SSebastian Reichel 	int ich_out)
1299*8c0984e5SSebastian Reichel {
1300*8c0984e5SSebastian Reichel 	return ab8500_charger_set_current(di, ich_out,
1301*8c0984e5SSebastian Reichel 		AB8500_CH_OPT_CRNTLVL_REG);
1302*8c0984e5SSebastian Reichel }
1303*8c0984e5SSebastian Reichel 
1304*8c0984e5SSebastian Reichel /**
1305*8c0984e5SSebastian Reichel  * ab8500_charger_led_en() - turn on/off chargign led
1306*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1307*8c0984e5SSebastian Reichel  * @on:		flag to turn on/off the chargign led
1308*8c0984e5SSebastian Reichel  *
1309*8c0984e5SSebastian Reichel  * Power ON/OFF charging LED indication
1310*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1311*8c0984e5SSebastian Reichel  */
1312*8c0984e5SSebastian Reichel static int ab8500_charger_led_en(struct ab8500_charger *di, int on)
1313*8c0984e5SSebastian Reichel {
1314*8c0984e5SSebastian Reichel 	int ret;
1315*8c0984e5SSebastian Reichel 
1316*8c0984e5SSebastian Reichel 	if (on) {
1317*8c0984e5SSebastian Reichel 		/* Power ON charging LED indicator, set LED current to 5mA */
1318*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1319*8c0984e5SSebastian Reichel 			AB8500_LED_INDICATOR_PWM_CTRL,
1320*8c0984e5SSebastian Reichel 			(LED_IND_CUR_5MA | LED_INDICATOR_PWM_ENA));
1321*8c0984e5SSebastian Reichel 		if (ret) {
1322*8c0984e5SSebastian Reichel 			dev_err(di->dev, "Power ON LED failed\n");
1323*8c0984e5SSebastian Reichel 			return ret;
1324*8c0984e5SSebastian Reichel 		}
1325*8c0984e5SSebastian Reichel 		/* LED indicator PWM duty cycle 252/256 */
1326*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1327*8c0984e5SSebastian Reichel 			AB8500_LED_INDICATOR_PWM_DUTY,
1328*8c0984e5SSebastian Reichel 			LED_INDICATOR_PWM_DUTY_252_256);
1329*8c0984e5SSebastian Reichel 		if (ret) {
1330*8c0984e5SSebastian Reichel 			dev_err(di->dev, "Set LED PWM duty cycle failed\n");
1331*8c0984e5SSebastian Reichel 			return ret;
1332*8c0984e5SSebastian Reichel 		}
1333*8c0984e5SSebastian Reichel 	} else {
1334*8c0984e5SSebastian Reichel 		/* Power off charging LED indicator */
1335*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1336*8c0984e5SSebastian Reichel 			AB8500_LED_INDICATOR_PWM_CTRL,
1337*8c0984e5SSebastian Reichel 			LED_INDICATOR_PWM_DIS);
1338*8c0984e5SSebastian Reichel 		if (ret) {
1339*8c0984e5SSebastian Reichel 			dev_err(di->dev, "Power-off LED failed\n");
1340*8c0984e5SSebastian Reichel 			return ret;
1341*8c0984e5SSebastian Reichel 		}
1342*8c0984e5SSebastian Reichel 	}
1343*8c0984e5SSebastian Reichel 
1344*8c0984e5SSebastian Reichel 	return ret;
1345*8c0984e5SSebastian Reichel }
1346*8c0984e5SSebastian Reichel 
1347*8c0984e5SSebastian Reichel /**
1348*8c0984e5SSebastian Reichel  * ab8500_charger_ac_en() - enable or disable ac charging
1349*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1350*8c0984e5SSebastian Reichel  * @enable:	enable/disable flag
1351*8c0984e5SSebastian Reichel  * @vset:	charging voltage
1352*8c0984e5SSebastian Reichel  * @iset:	charging current
1353*8c0984e5SSebastian Reichel  *
1354*8c0984e5SSebastian Reichel  * Enable/Disable AC/Mains charging and turns on/off the charging led
1355*8c0984e5SSebastian Reichel  * respectively.
1356*8c0984e5SSebastian Reichel  **/
1357*8c0984e5SSebastian Reichel static int ab8500_charger_ac_en(struct ux500_charger *charger,
1358*8c0984e5SSebastian Reichel 	int enable, int vset, int iset)
1359*8c0984e5SSebastian Reichel {
1360*8c0984e5SSebastian Reichel 	int ret;
1361*8c0984e5SSebastian Reichel 	int volt_index;
1362*8c0984e5SSebastian Reichel 	int curr_index;
1363*8c0984e5SSebastian Reichel 	int input_curr_index;
1364*8c0984e5SSebastian Reichel 	u8 overshoot = 0;
1365*8c0984e5SSebastian Reichel 
1366*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = to_ab8500_charger_ac_device_info(charger);
1367*8c0984e5SSebastian Reichel 
1368*8c0984e5SSebastian Reichel 	if (enable) {
1369*8c0984e5SSebastian Reichel 		/* Check if AC is connected */
1370*8c0984e5SSebastian Reichel 		if (!di->ac.charger_connected) {
1371*8c0984e5SSebastian Reichel 			dev_err(di->dev, "AC charger not connected\n");
1372*8c0984e5SSebastian Reichel 			return -ENXIO;
1373*8c0984e5SSebastian Reichel 		}
1374*8c0984e5SSebastian Reichel 
1375*8c0984e5SSebastian Reichel 		/* Enable AC charging */
1376*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "Enable AC: %dmV %dmA\n", vset, iset);
1377*8c0984e5SSebastian Reichel 
1378*8c0984e5SSebastian Reichel 		/*
1379*8c0984e5SSebastian Reichel 		 * Due to a bug in AB8500, BTEMP_HIGH/LOW interrupts
1380*8c0984e5SSebastian Reichel 		 * will be triggered everytime we enable the VDD ADC supply.
1381*8c0984e5SSebastian Reichel 		 * This will turn off charging for a short while.
1382*8c0984e5SSebastian Reichel 		 * It can be avoided by having the supply on when
1383*8c0984e5SSebastian Reichel 		 * there is a charger enabled. Normally the VDD ADC supply
1384*8c0984e5SSebastian Reichel 		 * is enabled everytime a GPADC conversion is triggered. We will
1385*8c0984e5SSebastian Reichel 		 * force it to be enabled from this driver to have
1386*8c0984e5SSebastian Reichel 		 * the GPADC module independant of the AB8500 chargers
1387*8c0984e5SSebastian Reichel 		 */
1388*8c0984e5SSebastian Reichel 		if (!di->vddadc_en_ac) {
1389*8c0984e5SSebastian Reichel 			ret = regulator_enable(di->regu);
1390*8c0984e5SSebastian Reichel 			if (ret)
1391*8c0984e5SSebastian Reichel 				dev_warn(di->dev,
1392*8c0984e5SSebastian Reichel 					"Failed to enable regulator\n");
1393*8c0984e5SSebastian Reichel 			else
1394*8c0984e5SSebastian Reichel 				di->vddadc_en_ac = true;
1395*8c0984e5SSebastian Reichel 		}
1396*8c0984e5SSebastian Reichel 
1397*8c0984e5SSebastian Reichel 		/* Check if the requested voltage or current is valid */
1398*8c0984e5SSebastian Reichel 		volt_index = ab8500_voltage_to_regval(vset);
1399*8c0984e5SSebastian Reichel 		curr_index = ab8500_current_to_regval(di, iset);
1400*8c0984e5SSebastian Reichel 		input_curr_index = ab8500_current_to_regval(di,
1401*8c0984e5SSebastian Reichel 			di->bm->chg_params->ac_curr_max);
1402*8c0984e5SSebastian Reichel 		if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) {
1403*8c0984e5SSebastian Reichel 			dev_err(di->dev,
1404*8c0984e5SSebastian Reichel 				"Charger voltage or current too high, "
1405*8c0984e5SSebastian Reichel 				"charging not started\n");
1406*8c0984e5SSebastian Reichel 			return -ENXIO;
1407*8c0984e5SSebastian Reichel 		}
1408*8c0984e5SSebastian Reichel 
1409*8c0984e5SSebastian Reichel 		/* ChVoltLevel: maximum battery charging voltage */
1410*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1411*8c0984e5SSebastian Reichel 			AB8500_CH_VOLT_LVL_REG, (u8) volt_index);
1412*8c0984e5SSebastian Reichel 		if (ret) {
1413*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s write failed\n", __func__);
1414*8c0984e5SSebastian Reichel 			return ret;
1415*8c0984e5SSebastian Reichel 		}
1416*8c0984e5SSebastian Reichel 		/* MainChInputCurr: current that can be drawn from the charger*/
1417*8c0984e5SSebastian Reichel 		ret = ab8500_charger_set_main_in_curr(di,
1418*8c0984e5SSebastian Reichel 			di->bm->chg_params->ac_curr_max);
1419*8c0984e5SSebastian Reichel 		if (ret) {
1420*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s Failed to set MainChInputCurr\n",
1421*8c0984e5SSebastian Reichel 				__func__);
1422*8c0984e5SSebastian Reichel 			return ret;
1423*8c0984e5SSebastian Reichel 		}
1424*8c0984e5SSebastian Reichel 		/* ChOutputCurentLevel: protected output current */
1425*8c0984e5SSebastian Reichel 		ret = ab8500_charger_set_output_curr(di, iset);
1426*8c0984e5SSebastian Reichel 		if (ret) {
1427*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s "
1428*8c0984e5SSebastian Reichel 				"Failed to set ChOutputCurentLevel\n",
1429*8c0984e5SSebastian Reichel 				__func__);
1430*8c0984e5SSebastian Reichel 			return ret;
1431*8c0984e5SSebastian Reichel 		}
1432*8c0984e5SSebastian Reichel 
1433*8c0984e5SSebastian Reichel 		/* Check if VBAT overshoot control should be enabled */
1434*8c0984e5SSebastian Reichel 		if (!di->bm->enable_overshoot)
1435*8c0984e5SSebastian Reichel 			overshoot = MAIN_CH_NO_OVERSHOOT_ENA_N;
1436*8c0984e5SSebastian Reichel 
1437*8c0984e5SSebastian Reichel 		/* Enable Main Charger */
1438*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1439*8c0984e5SSebastian Reichel 			AB8500_MCH_CTRL1, MAIN_CH_ENA | overshoot);
1440*8c0984e5SSebastian Reichel 		if (ret) {
1441*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s write failed\n", __func__);
1442*8c0984e5SSebastian Reichel 			return ret;
1443*8c0984e5SSebastian Reichel 		}
1444*8c0984e5SSebastian Reichel 
1445*8c0984e5SSebastian Reichel 		/* Power on charging LED indication */
1446*8c0984e5SSebastian Reichel 		ret = ab8500_charger_led_en(di, true);
1447*8c0984e5SSebastian Reichel 		if (ret < 0)
1448*8c0984e5SSebastian Reichel 			dev_err(di->dev, "failed to enable LED\n");
1449*8c0984e5SSebastian Reichel 
1450*8c0984e5SSebastian Reichel 		di->ac.charger_online = 1;
1451*8c0984e5SSebastian Reichel 	} else {
1452*8c0984e5SSebastian Reichel 		/* Disable AC charging */
1453*8c0984e5SSebastian Reichel 		if (is_ab8500_1p1_or_earlier(di->parent)) {
1454*8c0984e5SSebastian Reichel 			/*
1455*8c0984e5SSebastian Reichel 			 * For ABB revision 1.0 and 1.1 there is a bug in the
1456*8c0984e5SSebastian Reichel 			 * watchdog logic. That means we have to continously
1457*8c0984e5SSebastian Reichel 			 * kick the charger watchdog even when no charger is
1458*8c0984e5SSebastian Reichel 			 * connected. This is only valid once the AC charger
1459*8c0984e5SSebastian Reichel 			 * has been enabled. This is a bug that is not handled
1460*8c0984e5SSebastian Reichel 			 * by the algorithm and the watchdog have to be kicked
1461*8c0984e5SSebastian Reichel 			 * by the charger driver when the AC charger
1462*8c0984e5SSebastian Reichel 			 * is disabled
1463*8c0984e5SSebastian Reichel 			 */
1464*8c0984e5SSebastian Reichel 			if (di->ac_conn) {
1465*8c0984e5SSebastian Reichel 				queue_delayed_work(di->charger_wq,
1466*8c0984e5SSebastian Reichel 					&di->kick_wd_work,
1467*8c0984e5SSebastian Reichel 					round_jiffies(WD_KICK_INTERVAL));
1468*8c0984e5SSebastian Reichel 			}
1469*8c0984e5SSebastian Reichel 
1470*8c0984e5SSebastian Reichel 			/*
1471*8c0984e5SSebastian Reichel 			 * We can't turn off charging completely
1472*8c0984e5SSebastian Reichel 			 * due to a bug in AB8500 cut1.
1473*8c0984e5SSebastian Reichel 			 * If we do, charging will not start again.
1474*8c0984e5SSebastian Reichel 			 * That is why we set the lowest voltage
1475*8c0984e5SSebastian Reichel 			 * and current possible
1476*8c0984e5SSebastian Reichel 			 */
1477*8c0984e5SSebastian Reichel 			ret = abx500_set_register_interruptible(di->dev,
1478*8c0984e5SSebastian Reichel 				AB8500_CHARGER,
1479*8c0984e5SSebastian Reichel 				AB8500_CH_VOLT_LVL_REG, CH_VOL_LVL_3P5);
1480*8c0984e5SSebastian Reichel 			if (ret) {
1481*8c0984e5SSebastian Reichel 				dev_err(di->dev,
1482*8c0984e5SSebastian Reichel 					"%s write failed\n", __func__);
1483*8c0984e5SSebastian Reichel 				return ret;
1484*8c0984e5SSebastian Reichel 			}
1485*8c0984e5SSebastian Reichel 
1486*8c0984e5SSebastian Reichel 			ret = ab8500_charger_set_output_curr(di, 0);
1487*8c0984e5SSebastian Reichel 			if (ret) {
1488*8c0984e5SSebastian Reichel 				dev_err(di->dev, "%s "
1489*8c0984e5SSebastian Reichel 					"Failed to set ChOutputCurentLevel\n",
1490*8c0984e5SSebastian Reichel 					__func__);
1491*8c0984e5SSebastian Reichel 				return ret;
1492*8c0984e5SSebastian Reichel 			}
1493*8c0984e5SSebastian Reichel 		} else {
1494*8c0984e5SSebastian Reichel 			ret = abx500_set_register_interruptible(di->dev,
1495*8c0984e5SSebastian Reichel 				AB8500_CHARGER,
1496*8c0984e5SSebastian Reichel 				AB8500_MCH_CTRL1, 0);
1497*8c0984e5SSebastian Reichel 			if (ret) {
1498*8c0984e5SSebastian Reichel 				dev_err(di->dev,
1499*8c0984e5SSebastian Reichel 					"%s write failed\n", __func__);
1500*8c0984e5SSebastian Reichel 				return ret;
1501*8c0984e5SSebastian Reichel 			}
1502*8c0984e5SSebastian Reichel 		}
1503*8c0984e5SSebastian Reichel 
1504*8c0984e5SSebastian Reichel 		ret = ab8500_charger_led_en(di, false);
1505*8c0984e5SSebastian Reichel 		if (ret < 0)
1506*8c0984e5SSebastian Reichel 			dev_err(di->dev, "failed to disable LED\n");
1507*8c0984e5SSebastian Reichel 
1508*8c0984e5SSebastian Reichel 		di->ac.charger_online = 0;
1509*8c0984e5SSebastian Reichel 		di->ac.wd_expired = false;
1510*8c0984e5SSebastian Reichel 
1511*8c0984e5SSebastian Reichel 		/* Disable regulator if enabled */
1512*8c0984e5SSebastian Reichel 		if (di->vddadc_en_ac) {
1513*8c0984e5SSebastian Reichel 			regulator_disable(di->regu);
1514*8c0984e5SSebastian Reichel 			di->vddadc_en_ac = false;
1515*8c0984e5SSebastian Reichel 		}
1516*8c0984e5SSebastian Reichel 
1517*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "%s Disabled AC charging\n", __func__);
1518*8c0984e5SSebastian Reichel 	}
1519*8c0984e5SSebastian Reichel 	ab8500_power_supply_changed(di, di->ac_chg.psy);
1520*8c0984e5SSebastian Reichel 
1521*8c0984e5SSebastian Reichel 	return ret;
1522*8c0984e5SSebastian Reichel }
1523*8c0984e5SSebastian Reichel 
1524*8c0984e5SSebastian Reichel /**
1525*8c0984e5SSebastian Reichel  * ab8500_charger_usb_en() - enable usb charging
1526*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1527*8c0984e5SSebastian Reichel  * @enable:	enable/disable flag
1528*8c0984e5SSebastian Reichel  * @vset:	charging voltage
1529*8c0984e5SSebastian Reichel  * @ich_out:	charger output current
1530*8c0984e5SSebastian Reichel  *
1531*8c0984e5SSebastian Reichel  * Enable/Disable USB charging and turns on/off the charging led respectively.
1532*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1533*8c0984e5SSebastian Reichel  */
1534*8c0984e5SSebastian Reichel static int ab8500_charger_usb_en(struct ux500_charger *charger,
1535*8c0984e5SSebastian Reichel 	int enable, int vset, int ich_out)
1536*8c0984e5SSebastian Reichel {
1537*8c0984e5SSebastian Reichel 	int ret;
1538*8c0984e5SSebastian Reichel 	int volt_index;
1539*8c0984e5SSebastian Reichel 	int curr_index;
1540*8c0984e5SSebastian Reichel 	u8 overshoot = 0;
1541*8c0984e5SSebastian Reichel 
1542*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = to_ab8500_charger_usb_device_info(charger);
1543*8c0984e5SSebastian Reichel 
1544*8c0984e5SSebastian Reichel 	if (enable) {
1545*8c0984e5SSebastian Reichel 		/* Check if USB is connected */
1546*8c0984e5SSebastian Reichel 		if (!di->usb.charger_connected) {
1547*8c0984e5SSebastian Reichel 			dev_err(di->dev, "USB charger not connected\n");
1548*8c0984e5SSebastian Reichel 			return -ENXIO;
1549*8c0984e5SSebastian Reichel 		}
1550*8c0984e5SSebastian Reichel 
1551*8c0984e5SSebastian Reichel 		/*
1552*8c0984e5SSebastian Reichel 		 * Due to a bug in AB8500, BTEMP_HIGH/LOW interrupts
1553*8c0984e5SSebastian Reichel 		 * will be triggered everytime we enable the VDD ADC supply.
1554*8c0984e5SSebastian Reichel 		 * This will turn off charging for a short while.
1555*8c0984e5SSebastian Reichel 		 * It can be avoided by having the supply on when
1556*8c0984e5SSebastian Reichel 		 * there is a charger enabled. Normally the VDD ADC supply
1557*8c0984e5SSebastian Reichel 		 * is enabled everytime a GPADC conversion is triggered. We will
1558*8c0984e5SSebastian Reichel 		 * force it to be enabled from this driver to have
1559*8c0984e5SSebastian Reichel 		 * the GPADC module independant of the AB8500 chargers
1560*8c0984e5SSebastian Reichel 		 */
1561*8c0984e5SSebastian Reichel 		if (!di->vddadc_en_usb) {
1562*8c0984e5SSebastian Reichel 			ret = regulator_enable(di->regu);
1563*8c0984e5SSebastian Reichel 			if (ret)
1564*8c0984e5SSebastian Reichel 				dev_warn(di->dev,
1565*8c0984e5SSebastian Reichel 					"Failed to enable regulator\n");
1566*8c0984e5SSebastian Reichel 			else
1567*8c0984e5SSebastian Reichel 				di->vddadc_en_usb = true;
1568*8c0984e5SSebastian Reichel 		}
1569*8c0984e5SSebastian Reichel 
1570*8c0984e5SSebastian Reichel 		/* Enable USB charging */
1571*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "Enable USB: %dmV %dmA\n", vset, ich_out);
1572*8c0984e5SSebastian Reichel 
1573*8c0984e5SSebastian Reichel 		/* Check if the requested voltage or current is valid */
1574*8c0984e5SSebastian Reichel 		volt_index = ab8500_voltage_to_regval(vset);
1575*8c0984e5SSebastian Reichel 		curr_index = ab8500_current_to_regval(di, ich_out);
1576*8c0984e5SSebastian Reichel 		if (volt_index < 0 || curr_index < 0) {
1577*8c0984e5SSebastian Reichel 			dev_err(di->dev,
1578*8c0984e5SSebastian Reichel 				"Charger voltage or current too high, "
1579*8c0984e5SSebastian Reichel 				"charging not started\n");
1580*8c0984e5SSebastian Reichel 			return -ENXIO;
1581*8c0984e5SSebastian Reichel 		}
1582*8c0984e5SSebastian Reichel 
1583*8c0984e5SSebastian Reichel 		/* ChVoltLevel: max voltage upto which battery can be charged */
1584*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1585*8c0984e5SSebastian Reichel 			AB8500_CH_VOLT_LVL_REG, (u8) volt_index);
1586*8c0984e5SSebastian Reichel 		if (ret) {
1587*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s write failed\n", __func__);
1588*8c0984e5SSebastian Reichel 			return ret;
1589*8c0984e5SSebastian Reichel 		}
1590*8c0984e5SSebastian Reichel 		/* Check if VBAT overshoot control should be enabled */
1591*8c0984e5SSebastian Reichel 		if (!di->bm->enable_overshoot)
1592*8c0984e5SSebastian Reichel 			overshoot = USB_CHG_NO_OVERSHOOT_ENA_N;
1593*8c0984e5SSebastian Reichel 
1594*8c0984e5SSebastian Reichel 		/* Enable USB Charger */
1595*8c0984e5SSebastian Reichel 		dev_dbg(di->dev,
1596*8c0984e5SSebastian Reichel 			"Enabling USB with write to AB8500_USBCH_CTRL1_REG\n");
1597*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1598*8c0984e5SSebastian Reichel 			AB8500_USBCH_CTRL1_REG, USB_CH_ENA | overshoot);
1599*8c0984e5SSebastian Reichel 		if (ret) {
1600*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s write failed\n", __func__);
1601*8c0984e5SSebastian Reichel 			return ret;
1602*8c0984e5SSebastian Reichel 		}
1603*8c0984e5SSebastian Reichel 
1604*8c0984e5SSebastian Reichel 		/* If success power on charging LED indication */
1605*8c0984e5SSebastian Reichel 		ret = ab8500_charger_led_en(di, true);
1606*8c0984e5SSebastian Reichel 		if (ret < 0)
1607*8c0984e5SSebastian Reichel 			dev_err(di->dev, "failed to enable LED\n");
1608*8c0984e5SSebastian Reichel 
1609*8c0984e5SSebastian Reichel 		di->usb.charger_online = 1;
1610*8c0984e5SSebastian Reichel 
1611*8c0984e5SSebastian Reichel 		/* USBChInputCurr: current that can be drawn from the usb */
1612*8c0984e5SSebastian Reichel 		ret = ab8500_charger_set_vbus_in_curr(di,
1613*8c0984e5SSebastian Reichel 					di->max_usb_in_curr.usb_type_max);
1614*8c0984e5SSebastian Reichel 		if (ret) {
1615*8c0984e5SSebastian Reichel 			dev_err(di->dev, "setting USBChInputCurr failed\n");
1616*8c0984e5SSebastian Reichel 			return ret;
1617*8c0984e5SSebastian Reichel 		}
1618*8c0984e5SSebastian Reichel 
1619*8c0984e5SSebastian Reichel 		/* ChOutputCurentLevel: protected output current */
1620*8c0984e5SSebastian Reichel 		ret = ab8500_charger_set_output_curr(di, ich_out);
1621*8c0984e5SSebastian Reichel 		if (ret) {
1622*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s "
1623*8c0984e5SSebastian Reichel 				"Failed to set ChOutputCurentLevel\n",
1624*8c0984e5SSebastian Reichel 				__func__);
1625*8c0984e5SSebastian Reichel 			return ret;
1626*8c0984e5SSebastian Reichel 		}
1627*8c0984e5SSebastian Reichel 
1628*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq, &di->check_vbat_work, HZ);
1629*8c0984e5SSebastian Reichel 
1630*8c0984e5SSebastian Reichel 	} else {
1631*8c0984e5SSebastian Reichel 		/* Disable USB charging */
1632*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "%s Disabled USB charging\n", __func__);
1633*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev,
1634*8c0984e5SSebastian Reichel 			AB8500_CHARGER,
1635*8c0984e5SSebastian Reichel 			AB8500_USBCH_CTRL1_REG, 0);
1636*8c0984e5SSebastian Reichel 		if (ret) {
1637*8c0984e5SSebastian Reichel 			dev_err(di->dev,
1638*8c0984e5SSebastian Reichel 				"%s write failed\n", __func__);
1639*8c0984e5SSebastian Reichel 			return ret;
1640*8c0984e5SSebastian Reichel 		}
1641*8c0984e5SSebastian Reichel 
1642*8c0984e5SSebastian Reichel 		ret = ab8500_charger_led_en(di, false);
1643*8c0984e5SSebastian Reichel 		if (ret < 0)
1644*8c0984e5SSebastian Reichel 			dev_err(di->dev, "failed to disable LED\n");
1645*8c0984e5SSebastian Reichel 		/* USBChInputCurr: current that can be drawn from the usb */
1646*8c0984e5SSebastian Reichel 		ret = ab8500_charger_set_vbus_in_curr(di, 0);
1647*8c0984e5SSebastian Reichel 		if (ret) {
1648*8c0984e5SSebastian Reichel 			dev_err(di->dev, "setting USBChInputCurr failed\n");
1649*8c0984e5SSebastian Reichel 			return ret;
1650*8c0984e5SSebastian Reichel 		}
1651*8c0984e5SSebastian Reichel 
1652*8c0984e5SSebastian Reichel 		/* ChOutputCurentLevel: protected output current */
1653*8c0984e5SSebastian Reichel 		ret = ab8500_charger_set_output_curr(di, 0);
1654*8c0984e5SSebastian Reichel 		if (ret) {
1655*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s "
1656*8c0984e5SSebastian Reichel 				"Failed to reset ChOutputCurentLevel\n",
1657*8c0984e5SSebastian Reichel 				__func__);
1658*8c0984e5SSebastian Reichel 			return ret;
1659*8c0984e5SSebastian Reichel 		}
1660*8c0984e5SSebastian Reichel 		di->usb.charger_online = 0;
1661*8c0984e5SSebastian Reichel 		di->usb.wd_expired = false;
1662*8c0984e5SSebastian Reichel 
1663*8c0984e5SSebastian Reichel 		/* Disable regulator if enabled */
1664*8c0984e5SSebastian Reichel 		if (di->vddadc_en_usb) {
1665*8c0984e5SSebastian Reichel 			regulator_disable(di->regu);
1666*8c0984e5SSebastian Reichel 			di->vddadc_en_usb = false;
1667*8c0984e5SSebastian Reichel 		}
1668*8c0984e5SSebastian Reichel 
1669*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "%s Disabled USB charging\n", __func__);
1670*8c0984e5SSebastian Reichel 
1671*8c0984e5SSebastian Reichel 		/* Cancel any pending Vbat check work */
1672*8c0984e5SSebastian Reichel 		cancel_delayed_work(&di->check_vbat_work);
1673*8c0984e5SSebastian Reichel 
1674*8c0984e5SSebastian Reichel 	}
1675*8c0984e5SSebastian Reichel 	ab8500_power_supply_changed(di, di->usb_chg.psy);
1676*8c0984e5SSebastian Reichel 
1677*8c0984e5SSebastian Reichel 	return ret;
1678*8c0984e5SSebastian Reichel }
1679*8c0984e5SSebastian Reichel 
1680*8c0984e5SSebastian Reichel static int ab8500_external_charger_prepare(struct notifier_block *charger_nb,
1681*8c0984e5SSebastian Reichel 				unsigned long event, void *data)
1682*8c0984e5SSebastian Reichel {
1683*8c0984e5SSebastian Reichel 	int ret;
1684*8c0984e5SSebastian Reichel 	struct device *dev = data;
1685*8c0984e5SSebastian Reichel 	/*Toggle External charger control pin*/
1686*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(dev, AB8500_SYS_CTRL1_BLOCK,
1687*8c0984e5SSebastian Reichel 				  AB8500_SYS_CHARGER_CONTROL_REG,
1688*8c0984e5SSebastian Reichel 				  EXTERNAL_CHARGER_DISABLE_REG_VAL);
1689*8c0984e5SSebastian Reichel 	if (ret < 0) {
1690*8c0984e5SSebastian Reichel 		dev_err(dev, "write reg failed %d\n", ret);
1691*8c0984e5SSebastian Reichel 		goto out;
1692*8c0984e5SSebastian Reichel 	}
1693*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(dev, AB8500_SYS_CTRL1_BLOCK,
1694*8c0984e5SSebastian Reichel 				  AB8500_SYS_CHARGER_CONTROL_REG,
1695*8c0984e5SSebastian Reichel 				  EXTERNAL_CHARGER_ENABLE_REG_VAL);
1696*8c0984e5SSebastian Reichel 	if (ret < 0)
1697*8c0984e5SSebastian Reichel 		dev_err(dev, "Write reg failed %d\n", ret);
1698*8c0984e5SSebastian Reichel 
1699*8c0984e5SSebastian Reichel out:
1700*8c0984e5SSebastian Reichel 	return ret;
1701*8c0984e5SSebastian Reichel }
1702*8c0984e5SSebastian Reichel 
1703*8c0984e5SSebastian Reichel /**
1704*8c0984e5SSebastian Reichel  * ab8500_charger_usb_check_enable() - enable usb charging
1705*8c0984e5SSebastian Reichel  * @charger:	pointer to the ux500_charger structure
1706*8c0984e5SSebastian Reichel  * @vset:	charging voltage
1707*8c0984e5SSebastian Reichel  * @iset:	charger output current
1708*8c0984e5SSebastian Reichel  *
1709*8c0984e5SSebastian Reichel  * Check if the VBUS charger has been disconnected and reconnected without
1710*8c0984e5SSebastian Reichel  * AB8500 rising an interrupt. Returns 0 on success.
1711*8c0984e5SSebastian Reichel  */
1712*8c0984e5SSebastian Reichel static int ab8500_charger_usb_check_enable(struct ux500_charger *charger,
1713*8c0984e5SSebastian Reichel 	int vset, int iset)
1714*8c0984e5SSebastian Reichel {
1715*8c0984e5SSebastian Reichel 	u8 usbch_ctrl1 = 0;
1716*8c0984e5SSebastian Reichel 	int ret = 0;
1717*8c0984e5SSebastian Reichel 
1718*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = to_ab8500_charger_usb_device_info(charger);
1719*8c0984e5SSebastian Reichel 
1720*8c0984e5SSebastian Reichel 	if (!di->usb.charger_connected)
1721*8c0984e5SSebastian Reichel 		return ret;
1722*8c0984e5SSebastian Reichel 
1723*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
1724*8c0984e5SSebastian Reichel 				AB8500_USBCH_CTRL1_REG, &usbch_ctrl1);
1725*8c0984e5SSebastian Reichel 	if (ret < 0) {
1726*8c0984e5SSebastian Reichel 		dev_err(di->dev, "ab8500 read failed %d\n", __LINE__);
1727*8c0984e5SSebastian Reichel 		return ret;
1728*8c0984e5SSebastian Reichel 	}
1729*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "USB charger ctrl: 0x%02x\n", usbch_ctrl1);
1730*8c0984e5SSebastian Reichel 
1731*8c0984e5SSebastian Reichel 	if (!(usbch_ctrl1 & USB_CH_ENA)) {
1732*8c0984e5SSebastian Reichel 		dev_info(di->dev, "Charging has been disabled abnormally and will be re-enabled\n");
1733*8c0984e5SSebastian Reichel 
1734*8c0984e5SSebastian Reichel 		ret = abx500_mask_and_set_register_interruptible(di->dev,
1735*8c0984e5SSebastian Reichel 					AB8500_CHARGER, AB8500_CHARGER_CTRL,
1736*8c0984e5SSebastian Reichel 					DROP_COUNT_RESET, DROP_COUNT_RESET);
1737*8c0984e5SSebastian Reichel 		if (ret < 0) {
1738*8c0984e5SSebastian Reichel 			dev_err(di->dev, "ab8500 write failed %d\n", __LINE__);
1739*8c0984e5SSebastian Reichel 			return ret;
1740*8c0984e5SSebastian Reichel 		}
1741*8c0984e5SSebastian Reichel 
1742*8c0984e5SSebastian Reichel 		ret = ab8500_charger_usb_en(&di->usb_chg, true, vset, iset);
1743*8c0984e5SSebastian Reichel 		if (ret < 0) {
1744*8c0984e5SSebastian Reichel 			dev_err(di->dev, "Failed to enable VBUS charger %d\n",
1745*8c0984e5SSebastian Reichel 					__LINE__);
1746*8c0984e5SSebastian Reichel 			return ret;
1747*8c0984e5SSebastian Reichel 		}
1748*8c0984e5SSebastian Reichel 	}
1749*8c0984e5SSebastian Reichel 	return ret;
1750*8c0984e5SSebastian Reichel }
1751*8c0984e5SSebastian Reichel 
1752*8c0984e5SSebastian Reichel /**
1753*8c0984e5SSebastian Reichel  * ab8500_charger_ac_check_enable() - enable usb charging
1754*8c0984e5SSebastian Reichel  * @charger:	pointer to the ux500_charger structure
1755*8c0984e5SSebastian Reichel  * @vset:	charging voltage
1756*8c0984e5SSebastian Reichel  * @iset:	charger output current
1757*8c0984e5SSebastian Reichel  *
1758*8c0984e5SSebastian Reichel  * Check if the AC charger has been disconnected and reconnected without
1759*8c0984e5SSebastian Reichel  * AB8500 rising an interrupt. Returns 0 on success.
1760*8c0984e5SSebastian Reichel  */
1761*8c0984e5SSebastian Reichel static int ab8500_charger_ac_check_enable(struct ux500_charger *charger,
1762*8c0984e5SSebastian Reichel 	int vset, int iset)
1763*8c0984e5SSebastian Reichel {
1764*8c0984e5SSebastian Reichel 	u8 mainch_ctrl1 = 0;
1765*8c0984e5SSebastian Reichel 	int ret = 0;
1766*8c0984e5SSebastian Reichel 
1767*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = to_ab8500_charger_ac_device_info(charger);
1768*8c0984e5SSebastian Reichel 
1769*8c0984e5SSebastian Reichel 	if (!di->ac.charger_connected)
1770*8c0984e5SSebastian Reichel 		return ret;
1771*8c0984e5SSebastian Reichel 
1772*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
1773*8c0984e5SSebastian Reichel 				AB8500_MCH_CTRL1, &mainch_ctrl1);
1774*8c0984e5SSebastian Reichel 	if (ret < 0) {
1775*8c0984e5SSebastian Reichel 		dev_err(di->dev, "ab8500 read failed %d\n", __LINE__);
1776*8c0984e5SSebastian Reichel 		return ret;
1777*8c0984e5SSebastian Reichel 	}
1778*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "AC charger ctrl: 0x%02x\n", mainch_ctrl1);
1779*8c0984e5SSebastian Reichel 
1780*8c0984e5SSebastian Reichel 	if (!(mainch_ctrl1 & MAIN_CH_ENA)) {
1781*8c0984e5SSebastian Reichel 		dev_info(di->dev, "Charging has been disabled abnormally and will be re-enabled\n");
1782*8c0984e5SSebastian Reichel 
1783*8c0984e5SSebastian Reichel 		ret = abx500_mask_and_set_register_interruptible(di->dev,
1784*8c0984e5SSebastian Reichel 					AB8500_CHARGER, AB8500_CHARGER_CTRL,
1785*8c0984e5SSebastian Reichel 					DROP_COUNT_RESET, DROP_COUNT_RESET);
1786*8c0984e5SSebastian Reichel 
1787*8c0984e5SSebastian Reichel 		if (ret < 0) {
1788*8c0984e5SSebastian Reichel 			dev_err(di->dev, "ab8500 write failed %d\n", __LINE__);
1789*8c0984e5SSebastian Reichel 			return ret;
1790*8c0984e5SSebastian Reichel 		}
1791*8c0984e5SSebastian Reichel 
1792*8c0984e5SSebastian Reichel 		ret = ab8500_charger_ac_en(&di->usb_chg, true, vset, iset);
1793*8c0984e5SSebastian Reichel 		if (ret < 0) {
1794*8c0984e5SSebastian Reichel 			dev_err(di->dev, "failed to enable AC charger %d\n",
1795*8c0984e5SSebastian Reichel 				__LINE__);
1796*8c0984e5SSebastian Reichel 			return ret;
1797*8c0984e5SSebastian Reichel 		}
1798*8c0984e5SSebastian Reichel 	}
1799*8c0984e5SSebastian Reichel 	return ret;
1800*8c0984e5SSebastian Reichel }
1801*8c0984e5SSebastian Reichel 
1802*8c0984e5SSebastian Reichel /**
1803*8c0984e5SSebastian Reichel  * ab8500_charger_watchdog_kick() - kick charger watchdog
1804*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1805*8c0984e5SSebastian Reichel  *
1806*8c0984e5SSebastian Reichel  * Kick charger watchdog
1807*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1808*8c0984e5SSebastian Reichel  */
1809*8c0984e5SSebastian Reichel static int ab8500_charger_watchdog_kick(struct ux500_charger *charger)
1810*8c0984e5SSebastian Reichel {
1811*8c0984e5SSebastian Reichel 	int ret;
1812*8c0984e5SSebastian Reichel 	struct ab8500_charger *di;
1813*8c0984e5SSebastian Reichel 
1814*8c0984e5SSebastian Reichel 	if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS)
1815*8c0984e5SSebastian Reichel 		di = to_ab8500_charger_ac_device_info(charger);
1816*8c0984e5SSebastian Reichel 	else if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB)
1817*8c0984e5SSebastian Reichel 		di = to_ab8500_charger_usb_device_info(charger);
1818*8c0984e5SSebastian Reichel 	else
1819*8c0984e5SSebastian Reichel 		return -ENXIO;
1820*8c0984e5SSebastian Reichel 
1821*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1822*8c0984e5SSebastian Reichel 		AB8500_CHARG_WD_CTRL, CHARG_WD_KICK);
1823*8c0984e5SSebastian Reichel 	if (ret)
1824*8c0984e5SSebastian Reichel 		dev_err(di->dev, "Failed to kick WD!\n");
1825*8c0984e5SSebastian Reichel 
1826*8c0984e5SSebastian Reichel 	return ret;
1827*8c0984e5SSebastian Reichel }
1828*8c0984e5SSebastian Reichel 
1829*8c0984e5SSebastian Reichel /**
1830*8c0984e5SSebastian Reichel  * ab8500_charger_update_charger_current() - update charger current
1831*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
1832*8c0984e5SSebastian Reichel  *
1833*8c0984e5SSebastian Reichel  * Update the charger output current for the specified charger
1834*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1835*8c0984e5SSebastian Reichel  */
1836*8c0984e5SSebastian Reichel static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
1837*8c0984e5SSebastian Reichel 		int ich_out)
1838*8c0984e5SSebastian Reichel {
1839*8c0984e5SSebastian Reichel 	int ret;
1840*8c0984e5SSebastian Reichel 	struct ab8500_charger *di;
1841*8c0984e5SSebastian Reichel 
1842*8c0984e5SSebastian Reichel 	if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS)
1843*8c0984e5SSebastian Reichel 		di = to_ab8500_charger_ac_device_info(charger);
1844*8c0984e5SSebastian Reichel 	else if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB)
1845*8c0984e5SSebastian Reichel 		di = to_ab8500_charger_usb_device_info(charger);
1846*8c0984e5SSebastian Reichel 	else
1847*8c0984e5SSebastian Reichel 		return -ENXIO;
1848*8c0984e5SSebastian Reichel 
1849*8c0984e5SSebastian Reichel 	ret = ab8500_charger_set_output_curr(di, ich_out);
1850*8c0984e5SSebastian Reichel 	if (ret) {
1851*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s "
1852*8c0984e5SSebastian Reichel 			"Failed to set ChOutputCurentLevel\n",
1853*8c0984e5SSebastian Reichel 			__func__);
1854*8c0984e5SSebastian Reichel 		return ret;
1855*8c0984e5SSebastian Reichel 	}
1856*8c0984e5SSebastian Reichel 
1857*8c0984e5SSebastian Reichel 	/* Reset the main and usb drop input current measurement counter */
1858*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1859*8c0984e5SSebastian Reichel 				AB8500_CHARGER_CTRL, DROP_COUNT_RESET);
1860*8c0984e5SSebastian Reichel 	if (ret) {
1861*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s write failed\n", __func__);
1862*8c0984e5SSebastian Reichel 		return ret;
1863*8c0984e5SSebastian Reichel 	}
1864*8c0984e5SSebastian Reichel 
1865*8c0984e5SSebastian Reichel 	return ret;
1866*8c0984e5SSebastian Reichel }
1867*8c0984e5SSebastian Reichel 
1868*8c0984e5SSebastian Reichel /**
1869*8c0984e5SSebastian Reichel  * ab8540_charger_power_path_enable() - enable usb power path mode
1870*8c0984e5SSebastian Reichel  * @charger:	pointer to the ux500_charger structure
1871*8c0984e5SSebastian Reichel  * @enable:	enable/disable flag
1872*8c0984e5SSebastian Reichel  *
1873*8c0984e5SSebastian Reichel  * Enable or disable the power path for usb mode
1874*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1875*8c0984e5SSebastian Reichel  */
1876*8c0984e5SSebastian Reichel static int ab8540_charger_power_path_enable(struct ux500_charger *charger,
1877*8c0984e5SSebastian Reichel 		bool enable)
1878*8c0984e5SSebastian Reichel {
1879*8c0984e5SSebastian Reichel 	int ret;
1880*8c0984e5SSebastian Reichel 	struct ab8500_charger *di;
1881*8c0984e5SSebastian Reichel 
1882*8c0984e5SSebastian Reichel 	if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB)
1883*8c0984e5SSebastian Reichel 		di = to_ab8500_charger_usb_device_info(charger);
1884*8c0984e5SSebastian Reichel 	else
1885*8c0984e5SSebastian Reichel 		return -ENXIO;
1886*8c0984e5SSebastian Reichel 
1887*8c0984e5SSebastian Reichel 	ret = abx500_mask_and_set_register_interruptible(di->dev,
1888*8c0984e5SSebastian Reichel 				AB8500_CHARGER, AB8540_USB_PP_MODE_REG,
1889*8c0984e5SSebastian Reichel 				BUS_POWER_PATH_MODE_ENA, enable);
1890*8c0984e5SSebastian Reichel 	if (ret) {
1891*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s write failed\n", __func__);
1892*8c0984e5SSebastian Reichel 		return ret;
1893*8c0984e5SSebastian Reichel 	}
1894*8c0984e5SSebastian Reichel 
1895*8c0984e5SSebastian Reichel 	return ret;
1896*8c0984e5SSebastian Reichel }
1897*8c0984e5SSebastian Reichel 
1898*8c0984e5SSebastian Reichel 
1899*8c0984e5SSebastian Reichel /**
1900*8c0984e5SSebastian Reichel  * ab8540_charger_usb_pre_chg_enable() - enable usb pre change
1901*8c0984e5SSebastian Reichel  * @charger:	pointer to the ux500_charger structure
1902*8c0984e5SSebastian Reichel  * @enable:	enable/disable flag
1903*8c0984e5SSebastian Reichel  *
1904*8c0984e5SSebastian Reichel  * Enable or disable the pre-chage for usb mode
1905*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
1906*8c0984e5SSebastian Reichel  */
1907*8c0984e5SSebastian Reichel static int ab8540_charger_usb_pre_chg_enable(struct ux500_charger *charger,
1908*8c0984e5SSebastian Reichel 		bool enable)
1909*8c0984e5SSebastian Reichel {
1910*8c0984e5SSebastian Reichel 	int ret;
1911*8c0984e5SSebastian Reichel 	struct ab8500_charger *di;
1912*8c0984e5SSebastian Reichel 
1913*8c0984e5SSebastian Reichel 	if (charger->psy->desc->type == POWER_SUPPLY_TYPE_USB)
1914*8c0984e5SSebastian Reichel 		di = to_ab8500_charger_usb_device_info(charger);
1915*8c0984e5SSebastian Reichel 	else
1916*8c0984e5SSebastian Reichel 		return -ENXIO;
1917*8c0984e5SSebastian Reichel 
1918*8c0984e5SSebastian Reichel 	ret = abx500_mask_and_set_register_interruptible(di->dev,
1919*8c0984e5SSebastian Reichel 				AB8500_CHARGER, AB8540_USB_PP_CHR_REG,
1920*8c0984e5SSebastian Reichel 				BUS_POWER_PATH_PRECHG_ENA, enable);
1921*8c0984e5SSebastian Reichel 	if (ret) {
1922*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s write failed\n", __func__);
1923*8c0984e5SSebastian Reichel 		return ret;
1924*8c0984e5SSebastian Reichel 	}
1925*8c0984e5SSebastian Reichel 
1926*8c0984e5SSebastian Reichel 	return ret;
1927*8c0984e5SSebastian Reichel }
1928*8c0984e5SSebastian Reichel 
1929*8c0984e5SSebastian Reichel static int ab8500_charger_get_ext_psy_data(struct device *dev, void *data)
1930*8c0984e5SSebastian Reichel {
1931*8c0984e5SSebastian Reichel 	struct power_supply *psy;
1932*8c0984e5SSebastian Reichel 	struct power_supply *ext = dev_get_drvdata(dev);
1933*8c0984e5SSebastian Reichel 	const char **supplicants = (const char **)ext->supplied_to;
1934*8c0984e5SSebastian Reichel 	struct ab8500_charger *di;
1935*8c0984e5SSebastian Reichel 	union power_supply_propval ret;
1936*8c0984e5SSebastian Reichel 	int j;
1937*8c0984e5SSebastian Reichel 	struct ux500_charger *usb_chg;
1938*8c0984e5SSebastian Reichel 
1939*8c0984e5SSebastian Reichel 	usb_chg = (struct ux500_charger *)data;
1940*8c0984e5SSebastian Reichel 	psy = usb_chg->psy;
1941*8c0984e5SSebastian Reichel 
1942*8c0984e5SSebastian Reichel 	di = to_ab8500_charger_usb_device_info(usb_chg);
1943*8c0984e5SSebastian Reichel 
1944*8c0984e5SSebastian Reichel 	/* For all psy where the driver name appears in any supplied_to */
1945*8c0984e5SSebastian Reichel 	j = match_string(supplicants, ext->num_supplicants, psy->desc->name);
1946*8c0984e5SSebastian Reichel 	if (j < 0)
1947*8c0984e5SSebastian Reichel 		return 0;
1948*8c0984e5SSebastian Reichel 
1949*8c0984e5SSebastian Reichel 	/* Go through all properties for the psy */
1950*8c0984e5SSebastian Reichel 	for (j = 0; j < ext->desc->num_properties; j++) {
1951*8c0984e5SSebastian Reichel 		enum power_supply_property prop;
1952*8c0984e5SSebastian Reichel 		prop = ext->desc->properties[j];
1953*8c0984e5SSebastian Reichel 
1954*8c0984e5SSebastian Reichel 		if (power_supply_get_property(ext, prop, &ret))
1955*8c0984e5SSebastian Reichel 			continue;
1956*8c0984e5SSebastian Reichel 
1957*8c0984e5SSebastian Reichel 		switch (prop) {
1958*8c0984e5SSebastian Reichel 		case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1959*8c0984e5SSebastian Reichel 			switch (ext->desc->type) {
1960*8c0984e5SSebastian Reichel 			case POWER_SUPPLY_TYPE_BATTERY:
1961*8c0984e5SSebastian Reichel 				di->vbat = ret.intval / 1000;
1962*8c0984e5SSebastian Reichel 				break;
1963*8c0984e5SSebastian Reichel 			default:
1964*8c0984e5SSebastian Reichel 				break;
1965*8c0984e5SSebastian Reichel 			}
1966*8c0984e5SSebastian Reichel 			break;
1967*8c0984e5SSebastian Reichel 		default:
1968*8c0984e5SSebastian Reichel 			break;
1969*8c0984e5SSebastian Reichel 		}
1970*8c0984e5SSebastian Reichel 	}
1971*8c0984e5SSebastian Reichel 	return 0;
1972*8c0984e5SSebastian Reichel }
1973*8c0984e5SSebastian Reichel 
1974*8c0984e5SSebastian Reichel /**
1975*8c0984e5SSebastian Reichel  * ab8500_charger_check_vbat_work() - keep vbus current within spec
1976*8c0984e5SSebastian Reichel  * @work	pointer to the work_struct structure
1977*8c0984e5SSebastian Reichel  *
1978*8c0984e5SSebastian Reichel  * Due to a asic bug it is necessary to lower the input current to the vbus
1979*8c0984e5SSebastian Reichel  * charger when charging with at some specific levels. This issue is only valid
1980*8c0984e5SSebastian Reichel  * for below a certain battery voltage. This function makes sure that the
1981*8c0984e5SSebastian Reichel  * the allowed current limit isn't exceeded.
1982*8c0984e5SSebastian Reichel  */
1983*8c0984e5SSebastian Reichel static void ab8500_charger_check_vbat_work(struct work_struct *work)
1984*8c0984e5SSebastian Reichel {
1985*8c0984e5SSebastian Reichel 	int t = 10;
1986*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
1987*8c0984e5SSebastian Reichel 		struct ab8500_charger, check_vbat_work.work);
1988*8c0984e5SSebastian Reichel 
1989*8c0984e5SSebastian Reichel 	class_for_each_device(power_supply_class, NULL,
1990*8c0984e5SSebastian Reichel 		di->usb_chg.psy, ab8500_charger_get_ext_psy_data);
1991*8c0984e5SSebastian Reichel 
1992*8c0984e5SSebastian Reichel 	/* First run old_vbat is 0. */
1993*8c0984e5SSebastian Reichel 	if (di->old_vbat == 0)
1994*8c0984e5SSebastian Reichel 		di->old_vbat = di->vbat;
1995*8c0984e5SSebastian Reichel 
1996*8c0984e5SSebastian Reichel 	if (!((di->old_vbat <= VBAT_TRESH_IP_CUR_RED &&
1997*8c0984e5SSebastian Reichel 		di->vbat <= VBAT_TRESH_IP_CUR_RED) ||
1998*8c0984e5SSebastian Reichel 		(di->old_vbat > VBAT_TRESH_IP_CUR_RED &&
1999*8c0984e5SSebastian Reichel 		di->vbat > VBAT_TRESH_IP_CUR_RED))) {
2000*8c0984e5SSebastian Reichel 
2001*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "Vbat did cross threshold, curr: %d, new: %d,"
2002*8c0984e5SSebastian Reichel 			" old: %d\n", di->max_usb_in_curr.usb_type_max,
2003*8c0984e5SSebastian Reichel 			di->vbat, di->old_vbat);
2004*8c0984e5SSebastian Reichel 		ab8500_charger_set_vbus_in_curr(di,
2005*8c0984e5SSebastian Reichel 					di->max_usb_in_curr.usb_type_max);
2006*8c0984e5SSebastian Reichel 		power_supply_changed(di->usb_chg.psy);
2007*8c0984e5SSebastian Reichel 	}
2008*8c0984e5SSebastian Reichel 
2009*8c0984e5SSebastian Reichel 	di->old_vbat = di->vbat;
2010*8c0984e5SSebastian Reichel 
2011*8c0984e5SSebastian Reichel 	/*
2012*8c0984e5SSebastian Reichel 	 * No need to check the battery voltage every second when not close to
2013*8c0984e5SSebastian Reichel 	 * the threshold.
2014*8c0984e5SSebastian Reichel 	 */
2015*8c0984e5SSebastian Reichel 	if (di->vbat < (VBAT_TRESH_IP_CUR_RED + 100) &&
2016*8c0984e5SSebastian Reichel 		(di->vbat > (VBAT_TRESH_IP_CUR_RED - 100)))
2017*8c0984e5SSebastian Reichel 			t = 1;
2018*8c0984e5SSebastian Reichel 
2019*8c0984e5SSebastian Reichel 	queue_delayed_work(di->charger_wq, &di->check_vbat_work, t * HZ);
2020*8c0984e5SSebastian Reichel }
2021*8c0984e5SSebastian Reichel 
2022*8c0984e5SSebastian Reichel /**
2023*8c0984e5SSebastian Reichel  * ab8500_charger_check_hw_failure_work() - check main charger failure
2024*8c0984e5SSebastian Reichel  * @work:	pointer to the work_struct structure
2025*8c0984e5SSebastian Reichel  *
2026*8c0984e5SSebastian Reichel  * Work queue function for checking the main charger status
2027*8c0984e5SSebastian Reichel  */
2028*8c0984e5SSebastian Reichel static void ab8500_charger_check_hw_failure_work(struct work_struct *work)
2029*8c0984e5SSebastian Reichel {
2030*8c0984e5SSebastian Reichel 	int ret;
2031*8c0984e5SSebastian Reichel 	u8 reg_value;
2032*8c0984e5SSebastian Reichel 
2033*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2034*8c0984e5SSebastian Reichel 		struct ab8500_charger, check_hw_failure_work.work);
2035*8c0984e5SSebastian Reichel 
2036*8c0984e5SSebastian Reichel 	/* Check if the status bits for HW failure is still active */
2037*8c0984e5SSebastian Reichel 	if (di->flags.mainextchnotok) {
2038*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev,
2039*8c0984e5SSebastian Reichel 			AB8500_CHARGER, AB8500_CH_STATUS2_REG, &reg_value);
2040*8c0984e5SSebastian Reichel 		if (ret < 0) {
2041*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s ab8500 read failed\n", __func__);
2042*8c0984e5SSebastian Reichel 			return;
2043*8c0984e5SSebastian Reichel 		}
2044*8c0984e5SSebastian Reichel 		if (!(reg_value & MAIN_CH_NOK)) {
2045*8c0984e5SSebastian Reichel 			di->flags.mainextchnotok = false;
2046*8c0984e5SSebastian Reichel 			ab8500_power_supply_changed(di, di->ac_chg.psy);
2047*8c0984e5SSebastian Reichel 		}
2048*8c0984e5SSebastian Reichel 	}
2049*8c0984e5SSebastian Reichel 	if (di->flags.vbus_ovv) {
2050*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev,
2051*8c0984e5SSebastian Reichel 			AB8500_CHARGER, AB8500_CH_USBCH_STAT2_REG,
2052*8c0984e5SSebastian Reichel 			&reg_value);
2053*8c0984e5SSebastian Reichel 		if (ret < 0) {
2054*8c0984e5SSebastian Reichel 			dev_err(di->dev, "%s ab8500 read failed\n", __func__);
2055*8c0984e5SSebastian Reichel 			return;
2056*8c0984e5SSebastian Reichel 		}
2057*8c0984e5SSebastian Reichel 		if (!(reg_value & VBUS_OVV_TH)) {
2058*8c0984e5SSebastian Reichel 			di->flags.vbus_ovv = false;
2059*8c0984e5SSebastian Reichel 			ab8500_power_supply_changed(di, di->usb_chg.psy);
2060*8c0984e5SSebastian Reichel 		}
2061*8c0984e5SSebastian Reichel 	}
2062*8c0984e5SSebastian Reichel 	/* If we still have a failure, schedule a new check */
2063*8c0984e5SSebastian Reichel 	if (di->flags.mainextchnotok || di->flags.vbus_ovv) {
2064*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq,
2065*8c0984e5SSebastian Reichel 			&di->check_hw_failure_work, round_jiffies(HZ));
2066*8c0984e5SSebastian Reichel 	}
2067*8c0984e5SSebastian Reichel }
2068*8c0984e5SSebastian Reichel 
2069*8c0984e5SSebastian Reichel /**
2070*8c0984e5SSebastian Reichel  * ab8500_charger_kick_watchdog_work() - kick the watchdog
2071*8c0984e5SSebastian Reichel  * @work:	pointer to the work_struct structure
2072*8c0984e5SSebastian Reichel  *
2073*8c0984e5SSebastian Reichel  * Work queue function for kicking the charger watchdog.
2074*8c0984e5SSebastian Reichel  *
2075*8c0984e5SSebastian Reichel  * For ABB revision 1.0 and 1.1 there is a bug in the watchdog
2076*8c0984e5SSebastian Reichel  * logic. That means we have to continously kick the charger
2077*8c0984e5SSebastian Reichel  * watchdog even when no charger is connected. This is only
2078*8c0984e5SSebastian Reichel  * valid once the AC charger has been enabled. This is
2079*8c0984e5SSebastian Reichel  * a bug that is not handled by the algorithm and the
2080*8c0984e5SSebastian Reichel  * watchdog have to be kicked by the charger driver
2081*8c0984e5SSebastian Reichel  * when the AC charger is disabled
2082*8c0984e5SSebastian Reichel  */
2083*8c0984e5SSebastian Reichel static void ab8500_charger_kick_watchdog_work(struct work_struct *work)
2084*8c0984e5SSebastian Reichel {
2085*8c0984e5SSebastian Reichel 	int ret;
2086*8c0984e5SSebastian Reichel 
2087*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2088*8c0984e5SSebastian Reichel 		struct ab8500_charger, kick_wd_work.work);
2089*8c0984e5SSebastian Reichel 
2090*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
2091*8c0984e5SSebastian Reichel 		AB8500_CHARG_WD_CTRL, CHARG_WD_KICK);
2092*8c0984e5SSebastian Reichel 	if (ret)
2093*8c0984e5SSebastian Reichel 		dev_err(di->dev, "Failed to kick WD!\n");
2094*8c0984e5SSebastian Reichel 
2095*8c0984e5SSebastian Reichel 	/* Schedule a new watchdog kick */
2096*8c0984e5SSebastian Reichel 	queue_delayed_work(di->charger_wq,
2097*8c0984e5SSebastian Reichel 		&di->kick_wd_work, round_jiffies(WD_KICK_INTERVAL));
2098*8c0984e5SSebastian Reichel }
2099*8c0984e5SSebastian Reichel 
2100*8c0984e5SSebastian Reichel /**
2101*8c0984e5SSebastian Reichel  * ab8500_charger_ac_work() - work to get and set main charger status
2102*8c0984e5SSebastian Reichel  * @work:	pointer to the work_struct structure
2103*8c0984e5SSebastian Reichel  *
2104*8c0984e5SSebastian Reichel  * Work queue function for checking the main charger status
2105*8c0984e5SSebastian Reichel  */
2106*8c0984e5SSebastian Reichel static void ab8500_charger_ac_work(struct work_struct *work)
2107*8c0984e5SSebastian Reichel {
2108*8c0984e5SSebastian Reichel 	int ret;
2109*8c0984e5SSebastian Reichel 
2110*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2111*8c0984e5SSebastian Reichel 		struct ab8500_charger, ac_work);
2112*8c0984e5SSebastian Reichel 
2113*8c0984e5SSebastian Reichel 	/*
2114*8c0984e5SSebastian Reichel 	 * Since we can't be sure that the events are received
2115*8c0984e5SSebastian Reichel 	 * synchronously, we have the check if the main charger is
2116*8c0984e5SSebastian Reichel 	 * connected by reading the status register
2117*8c0984e5SSebastian Reichel 	 */
2118*8c0984e5SSebastian Reichel 	ret = ab8500_charger_detect_chargers(di, false);
2119*8c0984e5SSebastian Reichel 	if (ret < 0)
2120*8c0984e5SSebastian Reichel 		return;
2121*8c0984e5SSebastian Reichel 
2122*8c0984e5SSebastian Reichel 	if (ret & AC_PW_CONN) {
2123*8c0984e5SSebastian Reichel 		di->ac.charger_connected = 1;
2124*8c0984e5SSebastian Reichel 		di->ac_conn = true;
2125*8c0984e5SSebastian Reichel 	} else {
2126*8c0984e5SSebastian Reichel 		di->ac.charger_connected = 0;
2127*8c0984e5SSebastian Reichel 	}
2128*8c0984e5SSebastian Reichel 
2129*8c0984e5SSebastian Reichel 	ab8500_power_supply_changed(di, di->ac_chg.psy);
2130*8c0984e5SSebastian Reichel 	sysfs_notify(&di->ac_chg.psy->dev.kobj, NULL, "present");
2131*8c0984e5SSebastian Reichel }
2132*8c0984e5SSebastian Reichel 
2133*8c0984e5SSebastian Reichel static void ab8500_charger_usb_attached_work(struct work_struct *work)
2134*8c0984e5SSebastian Reichel {
2135*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2136*8c0984e5SSebastian Reichel 						 struct ab8500_charger,
2137*8c0984e5SSebastian Reichel 						 usb_charger_attached_work.work);
2138*8c0984e5SSebastian Reichel 	int usbch = (USB_CH_VBUSDROP | USB_CH_VBUSDETDBNC);
2139*8c0984e5SSebastian Reichel 	int ret, i;
2140*8c0984e5SSebastian Reichel 	u8 statval;
2141*8c0984e5SSebastian Reichel 
2142*8c0984e5SSebastian Reichel 	for (i = 0; i < 10; i++) {
2143*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev,
2144*8c0984e5SSebastian Reichel 							AB8500_CHARGER,
2145*8c0984e5SSebastian Reichel 							AB8500_CH_USBCH_STAT1_REG,
2146*8c0984e5SSebastian Reichel 							&statval);
2147*8c0984e5SSebastian Reichel 		if (ret < 0) {
2148*8c0984e5SSebastian Reichel 			dev_err(di->dev, "ab8500 read failed %d\n", __LINE__);
2149*8c0984e5SSebastian Reichel 			goto reschedule;
2150*8c0984e5SSebastian Reichel 		}
2151*8c0984e5SSebastian Reichel 		if ((statval & usbch) != usbch)
2152*8c0984e5SSebastian Reichel 			goto reschedule;
2153*8c0984e5SSebastian Reichel 
2154*8c0984e5SSebastian Reichel 		msleep(CHARGER_STATUS_POLL);
2155*8c0984e5SSebastian Reichel 	}
2156*8c0984e5SSebastian Reichel 
2157*8c0984e5SSebastian Reichel 	ab8500_charger_usb_en(&di->usb_chg, 0, 0, 0);
2158*8c0984e5SSebastian Reichel 
2159*8c0984e5SSebastian Reichel 	mutex_lock(&di->charger_attached_mutex);
2160*8c0984e5SSebastian Reichel 	mutex_unlock(&di->charger_attached_mutex);
2161*8c0984e5SSebastian Reichel 
2162*8c0984e5SSebastian Reichel 	return;
2163*8c0984e5SSebastian Reichel 
2164*8c0984e5SSebastian Reichel reschedule:
2165*8c0984e5SSebastian Reichel 	queue_delayed_work(di->charger_wq,
2166*8c0984e5SSebastian Reichel 			   &di->usb_charger_attached_work,
2167*8c0984e5SSebastian Reichel 			   HZ);
2168*8c0984e5SSebastian Reichel }
2169*8c0984e5SSebastian Reichel 
2170*8c0984e5SSebastian Reichel static void ab8500_charger_ac_attached_work(struct work_struct *work)
2171*8c0984e5SSebastian Reichel {
2172*8c0984e5SSebastian Reichel 
2173*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2174*8c0984e5SSebastian Reichel 						 struct ab8500_charger,
2175*8c0984e5SSebastian Reichel 						 ac_charger_attached_work.work);
2176*8c0984e5SSebastian Reichel 	int mainch = (MAIN_CH_STATUS2_MAINCHGDROP |
2177*8c0984e5SSebastian Reichel 		      MAIN_CH_STATUS2_MAINCHARGERDETDBNC);
2178*8c0984e5SSebastian Reichel 	int ret, i;
2179*8c0984e5SSebastian Reichel 	u8 statval;
2180*8c0984e5SSebastian Reichel 
2181*8c0984e5SSebastian Reichel 	for (i = 0; i < 10; i++) {
2182*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev,
2183*8c0984e5SSebastian Reichel 							AB8500_CHARGER,
2184*8c0984e5SSebastian Reichel 							AB8500_CH_STATUS2_REG,
2185*8c0984e5SSebastian Reichel 							&statval);
2186*8c0984e5SSebastian Reichel 		if (ret < 0) {
2187*8c0984e5SSebastian Reichel 			dev_err(di->dev, "ab8500 read failed %d\n", __LINE__);
2188*8c0984e5SSebastian Reichel 			goto reschedule;
2189*8c0984e5SSebastian Reichel 		}
2190*8c0984e5SSebastian Reichel 
2191*8c0984e5SSebastian Reichel 		if ((statval & mainch) != mainch)
2192*8c0984e5SSebastian Reichel 			goto reschedule;
2193*8c0984e5SSebastian Reichel 
2194*8c0984e5SSebastian Reichel 		msleep(CHARGER_STATUS_POLL);
2195*8c0984e5SSebastian Reichel 	}
2196*8c0984e5SSebastian Reichel 
2197*8c0984e5SSebastian Reichel 	ab8500_charger_ac_en(&di->ac_chg, 0, 0, 0);
2198*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->ac_work);
2199*8c0984e5SSebastian Reichel 
2200*8c0984e5SSebastian Reichel 	mutex_lock(&di->charger_attached_mutex);
2201*8c0984e5SSebastian Reichel 	mutex_unlock(&di->charger_attached_mutex);
2202*8c0984e5SSebastian Reichel 
2203*8c0984e5SSebastian Reichel 	return;
2204*8c0984e5SSebastian Reichel 
2205*8c0984e5SSebastian Reichel reschedule:
2206*8c0984e5SSebastian Reichel 	queue_delayed_work(di->charger_wq,
2207*8c0984e5SSebastian Reichel 			   &di->ac_charger_attached_work,
2208*8c0984e5SSebastian Reichel 			   HZ);
2209*8c0984e5SSebastian Reichel }
2210*8c0984e5SSebastian Reichel 
2211*8c0984e5SSebastian Reichel /**
2212*8c0984e5SSebastian Reichel  * ab8500_charger_detect_usb_type_work() - work to detect USB type
2213*8c0984e5SSebastian Reichel  * @work:	Pointer to the work_struct structure
2214*8c0984e5SSebastian Reichel  *
2215*8c0984e5SSebastian Reichel  * Detect the type of USB plugged
2216*8c0984e5SSebastian Reichel  */
2217*8c0984e5SSebastian Reichel static void ab8500_charger_detect_usb_type_work(struct work_struct *work)
2218*8c0984e5SSebastian Reichel {
2219*8c0984e5SSebastian Reichel 	int ret;
2220*8c0984e5SSebastian Reichel 
2221*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2222*8c0984e5SSebastian Reichel 		struct ab8500_charger, detect_usb_type_work);
2223*8c0984e5SSebastian Reichel 
2224*8c0984e5SSebastian Reichel 	/*
2225*8c0984e5SSebastian Reichel 	 * Since we can't be sure that the events are received
2226*8c0984e5SSebastian Reichel 	 * synchronously, we have the check if is
2227*8c0984e5SSebastian Reichel 	 * connected by reading the status register
2228*8c0984e5SSebastian Reichel 	 */
2229*8c0984e5SSebastian Reichel 	ret = ab8500_charger_detect_chargers(di, false);
2230*8c0984e5SSebastian Reichel 	if (ret < 0)
2231*8c0984e5SSebastian Reichel 		return;
2232*8c0984e5SSebastian Reichel 
2233*8c0984e5SSebastian Reichel 	if (!(ret & USB_PW_CONN)) {
2234*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "%s di->vbus_detected = false\n", __func__);
2235*8c0984e5SSebastian Reichel 		di->vbus_detected = false;
2236*8c0984e5SSebastian Reichel 		ab8500_charger_set_usb_connected(di, false);
2237*8c0984e5SSebastian Reichel 		ab8500_power_supply_changed(di, di->usb_chg.psy);
2238*8c0984e5SSebastian Reichel 	} else {
2239*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "%s di->vbus_detected = true\n", __func__);
2240*8c0984e5SSebastian Reichel 		di->vbus_detected = true;
2241*8c0984e5SSebastian Reichel 
2242*8c0984e5SSebastian Reichel 		if (is_ab8500_1p1_or_earlier(di->parent)) {
2243*8c0984e5SSebastian Reichel 			ret = ab8500_charger_detect_usb_type(di);
2244*8c0984e5SSebastian Reichel 			if (!ret) {
2245*8c0984e5SSebastian Reichel 				ab8500_charger_set_usb_connected(di, true);
2246*8c0984e5SSebastian Reichel 				ab8500_power_supply_changed(di,
2247*8c0984e5SSebastian Reichel 							    di->usb_chg.psy);
2248*8c0984e5SSebastian Reichel 			}
2249*8c0984e5SSebastian Reichel 		} else {
2250*8c0984e5SSebastian Reichel 			/*
2251*8c0984e5SSebastian Reichel 			 * For ABB cut2.0 and onwards we have an IRQ,
2252*8c0984e5SSebastian Reichel 			 * USB_LINK_STATUS that will be triggered when the USB
2253*8c0984e5SSebastian Reichel 			 * link status changes. The exception is USB connected
2254*8c0984e5SSebastian Reichel 			 * during startup. Then we don't get a
2255*8c0984e5SSebastian Reichel 			 * USB_LINK_STATUS IRQ
2256*8c0984e5SSebastian Reichel 			 */
2257*8c0984e5SSebastian Reichel 			if (di->vbus_detected_start) {
2258*8c0984e5SSebastian Reichel 				di->vbus_detected_start = false;
2259*8c0984e5SSebastian Reichel 				ret = ab8500_charger_detect_usb_type(di);
2260*8c0984e5SSebastian Reichel 				if (!ret) {
2261*8c0984e5SSebastian Reichel 					ab8500_charger_set_usb_connected(di,
2262*8c0984e5SSebastian Reichel 						true);
2263*8c0984e5SSebastian Reichel 					ab8500_power_supply_changed(di,
2264*8c0984e5SSebastian Reichel 						di->usb_chg.psy);
2265*8c0984e5SSebastian Reichel 				}
2266*8c0984e5SSebastian Reichel 			}
2267*8c0984e5SSebastian Reichel 		}
2268*8c0984e5SSebastian Reichel 	}
2269*8c0984e5SSebastian Reichel }
2270*8c0984e5SSebastian Reichel 
2271*8c0984e5SSebastian Reichel /**
2272*8c0984e5SSebastian Reichel  * ab8500_charger_usb_link_attach_work() - work to detect USB type
2273*8c0984e5SSebastian Reichel  * @work:	pointer to the work_struct structure
2274*8c0984e5SSebastian Reichel  *
2275*8c0984e5SSebastian Reichel  * Detect the type of USB plugged
2276*8c0984e5SSebastian Reichel  */
2277*8c0984e5SSebastian Reichel static void ab8500_charger_usb_link_attach_work(struct work_struct *work)
2278*8c0984e5SSebastian Reichel {
2279*8c0984e5SSebastian Reichel 	struct ab8500_charger *di =
2280*8c0984e5SSebastian Reichel 		container_of(work, struct ab8500_charger, attach_work.work);
2281*8c0984e5SSebastian Reichel 	int ret;
2282*8c0984e5SSebastian Reichel 
2283*8c0984e5SSebastian Reichel 	/* Update maximum input current if USB enumeration is not detected */
2284*8c0984e5SSebastian Reichel 	if (!di->usb.charger_online) {
2285*8c0984e5SSebastian Reichel 		ret = ab8500_charger_set_vbus_in_curr(di,
2286*8c0984e5SSebastian Reichel 					di->max_usb_in_curr.usb_type_max);
2287*8c0984e5SSebastian Reichel 		if (ret)
2288*8c0984e5SSebastian Reichel 			return;
2289*8c0984e5SSebastian Reichel 	}
2290*8c0984e5SSebastian Reichel 
2291*8c0984e5SSebastian Reichel 	ab8500_charger_set_usb_connected(di, true);
2292*8c0984e5SSebastian Reichel 	ab8500_power_supply_changed(di, di->usb_chg.psy);
2293*8c0984e5SSebastian Reichel }
2294*8c0984e5SSebastian Reichel 
2295*8c0984e5SSebastian Reichel /**
2296*8c0984e5SSebastian Reichel  * ab8500_charger_usb_link_status_work() - work to detect USB type
2297*8c0984e5SSebastian Reichel  * @work:	pointer to the work_struct structure
2298*8c0984e5SSebastian Reichel  *
2299*8c0984e5SSebastian Reichel  * Detect the type of USB plugged
2300*8c0984e5SSebastian Reichel  */
2301*8c0984e5SSebastian Reichel static void ab8500_charger_usb_link_status_work(struct work_struct *work)
2302*8c0984e5SSebastian Reichel {
2303*8c0984e5SSebastian Reichel 	int detected_chargers;
2304*8c0984e5SSebastian Reichel 	int ret;
2305*8c0984e5SSebastian Reichel 	u8 val;
2306*8c0984e5SSebastian Reichel 	u8 link_status;
2307*8c0984e5SSebastian Reichel 
2308*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2309*8c0984e5SSebastian Reichel 		struct ab8500_charger, usb_link_status_work);
2310*8c0984e5SSebastian Reichel 
2311*8c0984e5SSebastian Reichel 	/*
2312*8c0984e5SSebastian Reichel 	 * Since we can't be sure that the events are received
2313*8c0984e5SSebastian Reichel 	 * synchronously, we have the check if  is
2314*8c0984e5SSebastian Reichel 	 * connected by reading the status register
2315*8c0984e5SSebastian Reichel 	 */
2316*8c0984e5SSebastian Reichel 	detected_chargers = ab8500_charger_detect_chargers(di, false);
2317*8c0984e5SSebastian Reichel 	if (detected_chargers < 0)
2318*8c0984e5SSebastian Reichel 		return;
2319*8c0984e5SSebastian Reichel 
2320*8c0984e5SSebastian Reichel 	/*
2321*8c0984e5SSebastian Reichel 	 * Some chargers that breaks the USB spec is
2322*8c0984e5SSebastian Reichel 	 * identified as invalid by AB8500 and it refuse
2323*8c0984e5SSebastian Reichel 	 * to start the charging process. but by jumping
2324*8c0984e5SSebastian Reichel 	 * thru a few hoops it can be forced to start.
2325*8c0984e5SSebastian Reichel 	 */
2326*8c0984e5SSebastian Reichel 	if (is_ab8500(di->parent))
2327*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev, AB8500_USB,
2328*8c0984e5SSebastian Reichel 					AB8500_USB_LINE_STAT_REG, &val);
2329*8c0984e5SSebastian Reichel 	else
2330*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev, AB8500_USB,
2331*8c0984e5SSebastian Reichel 					AB8500_USB_LINK1_STAT_REG, &val);
2332*8c0984e5SSebastian Reichel 
2333*8c0984e5SSebastian Reichel 	if (ret >= 0)
2334*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "UsbLineStatus register = 0x%02x\n", val);
2335*8c0984e5SSebastian Reichel 	else
2336*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "Error reading USB link status\n");
2337*8c0984e5SSebastian Reichel 
2338*8c0984e5SSebastian Reichel 	if (is_ab8500(di->parent))
2339*8c0984e5SSebastian Reichel 		link_status = AB8500_USB_LINK_STATUS;
2340*8c0984e5SSebastian Reichel 	else
2341*8c0984e5SSebastian Reichel 		link_status = AB8505_USB_LINK_STATUS;
2342*8c0984e5SSebastian Reichel 
2343*8c0984e5SSebastian Reichel 	if (detected_chargers & USB_PW_CONN) {
2344*8c0984e5SSebastian Reichel 		if (((val & link_status) >> USB_LINK_STATUS_SHIFT) ==
2345*8c0984e5SSebastian Reichel 				USB_STAT_NOT_VALID_LINK &&
2346*8c0984e5SSebastian Reichel 				di->invalid_charger_detect_state == 0) {
2347*8c0984e5SSebastian Reichel 			dev_dbg(di->dev,
2348*8c0984e5SSebastian Reichel 					"Invalid charger detected, state= 0\n");
2349*8c0984e5SSebastian Reichel 			/*Enable charger*/
2350*8c0984e5SSebastian Reichel 			abx500_mask_and_set_register_interruptible(di->dev,
2351*8c0984e5SSebastian Reichel 					AB8500_CHARGER, AB8500_USBCH_CTRL1_REG,
2352*8c0984e5SSebastian Reichel 					USB_CH_ENA, USB_CH_ENA);
2353*8c0984e5SSebastian Reichel 			/*Enable charger detection*/
2354*8c0984e5SSebastian Reichel 			abx500_mask_and_set_register_interruptible(di->dev,
2355*8c0984e5SSebastian Reichel 					AB8500_USB, AB8500_USB_LINE_CTRL2_REG,
2356*8c0984e5SSebastian Reichel 					USB_CH_DET, USB_CH_DET);
2357*8c0984e5SSebastian Reichel 			di->invalid_charger_detect_state = 1;
2358*8c0984e5SSebastian Reichel 			/*exit and wait for new link status interrupt.*/
2359*8c0984e5SSebastian Reichel 			return;
2360*8c0984e5SSebastian Reichel 
2361*8c0984e5SSebastian Reichel 		}
2362*8c0984e5SSebastian Reichel 		if (di->invalid_charger_detect_state == 1) {
2363*8c0984e5SSebastian Reichel 			dev_dbg(di->dev,
2364*8c0984e5SSebastian Reichel 					"Invalid charger detected, state= 1\n");
2365*8c0984e5SSebastian Reichel 			/*Stop charger detection*/
2366*8c0984e5SSebastian Reichel 			abx500_mask_and_set_register_interruptible(di->dev,
2367*8c0984e5SSebastian Reichel 					AB8500_USB, AB8500_USB_LINE_CTRL2_REG,
2368*8c0984e5SSebastian Reichel 					USB_CH_DET, 0x00);
2369*8c0984e5SSebastian Reichel 			/*Check link status*/
2370*8c0984e5SSebastian Reichel 			if (is_ab8500(di->parent))
2371*8c0984e5SSebastian Reichel 				ret = abx500_get_register_interruptible(di->dev,
2372*8c0984e5SSebastian Reichel 					AB8500_USB, AB8500_USB_LINE_STAT_REG,
2373*8c0984e5SSebastian Reichel 					&val);
2374*8c0984e5SSebastian Reichel 			else
2375*8c0984e5SSebastian Reichel 				ret = abx500_get_register_interruptible(di->dev,
2376*8c0984e5SSebastian Reichel 					AB8500_USB, AB8500_USB_LINK1_STAT_REG,
2377*8c0984e5SSebastian Reichel 					&val);
2378*8c0984e5SSebastian Reichel 
2379*8c0984e5SSebastian Reichel 			dev_dbg(di->dev, "USB link status= 0x%02x\n",
2380*8c0984e5SSebastian Reichel 				(val & link_status) >> USB_LINK_STATUS_SHIFT);
2381*8c0984e5SSebastian Reichel 			di->invalid_charger_detect_state = 2;
2382*8c0984e5SSebastian Reichel 		}
2383*8c0984e5SSebastian Reichel 	} else {
2384*8c0984e5SSebastian Reichel 		di->invalid_charger_detect_state = 0;
2385*8c0984e5SSebastian Reichel 	}
2386*8c0984e5SSebastian Reichel 
2387*8c0984e5SSebastian Reichel 	if (!(detected_chargers & USB_PW_CONN)) {
2388*8c0984e5SSebastian Reichel 		di->vbus_detected = false;
2389*8c0984e5SSebastian Reichel 		ab8500_charger_set_usb_connected(di, false);
2390*8c0984e5SSebastian Reichel 		ab8500_power_supply_changed(di, di->usb_chg.psy);
2391*8c0984e5SSebastian Reichel 		return;
2392*8c0984e5SSebastian Reichel 	}
2393*8c0984e5SSebastian Reichel 
2394*8c0984e5SSebastian Reichel 	dev_dbg(di->dev,"%s di->vbus_detected = true\n",__func__);
2395*8c0984e5SSebastian Reichel 	di->vbus_detected = true;
2396*8c0984e5SSebastian Reichel 	ret = ab8500_charger_read_usb_type(di);
2397*8c0984e5SSebastian Reichel 	if (ret) {
2398*8c0984e5SSebastian Reichel 		if (ret == -ENXIO) {
2399*8c0984e5SSebastian Reichel 			/* No valid charger type detected */
2400*8c0984e5SSebastian Reichel 			ab8500_charger_set_usb_connected(di, false);
2401*8c0984e5SSebastian Reichel 			ab8500_power_supply_changed(di, di->usb_chg.psy);
2402*8c0984e5SSebastian Reichel 		}
2403*8c0984e5SSebastian Reichel 		return;
2404*8c0984e5SSebastian Reichel 	}
2405*8c0984e5SSebastian Reichel 
2406*8c0984e5SSebastian Reichel 	if (di->usb_device_is_unrecognised) {
2407*8c0984e5SSebastian Reichel 		dev_dbg(di->dev,
2408*8c0984e5SSebastian Reichel 			"Potential Legacy Charger device. "
2409*8c0984e5SSebastian Reichel 			"Delay work for %d msec for USB enum "
2410*8c0984e5SSebastian Reichel 			"to finish",
2411*8c0984e5SSebastian Reichel 			WAIT_ACA_RID_ENUMERATION);
2412*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq,
2413*8c0984e5SSebastian Reichel 				   &di->attach_work,
2414*8c0984e5SSebastian Reichel 				   msecs_to_jiffies(WAIT_ACA_RID_ENUMERATION));
2415*8c0984e5SSebastian Reichel 	} else if (di->is_aca_rid == 1) {
2416*8c0984e5SSebastian Reichel 		/* Only wait once */
2417*8c0984e5SSebastian Reichel 		di->is_aca_rid++;
2418*8c0984e5SSebastian Reichel 		dev_dbg(di->dev,
2419*8c0984e5SSebastian Reichel 			"%s Wait %d msec for USB enum to finish",
2420*8c0984e5SSebastian Reichel 			__func__, WAIT_ACA_RID_ENUMERATION);
2421*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq,
2422*8c0984e5SSebastian Reichel 				   &di->attach_work,
2423*8c0984e5SSebastian Reichel 				   msecs_to_jiffies(WAIT_ACA_RID_ENUMERATION));
2424*8c0984e5SSebastian Reichel 	} else {
2425*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq,
2426*8c0984e5SSebastian Reichel 				   &di->attach_work,
2427*8c0984e5SSebastian Reichel 				   0);
2428*8c0984e5SSebastian Reichel 	}
2429*8c0984e5SSebastian Reichel }
2430*8c0984e5SSebastian Reichel 
2431*8c0984e5SSebastian Reichel static void ab8500_charger_usb_state_changed_work(struct work_struct *work)
2432*8c0984e5SSebastian Reichel {
2433*8c0984e5SSebastian Reichel 	int ret;
2434*8c0984e5SSebastian Reichel 	unsigned long flags;
2435*8c0984e5SSebastian Reichel 
2436*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2437*8c0984e5SSebastian Reichel 		struct ab8500_charger, usb_state_changed_work.work);
2438*8c0984e5SSebastian Reichel 
2439*8c0984e5SSebastian Reichel 	if (!di->vbus_detected)	{
2440*8c0984e5SSebastian Reichel 		dev_dbg(di->dev,
2441*8c0984e5SSebastian Reichel 			"%s !di->vbus_detected\n",
2442*8c0984e5SSebastian Reichel 			__func__);
2443*8c0984e5SSebastian Reichel 		return;
2444*8c0984e5SSebastian Reichel 	}
2445*8c0984e5SSebastian Reichel 
2446*8c0984e5SSebastian Reichel 	spin_lock_irqsave(&di->usb_state.usb_lock, flags);
2447*8c0984e5SSebastian Reichel 	di->usb_state.state = di->usb_state.state_tmp;
2448*8c0984e5SSebastian Reichel 	di->usb_state.usb_current = di->usb_state.usb_current_tmp;
2449*8c0984e5SSebastian Reichel 	spin_unlock_irqrestore(&di->usb_state.usb_lock, flags);
2450*8c0984e5SSebastian Reichel 
2451*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "%s USB state: 0x%02x mA: %d\n",
2452*8c0984e5SSebastian Reichel 		__func__, di->usb_state.state, di->usb_state.usb_current);
2453*8c0984e5SSebastian Reichel 
2454*8c0984e5SSebastian Reichel 	switch (di->usb_state.state) {
2455*8c0984e5SSebastian Reichel 	case AB8500_BM_USB_STATE_RESET_HS:
2456*8c0984e5SSebastian Reichel 	case AB8500_BM_USB_STATE_RESET_FS:
2457*8c0984e5SSebastian Reichel 	case AB8500_BM_USB_STATE_SUSPEND:
2458*8c0984e5SSebastian Reichel 	case AB8500_BM_USB_STATE_MAX:
2459*8c0984e5SSebastian Reichel 		ab8500_charger_set_usb_connected(di, false);
2460*8c0984e5SSebastian Reichel 		ab8500_power_supply_changed(di, di->usb_chg.psy);
2461*8c0984e5SSebastian Reichel 		break;
2462*8c0984e5SSebastian Reichel 
2463*8c0984e5SSebastian Reichel 	case AB8500_BM_USB_STATE_RESUME:
2464*8c0984e5SSebastian Reichel 		/*
2465*8c0984e5SSebastian Reichel 		 * when suspend->resume there should be delay
2466*8c0984e5SSebastian Reichel 		 * of 1sec for enabling charging
2467*8c0984e5SSebastian Reichel 		 */
2468*8c0984e5SSebastian Reichel 		msleep(1000);
2469*8c0984e5SSebastian Reichel 		/* Intentional fall through */
2470*8c0984e5SSebastian Reichel 	case AB8500_BM_USB_STATE_CONFIGURED:
2471*8c0984e5SSebastian Reichel 		/*
2472*8c0984e5SSebastian Reichel 		 * USB is configured, enable charging with the charging
2473*8c0984e5SSebastian Reichel 		 * input current obtained from USB driver
2474*8c0984e5SSebastian Reichel 		 */
2475*8c0984e5SSebastian Reichel 		if (!ab8500_charger_get_usb_cur(di)) {
2476*8c0984e5SSebastian Reichel 			/* Update maximum input current */
2477*8c0984e5SSebastian Reichel 			ret = ab8500_charger_set_vbus_in_curr(di,
2478*8c0984e5SSebastian Reichel 					di->max_usb_in_curr.usb_type_max);
2479*8c0984e5SSebastian Reichel 			if (ret)
2480*8c0984e5SSebastian Reichel 				return;
2481*8c0984e5SSebastian Reichel 
2482*8c0984e5SSebastian Reichel 			ab8500_charger_set_usb_connected(di, true);
2483*8c0984e5SSebastian Reichel 			ab8500_power_supply_changed(di, di->usb_chg.psy);
2484*8c0984e5SSebastian Reichel 		}
2485*8c0984e5SSebastian Reichel 		break;
2486*8c0984e5SSebastian Reichel 
2487*8c0984e5SSebastian Reichel 	default:
2488*8c0984e5SSebastian Reichel 		break;
2489*8c0984e5SSebastian Reichel 	};
2490*8c0984e5SSebastian Reichel }
2491*8c0984e5SSebastian Reichel 
2492*8c0984e5SSebastian Reichel /**
2493*8c0984e5SSebastian Reichel  * ab8500_charger_check_usbchargernotok_work() - check USB chg not ok status
2494*8c0984e5SSebastian Reichel  * @work:	pointer to the work_struct structure
2495*8c0984e5SSebastian Reichel  *
2496*8c0984e5SSebastian Reichel  * Work queue function for checking the USB charger Not OK status
2497*8c0984e5SSebastian Reichel  */
2498*8c0984e5SSebastian Reichel static void ab8500_charger_check_usbchargernotok_work(struct work_struct *work)
2499*8c0984e5SSebastian Reichel {
2500*8c0984e5SSebastian Reichel 	int ret;
2501*8c0984e5SSebastian Reichel 	u8 reg_value;
2502*8c0984e5SSebastian Reichel 	bool prev_status;
2503*8c0984e5SSebastian Reichel 
2504*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2505*8c0984e5SSebastian Reichel 		struct ab8500_charger, check_usbchgnotok_work.work);
2506*8c0984e5SSebastian Reichel 
2507*8c0984e5SSebastian Reichel 	/* Check if the status bit for usbchargernotok is still active */
2508*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev,
2509*8c0984e5SSebastian Reichel 		AB8500_CHARGER, AB8500_CH_USBCH_STAT2_REG, &reg_value);
2510*8c0984e5SSebastian Reichel 	if (ret < 0) {
2511*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s ab8500 read failed\n", __func__);
2512*8c0984e5SSebastian Reichel 		return;
2513*8c0984e5SSebastian Reichel 	}
2514*8c0984e5SSebastian Reichel 	prev_status = di->flags.usbchargernotok;
2515*8c0984e5SSebastian Reichel 
2516*8c0984e5SSebastian Reichel 	if (reg_value & VBUS_CH_NOK) {
2517*8c0984e5SSebastian Reichel 		di->flags.usbchargernotok = true;
2518*8c0984e5SSebastian Reichel 		/* Check again in 1sec */
2519*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq,
2520*8c0984e5SSebastian Reichel 			&di->check_usbchgnotok_work, HZ);
2521*8c0984e5SSebastian Reichel 	} else {
2522*8c0984e5SSebastian Reichel 		di->flags.usbchargernotok = false;
2523*8c0984e5SSebastian Reichel 		di->flags.vbus_collapse = false;
2524*8c0984e5SSebastian Reichel 	}
2525*8c0984e5SSebastian Reichel 
2526*8c0984e5SSebastian Reichel 	if (prev_status != di->flags.usbchargernotok)
2527*8c0984e5SSebastian Reichel 		ab8500_power_supply_changed(di, di->usb_chg.psy);
2528*8c0984e5SSebastian Reichel }
2529*8c0984e5SSebastian Reichel 
2530*8c0984e5SSebastian Reichel /**
2531*8c0984e5SSebastian Reichel  * ab8500_charger_check_main_thermal_prot_work() - check main thermal status
2532*8c0984e5SSebastian Reichel  * @work:	pointer to the work_struct structure
2533*8c0984e5SSebastian Reichel  *
2534*8c0984e5SSebastian Reichel  * Work queue function for checking the Main thermal prot status
2535*8c0984e5SSebastian Reichel  */
2536*8c0984e5SSebastian Reichel static void ab8500_charger_check_main_thermal_prot_work(
2537*8c0984e5SSebastian Reichel 	struct work_struct *work)
2538*8c0984e5SSebastian Reichel {
2539*8c0984e5SSebastian Reichel 	int ret;
2540*8c0984e5SSebastian Reichel 	u8 reg_value;
2541*8c0984e5SSebastian Reichel 
2542*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2543*8c0984e5SSebastian Reichel 		struct ab8500_charger, check_main_thermal_prot_work);
2544*8c0984e5SSebastian Reichel 
2545*8c0984e5SSebastian Reichel 	/* Check if the status bit for main_thermal_prot is still active */
2546*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev,
2547*8c0984e5SSebastian Reichel 		AB8500_CHARGER, AB8500_CH_STATUS2_REG, &reg_value);
2548*8c0984e5SSebastian Reichel 	if (ret < 0) {
2549*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s ab8500 read failed\n", __func__);
2550*8c0984e5SSebastian Reichel 		return;
2551*8c0984e5SSebastian Reichel 	}
2552*8c0984e5SSebastian Reichel 	if (reg_value & MAIN_CH_TH_PROT)
2553*8c0984e5SSebastian Reichel 		di->flags.main_thermal_prot = true;
2554*8c0984e5SSebastian Reichel 	else
2555*8c0984e5SSebastian Reichel 		di->flags.main_thermal_prot = false;
2556*8c0984e5SSebastian Reichel 
2557*8c0984e5SSebastian Reichel 	ab8500_power_supply_changed(di, di->ac_chg.psy);
2558*8c0984e5SSebastian Reichel }
2559*8c0984e5SSebastian Reichel 
2560*8c0984e5SSebastian Reichel /**
2561*8c0984e5SSebastian Reichel  * ab8500_charger_check_usb_thermal_prot_work() - check usb thermal status
2562*8c0984e5SSebastian Reichel  * @work:	pointer to the work_struct structure
2563*8c0984e5SSebastian Reichel  *
2564*8c0984e5SSebastian Reichel  * Work queue function for checking the USB thermal prot status
2565*8c0984e5SSebastian Reichel  */
2566*8c0984e5SSebastian Reichel static void ab8500_charger_check_usb_thermal_prot_work(
2567*8c0984e5SSebastian Reichel 	struct work_struct *work)
2568*8c0984e5SSebastian Reichel {
2569*8c0984e5SSebastian Reichel 	int ret;
2570*8c0984e5SSebastian Reichel 	u8 reg_value;
2571*8c0984e5SSebastian Reichel 
2572*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2573*8c0984e5SSebastian Reichel 		struct ab8500_charger, check_usb_thermal_prot_work);
2574*8c0984e5SSebastian Reichel 
2575*8c0984e5SSebastian Reichel 	/* Check if the status bit for usb_thermal_prot is still active */
2576*8c0984e5SSebastian Reichel 	ret = abx500_get_register_interruptible(di->dev,
2577*8c0984e5SSebastian Reichel 		AB8500_CHARGER, AB8500_CH_USBCH_STAT2_REG, &reg_value);
2578*8c0984e5SSebastian Reichel 	if (ret < 0) {
2579*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s ab8500 read failed\n", __func__);
2580*8c0984e5SSebastian Reichel 		return;
2581*8c0984e5SSebastian Reichel 	}
2582*8c0984e5SSebastian Reichel 	if (reg_value & USB_CH_TH_PROT)
2583*8c0984e5SSebastian Reichel 		di->flags.usb_thermal_prot = true;
2584*8c0984e5SSebastian Reichel 	else
2585*8c0984e5SSebastian Reichel 		di->flags.usb_thermal_prot = false;
2586*8c0984e5SSebastian Reichel 
2587*8c0984e5SSebastian Reichel 	ab8500_power_supply_changed(di, di->usb_chg.psy);
2588*8c0984e5SSebastian Reichel }
2589*8c0984e5SSebastian Reichel 
2590*8c0984e5SSebastian Reichel /**
2591*8c0984e5SSebastian Reichel  * ab8500_charger_mainchunplugdet_handler() - main charger unplugged
2592*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2593*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2594*8c0984e5SSebastian Reichel  *
2595*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2596*8c0984e5SSebastian Reichel  */
2597*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_mainchunplugdet_handler(int irq, void *_di)
2598*8c0984e5SSebastian Reichel {
2599*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2600*8c0984e5SSebastian Reichel 
2601*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "Main charger unplugged\n");
2602*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->ac_work);
2603*8c0984e5SSebastian Reichel 
2604*8c0984e5SSebastian Reichel 	cancel_delayed_work_sync(&di->ac_charger_attached_work);
2605*8c0984e5SSebastian Reichel 	mutex_lock(&di->charger_attached_mutex);
2606*8c0984e5SSebastian Reichel 	mutex_unlock(&di->charger_attached_mutex);
2607*8c0984e5SSebastian Reichel 
2608*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2609*8c0984e5SSebastian Reichel }
2610*8c0984e5SSebastian Reichel 
2611*8c0984e5SSebastian Reichel /**
2612*8c0984e5SSebastian Reichel  * ab8500_charger_mainchplugdet_handler() - main charger plugged
2613*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2614*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2615*8c0984e5SSebastian Reichel  *
2616*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2617*8c0984e5SSebastian Reichel  */
2618*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_mainchplugdet_handler(int irq, void *_di)
2619*8c0984e5SSebastian Reichel {
2620*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2621*8c0984e5SSebastian Reichel 
2622*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "Main charger plugged\n");
2623*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->ac_work);
2624*8c0984e5SSebastian Reichel 
2625*8c0984e5SSebastian Reichel 	mutex_lock(&di->charger_attached_mutex);
2626*8c0984e5SSebastian Reichel 	mutex_unlock(&di->charger_attached_mutex);
2627*8c0984e5SSebastian Reichel 
2628*8c0984e5SSebastian Reichel 	if (is_ab8500(di->parent))
2629*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq,
2630*8c0984e5SSebastian Reichel 			   &di->ac_charger_attached_work,
2631*8c0984e5SSebastian Reichel 			   HZ);
2632*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2633*8c0984e5SSebastian Reichel }
2634*8c0984e5SSebastian Reichel 
2635*8c0984e5SSebastian Reichel /**
2636*8c0984e5SSebastian Reichel  * ab8500_charger_mainextchnotok_handler() - main charger not ok
2637*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2638*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2639*8c0984e5SSebastian Reichel  *
2640*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2641*8c0984e5SSebastian Reichel  */
2642*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_mainextchnotok_handler(int irq, void *_di)
2643*8c0984e5SSebastian Reichel {
2644*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2645*8c0984e5SSebastian Reichel 
2646*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "Main charger not ok\n");
2647*8c0984e5SSebastian Reichel 	di->flags.mainextchnotok = true;
2648*8c0984e5SSebastian Reichel 	ab8500_power_supply_changed(di, di->ac_chg.psy);
2649*8c0984e5SSebastian Reichel 
2650*8c0984e5SSebastian Reichel 	/* Schedule a new HW failure check */
2651*8c0984e5SSebastian Reichel 	queue_delayed_work(di->charger_wq, &di->check_hw_failure_work, 0);
2652*8c0984e5SSebastian Reichel 
2653*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2654*8c0984e5SSebastian Reichel }
2655*8c0984e5SSebastian Reichel 
2656*8c0984e5SSebastian Reichel /**
2657*8c0984e5SSebastian Reichel  * ab8500_charger_mainchthprotr_handler() - Die temp is above main charger
2658*8c0984e5SSebastian Reichel  * thermal protection threshold
2659*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2660*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2661*8c0984e5SSebastian Reichel  *
2662*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2663*8c0984e5SSebastian Reichel  */
2664*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_mainchthprotr_handler(int irq, void *_di)
2665*8c0984e5SSebastian Reichel {
2666*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2667*8c0984e5SSebastian Reichel 
2668*8c0984e5SSebastian Reichel 	dev_dbg(di->dev,
2669*8c0984e5SSebastian Reichel 		"Die temp above Main charger thermal protection threshold\n");
2670*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->check_main_thermal_prot_work);
2671*8c0984e5SSebastian Reichel 
2672*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2673*8c0984e5SSebastian Reichel }
2674*8c0984e5SSebastian Reichel 
2675*8c0984e5SSebastian Reichel /**
2676*8c0984e5SSebastian Reichel  * ab8500_charger_mainchthprotf_handler() - Die temp is below main charger
2677*8c0984e5SSebastian Reichel  * thermal protection threshold
2678*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2679*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2680*8c0984e5SSebastian Reichel  *
2681*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2682*8c0984e5SSebastian Reichel  */
2683*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_mainchthprotf_handler(int irq, void *_di)
2684*8c0984e5SSebastian Reichel {
2685*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2686*8c0984e5SSebastian Reichel 
2687*8c0984e5SSebastian Reichel 	dev_dbg(di->dev,
2688*8c0984e5SSebastian Reichel 		"Die temp ok for Main charger thermal protection threshold\n");
2689*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->check_main_thermal_prot_work);
2690*8c0984e5SSebastian Reichel 
2691*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2692*8c0984e5SSebastian Reichel }
2693*8c0984e5SSebastian Reichel 
2694*8c0984e5SSebastian Reichel static void ab8500_charger_vbus_drop_end_work(struct work_struct *work)
2695*8c0984e5SSebastian Reichel {
2696*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = container_of(work,
2697*8c0984e5SSebastian Reichel 		struct ab8500_charger, vbus_drop_end_work.work);
2698*8c0984e5SSebastian Reichel 	int ret, curr;
2699*8c0984e5SSebastian Reichel 	u8 reg_value;
2700*8c0984e5SSebastian Reichel 
2701*8c0984e5SSebastian Reichel 	di->flags.vbus_drop_end = false;
2702*8c0984e5SSebastian Reichel 
2703*8c0984e5SSebastian Reichel 	/* Reset the drop counter */
2704*8c0984e5SSebastian Reichel 	abx500_set_register_interruptible(di->dev,
2705*8c0984e5SSebastian Reichel 				  AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01);
2706*8c0984e5SSebastian Reichel 
2707*8c0984e5SSebastian Reichel 	if (is_ab8540(di->parent))
2708*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
2709*8c0984e5SSebastian Reichel 				AB8540_CH_USBCH_STAT3_REG, &reg_value);
2710*8c0984e5SSebastian Reichel 	else
2711*8c0984e5SSebastian Reichel 		ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
2712*8c0984e5SSebastian Reichel 				AB8500_CH_USBCH_STAT2_REG, &reg_value);
2713*8c0984e5SSebastian Reichel 	if (ret < 0) {
2714*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s read failed\n", __func__);
2715*8c0984e5SSebastian Reichel 		return;
2716*8c0984e5SSebastian Reichel 	}
2717*8c0984e5SSebastian Reichel 
2718*8c0984e5SSebastian Reichel 	if (is_ab8540(di->parent))
2719*8c0984e5SSebastian Reichel 		curr = di->bm->chg_input_curr[
2720*8c0984e5SSebastian Reichel 			reg_value & AB8540_AUTO_VBUS_IN_CURR_MASK];
2721*8c0984e5SSebastian Reichel 	else
2722*8c0984e5SSebastian Reichel 		curr = di->bm->chg_input_curr[
2723*8c0984e5SSebastian Reichel 			reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT];
2724*8c0984e5SSebastian Reichel 
2725*8c0984e5SSebastian Reichel 	if (di->max_usb_in_curr.calculated_max != curr) {
2726*8c0984e5SSebastian Reichel 		/* USB source is collapsing */
2727*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.calculated_max = curr;
2728*8c0984e5SSebastian Reichel 		dev_dbg(di->dev,
2729*8c0984e5SSebastian Reichel 			 "VBUS input current limiting to %d mA\n",
2730*8c0984e5SSebastian Reichel 			 di->max_usb_in_curr.calculated_max);
2731*8c0984e5SSebastian Reichel 	} else {
2732*8c0984e5SSebastian Reichel 		/*
2733*8c0984e5SSebastian Reichel 		 * USB source can not give more than this amount.
2734*8c0984e5SSebastian Reichel 		 * Taking more will collapse the source.
2735*8c0984e5SSebastian Reichel 		 */
2736*8c0984e5SSebastian Reichel 		di->max_usb_in_curr.set_max =
2737*8c0984e5SSebastian Reichel 			di->max_usb_in_curr.calculated_max;
2738*8c0984e5SSebastian Reichel 		dev_dbg(di->dev,
2739*8c0984e5SSebastian Reichel 			 "VBUS input current limited to %d mA\n",
2740*8c0984e5SSebastian Reichel 			 di->max_usb_in_curr.set_max);
2741*8c0984e5SSebastian Reichel 	}
2742*8c0984e5SSebastian Reichel 
2743*8c0984e5SSebastian Reichel 	if (di->usb.charger_connected)
2744*8c0984e5SSebastian Reichel 		ab8500_charger_set_vbus_in_curr(di,
2745*8c0984e5SSebastian Reichel 					di->max_usb_in_curr.usb_type_max);
2746*8c0984e5SSebastian Reichel }
2747*8c0984e5SSebastian Reichel 
2748*8c0984e5SSebastian Reichel /**
2749*8c0984e5SSebastian Reichel  * ab8500_charger_vbusdetf_handler() - VBUS falling detected
2750*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2751*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2752*8c0984e5SSebastian Reichel  *
2753*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2754*8c0984e5SSebastian Reichel  */
2755*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_vbusdetf_handler(int irq, void *_di)
2756*8c0984e5SSebastian Reichel {
2757*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2758*8c0984e5SSebastian Reichel 
2759*8c0984e5SSebastian Reichel 	di->vbus_detected = false;
2760*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "VBUS falling detected\n");
2761*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->detect_usb_type_work);
2762*8c0984e5SSebastian Reichel 
2763*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2764*8c0984e5SSebastian Reichel }
2765*8c0984e5SSebastian Reichel 
2766*8c0984e5SSebastian Reichel /**
2767*8c0984e5SSebastian Reichel  * ab8500_charger_vbusdetr_handler() - VBUS rising detected
2768*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2769*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2770*8c0984e5SSebastian Reichel  *
2771*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2772*8c0984e5SSebastian Reichel  */
2773*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_vbusdetr_handler(int irq, void *_di)
2774*8c0984e5SSebastian Reichel {
2775*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2776*8c0984e5SSebastian Reichel 
2777*8c0984e5SSebastian Reichel 	di->vbus_detected = true;
2778*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "VBUS rising detected\n");
2779*8c0984e5SSebastian Reichel 
2780*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->detect_usb_type_work);
2781*8c0984e5SSebastian Reichel 
2782*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2783*8c0984e5SSebastian Reichel }
2784*8c0984e5SSebastian Reichel 
2785*8c0984e5SSebastian Reichel /**
2786*8c0984e5SSebastian Reichel  * ab8500_charger_usblinkstatus_handler() - USB link status has changed
2787*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2788*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2789*8c0984e5SSebastian Reichel  *
2790*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2791*8c0984e5SSebastian Reichel  */
2792*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_usblinkstatus_handler(int irq, void *_di)
2793*8c0984e5SSebastian Reichel {
2794*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2795*8c0984e5SSebastian Reichel 
2796*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "USB link status changed\n");
2797*8c0984e5SSebastian Reichel 
2798*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->usb_link_status_work);
2799*8c0984e5SSebastian Reichel 
2800*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2801*8c0984e5SSebastian Reichel }
2802*8c0984e5SSebastian Reichel 
2803*8c0984e5SSebastian Reichel /**
2804*8c0984e5SSebastian Reichel  * ab8500_charger_usbchthprotr_handler() - Die temp is above usb charger
2805*8c0984e5SSebastian Reichel  * thermal protection threshold
2806*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2807*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2808*8c0984e5SSebastian Reichel  *
2809*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2810*8c0984e5SSebastian Reichel  */
2811*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_usbchthprotr_handler(int irq, void *_di)
2812*8c0984e5SSebastian Reichel {
2813*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2814*8c0984e5SSebastian Reichel 
2815*8c0984e5SSebastian Reichel 	dev_dbg(di->dev,
2816*8c0984e5SSebastian Reichel 		"Die temp above USB charger thermal protection threshold\n");
2817*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->check_usb_thermal_prot_work);
2818*8c0984e5SSebastian Reichel 
2819*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2820*8c0984e5SSebastian Reichel }
2821*8c0984e5SSebastian Reichel 
2822*8c0984e5SSebastian Reichel /**
2823*8c0984e5SSebastian Reichel  * ab8500_charger_usbchthprotf_handler() - Die temp is below usb charger
2824*8c0984e5SSebastian Reichel  * thermal protection threshold
2825*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2826*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2827*8c0984e5SSebastian Reichel  *
2828*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2829*8c0984e5SSebastian Reichel  */
2830*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_usbchthprotf_handler(int irq, void *_di)
2831*8c0984e5SSebastian Reichel {
2832*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2833*8c0984e5SSebastian Reichel 
2834*8c0984e5SSebastian Reichel 	dev_dbg(di->dev,
2835*8c0984e5SSebastian Reichel 		"Die temp ok for USB charger thermal protection threshold\n");
2836*8c0984e5SSebastian Reichel 	queue_work(di->charger_wq, &di->check_usb_thermal_prot_work);
2837*8c0984e5SSebastian Reichel 
2838*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2839*8c0984e5SSebastian Reichel }
2840*8c0984e5SSebastian Reichel 
2841*8c0984e5SSebastian Reichel /**
2842*8c0984e5SSebastian Reichel  * ab8500_charger_usbchargernotokr_handler() - USB charger not ok detected
2843*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2844*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2845*8c0984e5SSebastian Reichel  *
2846*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2847*8c0984e5SSebastian Reichel  */
2848*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_usbchargernotokr_handler(int irq, void *_di)
2849*8c0984e5SSebastian Reichel {
2850*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2851*8c0984e5SSebastian Reichel 
2852*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "Not allowed USB charger detected\n");
2853*8c0984e5SSebastian Reichel 	queue_delayed_work(di->charger_wq, &di->check_usbchgnotok_work, 0);
2854*8c0984e5SSebastian Reichel 
2855*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2856*8c0984e5SSebastian Reichel }
2857*8c0984e5SSebastian Reichel 
2858*8c0984e5SSebastian Reichel /**
2859*8c0984e5SSebastian Reichel  * ab8500_charger_chwdexp_handler() - Charger watchdog expired
2860*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2861*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2862*8c0984e5SSebastian Reichel  *
2863*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2864*8c0984e5SSebastian Reichel  */
2865*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_chwdexp_handler(int irq, void *_di)
2866*8c0984e5SSebastian Reichel {
2867*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2868*8c0984e5SSebastian Reichel 
2869*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "Charger watchdog expired\n");
2870*8c0984e5SSebastian Reichel 
2871*8c0984e5SSebastian Reichel 	/*
2872*8c0984e5SSebastian Reichel 	 * The charger that was online when the watchdog expired
2873*8c0984e5SSebastian Reichel 	 * needs to be restarted for charging to start again
2874*8c0984e5SSebastian Reichel 	 */
2875*8c0984e5SSebastian Reichel 	if (di->ac.charger_online) {
2876*8c0984e5SSebastian Reichel 		di->ac.wd_expired = true;
2877*8c0984e5SSebastian Reichel 		ab8500_power_supply_changed(di, di->ac_chg.psy);
2878*8c0984e5SSebastian Reichel 	}
2879*8c0984e5SSebastian Reichel 	if (di->usb.charger_online) {
2880*8c0984e5SSebastian Reichel 		di->usb.wd_expired = true;
2881*8c0984e5SSebastian Reichel 		ab8500_power_supply_changed(di, di->usb_chg.psy);
2882*8c0984e5SSebastian Reichel 	}
2883*8c0984e5SSebastian Reichel 
2884*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2885*8c0984e5SSebastian Reichel }
2886*8c0984e5SSebastian Reichel 
2887*8c0984e5SSebastian Reichel /**
2888*8c0984e5SSebastian Reichel  * ab8500_charger_vbuschdropend_handler() - VBUS drop removed
2889*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2890*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2891*8c0984e5SSebastian Reichel  *
2892*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2893*8c0984e5SSebastian Reichel  */
2894*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_vbuschdropend_handler(int irq, void *_di)
2895*8c0984e5SSebastian Reichel {
2896*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2897*8c0984e5SSebastian Reichel 
2898*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "VBUS charger drop ended\n");
2899*8c0984e5SSebastian Reichel 	di->flags.vbus_drop_end = true;
2900*8c0984e5SSebastian Reichel 
2901*8c0984e5SSebastian Reichel 	/*
2902*8c0984e5SSebastian Reichel 	 * VBUS might have dropped due to bad connection.
2903*8c0984e5SSebastian Reichel 	 * Schedule a new input limit set to the value SW requests.
2904*8c0984e5SSebastian Reichel 	 */
2905*8c0984e5SSebastian Reichel 	queue_delayed_work(di->charger_wq, &di->vbus_drop_end_work,
2906*8c0984e5SSebastian Reichel 			   round_jiffies(VBUS_IN_CURR_LIM_RETRY_SET_TIME * HZ));
2907*8c0984e5SSebastian Reichel 
2908*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2909*8c0984e5SSebastian Reichel }
2910*8c0984e5SSebastian Reichel 
2911*8c0984e5SSebastian Reichel /**
2912*8c0984e5SSebastian Reichel  * ab8500_charger_vbusovv_handler() - VBUS overvoltage detected
2913*8c0984e5SSebastian Reichel  * @irq:       interrupt number
2914*8c0984e5SSebastian Reichel  * @_di:       pointer to the ab8500_charger structure
2915*8c0984e5SSebastian Reichel  *
2916*8c0984e5SSebastian Reichel  * Returns IRQ status(IRQ_HANDLED)
2917*8c0984e5SSebastian Reichel  */
2918*8c0984e5SSebastian Reichel static irqreturn_t ab8500_charger_vbusovv_handler(int irq, void *_di)
2919*8c0984e5SSebastian Reichel {
2920*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = _di;
2921*8c0984e5SSebastian Reichel 
2922*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "VBUS overvoltage detected\n");
2923*8c0984e5SSebastian Reichel 	di->flags.vbus_ovv = true;
2924*8c0984e5SSebastian Reichel 	ab8500_power_supply_changed(di, di->usb_chg.psy);
2925*8c0984e5SSebastian Reichel 
2926*8c0984e5SSebastian Reichel 	/* Schedule a new HW failure check */
2927*8c0984e5SSebastian Reichel 	queue_delayed_work(di->charger_wq, &di->check_hw_failure_work, 0);
2928*8c0984e5SSebastian Reichel 
2929*8c0984e5SSebastian Reichel 	return IRQ_HANDLED;
2930*8c0984e5SSebastian Reichel }
2931*8c0984e5SSebastian Reichel 
2932*8c0984e5SSebastian Reichel /**
2933*8c0984e5SSebastian Reichel  * ab8500_charger_ac_get_property() - get the ac/mains properties
2934*8c0984e5SSebastian Reichel  * @psy:       pointer to the power_supply structure
2935*8c0984e5SSebastian Reichel  * @psp:       pointer to the power_supply_property structure
2936*8c0984e5SSebastian Reichel  * @val:       pointer to the power_supply_propval union
2937*8c0984e5SSebastian Reichel  *
2938*8c0984e5SSebastian Reichel  * This function gets called when an application tries to get the ac/mains
2939*8c0984e5SSebastian Reichel  * properties by reading the sysfs files.
2940*8c0984e5SSebastian Reichel  * AC/Mains properties are online, present and voltage.
2941*8c0984e5SSebastian Reichel  * online:     ac/mains charging is in progress or not
2942*8c0984e5SSebastian Reichel  * present:    presence of the ac/mains
2943*8c0984e5SSebastian Reichel  * voltage:    AC/Mains voltage
2944*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
2945*8c0984e5SSebastian Reichel  */
2946*8c0984e5SSebastian Reichel static int ab8500_charger_ac_get_property(struct power_supply *psy,
2947*8c0984e5SSebastian Reichel 	enum power_supply_property psp,
2948*8c0984e5SSebastian Reichel 	union power_supply_propval *val)
2949*8c0984e5SSebastian Reichel {
2950*8c0984e5SSebastian Reichel 	struct ab8500_charger *di;
2951*8c0984e5SSebastian Reichel 	int ret;
2952*8c0984e5SSebastian Reichel 
2953*8c0984e5SSebastian Reichel 	di = to_ab8500_charger_ac_device_info(psy_to_ux500_charger(psy));
2954*8c0984e5SSebastian Reichel 
2955*8c0984e5SSebastian Reichel 	switch (psp) {
2956*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_HEALTH:
2957*8c0984e5SSebastian Reichel 		if (di->flags.mainextchnotok)
2958*8c0984e5SSebastian Reichel 			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
2959*8c0984e5SSebastian Reichel 		else if (di->ac.wd_expired || di->usb.wd_expired)
2960*8c0984e5SSebastian Reichel 			val->intval = POWER_SUPPLY_HEALTH_DEAD;
2961*8c0984e5SSebastian Reichel 		else if (di->flags.main_thermal_prot)
2962*8c0984e5SSebastian Reichel 			val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
2963*8c0984e5SSebastian Reichel 		else
2964*8c0984e5SSebastian Reichel 			val->intval = POWER_SUPPLY_HEALTH_GOOD;
2965*8c0984e5SSebastian Reichel 		break;
2966*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_ONLINE:
2967*8c0984e5SSebastian Reichel 		val->intval = di->ac.charger_online;
2968*8c0984e5SSebastian Reichel 		break;
2969*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_PRESENT:
2970*8c0984e5SSebastian Reichel 		val->intval = di->ac.charger_connected;
2971*8c0984e5SSebastian Reichel 		break;
2972*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
2973*8c0984e5SSebastian Reichel 		ret = ab8500_charger_get_ac_voltage(di);
2974*8c0984e5SSebastian Reichel 		if (ret >= 0)
2975*8c0984e5SSebastian Reichel 			di->ac.charger_voltage = ret;
2976*8c0984e5SSebastian Reichel 		/* On error, use previous value */
2977*8c0984e5SSebastian Reichel 		val->intval = di->ac.charger_voltage * 1000;
2978*8c0984e5SSebastian Reichel 		break;
2979*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
2980*8c0984e5SSebastian Reichel 		/*
2981*8c0984e5SSebastian Reichel 		 * This property is used to indicate when CV mode is entered
2982*8c0984e5SSebastian Reichel 		 * for the AC charger
2983*8c0984e5SSebastian Reichel 		 */
2984*8c0984e5SSebastian Reichel 		di->ac.cv_active = ab8500_charger_ac_cv(di);
2985*8c0984e5SSebastian Reichel 		val->intval = di->ac.cv_active;
2986*8c0984e5SSebastian Reichel 		break;
2987*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_CURRENT_NOW:
2988*8c0984e5SSebastian Reichel 		ret = ab8500_charger_get_ac_current(di);
2989*8c0984e5SSebastian Reichel 		if (ret >= 0)
2990*8c0984e5SSebastian Reichel 			di->ac.charger_current = ret;
2991*8c0984e5SSebastian Reichel 		val->intval = di->ac.charger_current * 1000;
2992*8c0984e5SSebastian Reichel 		break;
2993*8c0984e5SSebastian Reichel 	default:
2994*8c0984e5SSebastian Reichel 		return -EINVAL;
2995*8c0984e5SSebastian Reichel 	}
2996*8c0984e5SSebastian Reichel 	return 0;
2997*8c0984e5SSebastian Reichel }
2998*8c0984e5SSebastian Reichel 
2999*8c0984e5SSebastian Reichel /**
3000*8c0984e5SSebastian Reichel  * ab8500_charger_usb_get_property() - get the usb properties
3001*8c0984e5SSebastian Reichel  * @psy:        pointer to the power_supply structure
3002*8c0984e5SSebastian Reichel  * @psp:        pointer to the power_supply_property structure
3003*8c0984e5SSebastian Reichel  * @val:        pointer to the power_supply_propval union
3004*8c0984e5SSebastian Reichel  *
3005*8c0984e5SSebastian Reichel  * This function gets called when an application tries to get the usb
3006*8c0984e5SSebastian Reichel  * properties by reading the sysfs files.
3007*8c0984e5SSebastian Reichel  * USB properties are online, present and voltage.
3008*8c0984e5SSebastian Reichel  * online:     usb charging is in progress or not
3009*8c0984e5SSebastian Reichel  * present:    presence of the usb
3010*8c0984e5SSebastian Reichel  * voltage:    vbus voltage
3011*8c0984e5SSebastian Reichel  * Returns error code in case of failure else 0(on success)
3012*8c0984e5SSebastian Reichel  */
3013*8c0984e5SSebastian Reichel static int ab8500_charger_usb_get_property(struct power_supply *psy,
3014*8c0984e5SSebastian Reichel 	enum power_supply_property psp,
3015*8c0984e5SSebastian Reichel 	union power_supply_propval *val)
3016*8c0984e5SSebastian Reichel {
3017*8c0984e5SSebastian Reichel 	struct ab8500_charger *di;
3018*8c0984e5SSebastian Reichel 	int ret;
3019*8c0984e5SSebastian Reichel 
3020*8c0984e5SSebastian Reichel 	di = to_ab8500_charger_usb_device_info(psy_to_ux500_charger(psy));
3021*8c0984e5SSebastian Reichel 
3022*8c0984e5SSebastian Reichel 	switch (psp) {
3023*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_HEALTH:
3024*8c0984e5SSebastian Reichel 		if (di->flags.usbchargernotok)
3025*8c0984e5SSebastian Reichel 			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
3026*8c0984e5SSebastian Reichel 		else if (di->ac.wd_expired || di->usb.wd_expired)
3027*8c0984e5SSebastian Reichel 			val->intval = POWER_SUPPLY_HEALTH_DEAD;
3028*8c0984e5SSebastian Reichel 		else if (di->flags.usb_thermal_prot)
3029*8c0984e5SSebastian Reichel 			val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
3030*8c0984e5SSebastian Reichel 		else if (di->flags.vbus_ovv)
3031*8c0984e5SSebastian Reichel 			val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
3032*8c0984e5SSebastian Reichel 		else
3033*8c0984e5SSebastian Reichel 			val->intval = POWER_SUPPLY_HEALTH_GOOD;
3034*8c0984e5SSebastian Reichel 		break;
3035*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_ONLINE:
3036*8c0984e5SSebastian Reichel 		val->intval = di->usb.charger_online;
3037*8c0984e5SSebastian Reichel 		break;
3038*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_PRESENT:
3039*8c0984e5SSebastian Reichel 		val->intval = di->usb.charger_connected;
3040*8c0984e5SSebastian Reichel 		break;
3041*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
3042*8c0984e5SSebastian Reichel 		ret = ab8500_charger_get_vbus_voltage(di);
3043*8c0984e5SSebastian Reichel 		if (ret >= 0)
3044*8c0984e5SSebastian Reichel 			di->usb.charger_voltage = ret;
3045*8c0984e5SSebastian Reichel 		val->intval = di->usb.charger_voltage * 1000;
3046*8c0984e5SSebastian Reichel 		break;
3047*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
3048*8c0984e5SSebastian Reichel 		/*
3049*8c0984e5SSebastian Reichel 		 * This property is used to indicate when CV mode is entered
3050*8c0984e5SSebastian Reichel 		 * for the USB charger
3051*8c0984e5SSebastian Reichel 		 */
3052*8c0984e5SSebastian Reichel 		di->usb.cv_active = ab8500_charger_usb_cv(di);
3053*8c0984e5SSebastian Reichel 		val->intval = di->usb.cv_active;
3054*8c0984e5SSebastian Reichel 		break;
3055*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_CURRENT_NOW:
3056*8c0984e5SSebastian Reichel 		ret = ab8500_charger_get_usb_current(di);
3057*8c0984e5SSebastian Reichel 		if (ret >= 0)
3058*8c0984e5SSebastian Reichel 			di->usb.charger_current = ret;
3059*8c0984e5SSebastian Reichel 		val->intval = di->usb.charger_current * 1000;
3060*8c0984e5SSebastian Reichel 		break;
3061*8c0984e5SSebastian Reichel 	case POWER_SUPPLY_PROP_CURRENT_AVG:
3062*8c0984e5SSebastian Reichel 		/*
3063*8c0984e5SSebastian Reichel 		 * This property is used to indicate when VBUS has collapsed
3064*8c0984e5SSebastian Reichel 		 * due to too high output current from the USB charger
3065*8c0984e5SSebastian Reichel 		 */
3066*8c0984e5SSebastian Reichel 		if (di->flags.vbus_collapse)
3067*8c0984e5SSebastian Reichel 			val->intval = 1;
3068*8c0984e5SSebastian Reichel 		else
3069*8c0984e5SSebastian Reichel 			val->intval = 0;
3070*8c0984e5SSebastian Reichel 		break;
3071*8c0984e5SSebastian Reichel 	default:
3072*8c0984e5SSebastian Reichel 		return -EINVAL;
3073*8c0984e5SSebastian Reichel 	}
3074*8c0984e5SSebastian Reichel 	return 0;
3075*8c0984e5SSebastian Reichel }
3076*8c0984e5SSebastian Reichel 
3077*8c0984e5SSebastian Reichel /**
3078*8c0984e5SSebastian Reichel  * ab8500_charger_init_hw_registers() - Set up charger related registers
3079*8c0984e5SSebastian Reichel  * @di:		pointer to the ab8500_charger structure
3080*8c0984e5SSebastian Reichel  *
3081*8c0984e5SSebastian Reichel  * Set up charger OVV, watchdog and maximum voltage registers as well as
3082*8c0984e5SSebastian Reichel  * charging of the backup battery
3083*8c0984e5SSebastian Reichel  */
3084*8c0984e5SSebastian Reichel static int ab8500_charger_init_hw_registers(struct ab8500_charger *di)
3085*8c0984e5SSebastian Reichel {
3086*8c0984e5SSebastian Reichel 	int ret = 0;
3087*8c0984e5SSebastian Reichel 	u8 bup_vch_range = 0, vbup33_vrtcn = 0;
3088*8c0984e5SSebastian Reichel 
3089*8c0984e5SSebastian Reichel 	/* Setup maximum charger current and voltage for ABB cut2.0 */
3090*8c0984e5SSebastian Reichel 	if (!is_ab8500_1p1_or_earlier(di->parent)) {
3091*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev,
3092*8c0984e5SSebastian Reichel 			AB8500_CHARGER,
3093*8c0984e5SSebastian Reichel 			AB8500_CH_VOLT_LVL_MAX_REG, CH_VOL_LVL_4P6);
3094*8c0984e5SSebastian Reichel 		if (ret) {
3095*8c0984e5SSebastian Reichel 			dev_err(di->dev,
3096*8c0984e5SSebastian Reichel 				"failed to set CH_VOLT_LVL_MAX_REG\n");
3097*8c0984e5SSebastian Reichel 			goto out;
3098*8c0984e5SSebastian Reichel 		}
3099*8c0984e5SSebastian Reichel 
3100*8c0984e5SSebastian Reichel 		if (is_ab8540(di->parent))
3101*8c0984e5SSebastian Reichel 			ret = abx500_set_register_interruptible(di->dev,
3102*8c0984e5SSebastian Reichel 				AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG,
3103*8c0984e5SSebastian Reichel 				CH_OP_CUR_LVL_2P);
3104*8c0984e5SSebastian Reichel 		else
3105*8c0984e5SSebastian Reichel 			ret = abx500_set_register_interruptible(di->dev,
3106*8c0984e5SSebastian Reichel 				AB8500_CHARGER, AB8500_CH_OPT_CRNTLVL_MAX_REG,
3107*8c0984e5SSebastian Reichel 				CH_OP_CUR_LVL_1P6);
3108*8c0984e5SSebastian Reichel 		if (ret) {
3109*8c0984e5SSebastian Reichel 			dev_err(di->dev,
3110*8c0984e5SSebastian Reichel 				"failed to set CH_OPT_CRNTLVL_MAX_REG\n");
3111*8c0984e5SSebastian Reichel 			goto out;
3112*8c0984e5SSebastian Reichel 		}
3113*8c0984e5SSebastian Reichel 	}
3114*8c0984e5SSebastian Reichel 
3115*8c0984e5SSebastian Reichel 	if (is_ab9540_2p0(di->parent) || is_ab9540_3p0(di->parent)
3116*8c0984e5SSebastian Reichel 	 || is_ab8505_2p0(di->parent) || is_ab8540(di->parent))
3117*8c0984e5SSebastian Reichel 		ret = abx500_mask_and_set_register_interruptible(di->dev,
3118*8c0984e5SSebastian Reichel 			AB8500_CHARGER,
3119*8c0984e5SSebastian Reichel 			AB8500_USBCH_CTRL2_REG,
3120*8c0984e5SSebastian Reichel 			VBUS_AUTO_IN_CURR_LIM_ENA,
3121*8c0984e5SSebastian Reichel 			VBUS_AUTO_IN_CURR_LIM_ENA);
3122*8c0984e5SSebastian Reichel 	else
3123*8c0984e5SSebastian Reichel 		/*
3124*8c0984e5SSebastian Reichel 		 * VBUS OVV set to 6.3V and enable automatic current limitation
3125*8c0984e5SSebastian Reichel 		 */
3126*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev,
3127*8c0984e5SSebastian Reichel 			AB8500_CHARGER,
3128*8c0984e5SSebastian Reichel 			AB8500_USBCH_CTRL2_REG,
3129*8c0984e5SSebastian Reichel 			VBUS_OVV_SELECT_6P3V | VBUS_AUTO_IN_CURR_LIM_ENA);
3130*8c0984e5SSebastian Reichel 	if (ret) {
3131*8c0984e5SSebastian Reichel 		dev_err(di->dev,
3132*8c0984e5SSebastian Reichel 			"failed to set automatic current limitation\n");
3133*8c0984e5SSebastian Reichel 		goto out;
3134*8c0984e5SSebastian Reichel 	}
3135*8c0984e5SSebastian Reichel 
3136*8c0984e5SSebastian Reichel 	/* Enable main watchdog in OTP */
3137*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev,
3138*8c0984e5SSebastian Reichel 		AB8500_OTP_EMUL, AB8500_OTP_CONF_15, OTP_ENABLE_WD);
3139*8c0984e5SSebastian Reichel 	if (ret) {
3140*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to enable main WD in OTP\n");
3141*8c0984e5SSebastian Reichel 		goto out;
3142*8c0984e5SSebastian Reichel 	}
3143*8c0984e5SSebastian Reichel 
3144*8c0984e5SSebastian Reichel 	/* Enable main watchdog */
3145*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev,
3146*8c0984e5SSebastian Reichel 		AB8500_SYS_CTRL2_BLOCK,
3147*8c0984e5SSebastian Reichel 		AB8500_MAIN_WDOG_CTRL_REG, MAIN_WDOG_ENA);
3148*8c0984e5SSebastian Reichel 	if (ret) {
3149*8c0984e5SSebastian Reichel 		dev_err(di->dev, "faile to enable main watchdog\n");
3150*8c0984e5SSebastian Reichel 		goto out;
3151*8c0984e5SSebastian Reichel 	}
3152*8c0984e5SSebastian Reichel 
3153*8c0984e5SSebastian Reichel 	/*
3154*8c0984e5SSebastian Reichel 	 * Due to internal synchronisation, Enable and Kick watchdog bits
3155*8c0984e5SSebastian Reichel 	 * cannot be enabled in a single write.
3156*8c0984e5SSebastian Reichel 	 * A minimum delay of 2*32 kHz period (62.5µs) must be inserted
3157*8c0984e5SSebastian Reichel 	 * between writing Enable then Kick bits.
3158*8c0984e5SSebastian Reichel 	 */
3159*8c0984e5SSebastian Reichel 	udelay(63);
3160*8c0984e5SSebastian Reichel 
3161*8c0984e5SSebastian Reichel 	/* Kick main watchdog */
3162*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev,
3163*8c0984e5SSebastian Reichel 		AB8500_SYS_CTRL2_BLOCK,
3164*8c0984e5SSebastian Reichel 		AB8500_MAIN_WDOG_CTRL_REG,
3165*8c0984e5SSebastian Reichel 		(MAIN_WDOG_ENA | MAIN_WDOG_KICK));
3166*8c0984e5SSebastian Reichel 	if (ret) {
3167*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to kick main watchdog\n");
3168*8c0984e5SSebastian Reichel 		goto out;
3169*8c0984e5SSebastian Reichel 	}
3170*8c0984e5SSebastian Reichel 
3171*8c0984e5SSebastian Reichel 	/* Disable main watchdog */
3172*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev,
3173*8c0984e5SSebastian Reichel 		AB8500_SYS_CTRL2_BLOCK,
3174*8c0984e5SSebastian Reichel 		AB8500_MAIN_WDOG_CTRL_REG, MAIN_WDOG_DIS);
3175*8c0984e5SSebastian Reichel 	if (ret) {
3176*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to disable main watchdog\n");
3177*8c0984e5SSebastian Reichel 		goto out;
3178*8c0984e5SSebastian Reichel 	}
3179*8c0984e5SSebastian Reichel 
3180*8c0984e5SSebastian Reichel 	/* Set watchdog timeout */
3181*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
3182*8c0984e5SSebastian Reichel 		AB8500_CH_WD_TIMER_REG, WD_TIMER);
3183*8c0984e5SSebastian Reichel 	if (ret) {
3184*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to set charger watchdog timeout\n");
3185*8c0984e5SSebastian Reichel 		goto out;
3186*8c0984e5SSebastian Reichel 	}
3187*8c0984e5SSebastian Reichel 
3188*8c0984e5SSebastian Reichel 	ret = ab8500_charger_led_en(di, false);
3189*8c0984e5SSebastian Reichel 	if (ret < 0) {
3190*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to disable LED\n");
3191*8c0984e5SSebastian Reichel 		goto out;
3192*8c0984e5SSebastian Reichel 	}
3193*8c0984e5SSebastian Reichel 
3194*8c0984e5SSebastian Reichel 	/* Backup battery voltage and current */
3195*8c0984e5SSebastian Reichel 	if (di->bm->bkup_bat_v > BUP_VCH_SEL_3P1V)
3196*8c0984e5SSebastian Reichel 		bup_vch_range = BUP_VCH_RANGE;
3197*8c0984e5SSebastian Reichel 	if (di->bm->bkup_bat_v == BUP_VCH_SEL_3P3V)
3198*8c0984e5SSebastian Reichel 		vbup33_vrtcn = VBUP33_VRTCN;
3199*8c0984e5SSebastian Reichel 
3200*8c0984e5SSebastian Reichel 	ret = abx500_set_register_interruptible(di->dev,
3201*8c0984e5SSebastian Reichel 		AB8500_RTC,
3202*8c0984e5SSebastian Reichel 		AB8500_RTC_BACKUP_CHG_REG,
3203*8c0984e5SSebastian Reichel 		(di->bm->bkup_bat_v & 0x3) | di->bm->bkup_bat_i);
3204*8c0984e5SSebastian Reichel 	if (ret) {
3205*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to setup backup battery charging\n");
3206*8c0984e5SSebastian Reichel 		goto out;
3207*8c0984e5SSebastian Reichel 	}
3208*8c0984e5SSebastian Reichel 	if (is_ab8540(di->parent)) {
3209*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev,
3210*8c0984e5SSebastian Reichel 			AB8500_RTC,
3211*8c0984e5SSebastian Reichel 			AB8500_RTC_CTRL1_REG,
3212*8c0984e5SSebastian Reichel 			bup_vch_range | vbup33_vrtcn);
3213*8c0984e5SSebastian Reichel 		if (ret) {
3214*8c0984e5SSebastian Reichel 			dev_err(di->dev,
3215*8c0984e5SSebastian Reichel 				"failed to setup backup battery charging\n");
3216*8c0984e5SSebastian Reichel 			goto out;
3217*8c0984e5SSebastian Reichel 		}
3218*8c0984e5SSebastian Reichel 	}
3219*8c0984e5SSebastian Reichel 
3220*8c0984e5SSebastian Reichel 	/* Enable backup battery charging */
3221*8c0984e5SSebastian Reichel 	abx500_mask_and_set_register_interruptible(di->dev,
3222*8c0984e5SSebastian Reichel 		AB8500_RTC, AB8500_RTC_CTRL_REG,
3223*8c0984e5SSebastian Reichel 		RTC_BUP_CH_ENA, RTC_BUP_CH_ENA);
3224*8c0984e5SSebastian Reichel 	if (ret < 0)
3225*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s mask and set failed\n", __func__);
3226*8c0984e5SSebastian Reichel 
3227*8c0984e5SSebastian Reichel 	if (is_ab8540(di->parent)) {
3228*8c0984e5SSebastian Reichel 		ret = abx500_mask_and_set_register_interruptible(di->dev,
3229*8c0984e5SSebastian Reichel 			AB8500_CHARGER, AB8540_USB_PP_MODE_REG,
3230*8c0984e5SSebastian Reichel 			BUS_VSYS_VOL_SELECT_MASK, BUS_VSYS_VOL_SELECT_3P6V);
3231*8c0984e5SSebastian Reichel 		if (ret) {
3232*8c0984e5SSebastian Reichel 			dev_err(di->dev,
3233*8c0984e5SSebastian Reichel 				"failed to setup usb power path vsys voltage\n");
3234*8c0984e5SSebastian Reichel 			goto out;
3235*8c0984e5SSebastian Reichel 		}
3236*8c0984e5SSebastian Reichel 		ret = abx500_mask_and_set_register_interruptible(di->dev,
3237*8c0984e5SSebastian Reichel 			AB8500_CHARGER, AB8540_USB_PP_CHR_REG,
3238*8c0984e5SSebastian Reichel 			BUS_PP_PRECHG_CURRENT_MASK, 0);
3239*8c0984e5SSebastian Reichel 		if (ret) {
3240*8c0984e5SSebastian Reichel 			dev_err(di->dev,
3241*8c0984e5SSebastian Reichel 				"failed to setup usb power path prechage current\n");
3242*8c0984e5SSebastian Reichel 			goto out;
3243*8c0984e5SSebastian Reichel 		}
3244*8c0984e5SSebastian Reichel 	}
3245*8c0984e5SSebastian Reichel 
3246*8c0984e5SSebastian Reichel out:
3247*8c0984e5SSebastian Reichel 	return ret;
3248*8c0984e5SSebastian Reichel }
3249*8c0984e5SSebastian Reichel 
3250*8c0984e5SSebastian Reichel /*
3251*8c0984e5SSebastian Reichel  * ab8500 charger driver interrupts and their respective isr
3252*8c0984e5SSebastian Reichel  */
3253*8c0984e5SSebastian Reichel static struct ab8500_charger_interrupts ab8500_charger_irq[] = {
3254*8c0984e5SSebastian Reichel 	{"MAIN_CH_UNPLUG_DET", ab8500_charger_mainchunplugdet_handler},
3255*8c0984e5SSebastian Reichel 	{"MAIN_CHARGE_PLUG_DET", ab8500_charger_mainchplugdet_handler},
3256*8c0984e5SSebastian Reichel 	{"MAIN_EXT_CH_NOT_OK", ab8500_charger_mainextchnotok_handler},
3257*8c0984e5SSebastian Reichel 	{"MAIN_CH_TH_PROT_R", ab8500_charger_mainchthprotr_handler},
3258*8c0984e5SSebastian Reichel 	{"MAIN_CH_TH_PROT_F", ab8500_charger_mainchthprotf_handler},
3259*8c0984e5SSebastian Reichel 	{"VBUS_DET_F", ab8500_charger_vbusdetf_handler},
3260*8c0984e5SSebastian Reichel 	{"VBUS_DET_R", ab8500_charger_vbusdetr_handler},
3261*8c0984e5SSebastian Reichel 	{"USB_LINK_STATUS", ab8500_charger_usblinkstatus_handler},
3262*8c0984e5SSebastian Reichel 	{"USB_CH_TH_PROT_R", ab8500_charger_usbchthprotr_handler},
3263*8c0984e5SSebastian Reichel 	{"USB_CH_TH_PROT_F", ab8500_charger_usbchthprotf_handler},
3264*8c0984e5SSebastian Reichel 	{"USB_CHARGER_NOT_OKR", ab8500_charger_usbchargernotokr_handler},
3265*8c0984e5SSebastian Reichel 	{"VBUS_OVV", ab8500_charger_vbusovv_handler},
3266*8c0984e5SSebastian Reichel 	{"CH_WD_EXP", ab8500_charger_chwdexp_handler},
3267*8c0984e5SSebastian Reichel 	{"VBUS_CH_DROP_END", ab8500_charger_vbuschdropend_handler},
3268*8c0984e5SSebastian Reichel };
3269*8c0984e5SSebastian Reichel 
3270*8c0984e5SSebastian Reichel static int ab8500_charger_usb_notifier_call(struct notifier_block *nb,
3271*8c0984e5SSebastian Reichel 		unsigned long event, void *power)
3272*8c0984e5SSebastian Reichel {
3273*8c0984e5SSebastian Reichel 	struct ab8500_charger *di =
3274*8c0984e5SSebastian Reichel 		container_of(nb, struct ab8500_charger, nb);
3275*8c0984e5SSebastian Reichel 	enum ab8500_usb_state bm_usb_state;
3276*8c0984e5SSebastian Reichel 	unsigned mA = *((unsigned *)power);
3277*8c0984e5SSebastian Reichel 
3278*8c0984e5SSebastian Reichel 	if (!di)
3279*8c0984e5SSebastian Reichel 		return NOTIFY_DONE;
3280*8c0984e5SSebastian Reichel 
3281*8c0984e5SSebastian Reichel 	if (event != USB_EVENT_VBUS) {
3282*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "not a standard host, returning\n");
3283*8c0984e5SSebastian Reichel 		return NOTIFY_DONE;
3284*8c0984e5SSebastian Reichel 	}
3285*8c0984e5SSebastian Reichel 
3286*8c0984e5SSebastian Reichel 	/* TODO: State is fabricate  here. See if charger really needs USB
3287*8c0984e5SSebastian Reichel 	 * state or if mA is enough
3288*8c0984e5SSebastian Reichel 	 */
3289*8c0984e5SSebastian Reichel 	if ((di->usb_state.usb_current == 2) && (mA > 2))
3290*8c0984e5SSebastian Reichel 		bm_usb_state = AB8500_BM_USB_STATE_RESUME;
3291*8c0984e5SSebastian Reichel 	else if (mA == 0)
3292*8c0984e5SSebastian Reichel 		bm_usb_state = AB8500_BM_USB_STATE_RESET_HS;
3293*8c0984e5SSebastian Reichel 	else if (mA == 2)
3294*8c0984e5SSebastian Reichel 		bm_usb_state = AB8500_BM_USB_STATE_SUSPEND;
3295*8c0984e5SSebastian Reichel 	else if (mA >= 8) /* 8, 100, 500 */
3296*8c0984e5SSebastian Reichel 		bm_usb_state = AB8500_BM_USB_STATE_CONFIGURED;
3297*8c0984e5SSebastian Reichel 	else /* Should never occur */
3298*8c0984e5SSebastian Reichel 		bm_usb_state = AB8500_BM_USB_STATE_RESET_FS;
3299*8c0984e5SSebastian Reichel 
3300*8c0984e5SSebastian Reichel 	dev_dbg(di->dev, "%s usb_state: 0x%02x mA: %d\n",
3301*8c0984e5SSebastian Reichel 		__func__, bm_usb_state, mA);
3302*8c0984e5SSebastian Reichel 
3303*8c0984e5SSebastian Reichel 	spin_lock(&di->usb_state.usb_lock);
3304*8c0984e5SSebastian Reichel 	di->usb_state.state_tmp = bm_usb_state;
3305*8c0984e5SSebastian Reichel 	di->usb_state.usb_current_tmp = mA;
3306*8c0984e5SSebastian Reichel 	spin_unlock(&di->usb_state.usb_lock);
3307*8c0984e5SSebastian Reichel 
3308*8c0984e5SSebastian Reichel 	/*
3309*8c0984e5SSebastian Reichel 	 * wait for some time until you get updates from the usb stack
3310*8c0984e5SSebastian Reichel 	 * and negotiations are completed
3311*8c0984e5SSebastian Reichel 	 */
3312*8c0984e5SSebastian Reichel 	queue_delayed_work(di->charger_wq, &di->usb_state_changed_work, HZ/2);
3313*8c0984e5SSebastian Reichel 
3314*8c0984e5SSebastian Reichel 	return NOTIFY_OK;
3315*8c0984e5SSebastian Reichel }
3316*8c0984e5SSebastian Reichel 
3317*8c0984e5SSebastian Reichel #if defined(CONFIG_PM)
3318*8c0984e5SSebastian Reichel static int ab8500_charger_resume(struct platform_device *pdev)
3319*8c0984e5SSebastian Reichel {
3320*8c0984e5SSebastian Reichel 	int ret;
3321*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = platform_get_drvdata(pdev);
3322*8c0984e5SSebastian Reichel 
3323*8c0984e5SSebastian Reichel 	/*
3324*8c0984e5SSebastian Reichel 	 * For ABB revision 1.0 and 1.1 there is a bug in the watchdog
3325*8c0984e5SSebastian Reichel 	 * logic. That means we have to continously kick the charger
3326*8c0984e5SSebastian Reichel 	 * watchdog even when no charger is connected. This is only
3327*8c0984e5SSebastian Reichel 	 * valid once the AC charger has been enabled. This is
3328*8c0984e5SSebastian Reichel 	 * a bug that is not handled by the algorithm and the
3329*8c0984e5SSebastian Reichel 	 * watchdog have to be kicked by the charger driver
3330*8c0984e5SSebastian Reichel 	 * when the AC charger is disabled
3331*8c0984e5SSebastian Reichel 	 */
3332*8c0984e5SSebastian Reichel 	if (di->ac_conn && is_ab8500_1p1_or_earlier(di->parent)) {
3333*8c0984e5SSebastian Reichel 		ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
3334*8c0984e5SSebastian Reichel 			AB8500_CHARG_WD_CTRL, CHARG_WD_KICK);
3335*8c0984e5SSebastian Reichel 		if (ret)
3336*8c0984e5SSebastian Reichel 			dev_err(di->dev, "Failed to kick WD!\n");
3337*8c0984e5SSebastian Reichel 
3338*8c0984e5SSebastian Reichel 		/* If not already pending start a new timer */
3339*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq, &di->kick_wd_work,
3340*8c0984e5SSebastian Reichel 				   round_jiffies(WD_KICK_INTERVAL));
3341*8c0984e5SSebastian Reichel 	}
3342*8c0984e5SSebastian Reichel 
3343*8c0984e5SSebastian Reichel 	/* If we still have a HW failure, schedule a new check */
3344*8c0984e5SSebastian Reichel 	if (di->flags.mainextchnotok || di->flags.vbus_ovv) {
3345*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq,
3346*8c0984e5SSebastian Reichel 			&di->check_hw_failure_work, 0);
3347*8c0984e5SSebastian Reichel 	}
3348*8c0984e5SSebastian Reichel 
3349*8c0984e5SSebastian Reichel 	if (di->flags.vbus_drop_end)
3350*8c0984e5SSebastian Reichel 		queue_delayed_work(di->charger_wq, &di->vbus_drop_end_work, 0);
3351*8c0984e5SSebastian Reichel 
3352*8c0984e5SSebastian Reichel 	return 0;
3353*8c0984e5SSebastian Reichel }
3354*8c0984e5SSebastian Reichel 
3355*8c0984e5SSebastian Reichel static int ab8500_charger_suspend(struct platform_device *pdev,
3356*8c0984e5SSebastian Reichel 	pm_message_t state)
3357*8c0984e5SSebastian Reichel {
3358*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = platform_get_drvdata(pdev);
3359*8c0984e5SSebastian Reichel 
3360*8c0984e5SSebastian Reichel 	/* Cancel any pending jobs */
3361*8c0984e5SSebastian Reichel 	cancel_delayed_work(&di->check_hw_failure_work);
3362*8c0984e5SSebastian Reichel 	cancel_delayed_work(&di->vbus_drop_end_work);
3363*8c0984e5SSebastian Reichel 
3364*8c0984e5SSebastian Reichel 	flush_delayed_work(&di->attach_work);
3365*8c0984e5SSebastian Reichel 	flush_delayed_work(&di->usb_charger_attached_work);
3366*8c0984e5SSebastian Reichel 	flush_delayed_work(&di->ac_charger_attached_work);
3367*8c0984e5SSebastian Reichel 	flush_delayed_work(&di->check_usbchgnotok_work);
3368*8c0984e5SSebastian Reichel 	flush_delayed_work(&di->check_vbat_work);
3369*8c0984e5SSebastian Reichel 	flush_delayed_work(&di->kick_wd_work);
3370*8c0984e5SSebastian Reichel 
3371*8c0984e5SSebastian Reichel 	flush_work(&di->usb_link_status_work);
3372*8c0984e5SSebastian Reichel 	flush_work(&di->ac_work);
3373*8c0984e5SSebastian Reichel 	flush_work(&di->detect_usb_type_work);
3374*8c0984e5SSebastian Reichel 
3375*8c0984e5SSebastian Reichel 	if (atomic_read(&di->current_stepping_sessions))
3376*8c0984e5SSebastian Reichel 		return -EAGAIN;
3377*8c0984e5SSebastian Reichel 
3378*8c0984e5SSebastian Reichel 	return 0;
3379*8c0984e5SSebastian Reichel }
3380*8c0984e5SSebastian Reichel #else
3381*8c0984e5SSebastian Reichel #define ab8500_charger_suspend      NULL
3382*8c0984e5SSebastian Reichel #define ab8500_charger_resume       NULL
3383*8c0984e5SSebastian Reichel #endif
3384*8c0984e5SSebastian Reichel 
3385*8c0984e5SSebastian Reichel static struct notifier_block charger_nb = {
3386*8c0984e5SSebastian Reichel 	.notifier_call = ab8500_external_charger_prepare,
3387*8c0984e5SSebastian Reichel };
3388*8c0984e5SSebastian Reichel 
3389*8c0984e5SSebastian Reichel static int ab8500_charger_remove(struct platform_device *pdev)
3390*8c0984e5SSebastian Reichel {
3391*8c0984e5SSebastian Reichel 	struct ab8500_charger *di = platform_get_drvdata(pdev);
3392*8c0984e5SSebastian Reichel 	int i, irq, ret;
3393*8c0984e5SSebastian Reichel 
3394*8c0984e5SSebastian Reichel 	/* Disable AC charging */
3395*8c0984e5SSebastian Reichel 	ab8500_charger_ac_en(&di->ac_chg, false, 0, 0);
3396*8c0984e5SSebastian Reichel 
3397*8c0984e5SSebastian Reichel 	/* Disable USB charging */
3398*8c0984e5SSebastian Reichel 	ab8500_charger_usb_en(&di->usb_chg, false, 0, 0);
3399*8c0984e5SSebastian Reichel 
3400*8c0984e5SSebastian Reichel 	/* Disable interrupts */
3401*8c0984e5SSebastian Reichel 	for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) {
3402*8c0984e5SSebastian Reichel 		irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name);
3403*8c0984e5SSebastian Reichel 		free_irq(irq, di);
3404*8c0984e5SSebastian Reichel 	}
3405*8c0984e5SSebastian Reichel 
3406*8c0984e5SSebastian Reichel 	/* Backup battery voltage and current disable */
3407*8c0984e5SSebastian Reichel 	ret = abx500_mask_and_set_register_interruptible(di->dev,
3408*8c0984e5SSebastian Reichel 		AB8500_RTC, AB8500_RTC_CTRL_REG, RTC_BUP_CH_ENA, 0);
3409*8c0984e5SSebastian Reichel 	if (ret < 0)
3410*8c0984e5SSebastian Reichel 		dev_err(di->dev, "%s mask and set failed\n", __func__);
3411*8c0984e5SSebastian Reichel 
3412*8c0984e5SSebastian Reichel 	usb_unregister_notifier(di->usb_phy, &di->nb);
3413*8c0984e5SSebastian Reichel 	usb_put_phy(di->usb_phy);
3414*8c0984e5SSebastian Reichel 
3415*8c0984e5SSebastian Reichel 	/* Delete the work queue */
3416*8c0984e5SSebastian Reichel 	destroy_workqueue(di->charger_wq);
3417*8c0984e5SSebastian Reichel 
3418*8c0984e5SSebastian Reichel 	/* Unregister external charger enable notifier */
3419*8c0984e5SSebastian Reichel 	if (!di->ac_chg.enabled)
3420*8c0984e5SSebastian Reichel 		blocking_notifier_chain_unregister(
3421*8c0984e5SSebastian Reichel 			&charger_notifier_list, &charger_nb);
3422*8c0984e5SSebastian Reichel 
3423*8c0984e5SSebastian Reichel 	flush_scheduled_work();
3424*8c0984e5SSebastian Reichel 	if (di->usb_chg.enabled)
3425*8c0984e5SSebastian Reichel 		power_supply_unregister(di->usb_chg.psy);
3426*8c0984e5SSebastian Reichel 
3427*8c0984e5SSebastian Reichel 	if (di->ac_chg.enabled && !di->ac_chg.external)
3428*8c0984e5SSebastian Reichel 		power_supply_unregister(di->ac_chg.psy);
3429*8c0984e5SSebastian Reichel 
3430*8c0984e5SSebastian Reichel 	return 0;
3431*8c0984e5SSebastian Reichel }
3432*8c0984e5SSebastian Reichel 
3433*8c0984e5SSebastian Reichel static char *supply_interface[] = {
3434*8c0984e5SSebastian Reichel 	"ab8500_chargalg",
3435*8c0984e5SSebastian Reichel 	"ab8500_fg",
3436*8c0984e5SSebastian Reichel 	"ab8500_btemp",
3437*8c0984e5SSebastian Reichel };
3438*8c0984e5SSebastian Reichel 
3439*8c0984e5SSebastian Reichel static const struct power_supply_desc ab8500_ac_chg_desc = {
3440*8c0984e5SSebastian Reichel 	.name		= "ab8500_ac",
3441*8c0984e5SSebastian Reichel 	.type		= POWER_SUPPLY_TYPE_MAINS,
3442*8c0984e5SSebastian Reichel 	.properties	= ab8500_charger_ac_props,
3443*8c0984e5SSebastian Reichel 	.num_properties	= ARRAY_SIZE(ab8500_charger_ac_props),
3444*8c0984e5SSebastian Reichel 	.get_property	= ab8500_charger_ac_get_property,
3445*8c0984e5SSebastian Reichel };
3446*8c0984e5SSebastian Reichel 
3447*8c0984e5SSebastian Reichel static const struct power_supply_desc ab8500_usb_chg_desc = {
3448*8c0984e5SSebastian Reichel 	.name		= "ab8500_usb",
3449*8c0984e5SSebastian Reichel 	.type		= POWER_SUPPLY_TYPE_USB,
3450*8c0984e5SSebastian Reichel 	.properties	= ab8500_charger_usb_props,
3451*8c0984e5SSebastian Reichel 	.num_properties	= ARRAY_SIZE(ab8500_charger_usb_props),
3452*8c0984e5SSebastian Reichel 	.get_property	= ab8500_charger_usb_get_property,
3453*8c0984e5SSebastian Reichel };
3454*8c0984e5SSebastian Reichel 
3455*8c0984e5SSebastian Reichel static int ab8500_charger_probe(struct platform_device *pdev)
3456*8c0984e5SSebastian Reichel {
3457*8c0984e5SSebastian Reichel 	struct device_node *np = pdev->dev.of_node;
3458*8c0984e5SSebastian Reichel 	struct abx500_bm_data *plat = pdev->dev.platform_data;
3459*8c0984e5SSebastian Reichel 	struct power_supply_config ac_psy_cfg = {}, usb_psy_cfg = {};
3460*8c0984e5SSebastian Reichel 	struct ab8500_charger *di;
3461*8c0984e5SSebastian Reichel 	int irq, i, charger_status, ret = 0, ch_stat;
3462*8c0984e5SSebastian Reichel 
3463*8c0984e5SSebastian Reichel 	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
3464*8c0984e5SSebastian Reichel 	if (!di) {
3465*8c0984e5SSebastian Reichel 		dev_err(&pdev->dev, "%s no mem for ab8500_charger\n", __func__);
3466*8c0984e5SSebastian Reichel 		return -ENOMEM;
3467*8c0984e5SSebastian Reichel 	}
3468*8c0984e5SSebastian Reichel 
3469*8c0984e5SSebastian Reichel 	if (!plat) {
3470*8c0984e5SSebastian Reichel 		dev_err(&pdev->dev, "no battery management data supplied\n");
3471*8c0984e5SSebastian Reichel 		return -EINVAL;
3472*8c0984e5SSebastian Reichel 	}
3473*8c0984e5SSebastian Reichel 	di->bm = plat;
3474*8c0984e5SSebastian Reichel 
3475*8c0984e5SSebastian Reichel 	if (np) {
3476*8c0984e5SSebastian Reichel 		ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm);
3477*8c0984e5SSebastian Reichel 		if (ret) {
3478*8c0984e5SSebastian Reichel 			dev_err(&pdev->dev, "failed to get battery information\n");
3479*8c0984e5SSebastian Reichel 			return ret;
3480*8c0984e5SSebastian Reichel 		}
3481*8c0984e5SSebastian Reichel 		di->autopower_cfg = of_property_read_bool(np, "autopower_cfg");
3482*8c0984e5SSebastian Reichel 	} else
3483*8c0984e5SSebastian Reichel 		di->autopower_cfg = false;
3484*8c0984e5SSebastian Reichel 
3485*8c0984e5SSebastian Reichel 	/* get parent data */
3486*8c0984e5SSebastian Reichel 	di->dev = &pdev->dev;
3487*8c0984e5SSebastian Reichel 	di->parent = dev_get_drvdata(pdev->dev.parent);
3488*8c0984e5SSebastian Reichel 	di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
3489*8c0984e5SSebastian Reichel 
3490*8c0984e5SSebastian Reichel 	/* initialize lock */
3491*8c0984e5SSebastian Reichel 	spin_lock_init(&di->usb_state.usb_lock);
3492*8c0984e5SSebastian Reichel 	mutex_init(&di->usb_ipt_crnt_lock);
3493*8c0984e5SSebastian Reichel 
3494*8c0984e5SSebastian Reichel 	di->autopower = false;
3495*8c0984e5SSebastian Reichel 	di->invalid_charger_detect_state = 0;
3496*8c0984e5SSebastian Reichel 
3497*8c0984e5SSebastian Reichel 	/* AC and USB supply config */
3498*8c0984e5SSebastian Reichel 	ac_psy_cfg.supplied_to = supply_interface;
3499*8c0984e5SSebastian Reichel 	ac_psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface);
3500*8c0984e5SSebastian Reichel 	ac_psy_cfg.drv_data = &di->ac_chg;
3501*8c0984e5SSebastian Reichel 	usb_psy_cfg.supplied_to = supply_interface;
3502*8c0984e5SSebastian Reichel 	usb_psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface);
3503*8c0984e5SSebastian Reichel 	usb_psy_cfg.drv_data = &di->usb_chg;
3504*8c0984e5SSebastian Reichel 
3505*8c0984e5SSebastian Reichel 	/* AC supply */
3506*8c0984e5SSebastian Reichel 	/* ux500_charger sub-class */
3507*8c0984e5SSebastian Reichel 	di->ac_chg.ops.enable = &ab8500_charger_ac_en;
3508*8c0984e5SSebastian Reichel 	di->ac_chg.ops.check_enable = &ab8500_charger_ac_check_enable;
3509*8c0984e5SSebastian Reichel 	di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
3510*8c0984e5SSebastian Reichel 	di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current;
3511*8c0984e5SSebastian Reichel 	di->ac_chg.max_out_volt = ab8500_charger_voltage_map[
3512*8c0984e5SSebastian Reichel 		ARRAY_SIZE(ab8500_charger_voltage_map) - 1];
3513*8c0984e5SSebastian Reichel 	di->ac_chg.max_out_curr =
3514*8c0984e5SSebastian Reichel 		di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1];
3515*8c0984e5SSebastian Reichel 	di->ac_chg.wdt_refresh = CHG_WD_INTERVAL;
3516*8c0984e5SSebastian Reichel 	di->ac_chg.enabled = di->bm->ac_enabled;
3517*8c0984e5SSebastian Reichel 	di->ac_chg.external = false;
3518*8c0984e5SSebastian Reichel 
3519*8c0984e5SSebastian Reichel 	/*notifier for external charger enabling*/
3520*8c0984e5SSebastian Reichel 	if (!di->ac_chg.enabled)
3521*8c0984e5SSebastian Reichel 		blocking_notifier_chain_register(
3522*8c0984e5SSebastian Reichel 			&charger_notifier_list, &charger_nb);
3523*8c0984e5SSebastian Reichel 
3524*8c0984e5SSebastian Reichel 	/* USB supply */
3525*8c0984e5SSebastian Reichel 	/* ux500_charger sub-class */
3526*8c0984e5SSebastian Reichel 	di->usb_chg.ops.enable = &ab8500_charger_usb_en;
3527*8c0984e5SSebastian Reichel 	di->usb_chg.ops.check_enable = &ab8500_charger_usb_check_enable;
3528*8c0984e5SSebastian Reichel 	di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
3529*8c0984e5SSebastian Reichel 	di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current;
3530*8c0984e5SSebastian Reichel 	di->usb_chg.ops.pp_enable = &ab8540_charger_power_path_enable;
3531*8c0984e5SSebastian Reichel 	di->usb_chg.ops.pre_chg_enable = &ab8540_charger_usb_pre_chg_enable;
3532*8c0984e5SSebastian Reichel 	di->usb_chg.max_out_volt = ab8500_charger_voltage_map[
3533*8c0984e5SSebastian Reichel 		ARRAY_SIZE(ab8500_charger_voltage_map) - 1];
3534*8c0984e5SSebastian Reichel 	di->usb_chg.max_out_curr =
3535*8c0984e5SSebastian Reichel 		di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1];
3536*8c0984e5SSebastian Reichel 	di->usb_chg.wdt_refresh = CHG_WD_INTERVAL;
3537*8c0984e5SSebastian Reichel 	di->usb_chg.enabled = di->bm->usb_enabled;
3538*8c0984e5SSebastian Reichel 	di->usb_chg.external = false;
3539*8c0984e5SSebastian Reichel 	di->usb_chg.power_path = di->bm->usb_power_path;
3540*8c0984e5SSebastian Reichel 	di->usb_state.usb_current = -1;
3541*8c0984e5SSebastian Reichel 
3542*8c0984e5SSebastian Reichel 	/* Create a work queue for the charger */
3543*8c0984e5SSebastian Reichel 	di->charger_wq =
3544*8c0984e5SSebastian Reichel 		create_singlethread_workqueue("ab8500_charger_wq");
3545*8c0984e5SSebastian Reichel 	if (di->charger_wq == NULL) {
3546*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to create work queue\n");
3547*8c0984e5SSebastian Reichel 		return -ENOMEM;
3548*8c0984e5SSebastian Reichel 	}
3549*8c0984e5SSebastian Reichel 
3550*8c0984e5SSebastian Reichel 	mutex_init(&di->charger_attached_mutex);
3551*8c0984e5SSebastian Reichel 
3552*8c0984e5SSebastian Reichel 	/* Init work for HW failure check */
3553*8c0984e5SSebastian Reichel 	INIT_DEFERRABLE_WORK(&di->check_hw_failure_work,
3554*8c0984e5SSebastian Reichel 		ab8500_charger_check_hw_failure_work);
3555*8c0984e5SSebastian Reichel 	INIT_DEFERRABLE_WORK(&di->check_usbchgnotok_work,
3556*8c0984e5SSebastian Reichel 		ab8500_charger_check_usbchargernotok_work);
3557*8c0984e5SSebastian Reichel 
3558*8c0984e5SSebastian Reichel 	INIT_DELAYED_WORK(&di->ac_charger_attached_work,
3559*8c0984e5SSebastian Reichel 			  ab8500_charger_ac_attached_work);
3560*8c0984e5SSebastian Reichel 	INIT_DELAYED_WORK(&di->usb_charger_attached_work,
3561*8c0984e5SSebastian Reichel 			  ab8500_charger_usb_attached_work);
3562*8c0984e5SSebastian Reichel 
3563*8c0984e5SSebastian Reichel 	/*
3564*8c0984e5SSebastian Reichel 	 * For ABB revision 1.0 and 1.1 there is a bug in the watchdog
3565*8c0984e5SSebastian Reichel 	 * logic. That means we have to continously kick the charger
3566*8c0984e5SSebastian Reichel 	 * watchdog even when no charger is connected. This is only
3567*8c0984e5SSebastian Reichel 	 * valid once the AC charger has been enabled. This is
3568*8c0984e5SSebastian Reichel 	 * a bug that is not handled by the algorithm and the
3569*8c0984e5SSebastian Reichel 	 * watchdog have to be kicked by the charger driver
3570*8c0984e5SSebastian Reichel 	 * when the AC charger is disabled
3571*8c0984e5SSebastian Reichel 	 */
3572*8c0984e5SSebastian Reichel 	INIT_DEFERRABLE_WORK(&di->kick_wd_work,
3573*8c0984e5SSebastian Reichel 		ab8500_charger_kick_watchdog_work);
3574*8c0984e5SSebastian Reichel 
3575*8c0984e5SSebastian Reichel 	INIT_DEFERRABLE_WORK(&di->check_vbat_work,
3576*8c0984e5SSebastian Reichel 		ab8500_charger_check_vbat_work);
3577*8c0984e5SSebastian Reichel 
3578*8c0984e5SSebastian Reichel 	INIT_DELAYED_WORK(&di->attach_work,
3579*8c0984e5SSebastian Reichel 		ab8500_charger_usb_link_attach_work);
3580*8c0984e5SSebastian Reichel 
3581*8c0984e5SSebastian Reichel 	INIT_DELAYED_WORK(&di->usb_state_changed_work,
3582*8c0984e5SSebastian Reichel 		ab8500_charger_usb_state_changed_work);
3583*8c0984e5SSebastian Reichel 
3584*8c0984e5SSebastian Reichel 	INIT_DELAYED_WORK(&di->vbus_drop_end_work,
3585*8c0984e5SSebastian Reichel 		ab8500_charger_vbus_drop_end_work);
3586*8c0984e5SSebastian Reichel 
3587*8c0984e5SSebastian Reichel 	/* Init work for charger detection */
3588*8c0984e5SSebastian Reichel 	INIT_WORK(&di->usb_link_status_work,
3589*8c0984e5SSebastian Reichel 		ab8500_charger_usb_link_status_work);
3590*8c0984e5SSebastian Reichel 	INIT_WORK(&di->ac_work, ab8500_charger_ac_work);
3591*8c0984e5SSebastian Reichel 	INIT_WORK(&di->detect_usb_type_work,
3592*8c0984e5SSebastian Reichel 		ab8500_charger_detect_usb_type_work);
3593*8c0984e5SSebastian Reichel 
3594*8c0984e5SSebastian Reichel 	/* Init work for checking HW status */
3595*8c0984e5SSebastian Reichel 	INIT_WORK(&di->check_main_thermal_prot_work,
3596*8c0984e5SSebastian Reichel 		ab8500_charger_check_main_thermal_prot_work);
3597*8c0984e5SSebastian Reichel 	INIT_WORK(&di->check_usb_thermal_prot_work,
3598*8c0984e5SSebastian Reichel 		ab8500_charger_check_usb_thermal_prot_work);
3599*8c0984e5SSebastian Reichel 
3600*8c0984e5SSebastian Reichel 	/*
3601*8c0984e5SSebastian Reichel 	 * VDD ADC supply needs to be enabled from this driver when there
3602*8c0984e5SSebastian Reichel 	 * is a charger connected to avoid erroneous BTEMP_HIGH/LOW
3603*8c0984e5SSebastian Reichel 	 * interrupts during charging
3604*8c0984e5SSebastian Reichel 	 */
3605*8c0984e5SSebastian Reichel 	di->regu = devm_regulator_get(di->dev, "vddadc");
3606*8c0984e5SSebastian Reichel 	if (IS_ERR(di->regu)) {
3607*8c0984e5SSebastian Reichel 		ret = PTR_ERR(di->regu);
3608*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to get vddadc regulator\n");
3609*8c0984e5SSebastian Reichel 		goto free_charger_wq;
3610*8c0984e5SSebastian Reichel 	}
3611*8c0984e5SSebastian Reichel 
3612*8c0984e5SSebastian Reichel 
3613*8c0984e5SSebastian Reichel 	/* Initialize OVV, and other registers */
3614*8c0984e5SSebastian Reichel 	ret = ab8500_charger_init_hw_registers(di);
3615*8c0984e5SSebastian Reichel 	if (ret) {
3616*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to initialize ABB registers\n");
3617*8c0984e5SSebastian Reichel 		goto free_charger_wq;
3618*8c0984e5SSebastian Reichel 	}
3619*8c0984e5SSebastian Reichel 
3620*8c0984e5SSebastian Reichel 	/* Register AC charger class */
3621*8c0984e5SSebastian Reichel 	if (di->ac_chg.enabled) {
3622*8c0984e5SSebastian Reichel 		di->ac_chg.psy = power_supply_register(di->dev,
3623*8c0984e5SSebastian Reichel 						       &ab8500_ac_chg_desc,
3624*8c0984e5SSebastian Reichel 						       &ac_psy_cfg);
3625*8c0984e5SSebastian Reichel 		if (IS_ERR(di->ac_chg.psy)) {
3626*8c0984e5SSebastian Reichel 			dev_err(di->dev, "failed to register AC charger\n");
3627*8c0984e5SSebastian Reichel 			ret = PTR_ERR(di->ac_chg.psy);
3628*8c0984e5SSebastian Reichel 			goto free_charger_wq;
3629*8c0984e5SSebastian Reichel 		}
3630*8c0984e5SSebastian Reichel 	}
3631*8c0984e5SSebastian Reichel 
3632*8c0984e5SSebastian Reichel 	/* Register USB charger class */
3633*8c0984e5SSebastian Reichel 	if (di->usb_chg.enabled) {
3634*8c0984e5SSebastian Reichel 		di->usb_chg.psy = power_supply_register(di->dev,
3635*8c0984e5SSebastian Reichel 							&ab8500_usb_chg_desc,
3636*8c0984e5SSebastian Reichel 							&usb_psy_cfg);
3637*8c0984e5SSebastian Reichel 		if (IS_ERR(di->usb_chg.psy)) {
3638*8c0984e5SSebastian Reichel 			dev_err(di->dev, "failed to register USB charger\n");
3639*8c0984e5SSebastian Reichel 			ret = PTR_ERR(di->usb_chg.psy);
3640*8c0984e5SSebastian Reichel 			goto free_ac;
3641*8c0984e5SSebastian Reichel 		}
3642*8c0984e5SSebastian Reichel 	}
3643*8c0984e5SSebastian Reichel 
3644*8c0984e5SSebastian Reichel 	di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2);
3645*8c0984e5SSebastian Reichel 	if (IS_ERR_OR_NULL(di->usb_phy)) {
3646*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to get usb transceiver\n");
3647*8c0984e5SSebastian Reichel 		ret = -EINVAL;
3648*8c0984e5SSebastian Reichel 		goto free_usb;
3649*8c0984e5SSebastian Reichel 	}
3650*8c0984e5SSebastian Reichel 	di->nb.notifier_call = ab8500_charger_usb_notifier_call;
3651*8c0984e5SSebastian Reichel 	ret = usb_register_notifier(di->usb_phy, &di->nb);
3652*8c0984e5SSebastian Reichel 	if (ret) {
3653*8c0984e5SSebastian Reichel 		dev_err(di->dev, "failed to register usb notifier\n");
3654*8c0984e5SSebastian Reichel 		goto put_usb_phy;
3655*8c0984e5SSebastian Reichel 	}
3656*8c0984e5SSebastian Reichel 
3657*8c0984e5SSebastian Reichel 	/* Identify the connected charger types during startup */
3658*8c0984e5SSebastian Reichel 	charger_status = ab8500_charger_detect_chargers(di, true);
3659*8c0984e5SSebastian Reichel 	if (charger_status & AC_PW_CONN) {
3660*8c0984e5SSebastian Reichel 		di->ac.charger_connected = 1;
3661*8c0984e5SSebastian Reichel 		di->ac_conn = true;
3662*8c0984e5SSebastian Reichel 		ab8500_power_supply_changed(di, di->ac_chg.psy);
3663*8c0984e5SSebastian Reichel 		sysfs_notify(&di->ac_chg.psy->dev.kobj, NULL, "present");
3664*8c0984e5SSebastian Reichel 	}
3665*8c0984e5SSebastian Reichel 
3666*8c0984e5SSebastian Reichel 	if (charger_status & USB_PW_CONN) {
3667*8c0984e5SSebastian Reichel 		di->vbus_detected = true;
3668*8c0984e5SSebastian Reichel 		di->vbus_detected_start = true;
3669*8c0984e5SSebastian Reichel 		queue_work(di->charger_wq,
3670*8c0984e5SSebastian Reichel 			&di->detect_usb_type_work);
3671*8c0984e5SSebastian Reichel 	}
3672*8c0984e5SSebastian Reichel 
3673*8c0984e5SSebastian Reichel 	/* Register interrupts */
3674*8c0984e5SSebastian Reichel 	for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) {
3675*8c0984e5SSebastian Reichel 		irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name);
3676*8c0984e5SSebastian Reichel 		ret = request_threaded_irq(irq, NULL, ab8500_charger_irq[i].isr,
3677*8c0984e5SSebastian Reichel 			IRQF_SHARED | IRQF_NO_SUSPEND,
3678*8c0984e5SSebastian Reichel 			ab8500_charger_irq[i].name, di);
3679*8c0984e5SSebastian Reichel 
3680*8c0984e5SSebastian Reichel 		if (ret != 0) {
3681*8c0984e5SSebastian Reichel 			dev_err(di->dev, "failed to request %s IRQ %d: %d\n"
3682*8c0984e5SSebastian Reichel 				, ab8500_charger_irq[i].name, irq, ret);
3683*8c0984e5SSebastian Reichel 			goto free_irq;
3684*8c0984e5SSebastian Reichel 		}
3685*8c0984e5SSebastian Reichel 		dev_dbg(di->dev, "Requested %s IRQ %d: %d\n",
3686*8c0984e5SSebastian Reichel 			ab8500_charger_irq[i].name, irq, ret);
3687*8c0984e5SSebastian Reichel 	}
3688*8c0984e5SSebastian Reichel 
3689*8c0984e5SSebastian Reichel 	platform_set_drvdata(pdev, di);
3690*8c0984e5SSebastian Reichel 
3691*8c0984e5SSebastian Reichel 	mutex_lock(&di->charger_attached_mutex);
3692*8c0984e5SSebastian Reichel 
3693*8c0984e5SSebastian Reichel 	ch_stat = ab8500_charger_detect_chargers(di, false);
3694*8c0984e5SSebastian Reichel 
3695*8c0984e5SSebastian Reichel 	if ((ch_stat & AC_PW_CONN) == AC_PW_CONN) {
3696*8c0984e5SSebastian Reichel 		if (is_ab8500(di->parent))
3697*8c0984e5SSebastian Reichel 			queue_delayed_work(di->charger_wq,
3698*8c0984e5SSebastian Reichel 					   &di->ac_charger_attached_work,
3699*8c0984e5SSebastian Reichel 					   HZ);
3700*8c0984e5SSebastian Reichel 	}
3701*8c0984e5SSebastian Reichel 	if ((ch_stat & USB_PW_CONN) == USB_PW_CONN) {
3702*8c0984e5SSebastian Reichel 		if (is_ab8500(di->parent))
3703*8c0984e5SSebastian Reichel 			queue_delayed_work(di->charger_wq,
3704*8c0984e5SSebastian Reichel 					   &di->usb_charger_attached_work,
3705*8c0984e5SSebastian Reichel 					   HZ);
3706*8c0984e5SSebastian Reichel 	}
3707*8c0984e5SSebastian Reichel 
3708*8c0984e5SSebastian Reichel 	mutex_unlock(&di->charger_attached_mutex);
3709*8c0984e5SSebastian Reichel 
3710*8c0984e5SSebastian Reichel 	return ret;
3711*8c0984e5SSebastian Reichel 
3712*8c0984e5SSebastian Reichel free_irq:
3713*8c0984e5SSebastian Reichel 	usb_unregister_notifier(di->usb_phy, &di->nb);
3714*8c0984e5SSebastian Reichel 
3715*8c0984e5SSebastian Reichel 	/* We also have to free all successfully registered irqs */
3716*8c0984e5SSebastian Reichel 	for (i = i - 1; i >= 0; i--) {
3717*8c0984e5SSebastian Reichel 		irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name);
3718*8c0984e5SSebastian Reichel 		free_irq(irq, di);
3719*8c0984e5SSebastian Reichel 	}
3720*8c0984e5SSebastian Reichel put_usb_phy:
3721*8c0984e5SSebastian Reichel 	usb_put_phy(di->usb_phy);
3722*8c0984e5SSebastian Reichel free_usb:
3723*8c0984e5SSebastian Reichel 	if (di->usb_chg.enabled)
3724*8c0984e5SSebastian Reichel 		power_supply_unregister(di->usb_chg.psy);
3725*8c0984e5SSebastian Reichel free_ac:
3726*8c0984e5SSebastian Reichel 	if (di->ac_chg.enabled)
3727*8c0984e5SSebastian Reichel 		power_supply_unregister(di->ac_chg.psy);
3728*8c0984e5SSebastian Reichel free_charger_wq:
3729*8c0984e5SSebastian Reichel 	destroy_workqueue(di->charger_wq);
3730*8c0984e5SSebastian Reichel 	return ret;
3731*8c0984e5SSebastian Reichel }
3732*8c0984e5SSebastian Reichel 
3733*8c0984e5SSebastian Reichel static const struct of_device_id ab8500_charger_match[] = {
3734*8c0984e5SSebastian Reichel 	{ .compatible = "stericsson,ab8500-charger", },
3735*8c0984e5SSebastian Reichel 	{ },
3736*8c0984e5SSebastian Reichel };
3737*8c0984e5SSebastian Reichel 
3738*8c0984e5SSebastian Reichel static struct platform_driver ab8500_charger_driver = {
3739*8c0984e5SSebastian Reichel 	.probe = ab8500_charger_probe,
3740*8c0984e5SSebastian Reichel 	.remove = ab8500_charger_remove,
3741*8c0984e5SSebastian Reichel 	.suspend = ab8500_charger_suspend,
3742*8c0984e5SSebastian Reichel 	.resume = ab8500_charger_resume,
3743*8c0984e5SSebastian Reichel 	.driver = {
3744*8c0984e5SSebastian Reichel 		.name = "ab8500-charger",
3745*8c0984e5SSebastian Reichel 		.of_match_table = ab8500_charger_match,
3746*8c0984e5SSebastian Reichel 	},
3747*8c0984e5SSebastian Reichel };
3748*8c0984e5SSebastian Reichel 
3749*8c0984e5SSebastian Reichel static int __init ab8500_charger_init(void)
3750*8c0984e5SSebastian Reichel {
3751*8c0984e5SSebastian Reichel 	return platform_driver_register(&ab8500_charger_driver);
3752*8c0984e5SSebastian Reichel }
3753*8c0984e5SSebastian Reichel 
3754*8c0984e5SSebastian Reichel static void __exit ab8500_charger_exit(void)
3755*8c0984e5SSebastian Reichel {
3756*8c0984e5SSebastian Reichel 	platform_driver_unregister(&ab8500_charger_driver);
3757*8c0984e5SSebastian Reichel }
3758*8c0984e5SSebastian Reichel 
3759*8c0984e5SSebastian Reichel subsys_initcall_sync(ab8500_charger_init);
3760*8c0984e5SSebastian Reichel module_exit(ab8500_charger_exit);
3761*8c0984e5SSebastian Reichel 
3762*8c0984e5SSebastian Reichel MODULE_LICENSE("GPL v2");
3763*8c0984e5SSebastian Reichel MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy");
3764*8c0984e5SSebastian Reichel MODULE_ALIAS("platform:ab8500-charger");
3765*8c0984e5SSebastian Reichel MODULE_DESCRIPTION("AB8500 charger management driver");
3766