diff options
Diffstat (limited to 'drivers/power/supply/sbs-charger.c')
| -rw-r--r-- | drivers/power/supply/sbs-charger.c | 71 |
1 files changed, 32 insertions, 39 deletions
diff --git a/drivers/power/supply/sbs-charger.c b/drivers/power/supply/sbs-charger.c index 15947dbb511e..7d5e67620580 100644 --- a/drivers/power/supply/sbs-charger.c +++ b/drivers/power/supply/sbs-charger.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) 2016, Prodys S.L. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * * This adds support for sbs-charger compilant chips as defined here: * http://sbs-forum.org/specs/sbc110.pdf * @@ -20,16 +16,15 @@ #include <linux/i2c.h> #include <linux/slab.h> #include <linux/interrupt.h> -#include <linux/gpio.h> #include <linux/regmap.h> -#include <linux/of_gpio.h> #include <linux/bitops.h> +#include <linux/devm-helpers.h> #define SBS_CHARGER_REG_SPEC_INFO 0x11 #define SBS_CHARGER_REG_STATUS 0x13 #define SBS_CHARGER_REG_ALARM_WARNING 0x16 -#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(1) +#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(0) #define SBS_CHARGER_STATUS_RES_COLD BIT(9) #define SBS_CHARGER_STATUS_RES_HOT BIT(10) #define SBS_CHARGER_STATUS_BATTERY_PRESENT BIT(14) @@ -159,27 +154,36 @@ static const struct regmap_config sbs_regmap = { .val_format_endian = REGMAP_ENDIAN_LITTLE, /* since based on SMBus */ }; -static const struct power_supply_desc sbs_desc = { - .name = "sbs-charger", +static const struct power_supply_desc sbs_default_desc = { .type = POWER_SUPPLY_TYPE_MAINS, .properties = sbs_properties, .num_properties = ARRAY_SIZE(sbs_properties), .get_property = sbs_get_property, }; -static int sbs_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sbs_probe(struct i2c_client *client) { struct power_supply_config psy_cfg = {}; + struct power_supply_desc *sbs_desc; struct sbs_info *chip; int ret, val; + sbs_desc = devm_kmemdup(&client->dev, &sbs_default_desc, + sizeof(*sbs_desc), GFP_KERNEL); + if (!sbs_desc) + return -ENOMEM; + + sbs_desc->name = devm_kasprintf(&client->dev, GFP_KERNEL, "sbs-%s", + dev_name(&client->dev)); + if (!sbs_desc->name) + return -ENOMEM; + chip = devm_kzalloc(&client->dev, sizeof(struct sbs_info), GFP_KERNEL); if (!chip) return -ENOMEM; chip->client = client; - psy_cfg.of_node = client->dev.of_node; + psy_cfg.fwnode = dev_fwnode(&client->dev); psy_cfg.drv_data = chip; i2c_set_clientdata(client, chip); @@ -193,18 +197,14 @@ static int sbs_probe(struct i2c_client *client, * to the battery. */ ret = regmap_read(chip->regmap, SBS_CHARGER_REG_STATUS, &val); - if (ret) { - dev_err(&client->dev, "Failed to get device status\n"); - return ret; - } + if (ret) + return dev_err_probe(&client->dev, ret, "Failed to get device status\n"); chip->last_state = val; - chip->power_supply = devm_power_supply_register(&client->dev, &sbs_desc, - &psy_cfg); - if (IS_ERR(chip->power_supply)) { - dev_err(&client->dev, "Failed to register power supply\n"); - return PTR_ERR(chip->power_supply); - } + chip->power_supply = devm_power_supply_register(&client->dev, sbs_desc, &psy_cfg); + if (IS_ERR(chip->power_supply)) + return dev_err_probe(&client->dev, PTR_ERR(chip->power_supply), + "Failed to register power supply\n"); /* * The sbs-charger spec doesn't impose the use of an interrupt. So in @@ -216,12 +216,15 @@ static int sbs_probe(struct i2c_client *client, NULL, sbs_irq_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(&client->dev), chip); - if (ret) { - dev_err(&client->dev, "Failed to request irq, %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(&client->dev, ret, "Failed to request irq\n"); } else { - INIT_DELAYED_WORK(&chip->work, sbs_delayed_work); + ret = devm_delayed_work_autocancel(&client->dev, &chip->work, + sbs_delayed_work); + if (ret) + return dev_err_probe(&client->dev, ret, + "Failed to init work for polling\n"); + schedule_delayed_work(&chip->work, msecs_to_jiffies(SBS_CHARGER_POLL_TIME)); } @@ -232,15 +235,6 @@ static int sbs_probe(struct i2c_client *client, return 0; } -static int sbs_remove(struct i2c_client *client) -{ - struct sbs_info *chip = i2c_get_clientdata(client); - - cancel_delayed_work_sync(&chip->work); - - return 0; -} - #ifdef CONFIG_OF static const struct of_device_id sbs_dt_ids[] = { { .compatible = "sbs,sbs-charger" }, @@ -250,14 +244,13 @@ MODULE_DEVICE_TABLE(of, sbs_dt_ids); #endif static const struct i2c_device_id sbs_id[] = { - { "sbs-charger", 0 }, + { "sbs-charger" }, { } }; MODULE_DEVICE_TABLE(i2c, sbs_id); static struct i2c_driver sbs_driver = { .probe = sbs_probe, - .remove = sbs_remove, .id_table = sbs_id, .driver = { .name = "sbs-charger", |
