aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-ntrig.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-ntrig.c')
-rw-r--r--drivers/hid/hid-ntrig.c69
1 files changed, 60 insertions, 9 deletions
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index fb69b8c4953f..69169efa1e16 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -90,6 +90,55 @@ struct ntrig_data {
90}; 90};
91 91
92 92
93/*
94 * This function converts the 4 byte raw firmware code into
95 * a string containing 5 comma separated numbers.
96 */
97static int ntrig_version_string(unsigned char *raw, char *buf)
98{
99 __u8 a = (raw[1] & 0x0e) >> 1;
100 __u8 b = (raw[0] & 0x3c) >> 2;
101 __u8 c = ((raw[0] & 0x03) << 3) | ((raw[3] & 0xe0) >> 5);
102 __u8 d = ((raw[3] & 0x07) << 3) | ((raw[2] & 0xe0) >> 5);
103 __u8 e = raw[2] & 0x07;
104
105 /*
106 * As yet unmapped bits:
107 * 0b11000000 0b11110001 0b00011000 0b00011000
108 */
109
110 return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e);
111}
112
113static void ntrig_report_version(struct hid_device *hdev)
114{
115 int ret;
116 char buf[20];
117 struct usb_device *usb_dev = hid_to_usb_dev(hdev);
118 unsigned char *data = kmalloc(8, GFP_KERNEL);
119
120 if (!data)
121 goto err_free;
122
123 ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
124 USB_REQ_CLEAR_FEATURE,
125 USB_TYPE_CLASS | USB_RECIP_INTERFACE |
126 USB_DIR_IN,
127 0x30c, 1, data, 8,
128 USB_CTRL_SET_TIMEOUT);
129
130 if (ret == 8) {
131 ret = ntrig_version_string(&data[2], buf);
132
133 dev_info(&hdev->dev,
134 "Firmware version: %s (%02x%02x %02x%02x)\n",
135 buf, data[2], data[3], data[4], data[5]);
136 }
137
138err_free:
139 kfree(data);
140}
141
93static ssize_t show_phys_width(struct device *dev, 142static ssize_t show_phys_width(struct device *dev,
94 struct device_attribute *attr, 143 struct device_attribute *attr,
95 char *buf) 144 char *buf)
@@ -377,8 +426,8 @@ static struct attribute_group ntrig_attribute_group = {
377 */ 426 */
378 427
379static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, 428static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
380 struct hid_field *field, struct hid_usage *usage, 429 struct hid_field *field, struct hid_usage *usage,
381 unsigned long **bit, int *max) 430 unsigned long **bit, int *max)
382{ 431{
383 struct ntrig_data *nd = hid_get_drvdata(hdev); 432 struct ntrig_data *nd = hid_get_drvdata(hdev);
384 433
@@ -448,13 +497,13 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
448 /* width/height mapped on TouchMajor/TouchMinor/Orientation */ 497 /* width/height mapped on TouchMajor/TouchMinor/Orientation */
449 case HID_DG_WIDTH: 498 case HID_DG_WIDTH:
450 hid_map_usage(hi, usage, bit, max, 499 hid_map_usage(hi, usage, bit, max,
451 EV_ABS, ABS_MT_TOUCH_MAJOR); 500 EV_ABS, ABS_MT_TOUCH_MAJOR);
452 return 1; 501 return 1;
453 case HID_DG_HEIGHT: 502 case HID_DG_HEIGHT:
454 hid_map_usage(hi, usage, bit, max, 503 hid_map_usage(hi, usage, bit, max,
455 EV_ABS, ABS_MT_TOUCH_MINOR); 504 EV_ABS, ABS_MT_TOUCH_MINOR);
456 input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 505 input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
457 0, 1, 0, 0); 506 0, 1, 0, 0);
458 return 1; 507 return 1;
459 } 508 }
460 return 0; 509 return 0;
@@ -468,8 +517,8 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
468} 517}
469 518
470static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, 519static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
471 struct hid_field *field, struct hid_usage *usage, 520 struct hid_field *field, struct hid_usage *usage,
472 unsigned long **bit, int *max) 521 unsigned long **bit, int *max)
473{ 522{
474 /* No special mappings needed for the pen and single touch */ 523 /* No special mappings needed for the pen and single touch */
475 if (field->physical) 524 if (field->physical)
@@ -489,7 +538,7 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
489 * and call input_mt_sync after each point if necessary 538 * and call input_mt_sync after each point if necessary
490 */ 539 */
491static int ntrig_event (struct hid_device *hid, struct hid_field *field, 540static int ntrig_event (struct hid_device *hid, struct hid_field *field,
492 struct hid_usage *usage, __s32 value) 541 struct hid_usage *usage, __s32 value)
493{ 542{
494 struct input_dev *input = field->hidinput->input; 543 struct input_dev *input = field->hidinput->input;
495 struct ntrig_data *nd = hid_get_drvdata(hid); 544 struct ntrig_data *nd = hid_get_drvdata(hid);
@@ -848,6 +897,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
848 if (report) 897 if (report)
849 usbhid_submit_report(hdev, report, USB_DIR_OUT); 898 usbhid_submit_report(hdev, report, USB_DIR_OUT);
850 899
900 ntrig_report_version(hdev);
901
851 ret = sysfs_create_group(&hdev->dev.kobj, 902 ret = sysfs_create_group(&hdev->dev.kobj,
852 &ntrig_attribute_group); 903 &ntrig_attribute_group);
853 904
@@ -860,7 +911,7 @@ err_free:
860static void ntrig_remove(struct hid_device *hdev) 911static void ntrig_remove(struct hid_device *hdev)
861{ 912{
862 sysfs_remove_group(&hdev->dev.kobj, 913 sysfs_remove_group(&hdev->dev.kobj,
863 &ntrig_attribute_group); 914 &ntrig_attribute_group);
864 hid_hw_stop(hdev); 915 hid_hw_stop(hdev);
865 kfree(hid_get_drvdata(hdev)); 916 kfree(hid_get_drvdata(hdev));
866} 917}