summaryrefslogtreecommitdiff
path: root/drivers/power/bq2415x_charger.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power/bq2415x_charger.c')
-rw-r--r--drivers/power/bq2415x_charger.c147
1 files changed, 69 insertions, 78 deletions
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
index 1f49986fc605..6c534dcbc19c 100644
--- a/drivers/power/bq2415x_charger.c
+++ b/drivers/power/bq2415x_charger.c
@@ -13,12 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/*
* Datasheets:
* http://www.ti.com/product/bq24150
* http://www.ti.com/product/bq24150a
@@ -26,6 +20,8 @@
* http://www.ti.com/product/bq24153
* http://www.ti.com/product/bq24153a
* http://www.ti.com/product/bq24155
+ * http://www.ti.com/product/bq24157s
+ * http://www.ti.com/product/bq24158
*/
#include <linux/kernel.h>
@@ -147,6 +143,7 @@ enum bq2415x_chip {
BQ24155,
BQ24156,
BQ24156A,
+ BQ24157S,
BQ24158,
};
@@ -162,18 +159,20 @@ static char *bq2415x_chip_name[] = {
"bq24155",
"bq24156",
"bq24156a",
+ "bq24157s",
"bq24158",
};
struct bq2415x_device {
struct device *dev;
struct bq2415x_platform_data init_data;
- struct power_supply charger;
+ struct power_supply *charger;
+ struct power_supply_desc charger_desc;
struct delayed_work work;
struct power_supply *notify_psy;
struct notifier_block nb;
enum bq2415x_mode reported_mode;/* mode reported by hook function */
- enum bq2415x_mode mode; /* current configured mode */
+ enum bq2415x_mode mode; /* currently configured mode */
enum bq2415x_chip chip;
const char *timer_error;
char *model;
@@ -352,8 +351,7 @@ static int bq2415x_exec_command(struct bq2415x_device *bq,
BQ2415X_BIT_CE);
if (ret < 0)
return ret;
- else
- return ret > 0 ? 0 : 1;
+ return ret > 0 ? 0 : 1;
case BQ2415X_CHARGER_ENABLE:
return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL,
0, BQ2415X_BIT_CE);
@@ -426,20 +424,17 @@ static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq)
case 0:
if (bq->chip == BQ24151A)
return bq->chip;
- else
- return BQ24151;
+ return BQ24151;
case 1:
if (bq->chip == BQ24150A ||
bq->chip == BQ24152 ||
bq->chip == BQ24155)
return bq->chip;
- else
- return BQ24150;
+ return BQ24150;
case 2:
if (bq->chip == BQ24153A)
return bq->chip;
- else
- return BQ24153;
+ return BQ24153;
default:
return BQUNKNOWN;
}
@@ -450,9 +445,10 @@ static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq)
case 0:
if (bq->chip == BQ24156A)
return bq->chip;
- else
- return BQ24156;
+ return BQ24156;
case 2:
+ if (bq->chip == BQ24157S)
+ return bq->chip;
return BQ24158;
default:
return BQUNKNOWN;
@@ -480,24 +476,22 @@ static int bq2415x_detect_revision(struct bq2415x_device *bq)
case BQ24152:
if (ret >= 0 && ret <= 3)
return ret;
- else
- return -1;
+ return -1;
case BQ24153:
case BQ24153A:
case BQ24156:
case BQ24156A:
+ case BQ24157S:
case BQ24158:
if (ret == 3)
return 0;
else if (ret == 1)
return 1;
- else
- return -1;
+ return -1;
case BQ24155:
if (ret == 3)
return 3;
- else
- return -1;
+ return -1;
case BQUNKNOWN:
return -1;
}
@@ -791,7 +785,7 @@ static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode)
bq2415x_set_default_value(bq, battery_regulation_voltage);
bq->mode = mode;
- sysfs_notify(&bq->charger.dev->kobj, NULL, "mode");
+ sysfs_notify(&bq->charger->dev.kobj, NULL, "mode");
return 0;
@@ -816,7 +810,8 @@ static int bq2415x_notifier_call(struct notifier_block *nb,
dev_dbg(bq->dev, "notifier call was called\n");
- ret = psy->get_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX, &prop);
+ ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX,
+ &prop);
if (ret != 0)
return NOTIFY_OK;
@@ -874,7 +869,7 @@ static void bq2415x_set_autotimer(struct bq2415x_device *bq, int state)
static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg)
{
bq->timer_error = msg;
- sysfs_notify(&bq->charger.dev->kobj, NULL, "timer");
+ sysfs_notify(&bq->charger->dev.kobj, NULL, "timer");
dev_err(bq->dev, "%s\n", msg);
if (bq->automode > 0)
bq->automode = 0;
@@ -892,7 +887,7 @@ static void bq2415x_timer_work(struct work_struct *work)
int boost;
if (bq->automode > 0 && (bq->reported_mode != bq->mode)) {
- sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode");
+ sysfs_notify(&bq->charger->dev.kobj, NULL, "reported_mode");
bq2415x_set_mode(bq, bq->reported_mode);
}
@@ -998,8 +993,7 @@ static int bq2415x_power_supply_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
int ret;
switch (psp) {
@@ -1030,12 +1024,14 @@ static int bq2415x_power_supply_init(struct bq2415x_device *bq)
int ret;
int chip;
char revstr[8];
+ struct power_supply_config psy_cfg = { .drv_data = bq, };
- bq->charger.name = bq->name;
- bq->charger.type = POWER_SUPPLY_TYPE_USB;
- bq->charger.properties = bq2415x_power_supply_props;
- bq->charger.num_properties = ARRAY_SIZE(bq2415x_power_supply_props);
- bq->charger.get_property = bq2415x_power_supply_get_property;
+ bq->charger_desc.name = bq->name;
+ bq->charger_desc.type = POWER_SUPPLY_TYPE_USB;
+ bq->charger_desc.properties = bq2415x_power_supply_props;
+ bq->charger_desc.num_properties =
+ ARRAY_SIZE(bq2415x_power_supply_props);
+ bq->charger_desc.get_property = bq2415x_power_supply_get_property;
ret = bq2415x_detect_chip(bq);
if (ret < 0)
@@ -1058,10 +1054,11 @@ static int bq2415x_power_supply_init(struct bq2415x_device *bq)
return -ENOMEM;
}
- ret = power_supply_register(bq->dev, &bq->charger);
- if (ret) {
+ bq->charger = power_supply_register(bq->dev, &bq->charger_desc,
+ &psy_cfg);
+ if (IS_ERR(bq->charger)) {
kfree(bq->model);
- return ret;
+ return PTR_ERR(bq->charger);
}
return 0;
@@ -1073,7 +1070,7 @@ static void bq2415x_power_supply_exit(struct bq2415x_device *bq)
if (bq->automode > 0)
bq->automode = 0;
cancel_delayed_work_sync(&bq->work);
- power_supply_unregister(&bq->charger);
+ power_supply_unregister(bq->charger);
kfree(bq->model);
}
@@ -1085,8 +1082,7 @@ static ssize_t bq2415x_sysfs_show_status(struct device *dev,
char *buf)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
enum bq2415x_command command;
int ret;
@@ -1119,8 +1115,7 @@ static ssize_t bq2415x_sysfs_set_timer(struct device *dev,
size_t count)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
int ret = 0;
if (strncmp(buf, "auto", 4) == 0)
@@ -1141,8 +1136,7 @@ static ssize_t bq2415x_sysfs_show_timer(struct device *dev,
char *buf)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
if (bq->timer_error)
return sprintf(buf, "%s\n", bq->timer_error);
@@ -1166,8 +1160,7 @@ static ssize_t bq2415x_sysfs_set_mode(struct device *dev,
size_t count)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
enum bq2415x_mode mode;
int ret = 0;
@@ -1219,8 +1212,7 @@ static ssize_t bq2415x_sysfs_show_mode(struct device *dev,
char *buf)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
ssize_t ret = 0;
if (bq->automode > 0)
@@ -1257,8 +1249,7 @@ static ssize_t bq2415x_sysfs_show_reported_mode(struct device *dev,
char *buf)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
if (bq->automode < 0)
return -EINVAL;
@@ -1286,8 +1277,7 @@ static ssize_t bq2415x_sysfs_set_registers(struct device *dev,
size_t count)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
ssize_t ret = 0;
unsigned int reg;
unsigned int val;
@@ -1322,8 +1312,7 @@ static ssize_t bq2415x_sysfs_show_registers(struct device *dev,
char *buf)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
ssize_t ret = 0;
ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_STATUS, buf+ret);
@@ -1341,8 +1330,7 @@ static ssize_t bq2415x_sysfs_set_limit(struct device *dev,
size_t count)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
long val;
int ret;
@@ -1373,8 +1361,7 @@ static ssize_t bq2415x_sysfs_show_limit(struct device *dev,
char *buf)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
int ret;
if (strcmp(attr->attr.name, "current_limit") == 0)
@@ -1402,8 +1389,7 @@ static ssize_t bq2415x_sysfs_set_enable(struct device *dev,
size_t count)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
enum bq2415x_command command;
long val;
int ret;
@@ -1438,8 +1424,7 @@ static ssize_t bq2415x_sysfs_show_enable(struct device *dev,
char *buf)
{
struct power_supply *psy = dev_get_drvdata(dev);
- struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
- charger);
+ struct bq2415x_device *bq = power_supply_get_drvdata(psy);
enum bq2415x_command command;
int ret;
@@ -1530,13 +1515,13 @@ static const struct attribute_group bq2415x_sysfs_attr_group = {
static int bq2415x_sysfs_init(struct bq2415x_device *bq)
{
- return sysfs_create_group(&bq->charger.dev->kobj,
+ return sysfs_create_group(&bq->charger->dev.kobj,
&bq2415x_sysfs_attr_group);
}
static void bq2415x_sysfs_exit(struct bq2415x_device *bq)
{
- sysfs_remove_group(&bq->charger.dev->kobj, &bq2415x_sysfs_attr_group);
+ sysfs_remove_group(&bq->charger->dev.kobj, &bq2415x_sysfs_attr_group);
}
/* main bq2415x probe function */
@@ -1609,27 +1594,27 @@ static int bq2415x_probe(struct i2c_client *client,
ret = of_property_read_u32(np, "ti,current-limit",
&bq->init_data.current_limit);
if (ret)
- goto error_2;
+ goto error_3;
ret = of_property_read_u32(np, "ti,weak-battery-voltage",
&bq->init_data.weak_battery_voltage);
if (ret)
- goto error_2;
+ goto error_3;
ret = of_property_read_u32(np, "ti,battery-regulation-voltage",
&bq->init_data.battery_regulation_voltage);
if (ret)
- goto error_2;
+ goto error_3;
ret = of_property_read_u32(np, "ti,charge-current",
&bq->init_data.charge_current);
if (ret)
- goto error_2;
+ goto error_3;
ret = of_property_read_u32(np, "ti,termination-current",
&bq->init_data.termination_current);
if (ret)
- goto error_2;
+ goto error_3;
ret = of_property_read_u32(np, "ti,resistor-sense",
&bq->init_data.resistor_sense);
if (ret)
- goto error_2;
+ goto error_3;
} else {
memcpy(&bq->init_data, pdata, sizeof(bq->init_data));
}
@@ -1639,19 +1624,19 @@ static int bq2415x_probe(struct i2c_client *client,
ret = bq2415x_power_supply_init(bq);
if (ret) {
dev_err(bq->dev, "failed to register power supply: %d\n", ret);
- goto error_2;
+ goto error_3;
}
ret = bq2415x_sysfs_init(bq);
if (ret) {
dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret);
- goto error_3;
+ goto error_4;
}
ret = bq2415x_set_defaults(bq);
if (ret) {
dev_err(bq->dev, "failed to set default values: %d\n", ret);
- goto error_4;
+ goto error_5;
}
if (bq->notify_psy) {
@@ -1659,7 +1644,7 @@ static int bq2415x_probe(struct i2c_client *client,
ret = power_supply_reg_notifier(&bq->nb);
if (ret) {
dev_err(bq->dev, "failed to reg notifier: %d\n", ret);
- goto error_5;
+ goto error_6;
}
/* Query for initial reported_mode and set it */
@@ -1679,11 +1664,14 @@ static int bq2415x_probe(struct i2c_client *client,
dev_info(bq->dev, "driver registered\n");
return 0;
+error_6:
error_5:
-error_4:
bq2415x_sysfs_exit(bq);
-error_3:
+error_4:
bq2415x_power_supply_exit(bq);
+error_3:
+ if (bq->notify_psy)
+ power_supply_put(bq->notify_psy);
error_2:
kfree(name);
error_1:
@@ -1700,8 +1688,10 @@ static int bq2415x_remove(struct i2c_client *client)
{
struct bq2415x_device *bq = i2c_get_clientdata(client);
- if (bq->notify_psy)
+ if (bq->notify_psy) {
power_supply_unreg_notifier(&bq->nb);
+ power_supply_put(bq->notify_psy);
+ }
bq2415x_sysfs_exit(bq);
bq2415x_power_supply_exit(bq);
@@ -1731,6 +1721,7 @@ static const struct i2c_device_id bq2415x_i2c_id_table[] = {
{ "bq24155", BQ24155 },
{ "bq24156", BQ24156 },
{ "bq24156a", BQ24156A },
+ { "bq24157s", BQ24157S },
{ "bq24158", BQ24158 },
{},
};