bq24735-charger.c (12698B)
1/* 2 * Battery charger driver for TI BQ24735 3 * 4 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; 9 * 10 * This program is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 */ 19 20#include <linux/devm-helpers.h> 21#include <linux/err.h> 22#include <linux/i2c.h> 23#include <linux/init.h> 24#include <linux/interrupt.h> 25#include <linux/kernel.h> 26#include <linux/module.h> 27#include <linux/of.h> 28#include <linux/gpio/consumer.h> 29#include <linux/power_supply.h> 30#include <linux/slab.h> 31 32#include <linux/power/bq24735-charger.h> 33 34/* BQ24735 available commands and their respective masks */ 35#define BQ24735_CHARGE_OPT 0x12 36#define BQ24735_CHARGE_CURRENT 0x14 37#define BQ24735_CHARGE_CURRENT_MASK 0x1fc0 38#define BQ24735_CHARGE_VOLTAGE 0x15 39#define BQ24735_CHARGE_VOLTAGE_MASK 0x7ff0 40#define BQ24735_INPUT_CURRENT 0x3f 41#define BQ24735_INPUT_CURRENT_MASK 0x1f80 42#define BQ24735_MANUFACTURER_ID 0xfe 43#define BQ24735_DEVICE_ID 0xff 44 45/* ChargeOptions bits of interest */ 46#define BQ24735_CHARGE_OPT_CHG_DISABLE (1 << 0) 47#define BQ24735_CHARGE_OPT_AC_PRESENT (1 << 4) 48 49struct bq24735 { 50 struct power_supply *charger; 51 struct power_supply_desc charger_desc; 52 struct i2c_client *client; 53 struct bq24735_platform *pdata; 54 struct mutex lock; 55 struct gpio_desc *status_gpio; 56 struct delayed_work poll; 57 u32 poll_interval; 58 bool charging; 59}; 60 61static inline struct bq24735 *to_bq24735(struct power_supply *psy) 62{ 63 return power_supply_get_drvdata(psy); 64} 65 66static enum power_supply_property bq24735_charger_properties[] = { 67 POWER_SUPPLY_PROP_STATUS, 68 POWER_SUPPLY_PROP_ONLINE, 69}; 70 71static int bq24735_charger_property_is_writeable(struct power_supply *psy, 72 enum power_supply_property psp) 73{ 74 switch (psp) { 75 case POWER_SUPPLY_PROP_STATUS: 76 return 1; 77 default: 78 break; 79 } 80 81 return 0; 82} 83 84static inline int bq24735_write_word(struct i2c_client *client, u8 reg, 85 u16 value) 86{ 87 return i2c_smbus_write_word_data(client, reg, value); 88} 89 90static inline int bq24735_read_word(struct i2c_client *client, u8 reg) 91{ 92 return i2c_smbus_read_word_data(client, reg); 93} 94 95static int bq24735_update_word(struct i2c_client *client, u8 reg, 96 u16 mask, u16 value) 97{ 98 unsigned int tmp; 99 int ret; 100 101 ret = bq24735_read_word(client, reg); 102 if (ret < 0) 103 return ret; 104 105 tmp = ret & ~mask; 106 tmp |= value & mask; 107 108 return bq24735_write_word(client, reg, tmp); 109} 110 111static int bq24735_config_charger(struct bq24735 *charger) 112{ 113 struct bq24735_platform *pdata = charger->pdata; 114 int ret; 115 u16 value; 116 117 if (pdata->ext_control) 118 return 0; 119 120 if (pdata->charge_current) { 121 value = pdata->charge_current & BQ24735_CHARGE_CURRENT_MASK; 122 123 ret = bq24735_write_word(charger->client, 124 BQ24735_CHARGE_CURRENT, value); 125 if (ret < 0) { 126 dev_err(&charger->client->dev, 127 "Failed to write charger current : %d\n", 128 ret); 129 return ret; 130 } 131 } 132 133 if (pdata->charge_voltage) { 134 value = pdata->charge_voltage & BQ24735_CHARGE_VOLTAGE_MASK; 135 136 ret = bq24735_write_word(charger->client, 137 BQ24735_CHARGE_VOLTAGE, value); 138 if (ret < 0) { 139 dev_err(&charger->client->dev, 140 "Failed to write charger voltage : %d\n", 141 ret); 142 return ret; 143 } 144 } 145 146 if (pdata->input_current) { 147 value = pdata->input_current & BQ24735_INPUT_CURRENT_MASK; 148 149 ret = bq24735_write_word(charger->client, 150 BQ24735_INPUT_CURRENT, value); 151 if (ret < 0) { 152 dev_err(&charger->client->dev, 153 "Failed to write input current : %d\n", 154 ret); 155 return ret; 156 } 157 } 158 159 return 0; 160} 161 162static inline int bq24735_enable_charging(struct bq24735 *charger) 163{ 164 int ret; 165 166 if (charger->pdata->ext_control) 167 return 0; 168 169 ret = bq24735_config_charger(charger); 170 if (ret) 171 return ret; 172 173 return bq24735_update_word(charger->client, BQ24735_CHARGE_OPT, 174 BQ24735_CHARGE_OPT_CHG_DISABLE, 0); 175} 176 177static inline int bq24735_disable_charging(struct bq24735 *charger) 178{ 179 if (charger->pdata->ext_control) 180 return 0; 181 182 return bq24735_update_word(charger->client, BQ24735_CHARGE_OPT, 183 BQ24735_CHARGE_OPT_CHG_DISABLE, 184 BQ24735_CHARGE_OPT_CHG_DISABLE); 185} 186 187static bool bq24735_charger_is_present(struct bq24735 *charger) 188{ 189 if (charger->status_gpio) { 190 return !gpiod_get_value_cansleep(charger->status_gpio); 191 } else { 192 int ac = 0; 193 194 ac = bq24735_read_word(charger->client, BQ24735_CHARGE_OPT); 195 if (ac < 0) { 196 dev_dbg(&charger->client->dev, 197 "Failed to read charger options : %d\n", 198 ac); 199 return false; 200 } 201 return (ac & BQ24735_CHARGE_OPT_AC_PRESENT) ? true : false; 202 } 203 204 return false; 205} 206 207static int bq24735_charger_is_charging(struct bq24735 *charger) 208{ 209 int ret; 210 211 if (!bq24735_charger_is_present(charger)) 212 return 0; 213 214 ret = bq24735_read_word(charger->client, BQ24735_CHARGE_OPT); 215 if (ret < 0) 216 return ret; 217 218 return !(ret & BQ24735_CHARGE_OPT_CHG_DISABLE); 219} 220 221static void bq24735_update(struct bq24735 *charger) 222{ 223 mutex_lock(&charger->lock); 224 225 if (charger->charging && bq24735_charger_is_present(charger)) 226 bq24735_enable_charging(charger); 227 else 228 bq24735_disable_charging(charger); 229 230 mutex_unlock(&charger->lock); 231 232 power_supply_changed(charger->charger); 233} 234 235static irqreturn_t bq24735_charger_isr(int irq, void *devid) 236{ 237 struct power_supply *psy = devid; 238 struct bq24735 *charger = to_bq24735(psy); 239 240 bq24735_update(charger); 241 242 return IRQ_HANDLED; 243} 244 245static void bq24735_poll(struct work_struct *work) 246{ 247 struct bq24735 *charger = container_of(work, struct bq24735, poll.work); 248 249 bq24735_update(charger); 250 251 schedule_delayed_work(&charger->poll, 252 msecs_to_jiffies(charger->poll_interval)); 253} 254 255static int bq24735_charger_get_property(struct power_supply *psy, 256 enum power_supply_property psp, 257 union power_supply_propval *val) 258{ 259 struct bq24735 *charger = to_bq24735(psy); 260 261 switch (psp) { 262 case POWER_SUPPLY_PROP_ONLINE: 263 val->intval = bq24735_charger_is_present(charger) ? 1 : 0; 264 break; 265 case POWER_SUPPLY_PROP_STATUS: 266 switch (bq24735_charger_is_charging(charger)) { 267 case 1: 268 val->intval = POWER_SUPPLY_STATUS_CHARGING; 269 break; 270 case 0: 271 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 272 break; 273 default: 274 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 275 break; 276 } 277 break; 278 default: 279 return -EINVAL; 280 } 281 282 return 0; 283} 284 285static int bq24735_charger_set_property(struct power_supply *psy, 286 enum power_supply_property psp, 287 const union power_supply_propval *val) 288{ 289 struct bq24735 *charger = to_bq24735(psy); 290 int ret; 291 292 switch (psp) { 293 case POWER_SUPPLY_PROP_STATUS: 294 switch (val->intval) { 295 case POWER_SUPPLY_STATUS_CHARGING: 296 mutex_lock(&charger->lock); 297 charger->charging = true; 298 ret = bq24735_enable_charging(charger); 299 mutex_unlock(&charger->lock); 300 if (ret) 301 return ret; 302 break; 303 case POWER_SUPPLY_STATUS_DISCHARGING: 304 case POWER_SUPPLY_STATUS_NOT_CHARGING: 305 mutex_lock(&charger->lock); 306 charger->charging = false; 307 ret = bq24735_disable_charging(charger); 308 mutex_unlock(&charger->lock); 309 if (ret) 310 return ret; 311 break; 312 default: 313 return -EINVAL; 314 } 315 power_supply_changed(psy); 316 break; 317 default: 318 return -EPERM; 319 } 320 321 return 0; 322} 323 324static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client) 325{ 326 struct bq24735_platform *pdata; 327 struct device_node *np = client->dev.of_node; 328 u32 val; 329 int ret; 330 331 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); 332 if (!pdata) { 333 dev_err(&client->dev, 334 "Memory alloc for bq24735 pdata failed\n"); 335 return NULL; 336 } 337 338 ret = of_property_read_u32(np, "ti,charge-current", &val); 339 if (!ret) 340 pdata->charge_current = val; 341 342 ret = of_property_read_u32(np, "ti,charge-voltage", &val); 343 if (!ret) 344 pdata->charge_voltage = val; 345 346 ret = of_property_read_u32(np, "ti,input-current", &val); 347 if (!ret) 348 pdata->input_current = val; 349 350 pdata->ext_control = of_property_read_bool(np, "ti,external-control"); 351 352 return pdata; 353} 354 355static int bq24735_charger_probe(struct i2c_client *client, 356 const struct i2c_device_id *id) 357{ 358 int ret; 359 struct bq24735 *charger; 360 struct power_supply_desc *supply_desc; 361 struct power_supply_config psy_cfg = {}; 362 char *name; 363 364 charger = devm_kzalloc(&client->dev, sizeof(*charger), GFP_KERNEL); 365 if (!charger) 366 return -ENOMEM; 367 368 mutex_init(&charger->lock); 369 charger->charging = true; 370 charger->pdata = client->dev.platform_data; 371 372 if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node) 373 charger->pdata = bq24735_parse_dt_data(client); 374 375 if (!charger->pdata) { 376 dev_err(&client->dev, "no platform data provided\n"); 377 return -EINVAL; 378 } 379 380 name = (char *)charger->pdata->name; 381 if (!name) { 382 name = devm_kasprintf(&client->dev, GFP_KERNEL, 383 "bq24735@%s", 384 dev_name(&client->dev)); 385 if (!name) { 386 dev_err(&client->dev, "Failed to alloc device name\n"); 387 return -ENOMEM; 388 } 389 } 390 391 charger->client = client; 392 393 supply_desc = &charger->charger_desc; 394 395 supply_desc->name = name; 396 supply_desc->type = POWER_SUPPLY_TYPE_MAINS; 397 supply_desc->properties = bq24735_charger_properties; 398 supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties); 399 supply_desc->get_property = bq24735_charger_get_property; 400 supply_desc->set_property = bq24735_charger_set_property; 401 supply_desc->property_is_writeable = 402 bq24735_charger_property_is_writeable; 403 404 psy_cfg.supplied_to = charger->pdata->supplied_to; 405 psy_cfg.num_supplicants = charger->pdata->num_supplicants; 406 psy_cfg.of_node = client->dev.of_node; 407 psy_cfg.drv_data = charger; 408 409 i2c_set_clientdata(client, charger); 410 411 charger->status_gpio = devm_gpiod_get_optional(&client->dev, 412 "ti,ac-detect", 413 GPIOD_IN); 414 if (IS_ERR(charger->status_gpio)) { 415 ret = PTR_ERR(charger->status_gpio); 416 dev_err(&client->dev, "Getting gpio failed: %d\n", ret); 417 return ret; 418 } 419 420 if (bq24735_charger_is_present(charger)) { 421 ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID); 422 if (ret < 0) { 423 dev_err(&client->dev, "Failed to read manufacturer id : %d\n", 424 ret); 425 return ret; 426 } else if (ret != 0x0040) { 427 dev_err(&client->dev, 428 "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret); 429 return -ENODEV; 430 } 431 432 ret = bq24735_read_word(client, BQ24735_DEVICE_ID); 433 if (ret < 0) { 434 dev_err(&client->dev, "Failed to read device id : %d\n", ret); 435 return ret; 436 } else if (ret != 0x000B) { 437 dev_err(&client->dev, 438 "device id mismatch. 0x000b != 0x%04x\n", ret); 439 return -ENODEV; 440 } 441 442 ret = bq24735_enable_charging(charger); 443 if (ret < 0) { 444 dev_err(&client->dev, "Failed to enable charging\n"); 445 return ret; 446 } 447 } 448 449 charger->charger = devm_power_supply_register(&client->dev, supply_desc, 450 &psy_cfg); 451 if (IS_ERR(charger->charger)) { 452 ret = PTR_ERR(charger->charger); 453 dev_err(&client->dev, "Failed to register power supply: %d\n", 454 ret); 455 return ret; 456 } 457 458 if (client->irq) { 459 ret = devm_request_threaded_irq(&client->dev, client->irq, 460 NULL, bq24735_charger_isr, 461 IRQF_TRIGGER_RISING | 462 IRQF_TRIGGER_FALLING | 463 IRQF_ONESHOT, 464 supply_desc->name, 465 charger->charger); 466 if (ret) { 467 dev_err(&client->dev, 468 "Unable to register IRQ %d err %d\n", 469 client->irq, ret); 470 return ret; 471 } 472 } else { 473 ret = device_property_read_u32(&client->dev, "poll-interval", 474 &charger->poll_interval); 475 if (ret) 476 return 0; 477 if (!charger->poll_interval) 478 return 0; 479 480 ret = devm_delayed_work_autocancel(&client->dev, &charger->poll, 481 bq24735_poll); 482 if (ret) 483 return ret; 484 485 schedule_delayed_work(&charger->poll, 486 msecs_to_jiffies(charger->poll_interval)); 487 } 488 489 return 0; 490} 491 492static const struct i2c_device_id bq24735_charger_id[] = { 493 { "bq24735-charger", 0 }, 494 {} 495}; 496MODULE_DEVICE_TABLE(i2c, bq24735_charger_id); 497 498static const struct of_device_id bq24735_match_ids[] = { 499 { .compatible = "ti,bq24735", }, 500 { /* end */ } 501}; 502MODULE_DEVICE_TABLE(of, bq24735_match_ids); 503 504static struct i2c_driver bq24735_charger_driver = { 505 .driver = { 506 .name = "bq24735-charger", 507 .of_match_table = bq24735_match_ids, 508 }, 509 .probe = bq24735_charger_probe, 510 .id_table = bq24735_charger_id, 511}; 512 513module_i2c_driver(bq24735_charger_driver); 514 515MODULE_DESCRIPTION("bq24735 battery charging driver"); 516MODULE_AUTHOR("Darbha Sriharsha <dsriharsha@nvidia.com>"); 517MODULE_LICENSE("GPL v2");