1 // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 /* 3 * Apple SMC Power/Battery Management Driver 4 * 5 * This driver exposes battery telemetry (voltage, current, temperature, health) 6 * and AC adapter status provided by the Apple SMC (System Management Controller) 7 * on Apple Silicon systems. 8 * 9 * Copyright The Asahi Linux Contributors 10 */ 11 12 #include <linux/ctype.h> 13 #include <linux/delay.h> 14 #include <linux/devm-helpers.h> 15 #include <linux/limits.h> 16 #include <linux/module.h> 17 #include <linux/mfd/macsmc.h> 18 #include <linux/notifier.h> 19 #include <linux/of.h> 20 #include <linux/platform_device.h> 21 #include <linux/power_supply.h> 22 #include <linux/reboot.h> 23 #include <linux/workqueue.h> 24 25 #define MAX_STRING_LENGTH 256 26 27 /* 28 * The SMC reports charge in mAh (Coulombs) but energy in mWh (Joules). 29 * We lack a register for "Nominal Voltage" or "Energy Accumulator". 30 * We use a fixed 3.8V/cell constant to approximate energy stats for userspace, 31 * derived from empirical data across supported MacBook models. 32 */ 33 #define MACSMC_NOMINAL_CELL_VOLTAGE_MV 3800 34 35 /* SMC Key Flags */ 36 #define CHNC_BATTERY_FULL BIT(0) 37 #define CHNC_NO_CHARGER BIT(7) 38 #define CHNC_NOCHG_CH0C BIT(14) 39 #define CHNC_NOCHG_CH0B_CH0K BIT(15) 40 #define CHNC_BATTERY_FULL_2 BIT(18) 41 #define CHNC_BMS_BUSY BIT(23) 42 #define CHNC_CHLS_LIMIT BIT(24) 43 #define CHNC_NOAC_CH0J BIT(53) 44 #define CHNC_NOAC_CH0I BIT(54) 45 46 #define CH0R_LOWER_FLAGS GENMASK(15, 0) 47 #define CH0R_NOAC_CH0I BIT(0) 48 #define CH0R_NOAC_DISCONNECTED BIT(4) 49 #define CH0R_NOAC_CH0J BIT(5) 50 #define CH0R_BMS_BUSY BIT(8) 51 #define CH0R_NOAC_CH0K BIT(9) 52 #define CH0R_NOAC_CHWA BIT(11) 53 54 #define CH0X_CH0C BIT(0) 55 #define CH0X_CH0B BIT(1) 56 57 #define ACSt_CAN_BOOT_AP BIT(2) 58 #define ACSt_CAN_BOOT_IBOOT BIT(1) 59 60 #define CHWA_CHLS_FIXED_START_OFFSET 5 61 #define CHLS_MIN_END_THRESHOLD 10 62 #define CHLS_FORCE_DISCHARGE 0x100 63 #define CHWA_FIXED_END_THRESHOLD 80 64 #define CHWA_PROP_WRITE_THRESHOLD 95 65 66 #define MACSMC_MAX_BATT_PROPS 50 67 #define MACSMC_MAX_AC_PROPS 10 68 69 struct macsmc_power { 70 struct device *dev; 71 struct apple_smc *smc; 72 73 struct power_supply_desc ac_desc; 74 struct power_supply_desc batt_desc; 75 76 struct power_supply *batt; 77 struct power_supply *ac; 78 79 char model_name[MAX_STRING_LENGTH]; 80 char serial_number[MAX_STRING_LENGTH]; 81 char mfg_date[MAX_STRING_LENGTH]; 82 83 /* Supported feature flags based on SMC key presence */ 84 bool has_chwa; /* Charge limit (Modern firmware) */ 85 bool has_chls; /* Charge limit (Older firmware) */ 86 bool has_ch0i; /* Force discharge (Older firmware) */ 87 bool has_ch0c; /* Inhibit charge (Older firmware) */ 88 bool has_chte; /* Inhibit charge (Modern firmware) */ 89 /* 90 * Battery critical key is 1 byte and charge key is little endian 91 * (Modern firmware) 92 */ 93 bool fw_ge_27; 94 95 u8 num_cells; 96 int nominal_voltage_mv; 97 98 struct notifier_block nb; 99 struct work_struct critical_work; 100 bool emergency_shutdown_triggered; 101 bool orderly_shutdown_triggered; 102 }; 103 104 static int macsmc_battery_get_status(struct macsmc_power *power) 105 { 106 u64 nocharge_flags; 107 u32 nopower_flags; 108 u16 ac_current; 109 int charge_limit = 0; 110 bool limited = false; 111 bool flag; 112 int ret; 113 114 /* 115 * B0AV (Voltage) is fundamental. If we can't read it, we assume the 116 * battery is gone. CHCE (Hardware charger present) / CHCC (Hardware 117 * charger capable) are fundamental status flags. 118 * BSFC (System full charge) / CHSC (System charging) are fundamental 119 * status flags. 120 */ 121 122 /* Check if power input is inhibited (e.g. BMS balancing cycle) */ 123 ret = apple_smc_read_u32(power->smc, SMC_KEY(CH0R), &nopower_flags); 124 if (!ret && (nopower_flags & CH0R_LOWER_FLAGS & ~CH0R_BMS_BUSY)) 125 return POWER_SUPPLY_STATUS_DISCHARGING; 126 127 /* Check if charger is present */ 128 ret = apple_smc_read_flag(power->smc, SMC_KEY(CHCE), &flag); 129 if (ret < 0) 130 return ret; 131 if (!flag) 132 return POWER_SUPPLY_STATUS_DISCHARGING; 133 134 /* Check if AC is charge capable */ 135 ret = apple_smc_read_flag(power->smc, SMC_KEY(CHCC), &flag); 136 if (ret < 0) 137 return ret; 138 if (!flag) 139 return POWER_SUPPLY_STATUS_DISCHARGING; 140 141 /* Check if AC input limit is too low */ 142 ret = apple_smc_read_u16(power->smc, SMC_KEY(AC-i), &ac_current); 143 if (!ret && ac_current < 100) 144 return POWER_SUPPLY_STATUS_DISCHARGING; 145 146 /* Check if battery is full */ 147 ret = apple_smc_read_flag(power->smc, SMC_KEY(BSFC), &flag); 148 if (ret < 0) 149 return ret; 150 if (flag) 151 return POWER_SUPPLY_STATUS_FULL; 152 153 /* Check for user-defined charge limits */ 154 if (power->has_chls) { 155 u16 vu16; 156 157 ret = apple_smc_read_u16(power->smc, SMC_KEY(CHLS), &vu16); 158 if (ret == 0 && (vu16 & 0xff) >= CHLS_MIN_END_THRESHOLD) 159 charge_limit = (vu16 & 0xff) - CHWA_CHLS_FIXED_START_OFFSET; 160 } else if (power->has_chwa) { 161 ret = apple_smc_read_flag(power->smc, SMC_KEY(CHWA), &flag); 162 if (ret == 0 && flag) 163 charge_limit = CHWA_FIXED_END_THRESHOLD - CHWA_CHLS_FIXED_START_OFFSET; 164 } 165 166 if (charge_limit > 0) { 167 u8 buic = 0; 168 169 if (apple_smc_read_u8(power->smc, SMC_KEY(BUIC), &buic) >= 0 && 170 buic >= charge_limit) 171 limited = true; 172 } 173 174 /* Check charging inhibitors */ 175 ret = apple_smc_read_u64(power->smc, SMC_KEY(CHNC), &nocharge_flags); 176 if (!ret) { 177 if (nocharge_flags & CHNC_BATTERY_FULL) 178 return POWER_SUPPLY_STATUS_FULL; 179 /* BMS busy shows up as inhibit, but we treat it as charging */ 180 else if (nocharge_flags == CHNC_BMS_BUSY && !limited) 181 return POWER_SUPPLY_STATUS_CHARGING; 182 else if (nocharge_flags) 183 return POWER_SUPPLY_STATUS_NOT_CHARGING; 184 else 185 return POWER_SUPPLY_STATUS_CHARGING; 186 } 187 188 /* Fallback: System charging flag */ 189 ret = apple_smc_read_flag(power->smc, SMC_KEY(CHSC), &flag); 190 if (ret < 0) 191 return ret; 192 if (!flag) 193 return POWER_SUPPLY_STATUS_NOT_CHARGING; 194 195 return POWER_SUPPLY_STATUS_CHARGING; 196 } 197 198 static int macsmc_battery_get_charge_behaviour(struct macsmc_power *power) 199 { 200 int ret; 201 u8 val8; 202 u8 chte_buf[4]; 203 204 if (power->has_ch0i) { 205 ret = apple_smc_read_u8(power->smc, SMC_KEY(CH0I), &val8); 206 if (ret) 207 return ret; 208 if (val8 & CH0R_NOAC_CH0I) 209 return POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE; 210 } 211 212 if (power->has_chte) { 213 ret = apple_smc_read(power->smc, SMC_KEY(CHTE), chte_buf, 4); 214 if (ret < 0) 215 return ret; 216 217 if (chte_buf[0] == 0x01) 218 return POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE; 219 } else if (power->has_ch0c) { 220 ret = apple_smc_read_u8(power->smc, SMC_KEY(CH0C), &val8); 221 if (ret) 222 return ret; 223 if (val8 & CH0X_CH0C) 224 return POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE; 225 } 226 227 return POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO; 228 } 229 230 static int macsmc_battery_set_charge_behaviour(struct macsmc_power *power, int val) 231 { 232 int ret; 233 234 switch (val) { 235 case POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO: 236 /* Reset all inhibitors to a known-good 'auto' state */ 237 if (power->has_ch0i) { 238 ret = apple_smc_write_u8(power->smc, SMC_KEY(CH0I), 0); 239 if (ret) 240 return ret; 241 } 242 243 if (power->has_chte) { 244 ret = apple_smc_write_u32(power->smc, SMC_KEY(CHTE), 0); 245 if (ret) 246 return ret; 247 } else if (power->has_ch0c) { 248 ret = apple_smc_write_u8(power->smc, SMC_KEY(CH0C), 0); 249 if (ret) 250 return ret; 251 } 252 return 0; 253 254 case POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE: 255 if (power->has_chte) 256 return apple_smc_write_u32(power->smc, SMC_KEY(CHTE), 1); 257 else if (power->has_ch0c) 258 return apple_smc_write_u8(power->smc, SMC_KEY(CH0C), 1); 259 else 260 return -EOPNOTSUPP; 261 262 case POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE: 263 if (!power->has_ch0i) 264 return -EOPNOTSUPP; 265 return apple_smc_write_u8(power->smc, SMC_KEY(CH0I), 1); 266 267 default: 268 return -EINVAL; 269 } 270 } 271 272 static int macsmc_battery_get_date(const char *s, int *out) 273 { 274 if (!isdigit(s[0]) || !isdigit(s[1])) 275 return -EOPNOTSUPP; 276 277 *out = (s[0] - '0') * 10 + s[1] - '0'; 278 return 0; 279 } 280 281 static int macsmc_battery_read_bcf0(struct macsmc_power *power, u32 *val) 282 { 283 u8 tval = 0; 284 int ret; 285 286 if (power->fw_ge_27) { 287 ret = apple_smc_read_u8(power->smc, SMC_KEY(BCF0), &tval); 288 *val = tval; 289 return ret; 290 } 291 292 return apple_smc_read_u32(power->smc, SMC_KEY(BCF0), val); 293 } 294 295 static int macsmc_battery_get_capacity_level(struct macsmc_power *power) 296 { 297 bool flag; 298 u32 val; 299 int ret; 300 301 /* Check for emergency shutdown condition */ 302 if (macsmc_battery_read_bcf0(power, &val) >= 0 && val) 303 return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; 304 305 /* Check AC status for whether we could boot in this state */ 306 if (apple_smc_read_u32(power->smc, SMC_KEY(ACSt), &val) >= 0) { 307 if (!(val & ACSt_CAN_BOOT_IBOOT)) 308 return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; 309 310 if (!(val & ACSt_CAN_BOOT_AP)) 311 return POWER_SUPPLY_CAPACITY_LEVEL_LOW; 312 } 313 314 /* BSFC = Battery System Full Charge */ 315 ret = apple_smc_read_flag(power->smc, SMC_KEY(BSFC), &flag); 316 if (ret < 0) 317 return POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; 318 319 if (flag) 320 return POWER_SUPPLY_CAPACITY_LEVEL_FULL; 321 else 322 return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; 323 } 324 325 static s16 macsmc_swap_b0rm(struct macsmc_power *power, s16 b0rm) 326 { 327 /* B0RM was Big Endian, likely pass through from TI gas gauge */ 328 return power->fw_ge_27 ? b0rm : (s16)swab16(b0rm); 329 } 330 331 static int macsmc_battery_get_property(struct power_supply *psy, 332 enum power_supply_property psp, 333 union power_supply_propval *val) 334 { 335 struct macsmc_power *power = power_supply_get_drvdata(psy); 336 int ret = 0; 337 u8 vu8; 338 u16 vu16; 339 s16 vs16; 340 s32 vs32; 341 s64 vs64; 342 bool flag; 343 344 switch (psp) { 345 case POWER_SUPPLY_PROP_STATUS: 346 val->intval = macsmc_battery_get_status(power); 347 ret = val->intval < 0 ? val->intval : 0; 348 break; 349 case POWER_SUPPLY_PROP_PRESENT: 350 val->intval = 1; 351 break; 352 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 353 val->intval = macsmc_battery_get_charge_behaviour(power); 354 ret = val->intval < 0 ? val->intval : 0; 355 break; 356 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: 357 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0TE), &vu16); 358 val->intval = vu16 == 0xffff ? 0 : vu16 * 60; 359 break; 360 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: 361 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0TF), &vu16); 362 val->intval = vu16 == 0xffff ? 0 : vu16 * 60; 363 break; 364 case POWER_SUPPLY_PROP_CAPACITY: 365 ret = apple_smc_read_u8(power->smc, SMC_KEY(BUIC), &vu8); 366 val->intval = vu8; 367 break; 368 case POWER_SUPPLY_PROP_CAPACITY_LEVEL: 369 val->intval = macsmc_battery_get_capacity_level(power); 370 ret = val->intval < 0 ? val->intval : 0; 371 break; 372 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 373 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0AV), &vu16); 374 val->intval = vu16 * 1000; 375 break; 376 case POWER_SUPPLY_PROP_CURRENT_NOW: 377 ret = apple_smc_read_s16(power->smc, SMC_KEY(B0AC), &vs16); 378 val->intval = vs16 * 1000; 379 break; 380 case POWER_SUPPLY_PROP_POWER_NOW: 381 ret = apple_smc_read_s32(power->smc, SMC_KEY(B0AP), &vs32); 382 val->intval = vs32 * 1000; 383 break; 384 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 385 ret = apple_smc_read_u16(power->smc, SMC_KEY(BITV), &vu16); 386 val->intval = vu16 * 1000; 387 break; 388 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 389 /* Calculate total max design voltage from per-cell maximum voltage */ 390 ret = apple_smc_read_u16(power->smc, SMC_KEY(BVVN), &vu16); 391 val->intval = vu16 * 1000 * power->num_cells; 392 break; 393 case POWER_SUPPLY_PROP_VOLTAGE_MIN: 394 /* Lifetime min */ 395 ret = apple_smc_read_s16(power->smc, SMC_KEY(BLPM), &vs16); 396 val->intval = vs16 * 1000; 397 break; 398 case POWER_SUPPLY_PROP_VOLTAGE_MAX: 399 /* Lifetime max */ 400 ret = apple_smc_read_s16(power->smc, SMC_KEY(BLPX), &vs16); 401 val->intval = vs16 * 1000; 402 break; 403 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 404 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0RC), &vu16); 405 val->intval = vu16 * 1000; 406 break; 407 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 408 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0RI), &vu16); 409 val->intval = vu16 * 1000; 410 break; 411 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 412 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0RV), &vu16); 413 val->intval = vu16 * 1000; 414 break; 415 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 416 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0DC), &vu16); 417 val->intval = vu16 * 1000; 418 break; 419 case POWER_SUPPLY_PROP_CHARGE_FULL: 420 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0FC), &vu16); 421 val->intval = vu16 * 1000; 422 break; 423 case POWER_SUPPLY_PROP_CHARGE_NOW: 424 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0RM), &vu16); 425 val->intval = macsmc_swap_b0rm(power, vu16) * 1000; 426 break; 427 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 428 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0DC), &vu16); 429 val->intval = vu16 * power->nominal_voltage_mv; 430 break; 431 case POWER_SUPPLY_PROP_ENERGY_FULL: 432 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0FC), &vu16); 433 val->intval = vu16 * power->nominal_voltage_mv; 434 break; 435 case POWER_SUPPLY_PROP_ENERGY_NOW: 436 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0RM), &vu16); 437 val->intval = macsmc_swap_b0rm(power, vu16) * power->nominal_voltage_mv; 438 break; 439 case POWER_SUPPLY_PROP_TEMP: 440 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0AT), &vu16); 441 val->intval = vu16 - 2732; /* Kelvin x10 to Celsius x10 */ 442 break; 443 case POWER_SUPPLY_PROP_CHARGE_COUNTER: 444 ret = apple_smc_read_s64(power->smc, SMC_KEY(BAAC), &vs64); 445 val->intval = vs64; 446 break; 447 case POWER_SUPPLY_PROP_CYCLE_COUNT: 448 ret = apple_smc_read_u16(power->smc, SMC_KEY(B0CT), &vu16); 449 val->intval = vu16; 450 break; 451 case POWER_SUPPLY_PROP_SCOPE: 452 val->intval = POWER_SUPPLY_SCOPE_SYSTEM; 453 break; 454 case POWER_SUPPLY_PROP_HEALTH: 455 flag = false; 456 ret = apple_smc_read_flag(power->smc, SMC_KEY(BBAD), &flag); 457 val->intval = flag ? POWER_SUPPLY_HEALTH_DEAD : POWER_SUPPLY_HEALTH_GOOD; 458 break; 459 case POWER_SUPPLY_PROP_MODEL_NAME: 460 val->strval = power->model_name; 461 break; 462 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 463 val->strval = power->serial_number; 464 break; 465 case POWER_SUPPLY_PROP_MANUFACTURE_YEAR: 466 ret = macsmc_battery_get_date(&power->mfg_date[0], &val->intval); 467 /* The SMC reports the manufacture year as an offset from 1992. */ 468 val->intval += 1992; 469 break; 470 case POWER_SUPPLY_PROP_MANUFACTURE_MONTH: 471 ret = macsmc_battery_get_date(&power->mfg_date[2], &val->intval); 472 break; 473 case POWER_SUPPLY_PROP_MANUFACTURE_DAY: 474 ret = macsmc_battery_get_date(&power->mfg_date[4], &val->intval); 475 break; 476 default: 477 return -EINVAL; 478 } 479 480 return ret; 481 } 482 483 static int macsmc_battery_set_property(struct power_supply *psy, 484 enum power_supply_property psp, 485 const union power_supply_propval *val) 486 { 487 struct macsmc_power *power = power_supply_get_drvdata(psy); 488 489 switch (psp) { 490 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 491 return macsmc_battery_set_charge_behaviour(power, val->intval); 492 default: 493 return -EINVAL; 494 } 495 } 496 497 static int macsmc_battery_property_is_writeable(struct power_supply *psy, 498 enum power_supply_property psp) 499 { 500 switch (psp) { 501 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 502 return true; 503 default: 504 return false; 505 } 506 } 507 508 static const struct power_supply_desc macsmc_battery_desc_template = { 509 .name = "macsmc-battery", 510 .type = POWER_SUPPLY_TYPE_BATTERY, 511 .get_property = macsmc_battery_get_property, 512 .set_property = macsmc_battery_set_property, 513 .property_is_writeable = macsmc_battery_property_is_writeable, 514 }; 515 516 static int macsmc_ac_get_property(struct power_supply *psy, 517 enum power_supply_property psp, 518 union power_supply_propval *val) 519 { 520 struct macsmc_power *power = power_supply_get_drvdata(psy); 521 int ret = 0; 522 u16 vu16; 523 u32 vu32; 524 525 switch (psp) { 526 case POWER_SUPPLY_PROP_ONLINE: 527 ret = apple_smc_read_u32(power->smc, SMC_KEY(CHIS), &vu32); 528 val->intval = !!vu32; 529 break; 530 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 531 ret = apple_smc_read_u16(power->smc, SMC_KEY(AC-n), &vu16); 532 val->intval = vu16 * 1000; 533 break; 534 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 535 ret = apple_smc_read_u16(power->smc, SMC_KEY(AC-i), &vu16); 536 val->intval = vu16 * 1000; 537 break; 538 case POWER_SUPPLY_PROP_INPUT_POWER_LIMIT: 539 ret = apple_smc_read_u32(power->smc, SMC_KEY(ACPW), &vu32); 540 val->intval = vu32 * 1000; 541 break; 542 default: 543 return -EINVAL; 544 } 545 546 return ret; 547 } 548 549 static const struct power_supply_desc macsmc_ac_desc_template = { 550 .name = "macsmc-ac", 551 .type = POWER_SUPPLY_TYPE_MAINS, 552 .get_property = macsmc_ac_get_property, 553 }; 554 555 static void macsmc_power_critical_work(struct work_struct *wrk) 556 { 557 struct macsmc_power *power = container_of(wrk, struct macsmc_power, critical_work); 558 u16 bitv, b0av; 559 u32 bcf0; 560 561 if (!power->batt) 562 return; 563 564 /* 565 * Avoid duplicate atempts at emergency shutdown 566 */ 567 if (power->emergency_shutdown_triggered || system_state > SYSTEM_RUNNING) 568 return; 569 570 /* 571 * EMERGENCY: Check voltage vs design minimum. 572 * If we are below BITV, the battery is physically exhausted. 573 * We must shut down NOW to protect the filesystem. 574 */ 575 if (apple_smc_read_u16(power->smc, SMC_KEY(BITV), &bitv) >= 0 && 576 apple_smc_read_u16(power->smc, SMC_KEY(B0AV), &b0av) >= 0 && 577 b0av < bitv) { 578 power->emergency_shutdown_triggered = true; 579 dev_emerg(power->dev, 580 "Battery voltage (%d mV) below design minimum (%d mV)! Emergency shutdown.\n", 581 b0av, bitv); 582 583 /* 584 * Shutdown is now imminent. Kick userspace again and give it some 585 * brief time to (hopefully) flush what's needed, before forcing. 586 */ 587 hw_protection_trigger("Battery voltage below design minimum", 1500); 588 } 589 590 /* 591 * Avoid duplicate attempts at orderly shutdown. 592 * Voltage check is above this as we may want to 593 * "upgrade" an orderly shutdown to a critical power 594 * off if voltage drops. 595 */ 596 if (power->orderly_shutdown_triggered || system_state > SYSTEM_RUNNING) 597 return; 598 599 /* 600 * Check if SMC flagged the battery as empty. 601 * We trigger a graceful shutdown to let the OS save data. 602 */ 603 if (macsmc_battery_read_bcf0(power, &bcf0) == 0 && bcf0 != 0) { 604 power->orderly_shutdown_triggered = true; 605 dev_crit(power->dev, "Battery critical (empty flag set). Triggering orderly shutdown.\n"); 606 orderly_poweroff(true); 607 } 608 } 609 610 static int macsmc_power_event(struct notifier_block *nb, unsigned long event, void *data) 611 { 612 struct macsmc_power *power = container_of(nb, struct macsmc_power, nb); 613 614 /* 615 * SMC Event IDs are correlated to physical events (e.g. charger 616 * connect/disconnect) but the exact meaning of each ID is predicted. 617 * 0x71... indicates power/battery events. 618 */ 619 if ((event & 0xffffff00) == 0x71010100 || /* Charger status change */ 620 (event & 0xffff0000) == 0x71060000 || /* Port charge state change */ 621 (event & 0xffff0000) == 0x71130000) { /* Connector insert/remove event */ 622 if (power->batt) 623 power_supply_changed(power->batt); 624 if (power->ac) 625 power_supply_changed(power->ac); 626 return NOTIFY_OK; 627 } else if (event == 0x71020000) { 628 /* Critical battery warning */ 629 if (power->batt) 630 schedule_work(&power->critical_work); 631 return NOTIFY_OK; 632 } 633 634 return NOTIFY_DONE; 635 } 636 637 static int macsmc_power_probe(struct platform_device *pdev) 638 { 639 struct device *dev = &pdev->dev; 640 struct apple_smc *smc = dev_get_drvdata(pdev->dev.parent); 641 struct power_supply_config psy_cfg = {}; 642 struct apple_smc_key_info info; 643 struct macsmc_power *power; 644 bool has_battery = false; 645 bool has_ac_adapter = false; 646 int ret = -ENODEV; 647 bool flag; 648 u16 vu16; 649 u32 val32; 650 enum power_supply_property *props; 651 size_t nprops; 652 653 if (!smc) 654 return -ENODEV; 655 656 power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL); 657 if (!power) 658 return -ENOMEM; 659 660 power->dev = dev; 661 power->smc = smc; 662 dev_set_drvdata(dev, power); 663 664 INIT_WORK(&power->critical_work, macsmc_power_critical_work); 665 ret = devm_work_autocancel(dev, &power->critical_work, macsmc_power_critical_work); 666 if (ret) 667 return ret; 668 669 /* 670 * Check for battery presence. 671 * B0AV is a fundamental key. 672 */ 673 if (apple_smc_read_u16(power->smc, SMC_KEY(B0AV), &vu16) == 0 && 674 macsmc_battery_get_status(power) > POWER_SUPPLY_STATUS_UNKNOWN) 675 has_battery = true; 676 677 /* 678 * Check for AC adapter presence. 679 * CHIS is a fundamental key. 680 */ 681 if (apple_smc_key_exists(smc, SMC_KEY(CHIS))) 682 has_ac_adapter = true; 683 684 if (!has_battery && !has_ac_adapter) 685 return -ENODEV; 686 687 if (has_battery) { 688 power->batt_desc = macsmc_battery_desc_template; 689 props = devm_kcalloc(dev, MACSMC_MAX_BATT_PROPS, 690 sizeof(enum power_supply_property), 691 GFP_KERNEL); 692 if (!props) 693 return -ENOMEM; 694 695 nprops = 0; 696 697 /* Fundamental properties */ 698 props[nprops++] = POWER_SUPPLY_PROP_STATUS; 699 props[nprops++] = POWER_SUPPLY_PROP_PRESENT; 700 props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_NOW; 701 props[nprops++] = POWER_SUPPLY_PROP_CURRENT_NOW; 702 props[nprops++] = POWER_SUPPLY_PROP_POWER_NOW; 703 props[nprops++] = POWER_SUPPLY_PROP_CAPACITY; 704 props[nprops++] = POWER_SUPPLY_PROP_CAPACITY_LEVEL; 705 props[nprops++] = POWER_SUPPLY_PROP_TEMP; 706 props[nprops++] = POWER_SUPPLY_PROP_CYCLE_COUNT; 707 props[nprops++] = POWER_SUPPLY_PROP_HEALTH; 708 props[nprops++] = POWER_SUPPLY_PROP_SCOPE; 709 props[nprops++] = POWER_SUPPLY_PROP_MODEL_NAME; 710 props[nprops++] = POWER_SUPPLY_PROP_SERIAL_NUMBER; 711 props[nprops++] = POWER_SUPPLY_PROP_MANUFACTURE_YEAR; 712 props[nprops++] = POWER_SUPPLY_PROP_MANUFACTURE_MONTH; 713 props[nprops++] = POWER_SUPPLY_PROP_MANUFACTURE_DAY; 714 715 /* Extended properties usually present */ 716 props[nprops++] = POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW; 717 props[nprops++] = POWER_SUPPLY_PROP_TIME_TO_FULL_NOW; 718 props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN; 719 props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN; 720 props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MIN; 721 props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_MAX; 722 props[nprops++] = POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT; 723 props[nprops++] = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; 724 props[nprops++] = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE; 725 props[nprops++] = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; 726 props[nprops++] = POWER_SUPPLY_PROP_CHARGE_FULL; 727 props[nprops++] = POWER_SUPPLY_PROP_CHARGE_NOW; 728 props[nprops++] = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; 729 props[nprops++] = POWER_SUPPLY_PROP_ENERGY_FULL; 730 props[nprops++] = POWER_SUPPLY_PROP_ENERGY_NOW; 731 props[nprops++] = POWER_SUPPLY_PROP_CHARGE_COUNTER; 732 733 /* Detect features based on key availability */ 734 if (apple_smc_key_exists(smc, SMC_KEY(CHTE))) 735 power->has_chte = true; 736 if (apple_smc_key_exists(smc, SMC_KEY(CH0C))) 737 power->has_ch0c = true; 738 if (apple_smc_key_exists(smc, SMC_KEY(CH0I))) 739 power->has_ch0i = true; 740 741 ret = apple_smc_get_key_info(power->smc, SMC_KEY(BCF0), &info); 742 if (ret) { 743 dev_err(&pdev->dev, "Failed to determine BCF0 key size\n"); 744 return ret; 745 } 746 if (info.size == 1) 747 power->fw_ge_27 = true; 748 else if (info.size == 4) 749 power->fw_ge_27 = false; 750 else { 751 dev_err(&pdev->dev, "Unexpected BCF0 key size %d\n", info.size); 752 return -EIO; 753 } 754 755 /* Reset "Optimised Battery Charging" flags to default state */ 756 if (power->has_chte) 757 apple_smc_write_u32(smc, SMC_KEY(CHTE), 0); 758 else if (power->has_ch0c) 759 apple_smc_write_u8(smc, SMC_KEY(CH0C), 0); 760 761 if (power->has_ch0i) 762 apple_smc_write_u8(smc, SMC_KEY(CH0I), 0); 763 764 apple_smc_write_u8(smc, SMC_KEY(CH0K), 0); 765 apple_smc_write_u8(smc, SMC_KEY(CH0B), 0); 766 767 /* Configure charge behaviour if supported */ 768 if (power->has_ch0i || power->has_ch0c || power->has_chte) { 769 props[nprops++] = POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR; 770 771 power->batt_desc.charge_behaviours = 772 BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO); 773 774 if (power->has_ch0i) 775 power->batt_desc.charge_behaviours |= 776 BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE); 777 778 if (power->has_chte || power->has_ch0c) 779 power->batt_desc.charge_behaviours |= 780 BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE); 781 } 782 783 /* Detect charge limit method (CHWA vs CHLS) */ 784 if (apple_smc_read_flag(power->smc, SMC_KEY(CHWA), &flag) == 0) 785 power->has_chwa = true; 786 else if (apple_smc_read_u16(power->smc, SMC_KEY(CHLS), &vu16) >= 0) 787 power->has_chls = true; 788 789 if (nprops > MACSMC_MAX_BATT_PROPS) 790 return -ENOMEM; 791 792 power->batt_desc.properties = props; 793 power->batt_desc.num_properties = nprops; 794 795 /* Fetch identity strings */ 796 apple_smc_read(smc, SMC_KEY(BMDN), power->model_name, 797 sizeof(power->model_name) - 1); 798 apple_smc_read(smc, SMC_KEY(BMSN), power->serial_number, 799 sizeof(power->serial_number) - 1); 800 apple_smc_read(smc, SMC_KEY(BMDT), power->mfg_date, 801 sizeof(power->mfg_date) - 1); 802 803 apple_smc_read_u8(power->smc, SMC_KEY(BNCB), &power->num_cells); 804 power->nominal_voltage_mv = MACSMC_NOMINAL_CELL_VOLTAGE_MV * power->num_cells; 805 806 /* Enable critical shutdown notifications by reading status once */ 807 macsmc_battery_read_bcf0(power, &val32); 808 809 psy_cfg.drv_data = power; 810 power->batt = devm_power_supply_register(dev, &power->batt_desc, &psy_cfg); 811 if (IS_ERR(power->batt)) { 812 dev_err_probe(dev, PTR_ERR(power->batt), 813 "Failed to register battery\n"); 814 /* Don't return failure yet; try AC registration first */ 815 power->batt = NULL; 816 } 817 } 818 819 if (has_ac_adapter) { 820 power->ac_desc = macsmc_ac_desc_template; 821 props = devm_kcalloc(dev, MACSMC_MAX_AC_PROPS, 822 sizeof(enum power_supply_property), 823 GFP_KERNEL); 824 if (!props) 825 return -ENOMEM; 826 827 nprops = 0; 828 829 /* Online status is fundamental */ 830 props[nprops++] = POWER_SUPPLY_PROP_ONLINE; 831 832 /* Input power limits are usually available */ 833 if (apple_smc_key_exists(power->smc, SMC_KEY(ACPW))) 834 props[nprops++] = POWER_SUPPLY_PROP_INPUT_POWER_LIMIT; 835 836 /* macOS 15.4+ firmware dropped legacy AC keys (AC-n, AC-i) */ 837 if (apple_smc_read_u16(power->smc, SMC_KEY(AC-n), &vu16) >= 0) { 838 props[nprops++] = POWER_SUPPLY_PROP_VOLTAGE_NOW; 839 props[nprops++] = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT; 840 } 841 842 if (nprops > MACSMC_MAX_AC_PROPS) 843 return -ENOMEM; 844 845 power->ac_desc.properties = props; 846 power->ac_desc.num_properties = nprops; 847 848 psy_cfg.drv_data = power; 849 power->ac = devm_power_supply_register(dev, &power->ac_desc, &psy_cfg); 850 if (IS_ERR(power->ac)) { 851 dev_err_probe(dev, PTR_ERR(power->ac), 852 "Failed to register AC adapter\n"); 853 power->ac = NULL; 854 } 855 } 856 857 /* Final check: did we register anything? */ 858 if (!power->batt && !power->ac) 859 return -ENODEV; 860 861 power->nb.notifier_call = macsmc_power_event; 862 blocking_notifier_chain_register(&smc->event_handlers, &power->nb); 863 864 return 0; 865 } 866 867 static void macsmc_power_remove(struct platform_device *pdev) 868 { 869 struct macsmc_power *power = dev_get_drvdata(&pdev->dev); 870 871 blocking_notifier_chain_unregister(&power->smc->event_handlers, &power->nb); 872 } 873 874 static const struct platform_device_id macsmc_power_id[] = { 875 { .name = "macsmc-power" }, 876 { /* sentinel */ } 877 }; 878 MODULE_DEVICE_TABLE(platform, macsmc_power_id); 879 880 static struct platform_driver macsmc_power_driver = { 881 .driver = { 882 .name = "macsmc-power", 883 }, 884 .id_table = macsmc_power_id, 885 .probe = macsmc_power_probe, 886 .remove = macsmc_power_remove, 887 }; 888 module_platform_driver(macsmc_power_driver); 889 890 MODULE_LICENSE("Dual MIT/GPL"); 891 MODULE_DESCRIPTION("Apple SMC battery and power management driver"); 892 MODULE_AUTHOR("Hector Martin <marcan@marcan.st>"); 893 MODULE_AUTHOR("Michael Reeves <michael.reeves077@gmail.com>"); 894