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