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