summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/power/bq27x00_battery.c19
-rw-r--r--drivers/staging/triune/ts81001.c172
-rw-r--r--drivers/staging/triune/ts81001.h4
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 */