diff options
| -rw-r--r-- | board/ti/sdp4430/Makefile | 2 | ||||
| -rw-r--r-- | board/ti/sdp4430/cmd_bat.c | 58 | ||||
| -rw-r--r-- | board/ti/sdp4430/sdp.c | 4 | ||||
| -rw-r--r-- | drivers/power/twl6030.c | 124 | ||||
| -rw-r--r-- | include/configs/omap4_sdp4430.h | 1 | ||||
| -rw-r--r-- | include/twl6030.h | 45 | 
6 files changed, 229 insertions, 5 deletions
| diff --git a/board/ti/sdp4430/Makefile b/board/ti/sdp4430/Makefile index bce85342a..f1ee5448e 100644 --- a/board/ti/sdp4430/Makefile +++ b/board/ti/sdp4430/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk  LIB	= $(obj)lib$(BOARD).o -COBJS	:= sdp.o +COBJS	:= sdp.o cmd_bat.o  SRCS	:= $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(COBJS)) diff --git a/board/ti/sdp4430/cmd_bat.c b/board/ti/sdp4430/cmd_bat.c new file mode 100644 index 000000000..fe3353896 --- /dev/null +++ b/board/ti/sdp4430/cmd_bat.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010 Texas Instruments + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> + +#ifdef CONFIG_CMD_BAT +#include <twl6030.h> + +int do_vbat(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	if (argc == 2) { +		if (strncmp(argv[1], "startcharge", 12) == 0) +			twl6030_start_usb_charging(); +		else if (strncmp(argv[1], "stopcharge", 11) == 0) +			twl6030_stop_usb_charging(); +		else if (strncmp(argv[1], "status", 7) == 0) { +			twl6030_get_battery_voltage(); +			twl6030_get_battery_current(); +		} else { +			goto bat_cmd_usage; +		} +	} else { +		goto bat_cmd_usage; +	} +	return 0; + +bat_cmd_usage: +	return cmd_usage(cmdtp); +} + +U_BOOT_CMD( +	bat, 2, 1, do_vbat, +	"battery charging, voltage/current measurements", +	"status - display battery voltage and current\n" +	"bat startcharge - start charging via USB\n" +	"bat stopcharge - stop charging\n" +); +#endif /* CONFIG_BAT_CMD */ diff --git a/board/ti/sdp4430/sdp.c b/board/ti/sdp4430/sdp.c index 01d5ce4f4..b13c4c5c1 100644 --- a/board/ti/sdp4430/sdp.c +++ b/board/ti/sdp4430/sdp.c @@ -23,6 +23,7 @@   * MA 02111-1307 USA   */  #include <common.h> +#include <twl6030.h>  #include <asm/arch/sys_proto.h>  #include <asm/arch/mmc_host_def.h> @@ -63,6 +64,9 @@ int board_eth_init(bd_t *bis)   */  int misc_init_r(void)  { +#ifdef CONFIG_TWL6030_POWER +	twl6030_init_battery_charging(); +#endif  	return 0;  } diff --git a/drivers/power/twl6030.c b/drivers/power/twl6030.c index cf1da6b6a..fef57b433 100644 --- a/drivers/power/twl6030.c +++ b/drivers/power/twl6030.c @@ -36,6 +36,54 @@ static inline int twl6030_i2c_read_u8(u8 chip_no, u8 *val, u8 reg)  	return i2c_read(chip_no, reg, 1, val, 1);  } +static int twl6030_gpadc_read_channel(u8 channel_no) +{ +	u8 lsb = 0; +	u8 msb = 0; +	int ret = 0; + +	ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &lsb, +				GPCH0_LSB + channel_no * 2); +	if (ret) +		return ret; + +	ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &msb, +				GPCH0_MSB + channel_no * 2); +	if (ret) +		return ret; + +	return (msb << 8) | lsb; +} + +static int twl6030_gpadc_sw2_trigger(void) +{ +	u8 val; +	int ret = 0; + +	ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC, CTRL_P2_SP2, CTRL_P2); +	if (ret) +		return ret; + +	/* Waiting until the SW1 conversion ends*/ +	val =  CTRL_P2_BUSY; + +	while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) { +		ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC, &val, CTRL_P2); +		if (ret) +			return ret; +		udelay(1000); +	} + +	return 0; +} + +void twl6030_stop_usb_charging(void) +{ +	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, 0, CONTROLLER_CTRL1); + +	return; +} +  void twl6030_start_usb_charging(void)  {  	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VICHRG_1500, @@ -48,17 +96,89 @@ void twl6030_start_usb_charging(void)  							CHARGERUSB_INT_MASK);  	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VOREG_4P0,  							CHARGERUSB_VOREG); -	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL2_VITERM_100, +	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL2_VITERM_400,  							CHARGERUSB_CTRL2); +	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TERM, CHARGERUSB_CTRL1);  	/* Enable USB charging */  	twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1_EN_CHARGER,  							CONTROLLER_CTRL1);  	return;  } +int twl6030_get_battery_current(void) +{ +	int battery_current = 0; +	u8 msb = 0; +	u8 lsb = 0; + +	twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &msb, FG_REG_11); +	twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &lsb, FG_REG_10); +	battery_current = ((msb << 8) | lsb); + +	/* convert 10 bit signed number to 16 bit signed number */ +	if (battery_current >= 0x2000) +		battery_current = (battery_current - 0x4000); + +	battery_current = battery_current * 3000 / 4096; +	printf("Battery Current: %d mA\n", battery_current); + +	return battery_current; +} + +int twl6030_get_battery_voltage(void) +{ +	int battery_volt = 0; +	int ret = 0; + +	/* Start GPADC SW conversion */ +	ret = twl6030_gpadc_sw2_trigger(); +	if (ret) { +		printf("Failed to convert battery voltage\n"); +		return ret; +	} + +	/* measure Vbat voltage */ +	battery_volt = twl6030_gpadc_read_channel(7); +	if (battery_volt < 0) { +		printf("Failed to read battery voltage\n"); +		return ret; +	} +	battery_volt = (battery_volt * 25 * 1000) >> (10 + 2); +	printf("Battery Voltage: %d mV\n", battery_volt); + +	return battery_volt; +} +  void twl6030_init_battery_charging(void)  { -	twl6030_start_usb_charging(); +	u8 stat1 = 0; +	int battery_volt = 0; +	int ret = 0; + +	/* Enable VBAT measurement */ +	twl6030_i2c_write_u8(TWL6030_CHIP_PM, VBAT_MEAS, MISC1); + +	/* Enable GPADC module */ +	ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, FGS | GPADCS, TOGGLE1); +	if (ret) { +		printf("Failed to enable GPADC\n"); +		return; +	} + +	battery_volt = twl6030_get_battery_voltage(); +	if (battery_volt < 0) +		return; + +	if (battery_volt < 3000) +		printf("Main battery voltage too low!\n"); + +	/* Check for the presence of USB charger */ +	twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, &stat1, CONTROLLER_STAT1); + +	/* check for battery presence indirectly via Fuel gauge */ +	if ((stat1 & VBUS_DET) && (battery_volt < 3300)) +		twl6030_start_usb_charging(); +  	return;  } diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h index ed0bd41f7..bdd330a74 100644 --- a/include/configs/omap4_sdp4430.h +++ b/include/configs/omap4_sdp4430.h @@ -102,6 +102,7 @@  /* TWL6030 */  #define CONFIG_TWL6030_POWER		1 +#define CONFIG_CMD_BAT			1  /* MMC */  #define CONFIG_GENERIC_MMC		1 diff --git a/include/twl6030.h b/include/twl6030.h index 54923ab2e..6ed68a0e1 100644 --- a/include/twl6030.h +++ b/include/twl6030.h @@ -32,6 +32,18 @@  #define TWL6030_CHIP_CHARGER	0x49  #define TWL6030_CHIP_PWM	0x49 +/* Slave Address 0x48 */ +#define VUSB_CFG_STATE		0xA2 + +#define MISC1			0xE4 +#define VAC_MEAS		(1 << 2) +#define VBAT_MEAS		(1 << 1) +#define BB_MEAS			(1 << 0) + +#define MISC2			0xE5 + +/* Slave Address 0x49 */ +  /* Battery CHARGER REGISTERS */  #define CONTROLLER_INT_MASK	0xE0  #define CONTROLLER_CTRL1	0xE1 @@ -76,16 +88,45 @@  #define CHARGERUSB_VOREG_4P0		0x19  #define CHARGERUSB_VOREG_4P2		0x23  #define CHARGERUSB_VOREG_4P76		0x3F +/* CHARGERUSB_CTRL1 */ +#define SUSPEND_BOOT		(1 << 7) +#define OPA_MODE		(1 << 6) +#define HZ_MODE			(1 << 5) +#define TERM			(1 << 4)  /* CHARGERUSB_CTRL2 */  #define CHARGERUSB_CTRL2_VITERM_50	(0 << 5)  #define CHARGERUSB_CTRL2_VITERM_100	(1 << 5)  #define CHARGERUSB_CTRL2_VITERM_150	(2 << 5) +#define CHARGERUSB_CTRL2_VITERM_400	(7 << 5)  /* CONTROLLER_CTRL1 */  #define CONTROLLER_CTRL1_EN_CHARGER	(1 << 4)  #define CONTROLLER_CTRL1_SEL_CHARGER	(1 << 3) +/* CONTROLLER_STAT1 */ +#define CHRG_EXTCHRG_STATZ	(1 << 7) +#define CHRG_DET_N		(1 << 5) +#define VAC_DET			(1 << 3) +#define VBUS_DET		(1 << 2) -#define VUSB_CFG_STATE		0xA2 -#define MISC2			0xE5 +#define FG_REG_10	0xCA +#define FG_REG_11	0xCB + +#define TOGGLE1		0x90 +#define FGS		(1 << 5) +#define FGR		(1 << 4) +#define GPADCS		(1 << 1) +#define GPADCR		(1 << 0) + +#define CTRL_P2		0x34 +#define CTRL_P2_SP2	(1 << 2) +#define CTRL_P2_EOCP2	(1 << 1) +#define CTRL_P2_BUSY	(1 << 0) + +#define GPCH0_LSB	0x57 +#define GPCH0_MSB	0x58  void twl6030_init_battery_charging(void);  void twl6030_usb_device_settings(void); +void twl6030_start_usb_charging(void); +void twl6030_stop_usb_charging(void); +int twl6030_get_battery_voltage(void); +int twl6030_get_battery_current(void); |