2020struct macsmc_power {
2121 struct device * dev ;
2222 struct apple_smc * smc ;
23+ struct power_supply_desc batt_desc ;
2324
2425 struct power_supply * batt ;
2526 char model_name [MAX_STRING_LENGTH ];
2627 char serial_number [MAX_STRING_LENGTH ];
2728 char mfg_date [MAX_STRING_LENGTH ];
29+ bool has_chwa ;
2830
2931 struct power_supply * ac ;
3032
@@ -62,16 +64,22 @@ static struct macsmc_power *g_power;
6264
6365#define CH0R_LOWER_FLAGS GENMASK(15, 0)
6466#define CH0R_NOAC_CH0I BIT(0)
67+ #define CH0R_NOAC_DISCONNECTED BIT(4)
6568#define CH0R_NOAC_CH0J BIT(5)
6669#define CH0R_BMS_BUSY BIT(8)
6770#define CH0R_NOAC_CH0K BIT(9)
71+ #define CH0R_NOAC_CHWA BIT(11)
6872
6973#define CH0X_CH0C BIT(0)
7074#define CH0X_CH0B BIT(1)
7175
7276#define ACSt_CAN_BOOT_AP BIT(2)
7377#define ACSt_CAN_BOOT_IBOOT BIT(1)
7478
79+ #define CHWA_FIXED_START_THRESHOLD 75
80+ #define CHWA_FIXED_END_THRESHOLD 80
81+ #define CHWA_PROP_WRITE_THRESHOLD 95
82+
7583static void macsmc_do_dbg (struct macsmc_power * power )
7684{
7785 int p_in = 0 , p_sys = 0 , p_3v8 = 0 , p_mpmu = 0 , p_spmu = 0 , p_clvr = 0 , p_cpu = 0 ;
@@ -107,6 +115,7 @@ static int macsmc_battery_get_status(struct macsmc_power *power)
107115 u64 nocharge_flags ;
108116 u32 nopower_flags ;
109117 u16 ac_current ;
118+ bool chwa_limit = false;
110119 int ret ;
111120
112121 /*
@@ -153,14 +162,29 @@ static int macsmc_battery_get_status(struct macsmc_power *power)
153162 else if (ret )
154163 return POWER_SUPPLY_STATUS_FULL ;
155164
165+ /*
166+ * If we have charge limits supported and enabled and the SoC is > 75%,
167+ * that means we are not charging for that reason (if not charging).
168+ */
169+ if (power -> has_chwa && apple_smc_read_flag (power -> smc , SMC_KEY (CHWA )) == 1 ) {
170+ u8 buic = 0 ;
171+
172+ if (apple_smc_read_u8 (power -> smc , SMC_KEY (BUIC ), & buic ) >= 0 &&
173+ buic >= CHWA_FIXED_START_THRESHOLD )
174+ chwa_limit = true;
175+ }
176+
156177 /* If there are reasons we aren't charging... */
157178 ret = apple_smc_read_u64 (power -> smc , SMC_KEY (CHNC ), & nocharge_flags );
158179 if (!ret ) {
159180 /* Perhaps the battery is full after all */
160181 if (nocharge_flags & CHNC_BATTERY_FULL )
161182 return POWER_SUPPLY_STATUS_FULL ;
162- /* Or maybe the BMS is just busy doing something, if so call it charging anyway */
163- else if (nocharge_flags == CHNC_BMS_BUSY )
183+ /*
184+ * Or maybe the BMS is just busy doing something, if so call it charging anyway.
185+ * But CHWA limits show up as this, so exclude those.
186+ */
187+ else if (nocharge_flags == CHNC_BMS_BUSY && !chwa_limit )
164188 return POWER_SUPPLY_STATUS_CHARGING ;
165189 /* If we have other reasons we aren't charging, say we aren't */
166190 else if (nocharge_flags )
@@ -393,6 +417,16 @@ static int macsmc_battery_get_property(struct power_supply *psy,
393417 case POWER_SUPPLY_PROP_MANUFACTURE_DAY :
394418 ret = macsmc_battery_get_date (& power -> mfg_date [4 ], & val -> intval );
395419 break ;
420+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD :
421+ ret = apple_smc_read_flag (power -> smc , SMC_KEY (CHWA ));
422+ val -> intval = ret == 1 ? CHWA_FIXED_START_THRESHOLD : 100 ;
423+ ret = ret < 0 ? ret : 0 ;
424+ break ;
425+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD :
426+ ret = apple_smc_read_flag (power -> smc , SMC_KEY (CHWA ));
427+ val -> intval = ret == 1 ? CHWA_FIXED_END_THRESHOLD : 100 ;
428+ ret = ret < 0 ? ret : 0 ;
429+ break ;
396430 default :
397431 return - EINVAL ;
398432 }
@@ -409,6 +443,16 @@ static int macsmc_battery_set_property(struct power_supply *psy,
409443 switch (psp ) {
410444 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR :
411445 return macsmc_battery_set_charge_behaviour (power , val -> intval );
446+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD :
447+ /*
448+ * Ignore, we allow writes so userspace isn't confused but this is
449+ * not configurable independently, it always is 75 or 100 depending
450+ * on the end_threshold boolean setting.
451+ */
452+ return 0 ;
453+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD :
454+ return apple_smc_write_flag (power -> smc , SMC_KEY (CHWA ),
455+ val -> intval <= CHWA_PROP_WRITE_THRESHOLD );
412456 default :
413457 return - EINVAL ;
414458 }
@@ -417,15 +461,20 @@ static int macsmc_battery_set_property(struct power_supply *psy,
417461static int macsmc_battery_property_is_writeable (struct power_supply * psy ,
418462 enum power_supply_property psp )
419463{
464+ struct macsmc_power * power = power_supply_get_drvdata (psy );
465+
420466 switch (psp ) {
421467 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR :
422468 return true;
469+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD :
470+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD :
471+ return power -> has_chwa ;
423472 default :
424473 return false;
425474 }
426475}
427476
428- static enum power_supply_property macsmc_battery_props [] = {
477+ static const enum power_supply_property macsmc_battery_props [] = {
429478 POWER_SUPPLY_PROP_STATUS ,
430479 POWER_SUPPLY_PROP_PRESENT ,
431480 POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR ,
@@ -454,6 +503,8 @@ static enum power_supply_property macsmc_battery_props[] = {
454503 POWER_SUPPLY_PROP_MANUFACTURE_YEAR ,
455504 POWER_SUPPLY_PROP_MANUFACTURE_MONTH ,
456505 POWER_SUPPLY_PROP_MANUFACTURE_DAY ,
506+ POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD ,
507+ POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD
457508};
458509
459510static const struct power_supply_desc macsmc_battery_desc = {
@@ -651,6 +702,7 @@ static int macsmc_power_probe(struct platform_device *pdev)
651702
652703 power -> dev = & pdev -> dev ;
653704 power -> smc = smc ;
705+ power -> batt_desc = macsmc_battery_desc ;
654706 dev_set_drvdata (& pdev -> dev , power );
655707
656708 /* Ignore devices without a charger/battery */
@@ -666,11 +718,18 @@ static int macsmc_power_probe(struct platform_device *pdev)
666718 apple_smc_write_u8 (power -> smc , SMC_KEY (CH0K ), 0 );
667719 apple_smc_write_u8 (power -> smc , SMC_KEY (CH0B ), 0 );
668720
721+ if (apple_smc_read_flag (power -> smc , SMC_KEY (CHWA )) >= 0 ) {
722+ power -> has_chwa = true;
723+ } else {
724+ /* Remove the last 2 properties that control the charge threshold */
725+ power -> batt_desc .num_properties -= 2 ;
726+ }
727+
669728 /* Doing one read of this flag enables critical shutdown notifications */
670729 apple_smc_read_u32 (power -> smc , SMC_KEY (BCF0 ), & val );
671730
672731 psy_cfg .drv_data = power ;
673- power -> batt = devm_power_supply_register (& pdev -> dev , & macsmc_battery_desc , & psy_cfg );
732+ power -> batt = devm_power_supply_register (& pdev -> dev , & power -> batt_desc , & psy_cfg );
674733 if (IS_ERR (power -> batt )) {
675734 dev_err (& pdev -> dev , "Failed to register battery\n" );
676735 ret = PTR_ERR (power -> batt );
0 commit comments