aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew F. Davis <afd@ti.com>2015-11-23 11:53:51 -0500
committerSebastian Reichel <sre@kernel.org>2015-12-04 20:06:51 -0500
commit703df6c097956d17a818e63961c82e8e9eef9fef (patch)
tree0feab6ac8900207ca50ff7d139943cceaef98e44
parent1f94b2563a02327aa8a1385c8a92b0c3f96d01b4 (diff)
power: bq27xxx_battery: Reorganize I2C into a module
Separate out I2C functionality into a module. This fixes several small issues and simplifies the driver initialization. Signed-off-by: Andrew F. Davis <afd@ti.com> Signed-off-by: Sebastian Reichel <sre@kernel.org>
-rw-r--r--drivers/power/Kconfig14
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/bq27xxx_battery.c326
-rw-r--r--drivers/power/bq27xxx_battery_i2c.c150
-rw-r--r--include/linux/power/bq27xxx_battery.h57
5 files changed, 227 insertions, 321 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 237d7aa73e8c..42a5b51c3d2e 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -160,22 +160,16 @@ config BATTERY_SBS
160config BATTERY_BQ27XXX 160config BATTERY_BQ27XXX
161 tristate "BQ27xxx battery driver" 161 tristate "BQ27xxx battery driver"
162 help 162 help
163 Say Y here to enable support for batteries with BQ27xxx (I2C/HDQ) chips. 163 Say Y here to enable support for batteries with BQ27xxx chips.
164 164
165config BATTERY_BQ27XXX_I2C 165config BATTERY_BQ27XXX_I2C
166 bool "BQ27xxx I2C support" 166 tristate "BQ27xxx I2C support"
167 depends on BATTERY_BQ27XXX 167 depends on BATTERY_BQ27XXX
168 depends on I2C 168 depends on I2C
169 default y 169 default y
170 help 170 help
171 Say Y here to enable support for batteries with BQ27xxx (I2C) chips. 171 Say Y here to enable support for batteries with BQ27xxx chips
172 172 connected over an I2C bus.
173config BATTERY_BQ27XXX_PLATFORM
174 bool "BQ27xxx HDQ support"
175 depends on BATTERY_BQ27XXX
176 default y
177 help
178 Say Y here to enable support for batteries with BQ27xxx (HDQ) chips.
179 173
180config BATTERY_DA9030 174config BATTERY_DA9030
181 tristate "DA9030 battery driver" 175 tristate "DA9030 battery driver"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b656638f8b39..0e4eab55f8d7 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o
31obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o 31obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
32obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o 32obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o
33obj-$(CONFIG_BATTERY_BQ27XXX) += bq27xxx_battery.o 33obj-$(CONFIG_BATTERY_BQ27XXX) += bq27xxx_battery.o
34obj-$(CONFIG_BATTERY_BQ27XXX_I2C) += bq27xxx_battery_i2c.o
34obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o 35obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
35obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o 36obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
36obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o 37obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o
diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 1cad7accf339..8d4ef9fd9b6e 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -45,11 +45,7 @@
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/platform_device.h> 46#include <linux/platform_device.h>
47#include <linux/power_supply.h> 47#include <linux/power_supply.h>
48#include <linux/idr.h>
49#include <linux/i2c.h>
50#include <linux/slab.h> 48#include <linux/slab.h>
51#include <linux/interrupt.h>
52#include <asm/unaligned.h>
53 49
54#include <linux/power/bq27xxx_battery.h> 50#include <linux/power/bq27xxx_battery.h>
55 51
@@ -78,11 +74,6 @@
78#define BQ27XXX_POWER_CONSTANT (29200) /* 29.2 µV^2 * 1000 */ 74#define BQ27XXX_POWER_CONSTANT (29200) /* 29.2 µV^2 * 1000 */
79#define BQ27XXX_CURRENT_CONSTANT (3570) /* 3.57 µV * 1000 */ 75#define BQ27XXX_CURRENT_CONSTANT (3570) /* 3.57 µV * 1000 */
80 76
81struct bq27xxx_device_info;
82struct bq27xxx_access_methods {
83 int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
84};
85
86#define INVALID_REG_ADDR 0xff 77#define INVALID_REG_ADDR 0xff
87 78
88/* 79/*
@@ -110,40 +101,6 @@ enum bq27xxx_reg_index {
110 BQ27XXX_REG_AP, /* Average Power */ 101 BQ27XXX_REG_AP, /* Average Power */
111}; 102};
112 103
113struct bq27xxx_reg_cache {
114 int temperature;
115 int time_to_empty;
116 int time_to_empty_avg;
117 int time_to_full;
118 int charge_full;
119 int cycle_count;
120 int capacity;
121 int energy;
122 int flags;
123 int power_avg;
124 int health;
125};
126
127struct bq27xxx_device_info {
128 struct device *dev;
129 int id;
130 enum bq27xxx_chip chip;
131
132 struct bq27xxx_reg_cache cache;
133 int charge_design_full;
134
135 unsigned long last_update;
136 struct delayed_work work;
137
138 struct power_supply *bat;
139
140 struct bq27xxx_access_methods bus;
141
142 struct mutex lock;
143
144 u8 *regs;
145};
146
147/* Register mappings */ 104/* Register mappings */
148static u8 bq27000_regs[] = { 105static u8 bq27000_regs[] = {
149 0x00, /* CONTROL */ 106 0x00, /* CONTROL */
@@ -710,7 +667,7 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
710 return POWER_SUPPLY_HEALTH_GOOD; 667 return POWER_SUPPLY_HEALTH_GOOD;
711} 668}
712 669
713static void bq27xxx_battery_update(struct bq27xxx_device_info *di) 670void bq27xxx_battery_update(struct bq27xxx_device_info *di)
714{ 671{
715 struct bq27xxx_reg_cache cache = {0, }; 672 struct bq27xxx_reg_cache cache = {0, };
716 bool has_ci_flag = di->chip == BQ27000 || di->chip == BQ27010; 673 bool has_ci_flag = di->chip == BQ27000 || di->chip == BQ27010;
@@ -761,6 +718,7 @@ static void bq27xxx_battery_update(struct bq27xxx_device_info *di)
761 718
762 di->last_update = jiffies; 719 di->last_update = jiffies;
763} 720}
721EXPORT_SYMBOL_GPL(bq27xxx_battery_update);
764 722
765static void bq27xxx_battery_poll(struct work_struct *work) 723static void bq27xxx_battery_poll(struct work_struct *work)
766{ 724{
@@ -991,32 +949,30 @@ static void bq27xxx_external_power_changed(struct power_supply *psy)
991 schedule_delayed_work(&di->work, 0); 949 schedule_delayed_work(&di->work, 0);
992} 950}
993 951
994static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di, 952int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
995 const char *name)
996{ 953{
997 int ret;
998 struct power_supply_desc *psy_desc; 954 struct power_supply_desc *psy_desc;
999 struct power_supply_config psy_cfg = { .drv_data = di, }; 955 struct power_supply_config psy_cfg = { .drv_data = di, };
1000 956
957 INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
958 mutex_init(&di->lock);
959 di->regs = bq27xxx_regs[di->chip];
960
1001 psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL); 961 psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL);
1002 if (!psy_desc) 962 if (!psy_desc)
1003 return -ENOMEM; 963 return -ENOMEM;
1004 964
1005 psy_desc->name = name; 965 psy_desc->name = di->name;
1006 psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; 966 psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
1007 psy_desc->properties = bq27xxx_battery_props[di->chip].props; 967 psy_desc->properties = bq27xxx_battery_props[di->chip].props;
1008 psy_desc->num_properties = bq27xxx_battery_props[di->chip].size; 968 psy_desc->num_properties = bq27xxx_battery_props[di->chip].size;
1009 psy_desc->get_property = bq27xxx_battery_get_property; 969 psy_desc->get_property = bq27xxx_battery_get_property;
1010 psy_desc->external_power_changed = bq27xxx_external_power_changed; 970 psy_desc->external_power_changed = bq27xxx_external_power_changed;
1011 971
1012 INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);
1013 mutex_init(&di->lock);
1014
1015 di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg); 972 di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg);
1016 if (IS_ERR(di->bat)) { 973 if (IS_ERR(di->bat)) {
1017 ret = PTR_ERR(di->bat); 974 dev_err(di->dev, "failed to register battery\n");
1018 dev_err(di->dev, "failed to register battery: %d\n", ret); 975 return PTR_ERR(di->bat);
1019 return ret;
1020 } 976 }
1021 977
1022 dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION); 978 dev_info(di->dev, "support ver. %s enabled\n", DRIVER_VERSION);
@@ -1025,8 +981,9 @@ static int bq27xxx_powersupply_init(struct bq27xxx_device_info *di,
1025 981
1026 return 0; 982 return 0;
1027} 983}
984EXPORT_SYMBOL_GPL(bq27xxx_battery_setup);
1028 985
1029static void bq27xxx_powersupply_unregister(struct bq27xxx_device_info *di) 986void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
1030{ 987{
1031 /* 988 /*
1032 * power_supply_unregister call bq27xxx_battery_get_property which 989 * power_supply_unregister call bq27xxx_battery_get_property which
@@ -1042,192 +999,7 @@ static void bq27xxx_powersupply_unregister(struct bq27xxx_device_info *di)
1042 999
1043 mutex_destroy(&di->lock); 1000 mutex_destroy(&di->lock);
1044} 1001}
1045 1002EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);
1046/* i2c specific code */
1047#ifdef CONFIG_BATTERY_BQ27XXX_I2C
1048
1049/* If the system has several batteries we need a different name for each
1050 * of them...
1051 */
1052static DEFINE_IDR(battery_id);
1053static DEFINE_MUTEX(battery_mutex);
1054
1055static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data)
1056{
1057 struct bq27xxx_device_info *di = data;
1058
1059 bq27xxx_battery_update(di);
1060
1061 return IRQ_HANDLED;
1062}
1063
1064static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
1065 bool single)
1066{
1067 struct i2c_client *client = to_i2c_client(di->dev);
1068 struct i2c_msg msg[2];
1069 unsigned char data[2];
1070 int ret;
1071
1072 if (!client->adapter)
1073 return -ENODEV;
1074
1075 msg[0].addr = client->addr;
1076 msg[0].flags = 0;
1077 msg[0].buf = &reg;
1078 msg[0].len = sizeof(reg);
1079 msg[1].addr = client->addr;
1080 msg[1].flags = I2C_M_RD;
1081 msg[1].buf = data;
1082 if (single)
1083 msg[1].len = 1;
1084 else
1085 msg[1].len = 2;
1086
1087 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
1088 if (ret < 0)
1089 return ret;
1090
1091 if (!single)
1092 ret = get_unaligned_le16(data);
1093 else
1094 ret = data[0];
1095
1096 return ret;
1097}
1098
1099static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
1100 const struct i2c_device_id *id)
1101{
1102 char *name;
1103 struct bq27xxx_device_info *di;
1104 int num;
1105 int retval = 0;
1106
1107 /* Get new ID for the new battery device */
1108 mutex_lock(&battery_mutex);
1109 num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL);
1110 mutex_unlock(&battery_mutex);
1111 if (num < 0)
1112 return num;
1113
1114 name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num);
1115 if (!name) {
1116 retval = -ENOMEM;
1117 goto batt_failed;
1118 }
1119
1120 di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL);
1121 if (!di) {
1122 retval = -ENOMEM;
1123 goto batt_failed;
1124 }
1125
1126 di->id = num;
1127 di->dev = &client->dev;
1128 di->chip = id->driver_data;
1129 di->bus.read = &bq27xxx_battery_i2c_read;
1130 di->regs = bq27xxx_regs[di->chip];
1131
1132 retval = bq27xxx_powersupply_init(di, name);
1133 if (retval)
1134 goto batt_failed;
1135
1136 /* Schedule a polling after about 1 min */
1137 schedule_delayed_work(&di->work, 60 * HZ);
1138
1139 i2c_set_clientdata(client, di);
1140
1141 if (client->irq) {
1142 retval = devm_request_threaded_irq(&client->dev, client->irq,
1143 NULL, bq27xxx_battery_irq_handler_thread,
1144 IRQF_ONESHOT,
1145 name, di);
1146 if (retval) {
1147 dev_err(&client->dev,
1148 "Unable to register IRQ %d error %d\n",
1149 client->irq, retval);
1150 return retval;
1151 }
1152 }
1153
1154 return 0;
1155
1156batt_failed:
1157 mutex_lock(&battery_mutex);
1158 idr_remove(&battery_id, num);
1159 mutex_unlock(&battery_mutex);
1160
1161 return retval;
1162}
1163
1164static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
1165{
1166 struct bq27xxx_device_info *di = i2c_get_clientdata(client);
1167
1168 bq27xxx_powersupply_unregister(di);
1169
1170 mutex_lock(&battery_mutex);
1171 idr_remove(&battery_id, di->id);
1172 mutex_unlock(&battery_mutex);
1173
1174 return 0;
1175}
1176
1177static const struct i2c_device_id bq27xxx_id[] = {
1178 { "bq27200", BQ27000 },
1179 { "bq27210", BQ27010 },
1180 { "bq27500", BQ27500 },
1181 { "bq27510", BQ27500 },
1182 { "bq27520", BQ27500 },
1183 { "bq27530", BQ27530 },
1184 { "bq27531", BQ27530 },
1185 { "bq27541", BQ27541 },
1186 { "bq27542", BQ27541 },
1187 { "bq27546", BQ27541 },
1188 { "bq27742", BQ27541 },
1189 { "bq27545", BQ27545 },
1190 { "bq27421", BQ27421 },
1191 { "bq27425", BQ27421 },
1192 { "bq27441", BQ27421 },
1193 { "bq27621", BQ27421 },
1194 {},
1195};
1196MODULE_DEVICE_TABLE(i2c, bq27xxx_id);
1197
1198static struct i2c_driver bq27xxx_battery_i2c_driver = {
1199 .driver = {
1200 .name = "bq27xxx-battery",
1201 },
1202 .probe = bq27xxx_battery_i2c_probe,
1203 .remove = bq27xxx_battery_i2c_remove,
1204 .id_table = bq27xxx_id,
1205};
1206
1207static inline int bq27xxx_battery_i2c_init(void)
1208{
1209 int ret = i2c_add_driver(&bq27xxx_battery_i2c_driver);
1210
1211 if (ret)
1212 pr_err("Unable to register BQ27xxx i2c driver\n");
1213
1214 return ret;
1215}
1216
1217static inline void bq27xxx_battery_i2c_exit(void)
1218{
1219 i2c_del_driver(&bq27xxx_battery_i2c_driver);
1220}
1221
1222#else
1223
1224static inline int bq27xxx_battery_i2c_init(void) { return 0; }
1225static inline void bq27xxx_battery_i2c_exit(void) {};
1226
1227#endif
1228
1229/* platform specific code */
1230#ifdef CONFIG_BATTERY_BQ27XXX_PLATFORM
1231 1003
1232static int bq27xxx_battery_platform_read(struct bq27xxx_device_info *di, u8 reg, 1004static int bq27xxx_battery_platform_read(struct bq27xxx_device_info *di, u8 reg,
1233 bool single) 1005 bool single)
@@ -1267,7 +1039,6 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
1267{ 1039{
1268 struct bq27xxx_device_info *di; 1040 struct bq27xxx_device_info *di;
1269 struct bq27xxx_platform_data *pdata = pdev->dev.platform_data; 1041 struct bq27xxx_platform_data *pdata = pdev->dev.platform_data;
1270 const char *name;
1271 1042
1272 if (!pdata) { 1043 if (!pdata) {
1273 dev_err(&pdev->dev, "no platform_data supplied\n"); 1044 dev_err(&pdev->dev, "no platform_data supplied\n");
@@ -1292,83 +1063,36 @@ static int bq27xxx_battery_platform_probe(struct platform_device *pdev)
1292 1063
1293 di->dev = &pdev->dev; 1064 di->dev = &pdev->dev;
1294 di->chip = pdata->chip; 1065 di->chip = pdata->chip;
1295 di->regs = bq27xxx_regs[di->chip]; 1066 di->name = pdata->name ?: dev_name(&pdev->dev);
1296 1067 di->bus.read = bq27xxx_battery_platform_read;
1297 name = pdata->name ?: dev_name(&pdev->dev);
1298 di->bus.read = &bq27xxx_battery_platform_read;
1299 1068
1300 return bq27xxx_powersupply_init(di, name); 1069 return bq27xxx_battery_setup(di);
1301} 1070}
1302 1071
1303static int bq27xxx_battery_platform_remove(struct platform_device *pdev) 1072static int bq27xxx_battery_platform_remove(struct platform_device *pdev)
1304{ 1073{
1305 struct bq27xxx_device_info *di = platform_get_drvdata(pdev); 1074 struct bq27xxx_device_info *di = platform_get_drvdata(pdev);
1306 1075
1307 bq27xxx_powersupply_unregister(di); 1076 bq27xxx_battery_teardown(di);
1308 1077
1309 return 0; 1078 return 0;
1310} 1079}
1311 1080
1081static const struct platform_device_id bq27xxx_battery_platform_id_table[] = {
1082 { "bq27000-battery", },
1083 { /* sentinel */ }
1084};
1085MODULE_DEVICE_TABLE(platform, bq27xxx_battery_platform_id_table);
1086
1312static struct platform_driver bq27xxx_battery_platform_driver = { 1087static struct platform_driver bq27xxx_battery_platform_driver = {
1313 .probe = bq27xxx_battery_platform_probe, 1088 .probe = bq27xxx_battery_platform_probe,
1314 .remove = bq27xxx_battery_platform_remove, 1089 .remove = bq27xxx_battery_platform_remove,
1315 .driver = { 1090 .driver = {
1316 .name = "bq27000-battery", 1091 .name = "bq27000-battery",
1317 }, 1092 },
1093 .id_table = bq27xxx_battery_platform_id_table,
1318}; 1094};
1319 1095module_platform_driver(bq27xxx_battery_platform_driver);
1320static inline int bq27xxx_battery_platform_init(void)
1321{
1322 int ret = platform_driver_register(&bq27xxx_battery_platform_driver);
1323
1324 if (ret)
1325 pr_err("Unable to register BQ27xxx platform driver\n");
1326
1327 return ret;
1328}
1329
1330static inline void bq27xxx_battery_platform_exit(void)
1331{
1332 platform_driver_unregister(&bq27xxx_battery_platform_driver);
1333}
1334
1335#else
1336
1337static inline int bq27xxx_battery_platform_init(void) { return 0; }
1338static inline void bq27xxx_battery_platform_exit(void) {};
1339
1340#endif
1341
1342/*
1343 * Module stuff
1344 */
1345
1346static int __init bq27xxx_battery_init(void)
1347{
1348 int ret;
1349
1350 ret = bq27xxx_battery_i2c_init();
1351 if (ret)
1352 return ret;
1353
1354 ret = bq27xxx_battery_platform_init();
1355 if (ret)
1356 bq27xxx_battery_i2c_exit();
1357
1358 return ret;
1359}
1360module_init(bq27xxx_battery_init);
1361
1362static void __exit bq27xxx_battery_exit(void)
1363{
1364 bq27xxx_battery_platform_exit();
1365 bq27xxx_battery_i2c_exit();
1366}
1367module_exit(bq27xxx_battery_exit);
1368
1369#ifdef CONFIG_BATTERY_BQ27XXX_PLATFORM
1370MODULE_ALIAS("platform:bq27000-battery");
1371#endif
1372 1096
1373MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); 1097MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
1374MODULE_DESCRIPTION("BQ27xxx battery monitor driver"); 1098MODULE_DESCRIPTION("BQ27xxx battery monitor driver");
diff --git a/drivers/power/bq27xxx_battery_i2c.c b/drivers/power/bq27xxx_battery_i2c.c
new file mode 100644
index 000000000000..9429e66be096
--- /dev/null
+++ b/drivers/power/bq27xxx_battery_i2c.c
@@ -0,0 +1,150 @@
1/*
2 * SCI Reset driver for Keystone based devices
3 *
4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
5 * Andrew F. Davis <afd@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/i2c.h>
18#include <linux/interrupt.h>
19#include <linux/module.h>
20#include <asm/unaligned.h>
21
22#include <linux/power/bq27xxx_battery.h>
23
24static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data)
25{
26 struct bq27xxx_device_info *di = data;
27
28 bq27xxx_battery_update(di);
29
30 return IRQ_HANDLED;
31}
32
33static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
34 bool single)
35{
36 struct i2c_client *client = to_i2c_client(di->dev);
37 struct i2c_msg msg[2];
38 unsigned char data[2];
39 int ret;
40
41 if (!client->adapter)
42 return -ENODEV;
43
44 msg[0].addr = client->addr;
45 msg[0].flags = 0;
46 msg[0].buf = &reg;
47 msg[0].len = sizeof(reg);
48 msg[1].addr = client->addr;
49 msg[1].flags = I2C_M_RD;
50 msg[1].buf = data;
51 if (single)
52 msg[1].len = 1;
53 else
54 msg[1].len = 2;
55
56 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
57 if (ret < 0)
58 return ret;
59
60 if (!single)
61 ret = get_unaligned_le16(data);
62 else
63 ret = data[0];
64
65 return ret;
66}
67
68static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
69 const struct i2c_device_id *id)
70{
71 struct bq27xxx_device_info *di;
72 int ret;
73
74 di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL);
75 if (!di)
76 return -ENOMEM;
77
78 di->dev = &client->dev;
79 di->chip = id->driver_data;
80 di->name = id->name;
81 di->bus.read = bq27xxx_battery_i2c_read;
82
83 ret = bq27xxx_battery_setup(di);
84 if (ret)
85 return ret;
86
87 /* Schedule a polling after about 1 min */
88 schedule_delayed_work(&di->work, 60 * HZ);
89
90 i2c_set_clientdata(client, di);
91
92 if (client->irq) {
93 ret = devm_request_threaded_irq(&client->dev, client->irq,
94 NULL, bq27xxx_battery_irq_handler_thread,
95 IRQF_ONESHOT,
96 di->name, di);
97 if (ret) {
98 dev_err(&client->dev,
99 "Unable to register IRQ %d error %d\n",
100 client->irq, ret);
101 return ret;
102 }
103 }
104
105 return 0;
106}
107
108static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
109{
110 struct bq27xxx_device_info *di = i2c_get_clientdata(client);
111
112 bq27xxx_battery_teardown(di);
113
114 return 0;
115}
116
117static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
118 { "bq27200", BQ27000 },
119 { "bq27210", BQ27010 },
120 { "bq27500", BQ27500 },
121 { "bq27510", BQ27500 },
122 { "bq27520", BQ27500 },
123 { "bq27530", BQ27530 },
124 { "bq27531", BQ27530 },
125 { "bq27541", BQ27541 },
126 { "bq27542", BQ27541 },
127 { "bq27546", BQ27541 },
128 { "bq27742", BQ27541 },
129 { "bq27545", BQ27545 },
130 { "bq27421", BQ27421 },
131 { "bq27425", BQ27421 },
132 { "bq27441", BQ27421 },
133 { "bq27621", BQ27421 },
134 {},
135};
136MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
137
138static struct i2c_driver bq27xxx_battery_i2c_driver = {
139 .driver = {
140 .name = "bq27xxx-battery",
141 },
142 .probe = bq27xxx_battery_i2c_probe,
143 .remove = bq27xxx_battery_i2c_remove,
144 .id_table = bq27xxx_i2c_id_table,
145};
146module_i2c_driver(bq27xxx_battery_i2c_driver);
147
148MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
149MODULE_DESCRIPTION("BQ27xxx battery monitor i2c driver");
150MODULE_LICENSE("GPL");
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index 45f6a7b5b3cb..998d8f1c3c91 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -1,6 +1,16 @@
1#ifndef __LINUX_BQ27X00_BATTERY_H__ 1#ifndef __LINUX_BQ27X00_BATTERY_H__
2#define __LINUX_BQ27X00_BATTERY_H__ 2#define __LINUX_BQ27X00_BATTERY_H__
3 3
4enum bq27xxx_chip {
5 BQ27000 = 1, /* bq27000, bq27200 */
6 BQ27010, /* bq27010, bq27210 */
7 BQ27500, /* bq27500, bq27510, bq27520 */
8 BQ27530, /* bq27530, bq27531 */
9 BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
10 BQ27545, /* bq27545 */
11 BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
12};
13
4/** 14/**
5 * struct bq27xxx_plaform_data - Platform data for bq27xxx devices 15 * struct bq27xxx_plaform_data - Platform data for bq27xxx devices
6 * @name: Name of the battery. 16 * @name: Name of the battery.
@@ -12,20 +22,47 @@
12 * register to be read. The return value should either be the content of 22 * register to be read. The return value should either be the content of
13 * the passed register or an error value. 23 * the passed register or an error value.
14 */ 24 */
15enum bq27xxx_chip {
16 BQ27000 = 1, /* bq27000, bq27200 */
17 BQ27010, /* bq27010, bq27210 */
18 BQ27500, /* bq27500, bq27510, bq27520 */
19 BQ27530, /* bq27530, bq27531 */
20 BQ27541, /* bq27541, bq27542, bq27546, bq27742 */
21 BQ27545, /* bq27545 */
22 BQ27421, /* bq27421, bq27425, bq27441, bq27621 */
23};
24
25struct bq27xxx_platform_data { 25struct bq27xxx_platform_data {
26 const char *name; 26 const char *name;
27 enum bq27xxx_chip chip; 27 enum bq27xxx_chip chip;
28 int (*read)(struct device *dev, unsigned int); 28 int (*read)(struct device *dev, unsigned int);
29}; 29};
30 30
31struct bq27xxx_device_info;
32struct bq27xxx_access_methods {
33 int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single);
34};
35
36struct bq27xxx_reg_cache {
37 int temperature;
38 int time_to_empty;
39 int time_to_empty_avg;
40 int time_to_full;
41 int charge_full;
42 int cycle_count;
43 int capacity;
44 int energy;
45 int flags;
46 int power_avg;
47 int health;
48};
49
50struct bq27xxx_device_info {
51 struct device *dev;
52 enum bq27xxx_chip chip;
53 const char *name;
54 struct bq27xxx_access_methods bus;
55 struct bq27xxx_reg_cache cache;
56 int charge_design_full;
57 unsigned long last_update;
58 struct delayed_work work;
59 struct power_supply *bat;
60 struct mutex lock;
61 u8 *regs;
62};
63
64void bq27xxx_battery_update(struct bq27xxx_device_info *di);
65int bq27xxx_battery_setup(struct bq27xxx_device_info *di);
66void bq27xxx_battery_teardown(struct bq27xxx_device_info *di);
67
31#endif 68#endif