1 /* 2 * axp288_charger.c - X-power AXP288 PMIC Charger driver 3 * 4 * Copyright (C) 2014 Intel Corporation 5 * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.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 in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include <linux/module.h> 18 #include <linux/device.h> 19 #include <linux/regmap.h> 20 #include <linux/workqueue.h> 21 #include <linux/delay.h> 22 #include <linux/platform_device.h> 23 #include <linux/usb/otg.h> 24 #include <linux/notifier.h> 25 #include <linux/power_supply.h> 26 #include <linux/property.h> 27 #include <linux/mfd/axp20x.h> 28 #include <linux/extcon.h> 29 30 #define PS_STAT_VBUS_TRIGGER (1 << 0) 31 #define PS_STAT_BAT_CHRG_DIR (1 << 2) 32 #define PS_STAT_VBAT_ABOVE_VHOLD (1 << 3) 33 #define PS_STAT_VBUS_VALID (1 << 4) 34 #define PS_STAT_VBUS_PRESENT (1 << 5) 35 36 #define CHRG_STAT_BAT_SAFE_MODE (1 << 3) 37 #define CHRG_STAT_BAT_VALID (1 << 4) 38 #define CHRG_STAT_BAT_PRESENT (1 << 5) 39 #define CHRG_STAT_CHARGING (1 << 6) 40 #define CHRG_STAT_PMIC_OTP (1 << 7) 41 42 #define VBUS_ISPOUT_CUR_LIM_MASK 0x03 43 #define VBUS_ISPOUT_CUR_LIM_BIT_POS 0 44 #define VBUS_ISPOUT_CUR_LIM_900MA 0x0 /* 900mA */ 45 #define VBUS_ISPOUT_CUR_LIM_1500MA 0x1 /* 1500mA */ 46 #define VBUS_ISPOUT_CUR_LIM_2000MA 0x2 /* 2000mA */ 47 #define VBUS_ISPOUT_CUR_NO_LIM 0x3 /* 2500mA */ 48 #define VBUS_ISPOUT_VHOLD_SET_MASK 0x31 49 #define VBUS_ISPOUT_VHOLD_SET_BIT_POS 0x3 50 #define VBUS_ISPOUT_VHOLD_SET_OFFSET 4000 /* 4000mV */ 51 #define VBUS_ISPOUT_VHOLD_SET_LSB_RES 100 /* 100mV */ 52 #define VBUS_ISPOUT_VHOLD_SET_4300MV 0x3 /* 4300mV */ 53 #define VBUS_ISPOUT_VBUS_PATH_DIS (1 << 7) 54 55 #define CHRG_CCCV_CC_MASK 0xf /* 4 bits */ 56 #define CHRG_CCCV_CC_BIT_POS 0 57 #define CHRG_CCCV_CC_OFFSET 200 /* 200mA */ 58 #define CHRG_CCCV_CC_LSB_RES 200 /* 200mA */ 59 #define CHRG_CCCV_ITERM_20P (1 << 4) /* 20% of CC */ 60 #define CHRG_CCCV_CV_MASK 0x60 /* 2 bits */ 61 #define CHRG_CCCV_CV_BIT_POS 5 62 #define CHRG_CCCV_CV_4100MV 0x0 /* 4.10V */ 63 #define CHRG_CCCV_CV_4150MV 0x1 /* 4.15V */ 64 #define CHRG_CCCV_CV_4200MV 0x2 /* 4.20V */ 65 #define CHRG_CCCV_CV_4350MV 0x3 /* 4.35V */ 66 #define CHRG_CCCV_CHG_EN (1 << 7) 67 68 #define CNTL2_CC_TIMEOUT_MASK 0x3 /* 2 bits */ 69 #define CNTL2_CC_TIMEOUT_OFFSET 6 /* 6 Hrs */ 70 #define CNTL2_CC_TIMEOUT_LSB_RES 2 /* 2 Hrs */ 71 #define CNTL2_CC_TIMEOUT_12HRS 0x3 /* 12 Hrs */ 72 #define CNTL2_CHGLED_TYPEB (1 << 4) 73 #define CNTL2_CHG_OUT_TURNON (1 << 5) 74 #define CNTL2_PC_TIMEOUT_MASK 0xC0 75 #define CNTL2_PC_TIMEOUT_OFFSET 40 /* 40 mins */ 76 #define CNTL2_PC_TIMEOUT_LSB_RES 10 /* 10 mins */ 77 #define CNTL2_PC_TIMEOUT_70MINS 0x3 78 79 #define CHRG_ILIM_TEMP_LOOP_EN (1 << 3) 80 #define CHRG_VBUS_ILIM_MASK 0xf0 81 #define CHRG_VBUS_ILIM_BIT_POS 4 82 #define CHRG_VBUS_ILIM_100MA 0x0 /* 100mA */ 83 #define CHRG_VBUS_ILIM_500MA 0x1 /* 500mA */ 84 #define CHRG_VBUS_ILIM_900MA 0x2 /* 900mA */ 85 #define CHRG_VBUS_ILIM_1500MA 0x3 /* 1500mA */ 86 #define CHRG_VBUS_ILIM_2000MA 0x4 /* 2000mA */ 87 #define CHRG_VBUS_ILIM_2500MA 0x5 /* 2500mA */ 88 #define CHRG_VBUS_ILIM_3000MA 0x6 /* 3000mA */ 89 90 #define CHRG_VLTFC_0C 0xA5 /* 0 DegC */ 91 #define CHRG_VHTFC_45C 0x1F /* 45 DegC */ 92 93 #define BAT_IRQ_CFG_CHRG_DONE (1 << 2) 94 #define BAT_IRQ_CFG_CHRG_START (1 << 3) 95 #define BAT_IRQ_CFG_BAT_SAFE_EXIT (1 << 4) 96 #define BAT_IRQ_CFG_BAT_SAFE_ENTER (1 << 5) 97 #define BAT_IRQ_CFG_BAT_DISCON (1 << 6) 98 #define BAT_IRQ_CFG_BAT_CONN (1 << 7) 99 #define BAT_IRQ_CFG_BAT_MASK 0xFC 100 101 #define TEMP_IRQ_CFG_QCBTU (1 << 4) 102 #define TEMP_IRQ_CFG_CBTU (1 << 5) 103 #define TEMP_IRQ_CFG_QCBTO (1 << 6) 104 #define TEMP_IRQ_CFG_CBTO (1 << 7) 105 #define TEMP_IRQ_CFG_MASK 0xF0 106 107 #define FG_CNTL_OCV_ADJ_EN (1 << 3) 108 109 #define CV_4100MV 4100 /* 4100mV */ 110 #define CV_4150MV 4150 /* 4150mV */ 111 #define CV_4200MV 4200 /* 4200mV */ 112 #define CV_4350MV 4350 /* 4350mV */ 113 114 #define CC_200MA 200 /* 200mA */ 115 #define CC_600MA 600 /* 600mA */ 116 #define CC_800MA 800 /* 800mA */ 117 #define CC_1000MA 1000 /* 1000mA */ 118 #define CC_1600MA 1600 /* 1600mA */ 119 #define CC_2000MA 2000 /* 2000mA */ 120 121 #define ILIM_100MA 100 /* 100mA */ 122 #define ILIM_500MA 500 /* 500mA */ 123 #define ILIM_900MA 900 /* 900mA */ 124 #define ILIM_1500MA 1500 /* 1500mA */ 125 #define ILIM_2000MA 2000 /* 2000mA */ 126 #define ILIM_2500MA 2500 /* 2500mA */ 127 #define ILIM_3000MA 3000 /* 3000mA */ 128 129 #define AXP288_EXTCON_DEV_NAME "axp288_extcon" 130 131 enum { 132 VBUS_OV_IRQ = 0, 133 CHARGE_DONE_IRQ, 134 CHARGE_CHARGING_IRQ, 135 BAT_SAFE_QUIT_IRQ, 136 BAT_SAFE_ENTER_IRQ, 137 QCBTU_IRQ, 138 CBTU_IRQ, 139 QCBTO_IRQ, 140 CBTO_IRQ, 141 CHRG_INTR_END, 142 }; 143 144 struct axp288_chrg_info { 145 struct platform_device *pdev; 146 struct axp20x_chrg_pdata *pdata; 147 struct regmap *regmap; 148 struct regmap_irq_chip_data *regmap_irqc; 149 int irq[CHRG_INTR_END]; 150 struct power_supply *psy_usb; 151 struct mutex lock; 152 153 /* OTG/Host mode */ 154 struct { 155 struct work_struct work; 156 struct extcon_dev *cable; 157 struct notifier_block id_nb; 158 bool id_short; 159 } otg; 160 161 /* SDP/CDP/DCP USB charging cable notifications */ 162 struct { 163 struct extcon_dev *edev; 164 bool connected; 165 enum power_supply_type chg_type; 166 struct notifier_block nb; 167 struct work_struct work; 168 } cable; 169 170 int health; 171 int inlmt; 172 int cc; 173 int cv; 174 int max_cc; 175 int max_cv; 176 bool online; 177 bool present; 178 bool enable_charger; 179 bool is_charger_enabled; 180 }; 181 182 static inline int axp288_charger_set_cc(struct axp288_chrg_info *info, int cc) 183 { 184 u8 reg_val; 185 int ret; 186 187 if (cc < CHRG_CCCV_CC_OFFSET) 188 cc = CHRG_CCCV_CC_OFFSET; 189 else if (cc > info->max_cc) 190 cc = info->max_cc; 191 192 reg_val = (cc - CHRG_CCCV_CC_OFFSET) / CHRG_CCCV_CC_LSB_RES; 193 cc = (reg_val * CHRG_CCCV_CC_LSB_RES) + CHRG_CCCV_CC_OFFSET; 194 reg_val = reg_val << CHRG_CCCV_CC_BIT_POS; 195 196 ret = regmap_update_bits(info->regmap, 197 AXP20X_CHRG_CTRL1, 198 CHRG_CCCV_CC_MASK, reg_val); 199 if (ret >= 0) 200 info->cc = cc; 201 202 return ret; 203 } 204 205 static inline int axp288_charger_set_cv(struct axp288_chrg_info *info, int cv) 206 { 207 u8 reg_val; 208 int ret; 209 210 if (cv <= CV_4100MV) { 211 reg_val = CHRG_CCCV_CV_4100MV; 212 cv = CV_4100MV; 213 } else if (cv <= CV_4150MV) { 214 reg_val = CHRG_CCCV_CV_4150MV; 215 cv = CV_4150MV; 216 } else if (cv <= CV_4200MV) { 217 reg_val = CHRG_CCCV_CV_4200MV; 218 cv = CV_4200MV; 219 } else { 220 reg_val = CHRG_CCCV_CV_4350MV; 221 cv = CV_4350MV; 222 } 223 224 reg_val = reg_val << CHRG_CCCV_CV_BIT_POS; 225 226 ret = regmap_update_bits(info->regmap, 227 AXP20X_CHRG_CTRL1, 228 CHRG_CCCV_CV_MASK, reg_val); 229 230 if (ret >= 0) 231 info->cv = cv; 232 233 return ret; 234 } 235 236 static inline int axp288_charger_set_vbus_inlmt(struct axp288_chrg_info *info, 237 int inlmt) 238 { 239 int ret; 240 unsigned int val; 241 u8 reg_val; 242 243 /* Read in limit register */ 244 ret = regmap_read(info->regmap, AXP20X_CHRG_BAK_CTRL, &val); 245 if (ret < 0) 246 goto set_inlmt_fail; 247 248 if (inlmt <= ILIM_100MA) { 249 reg_val = CHRG_VBUS_ILIM_100MA; 250 inlmt = ILIM_100MA; 251 } else if (inlmt <= ILIM_500MA) { 252 reg_val = CHRG_VBUS_ILIM_500MA; 253 inlmt = ILIM_500MA; 254 } else if (inlmt <= ILIM_900MA) { 255 reg_val = CHRG_VBUS_ILIM_900MA; 256 inlmt = ILIM_900MA; 257 } else if (inlmt <= ILIM_1500MA) { 258 reg_val = CHRG_VBUS_ILIM_1500MA; 259 inlmt = ILIM_1500MA; 260 } else if (inlmt <= ILIM_2000MA) { 261 reg_val = CHRG_VBUS_ILIM_2000MA; 262 inlmt = ILIM_2000MA; 263 } else if (inlmt <= ILIM_2500MA) { 264 reg_val = CHRG_VBUS_ILIM_2500MA; 265 inlmt = ILIM_2500MA; 266 } else { 267 reg_val = CHRG_VBUS_ILIM_3000MA; 268 inlmt = ILIM_3000MA; 269 } 270 271 reg_val = (val & ~CHRG_VBUS_ILIM_MASK) 272 | (reg_val << CHRG_VBUS_ILIM_BIT_POS); 273 ret = regmap_write(info->regmap, AXP20X_CHRG_BAK_CTRL, reg_val); 274 if (ret >= 0) 275 info->inlmt = inlmt; 276 else 277 dev_err(&info->pdev->dev, "charger BAK control %d\n", ret); 278 279 280 set_inlmt_fail: 281 return ret; 282 } 283 284 static int axp288_charger_vbus_path_select(struct axp288_chrg_info *info, 285 bool enable) 286 { 287 int ret; 288 289 if (enable) 290 ret = regmap_update_bits(info->regmap, AXP20X_VBUS_IPSOUT_MGMT, 291 VBUS_ISPOUT_VBUS_PATH_DIS, 0); 292 else 293 ret = regmap_update_bits(info->regmap, AXP20X_VBUS_IPSOUT_MGMT, 294 VBUS_ISPOUT_VBUS_PATH_DIS, VBUS_ISPOUT_VBUS_PATH_DIS); 295 296 if (ret < 0) 297 dev_err(&info->pdev->dev, "axp288 vbus path select %d\n", ret); 298 299 300 return ret; 301 } 302 303 static int axp288_charger_enable_charger(struct axp288_chrg_info *info, 304 bool enable) 305 { 306 int ret; 307 308 if (enable) 309 ret = regmap_update_bits(info->regmap, AXP20X_CHRG_CTRL1, 310 CHRG_CCCV_CHG_EN, CHRG_CCCV_CHG_EN); 311 else 312 ret = regmap_update_bits(info->regmap, AXP20X_CHRG_CTRL1, 313 CHRG_CCCV_CHG_EN, 0); 314 if (ret < 0) 315 dev_err(&info->pdev->dev, "axp288 enable charger %d\n", ret); 316 else 317 info->is_charger_enabled = enable; 318 319 return ret; 320 } 321 322 static int axp288_charger_is_present(struct axp288_chrg_info *info) 323 { 324 int ret, present = 0; 325 unsigned int val; 326 327 ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val); 328 if (ret < 0) 329 return ret; 330 331 if (val & PS_STAT_VBUS_PRESENT) 332 present = 1; 333 return present; 334 } 335 336 static int axp288_charger_is_online(struct axp288_chrg_info *info) 337 { 338 int ret, online = 0; 339 unsigned int val; 340 341 ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val); 342 if (ret < 0) 343 return ret; 344 345 if (val & PS_STAT_VBUS_VALID) 346 online = 1; 347 return online; 348 } 349 350 static int axp288_get_charger_health(struct axp288_chrg_info *info) 351 { 352 int ret, pwr_stat, chrg_stat; 353 int health = POWER_SUPPLY_HEALTH_UNKNOWN; 354 unsigned int val; 355 356 ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val); 357 if ((ret < 0) || !(val & PS_STAT_VBUS_PRESENT)) 358 goto health_read_fail; 359 else 360 pwr_stat = val; 361 362 ret = regmap_read(info->regmap, AXP20X_PWR_OP_MODE, &val); 363 if (ret < 0) 364 goto health_read_fail; 365 else 366 chrg_stat = val; 367 368 if (!(pwr_stat & PS_STAT_VBUS_VALID)) 369 health = POWER_SUPPLY_HEALTH_DEAD; 370 else if (chrg_stat & CHRG_STAT_PMIC_OTP) 371 health = POWER_SUPPLY_HEALTH_OVERHEAT; 372 else if (chrg_stat & CHRG_STAT_BAT_SAFE_MODE) 373 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; 374 else 375 health = POWER_SUPPLY_HEALTH_GOOD; 376 377 health_read_fail: 378 return health; 379 } 380 381 static int axp288_charger_usb_set_property(struct power_supply *psy, 382 enum power_supply_property psp, 383 const union power_supply_propval *val) 384 { 385 struct axp288_chrg_info *info = power_supply_get_drvdata(psy); 386 int ret = 0; 387 int scaled_val; 388 389 mutex_lock(&info->lock); 390 391 switch (psp) { 392 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 393 scaled_val = min(val->intval, info->max_cc); 394 scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000); 395 ret = axp288_charger_set_cc(info, scaled_val); 396 if (ret < 0) 397 dev_warn(&info->pdev->dev, "set charge current failed\n"); 398 break; 399 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 400 scaled_val = min(val->intval, info->max_cv); 401 scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000); 402 ret = axp288_charger_set_cv(info, scaled_val); 403 if (ret < 0) 404 dev_warn(&info->pdev->dev, "set charge voltage failed\n"); 405 break; 406 default: 407 ret = -EINVAL; 408 } 409 410 mutex_unlock(&info->lock); 411 return ret; 412 } 413 414 static int axp288_charger_usb_get_property(struct power_supply *psy, 415 enum power_supply_property psp, 416 union power_supply_propval *val) 417 { 418 struct axp288_chrg_info *info = power_supply_get_drvdata(psy); 419 int ret = 0; 420 421 mutex_lock(&info->lock); 422 423 switch (psp) { 424 case POWER_SUPPLY_PROP_PRESENT: 425 /* Check for OTG case first */ 426 if (info->otg.id_short) { 427 val->intval = 0; 428 break; 429 } 430 ret = axp288_charger_is_present(info); 431 if (ret < 0) 432 goto psy_get_prop_fail; 433 info->present = ret; 434 val->intval = info->present; 435 break; 436 case POWER_SUPPLY_PROP_ONLINE: 437 /* Check for OTG case first */ 438 if (info->otg.id_short) { 439 val->intval = 0; 440 break; 441 } 442 ret = axp288_charger_is_online(info); 443 if (ret < 0) 444 goto psy_get_prop_fail; 445 info->online = ret; 446 val->intval = info->online; 447 break; 448 case POWER_SUPPLY_PROP_HEALTH: 449 val->intval = axp288_get_charger_health(info); 450 break; 451 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 452 val->intval = info->cc * 1000; 453 break; 454 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 455 val->intval = info->max_cc * 1000; 456 break; 457 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 458 val->intval = info->cv * 1000; 459 break; 460 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 461 val->intval = info->max_cv * 1000; 462 break; 463 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 464 val->intval = info->inlmt * 1000; 465 break; 466 default: 467 ret = -EINVAL; 468 goto psy_get_prop_fail; 469 } 470 471 psy_get_prop_fail: 472 mutex_unlock(&info->lock); 473 return ret; 474 } 475 476 static int axp288_charger_property_is_writeable(struct power_supply *psy, 477 enum power_supply_property psp) 478 { 479 int ret; 480 481 switch (psp) { 482 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 483 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 484 ret = 1; 485 break; 486 default: 487 ret = 0; 488 } 489 490 return ret; 491 } 492 493 static enum power_supply_property axp288_usb_props[] = { 494 POWER_SUPPLY_PROP_PRESENT, 495 POWER_SUPPLY_PROP_ONLINE, 496 POWER_SUPPLY_PROP_TYPE, 497 POWER_SUPPLY_PROP_HEALTH, 498 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 499 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 500 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 501 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 502 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, 503 }; 504 505 static const struct power_supply_desc axp288_charger_desc = { 506 .name = "axp288_charger", 507 .type = POWER_SUPPLY_TYPE_USB, 508 .properties = axp288_usb_props, 509 .num_properties = ARRAY_SIZE(axp288_usb_props), 510 .get_property = axp288_charger_usb_get_property, 511 .set_property = axp288_charger_usb_set_property, 512 .property_is_writeable = axp288_charger_property_is_writeable, 513 }; 514 515 static irqreturn_t axp288_charger_irq_thread_handler(int irq, void *dev) 516 { 517 struct axp288_chrg_info *info = dev; 518 int i; 519 520 for (i = 0; i < CHRG_INTR_END; i++) { 521 if (info->irq[i] == irq) 522 break; 523 } 524 525 if (i >= CHRG_INTR_END) { 526 dev_warn(&info->pdev->dev, "spurious interrupt!!\n"); 527 return IRQ_NONE; 528 } 529 530 switch (i) { 531 case VBUS_OV_IRQ: 532 dev_dbg(&info->pdev->dev, "VBUS Over Voltage INTR\n"); 533 break; 534 case CHARGE_DONE_IRQ: 535 dev_dbg(&info->pdev->dev, "Charging Done INTR\n"); 536 break; 537 case CHARGE_CHARGING_IRQ: 538 dev_dbg(&info->pdev->dev, "Start Charging IRQ\n"); 539 break; 540 case BAT_SAFE_QUIT_IRQ: 541 dev_dbg(&info->pdev->dev, 542 "Quit Safe Mode(restart timer) Charging IRQ\n"); 543 break; 544 case BAT_SAFE_ENTER_IRQ: 545 dev_dbg(&info->pdev->dev, 546 "Enter Safe Mode(timer expire) Charging IRQ\n"); 547 break; 548 case QCBTU_IRQ: 549 dev_dbg(&info->pdev->dev, 550 "Quit Battery Under Temperature(CHRG) INTR\n"); 551 break; 552 case CBTU_IRQ: 553 dev_dbg(&info->pdev->dev, 554 "Hit Battery Under Temperature(CHRG) INTR\n"); 555 break; 556 case QCBTO_IRQ: 557 dev_dbg(&info->pdev->dev, 558 "Quit Battery Over Temperature(CHRG) INTR\n"); 559 break; 560 case CBTO_IRQ: 561 dev_dbg(&info->pdev->dev, 562 "Hit Battery Over Temperature(CHRG) INTR\n"); 563 break; 564 default: 565 dev_warn(&info->pdev->dev, "Spurious Interrupt!!!\n"); 566 goto out; 567 } 568 569 power_supply_changed(info->psy_usb); 570 out: 571 return IRQ_HANDLED; 572 } 573 574 static void axp288_charger_extcon_evt_worker(struct work_struct *work) 575 { 576 struct axp288_chrg_info *info = 577 container_of(work, struct axp288_chrg_info, cable.work); 578 int ret, current_limit; 579 bool changed = false; 580 struct extcon_dev *edev = info->cable.edev; 581 bool old_connected = info->cable.connected; 582 583 /* Determine cable/charger type */ 584 if (extcon_get_cable_state_(edev, EXTCON_CHG_USB_SDP) > 0) { 585 dev_dbg(&info->pdev->dev, "USB SDP charger is connected"); 586 info->cable.connected = true; 587 info->cable.chg_type = POWER_SUPPLY_TYPE_USB; 588 } else if (extcon_get_cable_state_(edev, EXTCON_CHG_USB_CDP) > 0) { 589 dev_dbg(&info->pdev->dev, "USB CDP charger is connected"); 590 info->cable.connected = true; 591 info->cable.chg_type = POWER_SUPPLY_TYPE_USB_CDP; 592 } else if (extcon_get_cable_state_(edev, EXTCON_CHG_USB_DCP) > 0) { 593 dev_dbg(&info->pdev->dev, "USB DCP charger is connected"); 594 info->cable.connected = true; 595 info->cable.chg_type = POWER_SUPPLY_TYPE_USB_DCP; 596 } else { 597 if (old_connected) 598 dev_dbg(&info->pdev->dev, "USB charger disconnected"); 599 info->cable.connected = false; 600 info->cable.chg_type = POWER_SUPPLY_TYPE_USB; 601 } 602 603 /* Cable status changed */ 604 if (old_connected != info->cable.connected) 605 changed = true; 606 607 if (!changed) 608 return; 609 610 mutex_lock(&info->lock); 611 612 if (info->is_charger_enabled && !info->cable.connected) { 613 info->enable_charger = false; 614 ret = axp288_charger_enable_charger(info, info->enable_charger); 615 if (ret < 0) 616 dev_err(&info->pdev->dev, 617 "cannot disable charger (%d)", ret); 618 619 } else if (!info->is_charger_enabled && info->cable.connected) { 620 switch (info->cable.chg_type) { 621 case POWER_SUPPLY_TYPE_USB: 622 current_limit = ILIM_500MA; 623 break; 624 case POWER_SUPPLY_TYPE_USB_CDP: 625 current_limit = ILIM_1500MA; 626 break; 627 case POWER_SUPPLY_TYPE_USB_DCP: 628 current_limit = ILIM_2000MA; 629 break; 630 default: 631 /* Unknown */ 632 current_limit = 0; 633 break; 634 } 635 636 /* Set vbus current limit first, then enable charger */ 637 ret = axp288_charger_set_vbus_inlmt(info, current_limit); 638 if (ret < 0) { 639 dev_err(&info->pdev->dev, 640 "error setting current limit (%d)", ret); 641 } else { 642 info->enable_charger = (current_limit > 0); 643 ret = axp288_charger_enable_charger(info, 644 info->enable_charger); 645 if (ret < 0) 646 dev_err(&info->pdev->dev, 647 "cannot enable charger (%d)", ret); 648 } 649 } 650 651 if (changed) 652 info->health = axp288_get_charger_health(info); 653 654 mutex_unlock(&info->lock); 655 656 if (changed) 657 power_supply_changed(info->psy_usb); 658 } 659 660 static int axp288_charger_handle_cable_evt(struct notifier_block *nb, 661 unsigned long event, void *param) 662 { 663 struct axp288_chrg_info *info = 664 container_of(nb, struct axp288_chrg_info, cable.nb); 665 666 schedule_work(&info->cable.work); 667 668 return NOTIFY_OK; 669 } 670 671 static void axp288_charger_otg_evt_worker(struct work_struct *work) 672 { 673 struct axp288_chrg_info *info = 674 container_of(work, struct axp288_chrg_info, otg.work); 675 int ret; 676 677 /* Disable VBUS path before enabling the 5V boost */ 678 ret = axp288_charger_vbus_path_select(info, !info->otg.id_short); 679 if (ret < 0) 680 dev_warn(&info->pdev->dev, "vbus path disable failed\n"); 681 } 682 683 static int axp288_charger_handle_otg_evt(struct notifier_block *nb, 684 unsigned long event, void *param) 685 { 686 struct axp288_chrg_info *info = 687 container_of(nb, struct axp288_chrg_info, otg.id_nb); 688 struct extcon_dev *edev = info->otg.cable; 689 int usb_host = extcon_get_cable_state_(edev, EXTCON_USB_HOST); 690 691 dev_dbg(&info->pdev->dev, "external connector USB-Host is %s\n", 692 usb_host ? "attached" : "detached"); 693 694 /* 695 * Set usb_id_short flag to avoid running charger detection logic 696 * in case usb host. 697 */ 698 info->otg.id_short = usb_host; 699 schedule_work(&info->otg.work); 700 701 return NOTIFY_OK; 702 } 703 704 static void charger_init_hw_regs(struct axp288_chrg_info *info) 705 { 706 int ret, cc, cv; 707 unsigned int val; 708 709 /* Program temperature thresholds */ 710 ret = regmap_write(info->regmap, AXP20X_V_LTF_CHRG, CHRG_VLTFC_0C); 711 if (ret < 0) 712 dev_warn(&info->pdev->dev, "register(%x) write error(%d)\n", 713 AXP20X_V_LTF_CHRG, ret); 714 715 ret = regmap_write(info->regmap, AXP20X_V_HTF_CHRG, CHRG_VHTFC_45C); 716 if (ret < 0) 717 dev_warn(&info->pdev->dev, "register(%x) write error(%d)\n", 718 AXP20X_V_HTF_CHRG, ret); 719 720 /* Do not turn-off charger o/p after charge cycle ends */ 721 ret = regmap_update_bits(info->regmap, 722 AXP20X_CHRG_CTRL2, 723 CNTL2_CHG_OUT_TURNON, 1); 724 if (ret < 0) 725 dev_warn(&info->pdev->dev, "register(%x) write error(%d)\n", 726 AXP20X_CHRG_CTRL2, ret); 727 728 /* Enable interrupts */ 729 ret = regmap_update_bits(info->regmap, 730 AXP20X_IRQ2_EN, 731 BAT_IRQ_CFG_BAT_MASK, 1); 732 if (ret < 0) 733 dev_warn(&info->pdev->dev, "register(%x) write error(%d)\n", 734 AXP20X_IRQ2_EN, ret); 735 736 ret = regmap_update_bits(info->regmap, AXP20X_IRQ3_EN, 737 TEMP_IRQ_CFG_MASK, 1); 738 if (ret < 0) 739 dev_warn(&info->pdev->dev, "register(%x) write error(%d)\n", 740 AXP20X_IRQ3_EN, ret); 741 742 /* Setup ending condition for charging to be 10% of I(chrg) */ 743 ret = regmap_update_bits(info->regmap, 744 AXP20X_CHRG_CTRL1, 745 CHRG_CCCV_ITERM_20P, 0); 746 if (ret < 0) 747 dev_warn(&info->pdev->dev, "register(%x) write error(%d)\n", 748 AXP20X_CHRG_CTRL1, ret); 749 750 /* Disable OCV-SOC curve calibration */ 751 ret = regmap_update_bits(info->regmap, 752 AXP20X_CC_CTRL, 753 FG_CNTL_OCV_ADJ_EN, 0); 754 if (ret < 0) 755 dev_warn(&info->pdev->dev, "register(%x) write error(%d)\n", 756 AXP20X_CC_CTRL, ret); 757 758 /* Init charging current and voltage */ 759 info->max_cc = info->pdata->max_cc; 760 info->max_cv = info->pdata->max_cv; 761 762 /* Read current charge voltage and current limit */ 763 ret = regmap_read(info->regmap, AXP20X_CHRG_CTRL1, &val); 764 if (ret < 0) { 765 /* Assume default if cannot read */ 766 info->cc = info->pdata->def_cc; 767 info->cv = info->pdata->def_cv; 768 } else { 769 /* Determine charge voltage */ 770 cv = (val & CHRG_CCCV_CV_MASK) >> CHRG_CCCV_CV_BIT_POS; 771 switch (cv) { 772 case CHRG_CCCV_CV_4100MV: 773 info->cv = CV_4100MV; 774 break; 775 case CHRG_CCCV_CV_4150MV: 776 info->cv = CV_4150MV; 777 break; 778 case CHRG_CCCV_CV_4200MV: 779 info->cv = CV_4200MV; 780 break; 781 case CHRG_CCCV_CV_4350MV: 782 info->cv = CV_4350MV; 783 break; 784 default: 785 info->cv = INT_MAX; 786 break; 787 } 788 789 /* Determine charge current limit */ 790 cc = (ret & CHRG_CCCV_CC_MASK) >> CHRG_CCCV_CC_BIT_POS; 791 cc = (cc * CHRG_CCCV_CC_LSB_RES) + CHRG_CCCV_CC_OFFSET; 792 info->cc = cc; 793 794 /* Program default charging voltage and current */ 795 cc = min(info->pdata->def_cc, info->max_cc); 796 cv = min(info->pdata->def_cv, info->max_cv); 797 798 ret = axp288_charger_set_cc(info, cc); 799 if (ret < 0) 800 dev_warn(&info->pdev->dev, 801 "error(%d) in setting CC\n", ret); 802 803 ret = axp288_charger_set_cv(info, cv); 804 if (ret < 0) 805 dev_warn(&info->pdev->dev, 806 "error(%d) in setting CV\n", ret); 807 } 808 } 809 810 static int axp288_charger_probe(struct platform_device *pdev) 811 { 812 int ret, i, pirq; 813 struct axp288_chrg_info *info; 814 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); 815 struct power_supply_config charger_cfg = {}; 816 817 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 818 if (!info) 819 return -ENOMEM; 820 821 info->pdev = pdev; 822 info->regmap = axp20x->regmap; 823 info->regmap_irqc = axp20x->regmap_irqc; 824 info->pdata = pdev->dev.platform_data; 825 826 if (!info->pdata) { 827 /* Try ACPI provided pdata via device properties */ 828 if (!device_property_present(&pdev->dev, 829 "axp288_charger_data\n")) 830 dev_err(&pdev->dev, "failed to get platform data\n"); 831 return -ENODEV; 832 } 833 834 info->cable.edev = extcon_get_extcon_dev(AXP288_EXTCON_DEV_NAME); 835 if (info->cable.edev == NULL) { 836 dev_dbg(&pdev->dev, "%s is not ready, probe deferred\n", 837 AXP288_EXTCON_DEV_NAME); 838 return -EPROBE_DEFER; 839 } 840 841 /* Register for extcon notification */ 842 INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker); 843 info->cable.nb.notifier_call = axp288_charger_handle_cable_evt; 844 ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, 845 &info->cable.nb); 846 if (ret) { 847 dev_err(&info->pdev->dev, 848 "failed to register extcon notifier for SDP %d\n", ret); 849 return ret; 850 } 851 852 ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, 853 &info->cable.nb); 854 if (ret) { 855 dev_err(&info->pdev->dev, 856 "failed to register extcon notifier for CDP %d\n", ret); 857 extcon_unregister_notifier(info->cable.edev, 858 EXTCON_CHG_USB_SDP, &info->cable.nb); 859 return ret; 860 } 861 862 ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_DCP, 863 &info->cable.nb); 864 if (ret) { 865 dev_err(&info->pdev->dev, 866 "failed to register extcon notifier for DCP %d\n", ret); 867 extcon_unregister_notifier(info->cable.edev, 868 EXTCON_CHG_USB_SDP, &info->cable.nb); 869 extcon_unregister_notifier(info->cable.edev, 870 EXTCON_CHG_USB_CDP, &info->cable.nb); 871 return ret; 872 } 873 874 platform_set_drvdata(pdev, info); 875 mutex_init(&info->lock); 876 877 /* Register with power supply class */ 878 charger_cfg.drv_data = info; 879 info->psy_usb = power_supply_register(&pdev->dev, &axp288_charger_desc, 880 &charger_cfg); 881 if (IS_ERR(info->psy_usb)) { 882 dev_err(&pdev->dev, "failed to register power supply charger\n"); 883 ret = PTR_ERR(info->psy_usb); 884 goto psy_reg_failed; 885 } 886 887 /* Register for OTG notification */ 888 INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker); 889 info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt; 890 ret = extcon_register_notifier(info->otg.cable, EXTCON_USB_HOST, 891 &info->otg.id_nb); 892 if (ret) 893 dev_warn(&pdev->dev, "failed to register otg notifier\n"); 894 895 if (info->otg.cable) 896 info->otg.id_short = extcon_get_cable_state_( 897 info->otg.cable, EXTCON_USB_HOST); 898 899 /* Register charger interrupts */ 900 for (i = 0; i < CHRG_INTR_END; i++) { 901 pirq = platform_get_irq(info->pdev, i); 902 info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); 903 if (info->irq[i] < 0) { 904 dev_warn(&info->pdev->dev, 905 "failed to get virtual interrupt=%d\n", pirq); 906 ret = info->irq[i]; 907 goto intr_reg_failed; 908 } 909 ret = devm_request_threaded_irq(&info->pdev->dev, info->irq[i], 910 NULL, axp288_charger_irq_thread_handler, 911 IRQF_ONESHOT, info->pdev->name, info); 912 if (ret) { 913 dev_err(&pdev->dev, "failed to request interrupt=%d\n", 914 info->irq[i]); 915 goto intr_reg_failed; 916 } 917 } 918 919 charger_init_hw_regs(info); 920 921 return 0; 922 923 intr_reg_failed: 924 if (info->otg.cable) 925 extcon_unregister_notifier(info->otg.cable, EXTCON_USB_HOST, 926 &info->otg.id_nb); 927 power_supply_unregister(info->psy_usb); 928 psy_reg_failed: 929 extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, 930 &info->cable.nb); 931 extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, 932 &info->cable.nb); 933 extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_DCP, 934 &info->cable.nb); 935 return ret; 936 } 937 938 static int axp288_charger_remove(struct platform_device *pdev) 939 { 940 struct axp288_chrg_info *info = dev_get_drvdata(&pdev->dev); 941 942 if (info->otg.cable) 943 extcon_unregister_notifier(info->otg.cable, EXTCON_USB_HOST, 944 &info->otg.id_nb); 945 946 extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, 947 &info->cable.nb); 948 extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, 949 &info->cable.nb); 950 extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_DCP, 951 &info->cable.nb); 952 power_supply_unregister(info->psy_usb); 953 954 return 0; 955 } 956 957 static struct platform_driver axp288_charger_driver = { 958 .probe = axp288_charger_probe, 959 .remove = axp288_charger_remove, 960 .driver = { 961 .name = "axp288_charger", 962 }, 963 }; 964 965 module_platform_driver(axp288_charger_driver); 966 967 MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>"); 968 MODULE_DESCRIPTION("X-power AXP288 Charger Driver"); 969 MODULE_LICENSE("GPL v2"); 970