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