aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-logitech-hidpp.c701
1 files changed, 593 insertions, 108 deletions
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index bd2ab476c65e..2869bbff0899 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -15,13 +15,19 @@
15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16 16
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/input.h>
19#include <linux/usb.h>
18#include <linux/hid.h> 20#include <linux/hid.h>
19#include <linux/module.h> 21#include <linux/module.h>
20#include <linux/slab.h> 22#include <linux/slab.h>
21#include <linux/sched.h> 23#include <linux/sched.h>
22#include <linux/kfifo.h> 24#include <linux/kfifo.h>
23#include <linux/input/mt.h> 25#include <linux/input/mt.h>
26#include <linux/workqueue.h>
27#include <linux/atomic.h>
28#include <linux/fixp-arith.h>
24#include <asm/unaligned.h> 29#include <asm/unaligned.h>
30#include "usbhid/usbhid.h"
25#include "hid-ids.h" 31#include "hid-ids.h"
26 32
27MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
@@ -773,6 +779,589 @@ static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev,
773 } 779 }
774} 780}
775 781
782/* -------------------------------------------------------------------------- */
783/* 0x8123: Force feedback support */
784/* -------------------------------------------------------------------------- */
785
786#define HIDPP_FF_GET_INFO 0x01
787#define HIDPP_FF_RESET_ALL 0x11
788#define HIDPP_FF_DOWNLOAD_EFFECT 0x21
789#define HIDPP_FF_SET_EFFECT_STATE 0x31
790#define HIDPP_FF_DESTROY_EFFECT 0x41
791#define HIDPP_FF_GET_APERTURE 0x51
792#define HIDPP_FF_SET_APERTURE 0x61
793#define HIDPP_FF_GET_GLOBAL_GAINS 0x71
794#define HIDPP_FF_SET_GLOBAL_GAINS 0x81
795
796#define HIDPP_FF_EFFECT_STATE_GET 0x00
797#define HIDPP_FF_EFFECT_STATE_STOP 0x01
798#define HIDPP_FF_EFFECT_STATE_PLAY 0x02
799#define HIDPP_FF_EFFECT_STATE_PAUSE 0x03
800
801#define HIDPP_FF_EFFECT_CONSTANT 0x00
802#define HIDPP_FF_EFFECT_PERIODIC_SINE 0x01
803#define HIDPP_FF_EFFECT_PERIODIC_SQUARE 0x02
804#define HIDPP_FF_EFFECT_PERIODIC_TRIANGLE 0x03
805#define HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHUP 0x04
806#define HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHDOWN 0x05
807#define HIDPP_FF_EFFECT_SPRING 0x06
808#define HIDPP_FF_EFFECT_DAMPER 0x07
809#define HIDPP_FF_EFFECT_FRICTION 0x08
810#define HIDPP_FF_EFFECT_INERTIA 0x09
811#define HIDPP_FF_EFFECT_RAMP 0x0A
812
813#define HIDPP_FF_EFFECT_AUTOSTART 0x80
814
815#define HIDPP_FF_EFFECTID_NONE -1
816#define HIDPP_FF_EFFECTID_AUTOCENTER -2
817
818#define HIDPP_FF_MAX_PARAMS 20
819#define HIDPP_FF_RESERVED_SLOTS 1
820
821struct hidpp_ff_private_data {
822 struct hidpp_device *hidpp;
823 u8 feature_index;
824 u8 version;
825 u16 gain;
826 s16 range;
827 u8 slot_autocenter;
828 u8 num_effects;
829 int *effect_ids;
830 struct workqueue_struct *wq;
831 atomic_t workqueue_size;
832};
833
834struct hidpp_ff_work_data {
835 struct work_struct work;
836 struct hidpp_ff_private_data *data;
837 int effect_id;
838 u8 command;
839 u8 params[HIDPP_FF_MAX_PARAMS];
840 u8 size;
841};
842
843static const signed short hiddpp_ff_effects[] = {
844 FF_CONSTANT,
845 FF_PERIODIC,
846 FF_SINE,
847 FF_SQUARE,
848 FF_SAW_UP,
849 FF_SAW_DOWN,
850 FF_TRIANGLE,
851 FF_SPRING,
852 FF_DAMPER,
853 FF_AUTOCENTER,
854 FF_GAIN,
855 -1
856};
857
858static const signed short hiddpp_ff_effects_v2[] = {
859 FF_RAMP,
860 FF_FRICTION,
861 FF_INERTIA,
862 -1
863};
864
865static const u8 HIDPP_FF_CONDITION_CMDS[] = {
866 HIDPP_FF_EFFECT_SPRING,
867 HIDPP_FF_EFFECT_FRICTION,
868 HIDPP_FF_EFFECT_DAMPER,
869 HIDPP_FF_EFFECT_INERTIA
870};
871
872static const char *HIDPP_FF_CONDITION_NAMES[] = {
873 "spring",
874 "friction",
875 "damper",
876 "inertia"
877};
878
879
880static u8 hidpp_ff_find_effect(struct hidpp_ff_private_data *data, int effect_id)
881{
882 int i;
883
884 for (i = 0; i < data->num_effects; i++)
885 if (data->effect_ids[i] == effect_id)
886 return i+1;
887
888 return 0;
889}
890
891static void hidpp_ff_work_handler(struct work_struct *w)
892{
893 struct hidpp_ff_work_data *wd = container_of(w, struct hidpp_ff_work_data, work);
894 struct hidpp_ff_private_data *data = wd->data;
895 struct hidpp_report response;
896 u8 slot;
897 int ret;
898
899 /* add slot number if needed */
900 switch (wd->effect_id) {
901 case HIDPP_FF_EFFECTID_AUTOCENTER:
902 wd->params[0] = data->slot_autocenter;
903 break;
904 case HIDPP_FF_EFFECTID_NONE:
905 /* leave slot as zero */
906 break;
907 default:
908 /* find current slot for effect */
909 wd->params[0] = hidpp_ff_find_effect(data, wd->effect_id);
910 break;
911 }
912
913 /* send command and wait for reply */
914 ret = hidpp_send_fap_command_sync(data->hidpp, data->feature_index,
915 wd->command, wd->params, wd->size, &response);
916
917 if (ret) {
918 hid_err(data->hidpp->hid_dev, "Failed to send command to device!\n");
919 goto out;
920 }
921
922 /* parse return data */
923 switch (wd->command) {
924 case HIDPP_FF_DOWNLOAD_EFFECT:
925 slot = response.fap.params[0];
926 if (slot > 0 && slot <= data->num_effects) {
927 if (wd->effect_id >= 0)
928 /* regular effect uploaded */
929 data->effect_ids[slot-1] = wd->effect_id;
930 else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER)
931 /* autocenter spring uploaded */
932 data->slot_autocenter = slot;
933 }
934 break;
935 case HIDPP_FF_DESTROY_EFFECT:
936 if (wd->effect_id >= 0)
937 /* regular effect destroyed */
938 data->effect_ids[wd->params[0]-1] = -1;
939 else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER)
940 /* autocenter spring destoyed */
941 data->slot_autocenter = 0;
942 break;
943 case HIDPP_FF_SET_GLOBAL_GAINS:
944 data->gain = (wd->params[0] << 8) + wd->params[1];
945 break;
946 case HIDPP_FF_SET_APERTURE:
947 data->range = (wd->params[0] << 8) + wd->params[1];
948 break;
949 default:
950 /* no action needed */
951 break;
952 }
953
954out:
955 atomic_dec(&data->workqueue_size);
956 kfree(wd);
957}
958
959static int hidpp_ff_queue_work(struct hidpp_ff_private_data *data, int effect_id, u8 command, u8 *params, u8 size)
960{
961 struct hidpp_ff_work_data *wd = kzalloc(sizeof(*wd), GFP_KERNEL);
962 int s;
963
964 if (!wd)
965 return -ENOMEM;
966
967 INIT_WORK(&wd->work, hidpp_ff_work_handler);
968
969 wd->data = data;
970 wd->effect_id = effect_id;
971 wd->command = command;
972 wd->size = size;
973 memcpy(wd->params, params, size);
974
975 atomic_inc(&data->workqueue_size);
976 queue_work(data->wq, &wd->work);
977
978 /* warn about excessive queue size */
979 s = atomic_read(&data->workqueue_size);
980 if (s >= 20 && s % 20 == 0)
981 hid_warn(data->hidpp->hid_dev, "Force feedback command queue contains %d commands, causing substantial delays!", s);
982
983 return 0;
984}
985
986static int hidpp_ff_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
987{
988 struct hidpp_ff_private_data *data = dev->ff->private;
989 u8 params[20];
990 u8 size;
991 int force;
992
993 /* set common parameters */
994 params[2] = effect->replay.length >> 8;
995 params[3] = effect->replay.length & 255;
996 params[4] = effect->replay.delay >> 8;
997 params[5] = effect->replay.delay & 255;
998
999 switch (effect->type) {
1000 case FF_CONSTANT:
1001 force = (effect->u.constant.level * fixp_sin16((effect->direction * 360) >> 16)) >> 15;
1002 params[1] = HIDPP_FF_EFFECT_CONSTANT;
1003 params[6] = force >> 8;
1004 params[7] = force & 255;
1005 params[8] = effect->u.constant.envelope.attack_level >> 7;
1006 params[9] = effect->u.constant.envelope.attack_length >> 8;
1007 params[10] = effect->u.constant.envelope.attack_length & 255;
1008 params[11] = effect->u.constant.envelope.fade_level >> 7;
1009 params[12] = effect->u.constant.envelope.fade_length >> 8;
1010 params[13] = effect->u.constant.envelope.fade_length & 255;
1011 size = 14;
1012 dbg_hid("Uploading constant force level=%d in dir %d = %d\n",
1013 effect->u.constant.level,
1014 effect->direction, force);
1015 dbg_hid(" envelope attack=(%d, %d ms) fade=(%d, %d ms)\n",
1016 effect->u.constant.envelope.attack_level,
1017 effect->u.constant.envelope.attack_length,
1018 effect->u.constant.envelope.fade_level,
1019 effect->u.constant.envelope.fade_length);
1020 break;
1021 case FF_PERIODIC:
1022 {
1023 switch (effect->u.periodic.waveform) {
1024 case FF_SINE:
1025 params[1] = HIDPP_FF_EFFECT_PERIODIC_SINE;
1026 break;
1027 case FF_SQUARE:
1028 params[1] = HIDPP_FF_EFFECT_PERIODIC_SQUARE;
1029 break;
1030 case FF_SAW_UP:
1031 params[1] = HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHUP;
1032 break;
1033 case FF_SAW_DOWN:
1034 params[1] = HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHDOWN;
1035 break;
1036 case FF_TRIANGLE:
1037 params[1] = HIDPP_FF_EFFECT_PERIODIC_TRIANGLE;
1038 break;
1039 default:
1040 hid_err(data->hidpp->hid_dev, "Unexpected periodic waveform type %i!\n", effect->u.periodic.waveform);
1041 return -EINVAL;
1042 }
1043 force = (effect->u.periodic.magnitude * fixp_sin16((effect->direction * 360) >> 16)) >> 15;
1044 params[6] = effect->u.periodic.magnitude >> 8;
1045 params[7] = effect->u.periodic.magnitude & 255;
1046 params[8] = effect->u.periodic.offset >> 8;
1047 params[9] = effect->u.periodic.offset & 255;
1048 params[10] = effect->u.periodic.period >> 8;
1049 params[11] = effect->u.periodic.period & 255;
1050 params[12] = effect->u.periodic.phase >> 8;
1051 params[13] = effect->u.periodic.phase & 255;
1052 params[14] = effect->u.periodic.envelope.attack_level >> 7;
1053 params[15] = effect->u.periodic.envelope.attack_length >> 8;
1054 params[16] = effect->u.periodic.envelope.attack_length & 255;
1055 params[17] = effect->u.periodic.envelope.fade_level >> 7;
1056 params[18] = effect->u.periodic.envelope.fade_length >> 8;
1057 params[19] = effect->u.periodic.envelope.fade_length & 255;
1058 size = 20;
1059 dbg_hid("Uploading periodic force mag=%d/dir=%d, offset=%d, period=%d ms, phase=%d\n",
1060 effect->u.periodic.magnitude, effect->direction,
1061 effect->u.periodic.offset,
1062 effect->u.periodic.period,
1063 effect->u.periodic.phase);
1064 dbg_hid(" envelope attack=(%d, %d ms) fade=(%d, %d ms)\n",
1065 effect->u.periodic.envelope.attack_level,
1066 effect->u.periodic.envelope.attack_length,
1067 effect->u.periodic.envelope.fade_level,
1068 effect->u.periodic.envelope.fade_length);
1069 break;
1070 }
1071 case FF_RAMP:
1072 params[1] = HIDPP_FF_EFFECT_RAMP;
1073 force = (effect->u.ramp.start_level * fixp_sin16((effect->direction * 360) >> 16)) >> 15;
1074 params[6] = force >> 8;
1075 params[7] = force & 255;
1076 force = (effect->u.ramp.end_level * fixp_sin16((effect->direction * 360) >> 16)) >> 15;
1077 params[8] = force >> 8;
1078 params[9] = force & 255;
1079 params[10] = effect->u.ramp.envelope.attack_level >> 7;
1080 params[11] = effect->u.ramp.envelope.attack_length >> 8;
1081 params[12] = effect->u.ramp.envelope.attack_length & 255;
1082 params[13] = effect->u.ramp.envelope.fade_level >> 7;
1083 params[14] = effect->u.ramp.envelope.fade_length >> 8;
1084 params[15] = effect->u.ramp.envelope.fade_length & 255;
1085 size = 16;
1086 dbg_hid("Uploading ramp force level=%d -> %d in dir %d = %d\n",
1087 effect->u.ramp.start_level,
1088 effect->u.ramp.end_level,
1089 effect->direction, force);
1090 dbg_hid(" envelope attack=(%d, %d ms) fade=(%d, %d ms)\n",
1091 effect->u.ramp.envelope.attack_level,
1092 effect->u.ramp.envelope.attack_length,
1093 effect->u.ramp.envelope.fade_level,
1094 effect->u.ramp.envelope.fade_length);
1095 break;
1096 case FF_FRICTION:
1097 case FF_INERTIA:
1098 case FF_SPRING:
1099 case FF_DAMPER:
1100 params[1] = HIDPP_FF_CONDITION_CMDS[effect->type - FF_SPRING];
1101 params[6] = effect->u.condition[0].left_saturation >> 9;
1102 params[7] = (effect->u.condition[0].left_saturation >> 1) & 255;
1103 params[8] = effect->u.condition[0].left_coeff >> 8;
1104 params[9] = effect->u.condition[0].left_coeff & 255;
1105 params[10] = effect->u.condition[0].deadband >> 9;
1106 params[11] = (effect->u.condition[0].deadband >> 1) & 255;
1107 params[12] = effect->u.condition[0].center >> 8;
1108 params[13] = effect->u.condition[0].center & 255;
1109 params[14] = effect->u.condition[0].right_coeff >> 8;
1110 params[15] = effect->u.condition[0].right_coeff & 255;
1111 params[16] = effect->u.condition[0].right_saturation >> 9;
1112 params[17] = (effect->u.condition[0].right_saturation >> 1) & 255;
1113 size = 18;
1114 dbg_hid("Uploading %s force left coeff=%d, left sat=%d, right coeff=%d, right sat=%d\n",
1115 HIDPP_FF_CONDITION_NAMES[effect->type - FF_SPRING],
1116 effect->u.condition[0].left_coeff,
1117 effect->u.condition[0].left_saturation,
1118 effect->u.condition[0].right_coeff,
1119 effect->u.condition[0].right_saturation);
1120 dbg_hid(" deadband=%d, center=%d\n",
1121 effect->u.condition[0].deadband,
1122 effect->u.condition[0].center);
1123 break;
1124 default:
1125 hid_err(data->hidpp->hid_dev, "Unexpected force type %i!\n", effect->type);
1126 return -EINVAL;
1127 }
1128
1129 return hidpp_ff_queue_work(data, effect->id, HIDPP_FF_DOWNLOAD_EFFECT, params, size);
1130}
1131
1132static int hidpp_ff_playback(struct input_dev *dev, int effect_id, int value)
1133{
1134 struct hidpp_ff_private_data *data = dev->ff->private;
1135 u8 params[2];
1136
1137 params[1] = value ? HIDPP_FF_EFFECT_STATE_PLAY : HIDPP_FF_EFFECT_STATE_STOP;
1138
1139 dbg_hid("St%sing playback of effect %d.\n", value?"art":"opp", effect_id);
1140
1141 return hidpp_ff_queue_work(data, effect_id, HIDPP_FF_SET_EFFECT_STATE, params, ARRAY_SIZE(params));
1142}
1143
1144static int hidpp_ff_erase_effect(struct input_dev *dev, int effect_id)
1145{
1146 struct hidpp_ff_private_data *data = dev->ff->private;
1147 u8 slot = 0;
1148
1149 dbg_hid("Erasing effect %d.\n", effect_id);
1150
1151 return hidpp_ff_queue_work(data, effect_id, HIDPP_FF_DESTROY_EFFECT, &slot, 1);
1152}
1153
1154static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude)
1155{
1156 struct hidpp_ff_private_data *data = dev->ff->private;
1157 u8 params[18];
1158
1159 dbg_hid("Setting autocenter to %d.\n", magnitude);
1160
1161 /* start a standard spring effect */
1162 params[1] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART;
1163 /* zero delay and duration */
1164 params[2] = params[3] = params[4] = params[5] = 0;
1165 /* set coeff to 25% of saturation */
1166 params[8] = params[14] = magnitude >> 11;
1167 params[9] = params[15] = (magnitude >> 3) & 255;
1168 params[6] = params[16] = magnitude >> 9;
1169 params[7] = params[17] = (magnitude >> 1) & 255;
1170 /* zero deadband and center */
1171 params[10] = params[11] = params[12] = params[13] = 0;
1172
1173 hidpp_ff_queue_work(data, HIDPP_FF_EFFECTID_AUTOCENTER, HIDPP_FF_DOWNLOAD_EFFECT, params, ARRAY_SIZE(params));
1174}
1175
1176static void hidpp_ff_set_gain(struct input_dev *dev, u16 gain)
1177{
1178 struct hidpp_ff_private_data *data = dev->ff->private;
1179 u8 params[4];
1180
1181 dbg_hid("Setting gain to %d.\n", gain);
1182
1183 params[0] = gain >> 8;
1184 params[1] = gain & 255;
1185 params[2] = 0; /* no boost */
1186 params[3] = 0;
1187
1188 hidpp_ff_queue_work(data, HIDPP_FF_EFFECTID_NONE, HIDPP_FF_SET_GLOBAL_GAINS, params, ARRAY_SIZE(params));
1189}
1190
1191static ssize_t hidpp_ff_range_show(struct device *dev, struct device_attribute *attr, char *buf)
1192{
1193 struct hid_device *hid = to_hid_device(dev);
1194 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
1195 struct input_dev *idev = hidinput->input;
1196 struct hidpp_ff_private_data *data = idev->ff->private;
1197
1198 return scnprintf(buf, PAGE_SIZE, "%u\n", data->range);
1199}
1200
1201static ssize_t hidpp_ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1202{
1203 struct hid_device *hid = to_hid_device(dev);
1204 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
1205 struct input_dev *idev = hidinput->input;
1206 struct hidpp_ff_private_data *data = idev->ff->private;
1207 u8 params[2];
1208 int range = simple_strtoul(buf, NULL, 10);
1209
1210 range = clamp(range, 180, 900);
1211
1212 params[0] = range >> 8;
1213 params[1] = range & 0x00FF;
1214
1215 hidpp_ff_queue_work(data, -1, HIDPP_FF_SET_APERTURE, params, ARRAY_SIZE(params));
1216
1217 return count;
1218}
1219
1220static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, hidpp_ff_range_show, hidpp_ff_range_store);
1221
1222static void hidpp_ff_destroy(struct ff_device *ff)
1223{
1224 struct hidpp_ff_private_data *data = ff->private;
1225
1226 kfree(data->effect_ids);
1227}
1228
1229int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
1230{
1231 struct hid_device *hid = hidpp->hid_dev;
1232 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
1233 struct input_dev *dev = hidinput->input;
1234 const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
1235 const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
1236 struct ff_device *ff;
1237 struct hidpp_report response;
1238 struct hidpp_ff_private_data *data;
1239 int error, j, num_slots;
1240 u8 version;
1241
1242 if (!dev) {
1243 hid_err(hid, "Struct input_dev not set!\n");
1244 return -EINVAL;
1245 }
1246
1247 /* Get firmware release */
1248 version = bcdDevice & 255;
1249
1250 /* Set supported force feedback capabilities */
1251 for (j = 0; hiddpp_ff_effects[j] >= 0; j++)
1252 set_bit(hiddpp_ff_effects[j], dev->ffbit);
1253 if (version > 1)
1254 for (j = 0; hiddpp_ff_effects_v2[j] >= 0; j++)
1255 set_bit(hiddpp_ff_effects_v2[j], dev->ffbit);
1256
1257 /* Read number of slots available in device */
1258 error = hidpp_send_fap_command_sync(hidpp, feature_index,
1259 HIDPP_FF_GET_INFO, NULL, 0, &response);
1260 if (error) {
1261 if (error < 0)
1262 return error;
1263 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
1264 __func__, error);
1265 return -EPROTO;
1266 }
1267
1268 num_slots = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS;
1269
1270 error = input_ff_create(dev, num_slots);
1271
1272 if (error) {
1273 hid_err(dev, "Failed to create FF device!\n");
1274 return error;
1275 }
1276
1277 data = kzalloc(sizeof(*data), GFP_KERNEL);
1278 if (!data)
1279 return -ENOMEM;
1280 data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL);
1281 if (!data->effect_ids) {
1282 kfree(data);
1283 return -ENOMEM;
1284 }
1285 data->hidpp = hidpp;
1286 data->feature_index = feature_index;
1287 data->version = version;
1288 data->slot_autocenter = 0;
1289 data->num_effects = num_slots;
1290 for (j = 0; j < num_slots; j++)
1291 data->effect_ids[j] = -1;
1292
1293 ff = dev->ff;
1294 ff->private = data;
1295
1296 ff->upload = hidpp_ff_upload_effect;
1297 ff->erase = hidpp_ff_erase_effect;
1298 ff->playback = hidpp_ff_playback;
1299 ff->set_gain = hidpp_ff_set_gain;
1300 ff->set_autocenter = hidpp_ff_set_autocenter;
1301 ff->destroy = hidpp_ff_destroy;
1302
1303
1304 /* reset all forces */
1305 error = hidpp_send_fap_command_sync(hidpp, feature_index,
1306 HIDPP_FF_RESET_ALL, NULL, 0, &response);
1307
1308 /* Read current Range */
1309 error = hidpp_send_fap_command_sync(hidpp, feature_index,
1310 HIDPP_FF_GET_APERTURE, NULL, 0, &response);
1311 if (error)
1312 hid_warn(hidpp->hid_dev, "Failed to read range from device!\n");
1313 data->range = error ? 900 : get_unaligned_be16(&response.fap.params[0]);
1314
1315 /* Create sysfs interface */
1316 error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range);
1317 if (error)
1318 hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error);
1319
1320 /* Read the current gain values */
1321 error = hidpp_send_fap_command_sync(hidpp, feature_index,
1322 HIDPP_FF_GET_GLOBAL_GAINS, NULL, 0, &response);
1323 if (error)
1324 hid_warn(hidpp->hid_dev, "Failed to read gain values from device!\n");
1325 data->gain = error ? 0xffff : get_unaligned_be16(&response.fap.params[0]);
1326 /* ignore boost value at response.fap.params[2] */
1327
1328 /* init the hardware command queue */
1329 data->wq = create_singlethread_workqueue("hidpp-ff-sendqueue");
1330 atomic_set(&data->workqueue_size, 0);
1331
1332 /* initialize with zero autocenter to get wheel in usable state */
1333 hidpp_ff_set_autocenter(dev, 0);
1334
1335 hid_info(hid, "Force feeback support loaded (firmware release %d).\n", version);
1336
1337 return 0;
1338}
1339
1340int hidpp_ff_deinit(struct hid_device *hid)
1341{
1342 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
1343 struct input_dev *dev = hidinput->input;
1344 struct hidpp_ff_private_data *data;
1345
1346 if (!dev) {
1347 hid_err(hid, "Struct input_dev not found!\n");
1348 return -EINVAL;
1349 }
1350
1351 hid_info(hid, "Unloading HID++ force feedback.\n");
1352 data = dev->ff->private;
1353 if (!data) {
1354 hid_err(hid, "Private data not found!\n");
1355 return -EINVAL;
1356 }
1357
1358 destroy_workqueue(data->wq);
1359 device_remove_file(&hid->dev, &dev_attr_range);
1360
1361 return 0;
1362}
1363
1364
776/* ************************************************************************** */ 1365/* ************************************************************************** */
777/* */ 1366/* */
778/* Device Support */ 1367/* Device Support */
@@ -1301,121 +1890,22 @@ static int k400_connect(struct hid_device *hdev, bool connected)
1301 1890
1302#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 1891#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123
1303 1892
1304/* Using session ID = 1 */
1305#define CMD_G920_FORCE_GET_APERTURE 0x51
1306#define CMD_G920_FORCE_SET_APERTURE 0x61
1307
1308struct g920_private_data {
1309 u8 force_feature;
1310 u16 range;
1311};
1312
1313static ssize_t g920_range_show(struct device *dev, struct device_attribute *attr,
1314 char *buf)
1315{
1316 struct hid_device *hid = to_hid_device(dev);
1317 struct hidpp_device *hidpp = hid_get_drvdata(hid);
1318 struct g920_private_data *pdata;
1319
1320 pdata = hidpp->private_data;
1321 if (!pdata) {
1322 hid_err(hid, "Private driver data not found!\n");
1323 return -EINVAL;
1324 }
1325
1326 return scnprintf(buf, PAGE_SIZE, "%u\n", pdata->range);
1327}
1328
1329static ssize_t g920_range_store(struct device *dev, struct device_attribute *attr,
1330 const char *buf, size_t count)
1331{
1332 struct hid_device *hid = to_hid_device(dev);
1333 struct hidpp_device *hidpp = hid_get_drvdata(hid);
1334 struct g920_private_data *pdata;
1335 struct hidpp_report response;
1336 u8 params[2];
1337 int ret;
1338 u16 range = simple_strtoul(buf, NULL, 10);
1339
1340 pdata = hidpp->private_data;
1341 if (!pdata) {
1342 hid_err(hid, "Private driver data not found!\n");
1343 return -EINVAL;
1344 }
1345
1346 if (range < 180)
1347 range = 180;
1348 else if (range > 900)
1349 range = 900;
1350
1351 params[0] = range >> 8;
1352 params[1] = range & 0x00FF;
1353
1354 ret = hidpp_send_fap_command_sync(hidpp, pdata->force_feature,
1355 CMD_G920_FORCE_SET_APERTURE, params, 2, &response);
1356 if (ret)
1357 return ret;
1358
1359 pdata->range = range;
1360 return count;
1361}
1362
1363static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, g920_range_show, g920_range_store);
1364
1365static int g920_allocate(struct hid_device *hdev)
1366{
1367 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1368 struct g920_private_data *pdata;
1369
1370 pdata = devm_kzalloc(&hdev->dev, sizeof(struct g920_private_data),
1371 GFP_KERNEL);
1372 if (!pdata)
1373 return -ENOMEM;
1374
1375 hidpp->private_data = pdata;
1376
1377 return 0;
1378}
1379
1380static int g920_get_config(struct hidpp_device *hidpp) 1893static int g920_get_config(struct hidpp_device *hidpp)
1381{ 1894{
1382 struct g920_private_data *pdata = hidpp->private_data;
1383 struct hidpp_report response;
1384 u8 feature_type; 1895 u8 feature_type;
1385 u8 feature_index; 1896 u8 feature_index;
1386 int ret; 1897 int ret;
1387 1898
1388 pdata = hidpp->private_data;
1389 if (!pdata) {
1390 hid_err(hidpp->hid_dev, "Private driver data not found!\n");
1391 return -EINVAL;
1392 }
1393
1394 /* Find feature and store for later use */ 1899 /* Find feature and store for later use */
1395 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, 1900 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK,
1396 &feature_index, &feature_type); 1901 &feature_index, &feature_type);
1397 if (ret) 1902 if (ret)
1398 return ret; 1903 return ret;
1399 1904
1400 pdata->force_feature = feature_index; 1905 ret = hidpp_ff_init(hidpp, feature_index);
1401
1402 /* Read current Range */
1403 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
1404 CMD_G920_FORCE_GET_APERTURE, NULL, 0, &response);
1405 if (ret > 0) {
1406 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
1407 __func__, ret);
1408 return -EPROTO;
1409 }
1410 if (ret)
1411 return ret;
1412
1413 pdata->range = get_unaligned_be16(&response.fap.params[0]);
1414
1415 /* Create sysfs interface */
1416 ret = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range);
1417 if (ret) 1906 if (ret)
1418 hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d\n", ret); 1907 hid_warn(hidpp->hid_dev, "Unable to initialize force feedback support, errno %d\n",
1908 ret);
1419 1909
1420 return 0; 1910 return 0;
1421} 1911}
@@ -1739,10 +2229,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
1739 ret = k400_allocate(hdev); 2229 ret = k400_allocate(hdev);
1740 if (ret) 2230 if (ret)
1741 goto allocate_fail; 2231 goto allocate_fail;
1742 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
1743 ret = g920_allocate(hdev);
1744 if (ret)
1745 goto allocate_fail;
1746 } 2232 }
1747 2233
1748 INIT_WORK(&hidpp->work, delayed_work_cb); 2234 INIT_WORK(&hidpp->work, delayed_work_cb);
@@ -1825,7 +2311,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
1825hid_hw_open_failed: 2311hid_hw_open_failed:
1826 hid_device_io_stop(hdev); 2312 hid_device_io_stop(hdev);
1827 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { 2313 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
1828 device_remove_file(&hdev->dev, &dev_attr_range);
1829 hid_hw_close(hdev); 2314 hid_hw_close(hdev);
1830 hid_hw_stop(hdev); 2315 hid_hw_stop(hdev);
1831 } 2316 }
@@ -1843,7 +2328,7 @@ static void hidpp_remove(struct hid_device *hdev)
1843 struct hidpp_device *hidpp = hid_get_drvdata(hdev); 2328 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1844 2329
1845 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { 2330 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
1846 device_remove_file(&hdev->dev, &dev_attr_range); 2331 hidpp_ff_deinit(hdev);
1847 hid_hw_close(hdev); 2332 hid_hw_close(hdev);
1848 } 2333 }
1849 hid_hw_stop(hdev); 2334 hid_hw_stop(hdev);