mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
add bq27510 battery check
This commit is contained in:
@@ -121,7 +121,24 @@ config BATTERY_BQ27510
|
||||
depends on I2C && ARCH_RK29
|
||||
help
|
||||
Say Y here to enable support for batteries with BQ27510(I2C) chip.
|
||||
|
||||
config CHECK_BATT_CAPACITY
|
||||
tristate "check the capacity in BQ27510 battery if 1000mah write capacity for BATT_CAPACITY_MAH"
|
||||
depends on BATTERY_BQ27510
|
||||
default n
|
||||
|
||||
config BATT_CAPACITY_MAH
|
||||
depends on CHECK_BATT_CAPACITY
|
||||
int "battery capacity (in mah)"
|
||||
default 2200
|
||||
|
||||
config NO_BATTERY_IC
|
||||
tristate "no BQ27510 battery ic in board"
|
||||
depends on BATTERY_BQ27510
|
||||
default n
|
||||
help
|
||||
Say no BQ27510(I2C) chip in board .
|
||||
|
||||
config BATTERY_RK2818
|
||||
tristate "RK2818 battery"
|
||||
depends on RK28_ADC
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <mach/gpio.h>
|
||||
|
||||
#define DRIVER_VERSION "1.1.0"
|
||||
|
||||
@@ -41,6 +42,8 @@
|
||||
|
||||
#define BQ27510_SPEED 300 * 1000
|
||||
|
||||
#define DC_CHECK_PIN RK29_PIN4_PA1
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
@@ -55,6 +58,7 @@ static DEFINE_MUTEX(battery_mutex);
|
||||
struct bq27510_device_info {
|
||||
struct device *dev;
|
||||
struct power_supply bat;
|
||||
struct power_supply ac;
|
||||
struct delayed_work work;
|
||||
unsigned int interval;
|
||||
struct i2c_client *client;
|
||||
@@ -66,12 +70,17 @@ static enum power_supply_property bq27510_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
//POWER_SUPPLY_PROP_TEMP,
|
||||
POWER_SUPPLY_PROP_TEMP,
|
||||
//POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
|
||||
//POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
|
||||
//POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
|
||||
};
|
||||
|
||||
static enum power_supply_property rk29_ac_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Common code for BQ27510 devices read
|
||||
*/
|
||||
@@ -81,7 +90,14 @@ static int bq27510_read(struct i2c_client *client, u8 reg, u8 buf[], unsigned le
|
||||
ret = i2c_master_reg8_recv(client, reg, buf, len, BQ27510_SPEED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CHECK_BATT_CAPACITY
|
||||
static int bq27510_write(struct i2c_client *client, u8 reg, u8 const buf[], unsigned len)
|
||||
{
|
||||
int ret;
|
||||
ret = i2c_master_reg8_send(client, reg, buf, (int)len, BQ27510_SPEED);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Return the battery temperature in tenths of degree Celsius
|
||||
* Or < 0 if something fails.
|
||||
@@ -141,6 +157,9 @@ static int bq27510_battery_current(struct bq27510_device_info *di)
|
||||
}
|
||||
|
||||
curr = get_unaligned_le16(buf);
|
||||
if(curr>0x8000){
|
||||
curr = 0xFFFF^(curr-1);
|
||||
}
|
||||
curr = curr * 1000;
|
||||
DBG("Enter:%s %d--curr = %d\n",__FUNCTION__,__LINE__,curr);
|
||||
return curr;
|
||||
@@ -154,6 +173,9 @@ static int bq27510_battery_rsoc(struct bq27510_device_info *di)
|
||||
{
|
||||
int ret;
|
||||
int rsoc = 0;
|
||||
#if 0
|
||||
int nvcap = 0,facap = 0,remcap=0,fccap=0,full=0,cnt=0;
|
||||
#endif
|
||||
u8 buf[2];
|
||||
|
||||
ret = bq27510_read(di->client,BQ27500_REG_SOC,buf,2);
|
||||
@@ -163,6 +185,29 @@ static int bq27510_battery_rsoc(struct bq27510_device_info *di)
|
||||
}
|
||||
rsoc = get_unaligned_le16(buf);
|
||||
DBG("Enter:%s %d--rsoc = %d\n",__FUNCTION__,__LINE__,rsoc);
|
||||
#if CONFIG_NO_BATTERY_IC
|
||||
rsoc = 100;
|
||||
#endif
|
||||
#if 0
|
||||
ret = bq27510_read(di->client,0x0c,buf,2);
|
||||
nvcap = get_unaligned_le16(buf);
|
||||
DBG("Enter:%s %d--nvcap = %d\n",__FUNCTION__,__LINE__,nvcap);
|
||||
ret = bq27510_read(di->client,0x0e,buf,2);
|
||||
facap = get_unaligned_le16(buf);
|
||||
DBG("Enter:%s %d--facap = %d\n",__FUNCTION__,__LINE__,facap);
|
||||
ret = bq27510_read(di->client,0x10,buf,2);
|
||||
remcap = get_unaligned_le16(buf);
|
||||
DBG("Enter:%s %d--remcap = %d\n",__FUNCTION__,__LINE__,remcap);
|
||||
ret = bq27510_read(di->client,0x12,buf,2);
|
||||
fccap = get_unaligned_le16(buf);
|
||||
DBG("Enter:%s %d--fccap = %d\n",__FUNCTION__,__LINE__,fccap);
|
||||
ret = bq27510_read(di->client,0x3c,buf,2);
|
||||
full = get_unaligned_le16(buf);
|
||||
DBG("Enter:%s %d--full = %d\n",__FUNCTION__,__LINE__,full);
|
||||
ret = bq27510_read(di->client,0x00,buf,2);
|
||||
cnt = get_unaligned_le16(buf);
|
||||
DBG("Enter:%s %d--full = %d\n",__FUNCTION__,__LINE__,cnt);
|
||||
#endif
|
||||
return rsoc;
|
||||
}
|
||||
|
||||
@@ -208,7 +253,7 @@ static int bq27510_battery_time(struct bq27510_device_info *di, int reg,
|
||||
return ret;
|
||||
}
|
||||
tval = get_unaligned_le16(buf);
|
||||
DBG("Enter:%s %d--no battery data\n",__FUNCTION__,__LINE__,val->intval);
|
||||
DBG("Enter:%s %d--tval=%d\n",__FUNCTION__,__LINE__,tval);
|
||||
if (tval == 65535)
|
||||
return -ENODATA;
|
||||
|
||||
@@ -241,7 +286,7 @@ static int bq27510_battery_get_property(struct power_supply *psy,
|
||||
val->intval = bq27510_battery_current(di);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
val->intval = 100; ///bq27510_battery_rsoc(di);
|
||||
val->intval = bq27510_battery_rsoc(di);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_TEMP:
|
||||
val->intval = bq27510_battery_temperature(di);
|
||||
@@ -262,15 +307,43 @@ static int bq27510_battery_get_property(struct power_supply *psy,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk29_ac_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
if (psy->type == POWER_SUPPLY_TYPE_MAINS){
|
||||
if(gpio_get_value(DC_CHECK_PIN))
|
||||
val->intval = 0;
|
||||
else
|
||||
val->intval = 1;
|
||||
}
|
||||
DBG("%s:%d val->intval = %d\n",__FUNCTION__,__LINE__,val->intval);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bq27510_powersupply_init(struct bq27510_device_info *di)
|
||||
{
|
||||
di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
di->bat.properties = bq27510_battery_props;
|
||||
di->bat.num_properties = ARRAY_SIZE(bq27510_battery_props);
|
||||
di->bat.get_property = bq27510_battery_get_property;
|
||||
di->bat.external_power_changed = NULL;
|
||||
|
||||
di->ac.type = POWER_SUPPLY_TYPE_MAINS;
|
||||
di->ac.properties = rk29_ac_props;
|
||||
di->ac.num_properties = ARRAY_SIZE(rk29_ac_props);
|
||||
di->ac.get_property = rk29_ac_get_property;
|
||||
}
|
||||
|
||||
|
||||
static void bq27510_battery_update_status(struct bq27510_device_info *di)
|
||||
{
|
||||
power_supply_changed(&di->bat);
|
||||
@@ -289,7 +362,11 @@ static int bq27510_battery_probe(struct i2c_client *client,
|
||||
{
|
||||
struct bq27510_device_info *di;
|
||||
int retval = 0;
|
||||
|
||||
|
||||
#ifdef CONFIG_CHECK_BATT_CAPACITY
|
||||
u8 buf[2];
|
||||
#endif
|
||||
|
||||
di = kzalloc(sizeof(*di), GFP_KERNEL);
|
||||
if (!di) {
|
||||
dev_err(&client->dev, "failed to allocate device info data\n");
|
||||
@@ -302,8 +379,18 @@ static int bq27510_battery_probe(struct i2c_client *client,
|
||||
di->client = client;
|
||||
/* 4 seconds between monotor runs interval */
|
||||
di->interval = msecs_to_jiffies(4 * 1000);
|
||||
|
||||
gpio_request(DC_CHECK_PIN,"dc_check");
|
||||
gpio_direction_input(DC_CHECK_PIN);
|
||||
bq27510_powersupply_init(di);
|
||||
|
||||
#ifdef CONFIG_CHECK_BATT_CAPACITY
|
||||
buf[0] = 0x41;
|
||||
buf[1] = 0x00;
|
||||
bq27510_write(di->client,0x00,buf,2);
|
||||
buf[0] = 0x21;
|
||||
buf[1] = 0x00;
|
||||
bq27510_write(di->client,0x00,buf,2);
|
||||
#endif
|
||||
retval = power_supply_register(&client->dev, &di->bat);
|
||||
if (retval) {
|
||||
dev_err(&client->dev, "failed to register battery\n");
|
||||
|
||||
Reference in New Issue
Block a user