xref: /rk3399_rockchip-uboot/drivers/power/twl6030.c (revision 3e664f6d50ea7f5d6ea96a028fc8f099236e99be)
1516799f6SSteve Sakoman /*
2516799f6SSteve Sakoman  * (C) Copyright 2010
3516799f6SSteve Sakoman  * Texas Instruments, <www.ti.com>
4516799f6SSteve Sakoman  *
5516799f6SSteve Sakoman  * See file CREDITS for list of people who contributed to this
6516799f6SSteve Sakoman  * project.
7516799f6SSteve Sakoman  *
8516799f6SSteve Sakoman  * This program is free software; you can redistribute it and/or
9516799f6SSteve Sakoman  * modify it under the terms of the GNU General Public License as
10516799f6SSteve Sakoman  * published by the Free Software Foundation; either version 2 of
11516799f6SSteve Sakoman  * the License, or (at your option) any later version.
12516799f6SSteve Sakoman  *
13516799f6SSteve Sakoman  * This program is distributed in the hope that it will be useful,
14516799f6SSteve Sakoman  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15516799f6SSteve Sakoman  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16516799f6SSteve Sakoman  * GNU General Public License for more details.
17516799f6SSteve Sakoman  *
18516799f6SSteve Sakoman  * You should have received a copy of the GNU General Public License
19516799f6SSteve Sakoman  * along with this program; if not, write to the Free Software
20516799f6SSteve Sakoman  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21516799f6SSteve Sakoman  * MA 02111-1307 USA
22516799f6SSteve Sakoman  */
23516799f6SSteve Sakoman #include <config.h>
24516799f6SSteve Sakoman #ifdef CONFIG_TWL6030_POWER
25516799f6SSteve Sakoman 
26516799f6SSteve Sakoman #include <twl6030.h>
27516799f6SSteve Sakoman 
28516799f6SSteve Sakoman /* Functions to read and write from TWL6030 */
29516799f6SSteve Sakoman static inline int twl6030_i2c_write_u8(u8 chip_no, u8 val, u8 reg)
30516799f6SSteve Sakoman {
31516799f6SSteve Sakoman 	return i2c_write(chip_no, reg, 1, &val, 1);
32516799f6SSteve Sakoman }
33516799f6SSteve Sakoman 
34516799f6SSteve Sakoman static inline int twl6030_i2c_read_u8(u8 chip_no, u8 *val, u8 reg)
35516799f6SSteve Sakoman {
36516799f6SSteve Sakoman 	return i2c_read(chip_no, reg, 1, val, 1);
37516799f6SSteve Sakoman }
38516799f6SSteve Sakoman 
39*3e664f6dSBalaji T K static int twl6030_gpadc_read_channel(u8 channel_no)
40*3e664f6dSBalaji T K {
41*3e664f6dSBalaji T K 	u8 lsb = 0;
42*3e664f6dSBalaji T K 	u8 msb = 0;
43*3e664f6dSBalaji T K 	int ret = 0;
44*3e664f6dSBalaji T K 
45*3e664f6dSBalaji T K 	ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &lsb,
46*3e664f6dSBalaji T K 				GPCH0_LSB + channel_no * 2);
47*3e664f6dSBalaji T K 	if (ret)
48*3e664f6dSBalaji T K 		return ret;
49*3e664f6dSBalaji T K 
50*3e664f6dSBalaji T K 	ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &msb,
51*3e664f6dSBalaji T K 				GPCH0_MSB + channel_no * 2);
52*3e664f6dSBalaji T K 	if (ret)
53*3e664f6dSBalaji T K 		return ret;
54*3e664f6dSBalaji T K 
55*3e664f6dSBalaji T K 	return (msb << 8) | lsb;
56*3e664f6dSBalaji T K }
57*3e664f6dSBalaji T K 
58*3e664f6dSBalaji T K static int twl6030_gpadc_sw2_trigger(void)
59*3e664f6dSBalaji T K {
60*3e664f6dSBalaji T K 	u8 val;
61*3e664f6dSBalaji T K 	int ret = 0;
62*3e664f6dSBalaji T K 
63*3e664f6dSBalaji T K 	ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC, CTRL_P2_SP2, CTRL_P2);
64*3e664f6dSBalaji T K 	if (ret)
65*3e664f6dSBalaji T K 		return ret;
66*3e664f6dSBalaji T K 
67*3e664f6dSBalaji T K 	/* Waiting until the SW1 conversion ends*/
68*3e664f6dSBalaji T K 	val =  CTRL_P2_BUSY;
69*3e664f6dSBalaji T K 
70*3e664f6dSBalaji T K 	while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) {
71*3e664f6dSBalaji T K 		ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &val, CTRL_P2);
72*3e664f6dSBalaji T K 		if (ret)
73*3e664f6dSBalaji T K 			return ret;
74*3e664f6dSBalaji T K 		udelay(1000);
75*3e664f6dSBalaji T K 	}
76*3e664f6dSBalaji T K 
77*3e664f6dSBalaji T K 	return 0;
78*3e664f6dSBalaji T K }
79*3e664f6dSBalaji T K 
80*3e664f6dSBalaji T K void twl6030_stop_usb_charging(void)
81*3e664f6dSBalaji T K {
82*3e664f6dSBalaji T K 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 0, CONTROLLER_CTRL1);
83*3e664f6dSBalaji T K 
84*3e664f6dSBalaji T K 	return;
85*3e664f6dSBalaji T K }
86*3e664f6dSBalaji T K 
87516799f6SSteve Sakoman void twl6030_start_usb_charging(void)
88516799f6SSteve Sakoman {
89516799f6SSteve Sakoman 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VICHRG_1500,
90516799f6SSteve Sakoman 							CHARGERUSB_VICHRG);
91516799f6SSteve Sakoman 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CIN_LIMIT_NONE,
92516799f6SSteve Sakoman 							CHARGERUSB_CINLIMIT);
93516799f6SSteve Sakoman 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, MBAT_TEMP,
94516799f6SSteve Sakoman 							CONTROLLER_INT_MASK);
95516799f6SSteve Sakoman 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, MASK_MCHARGERUSB_THMREG,
96516799f6SSteve Sakoman 							CHARGERUSB_INT_MASK);
97516799f6SSteve Sakoman 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VOREG_4P0,
98516799f6SSteve Sakoman 							CHARGERUSB_VOREG);
99*3e664f6dSBalaji T K 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL2_VITERM_400,
100516799f6SSteve Sakoman 							CHARGERUSB_CTRL2);
101*3e664f6dSBalaji T K 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TERM, CHARGERUSB_CTRL1);
102516799f6SSteve Sakoman 	/* Enable USB charging */
103516799f6SSteve Sakoman 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1_EN_CHARGER,
104516799f6SSteve Sakoman 							CONTROLLER_CTRL1);
105516799f6SSteve Sakoman 	return;
106516799f6SSteve Sakoman }
107516799f6SSteve Sakoman 
108*3e664f6dSBalaji T K int twl6030_get_battery_current(void)
109*3e664f6dSBalaji T K {
110*3e664f6dSBalaji T K 	int battery_current = 0;
111*3e664f6dSBalaji T K 	u8 msb = 0;
112*3e664f6dSBalaji T K 	u8 lsb = 0;
113*3e664f6dSBalaji T K 
114*3e664f6dSBalaji T K 	twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &msb, FG_REG_11);
115*3e664f6dSBalaji T K 	twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &lsb, FG_REG_10);
116*3e664f6dSBalaji T K 	battery_current = ((msb << 8) | lsb);
117*3e664f6dSBalaji T K 
118*3e664f6dSBalaji T K 	/* convert 10 bit signed number to 16 bit signed number */
119*3e664f6dSBalaji T K 	if (battery_current >= 0x2000)
120*3e664f6dSBalaji T K 		battery_current = (battery_current - 0x4000);
121*3e664f6dSBalaji T K 
122*3e664f6dSBalaji T K 	battery_current = battery_current * 3000 / 4096;
123*3e664f6dSBalaji T K 	printf("Battery Current: %d mA\n", battery_current);
124*3e664f6dSBalaji T K 
125*3e664f6dSBalaji T K 	return battery_current;
126*3e664f6dSBalaji T K }
127*3e664f6dSBalaji T K 
128*3e664f6dSBalaji T K int twl6030_get_battery_voltage(void)
129*3e664f6dSBalaji T K {
130*3e664f6dSBalaji T K 	int battery_volt = 0;
131*3e664f6dSBalaji T K 	int ret = 0;
132*3e664f6dSBalaji T K 
133*3e664f6dSBalaji T K 	/* Start GPADC SW conversion */
134*3e664f6dSBalaji T K 	ret = twl6030_gpadc_sw2_trigger();
135*3e664f6dSBalaji T K 	if (ret) {
136*3e664f6dSBalaji T K 		printf("Failed to convert battery voltage\n");
137*3e664f6dSBalaji T K 		return ret;
138*3e664f6dSBalaji T K 	}
139*3e664f6dSBalaji T K 
140*3e664f6dSBalaji T K 	/* measure Vbat voltage */
141*3e664f6dSBalaji T K 	battery_volt = twl6030_gpadc_read_channel(7);
142*3e664f6dSBalaji T K 	if (battery_volt < 0) {
143*3e664f6dSBalaji T K 		printf("Failed to read battery voltage\n");
144*3e664f6dSBalaji T K 		return ret;
145*3e664f6dSBalaji T K 	}
146*3e664f6dSBalaji T K 	battery_volt = (battery_volt * 25 * 1000) >> (10 + 2);
147*3e664f6dSBalaji T K 	printf("Battery Voltage: %d mV\n", battery_volt);
148*3e664f6dSBalaji T K 
149*3e664f6dSBalaji T K 	return battery_volt;
150*3e664f6dSBalaji T K }
151*3e664f6dSBalaji T K 
152516799f6SSteve Sakoman void twl6030_init_battery_charging(void)
153516799f6SSteve Sakoman {
154*3e664f6dSBalaji T K 	u8 stat1 = 0;
155*3e664f6dSBalaji T K 	int battery_volt = 0;
156*3e664f6dSBalaji T K 	int ret = 0;
157*3e664f6dSBalaji T K 
158*3e664f6dSBalaji T K 	/* Enable VBAT measurement */
159*3e664f6dSBalaji T K 	twl6030_i2c_write_u8(TWL6030_CHIP_PM, VBAT_MEAS, MISC1);
160*3e664f6dSBalaji T K 
161*3e664f6dSBalaji T K 	/* Enable GPADC module */
162*3e664f6dSBalaji T K 	ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, FGS | GPADCS, TOGGLE1);
163*3e664f6dSBalaji T K 	if (ret) {
164*3e664f6dSBalaji T K 		printf("Failed to enable GPADC\n");
165*3e664f6dSBalaji T K 		return;
166*3e664f6dSBalaji T K 	}
167*3e664f6dSBalaji T K 
168*3e664f6dSBalaji T K 	battery_volt = twl6030_get_battery_voltage();
169*3e664f6dSBalaji T K 	if (battery_volt < 0)
170*3e664f6dSBalaji T K 		return;
171*3e664f6dSBalaji T K 
172*3e664f6dSBalaji T K 	if (battery_volt < 3000)
173*3e664f6dSBalaji T K 		printf("Main battery voltage too low!\n");
174*3e664f6dSBalaji T K 
175*3e664f6dSBalaji T K 	/* Check for the presence of USB charger */
176*3e664f6dSBalaji T K 	twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &stat1, CONTROLLER_STAT1);
177*3e664f6dSBalaji T K 
178*3e664f6dSBalaji T K 	/* check for battery presence indirectly via Fuel gauge */
179*3e664f6dSBalaji T K 	if ((stat1 & VBUS_DET) && (battery_volt < 3300))
180516799f6SSteve Sakoman 		twl6030_start_usb_charging();
181*3e664f6dSBalaji T K 
182516799f6SSteve Sakoman 	return;
183516799f6SSteve Sakoman }
184516799f6SSteve Sakoman 
185516799f6SSteve Sakoman void twl6030_usb_device_settings()
186516799f6SSteve Sakoman {
187516799f6SSteve Sakoman 	u8 data = 0;
188516799f6SSteve Sakoman 
189516799f6SSteve Sakoman 	/* Select APP Group and set state to ON */
190516799f6SSteve Sakoman 	twl6030_i2c_write_u8(TWL6030_CHIP_PM, 0x21, VUSB_CFG_STATE);
191516799f6SSteve Sakoman 
192516799f6SSteve Sakoman 	twl6030_i2c_read_u8(TWL6030_CHIP_PM, &data, MISC2);
193516799f6SSteve Sakoman 	data |= 0x10;
194516799f6SSteve Sakoman 
195516799f6SSteve Sakoman 	/* Select the input supply for VBUS regulator */
196516799f6SSteve Sakoman 	twl6030_i2c_write_u8(TWL6030_CHIP_PM, data, MISC2);
197516799f6SSteve Sakoman }
198516799f6SSteve Sakoman #endif
199