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