ARMV7: OMAP4: twl6030 add battery charging support
Add battery charging support twl6030 driver. Add support for battery voltage and current measurements. Add command to get battery status and start/stop battery charging from USB. Signed-off-by: Balaji T K <balajitk@ti.com> Tested-by: Steve Sakoman <steve.sakoman@linaro.org> Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
This commit is contained in:
parent
917a62c0d2
commit
3e664f6d50
@ -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))
|
||||
|
58
board/ti/sdp4430/cmd_bat.c
Normal file
58
board/ti/sdp4430/cmd_bat.c
Normal file
@ -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 */
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -102,6 +102,7 @@
|
||||
|
||||
/* TWL6030 */
|
||||
#define CONFIG_TWL6030_POWER 1
|
||||
#define CONFIG_CMD_BAT 1
|
||||
|
||||
/* MMC */
|
||||
#define CONFIG_GENERIC_MMC 1
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user