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 FG_CNTL_OCV_ADJ_EN (1 << 3) 94 95 #define CV_4100MV 4100 /* 4100mV */ 96 #define CV_4150MV 4150 /* 4150mV */ 97 #define CV_4200MV 4200 /* 4200mV */ 98 #define CV_4350MV 4350 /* 4350mV */ 99 100 #define CC_200MA 200 /* 200mA */ 101 #define CC_600MA 600 /* 600mA */ 102 #define CC_800MA 800 /* 800mA */ 103 #define CC_1000MA 1000 /* 1000mA */ 104 #define CC_1600MA 1600 /* 1600mA */ 105 #define CC_2000MA 2000 /* 2000mA */ 106 107 #define ILIM_100MA 100 /* 100mA */ 108 #define ILIM_500MA 500 /* 500mA */ 109 #define ILIM_900MA 900 /* 900mA */ 110 #define ILIM_1500MA 1500 /* 1500mA */ 111 #define ILIM_2000MA 2000 /* 2000mA */ 112 #define ILIM_2500MA 2500 /* 2500mA */ 113 #define ILIM_3000MA 3000 /* 3000mA */ 114 115 #define AXP288_EXTCON_DEV_NAME "axp288_extcon" 116 #define USB_HOST_EXTCON_DEV_NAME "INT3496:00" 117 118 static const unsigned int cable_ids[] = 119 { EXTCON_CHG_USB_SDP, EXTCON_CHG_USB_CDP, EXTCON_CHG_USB_DCP }; 120 121 enum { 122 VBUS_OV_IRQ = 0, 123 CHARGE_DONE_IRQ, 124 CHARGE_CHARGING_IRQ, 125 BAT_SAFE_QUIT_IRQ, 126 BAT_SAFE_ENTER_IRQ, 127 QCBTU_IRQ, 128 CBTU_IRQ, 129 QCBTO_IRQ, 130 CBTO_IRQ, 131 CHRG_INTR_END, 132 }; 133 134 struct axp288_chrg_info { 135 struct platform_device *pdev; 136 struct regmap *regmap; 137 struct regmap_irq_chip_data *regmap_irqc; 138 int irq[CHRG_INTR_END]; 139 struct power_supply *psy_usb; 140 struct mutex lock; 141 142 /* OTG/Host mode */ 143 struct { 144 struct work_struct work; 145 struct extcon_dev *cable; 146 struct notifier_block id_nb; 147 bool id_short; 148 } otg; 149 150 /* SDP/CDP/DCP USB charging cable notifications */ 151 struct { 152 struct extcon_dev *edev; 153 bool connected; 154 enum power_supply_type chg_type; 155 struct notifier_block nb[ARRAY_SIZE(cable_ids)]; 156 struct work_struct work; 157 } cable; 158 159 int inlmt; 160 int cc; 161 int cv; 162 int max_cc; 163 int max_cv; 164 int is_charger_enabled; 165 }; 166 167 static inline int axp288_charger_set_cc(struct axp288_chrg_info *info, int cc) 168 { 169 u8 reg_val; 170 int ret; 171 172 if (cc < CHRG_CCCV_CC_OFFSET) 173 cc = CHRG_CCCV_CC_OFFSET; 174 else if (cc > info->max_cc) 175 cc = info->max_cc; 176 177 reg_val = (cc - CHRG_CCCV_CC_OFFSET) / CHRG_CCCV_CC_LSB_RES; 178 cc = (reg_val * CHRG_CCCV_CC_LSB_RES) + CHRG_CCCV_CC_OFFSET; 179 reg_val = reg_val << CHRG_CCCV_CC_BIT_POS; 180 181 ret = regmap_update_bits(info->regmap, 182 AXP20X_CHRG_CTRL1, 183 CHRG_CCCV_CC_MASK, reg_val); 184 if (ret >= 0) 185 info->cc = cc; 186 187 return ret; 188 } 189 190 static inline int axp288_charger_set_cv(struct axp288_chrg_info *info, int cv) 191 { 192 u8 reg_val; 193 int ret; 194 195 if (cv <= CV_4100MV) { 196 reg_val = CHRG_CCCV_CV_4100MV; 197 cv = CV_4100MV; 198 } else if (cv <= CV_4150MV) { 199 reg_val = CHRG_CCCV_CV_4150MV; 200 cv = CV_4150MV; 201 } else if (cv <= CV_4200MV) { 202 reg_val = CHRG_CCCV_CV_4200MV; 203 cv = CV_4200MV; 204 } else { 205 reg_val = CHRG_CCCV_CV_4350MV; 206 cv = CV_4350MV; 207 } 208 209 reg_val = reg_val << CHRG_CCCV_CV_BIT_POS; 210 211 ret = regmap_update_bits(info->regmap, 212 AXP20X_CHRG_CTRL1, 213 CHRG_CCCV_CV_MASK, reg_val); 214 215 if (ret >= 0) 216 info->cv = cv; 217 218 return ret; 219 } 220 221 static inline int axp288_charger_set_vbus_inlmt(struct axp288_chrg_info *info, 222 int inlmt) 223 { 224 int ret; 225 unsigned int val; 226 u8 reg_val; 227 228 /* Read in limit register */ 229 ret = regmap_read(info->regmap, AXP20X_CHRG_BAK_CTRL, &val); 230 if (ret < 0) 231 goto set_inlmt_fail; 232 233 if (inlmt <= ILIM_100MA) { 234 reg_val = CHRG_VBUS_ILIM_100MA; 235 inlmt = ILIM_100MA; 236 } else if (inlmt <= ILIM_500MA) { 237 reg_val = CHRG_VBUS_ILIM_500MA; 238 inlmt = ILIM_500MA; 239 } else if (inlmt <= ILIM_900MA) { 240 reg_val = CHRG_VBUS_ILIM_900MA; 241 inlmt = ILIM_900MA; 242 } else if (inlmt <= ILIM_1500MA) { 243 reg_val = CHRG_VBUS_ILIM_1500MA; 244 inlmt = ILIM_1500MA; 245 } else if (inlmt <= ILIM_2000MA) { 246 reg_val = CHRG_VBUS_ILIM_2000MA; 247 inlmt = ILIM_2000MA; 248 } else if (inlmt <= ILIM_2500MA) { 249 reg_val = CHRG_VBUS_ILIM_2500MA; 250 inlmt = ILIM_2500MA; 251 } else { 252 reg_val = CHRG_VBUS_ILIM_3000MA; 253 inlmt = ILIM_3000MA; 254 } 255 256 reg_val = (val & ~CHRG_VBUS_ILIM_MASK) 257 | (reg_val << CHRG_VBUS_ILIM_BIT_POS); 258 ret = regmap_write(info->regmap, AXP20X_CHRG_BAK_CTRL, reg_val); 259 if (ret >= 0) 260 info->inlmt = inlmt; 261 else 262 dev_err(&info->pdev->dev, "charger BAK control %d\n", ret); 263 264 265 set_inlmt_fail: 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 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 ((int)enable == info->is_charger_enabled) 294 return 0; 295 296 if (enable) 297 ret = regmap_update_bits(info->regmap, AXP20X_CHRG_CTRL1, 298 CHRG_CCCV_CHG_EN, CHRG_CCCV_CHG_EN); 299 else 300 ret = regmap_update_bits(info->regmap, AXP20X_CHRG_CTRL1, 301 CHRG_CCCV_CHG_EN, 0); 302 if (ret < 0) 303 dev_err(&info->pdev->dev, "axp288 enable charger %d\n", ret); 304 else 305 info->is_charger_enabled = enable; 306 307 return ret; 308 } 309 310 static int axp288_charger_is_present(struct axp288_chrg_info *info) 311 { 312 int ret, present = 0; 313 unsigned int val; 314 315 ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val); 316 if (ret < 0) 317 return ret; 318 319 if (val & PS_STAT_VBUS_PRESENT) 320 present = 1; 321 return present; 322 } 323 324 static int axp288_charger_is_online(struct axp288_chrg_info *info) 325 { 326 int ret, online = 0; 327 unsigned int val; 328 329 ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val); 330 if (ret < 0) 331 return ret; 332 333 if (val & PS_STAT_VBUS_VALID) 334 online = 1; 335 return online; 336 } 337 338 static int axp288_get_charger_health(struct axp288_chrg_info *info) 339 { 340 int ret, pwr_stat, chrg_stat; 341 int health = POWER_SUPPLY_HEALTH_UNKNOWN; 342 unsigned int val; 343 344 ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val); 345 if ((ret < 0) || !(val & PS_STAT_VBUS_PRESENT)) 346 goto health_read_fail; 347 else 348 pwr_stat = val; 349 350 ret = regmap_read(info->regmap, AXP20X_PWR_OP_MODE, &val); 351 if (ret < 0) 352 goto health_read_fail; 353 else 354 chrg_stat = val; 355 356 if (!(pwr_stat & PS_STAT_VBUS_VALID)) 357 health = POWER_SUPPLY_HEALTH_DEAD; 358 else if (chrg_stat & CHRG_STAT_PMIC_OTP) 359 health = POWER_SUPPLY_HEALTH_OVERHEAT; 360 else if (chrg_stat & CHRG_STAT_BAT_SAFE_MODE) 361 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; 362 else 363 health = POWER_SUPPLY_HEALTH_GOOD; 364 365 health_read_fail: 366 return health; 367 } 368 369 static int axp288_charger_usb_set_property(struct power_supply *psy, 370 enum power_supply_property psp, 371 const union power_supply_propval *val) 372 { 373 struct axp288_chrg_info *info = power_supply_get_drvdata(psy); 374 int ret = 0; 375 int scaled_val; 376 377 mutex_lock(&info->lock); 378 379 switch (psp) { 380 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 381 scaled_val = min(val->intval, info->max_cc); 382 scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000); 383 ret = axp288_charger_set_cc(info, scaled_val); 384 if (ret < 0) 385 dev_warn(&info->pdev->dev, "set charge current failed\n"); 386 break; 387 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 388 scaled_val = min(val->intval, info->max_cv); 389 scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000); 390 ret = axp288_charger_set_cv(info, scaled_val); 391 if (ret < 0) 392 dev_warn(&info->pdev->dev, "set charge voltage failed\n"); 393 break; 394 default: 395 ret = -EINVAL; 396 } 397 398 mutex_unlock(&info->lock); 399 return ret; 400 } 401 402 static int axp288_charger_usb_get_property(struct power_supply *psy, 403 enum power_supply_property psp, 404 union power_supply_propval *val) 405 { 406 struct axp288_chrg_info *info = power_supply_get_drvdata(psy); 407 int ret = 0; 408 409 mutex_lock(&info->lock); 410 411 switch (psp) { 412 case POWER_SUPPLY_PROP_PRESENT: 413 /* Check for OTG case first */ 414 if (info->otg.id_short) { 415 val->intval = 0; 416 break; 417 } 418 ret = axp288_charger_is_present(info); 419 if (ret < 0) 420 goto psy_get_prop_fail; 421 val->intval = ret; 422 break; 423 case POWER_SUPPLY_PROP_ONLINE: 424 /* Check for OTG case first */ 425 if (info->otg.id_short) { 426 val->intval = 0; 427 break; 428 } 429 ret = axp288_charger_is_online(info); 430 if (ret < 0) 431 goto psy_get_prop_fail; 432 val->intval = ret; 433 break; 434 case POWER_SUPPLY_PROP_HEALTH: 435 val->intval = axp288_get_charger_health(info); 436 break; 437 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 438 val->intval = info->cc * 1000; 439 break; 440 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 441 val->intval = info->max_cc * 1000; 442 break; 443 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 444 val->intval = info->cv * 1000; 445 break; 446 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 447 val->intval = info->max_cv * 1000; 448 break; 449 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 450 val->intval = info->inlmt * 1000; 451 break; 452 default: 453 ret = -EINVAL; 454 goto psy_get_prop_fail; 455 } 456 457 psy_get_prop_fail: 458 mutex_unlock(&info->lock); 459 return ret; 460 } 461 462 static int axp288_charger_property_is_writeable(struct power_supply *psy, 463 enum power_supply_property psp) 464 { 465 int ret; 466 467 switch (psp) { 468 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 469 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 470 ret = 1; 471 break; 472 default: 473 ret = 0; 474 } 475 476 return ret; 477 } 478 479 static enum power_supply_property axp288_usb_props[] = { 480 POWER_SUPPLY_PROP_PRESENT, 481 POWER_SUPPLY_PROP_ONLINE, 482 POWER_SUPPLY_PROP_TYPE, 483 POWER_SUPPLY_PROP_HEALTH, 484 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 485 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 486 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 487 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 488 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, 489 }; 490 491 static const struct power_supply_desc axp288_charger_desc = { 492 .name = "axp288_charger", 493 .type = POWER_SUPPLY_TYPE_USB, 494 .properties = axp288_usb_props, 495 .num_properties = ARRAY_SIZE(axp288_usb_props), 496 .get_property = axp288_charger_usb_get_property, 497 .set_property = axp288_charger_usb_set_property, 498 .property_is_writeable = axp288_charger_property_is_writeable, 499 }; 500 501 static irqreturn_t axp288_charger_irq_thread_handler(int irq, void *dev) 502 { 503 struct axp288_chrg_info *info = dev; 504 int i; 505 506 for (i = 0; i < CHRG_INTR_END; i++) { 507 if (info->irq[i] == irq) 508 break; 509 } 510 511 if (i >= CHRG_INTR_END) { 512 dev_warn(&info->pdev->dev, "spurious interrupt!!\n"); 513 return IRQ_NONE; 514 } 515 516 switch (i) { 517 case VBUS_OV_IRQ: 518 dev_dbg(&info->pdev->dev, "VBUS Over Voltage INTR\n"); 519 break; 520 case CHARGE_DONE_IRQ: 521 dev_dbg(&info->pdev->dev, "Charging Done INTR\n"); 522 break; 523 case CHARGE_CHARGING_IRQ: 524 dev_dbg(&info->pdev->dev, "Start Charging IRQ\n"); 525 break; 526 case BAT_SAFE_QUIT_IRQ: 527 dev_dbg(&info->pdev->dev, 528 "Quit Safe Mode(restart timer) Charging IRQ\n"); 529 break; 530 case BAT_SAFE_ENTER_IRQ: 531 dev_dbg(&info->pdev->dev, 532 "Enter Safe Mode(timer expire) Charging IRQ\n"); 533 break; 534 case QCBTU_IRQ: 535 dev_dbg(&info->pdev->dev, 536 "Quit Battery Under Temperature(CHRG) INTR\n"); 537 break; 538 case CBTU_IRQ: 539 dev_dbg(&info->pdev->dev, 540 "Hit Battery Under Temperature(CHRG) INTR\n"); 541 break; 542 case QCBTO_IRQ: 543 dev_dbg(&info->pdev->dev, 544 "Quit Battery Over Temperature(CHRG) INTR\n"); 545 break; 546 case CBTO_IRQ: 547 dev_dbg(&info->pdev->dev, 548 "Hit Battery Over Temperature(CHRG) INTR\n"); 549 break; 550 default: 551 dev_warn(&info->pdev->dev, "Spurious Interrupt!!!\n"); 552 goto out; 553 } 554 555 power_supply_changed(info->psy_usb); 556 out: 557 return IRQ_HANDLED; 558 } 559 560 static void axp288_charger_extcon_evt_worker(struct work_struct *work) 561 { 562 struct axp288_chrg_info *info = 563 container_of(work, struct axp288_chrg_info, cable.work); 564 int ret, current_limit; 565 struct extcon_dev *edev = info->cable.edev; 566 bool old_connected = info->cable.connected; 567 enum power_supply_type old_chg_type = info->cable.chg_type; 568 569 /* Determine cable/charger type */ 570 if (extcon_get_state(edev, EXTCON_CHG_USB_SDP) > 0) { 571 dev_dbg(&info->pdev->dev, "USB SDP charger is connected"); 572 info->cable.connected = true; 573 info->cable.chg_type = POWER_SUPPLY_TYPE_USB; 574 } else if (extcon_get_state(edev, EXTCON_CHG_USB_CDP) > 0) { 575 dev_dbg(&info->pdev->dev, "USB CDP charger is connected"); 576 info->cable.connected = true; 577 info->cable.chg_type = POWER_SUPPLY_TYPE_USB_CDP; 578 } else if (extcon_get_state(edev, EXTCON_CHG_USB_DCP) > 0) { 579 dev_dbg(&info->pdev->dev, "USB DCP charger is connected"); 580 info->cable.connected = true; 581 info->cable.chg_type = POWER_SUPPLY_TYPE_USB_DCP; 582 } else { 583 if (old_connected) 584 dev_dbg(&info->pdev->dev, "USB charger disconnected"); 585 info->cable.connected = false; 586 info->cable.chg_type = POWER_SUPPLY_TYPE_USB; 587 } 588 589 /* Cable status changed */ 590 if (old_connected == info->cable.connected && 591 old_chg_type == info->cable.chg_type) 592 return; 593 594 mutex_lock(&info->lock); 595 596 if (info->cable.connected) { 597 axp288_charger_enable_charger(info, false); 598 599 switch (info->cable.chg_type) { 600 case POWER_SUPPLY_TYPE_USB: 601 current_limit = ILIM_500MA; 602 break; 603 case POWER_SUPPLY_TYPE_USB_CDP: 604 current_limit = ILIM_1500MA; 605 break; 606 case POWER_SUPPLY_TYPE_USB_DCP: 607 current_limit = ILIM_2000MA; 608 break; 609 default: 610 /* Unknown */ 611 current_limit = 0; 612 break; 613 } 614 615 /* Set vbus current limit first, then enable charger */ 616 ret = axp288_charger_set_vbus_inlmt(info, current_limit); 617 if (ret == 0) 618 axp288_charger_enable_charger(info, true); 619 else 620 dev_err(&info->pdev->dev, 621 "error setting current limit (%d)", ret); 622 } else { 623 axp288_charger_enable_charger(info, false); 624 } 625 626 mutex_unlock(&info->lock); 627 628 power_supply_changed(info->psy_usb); 629 } 630 631 /* 632 * We need 3 copies of this, because there is no way to find out for which 633 * cable id we are being called from the passed in arguments; and we must 634 * have a separate nb for each extcon_register_notifier call. 635 */ 636 static int axp288_charger_handle_cable0_evt(struct notifier_block *nb, 637 unsigned long event, void *param) 638 { 639 struct axp288_chrg_info *info = 640 container_of(nb, struct axp288_chrg_info, cable.nb[0]); 641 schedule_work(&info->cable.work); 642 return NOTIFY_OK; 643 } 644 645 static int axp288_charger_handle_cable1_evt(struct notifier_block *nb, 646 unsigned long event, void *param) 647 { 648 struct axp288_chrg_info *info = 649 container_of(nb, struct axp288_chrg_info, cable.nb[1]); 650 schedule_work(&info->cable.work); 651 return NOTIFY_OK; 652 } 653 654 static int axp288_charger_handle_cable2_evt(struct notifier_block *nb, 655 unsigned long event, void *param) 656 { 657 struct axp288_chrg_info *info = 658 container_of(nb, struct axp288_chrg_info, cable.nb[2]); 659 schedule_work(&info->cable.work); 660 return NOTIFY_OK; 661 } 662 663 static void axp288_charger_otg_evt_worker(struct work_struct *work) 664 { 665 struct axp288_chrg_info *info = 666 container_of(work, struct axp288_chrg_info, otg.work); 667 struct extcon_dev *edev = info->otg.cable; 668 int ret, usb_host = extcon_get_state(edev, EXTCON_USB_HOST); 669 670 dev_dbg(&info->pdev->dev, "external connector USB-Host is %s\n", 671 usb_host ? "attached" : "detached"); 672 673 /* 674 * Set usb_id_short flag to avoid running charger detection logic 675 * in case usb host. 676 */ 677 info->otg.id_short = usb_host; 678 679 /* Disable VBUS path before enabling the 5V boost */ 680 ret = axp288_charger_vbus_path_select(info, !info->otg.id_short); 681 if (ret < 0) 682 dev_warn(&info->pdev->dev, "vbus path disable failed\n"); 683 } 684 685 static int axp288_charger_handle_otg_evt(struct notifier_block *nb, 686 unsigned long event, void *param) 687 { 688 struct axp288_chrg_info *info = 689 container_of(nb, struct axp288_chrg_info, otg.id_nb); 690 691 schedule_work(&info->otg.work); 692 693 return NOTIFY_OK; 694 } 695 696 static int charger_init_hw_regs(struct axp288_chrg_info *info) 697 { 698 int ret, cc, cv; 699 unsigned int val; 700 701 /* Program temperature thresholds */ 702 ret = regmap_write(info->regmap, AXP20X_V_LTF_CHRG, CHRG_VLTFC_0C); 703 if (ret < 0) { 704 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n", 705 AXP20X_V_LTF_CHRG, ret); 706 return ret; 707 } 708 709 ret = regmap_write(info->regmap, AXP20X_V_HTF_CHRG, CHRG_VHTFC_45C); 710 if (ret < 0) { 711 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n", 712 AXP20X_V_HTF_CHRG, ret); 713 return ret; 714 } 715 716 /* Do not turn-off charger o/p after charge cycle ends */ 717 ret = regmap_update_bits(info->regmap, 718 AXP20X_CHRG_CTRL2, 719 CNTL2_CHG_OUT_TURNON, CNTL2_CHG_OUT_TURNON); 720 if (ret < 0) { 721 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n", 722 AXP20X_CHRG_CTRL2, ret); 723 return ret; 724 } 725 726 /* Setup ending condition for charging to be 10% of I(chrg) */ 727 ret = regmap_update_bits(info->regmap, 728 AXP20X_CHRG_CTRL1, 729 CHRG_CCCV_ITERM_20P, 0); 730 if (ret < 0) { 731 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n", 732 AXP20X_CHRG_CTRL1, ret); 733 return ret; 734 } 735 736 /* Disable OCV-SOC curve calibration */ 737 ret = regmap_update_bits(info->regmap, 738 AXP20X_CC_CTRL, 739 FG_CNTL_OCV_ADJ_EN, 0); 740 if (ret < 0) { 741 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n", 742 AXP20X_CC_CTRL, ret); 743 return ret; 744 } 745 746 /* Read current charge voltage and current limit */ 747 ret = regmap_read(info->regmap, AXP20X_CHRG_CTRL1, &val); 748 if (ret < 0) { 749 dev_err(&info->pdev->dev, "register(%x) read error(%d)\n", 750 AXP20X_CHRG_CTRL1, ret); 751 return ret; 752 } 753 754 /* Determine charge voltage */ 755 cv = (val & CHRG_CCCV_CV_MASK) >> CHRG_CCCV_CV_BIT_POS; 756 switch (cv) { 757 case CHRG_CCCV_CV_4100MV: 758 info->cv = CV_4100MV; 759 break; 760 case CHRG_CCCV_CV_4150MV: 761 info->cv = CV_4150MV; 762 break; 763 case CHRG_CCCV_CV_4200MV: 764 info->cv = CV_4200MV; 765 break; 766 case CHRG_CCCV_CV_4350MV: 767 info->cv = CV_4350MV; 768 break; 769 } 770 771 /* Determine charge current limit */ 772 cc = (ret & CHRG_CCCV_CC_MASK) >> CHRG_CCCV_CC_BIT_POS; 773 cc = (cc * CHRG_CCCV_CC_LSB_RES) + CHRG_CCCV_CC_OFFSET; 774 info->cc = cc; 775 776 /* 777 * Do not allow the user to configure higher settings then those 778 * set by the firmware 779 */ 780 info->max_cv = info->cv; 781 info->max_cc = info->cc; 782 783 return 0; 784 } 785 786 static int axp288_charger_probe(struct platform_device *pdev) 787 { 788 int ret, i, pirq; 789 struct axp288_chrg_info *info; 790 struct device *dev = &pdev->dev; 791 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); 792 struct power_supply_config charger_cfg = {}; 793 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 794 if (!info) 795 return -ENOMEM; 796 797 info->pdev = pdev; 798 info->regmap = axp20x->regmap; 799 info->regmap_irqc = axp20x->regmap_irqc; 800 info->cable.chg_type = -1; 801 info->is_charger_enabled = -1; 802 803 info->cable.edev = extcon_get_extcon_dev(AXP288_EXTCON_DEV_NAME); 804 if (info->cable.edev == NULL) { 805 dev_dbg(&pdev->dev, "%s is not ready, probe deferred\n", 806 AXP288_EXTCON_DEV_NAME); 807 return -EPROBE_DEFER; 808 } 809 810 info->otg.cable = extcon_get_extcon_dev(USB_HOST_EXTCON_DEV_NAME); 811 if (info->otg.cable == NULL) { 812 dev_dbg(dev, "EXTCON_USB_HOST is not ready, probe deferred\n"); 813 return -EPROBE_DEFER; 814 } 815 816 platform_set_drvdata(pdev, info); 817 mutex_init(&info->lock); 818 819 ret = charger_init_hw_regs(info); 820 if (ret) 821 return ret; 822 823 /* Register with power supply class */ 824 charger_cfg.drv_data = info; 825 info->psy_usb = devm_power_supply_register(dev, &axp288_charger_desc, 826 &charger_cfg); 827 if (IS_ERR(info->psy_usb)) { 828 ret = PTR_ERR(info->psy_usb); 829 dev_err(dev, "failed to register power supply: %d\n", ret); 830 return ret; 831 } 832 833 /* Register for extcon notification */ 834 INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker); 835 info->cable.nb[0].notifier_call = axp288_charger_handle_cable0_evt; 836 info->cable.nb[1].notifier_call = axp288_charger_handle_cable1_evt; 837 info->cable.nb[2].notifier_call = axp288_charger_handle_cable2_evt; 838 for (i = 0; i < ARRAY_SIZE(cable_ids); i++) { 839 ret = devm_extcon_register_notifier(dev, info->cable.edev, 840 cable_ids[i], &info->cable.nb[i]); 841 if (ret) { 842 dev_err(dev, "failed to register extcon notifier for %u: %d\n", 843 cable_ids[i], ret); 844 return ret; 845 } 846 } 847 schedule_work(&info->cable.work); 848 849 /* Register for OTG notification */ 850 INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker); 851 info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt; 852 ret = devm_extcon_register_notifier(&pdev->dev, info->otg.cable, 853 EXTCON_USB_HOST, &info->otg.id_nb); 854 if (ret) { 855 dev_err(dev, "failed to register EXTCON_USB_HOST notifier\n"); 856 return ret; 857 } 858 schedule_work(&info->otg.work); 859 860 /* Register charger interrupts */ 861 for (i = 0; i < CHRG_INTR_END; i++) { 862 pirq = platform_get_irq(info->pdev, i); 863 info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); 864 if (info->irq[i] < 0) { 865 dev_warn(&info->pdev->dev, 866 "failed to get virtual interrupt=%d\n", pirq); 867 return info->irq[i]; 868 } 869 ret = devm_request_threaded_irq(&info->pdev->dev, info->irq[i], 870 NULL, axp288_charger_irq_thread_handler, 871 IRQF_ONESHOT, info->pdev->name, info); 872 if (ret) { 873 dev_err(&pdev->dev, "failed to request interrupt=%d\n", 874 info->irq[i]); 875 return ret; 876 } 877 } 878 879 return 0; 880 } 881 882 static const struct platform_device_id axp288_charger_id_table[] = { 883 { .name = "axp288_charger" }, 884 {}, 885 }; 886 MODULE_DEVICE_TABLE(platform, axp288_charger_id_table); 887 888 static struct platform_driver axp288_charger_driver = { 889 .probe = axp288_charger_probe, 890 .id_table = axp288_charger_id_table, 891 .driver = { 892 .name = "axp288_charger", 893 }, 894 }; 895 896 module_platform_driver(axp288_charger_driver); 897 898 MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>"); 899 MODULE_DESCRIPTION("X-power AXP288 Charger Driver"); 900 MODULE_LICENSE("GPL v2"); 901