diff options
author | Simon Wood <simon@mungewell.org> | 2015-11-02 09:56:51 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2015-11-06 15:18:05 -0500 |
commit | bbec1bd0faa211a0a0abaf947cd4a236d080ad28 (patch) | |
tree | 7c1d61b6215fa5af6e77d01e4c7530cc73e2ecba | |
parent | 90cdd986335eddb7cac6e456f7c48c1ce76fd095 (diff) |
HID: logitech: Simplify wheel detection scheme
Simplfy how hid-logitech driver detects the native mode of the wheel,
done by looking at the USB-ID revision and comparing bit mask.
Signed-off-by: Simon Wood <simon@mungewell.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-lg4ff.c | 70 |
1 files changed, 28 insertions, 42 deletions
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 02cec83caac3..b363d88267c2 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c | |||
@@ -114,16 +114,12 @@ struct lg4ff_compat_mode_switch { | |||
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct lg4ff_wheel_ident_info { | 116 | struct lg4ff_wheel_ident_info { |
117 | const u32 modes; | ||
117 | const u16 mask; | 118 | const u16 mask; |
118 | const u16 result; | 119 | const u16 result; |
119 | const u16 real_product_id; | 120 | const u16 real_product_id; |
120 | }; | 121 | }; |
121 | 122 | ||
122 | struct lg4ff_wheel_ident_checklist { | ||
123 | const u32 count; | ||
124 | const struct lg4ff_wheel_ident_info *models[]; | ||
125 | }; | ||
126 | |||
127 | struct lg4ff_multimode_wheel { | 123 | struct lg4ff_multimode_wheel { |
128 | const u16 product_id; | 124 | const u16 product_id; |
129 | const u32 alternate_modes; | 125 | const u32 alternate_modes; |
@@ -174,36 +170,39 @@ static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = { | |||
174 | 170 | ||
175 | /* Multimode wheel identificators */ | 171 | /* Multimode wheel identificators */ |
176 | static const struct lg4ff_wheel_ident_info lg4ff_dfp_ident_info = { | 172 | static const struct lg4ff_wheel_ident_info lg4ff_dfp_ident_info = { |
173 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, | ||
177 | 0xf000, | 174 | 0xf000, |
178 | 0x1000, | 175 | 0x1000, |
179 | USB_DEVICE_ID_LOGITECH_DFP_WHEEL | 176 | USB_DEVICE_ID_LOGITECH_DFP_WHEEL |
180 | }; | 177 | }; |
181 | 178 | ||
182 | static const struct lg4ff_wheel_ident_info lg4ff_g25_ident_info = { | 179 | static const struct lg4ff_wheel_ident_info lg4ff_g25_ident_info = { |
180 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, | ||
183 | 0xff00, | 181 | 0xff00, |
184 | 0x1200, | 182 | 0x1200, |
185 | USB_DEVICE_ID_LOGITECH_G25_WHEEL | 183 | USB_DEVICE_ID_LOGITECH_G25_WHEEL |
186 | }; | 184 | }; |
187 | 185 | ||
188 | static const struct lg4ff_wheel_ident_info lg4ff_g27_ident_info = { | 186 | static const struct lg4ff_wheel_ident_info lg4ff_g27_ident_info = { |
187 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, | ||
189 | 0xfff0, | 188 | 0xfff0, |
190 | 0x1230, | 189 | 0x1230, |
191 | USB_DEVICE_ID_LOGITECH_G27_WHEEL | 190 | USB_DEVICE_ID_LOGITECH_G27_WHEEL |
192 | }; | 191 | }; |
193 | 192 | ||
194 | static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = { | 193 | static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = { |
194 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, | ||
195 | 0xff00, | 195 | 0xff00, |
196 | 0x1300, | 196 | 0x1300, |
197 | USB_DEVICE_ID_LOGITECH_DFGT_WHEEL | 197 | USB_DEVICE_ID_LOGITECH_DFGT_WHEEL |
198 | }; | 198 | }; |
199 | 199 | ||
200 | /* Multimode wheel identification checklists */ | 200 | /* Multimode wheel identification checklists */ |
201 | static const struct lg4ff_wheel_ident_checklist lg4ff_main_checklist = { | 201 | static const struct lg4ff_wheel_ident_info *lg4ff_main_checklist[] = { |
202 | 4, | 202 | &lg4ff_dfgt_ident_info, |
203 | {&lg4ff_dfgt_ident_info, | 203 | &lg4ff_g27_ident_info, |
204 | &lg4ff_g27_ident_info, | 204 | &lg4ff_g25_ident_info, |
205 | &lg4ff_g25_ident_info, | 205 | &lg4ff_dfp_ident_info |
206 | &lg4ff_dfp_ident_info} | ||
207 | }; | 206 | }; |
208 | 207 | ||
209 | /* Compatibility mode switching commands */ | 208 | /* Compatibility mode switching commands */ |
@@ -1037,41 +1036,28 @@ static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cde | |||
1037 | 1036 | ||
1038 | static u16 lg4ff_identify_multimode_wheel(struct hid_device *hid, const u16 reported_product_id, const u16 bcdDevice) | 1037 | static u16 lg4ff_identify_multimode_wheel(struct hid_device *hid, const u16 reported_product_id, const u16 bcdDevice) |
1039 | { | 1038 | { |
1040 | const struct lg4ff_wheel_ident_checklist *checklist; | 1039 | u32 current_mode; |
1041 | int i, from_idx, to_idx; | 1040 | int i; |
1042 | 1041 | ||
1043 | switch (reported_product_id) { | 1042 | /* identify current mode from USB PID */ |
1044 | case USB_DEVICE_ID_LOGITECH_WHEEL: | 1043 | for (i = 1; i < ARRAY_SIZE(lg4ff_alternate_modes); i++) { |
1045 | case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: | 1044 | dbg_hid("Testing whether PID is %X\n", lg4ff_alternate_modes[i].product_id); |
1046 | checklist = &lg4ff_main_checklist; | 1045 | if (reported_product_id == lg4ff_alternate_modes[i].product_id) |
1047 | from_idx = 0; | 1046 | break; |
1048 | to_idx = checklist->count - 1; | ||
1049 | break; | ||
1050 | case USB_DEVICE_ID_LOGITECH_G25_WHEEL: | ||
1051 | checklist = &lg4ff_main_checklist; | ||
1052 | from_idx = 0; | ||
1053 | to_idx = checklist->count - 2; /* End identity check at G25 */ | ||
1054 | break; | ||
1055 | case USB_DEVICE_ID_LOGITECH_G27_WHEEL: | ||
1056 | checklist = &lg4ff_main_checklist; | ||
1057 | from_idx = 1; /* Start identity check at G27 */ | ||
1058 | to_idx = checklist->count - 3; /* End identity check at G27 */ | ||
1059 | break; | ||
1060 | case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: | ||
1061 | checklist = &lg4ff_main_checklist; | ||
1062 | from_idx = 0; | ||
1063 | to_idx = checklist->count - 4; /* End identity check at DFGT */ | ||
1064 | break; | ||
1065 | default: | ||
1066 | return 0; | ||
1067 | } | 1047 | } |
1068 | 1048 | ||
1069 | for (i = from_idx; i <= to_idx; i++) { | 1049 | if (i == ARRAY_SIZE(lg4ff_alternate_modes)) |
1070 | const u16 mask = checklist->models[i]->mask; | 1050 | return 0; |
1071 | const u16 result = checklist->models[i]->result; | 1051 | |
1072 | const u16 real_product_id = checklist->models[i]->real_product_id; | 1052 | current_mode = BIT(i); |
1053 | |||
1054 | for (i = 0; i < ARRAY_SIZE(lg4ff_main_checklist); i++) { | ||
1055 | const u16 mask = lg4ff_main_checklist[i]->mask; | ||
1056 | const u16 result = lg4ff_main_checklist[i]->result; | ||
1057 | const u16 real_product_id = lg4ff_main_checklist[i]->real_product_id; | ||
1073 | 1058 | ||
1074 | if ((bcdDevice & mask) == result) { | 1059 | if ((current_mode & lg4ff_main_checklist[i]->modes) && \ |
1060 | (bcdDevice & mask) == result) { | ||
1075 | dbg_hid("Found wheel with real PID %X whose reported PID is %X\n", real_product_id, reported_product_id); | 1061 | dbg_hid("Found wheel with real PID %X whose reported PID is %X\n", real_product_id, reported_product_id); |
1076 | return real_product_id; | 1062 | return real_product_id; |
1077 | } | 1063 | } |