xref: /OK3568_Linux_fs/kernel/drivers/power/supply/sgm41542_charger.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Chrager driver for Sgm4154x
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Xu Shengfei <xsf@rock-chips.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/delay.h>
11*4882a593Smuzhiyun #include <linux/i2c.h>
12*4882a593Smuzhiyun #include <linux/interrupt.h>
13*4882a593Smuzhiyun #include <linux/module.h>
14*4882a593Smuzhiyun #include <linux/power_supply.h>
15*4882a593Smuzhiyun #include <linux/regmap.h>
16*4882a593Smuzhiyun #include <linux/regulator/driver.h>
17*4882a593Smuzhiyun #include <linux/regulator/of_regulator.h>
18*4882a593Smuzhiyun #include <linux/regulator/machine.h>
19*4882a593Smuzhiyun #include <linux/types.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun static int dbg_enable;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun module_param_named(dbg_level, dbg_enable, int, 0644);
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define DBG(args...) \
26*4882a593Smuzhiyun 	do { \
27*4882a593Smuzhiyun 		if (dbg_enable) { \
28*4882a593Smuzhiyun 			pr_info(args); \
29*4882a593Smuzhiyun 		} \
30*4882a593Smuzhiyun 	} while (0)
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define SGM4154x_MANUFACTURER	"SGMICRO"
33*4882a593Smuzhiyun #define SGM4154x_NAME		"sgm41542"
34*4882a593Smuzhiyun #define SGM4154x_PN_ID		(BIT(6) | BIT(5) | BIT(3))
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /* define register */
37*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_0	0x00
38*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_1	0x01
39*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_2	0x02
40*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_3	0x03
41*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_4	0x04
42*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_5	0x05
43*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_6	0x06
44*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_7	0x07
45*4882a593Smuzhiyun #define SGM4154x_CHRG_STAT	0x08
46*4882a593Smuzhiyun #define SGM4154x_CHRG_FAULT	0x09
47*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_a	0x0a
48*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_b	0x0b
49*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_c	0x0c
50*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_d	0x0d
51*4882a593Smuzhiyun #define SGM4154x_INPUT_DET	0x0e
52*4882a593Smuzhiyun #define SGM4154x_CHRG_CTRL_f	0x0f
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* charge status flags */
55*4882a593Smuzhiyun #define SGM4154x_CHRG_EN		BIT(4)
56*4882a593Smuzhiyun #define SGM4154x_HIZ_EN			BIT(7)
57*4882a593Smuzhiyun #define SGM4154x_TERM_EN		BIT(7)
58*4882a593Smuzhiyun #define SGM4154x_VAC_OVP_MASK		GENMASK(7, 6)
59*4882a593Smuzhiyun #define SGM4154x_DPDM_ONGOING		BIT(7)
60*4882a593Smuzhiyun #define SGM4154x_VBUS_GOOD		BIT(7)
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #define SGM4154x_BOOSTV			GENMASK(5, 4)
63*4882a593Smuzhiyun #define SGM4154x_BOOST_LIM		BIT(7)
64*4882a593Smuzhiyun #define SGM4154x_OTG_EN			BIT(5)
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun /* Part ID */
67*4882a593Smuzhiyun #define SGM4154x_PN_MASK		GENMASK(6, 3)
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /* WDT TIMER SET */
70*4882a593Smuzhiyun #define SGM4154x_WDT_TIMER_MASK		GENMASK(5, 4)
71*4882a593Smuzhiyun #define SGM4154x_WDT_TIMER_DISABLE	0
72*4882a593Smuzhiyun #define SGM4154x_WDT_TIMER_40S		BIT(4)
73*4882a593Smuzhiyun #define SGM4154x_WDT_TIMER_80S		BIT(5)
74*4882a593Smuzhiyun #define SGM4154x_WDT_TIMER_160S		(BIT(4) | BIT(5))
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #define SGM4154x_WDT_RST_MASK		BIT(6)
77*4882a593Smuzhiyun #define SGM4154x_WDT_RST		BIT(6)
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /* SAFETY TIMER SET */
80*4882a593Smuzhiyun #define SGM4154x_SAFETY_TIMER_MASK	GENMASK(3, 3)
81*4882a593Smuzhiyun #define SGM4154x_SAFETY_TIMER_DISABLE	0
82*4882a593Smuzhiyun #define SGM4154x_SAFETY_TIMER_EN	BIT(3)
83*4882a593Smuzhiyun #define SGM4154x_SAFETY_TIMER_5H	0
84*4882a593Smuzhiyun #define SGM4154x_SAFETY_TIMER_10H	BIT(2)
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun /* recharge voltage */
87*4882a593Smuzhiyun #define SGM4154x_VRECHARGE		BIT(0)
88*4882a593Smuzhiyun #define SGM4154x_VRECHRG_STEP_mV	100
89*4882a593Smuzhiyun #define SGM4154x_VRECHRG_OFFSET_mV	100
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /* charge status */
92*4882a593Smuzhiyun #define SGM4154x_VSYS_STAT		BIT(0)
93*4882a593Smuzhiyun #define SGM4154x_THERM_STAT		BIT(1)
94*4882a593Smuzhiyun #define SGM4154x_PG_STAT		BIT(2)
95*4882a593Smuzhiyun #define SGM4154x_CHG_STAT_MASK		GENMASK(4, 3)
96*4882a593Smuzhiyun #define SGM4154x_PRECHRG		BIT(3)
97*4882a593Smuzhiyun #define SGM4154x_FAST_CHRG		BIT(4)
98*4882a593Smuzhiyun #define SGM4154x_TERM_CHRG		(BIT(3) | BIT(4))
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun /* charge type */
101*4882a593Smuzhiyun #define SGM4154x_VBUS_STAT_MASK		GENMASK(7, 5)
102*4882a593Smuzhiyun #define SGM4154x_NOT_CHRGING		0
103*4882a593Smuzhiyun #define SGM4154x_USB_SDP		BIT(5)
104*4882a593Smuzhiyun #define SGM4154x_USB_CDP		BIT(6)
105*4882a593Smuzhiyun #define SGM4154x_USB_DCP		(BIT(5) | BIT(6))
106*4882a593Smuzhiyun #define SGM4154x_UNKNOWN		(BIT(7) | BIT(5))
107*4882a593Smuzhiyun #define SGM4154x_NON_STANDARD		(BIT(7) | BIT(6))
108*4882a593Smuzhiyun #define SGM4154x_OTG_MODE		(BIT(7) | BIT(6) | BIT(5))
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /* TEMP Status */
111*4882a593Smuzhiyun #define SGM4154x_TEMP_MASK			GENMASK(2, 0)
112*4882a593Smuzhiyun #define SGM4154x_TEMP_NORMAL			BIT(0)
113*4882a593Smuzhiyun #define SGM4154x_TEMP_WARM			BIT(1)
114*4882a593Smuzhiyun #define SGM4154x_TEMP_COOL			(BIT(0) | BIT(1))
115*4882a593Smuzhiyun #define SGM4154x_TEMP_COLD			(BIT(0) | BIT(3))
116*4882a593Smuzhiyun #define SGM4154x_TEMP_HOT			(BIT(2) | BIT(3))
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun /* precharge current */
119*4882a593Smuzhiyun #define SGM4154x_PRECHRG_CUR_MASK		GENMASK(7, 4)
120*4882a593Smuzhiyun #define SGM4154x_PRECHRG_CURRENT_STEP_uA	60000
121*4882a593Smuzhiyun #define SGM4154x_PRECHRG_I_MIN_uA		60000
122*4882a593Smuzhiyun #define SGM4154x_PRECHRG_I_MAX_uA		780000
123*4882a593Smuzhiyun #define SGM4154x_PRECHRG_I_DEF_uA		180000
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun /* termination current */
126*4882a593Smuzhiyun #define SGM4154x_TERMCHRG_CUR_MASK		GENMASK(3, 0)
127*4882a593Smuzhiyun #define SGM4154x_TERMCHRG_CURRENT_STEP_uA	60000
128*4882a593Smuzhiyun #define SGM4154x_TERMCHRG_I_MIN_uA		60000
129*4882a593Smuzhiyun #define SGM4154x_TERMCHRG_I_MAX_uA		960000
130*4882a593Smuzhiyun #define SGM4154x_TERMCHRG_I_DEF_uA		180000
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun /* charge current */
133*4882a593Smuzhiyun #define SGM4154x_ICHRG_CUR_MASK		GENMASK(5, 0)
134*4882a593Smuzhiyun #define SGM4154x_ICHRG_I_STEP_uA	60000
135*4882a593Smuzhiyun #define SGM4154x_ICHRG_I_MIN_uA		0
136*4882a593Smuzhiyun #define SGM4154x_ICHRG_I_MAX_uA		3000000
137*4882a593Smuzhiyun #define SGM4154x_ICHRG_I_DEF_uA		2040000
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun /* charge voltage */
140*4882a593Smuzhiyun #define SGM4154x_VREG_V_MASK		GENMASK(7, 3)
141*4882a593Smuzhiyun #define SGM4154x_VREG_V_MAX_uV		4624000
142*4882a593Smuzhiyun #define SGM4154x_VREG_V_MIN_uV		3856000
143*4882a593Smuzhiyun #define SGM4154x_VREG_V_DEF_uV		4208000
144*4882a593Smuzhiyun #define SGM4154x_VREG_V_STEP_uV		32000
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun /* VREG Fine Tuning */
147*4882a593Smuzhiyun #define SGM4154x_VREG_FT_MASK		GENMASK(7, 6)
148*4882a593Smuzhiyun #define SGM4154x_VREG_FT_UP_8mV		BIT(6)
149*4882a593Smuzhiyun #define SGM4154x_VREG_FT_DN_8mV		BIT(7)
150*4882a593Smuzhiyun #define SGM4154x_VREG_FT_DN_16mV	(BIT(7) | BIT(6))
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun /* iindpm current */
153*4882a593Smuzhiyun #define SGM4154x_IINDPM_I_MASK		GENMASK(4, 0)
154*4882a593Smuzhiyun #define SGM4154x_IINDPM_I_MIN_uA	100000
155*4882a593Smuzhiyun #define SGM4154x_IINDPM_I_MAX_uA	3800000
156*4882a593Smuzhiyun #define SGM4154x_IINDPM_STEP_uA		100000
157*4882a593Smuzhiyun #define SGM4154x_IINDPM_DEF_uA		2400000
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun #define SGM4154x_VINDPM_INT_MASK	BIT(1)
160*4882a593Smuzhiyun #define SGM4154x_VINDPM_INT_DIS		BIT(1)
161*4882a593Smuzhiyun #define SGM4154x_IINDPM_INT_MASK	BIT(0)
162*4882a593Smuzhiyun #define SGM4154x_IINDPM_INT_DIS		BIT(0)
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun /* vindpm voltage */
165*4882a593Smuzhiyun #define SGM4154x_VINDPM_V_MASK		GENMASK(3, 0)
166*4882a593Smuzhiyun #define SGM4154x_VINDPM_V_MIN_uV	3900000
167*4882a593Smuzhiyun #define SGM4154x_VINDPM_V_MAX_uV	12000000
168*4882a593Smuzhiyun #define SGM4154x_VINDPM_STEP_uV		100000
169*4882a593Smuzhiyun #define SGM4154x_VINDPM_DEF_uV		4500000
170*4882a593Smuzhiyun #define SGM4154x_VINDPM_OS_MASK		GENMASK(1, 0)
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun /* DP DM SEL */
173*4882a593Smuzhiyun #define SGM4154x_DP_VSEL_MASK		GENMASK(4, 3)
174*4882a593Smuzhiyun #define SGM4154x_DM_VSEL_MASK		GENMASK(2, 1)
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun /* PUMPX SET */
177*4882a593Smuzhiyun #define SGM4154x_EN_PUMPX		BIT(7)
178*4882a593Smuzhiyun #define SGM4154x_PUMPX_UP		BIT(6)
179*4882a593Smuzhiyun #define SGM4154x_PUMPX_DN		BIT(5)
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun #define SGM4154x_BATFET_DIS_MSK		BIT(5)
182*4882a593Smuzhiyun #define SGM4154x_BATFET_DIS_DIS		BIT(5)
183*4882a593Smuzhiyun #define SGM4154x_BATFET_DLY_MSK		BIT(3)
184*4882a593Smuzhiyun #define SGM4154x_BATFET_DLY_EN		BIT(3)
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun #define DEFAULT_INPUT_CURRENT		(500 * 1000)
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun struct sgm4154x_init_data {
189*4882a593Smuzhiyun 	int ichg;	/* charge current */
190*4882a593Smuzhiyun 	int ilim;	/* input current */
191*4882a593Smuzhiyun 	int vreg;	/* regulation voltage */
192*4882a593Smuzhiyun 	int iterm;	/* termination current */
193*4882a593Smuzhiyun 	int iprechg;	/* precharge current */
194*4882a593Smuzhiyun 	int vlim;	/* minimum system voltage limit */
195*4882a593Smuzhiyun 	int max_ichg;
196*4882a593Smuzhiyun 	int max_vreg;
197*4882a593Smuzhiyun };
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun struct sgm4154x_state {
200*4882a593Smuzhiyun 	bool vsys_stat;
201*4882a593Smuzhiyun 	bool therm_stat;
202*4882a593Smuzhiyun 	bool online;
203*4882a593Smuzhiyun 	u8 chrg_stat;
204*4882a593Smuzhiyun 	u8 vbus_status;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	bool chrg_en;
207*4882a593Smuzhiyun 	bool hiz_en;
208*4882a593Smuzhiyun 	bool term_en;
209*4882a593Smuzhiyun 	bool vbus_gd;
210*4882a593Smuzhiyun 	u8 chrg_type;
211*4882a593Smuzhiyun 	u8 health;
212*4882a593Smuzhiyun 	u8 chrg_fault;
213*4882a593Smuzhiyun 	u8 ntc_fault;
214*4882a593Smuzhiyun };
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun struct sgm4154x_device {
217*4882a593Smuzhiyun 	struct i2c_client *client;
218*4882a593Smuzhiyun 	struct device *dev;
219*4882a593Smuzhiyun 	struct power_supply *charger;
220*4882a593Smuzhiyun 	struct mutex lock;
221*4882a593Smuzhiyun 	struct mutex i2c_rw_lock;
222*4882a593Smuzhiyun 	struct regmap *regmap;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	char model_name[I2C_NAME_SIZE];
225*4882a593Smuzhiyun 	int device_id;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	struct sgm4154x_init_data init_data;
228*4882a593Smuzhiyun 	struct sgm4154x_state state;
229*4882a593Smuzhiyun 	struct regulator_dev *otg_rdev;
230*4882a593Smuzhiyun 	struct notifier_block pm_nb;
231*4882a593Smuzhiyun 	int input_current;
232*4882a593Smuzhiyun 	bool sgm4154x_suspend_flag;
233*4882a593Smuzhiyun 	bool watchdog_enable;
234*4882a593Smuzhiyun 	struct workqueue_struct *sgm_monitor_wq;
235*4882a593Smuzhiyun 	struct delayed_work sgm_delay_work;
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /* SGM4154x REG06 BOOST_LIM[5:4], uV */
239*4882a593Smuzhiyun static const unsigned int BOOST_VOLT_LIMIT[] = {
240*4882a593Smuzhiyun 	4850000, 5000000, 5150000, 5300000
241*4882a593Smuzhiyun };
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun static const unsigned int BOOST_CURRENT_LIMIT[] = {
244*4882a593Smuzhiyun 	1200000, 2000000
245*4882a593Smuzhiyun };
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun enum SGM4154x_VINDPM_OS {
248*4882a593Smuzhiyun 	VINDPM_OS_3900mV,
249*4882a593Smuzhiyun 	VINDPM_OS_5900mV,
250*4882a593Smuzhiyun 	VINDPM_OS_7500mV,
251*4882a593Smuzhiyun 	VINDPM_OS_10500mV,
252*4882a593Smuzhiyun };
253*4882a593Smuzhiyun 
sgm4154x_set_term_curr(struct sgm4154x_device * sgm,int uA)254*4882a593Smuzhiyun static int sgm4154x_set_term_curr(struct sgm4154x_device *sgm, int uA)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun 	int reg_val;
257*4882a593Smuzhiyun 	int ret;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	if (uA < SGM4154x_TERMCHRG_I_MIN_uA)
260*4882a593Smuzhiyun 		uA = SGM4154x_TERMCHRG_I_MIN_uA;
261*4882a593Smuzhiyun 	else if (uA > SGM4154x_TERMCHRG_I_MAX_uA)
262*4882a593Smuzhiyun 		uA = SGM4154x_TERMCHRG_I_MAX_uA;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	reg_val = (uA - SGM4154x_TERMCHRG_I_MIN_uA) / SGM4154x_TERMCHRG_CURRENT_STEP_uA;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
267*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_3,
268*4882a593Smuzhiyun 				 SGM4154x_TERMCHRG_CUR_MASK,
269*4882a593Smuzhiyun 				 reg_val);
270*4882a593Smuzhiyun 	if (ret)
271*4882a593Smuzhiyun 		dev_err(sgm->dev, "set term current error!\n");
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	return ret;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun 
sgm4154x_set_prechrg_curr(struct sgm4154x_device * sgm,int uA)276*4882a593Smuzhiyun static int sgm4154x_set_prechrg_curr(struct sgm4154x_device *sgm, int uA)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun 	int reg_val;
279*4882a593Smuzhiyun 	int ret;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	if (uA < SGM4154x_PRECHRG_I_MIN_uA)
282*4882a593Smuzhiyun 		uA = SGM4154x_PRECHRG_I_MIN_uA;
283*4882a593Smuzhiyun 	else if (uA > SGM4154x_PRECHRG_I_MAX_uA)
284*4882a593Smuzhiyun 		uA = SGM4154x_PRECHRG_I_MAX_uA;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	reg_val = (uA - SGM4154x_PRECHRG_I_MIN_uA) / SGM4154x_PRECHRG_CURRENT_STEP_uA;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	reg_val = reg_val << 4;
289*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
290*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_3,
291*4882a593Smuzhiyun 				 SGM4154x_PRECHRG_CUR_MASK,
292*4882a593Smuzhiyun 				 reg_val);
293*4882a593Smuzhiyun 	if (ret)
294*4882a593Smuzhiyun 		dev_err(sgm->dev, "set precharge current error!\n");
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	return ret;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun 
sgm4154x_set_ichrg_curr(struct sgm4154x_device * sgm,int uA)299*4882a593Smuzhiyun static int sgm4154x_set_ichrg_curr(struct sgm4154x_device *sgm, int uA)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun 	int reg_val;
302*4882a593Smuzhiyun 	int ret;
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	if (uA < SGM4154x_ICHRG_I_MIN_uA)
305*4882a593Smuzhiyun 		uA = SGM4154x_ICHRG_I_MIN_uA;
306*4882a593Smuzhiyun 	else {
307*4882a593Smuzhiyun 		if ((sgm->init_data.max_ichg > 0) && (uA > sgm->init_data.max_ichg))
308*4882a593Smuzhiyun 			uA = sgm->init_data.max_ichg;
309*4882a593Smuzhiyun 		uA = min(uA, SGM4154x_ICHRG_I_MAX_uA);
310*4882a593Smuzhiyun 	}
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	reg_val = uA / SGM4154x_ICHRG_I_STEP_uA;
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
315*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_2,
316*4882a593Smuzhiyun 				 SGM4154x_ICHRG_CUR_MASK,
317*4882a593Smuzhiyun 				 reg_val);
318*4882a593Smuzhiyun 	if (ret)
319*4882a593Smuzhiyun 		dev_err(sgm->dev, "set icharge current error!\n");
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	return ret;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun 
sgm4154x_set_chrg_volt(struct sgm4154x_device * sgm,int chrg_volt)324*4882a593Smuzhiyun static int sgm4154x_set_chrg_volt(struct sgm4154x_device *sgm, int chrg_volt)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun 	int reg_val;
327*4882a593Smuzhiyun 	int ret;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	if (chrg_volt < SGM4154x_VREG_V_MIN_uV)
330*4882a593Smuzhiyun 		chrg_volt = SGM4154x_VREG_V_MIN_uV;
331*4882a593Smuzhiyun 	else {
332*4882a593Smuzhiyun 		if ((sgm->init_data.max_vreg > 0) && (chrg_volt > sgm->init_data.max_vreg))
333*4882a593Smuzhiyun 			chrg_volt = sgm->init_data.max_vreg;
334*4882a593Smuzhiyun 		chrg_volt = min(chrg_volt, SGM4154x_VREG_V_MAX_uV);
335*4882a593Smuzhiyun 	}
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	reg_val = (chrg_volt - SGM4154x_VREG_V_MIN_uV) / SGM4154x_VREG_V_STEP_uV;
338*4882a593Smuzhiyun 	if (chrg_volt == 4200 * 1000)
339*4882a593Smuzhiyun 		reg_val = 0x0b;
340*4882a593Smuzhiyun 	reg_val = reg_val << 3;
341*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
342*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_4,
343*4882a593Smuzhiyun 				 SGM4154x_VREG_V_MASK,
344*4882a593Smuzhiyun 				 reg_val);
345*4882a593Smuzhiyun 	if (ret)
346*4882a593Smuzhiyun 		dev_err(sgm->dev, "set charge voltage error!\n");
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	return ret;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun 
sgm4154x_set_vindpm_offset_os(struct sgm4154x_device * sgm,enum SGM4154x_VINDPM_OS offset_os)351*4882a593Smuzhiyun static int sgm4154x_set_vindpm_offset_os(struct sgm4154x_device *sgm,
352*4882a593Smuzhiyun 					 enum SGM4154x_VINDPM_OS offset_os)
353*4882a593Smuzhiyun {
354*4882a593Smuzhiyun 	int ret;
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
357*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_f,
358*4882a593Smuzhiyun 				 SGM4154x_VINDPM_OS_MASK,
359*4882a593Smuzhiyun 				 offset_os);
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	if (ret)
362*4882a593Smuzhiyun 		dev_err(sgm->dev, "set vindpm offset os error!\n");
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	return ret;
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun 
sgm4154x_set_input_volt_lim(struct sgm4154x_device * sgm,unsigned int vindpm)367*4882a593Smuzhiyun static int sgm4154x_set_input_volt_lim(struct sgm4154x_device *sgm,
368*4882a593Smuzhiyun 				       unsigned int vindpm)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun 	enum SGM4154x_VINDPM_OS os_val;
371*4882a593Smuzhiyun 	unsigned int offset;
372*4882a593Smuzhiyun 	u8 reg_val;
373*4882a593Smuzhiyun 	int ret;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	if (vindpm < SGM4154x_VINDPM_V_MIN_uV ||
377*4882a593Smuzhiyun 	    vindpm > SGM4154x_VINDPM_V_MAX_uV)
378*4882a593Smuzhiyun 		return -EINVAL;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	if (vindpm < 5900000) {
381*4882a593Smuzhiyun 		os_val = VINDPM_OS_3900mV;
382*4882a593Smuzhiyun 		offset = 3900000;
383*4882a593Smuzhiyun 	} else if (vindpm >= 5900000 && vindpm < 7500000) {
384*4882a593Smuzhiyun 		os_val = VINDPM_OS_5900mV;
385*4882a593Smuzhiyun 		offset = 5900000;
386*4882a593Smuzhiyun 	} else if (vindpm >= 7500000 && vindpm < 10500000) {
387*4882a593Smuzhiyun 		os_val = VINDPM_OS_7500mV;
388*4882a593Smuzhiyun 		offset = 7500000;
389*4882a593Smuzhiyun 	} else {
390*4882a593Smuzhiyun 		os_val = VINDPM_OS_10500mV;
391*4882a593Smuzhiyun 		offset = 10500000;
392*4882a593Smuzhiyun 	}
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	ret = sgm4154x_set_vindpm_offset_os(sgm, os_val);
395*4882a593Smuzhiyun 	if (ret) {
396*4882a593Smuzhiyun 		dev_err(sgm->dev, "set vin dpm error!\n");
397*4882a593Smuzhiyun 		return ret;
398*4882a593Smuzhiyun 	}
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	reg_val = (vindpm - offset) / SGM4154x_VINDPM_STEP_uV;
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap, SGM4154x_CHRG_CTRL_6,
403*4882a593Smuzhiyun 				 SGM4154x_VINDPM_V_MASK, reg_val);
404*4882a593Smuzhiyun 	if (ret) {
405*4882a593Smuzhiyun 		dev_err(sgm->dev, "input voltage error!\n");
406*4882a593Smuzhiyun 		return ret;
407*4882a593Smuzhiyun 	}
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	return ret;
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun 
sgm4154x_set_input_curr_lim(struct sgm4154x_device * sgm,int iindpm)412*4882a593Smuzhiyun static int sgm4154x_set_input_curr_lim(struct sgm4154x_device *sgm, int iindpm)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun 	int reg_val;
415*4882a593Smuzhiyun 	int ret;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	if (iindpm < SGM4154x_IINDPM_I_MIN_uA)
418*4882a593Smuzhiyun 		return -EINVAL;
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 	if ((iindpm > SGM4154x_IINDPM_I_MAX_uA) || (iindpm > sgm->init_data.ilim))
421*4882a593Smuzhiyun 		iindpm = min(SGM4154x_IINDPM_I_MAX_uA, sgm->init_data.ilim);
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 	sgm->input_current = iindpm;
424*4882a593Smuzhiyun 	reg_val = (iindpm-SGM4154x_IINDPM_I_MIN_uA) / SGM4154x_IINDPM_STEP_uA;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
427*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_0,
428*4882a593Smuzhiyun 				 SGM4154x_IINDPM_I_MASK,
429*4882a593Smuzhiyun 				 reg_val);
430*4882a593Smuzhiyun 	if (ret)
431*4882a593Smuzhiyun 		dev_err(sgm->dev, "set input current limit error!\n");
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	return ret;
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun 
sgm4154x_get_input_curr_lim(struct sgm4154x_device * sgm)436*4882a593Smuzhiyun static int sgm4154x_get_input_curr_lim(struct sgm4154x_device *sgm)
437*4882a593Smuzhiyun {
438*4882a593Smuzhiyun 	int ret;
439*4882a593Smuzhiyun 	int ilim;
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	ret = regmap_read(sgm->regmap, SGM4154x_CHRG_CTRL_0, &ilim);
442*4882a593Smuzhiyun 	if (ret) {
443*4882a593Smuzhiyun 		dev_err(sgm->dev, "get input current limit error!\n");
444*4882a593Smuzhiyun 		return ret;
445*4882a593Smuzhiyun 	}
446*4882a593Smuzhiyun 	if (SGM4154x_IINDPM_I_MASK == (ilim & SGM4154x_IINDPM_I_MASK))
447*4882a593Smuzhiyun 		return SGM4154x_IINDPM_I_MAX_uA;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	ilim = (ilim & SGM4154x_IINDPM_I_MASK) * SGM4154x_IINDPM_STEP_uA + SGM4154x_IINDPM_I_MIN_uA;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	return ilim;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun 
sgm4154x_watchdog_timer_reset(struct sgm4154x_device * sgm)454*4882a593Smuzhiyun static int sgm4154x_watchdog_timer_reset(struct sgm4154x_device *sgm)
455*4882a593Smuzhiyun {
456*4882a593Smuzhiyun 	int ret;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
459*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_1,
460*4882a593Smuzhiyun 				 SGM4154x_WDT_RST_MASK,
461*4882a593Smuzhiyun 				 SGM4154x_WDT_RST);
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	if (ret)
464*4882a593Smuzhiyun 		dev_err(sgm->dev, "set watchdog timer error!\n");
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	return ret;
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun 
sgm4154x_set_watchdog_timer(struct sgm4154x_device * sgm,int time)469*4882a593Smuzhiyun static int sgm4154x_set_watchdog_timer(struct sgm4154x_device *sgm, int time)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun 	u8 reg_val;
472*4882a593Smuzhiyun 	int ret;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	if (time == 0)
475*4882a593Smuzhiyun 		reg_val = SGM4154x_WDT_TIMER_DISABLE;
476*4882a593Smuzhiyun 	else if (time == 40)
477*4882a593Smuzhiyun 		reg_val = SGM4154x_WDT_TIMER_40S;
478*4882a593Smuzhiyun 	else if (time == 80)
479*4882a593Smuzhiyun 		reg_val = SGM4154x_WDT_TIMER_80S;
480*4882a593Smuzhiyun 	else
481*4882a593Smuzhiyun 		reg_val = SGM4154x_WDT_TIMER_160S;
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
484*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_5,
485*4882a593Smuzhiyun 				 SGM4154x_WDT_TIMER_MASK,
486*4882a593Smuzhiyun 				 reg_val);
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	if (ret) {
489*4882a593Smuzhiyun 		dev_err(sgm->dev, "set watchdog timer error!\n");
490*4882a593Smuzhiyun 		return ret;
491*4882a593Smuzhiyun 	}
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 	if (time) {
494*4882a593Smuzhiyun 		DBG("sgm41542: enable watchdog\n");
495*4882a593Smuzhiyun 		if (!sgm->watchdog_enable)
496*4882a593Smuzhiyun 			queue_delayed_work(sgm->sgm_monitor_wq,
497*4882a593Smuzhiyun 					   &sgm->sgm_delay_work,
498*4882a593Smuzhiyun 					   msecs_to_jiffies(1000 * 5));
499*4882a593Smuzhiyun 		sgm->watchdog_enable = true;
500*4882a593Smuzhiyun 	} else {
501*4882a593Smuzhiyun 		DBG("sgm41542: disable watchdog\n");
502*4882a593Smuzhiyun 		sgm->watchdog_enable = false;
503*4882a593Smuzhiyun 		sgm4154x_watchdog_timer_reset(sgm);
504*4882a593Smuzhiyun 	}
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun 	return ret;
507*4882a593Smuzhiyun }
508*4882a593Smuzhiyun 
sgm4154x_enable_charger(struct sgm4154x_device * sgm)509*4882a593Smuzhiyun static int sgm4154x_enable_charger(struct sgm4154x_device *sgm)
510*4882a593Smuzhiyun {
511*4882a593Smuzhiyun 	int ret;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
514*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_1,
515*4882a593Smuzhiyun 				 SGM4154x_CHRG_EN,
516*4882a593Smuzhiyun 				 SGM4154x_CHRG_EN);
517*4882a593Smuzhiyun 	if (ret)
518*4882a593Smuzhiyun 		dev_err(sgm->dev, "enable charger error!\n");
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	return ret;
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun 
sgm4154x_disable_charger(struct sgm4154x_device * sgm)523*4882a593Smuzhiyun static int sgm4154x_disable_charger(struct sgm4154x_device *sgm)
524*4882a593Smuzhiyun {
525*4882a593Smuzhiyun 	int ret;
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
528*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_1,
529*4882a593Smuzhiyun 				 SGM4154x_CHRG_EN,
530*4882a593Smuzhiyun 				 0);
531*4882a593Smuzhiyun 	if (ret)
532*4882a593Smuzhiyun 		dev_err(sgm->dev, "disable charger error!\n");
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 	return ret;
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun 
sgm4154x_set_vac_ovp(struct sgm4154x_device * sgm)537*4882a593Smuzhiyun static int sgm4154x_set_vac_ovp(struct sgm4154x_device *sgm)
538*4882a593Smuzhiyun {
539*4882a593Smuzhiyun 	int reg_val;
540*4882a593Smuzhiyun 	int ret;
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	reg_val = 0xFF & SGM4154x_VAC_OVP_MASK;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
545*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_6,
546*4882a593Smuzhiyun 				 SGM4154x_VAC_OVP_MASK,
547*4882a593Smuzhiyun 				 reg_val);
548*4882a593Smuzhiyun 	if (ret)
549*4882a593Smuzhiyun 		dev_err(sgm->dev, "set vac ovp error!\n");
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	return ret;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun 
sgm4154x_set_recharge_volt(struct sgm4154x_device * sgm,int recharge_volt)554*4882a593Smuzhiyun static int sgm4154x_set_recharge_volt(struct sgm4154x_device *sgm, int recharge_volt)
555*4882a593Smuzhiyun {
556*4882a593Smuzhiyun 	int reg_val;
557*4882a593Smuzhiyun 	int ret;
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	reg_val = (recharge_volt - SGM4154x_VRECHRG_OFFSET_mV) / SGM4154x_VRECHRG_STEP_mV;
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
562*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_4,
563*4882a593Smuzhiyun 				 SGM4154x_VRECHARGE,
564*4882a593Smuzhiyun 				 reg_val);
565*4882a593Smuzhiyun 	if (ret)
566*4882a593Smuzhiyun 		dev_err(sgm->dev, "set recharger error!\n");
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun 	return ret;
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun 
sgm4154x_get_state(struct sgm4154x_device * sgm,struct sgm4154x_state * state)571*4882a593Smuzhiyun static int sgm4154x_get_state(struct sgm4154x_device *sgm,
572*4882a593Smuzhiyun 			      struct sgm4154x_state *state)
573*4882a593Smuzhiyun {
574*4882a593Smuzhiyun 	int chrg_param_0, chrg_param_1, chrg_param_2;
575*4882a593Smuzhiyun 	int chrg_stat;
576*4882a593Smuzhiyun 	int fault;
577*4882a593Smuzhiyun 	int ret;
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	ret = regmap_read(sgm->regmap, SGM4154x_CHRG_STAT, &chrg_stat);
580*4882a593Smuzhiyun 	if (ret) {
581*4882a593Smuzhiyun 		pr_err("read SGM4154x_CHRG_STAT fail\n");
582*4882a593Smuzhiyun 		return ret;
583*4882a593Smuzhiyun 	}
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	DBG("SGM4154x_CHRG_STAT[0x%x]: 0x%x\n", SGM4154x_CHRG_STAT, chrg_stat);
586*4882a593Smuzhiyun 	state->chrg_type = chrg_stat & SGM4154x_VBUS_STAT_MASK;
587*4882a593Smuzhiyun 	state->chrg_stat = chrg_stat & SGM4154x_CHG_STAT_MASK;
588*4882a593Smuzhiyun 	state->online = !!(chrg_stat & SGM4154x_PG_STAT);
589*4882a593Smuzhiyun 	state->therm_stat = !!(chrg_stat & SGM4154x_THERM_STAT);
590*4882a593Smuzhiyun 	state->vsys_stat = !!(chrg_stat & SGM4154x_VSYS_STAT);
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 	ret = regmap_read(sgm->regmap, SGM4154x_CHRG_FAULT, &fault);
593*4882a593Smuzhiyun 	if (ret) {
594*4882a593Smuzhiyun 		pr_err("read SGM4154x_CHRG_FAULT fail\n");
595*4882a593Smuzhiyun 		return ret;
596*4882a593Smuzhiyun 	}
597*4882a593Smuzhiyun 	DBG("SGM4154x_CHRG_FAULT[0x%x]: 0x%x\n", SGM4154x_CHRG_FAULT, fault);
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	state->chrg_fault = fault;
600*4882a593Smuzhiyun 	state->ntc_fault = fault & SGM4154x_TEMP_MASK;
601*4882a593Smuzhiyun 	state->health = state->ntc_fault;
602*4882a593Smuzhiyun 	ret = regmap_read(sgm->regmap, SGM4154x_CHRG_CTRL_0, &chrg_param_0);
603*4882a593Smuzhiyun 	if (ret) {
604*4882a593Smuzhiyun 		pr_err("read SGM4154x_CHRG_CTRL_0 fail\n");
605*4882a593Smuzhiyun 		return ret;
606*4882a593Smuzhiyun 	}
607*4882a593Smuzhiyun 	state->hiz_en = !!(chrg_param_0 & SGM4154x_HIZ_EN);
608*4882a593Smuzhiyun 	DBG("SGM4154x_CHRG_CTRL_0[0x%x]: 0x%x\n", SGM4154x_CHRG_CTRL_0, chrg_param_0);
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	ret = regmap_read(sgm->regmap, SGM4154x_CHRG_CTRL_5, &chrg_param_1);
611*4882a593Smuzhiyun 	if (ret) {
612*4882a593Smuzhiyun 		pr_err("read SGM4154x_CHRG_CTRL_5 fail\n");
613*4882a593Smuzhiyun 		return ret;
614*4882a593Smuzhiyun 	}
615*4882a593Smuzhiyun 	state->term_en = !!(chrg_param_1 & SGM4154x_TERM_EN);
616*4882a593Smuzhiyun 	DBG("SGM4154x_CHRG_CTRL_5[0x%x]: 0x%x\n", SGM4154x_CHRG_CTRL_5, chrg_param_1);
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	ret = regmap_read(sgm->regmap, SGM4154x_CHRG_CTRL_a, &chrg_param_2);
619*4882a593Smuzhiyun 	if (ret) {
620*4882a593Smuzhiyun 		pr_err("read SGM4154x_CHRG_CTRL_a fail\n");
621*4882a593Smuzhiyun 		return ret;
622*4882a593Smuzhiyun 	}
623*4882a593Smuzhiyun 	state->vbus_gd = !!(chrg_param_2 & SGM4154x_VBUS_GOOD);
624*4882a593Smuzhiyun 	DBG("SGM4154x_CHRG_CTRL_a[0x%x]: 0x%x\n", SGM4154x_CHRG_CTRL_a, chrg_param_2);
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 	DBG("chrg_type: 0x%x\n", state->chrg_type);
627*4882a593Smuzhiyun 	DBG("chrg_stat: 0x%x\n", state->chrg_stat);
628*4882a593Smuzhiyun 	DBG("online: 0x%x\n", state->online);
629*4882a593Smuzhiyun 	DBG("therm_stat: 0x%x\n", state->therm_stat);
630*4882a593Smuzhiyun 	DBG("vsys_stat: 0x%x\n", state->vsys_stat);
631*4882a593Smuzhiyun 	DBG("chrg_fault: 0x%x\n", state->chrg_fault);
632*4882a593Smuzhiyun 	DBG("ntc_fault: 0x%x\n", state->ntc_fault);
633*4882a593Smuzhiyun 	DBG("health: 0x%x\n", state->health);
634*4882a593Smuzhiyun 	DBG("hiz_en: 0x%x\n", state->hiz_en);
635*4882a593Smuzhiyun 	DBG("term_en: 0x%x\n", state->term_en);
636*4882a593Smuzhiyun 	DBG("vbus_gd: 0x%x\n", state->vbus_gd);
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 	return ret;
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun 
sgm4154x_property_is_writeable(struct power_supply * psy,enum power_supply_property prop)641*4882a593Smuzhiyun static int sgm4154x_property_is_writeable(struct power_supply *psy,
642*4882a593Smuzhiyun 					  enum power_supply_property prop)
643*4882a593Smuzhiyun {
644*4882a593Smuzhiyun 	switch (prop) {
645*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
646*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
647*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
648*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_ONLINE:
649*4882a593Smuzhiyun 		return true;
650*4882a593Smuzhiyun 	default:
651*4882a593Smuzhiyun 		return false;
652*4882a593Smuzhiyun 	}
653*4882a593Smuzhiyun }
654*4882a593Smuzhiyun 
sgm4154x_charger_set_property(struct power_supply * psy,enum power_supply_property prop,const union power_supply_propval * val)655*4882a593Smuzhiyun static int sgm4154x_charger_set_property(struct power_supply *psy,
656*4882a593Smuzhiyun 					 enum power_supply_property prop,
657*4882a593Smuzhiyun 					 const union power_supply_propval *val)
658*4882a593Smuzhiyun {
659*4882a593Smuzhiyun 	struct sgm4154x_device *sgm = power_supply_get_drvdata(psy);
660*4882a593Smuzhiyun 	int ret = -EINVAL;
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	switch (prop) {
663*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_ONLINE:
664*4882a593Smuzhiyun 		if (val->intval) {
665*4882a593Smuzhiyun 			ret = sgm4154x_enable_charger(sgm);
666*4882a593Smuzhiyun 			sgm4154x_set_watchdog_timer(sgm, SGM4154x_WDT_TIMER_40S);
667*4882a593Smuzhiyun 		} else {
668*4882a593Smuzhiyun 			sgm4154x_set_watchdog_timer(sgm, 0);
669*4882a593Smuzhiyun 			ret = sgm4154x_disable_charger(sgm);
670*4882a593Smuzhiyun 		}
671*4882a593Smuzhiyun 		break;
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
674*4882a593Smuzhiyun 		ret = sgm4154x_set_input_curr_lim(sgm, val->intval);
675*4882a593Smuzhiyun 		break;
676*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
677*4882a593Smuzhiyun 		ret = sgm4154x_set_ichrg_curr(sgm, val->intval);
678*4882a593Smuzhiyun 		break;
679*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
680*4882a593Smuzhiyun 		ret = sgm4154x_set_chrg_volt(sgm, val->intval);
681*4882a593Smuzhiyun 		break;
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	default:
684*4882a593Smuzhiyun 		return -EINVAL;
685*4882a593Smuzhiyun 	}
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun 	return ret;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun 
sgm4154x_charger_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)690*4882a593Smuzhiyun static int sgm4154x_charger_get_property(struct power_supply *psy,
691*4882a593Smuzhiyun 					 enum power_supply_property psp,
692*4882a593Smuzhiyun 					 union power_supply_propval *val)
693*4882a593Smuzhiyun {
694*4882a593Smuzhiyun 	struct sgm4154x_device *sgm = power_supply_get_drvdata(psy);
695*4882a593Smuzhiyun 	struct sgm4154x_state state;
696*4882a593Smuzhiyun 	int ret = 0;
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	mutex_lock(&sgm->lock);
699*4882a593Smuzhiyun 	ret = sgm4154x_get_state(sgm, &state);
700*4882a593Smuzhiyun 	if (ret) {
701*4882a593Smuzhiyun 		dev_err(sgm->dev, "get state error!\n");
702*4882a593Smuzhiyun 		mutex_unlock(&sgm->lock);
703*4882a593Smuzhiyun 		return ret;
704*4882a593Smuzhiyun 	}
705*4882a593Smuzhiyun 	sgm->state = state;
706*4882a593Smuzhiyun 	mutex_unlock(&sgm->lock);
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 	switch (psp) {
709*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_STATUS:
710*4882a593Smuzhiyun 		if (!state.chrg_type || (state.chrg_type == SGM4154x_OTG_MODE))
711*4882a593Smuzhiyun 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
712*4882a593Smuzhiyun 		else if (!state.chrg_stat)
713*4882a593Smuzhiyun 			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
714*4882a593Smuzhiyun 		else if (state.chrg_stat == SGM4154x_TERM_CHRG)
715*4882a593Smuzhiyun 			val->intval = POWER_SUPPLY_STATUS_FULL;
716*4882a593Smuzhiyun 		else
717*4882a593Smuzhiyun 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
718*4882a593Smuzhiyun 		break;
719*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
720*4882a593Smuzhiyun 		switch (state.chrg_stat) {
721*4882a593Smuzhiyun 		case SGM4154x_PRECHRG:
722*4882a593Smuzhiyun 			val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
723*4882a593Smuzhiyun 			break;
724*4882a593Smuzhiyun 		case SGM4154x_FAST_CHRG:
725*4882a593Smuzhiyun 			val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
726*4882a593Smuzhiyun 			break;
727*4882a593Smuzhiyun 		case SGM4154x_TERM_CHRG:
728*4882a593Smuzhiyun 			val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
729*4882a593Smuzhiyun 			break;
730*4882a593Smuzhiyun 		case SGM4154x_NOT_CHRGING:
731*4882a593Smuzhiyun 			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
732*4882a593Smuzhiyun 			break;
733*4882a593Smuzhiyun 		default:
734*4882a593Smuzhiyun 			val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
735*4882a593Smuzhiyun 		}
736*4882a593Smuzhiyun 		break;
737*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_MANUFACTURER:
738*4882a593Smuzhiyun 		val->strval = SGM4154x_MANUFACTURER;
739*4882a593Smuzhiyun 		break;
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_MODEL_NAME:
742*4882a593Smuzhiyun 		val->strval = SGM4154x_NAME;
743*4882a593Smuzhiyun 		break;
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_ONLINE:
746*4882a593Smuzhiyun 		val->intval = state.online;
747*4882a593Smuzhiyun 		break;
748*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_PRESENT:
749*4882a593Smuzhiyun 		val->intval = state.vbus_gd;
750*4882a593Smuzhiyun 		break;
751*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_TYPE:
752*4882a593Smuzhiyun 		val->intval = POWER_SUPPLY_TYPE_USB;
753*4882a593Smuzhiyun 		break;
754*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
755*4882a593Smuzhiyun 		val->intval = sgm->init_data.max_vreg;
756*4882a593Smuzhiyun 		break;
757*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
758*4882a593Smuzhiyun 		val->intval = SGM4154x_ICHRG_I_MAX_uA;
759*4882a593Smuzhiyun 		break;
760*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
761*4882a593Smuzhiyun 		val->intval = 12 * 1000 * 1000;
762*4882a593Smuzhiyun 		break;
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
765*4882a593Smuzhiyun 		 val->intval = sgm4154x_get_input_curr_lim(sgm);
766*4882a593Smuzhiyun 		if (val->intval < 0)
767*4882a593Smuzhiyun 			return  -EINVAL;
768*4882a593Smuzhiyun 		break;
769*4882a593Smuzhiyun 	default:
770*4882a593Smuzhiyun 		return -EINVAL;
771*4882a593Smuzhiyun 	}
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun 	return ret;
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun 
registers_show(struct device * dev,struct device_attribute * attr,char * buf)776*4882a593Smuzhiyun static ssize_t registers_show(struct device *dev,
777*4882a593Smuzhiyun 			      struct device_attribute *attr,
778*4882a593Smuzhiyun 			      char *buf)
779*4882a593Smuzhiyun {
780*4882a593Smuzhiyun 	struct sgm4154x_device *sgm4154x = dev_get_drvdata(dev);
781*4882a593Smuzhiyun 	u8 tmpbuf[30];
782*4882a593Smuzhiyun 	int idx = 0;
783*4882a593Smuzhiyun 	u8 addr;
784*4882a593Smuzhiyun 	int val;
785*4882a593Smuzhiyun 	int len;
786*4882a593Smuzhiyun 	int ret;
787*4882a593Smuzhiyun 
788*4882a593Smuzhiyun 	for (addr = 0x0; addr <= SGM4154x_CHRG_CTRL_f; addr++) {
789*4882a593Smuzhiyun 		ret = regmap_read(sgm4154x->regmap, addr, &val);
790*4882a593Smuzhiyun 		if (ret == 0) {
791*4882a593Smuzhiyun 			len = snprintf(tmpbuf, 30,
792*4882a593Smuzhiyun 				       "Reg[%.2X] = 0x%.2x\n",
793*4882a593Smuzhiyun 				       addr,
794*4882a593Smuzhiyun 				       val);
795*4882a593Smuzhiyun 			memcpy(&buf[idx], tmpbuf, len);
796*4882a593Smuzhiyun 			idx += len;
797*4882a593Smuzhiyun 		}
798*4882a593Smuzhiyun 	}
799*4882a593Smuzhiyun 
800*4882a593Smuzhiyun 	return idx;
801*4882a593Smuzhiyun }
802*4882a593Smuzhiyun 
registers_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)803*4882a593Smuzhiyun static ssize_t registers_store(struct device *dev,
804*4882a593Smuzhiyun 			       struct device_attribute *attr,
805*4882a593Smuzhiyun 			       const char *buf, size_t count)
806*4882a593Smuzhiyun {
807*4882a593Smuzhiyun 	struct sgm4154x_device *sgm4154x = dev_get_drvdata(dev);
808*4882a593Smuzhiyun 	unsigned int reg;
809*4882a593Smuzhiyun 	int ret;
810*4882a593Smuzhiyun 	int val;
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	ret = sscanf(buf, "%x %x", &reg, &val);
813*4882a593Smuzhiyun 	if (ret == 2 && reg <= SGM4154x_CHRG_CTRL_f)
814*4882a593Smuzhiyun 		regmap_write(sgm4154x->regmap, (unsigned char)reg, val);
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun 	return count;
817*4882a593Smuzhiyun }
818*4882a593Smuzhiyun static DEVICE_ATTR_RW(registers);
819*4882a593Smuzhiyun 
sgm4154x_create_device_node(struct device * dev)820*4882a593Smuzhiyun static void sgm4154x_create_device_node(struct device *dev)
821*4882a593Smuzhiyun {
822*4882a593Smuzhiyun 	device_create_file(dev, &dev_attr_registers);
823*4882a593Smuzhiyun }
824*4882a593Smuzhiyun 
sgm4154x_irq_handler_thread(int irq,void * private)825*4882a593Smuzhiyun static irqreturn_t sgm4154x_irq_handler_thread(int irq, void *private)
826*4882a593Smuzhiyun {
827*4882a593Smuzhiyun 	struct sgm4154x_device *sgm4154x = private;
828*4882a593Smuzhiyun 	struct sgm4154x_state state;
829*4882a593Smuzhiyun 	int ret;
830*4882a593Smuzhiyun 	u8 addr;
831*4882a593Smuzhiyun 	int val;
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 	for (addr = 0x0; addr <= SGM4154x_CHRG_CTRL_f; addr++) {
834*4882a593Smuzhiyun 		ret = regmap_read(sgm4154x->regmap, addr, &val);
835*4882a593Smuzhiyun 		if (ret)
836*4882a593Smuzhiyun 			dev_err(sgm4154x->dev, "read addr[0x%x] error!\n", addr);
837*4882a593Smuzhiyun 		DBG("[0x%x]: 0x%x\n", addr, val);
838*4882a593Smuzhiyun 	}
839*4882a593Smuzhiyun 	ret = sgm4154x_get_state(sgm4154x, &state);
840*4882a593Smuzhiyun 	if (ret) {
841*4882a593Smuzhiyun 		dev_err(sgm4154x->dev, "get state error!\n");
842*4882a593Smuzhiyun 		return IRQ_NONE;
843*4882a593Smuzhiyun 	}
844*4882a593Smuzhiyun 	sgm4154x->state = state;
845*4882a593Smuzhiyun 	if (state.vbus_gd) {
846*4882a593Smuzhiyun 		if (sgm4154x->input_current >= DEFAULT_INPUT_CURRENT) {
847*4882a593Smuzhiyun 			ret = sgm4154x_set_input_curr_lim(sgm4154x, sgm4154x->input_current);
848*4882a593Smuzhiyun 			if (ret) {
849*4882a593Smuzhiyun 				dev_err(sgm4154x->dev, "set input current error!\n");
850*4882a593Smuzhiyun 				return IRQ_NONE;
851*4882a593Smuzhiyun 			}
852*4882a593Smuzhiyun 		}
853*4882a593Smuzhiyun 	}
854*4882a593Smuzhiyun 	power_supply_changed(sgm4154x->charger);
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 	return IRQ_HANDLED;
857*4882a593Smuzhiyun }
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun static enum power_supply_property sgm4154x_power_supply_props[] = {
860*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_TYPE,
861*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_MANUFACTURER,
862*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_MODEL_NAME,
863*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_STATUS,
864*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_ONLINE,
865*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT,
866*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
867*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_CHARGE_TYPE,
868*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
869*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
870*4882a593Smuzhiyun 	POWER_SUPPLY_PROP_PRESENT
871*4882a593Smuzhiyun };
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun static char *sgm4154x_charger_supplied_to[] = {
874*4882a593Smuzhiyun 	"usb",
875*4882a593Smuzhiyun };
876*4882a593Smuzhiyun 
877*4882a593Smuzhiyun static struct power_supply_desc sgm4154x_power_supply_desc = {
878*4882a593Smuzhiyun 	.name = "sgm4154x-charger",
879*4882a593Smuzhiyun 	.type = POWER_SUPPLY_TYPE_USB,
880*4882a593Smuzhiyun 	.properties = sgm4154x_power_supply_props,
881*4882a593Smuzhiyun 	.num_properties = ARRAY_SIZE(sgm4154x_power_supply_props),
882*4882a593Smuzhiyun 	.get_property = sgm4154x_charger_get_property,
883*4882a593Smuzhiyun 	.set_property = sgm4154x_charger_set_property,
884*4882a593Smuzhiyun 	.property_is_writeable = sgm4154x_property_is_writeable,
885*4882a593Smuzhiyun };
886*4882a593Smuzhiyun 
sgm4154x_is_volatile_reg(struct device * dev,unsigned int reg)887*4882a593Smuzhiyun static bool sgm4154x_is_volatile_reg(struct device *dev, unsigned int reg)
888*4882a593Smuzhiyun {
889*4882a593Smuzhiyun 	switch (reg) {
890*4882a593Smuzhiyun 	case SGM4154x_CHRG_CTRL_0 ... SGM4154x_CHRG_CTRL_f:
891*4882a593Smuzhiyun 		return true;
892*4882a593Smuzhiyun 	default:
893*4882a593Smuzhiyun 		return false;
894*4882a593Smuzhiyun 	}
895*4882a593Smuzhiyun }
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun static const struct regmap_config sgm4154x_regmap_config = {
898*4882a593Smuzhiyun 	.reg_bits = 8,
899*4882a593Smuzhiyun 	.val_bits = 8,
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun 	.max_register = SGM4154x_CHRG_CTRL_f,
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun 	.cache_type = REGCACHE_RBTREE,
904*4882a593Smuzhiyun 	.volatile_reg = sgm4154x_is_volatile_reg,
905*4882a593Smuzhiyun };
906*4882a593Smuzhiyun 
sgm4154x_power_supply_init(struct sgm4154x_device * sgm,struct device * dev)907*4882a593Smuzhiyun static int sgm4154x_power_supply_init(struct sgm4154x_device *sgm,
908*4882a593Smuzhiyun 				      struct device *dev)
909*4882a593Smuzhiyun {
910*4882a593Smuzhiyun 	struct power_supply_config psy_cfg = { .drv_data = sgm,
911*4882a593Smuzhiyun 					       .of_node = dev->of_node, };
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun 	psy_cfg.supplied_to = sgm4154x_charger_supplied_to;
914*4882a593Smuzhiyun 	psy_cfg.num_supplicants = ARRAY_SIZE(sgm4154x_charger_supplied_to);
915*4882a593Smuzhiyun 	psy_cfg.of_node = dev->of_node;
916*4882a593Smuzhiyun 	sgm->charger = devm_power_supply_register(sgm->dev,
917*4882a593Smuzhiyun 						  &sgm4154x_power_supply_desc,
918*4882a593Smuzhiyun 						  &psy_cfg);
919*4882a593Smuzhiyun 	if (IS_ERR(sgm->charger))
920*4882a593Smuzhiyun 		return -EINVAL;
921*4882a593Smuzhiyun 
922*4882a593Smuzhiyun 	return 0;
923*4882a593Smuzhiyun }
924*4882a593Smuzhiyun 
sgm4154x_hw_init(struct sgm4154x_device * sgm)925*4882a593Smuzhiyun static int sgm4154x_hw_init(struct sgm4154x_device *sgm)
926*4882a593Smuzhiyun {
927*4882a593Smuzhiyun 	struct power_supply_battery_info bat_info = { };
928*4882a593Smuzhiyun 	int chrg_stat, ret = 0;
929*4882a593Smuzhiyun 
930*4882a593Smuzhiyun 	ret = power_supply_get_battery_info(sgm->charger, &bat_info);
931*4882a593Smuzhiyun 	if (ret) {
932*4882a593Smuzhiyun 		pr_info("sgm4154x: no battery information is supplied\n");
933*4882a593Smuzhiyun 		/*
934*4882a593Smuzhiyun 		 * If no battery information is supplied, we should set
935*4882a593Smuzhiyun 		 * default charge termination current to 120 mA, and default
936*4882a593Smuzhiyun 		 * charge termination voltage to 4.35V.
937*4882a593Smuzhiyun 		 */
938*4882a593Smuzhiyun 		bat_info.constant_charge_current_max_ua =
939*4882a593Smuzhiyun 			SGM4154x_ICHRG_I_DEF_uA;
940*4882a593Smuzhiyun 		bat_info.constant_charge_voltage_max_uv =
941*4882a593Smuzhiyun 			SGM4154x_VREG_V_DEF_uV;
942*4882a593Smuzhiyun 		bat_info.precharge_current_ua =
943*4882a593Smuzhiyun 			SGM4154x_PRECHRG_I_DEF_uA;
944*4882a593Smuzhiyun 		bat_info.charge_term_current_ua =
945*4882a593Smuzhiyun 			SGM4154x_TERMCHRG_I_DEF_uA;
946*4882a593Smuzhiyun 		sgm->init_data.max_ichg =
947*4882a593Smuzhiyun 			SGM4154x_ICHRG_I_MAX_uA;
948*4882a593Smuzhiyun 		sgm->init_data.max_vreg = SGM4154x_VREG_V_DEF_uV;
949*4882a593Smuzhiyun 	}
950*4882a593Smuzhiyun 	if (!bat_info.constant_charge_current_max_ua)
951*4882a593Smuzhiyun 		bat_info.constant_charge_current_max_ua =
952*4882a593Smuzhiyun 					SGM4154x_ICHRG_I_MAX_uA;
953*4882a593Smuzhiyun 	if (!bat_info.constant_charge_voltage_max_uv)
954*4882a593Smuzhiyun 		bat_info.constant_charge_voltage_max_uv =
955*4882a593Smuzhiyun 			SGM4154x_VREG_V_DEF_uV;
956*4882a593Smuzhiyun 	if (!bat_info.precharge_current_ua)
957*4882a593Smuzhiyun 		bat_info.precharge_current_ua =
958*4882a593Smuzhiyun 			SGM4154x_PRECHRG_I_DEF_uA;
959*4882a593Smuzhiyun 	if (!bat_info.charge_term_current_ua)
960*4882a593Smuzhiyun 		bat_info.charge_term_current_ua =
961*4882a593Smuzhiyun 			SGM4154x_TERMCHRG_I_DEF_uA;
962*4882a593Smuzhiyun 	if (!sgm->init_data.max_ichg)
963*4882a593Smuzhiyun 		sgm->init_data.max_ichg =
964*4882a593Smuzhiyun 			SGM4154x_ICHRG_I_MAX_uA;
965*4882a593Smuzhiyun 
966*4882a593Smuzhiyun 	if (bat_info.constant_charge_voltage_max_uv)
967*4882a593Smuzhiyun 		sgm->init_data.max_vreg = bat_info.constant_charge_voltage_max_uv;
968*4882a593Smuzhiyun 
969*4882a593Smuzhiyun 	ret = sgm4154x_set_watchdog_timer(sgm, 0);
970*4882a593Smuzhiyun 	if (ret)
971*4882a593Smuzhiyun 		goto err_out;
972*4882a593Smuzhiyun 
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun 	ret = sgm4154x_set_prechrg_curr(sgm, bat_info.precharge_current_ua);
975*4882a593Smuzhiyun 	if (ret)
976*4882a593Smuzhiyun 		goto err_out;
977*4882a593Smuzhiyun 
978*4882a593Smuzhiyun 	ret = sgm4154x_set_chrg_volt(sgm,
979*4882a593Smuzhiyun 				     sgm->init_data.max_vreg);
980*4882a593Smuzhiyun 	if (ret)
981*4882a593Smuzhiyun 		goto err_out;
982*4882a593Smuzhiyun 
983*4882a593Smuzhiyun 	ret = sgm4154x_set_term_curr(sgm,
984*4882a593Smuzhiyun 				     bat_info.charge_term_current_ua);
985*4882a593Smuzhiyun 	if (ret)
986*4882a593Smuzhiyun 		goto err_out;
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun 	ret = sgm4154x_set_input_volt_lim(sgm, sgm->init_data.vlim);
989*4882a593Smuzhiyun 	if (ret)
990*4882a593Smuzhiyun 		goto err_out;
991*4882a593Smuzhiyun 
992*4882a593Smuzhiyun 	ret = regmap_read(sgm->regmap, SGM4154x_CHRG_STAT, &chrg_stat);
993*4882a593Smuzhiyun 	if (ret) {
994*4882a593Smuzhiyun 		pr_err("read SGM4154x_CHRG_STAT fail\n");
995*4882a593Smuzhiyun 		goto err_out;
996*4882a593Smuzhiyun 	}
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun 	if (!(chrg_stat & SGM4154x_PG_STAT)) {
999*4882a593Smuzhiyun 		ret = sgm4154x_set_input_curr_lim(sgm, DEFAULT_INPUT_CURRENT);
1000*4882a593Smuzhiyun 		if (ret)
1001*4882a593Smuzhiyun 			goto err_out;
1002*4882a593Smuzhiyun 		ret = sgm4154x_set_ichrg_curr(sgm,
1003*4882a593Smuzhiyun 			      bat_info.constant_charge_current_max_ua);
1004*4882a593Smuzhiyun 		if (ret)
1005*4882a593Smuzhiyun 			goto err_out;
1006*4882a593Smuzhiyun 
1007*4882a593Smuzhiyun 		ret = sgm4154x_disable_charger(sgm);
1008*4882a593Smuzhiyun 		if (ret)
1009*4882a593Smuzhiyun 			goto err_out;
1010*4882a593Smuzhiyun 	}
1011*4882a593Smuzhiyun 	ret = sgm4154x_set_vac_ovp(sgm);
1012*4882a593Smuzhiyun 	if (ret)
1013*4882a593Smuzhiyun 		goto err_out;
1014*4882a593Smuzhiyun 
1015*4882a593Smuzhiyun 	regmap_update_bits(sgm->regmap,
1016*4882a593Smuzhiyun 			   SGM4154x_CHRG_CTRL_d,
1017*4882a593Smuzhiyun 			   0x01,
1018*4882a593Smuzhiyun 			   0x00);
1019*4882a593Smuzhiyun 
1020*4882a593Smuzhiyun 	regmap_update_bits(sgm->regmap,
1021*4882a593Smuzhiyun 			   SGM4154x_CHRG_CTRL_a,
1022*4882a593Smuzhiyun 			   SGM4154x_IINDPM_INT_MASK,
1023*4882a593Smuzhiyun 			   SGM4154x_IINDPM_INT_DIS);
1024*4882a593Smuzhiyun 
1025*4882a593Smuzhiyun 	regmap_update_bits(sgm->regmap,
1026*4882a593Smuzhiyun 			   SGM4154x_CHRG_CTRL_a,
1027*4882a593Smuzhiyun 			   SGM4154x_VINDPM_INT_MASK,
1028*4882a593Smuzhiyun 			   SGM4154x_VINDPM_INT_DIS);
1029*4882a593Smuzhiyun 
1030*4882a593Smuzhiyun 
1031*4882a593Smuzhiyun 	ret = sgm4154x_set_recharge_volt(sgm, 200);
1032*4882a593Smuzhiyun 	if (ret)
1033*4882a593Smuzhiyun 		goto err_out;
1034*4882a593Smuzhiyun 
1035*4882a593Smuzhiyun 	DBG("ichrg_curr:%d\n"
1036*4882a593Smuzhiyun 	    "prechrg_curr:%d\n"
1037*4882a593Smuzhiyun 	    "chrg_vol:%d\n"
1038*4882a593Smuzhiyun 	    "term_curr:%d\n"
1039*4882a593Smuzhiyun 	    "input_curr_lim:%d\n",
1040*4882a593Smuzhiyun 	    bat_info.constant_charge_current_max_ua,
1041*4882a593Smuzhiyun 	    bat_info.precharge_current_ua,
1042*4882a593Smuzhiyun 	    bat_info.constant_charge_voltage_max_uv,
1043*4882a593Smuzhiyun 	    bat_info.charge_term_current_ua,
1044*4882a593Smuzhiyun 	    sgm->init_data.ilim);
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 	return 0;
1047*4882a593Smuzhiyun 
1048*4882a593Smuzhiyun err_out:
1049*4882a593Smuzhiyun 	return ret;
1050*4882a593Smuzhiyun }
1051*4882a593Smuzhiyun 
sgm4154x_parse_dt(struct sgm4154x_device * sgm)1052*4882a593Smuzhiyun static int sgm4154x_parse_dt(struct sgm4154x_device *sgm)
1053*4882a593Smuzhiyun {
1054*4882a593Smuzhiyun 	int ret;
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun 	ret = device_property_read_u32(sgm->dev,
1057*4882a593Smuzhiyun 				       "input-voltage-limit-microvolt",
1058*4882a593Smuzhiyun 				       &sgm->init_data.vlim);
1059*4882a593Smuzhiyun 	if (ret)
1060*4882a593Smuzhiyun 		sgm->init_data.vlim = SGM4154x_VINDPM_DEF_uV;
1061*4882a593Smuzhiyun 
1062*4882a593Smuzhiyun 	if (sgm->init_data.vlim > SGM4154x_VINDPM_V_MAX_uV ||
1063*4882a593Smuzhiyun 	    sgm->init_data.vlim < SGM4154x_VINDPM_V_MIN_uV)
1064*4882a593Smuzhiyun 		return -EINVAL;
1065*4882a593Smuzhiyun 
1066*4882a593Smuzhiyun 	ret = device_property_read_u32(sgm->dev,
1067*4882a593Smuzhiyun 				       "input-current-limit-microamp",
1068*4882a593Smuzhiyun 				       &sgm->init_data.ilim);
1069*4882a593Smuzhiyun 	if (ret)
1070*4882a593Smuzhiyun 		sgm->init_data.ilim = SGM4154x_IINDPM_DEF_uA;
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	if (sgm->init_data.ilim > SGM4154x_IINDPM_I_MAX_uA ||
1073*4882a593Smuzhiyun 	    sgm->init_data.ilim < SGM4154x_IINDPM_I_MIN_uA)
1074*4882a593Smuzhiyun 		return -EINVAL;
1075*4882a593Smuzhiyun 
1076*4882a593Smuzhiyun 	return 0;
1077*4882a593Smuzhiyun }
1078*4882a593Smuzhiyun 
sgm4154x_set_otg_voltage(struct sgm4154x_device * sgm,int uv)1079*4882a593Smuzhiyun static int sgm4154x_set_otg_voltage(struct sgm4154x_device *sgm, int uv)
1080*4882a593Smuzhiyun {
1081*4882a593Smuzhiyun 	int ret = 0;
1082*4882a593Smuzhiyun 	int reg_val = -1;
1083*4882a593Smuzhiyun 	int i = 0;
1084*4882a593Smuzhiyun 
1085*4882a593Smuzhiyun 	while (i < 4) {
1086*4882a593Smuzhiyun 		if (uv == BOOST_VOLT_LIMIT[i]) {
1087*4882a593Smuzhiyun 			reg_val = i;
1088*4882a593Smuzhiyun 			break;
1089*4882a593Smuzhiyun 		}
1090*4882a593Smuzhiyun 		i++;
1091*4882a593Smuzhiyun 	}
1092*4882a593Smuzhiyun 	if (reg_val < 0)
1093*4882a593Smuzhiyun 		return reg_val;
1094*4882a593Smuzhiyun 	reg_val = reg_val << 4;
1095*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
1096*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_6,
1097*4882a593Smuzhiyun 				 SGM4154x_BOOSTV,
1098*4882a593Smuzhiyun 				 reg_val);
1099*4882a593Smuzhiyun 	if (ret) {
1100*4882a593Smuzhiyun 		dev_err(sgm->dev, "set otg voltage error!\n");
1101*4882a593Smuzhiyun 		return ret;
1102*4882a593Smuzhiyun 	}
1103*4882a593Smuzhiyun 
1104*4882a593Smuzhiyun 	return ret;
1105*4882a593Smuzhiyun }
1106*4882a593Smuzhiyun 
sgm4154x_set_otg_current(struct sgm4154x_device * sgm,int ua)1107*4882a593Smuzhiyun static int sgm4154x_set_otg_current(struct sgm4154x_device *sgm, int ua)
1108*4882a593Smuzhiyun {
1109*4882a593Smuzhiyun 	int ret = 0;
1110*4882a593Smuzhiyun 
1111*4882a593Smuzhiyun 	if (ua == BOOST_CURRENT_LIMIT[0]) {
1112*4882a593Smuzhiyun 		ret = regmap_update_bits(sgm->regmap,
1113*4882a593Smuzhiyun 					 SGM4154x_CHRG_CTRL_2,
1114*4882a593Smuzhiyun 					 SGM4154x_BOOST_LIM,
1115*4882a593Smuzhiyun 					 0);
1116*4882a593Smuzhiyun 		if (ret) {
1117*4882a593Smuzhiyun 			dev_err(sgm->dev, "set boost current limit error!\n");
1118*4882a593Smuzhiyun 			return ret;
1119*4882a593Smuzhiyun 		}
1120*4882a593Smuzhiyun 	} else if (ua == BOOST_CURRENT_LIMIT[1]) {
1121*4882a593Smuzhiyun 		ret = regmap_update_bits(sgm->regmap,
1122*4882a593Smuzhiyun 					 SGM4154x_CHRG_CTRL_2,
1123*4882a593Smuzhiyun 					 SGM4154x_BOOST_LIM,
1124*4882a593Smuzhiyun 					 BIT(7));
1125*4882a593Smuzhiyun 		if (ret) {
1126*4882a593Smuzhiyun 			dev_err(sgm->dev, "set boost current limit error!\n");
1127*4882a593Smuzhiyun 			return ret;
1128*4882a593Smuzhiyun 		}
1129*4882a593Smuzhiyun 	}
1130*4882a593Smuzhiyun 
1131*4882a593Smuzhiyun 	return ret;
1132*4882a593Smuzhiyun }
1133*4882a593Smuzhiyun 
sgm4154x_enable_vbus(struct regulator_dev * rdev)1134*4882a593Smuzhiyun static int sgm4154x_enable_vbus(struct regulator_dev *rdev)
1135*4882a593Smuzhiyun {
1136*4882a593Smuzhiyun 	struct sgm4154x_device *sgm = rdev_get_drvdata(rdev);
1137*4882a593Smuzhiyun 	int ret = 0;
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
1140*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_1,
1141*4882a593Smuzhiyun 				 SGM4154x_OTG_EN,
1142*4882a593Smuzhiyun 				 SGM4154x_OTG_EN);
1143*4882a593Smuzhiyun 	if (ret) {
1144*4882a593Smuzhiyun 		dev_err(sgm->dev, "set OTG enable error!\n");
1145*4882a593Smuzhiyun 		return ret;
1146*4882a593Smuzhiyun 	}
1147*4882a593Smuzhiyun 
1148*4882a593Smuzhiyun 	return ret;
1149*4882a593Smuzhiyun }
1150*4882a593Smuzhiyun 
sgm4154x_disable_vbus(struct regulator_dev * rdev)1151*4882a593Smuzhiyun static int sgm4154x_disable_vbus(struct regulator_dev *rdev)
1152*4882a593Smuzhiyun {
1153*4882a593Smuzhiyun 	struct sgm4154x_device *sgm = rdev_get_drvdata(rdev);
1154*4882a593Smuzhiyun 	int ret = 0;
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 	ret = regmap_update_bits(sgm->regmap,
1157*4882a593Smuzhiyun 				 SGM4154x_CHRG_CTRL_1,
1158*4882a593Smuzhiyun 				 SGM4154x_OTG_EN,
1159*4882a593Smuzhiyun 				 0);
1160*4882a593Smuzhiyun 	if (ret) {
1161*4882a593Smuzhiyun 		dev_err(sgm->dev, "set OTG disable error!\n");
1162*4882a593Smuzhiyun 		return ret;
1163*4882a593Smuzhiyun 	}
1164*4882a593Smuzhiyun 
1165*4882a593Smuzhiyun 	return ret;
1166*4882a593Smuzhiyun }
1167*4882a593Smuzhiyun 
sgm4154x_is_enabled_vbus(struct regulator_dev * rdev)1168*4882a593Smuzhiyun static int sgm4154x_is_enabled_vbus(struct regulator_dev *rdev)
1169*4882a593Smuzhiyun {
1170*4882a593Smuzhiyun 	struct sgm4154x_device *sgm = rdev_get_drvdata(rdev);
1171*4882a593Smuzhiyun 	int temp = 0;
1172*4882a593Smuzhiyun 	int ret = 0;
1173*4882a593Smuzhiyun 
1174*4882a593Smuzhiyun 	ret = regmap_read(sgm->regmap, SGM4154x_CHRG_CTRL_1, &temp);
1175*4882a593Smuzhiyun 	if (ret) {
1176*4882a593Smuzhiyun 		dev_err(sgm->dev, "get vbus status error!\n");
1177*4882a593Smuzhiyun 		return ret;
1178*4882a593Smuzhiyun 	}
1179*4882a593Smuzhiyun 
1180*4882a593Smuzhiyun 	return (temp & SGM4154x_OTG_EN) ? 1 : 0;
1181*4882a593Smuzhiyun }
1182*4882a593Smuzhiyun 
1183*4882a593Smuzhiyun static const struct regulator_ops sgm4154x_vbus_ops = {
1184*4882a593Smuzhiyun 	.enable = sgm4154x_enable_vbus,
1185*4882a593Smuzhiyun 	.disable = sgm4154x_disable_vbus,
1186*4882a593Smuzhiyun 	.is_enabled = sgm4154x_is_enabled_vbus,
1187*4882a593Smuzhiyun };
1188*4882a593Smuzhiyun 
1189*4882a593Smuzhiyun static struct regulator_desc sgm4154x_otg_rdesc = {
1190*4882a593Smuzhiyun 	.of_match = "otg-vbus",
1191*4882a593Smuzhiyun 	.name = "otg-vbus",
1192*4882a593Smuzhiyun 	.regulators_node = of_match_ptr("regulators"),
1193*4882a593Smuzhiyun 	.ops = &sgm4154x_vbus_ops,
1194*4882a593Smuzhiyun 	.owner = THIS_MODULE,
1195*4882a593Smuzhiyun 	.type = REGULATOR_VOLTAGE,
1196*4882a593Smuzhiyun 	.fixed_uV = 5000000,
1197*4882a593Smuzhiyun 	.n_voltages = 1,
1198*4882a593Smuzhiyun };
1199*4882a593Smuzhiyun 
sgm4154x_vbus_regulator_register(struct sgm4154x_device * sgm)1200*4882a593Smuzhiyun static int sgm4154x_vbus_regulator_register(struct sgm4154x_device *sgm)
1201*4882a593Smuzhiyun {
1202*4882a593Smuzhiyun 	struct device_node *np;
1203*4882a593Smuzhiyun 	struct regulator_config config = {};
1204*4882a593Smuzhiyun 	int ret = 0;
1205*4882a593Smuzhiyun 
1206*4882a593Smuzhiyun 	np = of_get_child_by_name(sgm->dev->of_node, "regulators");
1207*4882a593Smuzhiyun 	if (!np) {
1208*4882a593Smuzhiyun 		dev_warn(sgm->dev, "cannot find regulators node\n");
1209*4882a593Smuzhiyun 		return -ENXIO;
1210*4882a593Smuzhiyun 	}
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun 	/* otg regulator */
1213*4882a593Smuzhiyun 	config.dev = sgm->dev;
1214*4882a593Smuzhiyun 	config.driver_data = sgm;
1215*4882a593Smuzhiyun 	sgm->otg_rdev = devm_regulator_register(sgm->dev,
1216*4882a593Smuzhiyun 						&sgm4154x_otg_rdesc,
1217*4882a593Smuzhiyun 						&config);
1218*4882a593Smuzhiyun 	if (IS_ERR(sgm->otg_rdev))
1219*4882a593Smuzhiyun 		ret = PTR_ERR(sgm->otg_rdev);
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 	return ret;
1222*4882a593Smuzhiyun }
1223*4882a593Smuzhiyun 
sgm4154x_suspend_notifier(struct notifier_block * nb,unsigned long event,void * dummy)1224*4882a593Smuzhiyun static int sgm4154x_suspend_notifier(struct notifier_block *nb,
1225*4882a593Smuzhiyun 				     unsigned long event,
1226*4882a593Smuzhiyun 				     void *dummy)
1227*4882a593Smuzhiyun {
1228*4882a593Smuzhiyun 	struct sgm4154x_device *sgm = container_of(nb, struct sgm4154x_device, pm_nb);
1229*4882a593Smuzhiyun 
1230*4882a593Smuzhiyun 	switch (event) {
1231*4882a593Smuzhiyun 
1232*4882a593Smuzhiyun 	case PM_SUSPEND_PREPARE:
1233*4882a593Smuzhiyun 		sgm->sgm4154x_suspend_flag = 1;
1234*4882a593Smuzhiyun 		return NOTIFY_OK;
1235*4882a593Smuzhiyun 
1236*4882a593Smuzhiyun 	case PM_POST_SUSPEND:
1237*4882a593Smuzhiyun 		sgm->sgm4154x_suspend_flag = 0;
1238*4882a593Smuzhiyun 		return NOTIFY_OK;
1239*4882a593Smuzhiyun 
1240*4882a593Smuzhiyun 	default:
1241*4882a593Smuzhiyun 		return NOTIFY_DONE;
1242*4882a593Smuzhiyun 	}
1243*4882a593Smuzhiyun }
1244*4882a593Smuzhiyun 
sgm4154x_hw_chipid_detect(struct sgm4154x_device * sgm)1245*4882a593Smuzhiyun static int sgm4154x_hw_chipid_detect(struct sgm4154x_device *sgm)
1246*4882a593Smuzhiyun {
1247*4882a593Smuzhiyun 	int ret = 0;
1248*4882a593Smuzhiyun 	int val = 0;
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun 	ret = regmap_read(sgm->regmap, SGM4154x_CHRG_CTRL_b, &val);
1251*4882a593Smuzhiyun 	if (ret < 0)
1252*4882a593Smuzhiyun 		return ret;
1253*4882a593Smuzhiyun 
1254*4882a593Smuzhiyun 	return val;
1255*4882a593Smuzhiyun }
1256*4882a593Smuzhiyun 
sgm_charger_work(struct work_struct * work)1257*4882a593Smuzhiyun static void sgm_charger_work(struct work_struct *work)
1258*4882a593Smuzhiyun {
1259*4882a593Smuzhiyun 	struct sgm4154x_device *sgm =
1260*4882a593Smuzhiyun 		container_of(work,
1261*4882a593Smuzhiyun 			     struct sgm4154x_device,
1262*4882a593Smuzhiyun 			     sgm_delay_work.work);
1263*4882a593Smuzhiyun 
1264*4882a593Smuzhiyun 	sgm4154x_watchdog_timer_reset(sgm);
1265*4882a593Smuzhiyun 	if (sgm->watchdog_enable)
1266*4882a593Smuzhiyun 		queue_delayed_work(sgm->sgm_monitor_wq,
1267*4882a593Smuzhiyun 				   &sgm->sgm_delay_work,
1268*4882a593Smuzhiyun 				   msecs_to_jiffies(1000 * 5));
1269*4882a593Smuzhiyun }
1270*4882a593Smuzhiyun 
sgm4154x_probe(struct i2c_client * client,const struct i2c_device_id * id)1271*4882a593Smuzhiyun static int sgm4154x_probe(struct i2c_client *client,
1272*4882a593Smuzhiyun 			  const struct i2c_device_id *id)
1273*4882a593Smuzhiyun {
1274*4882a593Smuzhiyun 	struct device *dev = &client->dev;
1275*4882a593Smuzhiyun 	struct sgm4154x_device *sgm;
1276*4882a593Smuzhiyun 	int ret;
1277*4882a593Smuzhiyun 
1278*4882a593Smuzhiyun 	sgm = devm_kzalloc(dev, sizeof(*sgm), GFP_KERNEL);
1279*4882a593Smuzhiyun 	if (!sgm)
1280*4882a593Smuzhiyun 		return -ENOMEM;
1281*4882a593Smuzhiyun 
1282*4882a593Smuzhiyun 	sgm->client = client;
1283*4882a593Smuzhiyun 	sgm->dev = dev;
1284*4882a593Smuzhiyun 
1285*4882a593Smuzhiyun 	mutex_init(&sgm->lock);
1286*4882a593Smuzhiyun 
1287*4882a593Smuzhiyun 	strncpy(sgm->model_name, id->name, I2C_NAME_SIZE);
1288*4882a593Smuzhiyun 
1289*4882a593Smuzhiyun 	sgm->regmap = devm_regmap_init_i2c(client, &sgm4154x_regmap_config);
1290*4882a593Smuzhiyun 	if (IS_ERR(sgm->regmap)) {
1291*4882a593Smuzhiyun 		dev_err(dev, "Failed to allocate register map\n");
1292*4882a593Smuzhiyun 		return PTR_ERR(sgm->regmap);
1293*4882a593Smuzhiyun 	}
1294*4882a593Smuzhiyun 
1295*4882a593Smuzhiyun 	i2c_set_clientdata(client, sgm);
1296*4882a593Smuzhiyun 
1297*4882a593Smuzhiyun 	ret = sgm4154x_parse_dt(sgm);
1298*4882a593Smuzhiyun 	if (ret) {
1299*4882a593Smuzhiyun 		dev_err(dev, "Failed to read device tree properties%d\n", ret);
1300*4882a593Smuzhiyun 		return ret;
1301*4882a593Smuzhiyun 	}
1302*4882a593Smuzhiyun 
1303*4882a593Smuzhiyun 	ret = sgm4154x_hw_chipid_detect(sgm);
1304*4882a593Smuzhiyun 	if ((ret & SGM4154x_PN_MASK) != SGM4154x_PN_ID) {
1305*4882a593Smuzhiyun 		pr_info("[%s] device not found !\n", __func__);
1306*4882a593Smuzhiyun 		return ret;
1307*4882a593Smuzhiyun 	}
1308*4882a593Smuzhiyun 
1309*4882a593Smuzhiyun 	device_init_wakeup(dev, 1);
1310*4882a593Smuzhiyun 
1311*4882a593Smuzhiyun 	if (client->irq) {
1312*4882a593Smuzhiyun 		ret = devm_request_threaded_irq(dev, client->irq, NULL,
1313*4882a593Smuzhiyun 						sgm4154x_irq_handler_thread,
1314*4882a593Smuzhiyun 						IRQF_TRIGGER_FALLING |
1315*4882a593Smuzhiyun 						IRQF_ONESHOT,
1316*4882a593Smuzhiyun 						"sgm41542-irq", sgm);
1317*4882a593Smuzhiyun 		if (ret)
1318*4882a593Smuzhiyun 			goto error_out;
1319*4882a593Smuzhiyun 		enable_irq_wake(client->irq);
1320*4882a593Smuzhiyun 	}
1321*4882a593Smuzhiyun 
1322*4882a593Smuzhiyun 	sgm->pm_nb.notifier_call = sgm4154x_suspend_notifier;
1323*4882a593Smuzhiyun 	register_pm_notifier(&sgm->pm_nb);
1324*4882a593Smuzhiyun 
1325*4882a593Smuzhiyun 	ret = sgm4154x_power_supply_init(sgm, dev);
1326*4882a593Smuzhiyun 	if (ret) {
1327*4882a593Smuzhiyun 		dev_err(dev, "Failed to register power supply\n");
1328*4882a593Smuzhiyun 		goto error_out;
1329*4882a593Smuzhiyun 	}
1330*4882a593Smuzhiyun 
1331*4882a593Smuzhiyun 	ret = sgm4154x_hw_init(sgm);
1332*4882a593Smuzhiyun 	if (ret) {
1333*4882a593Smuzhiyun 		dev_err(dev, "Cannot initialize the chip.\n");
1334*4882a593Smuzhiyun 		goto error_out;
1335*4882a593Smuzhiyun 	}
1336*4882a593Smuzhiyun 
1337*4882a593Smuzhiyun 	/* OTG setting 5V/1.2A */
1338*4882a593Smuzhiyun 	ret = sgm4154x_set_otg_voltage(sgm, 5000000);
1339*4882a593Smuzhiyun 	if (ret) {
1340*4882a593Smuzhiyun 		dev_err(sgm->dev, "set OTG voltage error!\n");
1341*4882a593Smuzhiyun 		return ret;
1342*4882a593Smuzhiyun 	}
1343*4882a593Smuzhiyun 
1344*4882a593Smuzhiyun 	ret = sgm4154x_set_otg_current(sgm, 1200000);
1345*4882a593Smuzhiyun 	if (ret) {
1346*4882a593Smuzhiyun 		dev_err(sgm->dev, "set OTG current error!\n");
1347*4882a593Smuzhiyun 		return ret;
1348*4882a593Smuzhiyun 	}
1349*4882a593Smuzhiyun 
1350*4882a593Smuzhiyun 	sgm->sgm_monitor_wq = alloc_ordered_workqueue("%s",
1351*4882a593Smuzhiyun 			WQ_MEM_RECLAIM | WQ_FREEZABLE, "sgm-monitor-wq");
1352*4882a593Smuzhiyun 	INIT_DELAYED_WORK(&sgm->sgm_delay_work, sgm_charger_work);
1353*4882a593Smuzhiyun 
1354*4882a593Smuzhiyun 	sgm4154x_vbus_regulator_register(sgm);
1355*4882a593Smuzhiyun 	sgm4154x_create_device_node(sgm->dev);
1356*4882a593Smuzhiyun 	return ret;
1357*4882a593Smuzhiyun error_out:
1358*4882a593Smuzhiyun 
1359*4882a593Smuzhiyun 	return ret;
1360*4882a593Smuzhiyun }
1361*4882a593Smuzhiyun 
sgm4154x_charger_remove(struct i2c_client * client)1362*4882a593Smuzhiyun static int sgm4154x_charger_remove(struct i2c_client *client)
1363*4882a593Smuzhiyun {
1364*4882a593Smuzhiyun 	struct sgm4154x_device *sgm = i2c_get_clientdata(client);
1365*4882a593Smuzhiyun 
1366*4882a593Smuzhiyun 	destroy_workqueue(sgm->sgm_monitor_wq);
1367*4882a593Smuzhiyun 	regulator_unregister(sgm->otg_rdev);
1368*4882a593Smuzhiyun 	power_supply_unregister(sgm->charger);
1369*4882a593Smuzhiyun 	mutex_destroy(&sgm->lock);
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun 	return 0;
1372*4882a593Smuzhiyun }
1373*4882a593Smuzhiyun 
sgm4154x_charger_shutdown(struct i2c_client * client)1374*4882a593Smuzhiyun static void sgm4154x_charger_shutdown(struct i2c_client *client)
1375*4882a593Smuzhiyun {
1376*4882a593Smuzhiyun 	struct sgm4154x_device *sgm = i2c_get_clientdata(client);
1377*4882a593Smuzhiyun 	int ret = 0;
1378*4882a593Smuzhiyun 
1379*4882a593Smuzhiyun 	sgm4154x_set_prechrg_curr(sgm, SGM4154x_PRECHRG_I_DEF_uA);
1380*4882a593Smuzhiyun 	ret = sgm4154x_disable_charger(sgm);
1381*4882a593Smuzhiyun 	if (ret)
1382*4882a593Smuzhiyun 		pr_err("Failed to disable charger, ret = %d\n", ret);
1383*4882a593Smuzhiyun }
1384*4882a593Smuzhiyun 
1385*4882a593Smuzhiyun static const struct i2c_device_id sgm4154x_i2c_ids[] = {
1386*4882a593Smuzhiyun 	{ "sgm41542", 0 },
1387*4882a593Smuzhiyun 	{},
1388*4882a593Smuzhiyun };
1389*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, sgm4154x_i2c_ids);
1390*4882a593Smuzhiyun 
1391*4882a593Smuzhiyun static const struct of_device_id sgm4154x_of_match[] = {
1392*4882a593Smuzhiyun 	{ .compatible = "sgm,sgm41542", },
1393*4882a593Smuzhiyun 	{ },
1394*4882a593Smuzhiyun };
1395*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, sgm4154x_of_match);
1396*4882a593Smuzhiyun 
1397*4882a593Smuzhiyun static struct i2c_driver sgm4154x_driver = {
1398*4882a593Smuzhiyun 	.driver = {
1399*4882a593Smuzhiyun 		.name = "sgm4154x-charger",
1400*4882a593Smuzhiyun 		.of_match_table = sgm4154x_of_match,
1401*4882a593Smuzhiyun 	},
1402*4882a593Smuzhiyun 	.probe = sgm4154x_probe,
1403*4882a593Smuzhiyun 	.remove = sgm4154x_charger_remove,
1404*4882a593Smuzhiyun 	.shutdown = sgm4154x_charger_shutdown,
1405*4882a593Smuzhiyun 	.id_table = sgm4154x_i2c_ids,
1406*4882a593Smuzhiyun };
1407*4882a593Smuzhiyun module_i2c_driver(sgm4154x_driver);
1408*4882a593Smuzhiyun 
1409*4882a593Smuzhiyun MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
1410*4882a593Smuzhiyun MODULE_DESCRIPTION("sgm4154x charger driver");
1411*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1412