@@ -1331,6 +1331,43 @@ static int hidpp20_battery_get_battery_voltage(struct hidpp_device *hidpp,
13311331 return 0 ;
13321332}
13331333
1334+ static int hidpp20_map_battery_capacity (struct hid_device * hid_dev , int voltage )
1335+ {
1336+ /* NB: This voltage curve doesn't necessarily map perfectly to all
1337+ * devices that implement the BATTERY_VOLTAGE feature. This is because
1338+ * there are a few devices that use different battery technology.
1339+ */
1340+
1341+ static const int voltages [] = {
1342+ 4186 , 4156 , 4143 , 4133 , 4122 , 4113 , 4103 , 4094 , 4086 , 4075 ,
1343+ 4067 , 4059 , 4051 , 4043 , 4035 , 4027 , 4019 , 4011 , 4003 , 3997 ,
1344+ 3989 , 3983 , 3976 , 3969 , 3961 , 3955 , 3949 , 3942 , 3935 , 3929 ,
1345+ 3922 , 3916 , 3909 , 3902 , 3896 , 3890 , 3883 , 3877 , 3870 , 3865 ,
1346+ 3859 , 3853 , 3848 , 3842 , 3837 , 3833 , 3828 , 3824 , 3819 , 3815 ,
1347+ 3811 , 3808 , 3804 , 3800 , 3797 , 3793 , 3790 , 3787 , 3784 , 3781 ,
1348+ 3778 , 3775 , 3772 , 3770 , 3767 , 3764 , 3762 , 3759 , 3757 , 3754 ,
1349+ 3751 , 3748 , 3744 , 3741 , 3737 , 3734 , 3730 , 3726 , 3724 , 3720 ,
1350+ 3717 , 3714 , 3710 , 3706 , 3702 , 3697 , 3693 , 3688 , 3683 , 3677 ,
1351+ 3671 , 3666 , 3662 , 3658 , 3654 , 3646 , 3633 , 3612 , 3579 , 3537
1352+ };
1353+
1354+ int i ;
1355+
1356+ BUILD_BUG_ON (ARRAY_SIZE (voltages ) != 100 );
1357+
1358+ if (unlikely (voltage < 3500 || voltage >= 5000 ))
1359+ hid_warn_once (hid_dev ,
1360+ "%s: possibly using the wrong voltage curve\n" ,
1361+ __func__ );
1362+
1363+ for (i = 0 ; i < ARRAY_SIZE (voltages ); i ++ ) {
1364+ if (voltage >= voltages [i ])
1365+ return ARRAY_SIZE (voltages ) - i ;
1366+ }
1367+
1368+ return 0 ;
1369+ }
1370+
13341371static int hidpp20_query_battery_voltage_info (struct hidpp_device * hidpp )
13351372{
13361373 u8 feature_type ;
@@ -1354,6 +1391,8 @@ static int hidpp20_query_battery_voltage_info(struct hidpp_device *hidpp)
13541391
13551392 hidpp -> battery .status = status ;
13561393 hidpp -> battery .voltage = voltage ;
1394+ hidpp -> battery .capacity = hidpp20_map_battery_capacity (hidpp -> hid_dev ,
1395+ voltage );
13571396 hidpp -> battery .level = level ;
13581397 hidpp -> battery .charge_type = charge_type ;
13591398 hidpp -> battery .online = status != POWER_SUPPLY_STATUS_NOT_CHARGING ;
@@ -1378,6 +1417,8 @@ static int hidpp20_battery_voltage_event(struct hidpp_device *hidpp,
13781417
13791418 if (voltage != hidpp -> battery .voltage || status != hidpp -> battery .status ) {
13801419 hidpp -> battery .voltage = voltage ;
1420+ hidpp -> battery .capacity = hidpp20_map_battery_capacity (hidpp -> hid_dev ,
1421+ voltage );
13811422 hidpp -> battery .status = status ;
13821423 hidpp -> battery .level = level ;
13831424 hidpp -> battery .charge_type = charge_type ;
@@ -2240,11 +2281,10 @@ static int hidpp_ff_queue_work(struct hidpp_ff_private_data *data, int effect_id
22402281 wd -> size = size ;
22412282 memcpy (wd -> params , params , size );
22422283
2243- atomic_inc (& data -> workqueue_size );
2284+ s = atomic_inc_return (& data -> workqueue_size );
22442285 queue_work (data -> wq , & wd -> work );
22452286
22462287 /* warn about excessive queue size */
2247- s = atomic_read (& data -> workqueue_size );
22482288 if (s >= 20 && s % 20 == 0 )
22492289 hid_warn (data -> hidpp -> hid_dev , "Force feedback command queue contains %d commands, causing substantial delays!" , s );
22502290
@@ -3717,7 +3757,8 @@ static int hidpp_initialize_battery(struct hidpp_device *hidpp)
37173757 num_battery_props = ARRAY_SIZE (hidpp_battery_props ) - 3 ;
37183758
37193759 if (hidpp -> capabilities & HIDPP_CAPABILITY_BATTERY_MILEAGE ||
3720- hidpp -> capabilities & HIDPP_CAPABILITY_BATTERY_PERCENTAGE )
3760+ hidpp -> capabilities & HIDPP_CAPABILITY_BATTERY_PERCENTAGE ||
3761+ hidpp -> capabilities & HIDPP_CAPABILITY_BATTERY_VOLTAGE )
37213762 battery_props [num_battery_props ++ ] =
37223763 POWER_SUPPLY_PROP_CAPACITY ;
37233764
0 commit comments