diff options
| author | mattis fjallstrom <mattis@acm.org> | 2015-12-22 09:08:51 -0800 |
|---|---|---|
| committer | mattis fjallstrom <mattis@acm.org> | 2015-12-22 09:11:17 -0800 |
| commit | d5e9b490da6d4444025a9315a89ad6d8ec70f50b (patch) | |
| tree | 27defa50c232d02ad0aa7cc1ef3d6dfb86744bef | |
| parent | f3fe6c93fcb0efee43eb00bba5112696806b65c3 (diff) | |
| download | olio-linux-3.10-d5e9b490da6d4444025a9315a89ad6d8ec70f50b.tar.xz olio-linux-3.10-d5e9b490da6d4444025a9315a89ad6d8ec70f50b.zip | |
Adding current parameter to request_current, currently requesting 100mA when battery is full and 390 otherwise. Also bugfixes and clean-up.
Change-Id: Id4c3c6008ea12bfdcdd1145d32ff9d8ef7784d66
| -rw-r--r-- | drivers/power/bq27x00_battery.c | 19 | ||||
| -rw-r--r-- | drivers/staging/triune/ts81001.c | 172 | ||||
| -rw-r--r-- | drivers/staging/triune/ts81001.h | 4 |
3 files changed, 162 insertions, 33 deletions
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index ed6846f6133..e0ab81f4cc3 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -50,9 +50,9 @@ #include "../staging/triune/ts81001.h" #endif /* CONFIG_OLIO_TS81001 */ - #ifdef OLIODEBUG -#define do { olio_debug(format, ...) printk("OLIO %s: ", __FUNCTION__); \ +#define olio_debug(format, ...) do { \ + printk("OLIO %s: ", __FUNCTION__); \ printk(format, ##__VA_ARGS__); } while(0) #else #define olio_debug(format, ...) @@ -974,9 +974,11 @@ static void bq27x00_update(struct bq27x00_device_info *di) bool is_bq274xx = di->chip == BQ274XX; bool is_bq276xx = di->chip == BQ276XX; + olio_debug ("entered\n"); + cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, !is_bq27500); - printk ("%s OLIO Cache flags read from bq is 0x%x\n", __FUNCTION__, cache.flags); + printk ("Cache flags read from bq is 0x%x\n", cache.flags); if (cache.flags >= 0) { if (is_bq27200 && (cache.flags & BQ27200_FLAG_CI)) { @@ -1210,13 +1212,11 @@ static int bq27x00_charger_status(struct bq27x00_device_info *di) { olio_debug("Got client data for dev %s\n", dev_name(ts81001->dev)); -#ifdef CHG_FLAGS_WORKING - if(di->cache.flags & BQ27XXX_FLAG_CHG) { -#endif - ts81001->ops->request_charge(ts81001); -#ifdef CHG_FLAGS_WORKING + if(di->cache.flags & BQ27XXX_FLAG_FC) { + ts81001->ops->request_charge(ts81001, 100); + } else { + ts81001->ops->request_charge(ts81001, 390); } -#endif state = ts81001->ops->get_status(ts81001); @@ -1509,6 +1509,7 @@ static int __init bq27x00_powersupply_init(struct bq27x00_device_info *di) } ret = enable_irq_wake(di->irq); + if (ret) { dev_err(di->dev, "failed to enable irq: %d, as wake\n", di->irq); return ret; diff --git a/drivers/staging/triune/ts81001.c b/drivers/staging/triune/ts81001.c index b3cb6c64a1f..d5046af4545 100644 --- a/drivers/staging/triune/ts81001.c +++ b/drivers/staging/triune/ts81001.c @@ -56,8 +56,11 @@ const u8 TS81001_CURRENT_REG_MSB = 0x21; /* Trying 400mA since we can't actually set 390mA. */ const u16 TS81001_CHARGE_CURRENT = 400; -const u8 TS81001_CHARGE_CURRENT_LSB = 0x90; /* 0x186 -> 390 dec = 0x186 hex */ -const u8 TS81001_CHARGE_CURRENT_MSB = 0x01; /* 0x190 -> 400dec */ +const u8 TS81001_CHARGE_CURRENT_LSB = 0x90; /* 0x190 == 400 (0x186 == 390)*/ +const u8 TS81001_CHARGE_CURRENT_MSB = 0x01; + +const u8 TS81001_CHARGE_CURR_100_LSB = 0x64; /* 0x64 == 100 */ +const u8 TS81001_CHARGE_CURR_100_MSB = 0x00; /*************************************************************************** @@ -94,34 +97,34 @@ static int ts81001_i2c_read (struct i2c_client * client, return err; } -static int ts81001_write_i2c_blk(struct i2c_client * client, u8 reg, - u8 *data, u8 sz) +static int ts81001_write_i2c_blk(struct i2c_client * client, u8 reg_addr, + u8 * data, u16 sz) { struct i2c_msg msg; int ret; - u8 buf[33]; + u8 buf[3]; olio_debug ("entered\n"); if (!client->adapter) return -ENODEV; - buf[0] = reg; + buf[0] = reg_addr; memcpy(&buf[1], data, sz); - msg.buf = buf; + olio_debug ("writing 0x%x,0x%x to 0x%x device 0x%x\n", + buf[1], buf[2], buf[0], client->addr); + msg.addr = client->addr; - msg.flags = client->flags; + msg.flags = 0; //client->flags; msg.len = sz + 1; + msg.buf = buf; ret = i2c_transfer(client->adapter, &msg, 1); olio_debug ("exiting, ret = %d\n", ret); - if (ret < 0) - return ret; - - return 0; + return ret; } /*************************************************************************** @@ -143,10 +146,11 @@ static int ts81001_get_status (struct ts81001 * ts) { olio_debug ("entered\n"); for (i = 0; i < retries; i++) { - err = ts81001_i2c_read (ts->client, TS81001_STATUS_REG, len, &data, false); - + err = ts81001_i2c_read (ts->client, + TS81001_STATUS_REG, len, &data, false); if (err <= 0) { - olio_debug ("Error reading status from ts81001, err = %d\n", err); + olio_debug ("Error reading status from ts81001, err = %d\n", + err); state = err; } else { state = (ts81001_state_t) data; @@ -159,31 +163,153 @@ static int ts81001_get_status (struct ts81001 * ts) { return state; } -static int ts81001_request_charge (struct ts81001 * ts) { +/*************************************************************************** + * ts81001_request_charge - ask for current from charger + * + * This function allows us to set a new current for the charger. It depends + * on the firmware being recent enough, though. + */ + +static int ts81001_request_charge (struct ts81001 * ts, u16 mA) { int retries = 2; int err = 0; int i; /* u16 request_current = TS81001_CHARGE_CURRENT; */ u8 data[2]; - data[0] = TS81001_CHARGE_CURRENT_LSB; - data[1] = TS81001_CHARGE_CURRENT_MSB; - - olio_debug ("entered, requested current = 0x%x, 0x%x\n", - TS81001_CHARGE_CURRENT_LSB, TS81001_CHARGE_CURRENT_MSB); + data[0] = mA & 0x00ff; + data[1] = (mA & 0xff00) >> 8; + olio_debug ("entered, requested current = lb:0x%x, hb:0x%x\n", + data[0], data[1]); + for (i = 0; i < retries; i++) { - err = ts81001_write_i2c_blk(ts->client, TS81001_CURRENT_REG_LSB, + err = ts81001_write_i2c_blk(ts->client, + TS81001_CURRENT_REG_LSB, &data[0], 2); + if (err <= 0) + olio_debug ("error (%d) writing data to " + "register (try = %d)\n", err, i); } + + return err; +} + +/*************************************************************************** + * ts81001_charging_stop - send charge complete to power provider + * + * This function allows to stop charging - stopping and restarting charging + * is intended to simulate the device taken off the charger and put back on. + */ + +#define TS81001_CHARGE_COMPLETE 0x01 +#define TS81001_STATE_REPORT_REG 0x12 + +static int ts81001_charging_stop (struct ts81001 * ts) { + u8 data; + int len = 1; + int err = 0; + int i, retries = 2; + + olio_debug ("entered\n"); + + data = TS81001_CHARGE_COMPLETE; + + for (i = 0; i < retries; i++) { + err = ts81001_write_i2c_blk(ts->client, TS81001_STATE_REPORT_REG, + (u8*) &data, len); + } + + if (err <= 0) { + olio_debug ("Error writing charging stop to ts81001, " + "err = %d\n", err); + } + + + olio_debug ("exiting\n"); return err; } +/*************************************************************************** + * ts81001_charging_stop - send charge complete to power provider + * + * This function allows to stop charging - stopping and restarting charging + * is intended to simulate the device taken off the charger and put back on. + */ + +#define TS81001_CHARGE_RESTART 0xFF + +static int ts81001_charging_restart (struct ts81001 * ts) { + u8 data; + int len = 1; + int err = 0; + int i, retries = 2; + + olio_debug ("entered\n"); + + data = TS81001_CHARGE_RESTART; + + for (i = 0; i < retries; i++) { + err = ts81001_write_i2c_blk(ts->client, + TS81001_STATE_REPORT_REG, + (u8*) &data, len); + + if (err <= 0) { + olio_debug ("Error writing state to ts81001, " + "err = %d\n", err); + } + } + + olio_debug ("exiting\n"); + + return err; +} + +#if 0 + +/* NOT FUNCTIONAL, NOT SURE HOW TO MAKE IT FUNCTIONAL! */ + +/*************************************************************************** + * ts81001_disconnect - stop talking to power TX + * + * If we send a 'signal strength' package, the TX unit should forget that + * we've reached full charge. + */ + +static int ts81001_disconnect (struct ts81001 * ts) { + u8 data; + int len = 1; + int err = 0; + int i, retries = 2; + + olio_debug ("entered\n"); + + data = TS81001_CHARGE_RESTART; + + for (i = 0; i < retries; i++) { + err = ts81001_write_i2c_blk(ts->client, + TS81001_STATE_REPORT_REG, + (u8*) &data, len); + + if (err <= 0) { + olio_debug ("Error writing state to ts81001, " + "err = %d\n", err); + } + } + + olio_debug ("exiting\n"); + + return err; +} +#endif + static struct ts81001_ops ts_ops = { .get_status = ts81001_get_status, .request_charge = ts81001_request_charge, + .charge_stop = ts81001_charging_stop, + .charge_start = ts81001_charging_restart, }; /*************************************************************************** @@ -249,6 +375,6 @@ static struct i2c_driver ts81001_i2c_driver = { module_i2c_driver(ts81001_i2c_driver); -MODULE_AUTHOR("Mattis Fjallstrom <mattis@oliodevice.com"); +MODULE_AUTHOR("Mattis Fjallstrom <mattis@oliodevices.com"); MODULE_DESCRIPTION("Basic driver for TS81001"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/triune/ts81001.h b/drivers/staging/triune/ts81001.h index 8978ca2f0d1..aecf19780cc 100644 --- a/drivers/staging/triune/ts81001.h +++ b/drivers/staging/triune/ts81001.h @@ -52,7 +52,9 @@ struct ts81001 { struct ts81001_ops { int (*get_status) (struct ts81001 * ts); - int (*request_charge) (struct ts81001 * ts); + int (*request_charge) (struct ts81001 * ts, u16 charge); + int (*charge_stop) (struct ts81001 * ts); + int (*charge_start) (struct ts81001 * ts); }; #endif /* _CONFIG_TS81001_H */ |