diff options
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r-- | drivers/hid/hid-input.c | 97 |
1 files changed, 62 insertions, 35 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index d917c0d53685..21b196c394b1 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -192,7 +192,6 @@ static int hidinput_setkeycode(struct input_dev *dev, | |||
192 | return -EINVAL; | 192 | return -EINVAL; |
193 | } | 193 | } |
194 | 194 | ||
195 | |||
196 | /** | 195 | /** |
197 | * hidinput_calc_abs_res - calculate an absolute axis resolution | 196 | * hidinput_calc_abs_res - calculate an absolute axis resolution |
198 | * @field: the HID report field to calculate resolution for | 197 | * @field: the HID report field to calculate resolution for |
@@ -208,7 +207,7 @@ static int hidinput_setkeycode(struct input_dev *dev, | |||
208 | * Only exponent 1 length units are processed. Centimeters and inches are | 207 | * Only exponent 1 length units are processed. Centimeters and inches are |
209 | * converted to millimeters. Degrees are converted to radians. | 208 | * converted to millimeters. Degrees are converted to radians. |
210 | */ | 209 | */ |
211 | static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | 210 | __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) |
212 | { | 211 | { |
213 | __s32 unit_exponent = field->unit_exponent; | 212 | __s32 unit_exponent = field->unit_exponent; |
214 | __s32 logical_extents = field->logical_maximum - | 213 | __s32 logical_extents = field->logical_maximum - |
@@ -229,17 +228,29 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
229 | case ABS_X: | 228 | case ABS_X: |
230 | case ABS_Y: | 229 | case ABS_Y: |
231 | case ABS_Z: | 230 | case ABS_Z: |
232 | if (field->unit == 0x11) { /* If centimeters */ | 231 | case ABS_MT_POSITION_X: |
232 | case ABS_MT_POSITION_Y: | ||
233 | case ABS_MT_TOOL_X: | ||
234 | case ABS_MT_TOOL_Y: | ||
235 | case ABS_MT_TOUCH_MAJOR: | ||
236 | case ABS_MT_TOUCH_MINOR: | ||
237 | if (field->unit & 0xffffff00) /* Not a length */ | ||
238 | return 0; | ||
239 | unit_exponent += hid_snto32(field->unit >> 4, 4) - 1; | ||
240 | switch (field->unit & 0xf) { | ||
241 | case 0x1: /* If centimeters */ | ||
233 | /* Convert to millimeters */ | 242 | /* Convert to millimeters */ |
234 | unit_exponent += 1; | 243 | unit_exponent += 1; |
235 | } else if (field->unit == 0x13) { /* If inches */ | 244 | break; |
245 | case 0x3: /* If inches */ | ||
236 | /* Convert to millimeters */ | 246 | /* Convert to millimeters */ |
237 | prev = physical_extents; | 247 | prev = physical_extents; |
238 | physical_extents *= 254; | 248 | physical_extents *= 254; |
239 | if (physical_extents < prev) | 249 | if (physical_extents < prev) |
240 | return 0; | 250 | return 0; |
241 | unit_exponent -= 1; | 251 | unit_exponent -= 1; |
242 | } else { | 252 | break; |
253 | default: | ||
243 | return 0; | 254 | return 0; |
244 | } | 255 | } |
245 | break; | 256 | break; |
@@ -281,8 +292,9 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
281 | } | 292 | } |
282 | 293 | ||
283 | /* Calculate resolution */ | 294 | /* Calculate resolution */ |
284 | return logical_extents / physical_extents; | 295 | return DIV_ROUND_CLOSEST(logical_extents, physical_extents); |
285 | } | 296 | } |
297 | EXPORT_SYMBOL_GPL(hidinput_calc_abs_res); | ||
286 | 298 | ||
287 | #ifdef CONFIG_HID_BATTERY_STRENGTH | 299 | #ifdef CONFIG_HID_BATTERY_STRENGTH |
288 | static enum power_supply_property hidinput_battery_props[] = { | 300 | static enum power_supply_property hidinput_battery_props[] = { |
@@ -299,6 +311,9 @@ static enum power_supply_property hidinput_battery_props[] = { | |||
299 | 311 | ||
300 | static const struct hid_device_id hid_battery_quirks[] = { | 312 | static const struct hid_device_id hid_battery_quirks[] = { |
301 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 313 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
314 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), | ||
315 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | ||
316 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
302 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | 317 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
303 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | 318 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
304 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 319 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
@@ -502,9 +517,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
502 | if (code <= 0xf) | 517 | if (code <= 0xf) |
503 | code += BTN_JOYSTICK; | 518 | code += BTN_JOYSTICK; |
504 | else | 519 | else |
505 | code += BTN_TRIGGER_HAPPY; | 520 | code += BTN_TRIGGER_HAPPY - 0x10; |
521 | break; | ||
522 | case HID_GD_GAMEPAD: | ||
523 | if (code <= 0xf) | ||
524 | code += BTN_GAMEPAD; | ||
525 | else | ||
526 | code += BTN_TRIGGER_HAPPY - 0x10; | ||
506 | break; | 527 | break; |
507 | case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break; | ||
508 | default: | 528 | default: |
509 | switch (field->physical) { | 529 | switch (field->physical) { |
510 | case HID_GD_MOUSE: | 530 | case HID_GD_MOUSE: |
@@ -1146,6 +1166,38 @@ static void report_features(struct hid_device *hid) | |||
1146 | } | 1166 | } |
1147 | } | 1167 | } |
1148 | 1168 | ||
1169 | static struct hid_input *hidinput_allocate(struct hid_device *hid) | ||
1170 | { | ||
1171 | struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); | ||
1172 | struct input_dev *input_dev = input_allocate_device(); | ||
1173 | if (!hidinput || !input_dev) { | ||
1174 | kfree(hidinput); | ||
1175 | input_free_device(input_dev); | ||
1176 | hid_err(hid, "Out of memory during hid input probe\n"); | ||
1177 | return NULL; | ||
1178 | } | ||
1179 | |||
1180 | input_set_drvdata(input_dev, hid); | ||
1181 | input_dev->event = hid->ll_driver->hidinput_input_event; | ||
1182 | input_dev->open = hidinput_open; | ||
1183 | input_dev->close = hidinput_close; | ||
1184 | input_dev->setkeycode = hidinput_setkeycode; | ||
1185 | input_dev->getkeycode = hidinput_getkeycode; | ||
1186 | |||
1187 | input_dev->name = hid->name; | ||
1188 | input_dev->phys = hid->phys; | ||
1189 | input_dev->uniq = hid->uniq; | ||
1190 | input_dev->id.bustype = hid->bus; | ||
1191 | input_dev->id.vendor = hid->vendor; | ||
1192 | input_dev->id.product = hid->product; | ||
1193 | input_dev->id.version = hid->version; | ||
1194 | input_dev->dev.parent = hid->dev.parent; | ||
1195 | hidinput->input = input_dev; | ||
1196 | list_add_tail(&hidinput->list, &hid->inputs); | ||
1197 | |||
1198 | return hidinput; | ||
1199 | } | ||
1200 | |||
1149 | /* | 1201 | /* |
1150 | * Register the input device; print a message. | 1202 | * Register the input device; print a message. |
1151 | * Configure the input layer interface | 1203 | * Configure the input layer interface |
@@ -1157,7 +1209,6 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
1157 | struct hid_driver *drv = hid->driver; | 1209 | struct hid_driver *drv = hid->driver; |
1158 | struct hid_report *report; | 1210 | struct hid_report *report; |
1159 | struct hid_input *hidinput = NULL; | 1211 | struct hid_input *hidinput = NULL; |
1160 | struct input_dev *input_dev; | ||
1161 | int i, j, k; | 1212 | int i, j, k; |
1162 | 1213 | ||
1163 | INIT_LIST_HEAD(&hid->inputs); | 1214 | INIT_LIST_HEAD(&hid->inputs); |
@@ -1188,33 +1239,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
1188 | continue; | 1239 | continue; |
1189 | 1240 | ||
1190 | if (!hidinput) { | 1241 | if (!hidinput) { |
1191 | hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); | 1242 | hidinput = hidinput_allocate(hid); |
1192 | input_dev = input_allocate_device(); | 1243 | if (!hidinput) |
1193 | if (!hidinput || !input_dev) { | ||
1194 | kfree(hidinput); | ||
1195 | input_free_device(input_dev); | ||
1196 | hid_err(hid, "Out of memory during hid input probe\n"); | ||
1197 | goto out_unwind; | 1244 | goto out_unwind; |
1198 | } | ||
1199 | |||
1200 | input_set_drvdata(input_dev, hid); | ||
1201 | input_dev->event = | ||
1202 | hid->ll_driver->hidinput_input_event; | ||
1203 | input_dev->open = hidinput_open; | ||
1204 | input_dev->close = hidinput_close; | ||
1205 | input_dev->setkeycode = hidinput_setkeycode; | ||
1206 | input_dev->getkeycode = hidinput_getkeycode; | ||
1207 | |||
1208 | input_dev->name = hid->name; | ||
1209 | input_dev->phys = hid->phys; | ||
1210 | input_dev->uniq = hid->uniq; | ||
1211 | input_dev->id.bustype = hid->bus; | ||
1212 | input_dev->id.vendor = hid->vendor; | ||
1213 | input_dev->id.product = hid->product; | ||
1214 | input_dev->id.version = hid->version; | ||
1215 | input_dev->dev.parent = hid->dev.parent; | ||
1216 | hidinput->input = input_dev; | ||
1217 | list_add_tail(&hidinput->list, &hid->inputs); | ||
1218 | } | 1245 | } |
1219 | 1246 | ||
1220 | for (i = 0; i < report->maxfield; i++) | 1247 | for (i = 0; i < report->maxfield; i++) |