20
20
struct macsmc_power {
21
21
struct device * dev ;
22
22
struct apple_smc * smc ;
23
+ struct power_supply_desc batt_desc ;
23
24
24
25
struct power_supply * batt ;
25
26
char model_name [MAX_STRING_LENGTH ];
26
27
char serial_number [MAX_STRING_LENGTH ];
27
28
char mfg_date [MAX_STRING_LENGTH ];
29
+ bool has_chwa ;
28
30
29
31
struct power_supply * ac ;
30
32
@@ -62,16 +64,22 @@ static struct macsmc_power *g_power;
62
64
63
65
#define CH0R_LOWER_FLAGS GENMASK(15, 0)
64
66
#define CH0R_NOAC_CH0I BIT(0)
67
+ #define CH0R_NOAC_DISCONNECTED BIT(4)
65
68
#define CH0R_NOAC_CH0J BIT(5)
66
69
#define CH0R_BMS_BUSY BIT(8)
67
70
#define CH0R_NOAC_CH0K BIT(9)
71
+ #define CH0R_NOAC_CHWA BIT(11)
68
72
69
73
#define CH0X_CH0C BIT(0)
70
74
#define CH0X_CH0B BIT(1)
71
75
72
76
#define ACSt_CAN_BOOT_AP BIT(2)
73
77
#define ACSt_CAN_BOOT_IBOOT BIT(1)
74
78
79
+ #define CHWA_FIXED_START_THRESHOLD 75
80
+ #define CHWA_FIXED_END_THRESHOLD 80
81
+ #define CHWA_PROP_WRITE_THRESHOLD 95
82
+
75
83
static void macsmc_do_dbg (struct macsmc_power * power )
76
84
{
77
85
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)
107
115
u64 nocharge_flags ;
108
116
u32 nopower_flags ;
109
117
u16 ac_current ;
118
+ bool chwa_limit = false;
110
119
int ret ;
111
120
112
121
/*
@@ -153,14 +162,29 @@ static int macsmc_battery_get_status(struct macsmc_power *power)
153
162
else if (ret )
154
163
return POWER_SUPPLY_STATUS_FULL ;
155
164
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
+
156
177
/* If there are reasons we aren't charging... */
157
178
ret = apple_smc_read_u64 (power -> smc , SMC_KEY (CHNC ), & nocharge_flags );
158
179
if (!ret ) {
159
180
/* Perhaps the battery is full after all */
160
181
if (nocharge_flags & CHNC_BATTERY_FULL )
161
182
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 )
164
188
return POWER_SUPPLY_STATUS_CHARGING ;
165
189
/* If we have other reasons we aren't charging, say we aren't */
166
190
else if (nocharge_flags )
@@ -393,6 +417,16 @@ static int macsmc_battery_get_property(struct power_supply *psy,
393
417
case POWER_SUPPLY_PROP_MANUFACTURE_DAY :
394
418
ret = macsmc_battery_get_date (& power -> mfg_date [4 ], & val -> intval );
395
419
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 ;
396
430
default :
397
431
return - EINVAL ;
398
432
}
@@ -409,6 +443,16 @@ static int macsmc_battery_set_property(struct power_supply *psy,
409
443
switch (psp ) {
410
444
case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR :
411
445
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 );
412
456
default :
413
457
return - EINVAL ;
414
458
}
@@ -417,15 +461,20 @@ static int macsmc_battery_set_property(struct power_supply *psy,
417
461
static int macsmc_battery_property_is_writeable (struct power_supply * psy ,
418
462
enum power_supply_property psp )
419
463
{
464
+ struct macsmc_power * power = power_supply_get_drvdata (psy );
465
+
420
466
switch (psp ) {
421
467
case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR :
422
468
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 ;
423
472
default :
424
473
return false;
425
474
}
426
475
}
427
476
428
- static enum power_supply_property macsmc_battery_props [] = {
477
+ static const enum power_supply_property macsmc_battery_props [] = {
429
478
POWER_SUPPLY_PROP_STATUS ,
430
479
POWER_SUPPLY_PROP_PRESENT ,
431
480
POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR ,
@@ -454,6 +503,8 @@ static enum power_supply_property macsmc_battery_props[] = {
454
503
POWER_SUPPLY_PROP_MANUFACTURE_YEAR ,
455
504
POWER_SUPPLY_PROP_MANUFACTURE_MONTH ,
456
505
POWER_SUPPLY_PROP_MANUFACTURE_DAY ,
506
+ POWER_SUPPLY_PROP_CHARGE_CONTROL_START_THRESHOLD ,
507
+ POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD
457
508
};
458
509
459
510
static const struct power_supply_desc macsmc_battery_desc = {
@@ -651,6 +702,7 @@ static int macsmc_power_probe(struct platform_device *pdev)
651
702
652
703
power -> dev = & pdev -> dev ;
653
704
power -> smc = smc ;
705
+ power -> batt_desc = macsmc_battery_desc ;
654
706
dev_set_drvdata (& pdev -> dev , power );
655
707
656
708
/* Ignore devices without a charger/battery */
@@ -666,11 +718,18 @@ static int macsmc_power_probe(struct platform_device *pdev)
666
718
apple_smc_write_u8 (power -> smc , SMC_KEY (CH0K ), 0 );
667
719
apple_smc_write_u8 (power -> smc , SMC_KEY (CH0B ), 0 );
668
720
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
+
669
728
/* Doing one read of this flag enables critical shutdown notifications */
670
729
apple_smc_read_u32 (power -> smc , SMC_KEY (BCF0 ), & val );
671
730
672
731
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 );
674
733
if (IS_ERR (power -> batt )) {
675
734
dev_err (& pdev -> dev , "Failed to register battery\n" );
676
735
ret = PTR_ERR (power -> batt );
0 commit comments