@@ -38,6 +38,7 @@ struct macsmc_power {
3838 char serial_number [MAX_STRING_LENGTH ];
3939 char mfg_date [MAX_STRING_LENGTH ];
4040 bool has_chwa ;
41+ bool has_chls ;
4142 u8 num_cells ;
4243 int nominal_voltage_mv ;
4344
@@ -72,6 +73,7 @@ static struct macsmc_power *g_power;
7273#define CHNC_NOCHG_CH0B_CH0K BIT(15)
7374#define CHNC_BATTERY_FULL_2 BIT(18)
7475#define CHNC_BMS_BUSY BIT(23)
76+ #define CHNC_CHLS_LIMIT BIT(24)
7577#define CHNC_NOAC_CH0J BIT(53)
7678#define CHNC_NOAC_CH0I BIT(54)
7779
@@ -89,7 +91,9 @@ static struct macsmc_power *g_power;
8991#define ACSt_CAN_BOOT_AP BIT(2)
9092#define ACSt_CAN_BOOT_IBOOT BIT(1)
9193
92- #define CHWA_FIXED_START_THRESHOLD 75
94+ #define CHWA_CHLS_FIXED_START_OFFSET 5
95+ #define CHLS_MIN_END_THRESHOLD 10
96+ #define CHLS_FORCE_DISCHARGE 0x100
9397#define CHWA_FIXED_END_THRESHOLD 80
9498#define CHWA_PROP_WRITE_THRESHOLD 95
9599
@@ -183,7 +187,7 @@ static int macsmc_battery_get_status(struct macsmc_power *power)
183187 u8 buic = 0 ;
184188
185189 if (apple_smc_read_u8 (power -> smc , SMC_KEY (BUIC ), & buic ) >= 0 &&
186- buic >= CHWA_FIXED_START_THRESHOLD )
190+ buic >= ( CHWA_FIXED_END_THRESHOLD - CHWA_CHLS_FIXED_START_OFFSET ) )
187191 chwa_limit = true;
188192 }
189193
@@ -465,14 +469,23 @@ static int macsmc_battery_get_property(struct power_supply *psy,
465469 ret = macsmc_battery_get_date (& power -> mfg_date [4 ], & val -> intval );
466470 break ;
467471 case POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD :
468- ret = apple_smc_read_flag (power -> smc , SMC_KEY (CHWA ));
469- val -> intval = ret == 1 ? CHWA_FIXED_START_THRESHOLD : 100 ;
470- ret = ret < 0 ? ret : 0 ;
471- break ;
472472 case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD :
473- ret = apple_smc_read_flag (power -> smc , SMC_KEY (CHWA ));
474- val -> intval = ret == 1 ? CHWA_FIXED_END_THRESHOLD : 100 ;
475- ret = ret < 0 ? ret : 0 ;
473+ if (power -> has_chls ) {
474+ ret = apple_smc_read_u16 (power -> smc , SMC_KEY (CHLS ), & vu16 );
475+ val -> intval = vu16 & 0xff ;
476+ if (val -> intval < CHLS_MIN_END_THRESHOLD || val -> intval >= 100 )
477+ val -> intval = 100 ;
478+ }
479+ else if (power -> has_chwa ) {
480+ ret = apple_smc_read_flag (power -> smc , SMC_KEY (CHWA ));
481+ val -> intval = ret == 1 ? CHWA_FIXED_END_THRESHOLD : 100 ;
482+ ret = ret < 0 ? ret : 0 ;
483+ } else {
484+ return - EINVAL ;
485+ }
486+ if (psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD &&
487+ ret >= 0 && val -> intval < 100 && val -> intval >= CHLS_MIN_END_THRESHOLD )
488+ val -> intval -= CHWA_CHLS_FIXED_START_OFFSET ;
476489 break ;
477490 default :
478491 return - EINVAL ;
@@ -493,13 +506,25 @@ static int macsmc_battery_set_property(struct power_supply *psy,
493506 case POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD :
494507 /*
495508 * Ignore, we allow writes so userspace isn't confused but this is
496- * not configurable independently, it always is 75 or 100 depending
497- * on the end_threshold boolean setting.
509+ * not configurable independently, it always is end - 5 or 100 depending
510+ * on the end_threshold setting.
498511 */
499512 return 0 ;
500513 case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD :
501- return apple_smc_write_flag (power -> smc , SMC_KEY (CHWA ),
502- val -> intval <= CHWA_PROP_WRITE_THRESHOLD );
514+ if (power -> has_chls ) {
515+ u16 kval = 0 ;
516+ /* TODO: Make CHLS_FORCE_DISCHARGE configurable */
517+ if (val -> intval < CHLS_MIN_END_THRESHOLD )
518+ kval = CHLS_FORCE_DISCHARGE | CHLS_MIN_END_THRESHOLD ;
519+ else if (val -> intval < 100 )
520+ kval = CHLS_FORCE_DISCHARGE | (val -> intval & 0xff );
521+ return apple_smc_write_u16 (power -> smc , SMC_KEY (CHLS ), kval );
522+ } else if (power -> has_chwa ) {
523+ return apple_smc_write_flag (power -> smc , SMC_KEY (CHWA ),
524+ val -> intval <= CHWA_PROP_WRITE_THRESHOLD );
525+ } else {
526+ return - EINVAL ;
527+ }
503528 default :
504529 return - EINVAL ;
505530 }
@@ -515,7 +540,7 @@ static int macsmc_battery_property_is_writeable(struct power_supply *psy,
515540 return true;
516541 case POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD :
517542 case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD :
518- return power -> has_chwa ;
543+ return power -> has_chwa || power -> has_chls ;
519544 default :
520545 return false;
521546 }
@@ -750,6 +775,7 @@ static int macsmc_power_probe(struct platform_device *pdev)
750775 struct power_supply_config psy_cfg = {};
751776 struct macsmc_power * power ;
752777 u32 val ;
778+ u16 vu16 ;
753779 int ret ;
754780
755781 power = devm_kzalloc (& pdev -> dev , sizeof (* power ), GFP_KERNEL );
@@ -774,8 +800,14 @@ static int macsmc_power_probe(struct platform_device *pdev)
774800 apple_smc_write_u8 (power -> smc , SMC_KEY (CH0K ), 0 );
775801 apple_smc_write_u8 (power -> smc , SMC_KEY (CH0B ), 0 );
776802
803+ /*
804+ * Prefer CHWA as the SMC firmware from iBoot-10151.1.1 is not compatible with
805+ * this CHLS usage.
806+ */
777807 if (apple_smc_read_flag (power -> smc , SMC_KEY (CHWA )) >= 0 ) {
778808 power -> has_chwa = true;
809+ } else if (apple_smc_read_u16 (power -> smc , SMC_KEY (CHLS ), & vu16 ) >= 0 ) {
810+ power -> has_chls = true;
779811 } else {
780812 /* Remove the last 2 properties that control the charge threshold */
781813 power -> batt_desc .num_properties -= 2 ;
0 commit comments