Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Battery charger driver for TI BQ24735
0003  *
0004  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
0005  *
0006  * This program is free software; you can redistribute it and/or modify
0007  * it under the terms of the GNU General Public License as published by
0008  * the Free Software Foundation;
0009  *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT
0011  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0012  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
0013  * more details.
0014  *
0015  * You should have received a copy of the GNU General Public License along
0016  * with this program; if not, write to the Free Software Foundation, Inc.,
0017  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
0018  */
0019 
0020 #include <linux/devm-helpers.h>
0021 #include <linux/err.h>
0022 #include <linux/i2c.h>
0023 #include <linux/init.h>
0024 #include <linux/interrupt.h>
0025 #include <linux/kernel.h>
0026 #include <linux/module.h>
0027 #include <linux/of.h>
0028 #include <linux/gpio/consumer.h>
0029 #include <linux/power_supply.h>
0030 #include <linux/slab.h>
0031 
0032 #include <linux/power/bq24735-charger.h>
0033 
0034 /* BQ24735 available commands and their respective masks */
0035 #define BQ24735_CHARGE_OPT      0x12
0036 #define BQ24735_CHARGE_CURRENT      0x14
0037 #define BQ24735_CHARGE_CURRENT_MASK 0x1fc0
0038 #define BQ24735_CHARGE_VOLTAGE      0x15
0039 #define BQ24735_CHARGE_VOLTAGE_MASK 0x7ff0
0040 #define BQ24735_INPUT_CURRENT       0x3f
0041 #define BQ24735_INPUT_CURRENT_MASK  0x1f80
0042 #define BQ24735_MANUFACTURER_ID     0xfe
0043 #define BQ24735_DEVICE_ID       0xff
0044 
0045 /* ChargeOptions bits of interest */
0046 #define BQ24735_CHARGE_OPT_CHG_DISABLE  (1 << 0)
0047 #define BQ24735_CHARGE_OPT_AC_PRESENT   (1 << 4)
0048 
0049 struct bq24735 {
0050     struct power_supply     *charger;
0051     struct power_supply_desc    charger_desc;
0052     struct i2c_client       *client;
0053     struct bq24735_platform     *pdata;
0054     struct mutex            lock;
0055     struct gpio_desc        *status_gpio;
0056     struct delayed_work     poll;
0057     u32             poll_interval;
0058     bool                charging;
0059 };
0060 
0061 static inline struct bq24735 *to_bq24735(struct power_supply *psy)
0062 {
0063     return power_supply_get_drvdata(psy);
0064 }
0065 
0066 static enum power_supply_property bq24735_charger_properties[] = {
0067     POWER_SUPPLY_PROP_STATUS,
0068     POWER_SUPPLY_PROP_ONLINE,
0069 };
0070 
0071 static int bq24735_charger_property_is_writeable(struct power_supply *psy,
0072                          enum power_supply_property psp)
0073 {
0074     switch (psp) {
0075     case POWER_SUPPLY_PROP_STATUS:
0076         return 1;
0077     default:
0078         break;
0079     }
0080 
0081     return 0;
0082 }
0083 
0084 static inline int bq24735_write_word(struct i2c_client *client, u8 reg,
0085                      u16 value)
0086 {
0087     return i2c_smbus_write_word_data(client, reg, value);
0088 }
0089 
0090 static inline int bq24735_read_word(struct i2c_client *client, u8 reg)
0091 {
0092     return i2c_smbus_read_word_data(client, reg);
0093 }
0094 
0095 static int bq24735_update_word(struct i2c_client *client, u8 reg,
0096                    u16 mask, u16 value)
0097 {
0098     unsigned int tmp;
0099     int ret;
0100 
0101     ret = bq24735_read_word(client, reg);
0102     if (ret < 0)
0103         return ret;
0104 
0105     tmp = ret & ~mask;
0106     tmp |= value & mask;
0107 
0108     return bq24735_write_word(client, reg, tmp);
0109 }
0110 
0111 static int bq24735_config_charger(struct bq24735 *charger)
0112 {
0113     struct bq24735_platform *pdata = charger->pdata;
0114     int ret;
0115     u16 value;
0116 
0117     if (pdata->ext_control)
0118         return 0;
0119 
0120     if (pdata->charge_current) {
0121         value = pdata->charge_current & BQ24735_CHARGE_CURRENT_MASK;
0122 
0123         ret = bq24735_write_word(charger->client,
0124                      BQ24735_CHARGE_CURRENT, value);
0125         if (ret < 0) {
0126             dev_err(&charger->client->dev,
0127                 "Failed to write charger current : %d\n",
0128                 ret);
0129             return ret;
0130         }
0131     }
0132 
0133     if (pdata->charge_voltage) {
0134         value = pdata->charge_voltage & BQ24735_CHARGE_VOLTAGE_MASK;
0135 
0136         ret = bq24735_write_word(charger->client,
0137                      BQ24735_CHARGE_VOLTAGE, value);
0138         if (ret < 0) {
0139             dev_err(&charger->client->dev,
0140                 "Failed to write charger voltage : %d\n",
0141                 ret);
0142             return ret;
0143         }
0144     }
0145 
0146     if (pdata->input_current) {
0147         value = pdata->input_current & BQ24735_INPUT_CURRENT_MASK;
0148 
0149         ret = bq24735_write_word(charger->client,
0150                      BQ24735_INPUT_CURRENT, value);
0151         if (ret < 0) {
0152             dev_err(&charger->client->dev,
0153                 "Failed to write input current : %d\n",
0154                 ret);
0155             return ret;
0156         }
0157     }
0158 
0159     return 0;
0160 }
0161 
0162 static inline int bq24735_enable_charging(struct bq24735 *charger)
0163 {
0164     int ret;
0165 
0166     if (charger->pdata->ext_control)
0167         return 0;
0168 
0169     ret = bq24735_config_charger(charger);
0170     if (ret)
0171         return ret;
0172 
0173     return bq24735_update_word(charger->client, BQ24735_CHARGE_OPT,
0174                    BQ24735_CHARGE_OPT_CHG_DISABLE, 0);
0175 }
0176 
0177 static inline int bq24735_disable_charging(struct bq24735 *charger)
0178 {
0179     if (charger->pdata->ext_control)
0180         return 0;
0181 
0182     return bq24735_update_word(charger->client, BQ24735_CHARGE_OPT,
0183                    BQ24735_CHARGE_OPT_CHG_DISABLE,
0184                    BQ24735_CHARGE_OPT_CHG_DISABLE);
0185 }
0186 
0187 static bool bq24735_charger_is_present(struct bq24735 *charger)
0188 {
0189     if (charger->status_gpio) {
0190         return !gpiod_get_value_cansleep(charger->status_gpio);
0191     } else {
0192         int ac = 0;
0193 
0194         ac = bq24735_read_word(charger->client, BQ24735_CHARGE_OPT);
0195         if (ac < 0) {
0196             dev_dbg(&charger->client->dev,
0197                 "Failed to read charger options : %d\n",
0198                 ac);
0199             return false;
0200         }
0201         return (ac & BQ24735_CHARGE_OPT_AC_PRESENT) ? true : false;
0202     }
0203 
0204     return false;
0205 }
0206 
0207 static int bq24735_charger_is_charging(struct bq24735 *charger)
0208 {
0209     int ret;
0210 
0211     if (!bq24735_charger_is_present(charger))
0212         return 0;
0213 
0214     ret  = bq24735_read_word(charger->client, BQ24735_CHARGE_OPT);
0215     if (ret < 0)
0216         return ret;
0217 
0218     return !(ret & BQ24735_CHARGE_OPT_CHG_DISABLE);
0219 }
0220 
0221 static void bq24735_update(struct bq24735 *charger)
0222 {
0223     mutex_lock(&charger->lock);
0224 
0225     if (charger->charging && bq24735_charger_is_present(charger))
0226         bq24735_enable_charging(charger);
0227     else
0228         bq24735_disable_charging(charger);
0229 
0230     mutex_unlock(&charger->lock);
0231 
0232     power_supply_changed(charger->charger);
0233 }
0234 
0235 static irqreturn_t bq24735_charger_isr(int irq, void *devid)
0236 {
0237     struct power_supply *psy = devid;
0238     struct bq24735 *charger = to_bq24735(psy);
0239 
0240     bq24735_update(charger);
0241 
0242     return IRQ_HANDLED;
0243 }
0244 
0245 static void bq24735_poll(struct work_struct *work)
0246 {
0247     struct bq24735 *charger = container_of(work, struct bq24735, poll.work);
0248 
0249     bq24735_update(charger);
0250 
0251     schedule_delayed_work(&charger->poll,
0252                   msecs_to_jiffies(charger->poll_interval));
0253 }
0254 
0255 static int bq24735_charger_get_property(struct power_supply *psy,
0256                     enum power_supply_property psp,
0257                     union power_supply_propval *val)
0258 {
0259     struct bq24735 *charger = to_bq24735(psy);
0260 
0261     switch (psp) {
0262     case POWER_SUPPLY_PROP_ONLINE:
0263         val->intval = bq24735_charger_is_present(charger) ? 1 : 0;
0264         break;
0265     case POWER_SUPPLY_PROP_STATUS:
0266         switch (bq24735_charger_is_charging(charger)) {
0267         case 1:
0268             val->intval = POWER_SUPPLY_STATUS_CHARGING;
0269             break;
0270         case 0:
0271             val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
0272             break;
0273         default:
0274             val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
0275             break;
0276         }
0277         break;
0278     default:
0279         return -EINVAL;
0280     }
0281 
0282     return 0;
0283 }
0284 
0285 static int bq24735_charger_set_property(struct power_supply *psy,
0286                     enum power_supply_property psp,
0287                     const union power_supply_propval *val)
0288 {
0289     struct bq24735 *charger = to_bq24735(psy);
0290     int ret;
0291 
0292     switch (psp) {
0293     case POWER_SUPPLY_PROP_STATUS:
0294         switch (val->intval) {
0295         case POWER_SUPPLY_STATUS_CHARGING:
0296             mutex_lock(&charger->lock);
0297             charger->charging = true;
0298             ret = bq24735_enable_charging(charger);
0299             mutex_unlock(&charger->lock);
0300             if (ret)
0301                 return ret;
0302             break;
0303         case POWER_SUPPLY_STATUS_DISCHARGING:
0304         case POWER_SUPPLY_STATUS_NOT_CHARGING:
0305             mutex_lock(&charger->lock);
0306             charger->charging = false;
0307             ret = bq24735_disable_charging(charger);
0308             mutex_unlock(&charger->lock);
0309             if (ret)
0310                 return ret;
0311             break;
0312         default:
0313             return -EINVAL;
0314         }
0315         power_supply_changed(psy);
0316         break;
0317     default:
0318         return -EPERM;
0319     }
0320 
0321     return 0;
0322 }
0323 
0324 static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
0325 {
0326     struct bq24735_platform *pdata;
0327     struct device_node *np = client->dev.of_node;
0328     u32 val;
0329     int ret;
0330 
0331     pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
0332     if (!pdata) {
0333         dev_err(&client->dev,
0334             "Memory alloc for bq24735 pdata failed\n");
0335         return NULL;
0336     }
0337 
0338     ret = of_property_read_u32(np, "ti,charge-current", &val);
0339     if (!ret)
0340         pdata->charge_current = val;
0341 
0342     ret = of_property_read_u32(np, "ti,charge-voltage", &val);
0343     if (!ret)
0344         pdata->charge_voltage = val;
0345 
0346     ret = of_property_read_u32(np, "ti,input-current", &val);
0347     if (!ret)
0348         pdata->input_current = val;
0349 
0350     pdata->ext_control = of_property_read_bool(np, "ti,external-control");
0351 
0352     return pdata;
0353 }
0354 
0355 static int bq24735_charger_probe(struct i2c_client *client,
0356                  const struct i2c_device_id *id)
0357 {
0358     int ret;
0359     struct bq24735 *charger;
0360     struct power_supply_desc *supply_desc;
0361     struct power_supply_config psy_cfg = {};
0362     char *name;
0363 
0364     charger = devm_kzalloc(&client->dev, sizeof(*charger), GFP_KERNEL);
0365     if (!charger)
0366         return -ENOMEM;
0367 
0368     mutex_init(&charger->lock);
0369     charger->charging = true;
0370     charger->pdata = client->dev.platform_data;
0371 
0372     if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node)
0373         charger->pdata = bq24735_parse_dt_data(client);
0374 
0375     if (!charger->pdata) {
0376         dev_err(&client->dev, "no platform data provided\n");
0377         return -EINVAL;
0378     }
0379 
0380     name = (char *)charger->pdata->name;
0381     if (!name) {
0382         name = devm_kasprintf(&client->dev, GFP_KERNEL,
0383                       "bq24735@%s",
0384                       dev_name(&client->dev));
0385         if (!name) {
0386             dev_err(&client->dev, "Failed to alloc device name\n");
0387             return -ENOMEM;
0388         }
0389     }
0390 
0391     charger->client = client;
0392 
0393     supply_desc = &charger->charger_desc;
0394 
0395     supply_desc->name = name;
0396     supply_desc->type = POWER_SUPPLY_TYPE_MAINS;
0397     supply_desc->properties = bq24735_charger_properties;
0398     supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties);
0399     supply_desc->get_property = bq24735_charger_get_property;
0400     supply_desc->set_property = bq24735_charger_set_property;
0401     supply_desc->property_is_writeable =
0402                 bq24735_charger_property_is_writeable;
0403 
0404     psy_cfg.supplied_to = charger->pdata->supplied_to;
0405     psy_cfg.num_supplicants = charger->pdata->num_supplicants;
0406     psy_cfg.of_node = client->dev.of_node;
0407     psy_cfg.drv_data = charger;
0408 
0409     i2c_set_clientdata(client, charger);
0410 
0411     charger->status_gpio = devm_gpiod_get_optional(&client->dev,
0412                                "ti,ac-detect",
0413                                GPIOD_IN);
0414     if (IS_ERR(charger->status_gpio)) {
0415         ret = PTR_ERR(charger->status_gpio);
0416         dev_err(&client->dev, "Getting gpio failed: %d\n", ret);
0417         return ret;
0418     }
0419 
0420     if (bq24735_charger_is_present(charger)) {
0421         ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID);
0422         if (ret < 0) {
0423             dev_err(&client->dev, "Failed to read manufacturer id : %d\n",
0424                 ret);
0425             return ret;
0426         } else if (ret != 0x0040) {
0427             dev_err(&client->dev,
0428                 "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret);
0429             return -ENODEV;
0430         }
0431 
0432         ret = bq24735_read_word(client, BQ24735_DEVICE_ID);
0433         if (ret < 0) {
0434             dev_err(&client->dev, "Failed to read device id : %d\n", ret);
0435             return ret;
0436         } else if (ret != 0x000B) {
0437             dev_err(&client->dev,
0438                 "device id mismatch. 0x000b != 0x%04x\n", ret);
0439             return -ENODEV;
0440         }
0441 
0442         ret = bq24735_enable_charging(charger);
0443         if (ret < 0) {
0444             dev_err(&client->dev, "Failed to enable charging\n");
0445             return ret;
0446         }
0447     }
0448 
0449     charger->charger = devm_power_supply_register(&client->dev, supply_desc,
0450                               &psy_cfg);
0451     if (IS_ERR(charger->charger)) {
0452         ret = PTR_ERR(charger->charger);
0453         dev_err(&client->dev, "Failed to register power supply: %d\n",
0454             ret);
0455         return ret;
0456     }
0457 
0458     if (client->irq) {
0459         ret = devm_request_threaded_irq(&client->dev, client->irq,
0460                         NULL, bq24735_charger_isr,
0461                         IRQF_TRIGGER_RISING |
0462                         IRQF_TRIGGER_FALLING |
0463                         IRQF_ONESHOT,
0464                         supply_desc->name,
0465                         charger->charger);
0466         if (ret) {
0467             dev_err(&client->dev,
0468                 "Unable to register IRQ %d err %d\n",
0469                 client->irq, ret);
0470             return ret;
0471         }
0472     } else {
0473         ret = device_property_read_u32(&client->dev, "poll-interval",
0474                            &charger->poll_interval);
0475         if (ret)
0476             return 0;
0477         if (!charger->poll_interval)
0478             return 0;
0479 
0480         ret = devm_delayed_work_autocancel(&client->dev, &charger->poll,
0481                            bq24735_poll);
0482         if (ret)
0483             return ret;
0484 
0485         schedule_delayed_work(&charger->poll,
0486                       msecs_to_jiffies(charger->poll_interval));
0487     }
0488 
0489     return 0;
0490 }
0491 
0492 static const struct i2c_device_id bq24735_charger_id[] = {
0493     { "bq24735-charger", 0 },
0494     {}
0495 };
0496 MODULE_DEVICE_TABLE(i2c, bq24735_charger_id);
0497 
0498 static const struct of_device_id bq24735_match_ids[] = {
0499     { .compatible = "ti,bq24735", },
0500     { /* end */ }
0501 };
0502 MODULE_DEVICE_TABLE(of, bq24735_match_ids);
0503 
0504 static struct i2c_driver bq24735_charger_driver = {
0505     .driver = {
0506         .name = "bq24735-charger",
0507         .of_match_table = bq24735_match_ids,
0508     },
0509     .probe = bq24735_charger_probe,
0510     .id_table = bq24735_charger_id,
0511 };
0512 
0513 module_i2c_driver(bq24735_charger_driver);
0514 
0515 MODULE_DESCRIPTION("bq24735 battery charging driver");
0516 MODULE_AUTHOR("Darbha Sriharsha <dsriharsha@nvidia.com>");
0517 MODULE_LICENSE("GPL v2");