aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Wood <simon@mungewell.org>2015-11-02 09:56:51 -0500
committerJiri Kosina <jkosina@suse.cz>2015-11-06 15:18:05 -0500
commitbbec1bd0faa211a0a0abaf947cd4a236d080ad28 (patch)
tree7c1d61b6215fa5af6e77d01e4c7530cc73e2ecba
parent90cdd986335eddb7cac6e456f7c48c1ce76fd095 (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.c70
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
116struct lg4ff_wheel_ident_info { 116struct 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
122struct lg4ff_wheel_ident_checklist {
123 const u32 count;
124 const struct lg4ff_wheel_ident_info *models[];
125};
126
127struct lg4ff_multimode_wheel { 123struct 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 */
176static const struct lg4ff_wheel_ident_info lg4ff_dfp_ident_info = { 172static 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
182static const struct lg4ff_wheel_ident_info lg4ff_g25_ident_info = { 179static 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
188static const struct lg4ff_wheel_ident_info lg4ff_g27_ident_info = { 186static 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
194static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = { 193static 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 */
201static const struct lg4ff_wheel_ident_checklist lg4ff_main_checklist = { 201static 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
1038static u16 lg4ff_identify_multimode_wheel(struct hid_device *hid, const u16 reported_product_id, const u16 bcdDevice) 1037static 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 }