From a91ea896443c408ca9d7b04fe69a8f07e8601876 Mon Sep 17 00:00:00 2001 From: lhh Date: Thu, 23 Dec 2010 15:22:33 +0800 Subject: [PATCH] add bq27510 battery check --- drivers/power/Kconfig | 19 +++++- drivers/power/bq27510_battery.c | 101 +++++++++++++++++++++++++++++--- 2 files changed, 112 insertions(+), 8 deletions(-) diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index a02b63a77c46..0b5e176a9162 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -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 diff --git a/drivers/power/bq27510_battery.c b/drivers/power/bq27510_battery.c index 00194fe6e7ab..1794cd1902ac 100644 --- a/drivers/power/bq27510_battery.c +++ b/drivers/power/bq27510_battery.c @@ -21,6 +21,7 @@ #include #include #include +#include #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"); -- 2.34.1