4747#define SBS_MANUFACTURE_MONTH_MASK GENMASK(8, 5)
4848#define SBS_MANUFACTURE_DAY_MASK GENMASK(4, 0)
4949
50+ #define MA_FAILURE_MODE_MASK GENMASK(11, 8)
51+ #define MA_FAILURE_MODE_PERMANENT 0x9
52+ #define MA_FAILURE_MODE_OVERHEAT 0xA
53+ #define MA_FAILURE_MODE_OVERCURRENT 0xB
54+
55+ #define MA_PERMANENT_FAILURE_CODE_MASK GENMASK(13, 12)
56+ #define MA_PERMANENT_FAILURE_FUSE_BLOWN 0x0
57+ #define MA_PERMANENT_FAILURE_CELL_IMBALANCE 0x1
58+ #define MA_PERMANENT_FAILURE_OVERVOLTAGE 0x2
59+ #define MA_PERMANENT_FAILURE_FET_FAILURE 0x3
60+
61+ #define MA_OVERHEAT_FAILURE_CODE_MASK GENMASK(15, 12)
62+ #define MA_OVERHEAT_FAILURE_START 0x5
63+ #define MA_OVERHEAT_FAILURE_CHARGING 0x7
64+ #define MA_OVERHEAT_FAILURE_DISCHARGING 0x8
65+
66+ #define MA_OVERCURRENT_FAILURE_CODE_MASK GENMASK(15, 12)
67+ #define MA_OVERCURRENT_FAILURE_CHARGING 0x6
68+ #define MA_OVERCURRENT_FAILURE_DISCHARGING 0xB
69+
5070#define DELL_EPPID_LENGTH 20
5171#define DELL_EPPID_EXT_LENGTH 23
5272
@@ -749,6 +769,72 @@ static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, cha
749769 return ret ;
750770}
751771
772+ static int dell_wmi_ddv_get_health (struct dell_wmi_ddv_data * data , u32 index ,
773+ union power_supply_propval * val )
774+ {
775+ u32 value , code ;
776+ int ret ;
777+
778+ ret = dell_wmi_ddv_query_integer (data -> wdev , DELL_DDV_BATTERY_MANUFACTURER_ACCESS , index ,
779+ & value );
780+ if (ret < 0 )
781+ return ret ;
782+
783+ switch (FIELD_GET (MA_FAILURE_MODE_MASK , value )) {
784+ case MA_FAILURE_MODE_PERMANENT :
785+ code = FIELD_GET (MA_PERMANENT_FAILURE_CODE_MASK , value );
786+ switch (code ) {
787+ case MA_PERMANENT_FAILURE_FUSE_BLOWN :
788+ val -> intval = POWER_SUPPLY_HEALTH_BLOWN_FUSE ;
789+ return 0 ;
790+ case MA_PERMANENT_FAILURE_CELL_IMBALANCE :
791+ val -> intval = POWER_SUPPLY_HEALTH_CELL_IMBALANCE ;
792+ return 0 ;
793+ case MA_PERMANENT_FAILURE_OVERVOLTAGE :
794+ val -> intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE ;
795+ return 0 ;
796+ case MA_PERMANENT_FAILURE_FET_FAILURE :
797+ val -> intval = POWER_SUPPLY_HEALTH_DEAD ;
798+ return 0 ;
799+ default :
800+ dev_notice_once (& data -> wdev -> dev , "Unknown permanent failure code %u\n" ,
801+ code );
802+ val -> intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE ;
803+ return 0 ;
804+ }
805+ case MA_FAILURE_MODE_OVERHEAT :
806+ code = FIELD_GET (MA_OVERHEAT_FAILURE_CODE_MASK , value );
807+ switch (code ) {
808+ case MA_OVERHEAT_FAILURE_START :
809+ case MA_OVERHEAT_FAILURE_CHARGING :
810+ case MA_OVERHEAT_FAILURE_DISCHARGING :
811+ val -> intval = POWER_SUPPLY_HEALTH_OVERHEAT ;
812+ return 0 ;
813+ default :
814+ dev_notice_once (& data -> wdev -> dev , "Unknown overheat failure code %u\n" ,
815+ code );
816+ val -> intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE ;
817+ return 0 ;
818+ }
819+ case MA_FAILURE_MODE_OVERCURRENT :
820+ code = FIELD_GET (MA_OVERCURRENT_FAILURE_CODE_MASK , value );
821+ switch (code ) {
822+ case MA_OVERCURRENT_FAILURE_CHARGING :
823+ case MA_OVERCURRENT_FAILURE_DISCHARGING :
824+ val -> intval = POWER_SUPPLY_HEALTH_OVERCURRENT ;
825+ return 0 ;
826+ default :
827+ dev_notice_once (& data -> wdev -> dev , "Unknown overcurrent failure code %u\n" ,
828+ code );
829+ val -> intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE ;
830+ return 0 ;
831+ }
832+ default :
833+ val -> intval = POWER_SUPPLY_HEALTH_GOOD ;
834+ return 0 ;
835+ }
836+ }
837+
752838static int dell_wmi_ddv_get_manufacture_date (struct dell_wmi_ddv_data * data , u32 index ,
753839 enum power_supply_property psp ,
754840 union power_supply_propval * val )
@@ -806,6 +892,8 @@ static int dell_wmi_ddv_get_property(struct power_supply *psy, const struct powe
806892 return ret ;
807893
808894 switch (psp ) {
895+ case POWER_SUPPLY_PROP_HEALTH :
896+ return dell_wmi_ddv_get_health (data , index , val );
809897 case POWER_SUPPLY_PROP_TEMP :
810898 ret = dell_wmi_ddv_query_integer (data -> wdev , DELL_DDV_BATTERY_TEMPERATURE , index ,
811899 & value );
@@ -827,6 +915,7 @@ static int dell_wmi_ddv_get_property(struct power_supply *psy, const struct powe
827915}
828916
829917static const enum power_supply_property dell_wmi_ddv_properties [] = {
918+ POWER_SUPPLY_PROP_HEALTH ,
830919 POWER_SUPPLY_PROP_TEMP ,
831920 POWER_SUPPLY_PROP_MANUFACTURE_YEAR ,
832921 POWER_SUPPLY_PROP_MANUFACTURE_MONTH ,
0 commit comments