xref: /openbmc/u-boot/drivers/power/twl6030.c (revision 345ef204)
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 */
29*345ef204SNishanth Menon static inline int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
30516799f6SSteve Sakoman {
31516799f6SSteve Sakoman 	return i2c_write(chip_no, reg, 1, &val, 1);
32516799f6SSteve Sakoman }
33516799f6SSteve Sakoman 
34*345ef204SNishanth Menon static inline int twl6030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val)
35516799f6SSteve Sakoman {
36516799f6SSteve Sakoman 	return i2c_read(chip_no, reg, 1, val, 1);
37516799f6SSteve Sakoman }
38516799f6SSteve Sakoman 
393e664f6dSBalaji T K static int twl6030_gpadc_read_channel(u8 channel_no)
403e664f6dSBalaji T K {
413e664f6dSBalaji T K 	u8 lsb = 0;
423e664f6dSBalaji T K 	u8 msb = 0;
433e664f6dSBalaji T K 	int ret = 0;
443e664f6dSBalaji T K 
45*345ef204SNishanth Menon 	ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
46*345ef204SNishanth Menon 				  GPCH0_LSB + channel_no * 2, &lsb);
473e664f6dSBalaji T K 	if (ret)
483e664f6dSBalaji T K 		return ret;
493e664f6dSBalaji T K 
50*345ef204SNishanth Menon 	ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
51*345ef204SNishanth Menon 				  GPCH0_MSB + channel_no * 2, &msb);
523e664f6dSBalaji T K 	if (ret)
533e664f6dSBalaji T K 		return ret;
543e664f6dSBalaji T K 
553e664f6dSBalaji T K 	return (msb << 8) | lsb;
563e664f6dSBalaji T K }
573e664f6dSBalaji T K 
583e664f6dSBalaji T K static int twl6030_gpadc_sw2_trigger(void)
593e664f6dSBalaji T K {
603e664f6dSBalaji T K 	u8 val;
613e664f6dSBalaji T K 	int ret = 0;
623e664f6dSBalaji T K 
63*345ef204SNishanth Menon 	ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC, CTRL_P2, CTRL_P2_SP2);
643e664f6dSBalaji T K 	if (ret)
653e664f6dSBalaji T K 		return ret;
663e664f6dSBalaji T K 
673e664f6dSBalaji T K 	/* Waiting until the SW1 conversion ends*/
683e664f6dSBalaji T K 	val =  CTRL_P2_BUSY;
693e664f6dSBalaji T K 
703e664f6dSBalaji T K 	while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) {
71*345ef204SNishanth Menon 		ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, CTRL_P2, &val);
723e664f6dSBalaji T K 		if (ret)
733e664f6dSBalaji T K 			return ret;
743e664f6dSBalaji T K 		udelay(1000);
753e664f6dSBalaji T K 	}
763e664f6dSBalaji T K 
773e664f6dSBalaji T K 	return 0;
783e664f6dSBalaji T K }
793e664f6dSBalaji T K 
803e664f6dSBalaji T K void twl6030_stop_usb_charging(void)
813e664f6dSBalaji T K {
82*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1, 0);
833e664f6dSBalaji T K 
843e664f6dSBalaji T K 	return;
853e664f6dSBalaji T K }
863e664f6dSBalaji T K 
87516799f6SSteve Sakoman void twl6030_start_usb_charging(void)
88516799f6SSteve Sakoman {
89*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
90*345ef204SNishanth Menon 			     CHARGERUSB_VICHRG, CHARGERUSB_VICHRG_1500);
91*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
92*345ef204SNishanth Menon 			     CHARGERUSB_CINLIMIT, CHARGERUSB_CIN_LIMIT_NONE);
93*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
94*345ef204SNishanth Menon 			     CONTROLLER_INT_MASK, MBAT_TEMP);
95*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
96*345ef204SNishanth Menon 			     CHARGERUSB_INT_MASK, MASK_MCHARGERUSB_THMREG);
97*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
98*345ef204SNishanth Menon 			     CHARGERUSB_VOREG, CHARGERUSB_VOREG_4P0);
99*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
100*345ef204SNishanth Menon 			     CHARGERUSB_CTRL2, CHARGERUSB_CTRL2_VITERM_400);
101*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL1, TERM);
102516799f6SSteve Sakoman 	/* Enable USB charging */
103*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
104*345ef204SNishanth Menon 			     CONTROLLER_CTRL1, CONTROLLER_CTRL1_EN_CHARGER);
105516799f6SSteve Sakoman 	return;
106516799f6SSteve Sakoman }
107516799f6SSteve Sakoman 
1083e664f6dSBalaji T K int twl6030_get_battery_current(void)
1093e664f6dSBalaji T K {
1103e664f6dSBalaji T K 	int battery_current = 0;
1113e664f6dSBalaji T K 	u8 msb = 0;
1123e664f6dSBalaji T K 	u8 lsb = 0;
1133e664f6dSBalaji T K 
114*345ef204SNishanth Menon 	twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_11, &msb);
115*345ef204SNishanth Menon 	twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_10, &lsb);
1163e664f6dSBalaji T K 	battery_current = ((msb << 8) | lsb);
1173e664f6dSBalaji T K 
1183e664f6dSBalaji T K 	/* convert 10 bit signed number to 16 bit signed number */
1193e664f6dSBalaji T K 	if (battery_current >= 0x2000)
1203e664f6dSBalaji T K 		battery_current = (battery_current - 0x4000);
1213e664f6dSBalaji T K 
1223e664f6dSBalaji T K 	battery_current = battery_current * 3000 / 4096;
1233e664f6dSBalaji T K 	printf("Battery Current: %d mA\n", battery_current);
1243e664f6dSBalaji T K 
1253e664f6dSBalaji T K 	return battery_current;
1263e664f6dSBalaji T K }
1273e664f6dSBalaji T K 
1283e664f6dSBalaji T K int twl6030_get_battery_voltage(void)
1293e664f6dSBalaji T K {
1303e664f6dSBalaji T K 	int battery_volt = 0;
1313e664f6dSBalaji T K 	int ret = 0;
1323e664f6dSBalaji T K 
1333e664f6dSBalaji T K 	/* Start GPADC SW conversion */
1343e664f6dSBalaji T K 	ret = twl6030_gpadc_sw2_trigger();
1353e664f6dSBalaji T K 	if (ret) {
1363e664f6dSBalaji T K 		printf("Failed to convert battery voltage\n");
1373e664f6dSBalaji T K 		return ret;
1383e664f6dSBalaji T K 	}
1393e664f6dSBalaji T K 
1403e664f6dSBalaji T K 	/* measure Vbat voltage */
1413e664f6dSBalaji T K 	battery_volt = twl6030_gpadc_read_channel(7);
1423e664f6dSBalaji T K 	if (battery_volt < 0) {
1433e664f6dSBalaji T K 		printf("Failed to read battery voltage\n");
1443e664f6dSBalaji T K 		return ret;
1453e664f6dSBalaji T K 	}
1463e664f6dSBalaji T K 	battery_volt = (battery_volt * 25 * 1000) >> (10 + 2);
1473e664f6dSBalaji T K 	printf("Battery Voltage: %d mV\n", battery_volt);
1483e664f6dSBalaji T K 
1493e664f6dSBalaji T K 	return battery_volt;
1503e664f6dSBalaji T K }
1513e664f6dSBalaji T K 
152516799f6SSteve Sakoman void twl6030_init_battery_charging(void)
153516799f6SSteve Sakoman {
1543e664f6dSBalaji T K 	u8 stat1 = 0;
1553e664f6dSBalaji T K 	int battery_volt = 0;
1563e664f6dSBalaji T K 	int ret = 0;
1573e664f6dSBalaji T K 
1583e664f6dSBalaji T K 	/* Enable VBAT measurement */
159*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC1, VBAT_MEAS);
1603e664f6dSBalaji T K 
1613e664f6dSBalaji T K 	/* Enable GPADC module */
162*345ef204SNishanth Menon 	ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TOGGLE1, FGS | GPADCS);
1633e664f6dSBalaji T K 	if (ret) {
1643e664f6dSBalaji T K 		printf("Failed to enable GPADC\n");
1653e664f6dSBalaji T K 		return;
1663e664f6dSBalaji T K 	}
1673e664f6dSBalaji T K 
1683e664f6dSBalaji T K 	battery_volt = twl6030_get_battery_voltage();
1693e664f6dSBalaji T K 	if (battery_volt < 0)
1703e664f6dSBalaji T K 		return;
1713e664f6dSBalaji T K 
1723e664f6dSBalaji T K 	if (battery_volt < 3000)
1733e664f6dSBalaji T K 		printf("Main battery voltage too low!\n");
1743e664f6dSBalaji T K 
1753e664f6dSBalaji T K 	/* Check for the presence of USB charger */
176*345ef204SNishanth Menon 	twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, CONTROLLER_STAT1, &stat1);
1773e664f6dSBalaji T K 
1783e664f6dSBalaji T K 	/* check for battery presence indirectly via Fuel gauge */
1793e664f6dSBalaji T K 	if ((stat1 & VBUS_DET) && (battery_volt < 3300))
180516799f6SSteve Sakoman 		twl6030_start_usb_charging();
1813e664f6dSBalaji T K 
182516799f6SSteve Sakoman 	return;
183516799f6SSteve Sakoman }
184516799f6SSteve Sakoman 
18514fa2dd0SBalaji T K void twl6030_power_mmc_init()
18614fa2dd0SBalaji T K {
18714fa2dd0SBalaji T K 	/* set voltage to 3.0 and turnon for APP */
188*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_VOLTATE, 0x15);
189*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_STATE, 0x21);
19014fa2dd0SBalaji T K }
19114fa2dd0SBalaji T K 
192516799f6SSteve Sakoman void twl6030_usb_device_settings()
193516799f6SSteve Sakoman {
194516799f6SSteve Sakoman 	u8 data = 0;
195516799f6SSteve Sakoman 
196516799f6SSteve Sakoman 	/* Select APP Group and set state to ON */
197*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_PM, VUSB_CFG_STATE, 0x21);
198516799f6SSteve Sakoman 
199*345ef204SNishanth Menon 	twl6030_i2c_read_u8(TWL6030_CHIP_PM, MISC2, &data);
200516799f6SSteve Sakoman 	data |= 0x10;
201516799f6SSteve Sakoman 
202516799f6SSteve Sakoman 	/* Select the input supply for VBUS regulator */
203*345ef204SNishanth Menon 	twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC2, data);
204516799f6SSteve Sakoman }
205516799f6SSteve Sakoman #endif
206