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