* [PATCH 1/2] HID: N-trig Add set feature commands to driver @ 2010-03-22 12:16 micki 2010-03-22 12:16 ` [PATCH 2/2] HID:HID-NTRIG update ntrig_event function micki 2010-03-22 17:29 ` [PATCH 1/2] HID: N-trig Add set feature commands to driver Rafi Rubin 0 siblings, 2 replies; 10+ messages in thread From: micki @ 2010-03-22 12:16 UTC (permalink / raw) To: jkosina, rafi, chatty, peterhuewe, micki; +Cc: linux-input, linux-kernel From: micki <micki@micki-laptop.(none)> Add set feature commands to initialize N-trig firwmare. Add debug option to driver, Add Macro. Update probe function, delete name allocation caused kernel panaic Signed-off-by: Micki Balanga <micki@n-trig.com> --- drivers/hid/hid-ntrig.c | 169 +++++++++++++++++++++++++++++++++++----------- 1 files changed, 128 insertions(+), 41 deletions(-) diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index edcc0c4..b4a573b 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -3,6 +3,7 @@ * * Copyright (c) 2008 Rafi Rubin * Copyright (c) 2009 Stephane Chatty + * Copyright (c) 2010 N-TRIG * */ @@ -16,8 +17,77 @@ #include <linux/device.h> #include <linux/hid.h> #include <linux/module.h> +#include <linux/usb.h> #include "hid-ids.h" +#include "usbhid/usbhid.h" +/* + * Pen Event Field Declaration + */ +#define EVENT_PEN_TIP 0x03 +#define EVENT_PEN_RIGHT 0x05 +#define EVENT_TOUCH_PEN 0x07 +#define EVENT_PEN_IN_RANGE 0x01 + +/* + * MTM 4 last bytes of report descriptor + */ +#define REPORT_GENERIC1 0x01 +#define REPORT_MT 0x02 +#define REPORT_PALM 0x03 +#define REPORT_GENERIC2 0x04 + +#define NTRIG_USB_DEVICE_ID 0x0001 + +/* + * MTM fields + */ +#define MAX_FINGERS_SUPPORT 0x06 +#define END_OF_REPORT 0x64 + +/* + * Dummy Finger Declaration + */ +#define DUMMY_X_CORD_VAL 0x00 +#define DUMMY_Y_CORD_VAL 0x00 +#define DUMMY_DX_CORD_VAL 0xFA +#define DUMMY_DY_CORD_VAL 0x96 +#define DUMMY_GENERIC_BYTE_VAL 0x0D + +/* + * MTM Parse Event + */ +#define MTM_FRAME_INDEX 0xff000001 +#define MTM_PROPROETARY 0xff000002 + +/* + * MTM Set Feature Commands + */ +#define REPORTID_DRIVER_ALIVE 0x0A +#define REPORTID_CALIBRATION 0x0B +#define REPORTID_GET_VERSION 0x0C +#define REPORTID_GET_MODE 0x0D +#define REPORTID_SET_MODE_PEN 0x0E +#define REPORTID_SET_MODE_TOUCH 0x0F +#define REPORTID_SET_MODE_DUAL 0x10 +#define REPORTID_CALIBRATION_RESPOND 0x11 +#define HID_CAPACITORS_CALIB 0x12 +#define HID_GET_CAPACITORS_CALIB_DONE 0x13 + + +static int debug; + +#define MODULE_NAME "hid_ntrig" + + +#define info(format, arg...) \ + printk(KERN_INFO "%s: " format , MODULE_NAME , ## arg) +#define ntrig_dbg(format, arg...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG "%s: " format, \ + MODULE_NAME , ## arg); \ + } while (0) #define NTRIG_DUPLICATE_USAGES 0x001 @@ -123,8 +193,8 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, * decide whether we are in multi or single touch mode * and call input_mt_sync after each point if necessary */ -static int ntrig_event (struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) +static int ntrig_event(struct hid_device *hid, struct hid_field *field, + struct hid_usage *usage, __s32 value) { struct input_dev *input = field->hidinput->input; struct ntrig_data *nd = hid_get_drvdata(hid); @@ -133,7 +203,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, if (field->application == HID_DG_PEN) return 0; - if (hid->claimed & HID_CLAIMED_INPUT) { + if (hid->claimed & HID_CLAIMED_INPUT) { switch (usage->hid) { case 0xff000001: /* Tag indicating the start of a multitouch group */ @@ -279,12 +349,58 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, return 1; } +/* + * This function used to configure N-trig firmware + * The first command we need to send to firmware is change + * to Multi-touch Mode we don't receive a reply + */ +static int ntrig_send_report(struct hid_device *hid) +{ + struct hid_report *report; + struct list_head *report_list = + &hid->report_enum[HID_FEATURE_REPORT].report_list; + + if (list_empty(report_list)) { + ntrig_dbg("no feature reports found\n"); + return -ENODEV; + } + report = list_first_entry(report_list, struct hid_report, list); + if (report->maxfield < 1) + return -ENODEV; + + list_for_each_entry(report, + report_list, list) { + if (report->maxfield < 1) { + ntrig_dbg("no fields in the report\n"); + continue; + } + ntrig_dbg("report id %x\n", report->id); + switch (report->id) { + case REPORTID_DRIVER_ALIVE: + usbhid_submit_report(hid, report, USB_DIR_OUT); + break; + /* + * These command will implement later accroding to demand + */ + case REPORTID_GET_VERSION: /* FALLTHRU */ + case REPORTID_SET_MODE_DUAL: /* FALLTHRU */ + case REPORTID_CALIBRATION: /* FALLTHRU */ + case REPORTID_GET_MODE: /* FALLTHRU */ + case REPORTID_SET_MODE_PEN: /* FALLTHRU */ + case REPORTID_SET_MODE_TOUCH: /* FALLTHRU */ + case REPORTID_CALIBRATION_RESPOND:/* FALLTHRU */ + case HID_CAPACITORS_CALIB: /* FALLTHRU */ + case HID_GET_CAPACITORS_CALIB_DONE: + break; + } + } + return 0; +} + static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; struct ntrig_data *nd; - struct hid_input *hidinput; - struct input_dev *input; if (id->driver_data) hdev->quirks |= HID_QUIRK_MULTI_INPUT; @@ -310,42 +426,10 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err_free; } - - list_for_each_entry(hidinput, &hdev->inputs, list) { - if (hidinput->report->maxfield < 1) - continue; - - input = hidinput->input; - switch (hidinput->report->field[0]->application) { - case HID_DG_PEN: - input->name = "N-Trig Pen"; - break; - case HID_DG_TOUCHSCREEN: - /* These keys are redundant for fingers, clear them - * to prevent incorrect identification */ - __clear_bit(BTN_TOOL_PEN, input->keybit); - __clear_bit(BTN_TOOL_FINGER, input->keybit); - __clear_bit(BTN_0, input->keybit); - /* - * A little something special to enable - * two and three finger taps. - */ - __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); - __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); - __set_bit(BTN_TOOL_QUADTAP, input->keybit); - /* - * The physical touchscreen (single touch) - * input has a value for physical, whereas - * the multitouch only has logical input - * fields. - */ - input->name = - (hidinput->report->field[0] - ->physical) ? - "N-Trig Touchscreen" : - "N-Trig MultiTouch"; - break; - } + ret = ntrig_send_report(hdev); + if (ret) { + dev_err(&hdev->dev, "send set feature failed\n"); + goto err_free; } return 0; @@ -395,4 +479,7 @@ static void __exit ntrig_exit(void) module_init(ntrig_init); module_exit(ntrig_exit); + +MODULE_PARM_DESC(debug, "Debug mode enable disable"); +module_param(debug, bool, 0644); MODULE_LICENSE("GPL"); -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/2] HID:HID-NTRIG update ntrig_event function 2010-03-22 12:16 [PATCH 1/2] HID: N-trig Add set feature commands to driver micki @ 2010-03-22 12:16 ` micki 2010-03-22 18:06 ` Rafi Rubin 2010-03-22 17:29 ` [PATCH 1/2] HID: N-trig Add set feature commands to driver Rafi Rubin 1 sibling, 1 reply; 10+ messages in thread From: micki @ 2010-03-22 12:16 UTC (permalink / raw) To: jkosina, rafi, chatty, peterhuewe, micki; +Cc: linux-input, linux-kernel From: micki <micki@n-trig.com> This patch is a part of 2 patches sumbitted by N-trig to hid-ntrig driver. The driver send events to a user space application which will translate the events (ignore ghost events, calcuate real X,Y coorindate, add palm). Fake Finger events used by the user space applicaition to anaylze the information recevied by N-trig sensor. User space application (for any linux distro) will be available at N-trig website. The driver seprarate pen finger events because the user space application each device seperatly. N-trig will maintian the driver in the kernel(Bug fix, New feautres) Signed-off-by: Micki Balanga <micki@n-trig.com> --- drivers/hid/hid-ntrig.c | 326 ++++++++++++++++++++++++----------------------- 1 files changed, 167 insertions(+), 159 deletions(-) diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index b4a573b..9f1b916 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -89,22 +89,25 @@ static int debug; MODULE_NAME , ## arg); \ } while (0) -#define NTRIG_DUPLICATE_USAGES 0x001 - -#define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) - +/* + * N-trig HID Report Structure + * The driver will support MTM firwmare Pen, Fingers + */ struct ntrig_data { - /* Incoming raw values for a single contact */ - __u16 x, y, w, h; - __u16 id; - __u8 confidence; - - bool reading_mt; - __u8 first_contact_confidence; - - __u8 mt_footer[4]; - __u8 mt_foot_count; + __u8 pressure; + __u8 events; + __s32 btn_pressed; + __u16 x; + __u16 y; + __u16 frame_index; + __u8 finger_id; + __u16 dx; + __u16 dy; + __u8 generic_byte; + __u8 isPalm; + __u8 msc_cnt; + __u8 real_fingers; + __u8 fake_fingers; }; /* @@ -117,10 +120,6 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { - /* No special mappings needed for the pen and single touch */ - if (field->physical) - return 0; - switch (usage->hid & HID_USAGE_PAGE) { case HID_UP_GENDESK: switch (usage->hid) { @@ -144,6 +143,9 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_UP_DIGITIZER: switch (usage->hid) { /* we do not want to map these for now */ + case HID_DG_INVERT: /* Not support by pen */ + case HID_DG_ERASER: /* Not support by pen */ + case HID_DG_CONTACTID: /* Not trustworthy, squelch for now */ case HID_DG_INPUTMODE: case HID_DG_DEVICEINDEX: @@ -158,8 +160,8 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MINOR); - input_set_abs_params(hi->input, ABS_MT_ORIENTATION, - 0, 1, 0, 0); + hid_map_usage(hi, usage, bit, max, + EV_ABS, ABS_MT_TRACKING_ID); return 1; } return 0; @@ -176,13 +178,21 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { - /* No special mappings needed for the pen and single touch */ - if (field->physical) - return 0; - - if (usage->type == EV_KEY || usage->type == EV_REL - || usage->type == EV_ABS) - clear_bit(usage->code, *bit); + /* + * Map Keys For Pen And Touch events + * MSC events used to transfer information about finger status + * In curent Frame + */ + struct input_dev *input = hi->input; + set_bit(BTN_LEFT, input->keybit); + set_bit(BTN_RIGHT, input->keybit); + set_bit(EV_MSC, input->evbit); + set_bit(MSC_GESTURE, input->mscbit); + set_bit(MSC_SERIAL, input->mscbit); + set_bit(MSC_RAW, input->mscbit); + + input_set_abs_params(hi->input, ABS_PRESSURE, + 0/*Min*/, 255 /*Max*/, 0, 0); return 0; } @@ -199,146 +209,154 @@ static int ntrig_event(struct hid_device *hid, struct hid_field *field, struct input_dev *input = field->hidinput->input; struct ntrig_data *nd = hid_get_drvdata(hid); - /* No special handling needed for the pen */ - if (field->application == HID_DG_PEN) - return 0; - if (hid->claimed & HID_CLAIMED_INPUT) { + /* + * Update Common Fields For Pen and MultiTouch + */ switch (usage->hid) { - case 0xff000001: - /* Tag indicating the start of a multitouch group */ - nd->reading_mt = 1; - nd->first_contact_confidence = 0; - break; - case HID_DG_TIPSWITCH: - /* Prevent emission of touch until validated */ - return 1; - case HID_DG_CONFIDENCE: - nd->confidence = value; - break; case HID_GD_X: nd->x = value; - /* Clear the contact footer */ - nd->mt_foot_count = 0; break; case HID_GD_Y: nd->y = value; break; - case HID_DG_CONTACTID: - nd->id = value; - break; - case HID_DG_WIDTH: - nd->w = value; - break; - case HID_DG_HEIGHT: - nd->h = value; - /* - * when in single touch mode, this is the last - * report received in a finger event. We want - * to emit a normal (X, Y) position - */ - if (!nd->reading_mt) { - input_report_key(input, BTN_TOOL_DOUBLETAP, - (nd->confidence != 0)); - input_event(input, EV_ABS, ABS_X, nd->x); - input_event(input, EV_ABS, ABS_Y, nd->y); - } - break; - case 0xff000002: + } + if (field->application == HID_DG_PEN) { /* - * we receive this when the device is in multitouch - * mode. The first of the three values tagged with - * this usage tells if the contact point is real - * or a placeholder + * Pen Button state */ - - /* Shouldn't get more than 4 footer packets, so skip */ - if (nd->mt_foot_count >= 4) + switch (usage->hid) { + case HID_DG_INRANGE: + nd->events = value; break; - - nd->mt_footer[nd->mt_foot_count++] = value; - - /* if the footer isn't complete break */ - if (nd->mt_foot_count != 4) + case HID_DG_TIPSWITCH: + nd->events |= (value << 1); break; - - /* Pen activity signal, trigger end of touch. */ - if (nd->mt_footer[2]) { - nd->confidence = 0; + case HID_DG_BARRELSWITCH: + nd->events |= (value << 2); break; - } - - /* If the contact was invalid */ - if (!(nd->confidence && nd->mt_footer[0]) - || nd->w <= 250 - || nd->h <= 190) { - nd->confidence = 0; + case HID_DG_INVERT: + nd->events |= (value << 3); break; + case HID_DG_ERASER: + nd->events |= (value << 4); + break; + case HID_DG_TIPPRESSURE: + /* + * Last Report Received For Pen Event + */ + nd->pressure = value; + input_report_abs(input, ABS_MT_TOOL_TYPE, + MT_TOOL_PEN); + input_report_abs(input, ABS_MT_POSITION_X, + nd->x); + input_report_abs(input, ABS_MT_POSITION_Y, + nd->y); + /* + * Handle Button Code + */ + switch (nd->events) { + case EVENT_PEN_IN_RANGE: + if (0 != nd->btn_pressed) { + input_event(input, EV_KEY, + nd->btn_pressed, 0x00); + nd->btn_pressed = 0; + } + break; + case EVENT_PEN_TIP: + if (BTN_LEFT != nd->btn_pressed) { + nd->btn_pressed = BTN_LEFT; + input_event(input, EV_KEY, + nd->btn_pressed, 0x01); + } + break; + case EVENT_TOUCH_PEN: /* FALLTHRU */ + case EVENT_PEN_RIGHT: + if (BTN_RIGHT != nd->btn_pressed) { + nd->btn_pressed = BTN_RIGHT; + input_event(input, EV_KEY, + nd->btn_pressed, 0x01); + } + break; + } + input_report_abs(input, ABS_PRESSURE, + nd->pressure); + input_sync(input); + ntrig_dbg("X=%d Y=%d Button=%d Pressure=%d\n", + nd->x, nd->y, + nd->btn_pressed, nd->pressure); } - - /* emit a normal (X, Y) for the first point only */ - if (nd->id == 0) { - nd->first_contact_confidence = nd->confidence; - input_event(input, EV_ABS, ABS_X, nd->x); - input_event(input, EV_ABS, ABS_Y, nd->y); - } - input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); - input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); - if (nd->w > nd->h) { - input_event(input, EV_ABS, - ABS_MT_ORIENTATION, 1); - input_event(input, EV_ABS, - ABS_MT_TOUCH_MAJOR, nd->w); - input_event(input, EV_ABS, - ABS_MT_TOUCH_MINOR, nd->h); - } else { - input_event(input, EV_ABS, - ABS_MT_ORIENTATION, 0); - input_event(input, EV_ABS, - ABS_MT_TOUCH_MAJOR, nd->h); - input_event(input, EV_ABS, - ABS_MT_TOUCH_MINOR, nd->w); - } - input_mt_sync(field->hidinput->input); - break; - - case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ - if (!nd->reading_mt) + } else { /* MultiTouch Report */ + switch (usage->hid) { + case HID_DG_CONTACTCOUNT: + nd->real_fingers = value; + nd->fake_fingers = MAX_FINGERS_SUPPORT - value; break; - - nd->reading_mt = 0; - - if (nd->first_contact_confidence) { - switch (value) { - case 0: /* for single touch devices */ - case 1: - input_report_key(input, - BTN_TOOL_DOUBLETAP, 1); + case MTM_FRAME_INDEX: /* Index 1 */ + nd->frame_index = value; + break; + case HID_DG_TIPSWITCH: /* FALLTHRU */ + case HID_DG_INRANGE: /* FALLTHRU */ + case HID_DG_CONFIDENCE: /* Not Relevant-Index 2 - 4 */ + break; + case HID_DG_CONTACTID: /* Index 5 */ + nd->finger_id = value; + break; + case HID_DG_WIDTH:/* Index 6 - 7*/ + nd->dx = value; + break; + case HID_DG_HEIGHT:/* Index 8 - 9 */ + nd->dy = value; + /* Start The Sequence of MSC bytes */ + nd->msc_cnt = 0; + break; + case MTM_PROPROETARY:/* Index 10 - 14 */ + nd->msc_cnt++; + switch (nd->msc_cnt) { + case REPORT_GENERIC1: + nd->generic_byte = value; + break; + case REPORT_MT: break; - case 2: - input_report_key(input, - BTN_TOOL_TRIPLETAP, 1); + case REPORT_PALM: + nd->isPalm = value; + break; + case REPORT_GENERIC2: + if ((DUMMY_X_CORD_VAL == nd->x) && (DUMMY_Y_CORD_VAL == nd->y) && + (DUMMY_DX_CORD_VAL == nd->dx) && (DUMMY_DY_CORD_VAL == nd->dy) && + (DUMMY_GENERIC_BYTE_VAL == value)) { + if (MAX_FINGERS_SUPPORT == nd->fake_fingers--) { + input_report_abs(input, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); + input_report_abs(input, ABS_MT_TRACKING_ID, END_OF_REPORT); + input_event(input, EV_MSC, MSC_RAW, nd->frame_index); + input_sync(input); + ntrig_dbg("Session Sync Frame %x\n", nd->frame_index); + } else + ntrig_dbg("Fake Finger %x\n", nd->frame_index); + } else { + input_report_abs(input, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); + input_report_abs(input, ABS_MT_TRACKING_ID, nd->finger_id); + input_report_abs(input, ABS_MT_POSITION_X, nd->x); + input_report_abs(input, ABS_MT_POSITION_Y, nd->y); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, nd->dx); + input_report_abs(input, ABS_MT_TOUCH_MINOR, nd->dy); + input_event(input, EV_MSC, MSC_GESTURE, nd->generic_byte); + input_event(input, EV_MSC, MSC_SERIAL, nd->isPalm); + input_mt_sync(input); + ntrig_dbg("Real Finger Index %x Count %d X=%d Y=%d DX=%d DY=%d FirstOccur=%d Palm=%d\n", + nd->frame_index, nd->real_fingers, nd->x, + nd->y, nd->dx, nd->dy, + nd->generic_byte, nd->isPalm); + if (0 == --nd->real_fingers) { + input_event(input, EV_MSC, MSC_RAW, nd->frame_index); + input_sync(input); + ntrig_dbg("Real Finger Sync Frame %x\n", nd->frame_index); + } + } break; - case 3: - default: - input_report_key(input, - BTN_TOOL_QUADTAP, 1); } - input_report_key(input, BTN_TOUCH, 1); - } else { - input_report_key(input, - BTN_TOOL_DOUBLETAP, 0); - input_report_key(input, - BTN_TOOL_TRIPLETAP, 0); - input_report_key(input, - BTN_TOOL_QUADTAP, 0); - input_report_key(input, BTN_TOUCH, 0); + break; } - break; - - default: - /* fallback to the generic hidinput handling */ - return 0; } } @@ -402,16 +420,12 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) int ret; struct ntrig_data *nd; - if (id->driver_data) - hdev->quirks |= HID_QUIRK_MULTI_INPUT; - nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); if (!nd) { dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); return -ENOMEM; } - nd->reading_mt = 0; hid_set_drvdata(hdev, nd); ret = hid_parse(hdev); @@ -446,16 +460,11 @@ static void ntrig_remove(struct hid_device *hdev) static const struct hid_device_id ntrig_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN), - .driver_data = NTRIG_DUPLICATE_USAGES }, + .driver_data = NTRIG_USB_DEVICE_ID }, { } }; MODULE_DEVICE_TABLE(hid, ntrig_devices); -static const struct hid_usage_id ntrig_grabbed_usages[] = { - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } -}; - static struct hid_driver ntrig_driver = { .name = "ntrig", .id_table = ntrig_devices, @@ -463,7 +472,6 @@ static struct hid_driver ntrig_driver = { .remove = ntrig_remove, .input_mapping = ntrig_input_mapping, .input_mapped = ntrig_input_mapped, - .usage_table = ntrig_grabbed_usages, .event = ntrig_event, }; -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] HID:HID-NTRIG update ntrig_event function 2010-03-22 12:16 ` [PATCH 2/2] HID:HID-NTRIG update ntrig_event function micki @ 2010-03-22 18:06 ` Rafi Rubin 0 siblings, 0 replies; 10+ messages in thread From: Rafi Rubin @ 2010-03-22 18:06 UTC (permalink / raw) To: micki; +Cc: jkosina, chatty, peterhuewe, linux-input, linux-kernel On Mon, Mar 22, 2010 at 02:16:13PM +0200, micki@n-trig.com wrote: > From: micki <micki@n-trig.com> Again this commit message looks documentation, discussion, and a hit of advertising (though thankfully not like the previous patches). There are other places for all those. > This patch is a part of 2 patches sumbitted by N-trig to hid-ntrig driver. > The driver send events to a user space application which will translate > the events (ignore ghost events, calcuate real X,Y coorindate, add palm). > Fake Finger events used by the user space applicaition to anaylze the information > recevied by N-trig sensor. Might want to explain the behavior of the driver as comments in the code, or for a longer discussion, put something in the Documentation tree. Um, you still haven't really explained fake fingers, every event emitted offers information for the user space applications to analyze. Moving past the meaning of fake fingers, you still haven't explained why you bother with an extra field and extra instructions to compute information already expressed with real_fingers. It appears wasteful and convoluted. > User space application (for any linux distro) will be available at N-trig website. > The driver seprarate pen finger events because the user space application each device seperatly. > N-trig will maintian the driver in the kernel(Bug fix, New feautres) You keep talking about things that _will_ be available on the website. Do you have any reason to hold back on utilities which do not require your changes to the kernel, such as possibly the firmware loader? Also its not actually all that clear without careful analysis of how you separate pen and touch, particularly in light of removing the multi-input quirk which causes the hid framework to do that automatically. As for your choice of key/button mappings, perhaps Jiri can suggest which events are most apropriate for the tip, barrel, and eraser switches. I've been letting hid-input.c assign those mappings, and its choice of TOUCH, STYLUS, and RUBBER oddly enough seem to work well with the user space drivers. We can discuss protocol further once you address the question about the multi input quirk. Rafi > Signed-off-by: Micki Balanga <micki@n-trig.com> > --- > drivers/hid/hid-ntrig.c | 326 ++++++++++++++++++++++++----------------------- > 1 files changed, 167 insertions(+), 159 deletions(-) > > diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c > index b4a573b..9f1b916 100644 > --- a/drivers/hid/hid-ntrig.c > +++ b/drivers/hid/hid-ntrig.c > @@ -89,22 +89,25 @@ static int debug; > MODULE_NAME , ## arg); \ > } while (0) > > -#define NTRIG_DUPLICATE_USAGES 0x001 > - > -#define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ > - EV_KEY, (c)) > - > +/* > + * N-trig HID Report Structure > + * The driver will support MTM firwmare Pen, Fingers > + */ > struct ntrig_data { > - /* Incoming raw values for a single contact */ > - __u16 x, y, w, h; > - __u16 id; > - __u8 confidence; > - > - bool reading_mt; > - __u8 first_contact_confidence; > - > - __u8 mt_footer[4]; > - __u8 mt_foot_count; > + __u8 pressure; > + __u8 events; > + __s32 btn_pressed; > + __u16 x; > + __u16 y; > + __u16 frame_index; > + __u8 finger_id; > + __u16 dx; > + __u16 dy; > + __u8 generic_byte; > + __u8 isPalm; > + __u8 msc_cnt; > + __u8 real_fingers; > + __u8 fake_fingers; > }; > > /* > @@ -117,10 +120,6 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, > struct hid_field *field, struct hid_usage *usage, > unsigned long **bit, int *max) > { > - /* No special mappings needed for the pen and single touch */ > - if (field->physical) > - return 0; > - > switch (usage->hid & HID_USAGE_PAGE) { > case HID_UP_GENDESK: > switch (usage->hid) { > @@ -144,6 +143,9 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, > case HID_UP_DIGITIZER: > switch (usage->hid) { > /* we do not want to map these for now */ > + case HID_DG_INVERT: /* Not support by pen */ > + case HID_DG_ERASER: /* Not support by pen */ > + > case HID_DG_CONTACTID: /* Not trustworthy, squelch for now */ > case HID_DG_INPUTMODE: > case HID_DG_DEVICEINDEX: > @@ -158,8 +160,8 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, > case HID_DG_HEIGHT: > hid_map_usage(hi, usage, bit, max, > EV_ABS, ABS_MT_TOUCH_MINOR); > - input_set_abs_params(hi->input, ABS_MT_ORIENTATION, > - 0, 1, 0, 0); > + hid_map_usage(hi, usage, bit, max, > + EV_ABS, ABS_MT_TRACKING_ID); > return 1; > } > return 0; > @@ -176,13 +178,21 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, > struct hid_field *field, struct hid_usage *usage, > unsigned long **bit, int *max) > { > - /* No special mappings needed for the pen and single touch */ > - if (field->physical) > - return 0; > - > - if (usage->type == EV_KEY || usage->type == EV_REL > - || usage->type == EV_ABS) > - clear_bit(usage->code, *bit); > + /* > + * Map Keys For Pen And Touch events > + * MSC events used to transfer information about finger status > + * In curent Frame > + */ > + struct input_dev *input = hi->input; > + set_bit(BTN_LEFT, input->keybit); > + set_bit(BTN_RIGHT, input->keybit); > + set_bit(EV_MSC, input->evbit); > + set_bit(MSC_GESTURE, input->mscbit); > + set_bit(MSC_SERIAL, input->mscbit); > + set_bit(MSC_RAW, input->mscbit); > + > + input_set_abs_params(hi->input, ABS_PRESSURE, > + 0/*Min*/, 255 /*Max*/, 0, 0); > > return 0; > } > @@ -199,146 +209,154 @@ static int ntrig_event(struct hid_device *hid, struct hid_field *field, > struct input_dev *input = field->hidinput->input; > struct ntrig_data *nd = hid_get_drvdata(hid); > > - /* No special handling needed for the pen */ > - if (field->application == HID_DG_PEN) > - return 0; > - > if (hid->claimed & HID_CLAIMED_INPUT) { > + /* > + * Update Common Fields For Pen and MultiTouch > + */ > switch (usage->hid) { > - case 0xff000001: > - /* Tag indicating the start of a multitouch group */ > - nd->reading_mt = 1; > - nd->first_contact_confidence = 0; > - break; > - case HID_DG_TIPSWITCH: > - /* Prevent emission of touch until validated */ > - return 1; > - case HID_DG_CONFIDENCE: > - nd->confidence = value; > - break; > case HID_GD_X: > nd->x = value; > - /* Clear the contact footer */ > - nd->mt_foot_count = 0; > break; > case HID_GD_Y: > nd->y = value; > break; > - case HID_DG_CONTACTID: > - nd->id = value; > - break; > - case HID_DG_WIDTH: > - nd->w = value; > - break; > - case HID_DG_HEIGHT: > - nd->h = value; > - /* > - * when in single touch mode, this is the last > - * report received in a finger event. We want > - * to emit a normal (X, Y) position > - */ > - if (!nd->reading_mt) { > - input_report_key(input, BTN_TOOL_DOUBLETAP, > - (nd->confidence != 0)); > - input_event(input, EV_ABS, ABS_X, nd->x); > - input_event(input, EV_ABS, ABS_Y, nd->y); > - } > - break; > - case 0xff000002: > + } > + if (field->application == HID_DG_PEN) { > /* > - * we receive this when the device is in multitouch > - * mode. The first of the three values tagged with > - * this usage tells if the contact point is real > - * or a placeholder > + * Pen Button state > */ > - > - /* Shouldn't get more than 4 footer packets, so skip */ > - if (nd->mt_foot_count >= 4) > + switch (usage->hid) { > + case HID_DG_INRANGE: > + nd->events = value; > break; > - > - nd->mt_footer[nd->mt_foot_count++] = value; > - > - /* if the footer isn't complete break */ > - if (nd->mt_foot_count != 4) > + case HID_DG_TIPSWITCH: > + nd->events |= (value << 1); > break; > - > - /* Pen activity signal, trigger end of touch. */ > - if (nd->mt_footer[2]) { > - nd->confidence = 0; > + case HID_DG_BARRELSWITCH: > + nd->events |= (value << 2); > break; > - } > - > - /* If the contact was invalid */ > - if (!(nd->confidence && nd->mt_footer[0]) > - || nd->w <= 250 > - || nd->h <= 190) { > - nd->confidence = 0; > + case HID_DG_INVERT: > + nd->events |= (value << 3); > break; > + case HID_DG_ERASER: > + nd->events |= (value << 4); > + break; > + case HID_DG_TIPPRESSURE: > + /* > + * Last Report Received For Pen Event > + */ > + nd->pressure = value; > + input_report_abs(input, ABS_MT_TOOL_TYPE, > + MT_TOOL_PEN); > + input_report_abs(input, ABS_MT_POSITION_X, > + nd->x); > + input_report_abs(input, ABS_MT_POSITION_Y, > + nd->y); > + /* > + * Handle Button Code > + */ > + switch (nd->events) { > + case EVENT_PEN_IN_RANGE: > + if (0 != nd->btn_pressed) { > + input_event(input, EV_KEY, > + nd->btn_pressed, 0x00); > + nd->btn_pressed = 0; > + } > + break; > + case EVENT_PEN_TIP: > + if (BTN_LEFT != nd->btn_pressed) { > + nd->btn_pressed = BTN_LEFT; > + input_event(input, EV_KEY, > + nd->btn_pressed, 0x01); > + } > + break; > + case EVENT_TOUCH_PEN: /* FALLTHRU */ > + case EVENT_PEN_RIGHT: > + if (BTN_RIGHT != nd->btn_pressed) { > + nd->btn_pressed = BTN_RIGHT; > + input_event(input, EV_KEY, > + nd->btn_pressed, 0x01); > + } > + break; > + } > + input_report_abs(input, ABS_PRESSURE, > + nd->pressure); > + input_sync(input); > + ntrig_dbg("X=%d Y=%d Button=%d Pressure=%d\n", > + nd->x, nd->y, > + nd->btn_pressed, nd->pressure); > } > - > - /* emit a normal (X, Y) for the first point only */ > - if (nd->id == 0) { > - nd->first_contact_confidence = nd->confidence; > - input_event(input, EV_ABS, ABS_X, nd->x); > - input_event(input, EV_ABS, ABS_Y, nd->y); > - } > - input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); > - input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); > - if (nd->w > nd->h) { > - input_event(input, EV_ABS, > - ABS_MT_ORIENTATION, 1); > - input_event(input, EV_ABS, > - ABS_MT_TOUCH_MAJOR, nd->w); > - input_event(input, EV_ABS, > - ABS_MT_TOUCH_MINOR, nd->h); > - } else { > - input_event(input, EV_ABS, > - ABS_MT_ORIENTATION, 0); > - input_event(input, EV_ABS, > - ABS_MT_TOUCH_MAJOR, nd->h); > - input_event(input, EV_ABS, > - ABS_MT_TOUCH_MINOR, nd->w); > - } > - input_mt_sync(field->hidinput->input); > - break; > - > - case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ > - if (!nd->reading_mt) > + } else { /* MultiTouch Report */ > + switch (usage->hid) { > + case HID_DG_CONTACTCOUNT: > + nd->real_fingers = value; > + nd->fake_fingers = MAX_FINGERS_SUPPORT - value; > break; > - > - nd->reading_mt = 0; > - > - if (nd->first_contact_confidence) { > - switch (value) { > - case 0: /* for single touch devices */ > - case 1: > - input_report_key(input, > - BTN_TOOL_DOUBLETAP, 1); > + case MTM_FRAME_INDEX: /* Index 1 */ > + nd->frame_index = value; > + break; > + case HID_DG_TIPSWITCH: /* FALLTHRU */ > + case HID_DG_INRANGE: /* FALLTHRU */ > + case HID_DG_CONFIDENCE: /* Not Relevant-Index 2 - 4 */ > + break; > + case HID_DG_CONTACTID: /* Index 5 */ > + nd->finger_id = value; > + break; > + case HID_DG_WIDTH:/* Index 6 - 7*/ > + nd->dx = value; > + break; > + case HID_DG_HEIGHT:/* Index 8 - 9 */ > + nd->dy = value; > + /* Start The Sequence of MSC bytes */ > + nd->msc_cnt = 0; > + break; > + case MTM_PROPROETARY:/* Index 10 - 14 */ > + nd->msc_cnt++; > + switch (nd->msc_cnt) { > + case REPORT_GENERIC1: > + nd->generic_byte = value; > + break; > + case REPORT_MT: > break; > - case 2: > - input_report_key(input, > - BTN_TOOL_TRIPLETAP, 1); > + case REPORT_PALM: > + nd->isPalm = value; > + break; > + case REPORT_GENERIC2: > + if ((DUMMY_X_CORD_VAL == nd->x) && (DUMMY_Y_CORD_VAL == nd->y) && > + (DUMMY_DX_CORD_VAL == nd->dx) && (DUMMY_DY_CORD_VAL == nd->dy) && > + (DUMMY_GENERIC_BYTE_VAL == value)) { > + if (MAX_FINGERS_SUPPORT == nd->fake_fingers--) { > + input_report_abs(input, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); > + input_report_abs(input, ABS_MT_TRACKING_ID, END_OF_REPORT); > + input_event(input, EV_MSC, MSC_RAW, nd->frame_index); > + input_sync(input); > + ntrig_dbg("Session Sync Frame %x\n", nd->frame_index); > + } else > + ntrig_dbg("Fake Finger %x\n", nd->frame_index); > + } else { > + input_report_abs(input, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); > + input_report_abs(input, ABS_MT_TRACKING_ID, nd->finger_id); > + input_report_abs(input, ABS_MT_POSITION_X, nd->x); > + input_report_abs(input, ABS_MT_POSITION_Y, nd->y); > + input_report_abs(input, ABS_MT_TOUCH_MAJOR, nd->dx); > + input_report_abs(input, ABS_MT_TOUCH_MINOR, nd->dy); > + input_event(input, EV_MSC, MSC_GESTURE, nd->generic_byte); > + input_event(input, EV_MSC, MSC_SERIAL, nd->isPalm); > + input_mt_sync(input); > + ntrig_dbg("Real Finger Index %x Count %d X=%d Y=%d DX=%d DY=%d FirstOccur=%d Palm=%d\n", > + nd->frame_index, nd->real_fingers, nd->x, > + nd->y, nd->dx, nd->dy, > + nd->generic_byte, nd->isPalm); > + if (0 == --nd->real_fingers) { > + input_event(input, EV_MSC, MSC_RAW, nd->frame_index); > + input_sync(input); > + ntrig_dbg("Real Finger Sync Frame %x\n", nd->frame_index); > + } > + } > break; > - case 3: > - default: > - input_report_key(input, > - BTN_TOOL_QUADTAP, 1); > } > - input_report_key(input, BTN_TOUCH, 1); > - } else { > - input_report_key(input, > - BTN_TOOL_DOUBLETAP, 0); > - input_report_key(input, > - BTN_TOOL_TRIPLETAP, 0); > - input_report_key(input, > - BTN_TOOL_QUADTAP, 0); > - input_report_key(input, BTN_TOUCH, 0); > + break; > } > - break; > - > - default: > - /* fallback to the generic hidinput handling */ > - return 0; > } > } > > @@ -402,16 +420,12 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) > int ret; > struct ntrig_data *nd; > > - if (id->driver_data) > - hdev->quirks |= HID_QUIRK_MULTI_INPUT; > - > nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); > if (!nd) { > dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); > return -ENOMEM; > } > > - nd->reading_mt = 0; > hid_set_drvdata(hdev, nd); > > ret = hid_parse(hdev); > @@ -446,16 +460,11 @@ static void ntrig_remove(struct hid_device *hdev) > > static const struct hid_device_id ntrig_devices[] = { > { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN), > - .driver_data = NTRIG_DUPLICATE_USAGES }, > + .driver_data = NTRIG_USB_DEVICE_ID }, > { } > }; > MODULE_DEVICE_TABLE(hid, ntrig_devices); > > -static const struct hid_usage_id ntrig_grabbed_usages[] = { > - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, > - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } > -}; > - > static struct hid_driver ntrig_driver = { > .name = "ntrig", > .id_table = ntrig_devices, > @@ -463,7 +472,6 @@ static struct hid_driver ntrig_driver = { > .remove = ntrig_remove, > .input_mapping = ntrig_input_mapping, > .input_mapped = ntrig_input_mapped, > - .usage_table = ntrig_grabbed_usages, > .event = ntrig_event, > }; > > -- > 1.6.3.3 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver 2010-03-22 12:16 [PATCH 1/2] HID: N-trig Add set feature commands to driver micki 2010-03-22 12:16 ` [PATCH 2/2] HID:HID-NTRIG update ntrig_event function micki @ 2010-03-22 17:29 ` Rafi Rubin [not found] ` <48A28051AC6D7A48B64F28272458190326DEE8@Exchange-IL.n-trig.com> 1 sibling, 1 reply; 10+ messages in thread From: Rafi Rubin @ 2010-03-22 17:29 UTC (permalink / raw) To: micki; +Cc: jkosina, chatty, peterhuewe, linux-input, linux-kernel On Mon, Mar 22, 2010 at 02:16:12PM +0200, micki@n-trig.com wrote: > From: micki <micki@micki-laptop.(none)> > > Add set feature commands to initialize N-trig firwmare. > Add debug option to driver, Add Macro. > Update probe function, delete name allocation caused kernel panaic Its been brought to my attention that the probe code you are having trouble with is incompatible with older kernels due to a bug which was fixed shortly before 2.6.30. It seems to me that your patches suggest that you've been working with an older version of the kernel and that has greatly influenced the design of the changes you suggested. I'm sorry I wasn't able to catch this sooner. But that's part of the risk you take with developing with out of date branches. Anyway, I suggest you either try applying your changes bit by bit to a newer kernel, or move the multi-input quirk to usbhid/hid-quirks.c (I should probably do that anyway to keep things cleaner). Once you have valid multiple input devices with the pen events routed to a separate device, I'm sure you will see how much it simplifies the design of this driver. After that we can discuss what does or does not need handling in the ntrig specific event handler and which mappings should or should not be changed. Also when you break up your changes into multiple patches, I ask that you add you #defines where needed. In this case your feature commands defines make sense, but none of the rest make sense in the scope of this patch. > Signed-off-by: Micki Balanga <micki@n-trig.com> > --- > drivers/hid/hid-ntrig.c | 169 +++++++++++++++++++++++++++++++++++----------- > 1 files changed, 128 insertions(+), 41 deletions(-) > > diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c > index edcc0c4..b4a573b 100644 > --- a/drivers/hid/hid-ntrig.c > +++ b/drivers/hid/hid-ntrig.c > @@ -3,6 +3,7 @@ > * > * Copyright (c) 2008 Rafi Rubin > * Copyright (c) 2009 Stephane Chatty > + * Copyright (c) 2010 N-TRIG > * > */ > > @@ -16,8 +17,77 @@ > #include <linux/device.h> > #include <linux/hid.h> > #include <linux/module.h> > +#include <linux/usb.h> > > #include "hid-ids.h" > +#include "usbhid/usbhid.h" > +/* > + * Pen Event Field Declaration > + */ > +#define EVENT_PEN_TIP 0x03 > +#define EVENT_PEN_RIGHT 0x05 > +#define EVENT_TOUCH_PEN 0x07 > +#define EVENT_PEN_IN_RANGE 0x01 > + > +/* > + * MTM 4 last bytes of report descriptor > + */ > +#define REPORT_GENERIC1 0x01 > +#define REPORT_MT 0x02 > +#define REPORT_PALM 0x03 > +#define REPORT_GENERIC2 0x04 > + > +#define NTRIG_USB_DEVICE_ID 0x0001 > + > +/* > + * MTM fields > + */ > +#define MAX_FINGERS_SUPPORT 0x06 > +#define END_OF_REPORT 0x64 > + > +/* > + * Dummy Finger Declaration > + */ > +#define DUMMY_X_CORD_VAL 0x00 > +#define DUMMY_Y_CORD_VAL 0x00 > +#define DUMMY_DX_CORD_VAL 0xFA > +#define DUMMY_DY_CORD_VAL 0x96 > +#define DUMMY_GENERIC_BYTE_VAL 0x0D > + > +/* > + * MTM Parse Event > + */ > +#define MTM_FRAME_INDEX 0xff000001 > +#define MTM_PROPROETARY 0xff000002 > + > +/* > + * MTM Set Feature Commands > + */ > +#define REPORTID_DRIVER_ALIVE 0x0A > +#define REPORTID_CALIBRATION 0x0B > +#define REPORTID_GET_VERSION 0x0C > +#define REPORTID_GET_MODE 0x0D > +#define REPORTID_SET_MODE_PEN 0x0E > +#define REPORTID_SET_MODE_TOUCH 0x0F > +#define REPORTID_SET_MODE_DUAL 0x10 > +#define REPORTID_CALIBRATION_RESPOND 0x11 > +#define HID_CAPACITORS_CALIB 0x12 > +#define HID_GET_CAPACITORS_CALIB_DONE 0x13 > + > + > +static int debug; > + > +#define MODULE_NAME "hid_ntrig" > + > + > +#define info(format, arg...) \ > + printk(KERN_INFO "%s: " format , MODULE_NAME , ## arg) > +#define ntrig_dbg(format, arg...) \ > + do { \ > + if (debug) \ > + printk(KERN_DEBUG "%s: " format, \ > + MODULE_NAME , ## arg); \ > + } while (0) > > #define NTRIG_DUPLICATE_USAGES 0x001 > > @@ -123,8 +193,8 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, > * decide whether we are in multi or single touch mode > * and call input_mt_sync after each point if necessary > */ > -static int ntrig_event (struct hid_device *hid, struct hid_field *field, > - struct hid_usage *usage, __s32 value) > +static int ntrig_event(struct hid_device *hid, struct hid_field *field, > + struct hid_usage *usage, __s32 value) > { > struct input_dev *input = field->hidinput->input; > struct ntrig_data *nd = hid_get_drvdata(hid); > @@ -133,7 +203,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, > if (field->application == HID_DG_PEN) > return 0; > > - if (hid->claimed & HID_CLAIMED_INPUT) { > + if (hid->claimed & HID_CLAIMED_INPUT) { > switch (usage->hid) { > case 0xff000001: > /* Tag indicating the start of a multitouch group */ > @@ -279,12 +349,58 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, > return 1; > } > > +/* > + * This function used to configure N-trig firmware > + * The first command we need to send to firmware is change > + * to Multi-touch Mode we don't receive a reply > + */ > +static int ntrig_send_report(struct hid_device *hid) > +{ > + struct hid_report *report; > + struct list_head *report_list = > + &hid->report_enum[HID_FEATURE_REPORT].report_list; > + > + if (list_empty(report_list)) { > + ntrig_dbg("no feature reports found\n"); > + return -ENODEV; > + } > + report = list_first_entry(report_list, struct hid_report, list); > + if (report->maxfield < 1) > + return -ENODEV; > + > + list_for_each_entry(report, > + report_list, list) { > + if (report->maxfield < 1) { > + ntrig_dbg("no fields in the report\n"); > + continue; > + } > + ntrig_dbg("report id %x\n", report->id); > + switch (report->id) { > + case REPORTID_DRIVER_ALIVE: > + usbhid_submit_report(hid, report, USB_DIR_OUT); > + break; > + /* > + * These command will implement later accroding to demand > + */ > + case REPORTID_GET_VERSION: /* FALLTHRU */ > + case REPORTID_SET_MODE_DUAL: /* FALLTHRU */ > + case REPORTID_CALIBRATION: /* FALLTHRU */ > + case REPORTID_GET_MODE: /* FALLTHRU */ > + case REPORTID_SET_MODE_PEN: /* FALLTHRU */ > + case REPORTID_SET_MODE_TOUCH: /* FALLTHRU */ > + case REPORTID_CALIBRATION_RESPOND:/* FALLTHRU */ > + case HID_CAPACITORS_CALIB: /* FALLTHRU */ > + case HID_GET_CAPACITORS_CALIB_DONE: > + break; > + } > + } > + return 0; > +} > + > static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) > { > int ret; > struct ntrig_data *nd; > - struct hid_input *hidinput; > - struct input_dev *input; > > if (id->driver_data) > hdev->quirks |= HID_QUIRK_MULTI_INPUT; > @@ -310,42 +426,10 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) > goto err_free; > } > > - > - list_for_each_entry(hidinput, &hdev->inputs, list) { > - if (hidinput->report->maxfield < 1) > - continue; > - > - input = hidinput->input; > - switch (hidinput->report->field[0]->application) { > - case HID_DG_PEN: > - input->name = "N-Trig Pen"; > - break; > - case HID_DG_TOUCHSCREEN: > - /* These keys are redundant for fingers, clear them > - * to prevent incorrect identification */ > - __clear_bit(BTN_TOOL_PEN, input->keybit); > - __clear_bit(BTN_TOOL_FINGER, input->keybit); > - __clear_bit(BTN_0, input->keybit); > - /* > - * A little something special to enable > - * two and three finger taps. > - */ > - __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); > - __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); > - __set_bit(BTN_TOOL_QUADTAP, input->keybit); > - /* > - * The physical touchscreen (single touch) > - * input has a value for physical, whereas > - * the multitouch only has logical input > - * fields. > - */ > - input->name = > - (hidinput->report->field[0] > - ->physical) ? > - "N-Trig Touchscreen" : > - "N-Trig MultiTouch"; > - break; > - } > + ret = ntrig_send_report(hdev); > + if (ret) { > + dev_err(&hdev->dev, "send set feature failed\n"); > + goto err_free; > } > > return 0; > @@ -395,4 +479,7 @@ static void __exit ntrig_exit(void) > > module_init(ntrig_init); > module_exit(ntrig_exit); > + > +MODULE_PARM_DESC(debug, "Debug mode enable disable"); > +module_param(debug, bool, 0644); > MODULE_LICENSE("GPL"); > -- > 1.6.3.3 > ^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <48A28051AC6D7A48B64F28272458190326DEE8@Exchange-IL.n-trig.com>]
* Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver [not found] ` <48A28051AC6D7A48B64F28272458190326DEE8@Exchange-IL.n-trig.com> @ 2010-03-22 18:17 ` Rafi Rubin [not found] ` <48A28051AC6D7A48B64F28272458190326DEEB@Exchange-IL.n-trig.com> 0 siblings, 1 reply; 10+ messages in thread From: Rafi Rubin @ 2010-03-22 18:17 UTC (permalink / raw) To: Micki Balanga; +Cc: jkosina, chatty, peterhuewe, linux-input, linux-kernel On Mon, Mar 22, 2010 at 07:39:56PM +0200, Micki Balanga wrote: > > Hi > Thank you for you comment but the driver as been tested on kernel 2.6.31 and above, > and i got the module to kill himself this is the reason i deleted the code. > I put the task in my TODO list so the next version of the driver we release > will include input->name. Please explain where its dying. Is it a NULL report? In the case where it dies, do you have the multi-input quirk cleared? Have you considered the possibility that perhaps setting the features _after_ hw_start (which results in changing the reports) might not be such a good idea? If you have specific probing and setup code, perhaps its best to do that before initializing data structures, parsing the records, and activating the device. I haven't tried out your feature enabling code yet, so haven't had a chance to debug it. Does the MT enable change the behavior of all firmwares or just those from the 2.59 software package? (Again, easier to test if you want to make firmware blobs and loader available) > -----Original Message----- > From: Rafi Rubin [mailto:rafi@seas.upenn.edu] > Sent: Mon 3/22/2010 7:29 PM > To: Micki Balanga > Cc: jkosina@suse.cz; chatty@enac.fr; peterhuewe@gmx.de; linux-input@vger.kernel.org; linux-kernel@vger.kernel.org > Subject: Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver > > On Mon, Mar 22, 2010 at 02:16:12PM +0200, micki@n-trig.com wrote: > > From: micki <micki@micki-laptop.(none)> > > > > Add set feature commands to initialize N-trig firwmare. > > Add debug option to driver, Add Macro. > > Update probe function, delete name allocation caused kernel panaic > > Its been brought to my attention that the probe code you are having > trouble with is incompatible with older kernels due to a bug which was > fixed shortly before 2.6.30. > > It seems to me that your patches suggest that you've been working with an > older version of the kernel and that has greatly influenced the design of > the changes you suggested. > > I'm sorry I wasn't able to catch this sooner. But that's part of the risk > you take with developing with out of date branches. > > > Anyway, I suggest you either try applying your changes bit by bit to a > newer kernel, or move the multi-input quirk to usbhid/hid-quirks.c (I > should probably do that anyway to keep things cleaner). > > Once you have valid multiple input devices with the pen events routed to a > separate device, I'm sure you will see how much it simplifies the design > of this driver. After that we can discuss what does or does not need > handling in the ntrig specific event handler and which mappings should or > should not be changed. > > Also when you break up your changes into multiple patches, I ask that you > add you #defines where needed. In this case your feature commands defines > make sense, but none of the rest make sense in the scope of this patch. > > > Signed-off-by: Micki Balanga <micki@n-trig.com> > > --- > > drivers/hid/hid-ntrig.c | 169 +++++++++++++++++++++++++++++++++++----------- > > 1 files changed, 128 insertions(+), 41 deletions(-) > > > > diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c > > index edcc0c4..b4a573b 100644 > > --- a/drivers/hid/hid-ntrig.c > > +++ b/drivers/hid/hid-ntrig.c > > @@ -3,6 +3,7 @@ > > * > > * Copyright (c) 2008 Rafi Rubin > > * Copyright (c) 2009 Stephane Chatty > > + * Copyright (c) 2010 N-TRIG > > * > > */ > > > > @@ -16,8 +17,77 @@ > > #include <linux/device.h> > > #include <linux/hid.h> > > #include <linux/module.h> > > +#include <linux/usb.h> > > > > #include "hid-ids.h" > > +#include "usbhid/usbhid.h" > > +/* > > + * Pen Event Field Declaration > > + */ > > +#define EVENT_PEN_TIP 0x03 > > +#define EVENT_PEN_RIGHT 0x05 > > +#define EVENT_TOUCH_PEN 0x07 > > +#define EVENT_PEN_IN_RANGE 0x01 > > + > > +/* > > + * MTM 4 last bytes of report descriptor > > + */ > > +#define REPORT_GENERIC1 0x01 > > +#define REPORT_MT 0x02 > > +#define REPORT_PALM 0x03 > > +#define REPORT_GENERIC2 0x04 > > + > > +#define NTRIG_USB_DEVICE_ID 0x0001 > > + > > +/* > > + * MTM fields > > + */ > > +#define MAX_FINGERS_SUPPORT 0x06 > > +#define END_OF_REPORT 0x64 > > + > > +/* > > + * Dummy Finger Declaration > > + */ > > +#define DUMMY_X_CORD_VAL 0x00 > > +#define DUMMY_Y_CORD_VAL 0x00 > > +#define DUMMY_DX_CORD_VAL 0xFA > > +#define DUMMY_DY_CORD_VAL 0x96 > > +#define DUMMY_GENERIC_BYTE_VAL 0x0D > > + > > +/* > > + * MTM Parse Event > > + */ > > +#define MTM_FRAME_INDEX 0xff000001 > > +#define MTM_PROPROETARY 0xff000002 > > + > > +/* > > + * MTM Set Feature Commands > > + */ > > +#define REPORTID_DRIVER_ALIVE 0x0A > > +#define REPORTID_CALIBRATION 0x0B > > +#define REPORTID_GET_VERSION 0x0C > > +#define REPORTID_GET_MODE 0x0D > > +#define REPORTID_SET_MODE_PEN 0x0E > > +#define REPORTID_SET_MODE_TOUCH 0x0F > > +#define REPORTID_SET_MODE_DUAL 0x10 > > +#define REPORTID_CALIBRATION_RESPOND 0x11 > > +#define HID_CAPACITORS_CALIB 0x12 > > +#define HID_GET_CAPACITORS_CALIB_DONE 0x13 > > + > > + > > +static int debug; > > + > > +#define MODULE_NAME "hid_ntrig" > > + > > + > > +#define info(format, arg...) \ > > + printk(KERN_INFO "%s: " format , MODULE_NAME , ## arg) > > +#define ntrig_dbg(format, arg...) \ > > + do { \ > > + if (debug) \ > > + printk(KERN_DEBUG "%s: " format, \ > > + MODULE_NAME , ## arg); \ > > + } while (0) > > > > #define NTRIG_DUPLICATE_USAGES 0x001 > > > > @@ -123,8 +193,8 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, > > * decide whether we are in multi or single touch mode > > * and call input_mt_sync after each point if necessary > > */ > > -static int ntrig_event (struct hid_device *hid, struct hid_field *field, > > - struct hid_usage *usage, __s32 value) > > +static int ntrig_event(struct hid_device *hid, struct hid_field *field, > > + struct hid_usage *usage, __s32 value) > > { > > struct input_dev *input = field->hidinput->input; > > struct ntrig_data *nd = hid_get_drvdata(hid); > > @@ -133,7 +203,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, > > if (field->application == HID_DG_PEN) > > return 0; > > > > - if (hid->claimed & HID_CLAIMED_INPUT) { > > + if (hid->claimed & HID_CLAIMED_INPUT) { > > switch (usage->hid) { > > case 0xff000001: > > /* Tag indicating the start of a multitouch group */ > > @@ -279,12 +349,58 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, > > return 1; > > } > > > > +/* > > + * This function used to configure N-trig firmware > > + * The first command we need to send to firmware is change > > + * to Multi-touch Mode we don't receive a reply > > + */ > > +static int ntrig_send_report(struct hid_device *hid) > > +{ > > + struct hid_report *report; > > + struct list_head *report_list = > > + &hid->report_enum[HID_FEATURE_REPORT].report_list; > > + > > + if (list_empty(report_list)) { > > + ntrig_dbg("no feature reports found\n"); > > + return -ENODEV; > > + } > > + report = list_first_entry(report_list, struct hid_report, list); > > + if (report->maxfield < 1) > > + return -ENODEV; > > + > > + list_for_each_entry(report, > > + report_list, list) { > > + if (report->maxfield < 1) { > > + ntrig_dbg("no fields in the report\n"); > > + continue; > > + } > > + ntrig_dbg("report id %x\n", report->id); > > + switch (report->id) { > > + case REPORTID_DRIVER_ALIVE: > > + usbhid_submit_report(hid, report, USB_DIR_OUT); > > + break; > > + /* > > + * These command will implement later accroding to demand > > + */ > > + case REPORTID_GET_VERSION: /* FALLTHRU */ > > + case REPORTID_SET_MODE_DUAL: /* FALLTHRU */ > > + case REPORTID_CALIBRATION: /* FALLTHRU */ > > + case REPORTID_GET_MODE: /* FALLTHRU */ > > + case REPORTID_SET_MODE_PEN: /* FALLTHRU */ > > + case REPORTID_SET_MODE_TOUCH: /* FALLTHRU */ > > + case REPORTID_CALIBRATION_RESPOND:/* FALLTHRU */ > > + case HID_CAPACITORS_CALIB: /* FALLTHRU */ > > + case HID_GET_CAPACITORS_CALIB_DONE: > > + break; > > + } > > + } > > + return 0; > > +} > > + > > static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) > > { > > int ret; > > struct ntrig_data *nd; > > - struct hid_input *hidinput; > > - struct input_dev *input; > > > > if (id->driver_data) > > hdev->quirks |= HID_QUIRK_MULTI_INPUT; > > @@ -310,42 +426,10 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) > > goto err_free; > > } > > > > - > > - list_for_each_entry(hidinput, &hdev->inputs, list) { > > - if (hidinput->report->maxfield < 1) > > - continue; > > - > > - input = hidinput->input; > > - switch (hidinput->report->field[0]->application) { > > - case HID_DG_PEN: > > - input->name = "N-Trig Pen"; > > - break; > > - case HID_DG_TOUCHSCREEN: > > - /* These keys are redundant for fingers, clear them > > - * to prevent incorrect identification */ > > - __clear_bit(BTN_TOOL_PEN, input->keybit); > > - __clear_bit(BTN_TOOL_FINGER, input->keybit); > > - __clear_bit(BTN_0, input->keybit); > > - /* > > - * A little something special to enable > > - * two and three finger taps. > > - */ > > - __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); > > - __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); > > - __set_bit(BTN_TOOL_QUADTAP, input->keybit); > > - /* > > - * The physical touchscreen (single touch) > > - * input has a value for physical, whereas > > - * the multitouch only has logical input > > - * fields. > > - */ > > - input->name = > > - (hidinput->report->field[0] > > - ->physical) ? > > - "N-Trig Touchscreen" : > > - "N-Trig MultiTouch"; > > - break; > > - } > > + ret = ntrig_send_report(hdev); > > + if (ret) { > > + dev_err(&hdev->dev, "send set feature failed\n"); > > + goto err_free; > > } > > > > return 0; > > @@ -395,4 +479,7 @@ static void __exit ntrig_exit(void) > > > > module_init(ntrig_init); > > module_exit(ntrig_exit); > > + > > +MODULE_PARM_DESC(debug, "Debug mode enable disable"); > > +module_param(debug, bool, 0644); > > MODULE_LICENSE("GPL"); > > -- > > 1.6.3.3 > > > ^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <48A28051AC6D7A48B64F28272458190326DEEB@Exchange-IL.n-trig.com>]
* Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver [not found] ` <48A28051AC6D7A48B64F28272458190326DEEB@Exchange-IL.n-trig.com> @ 2010-03-22 20:43 ` Rafi Rubin [not found] ` <48A28051AC6D7A48B64F28272458190326DEEE@Exchange-IL.n-trig.com> 0 siblings, 1 reply; 10+ messages in thread From: Rafi Rubin @ 2010-03-22 20:43 UTC (permalink / raw) To: Micki Balanga Cc: jkosina, chatty, peterhuewe, linux-input, linux-kernel, Henrik Rydberg [-- Attachment #1: Type: text/plain, Size: 2498 bytes --] On 03/22/2010 03:58 PM, Micki Balanga wrote: > > Hi > I would like to add more information about the Fake button. > I will explain using this scenario: > You touch the sensor with one finger and then remove the finger, > Firmware will report six frames with fake fingers,(Indicate end of session) > The driver will report this as fake fingers (Will send 3 events) and > input_sync > to inform user space application that the user removed finger from sensor. > this information is needed in order to analyze the data received from > N-trig firmware. > Micki Thank you for taking this to a discussion format. It seems you have raised an issue that is an active discussion for multi touch handling in general and an issue that I have considered for n-trig support in specific. The current published version of the driver does send one more sequence of events after it decides all fingers are off the screen. That final sequence is necessary to tell single touch drivers that the tools are released (BTN_TOUCH is set to zero, etc). This also resets the active contact count to zero for multi touch handlers, which look to see how many MT events come from each frame. I had observed that sometimes the tablet looses contacts semi arbitrarily, and we get a zero contact group as a mistake. In the patches I sent in early in February you will notice a solution that I was considering at the time. I was also playing with correcting for events that looked like real contacts but were also just noise. After rethinking my patches and reading the multi touch doc in the Documents tree, I chose to leave out these corrections. That being said, I do have a specific patch to handle the set of end of stream events. All that's needed is to count the empty groups and send the terminal events only when a counter hits the specified value (attached is a tiny patch I wrote when I needed that feature back really quickly when my screen started misbehaving during a meeting). Note I have submitted that as a patch for 2 reasons. First I couldn't be completely sure that there was a specific number of empty groups to signal end of stream which would be expected to be maintained over time. And secondly the erroneous termination of stream has not been much of a problem in general. You will note, that this is something that is simple enough that it makes perfect sense to put into the kernel. There's little point in wasting the cycles to push that decision to user space. [-- Attachment #2: commit-4c6fffa --] [-- Type: text/plain, Size: 1515 bytes --] commit 4c6fffa347e529672dfb858b07168f49ba4bbe97 Author: Rafi Rubin <rafi@seas.upenn.edu> Date: Tue Feb 23 12:11:41 2010 -0500 Quick and dirty avoidance of erroneous end of contact events. diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 3234c72..25ee5a4 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -35,6 +35,9 @@ struct ntrig_data { __u8 mt_footer[4]; __u8 mt_foot_count; + + __u8 deactivate_slack; + __u8 deactivate_state; }; /* @@ -192,6 +195,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, /* Pen activity signal, trigger end of touch. */ if (nd->mt_footer[2]) { nd->confidence = 0; + nd->deactivate_state = 0; break; } @@ -252,14 +256,16 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, BTN_TOOL_QUADTAP, 1); } input_report_key(input, BTN_TOUCH, 1); - } else { + nd->deactivate_state = nd->deactivate_slack; + } else if (! nd->deactivate_state) { input_report_key(input, BTN_TOOL_DOUBLETAP, 0); input_report_key(input, BTN_TOOL_TRIPLETAP, 0); input_report_key(input, BTN_TOOL_QUADTAP, 0); - } + } else + nd->deactivate_state--; break; default: @@ -292,6 +298,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) } nd->reading_mt = 0; + nd->deactivate_slack = 4; + nd->deactivate_state = 0; hid_set_drvdata(hdev, nd); ret = hid_parse(hdev); ^ permalink raw reply related [flat|nested] 10+ messages in thread
[parent not found: <48A28051AC6D7A48B64F28272458190326DEEE@Exchange-IL.n-trig.com>]
* Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver [not found] ` <48A28051AC6D7A48B64F28272458190326DEEE@Exchange-IL.n-trig.com> @ 2010-03-22 21:55 ` Rafi Rubin 2010-03-23 14:43 ` Micki Balanga 0 siblings, 1 reply; 10+ messages in thread From: Rafi Rubin @ 2010-03-22 21:55 UTC (permalink / raw) To: Micki Balanga Cc: jkosina, chatty, peterhuewe, linux-input, linux-kernel, Henrik Rydberg, Dmitry Torokhov On 03/22/2010 05:14 PM, Micki Balanga wrote: > Hi > first of all i am happy my explanation helps you to understand the > necessity of fake finger report. > The algorithm to analyze the information use complex math calculation, > so it can't be transfer to the driver. > (the driver should stay simple as possible, main purpose analyze USB > message and transfer it to Linux events) > As i mentioned before you talked about glitch a noise, which N-trig > solution solve. > The driver implement the necessary events needed by the user, in order > to analyze touch events. I'm not really much of a judge of how to balance kernel vs user land load. Though I can certainly see why you would want to keep all proprietary analysis to the user land and thus want to pass through necessary events. I was "encouraged" earlier to take a deeper look at what I was writing, and determine if all that I was trying to send was actually necessary or just me missing something. I will look more closely, and perhaps see if I can suggest modifications which include the events you need without breaking the existing protocol. Dmitry seems to be an authority on how input events should be used. I'm still just learning myself. But this still leaves the point of lets try to keep the split input devices. It is still a cleaner abstraction than splitting in the user space code. > About a question you raised before about set_feature location, it should > be done after the hw_start because > if the HW start fail there is no reason to send the command. this > command doesn't change the report descriptor size. I'm still not entirely sure of the ordering of things. Users have sent me the rdesc outputs from a device with 2.59 with and without your code to enable MT, and it looked to me like the report descriptor was different. I can try to experiment with that. Can you specify conditions or versions which cause this failure? It would be nice to be able to see for myself, especially since removing the naming and the quirk will disrupt quite a number of users. I do agree that the code should be more robust to bad conditions, so please try it with: list_for_each_entry(hidinput, &hdev->inputs, list) { + if (hidinput->report == NULL) { + dev_err(&hdev->dev, "NULL report\n"); + continue; + } That way we'll have a graceful fallback for your needs without breaking users. And also, hopefully this will lead to finding any lingering bugs. > -----Original Message----- > From: Rafi Rubin [mailto:rafi@seas.upenn.edu] > Sent: Mon 3/22/2010 10:43 PM > To: Micki Balanga > Cc: jkosina@suse.cz; chatty@enac.fr; peterhuewe@gmx.de; > linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; Henrik Rydberg > Subject: Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver > > On 03/22/2010 03:58 PM, Micki Balanga wrote: > > > > Hi > > I would like to add more information about the Fake button. > > I will explain using this scenario: > > You touch the sensor with one finger and then remove the finger, > > Firmware will report six frames with fake fingers,(Indicate end of > session) > > The driver will report this as fake fingers (Will send 3 events) and > > input_sync > > to inform user space application that the user removed finger from > sensor. > > this information is needed in order to analyze the data received from > > N-trig firmware. > > Micki > > Thank you for taking this to a discussion format. > > It seems you have raised an issue that is an active discussion for multi > touch handling in general and an issue that I have considered for n-trig > support in specific. > > > The current published version of the driver does send one more sequence > of events after it decides all fingers are off the screen. That final > sequence is necessary to tell single touch drivers that the tools are > released (BTN_TOUCH is set to zero, etc). This also resets the active > contact count to zero for multi touch handlers, which look to see how > many MT events come from each frame. > > I had observed that sometimes the tablet looses contacts semi > arbitrarily, and we get a zero contact group as a mistake. In the > patches I sent in early in February you will notice a solution that I > was considering at the time. I was also playing with correcting for > events that looked like real contacts but were also just noise. After > rethinking my patches and reading the multi touch doc in the Documents > tree, I chose to leave out these corrections. > > That being said, I do have a specific patch to handle the set of end of > stream events. All that's needed is to count the empty groups and send > the terminal events only when a counter hits the specified value > (attached is a tiny patch I wrote when I needed that feature back really > quickly when my screen started misbehaving during a meeting). > > Note I have submitted that as a patch for 2 reasons. First I couldn't > be completely sure that there was a specific number of empty groups to > signal end of stream which would be expected to be maintained over time. > And secondly the erroneous termination of stream has not been much of > a problem in general. > > You will note, that this is something that is simple enough that it > makes perfect sense to put into the kernel. There's little point in > wasting the cycles to push that decision to user space. > ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH 1/2] HID: N-trig Add set feature commands to driver 2010-03-22 21:55 ` Rafi Rubin @ 2010-03-23 14:43 ` Micki Balanga 2010-03-24 13:27 ` Mohamed Ikbel Boulabiar 0 siblings, 1 reply; 10+ messages in thread From: Micki Balanga @ 2010-03-23 14:43 UTC (permalink / raw) To: Rafi Rubin Cc: jkosina, chatty, peterhuewe, linux-input, linux-kernel, Henrik Rydberg, Dmitry Torokhov N-trig driver can be used directly for Multi-Touch and Pen support. Furthermore, in the coming weeks we'll provide an additional package that will improve and enhance the system performance. This package will support Linux events as well as Message Queue based API for the benefit of the developers. -----Original Message----- From: Rafi Rubin [mailto:rafi@seas.upenn.edu] Sent: Monday, March 22, 2010 11:55 PM To: Micki Balanga Cc: jkosina@suse.cz; chatty@enac.fr; peterhuewe@gmx.de; linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; Henrik Rydberg; Dmitry Torokhov Subject: Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver On 03/22/2010 05:14 PM, Micki Balanga wrote: > Hi > first of all i am happy my explanation helps you to understand the > necessity of fake finger report. > The algorithm to analyze the information use complex math calculation, > so it can't be transfer to the driver. > (the driver should stay simple as possible, main purpose analyze USB > message and transfer it to Linux events) > As i mentioned before you talked about glitch a noise, which N-trig > solution solve. > The driver implement the necessary events needed by the user, in order > to analyze touch events. I'm not really much of a judge of how to balance kernel vs user land load. Though I can certainly see why you would want to keep all proprietary analysis to the user land and thus want to pass through necessary events. I was "encouraged" earlier to take a deeper look at what I was writing, and determine if all that I was trying to send was actually necessary or just me missing something. I will look more closely, and perhaps see if I can suggest modifications which include the events you need without breaking the existing protocol. Dmitry seems to be an authority on how input events should be used. I'm still just learning myself. But this still leaves the point of lets try to keep the split input devices. It is still a cleaner abstraction than splitting in the user space code. > About a question you raised before about set_feature location, it should > be done after the hw_start because > if the HW start fail there is no reason to send the command. this > command doesn't change the report descriptor size. I'm still not entirely sure of the ordering of things. Users have sent me the rdesc outputs from a device with 2.59 with and without your code to enable MT, and it looked to me like the report descriptor was different. I can try to experiment with that. Can you specify conditions or versions which cause this failure? It would be nice to be able to see for myself, especially since removing the naming and the quirk will disrupt quite a number of users. I do agree that the code should be more robust to bad conditions, so please try it with: list_for_each_entry(hidinput, &hdev->inputs, list) { + if (hidinput->report == NULL) { + dev_err(&hdev->dev, "NULL report\n"); + continue; + } That way we'll have a graceful fallback for your needs without breaking users. And also, hopefully this will lead to finding any lingering bugs. > -----Original Message----- > From: Rafi Rubin [mailto:rafi@seas.upenn.edu] > Sent: Mon 3/22/2010 10:43 PM > To: Micki Balanga > Cc: jkosina@suse.cz; chatty@enac.fr; peterhuewe@gmx.de; > linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; Henrik Rydberg > Subject: Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver > > On 03/22/2010 03:58 PM, Micki Balanga wrote: > > > > Hi > > I would like to add more information about the Fake button. > > I will explain using this scenario: > > You touch the sensor with one finger and then remove the finger, > > Firmware will report six frames with fake fingers,(Indicate end of > session) > > The driver will report this as fake fingers (Will send 3 events) and > > input_sync > > to inform user space application that the user removed finger from > sensor. > > this information is needed in order to analyze the data received from > > N-trig firmware. > > Micki > > Thank you for taking this to a discussion format. > > It seems you have raised an issue that is an active discussion for multi > touch handling in general and an issue that I have considered for n-trig > support in specific. > > > The current published version of the driver does send one more sequence > of events after it decides all fingers are off the screen. That final > sequence is necessary to tell single touch drivers that the tools are > released (BTN_TOUCH is set to zero, etc). This also resets the active > contact count to zero for multi touch handlers, which look to see how > many MT events come from each frame. > > I had observed that sometimes the tablet looses contacts semi > arbitrarily, and we get a zero contact group as a mistake. In the > patches I sent in early in February you will notice a solution that I > was considering at the time. I was also playing with correcting for > events that looked like real contacts but were also just noise. After > rethinking my patches and reading the multi touch doc in the Documents > tree, I chose to leave out these corrections. > > That being said, I do have a specific patch to handle the set of end of > stream events. All that's needed is to count the empty groups and send > the terminal events only when a counter hits the specified value > (attached is a tiny patch I wrote when I needed that feature back really > quickly when my screen started misbehaving during a meeting). > > Note I have submitted that as a patch for 2 reasons. First I couldn't > be completely sure that there was a specific number of empty groups to > signal end of stream which would be expected to be maintained over time. > And secondly the erroneous termination of stream has not been much of > a problem in general. > > You will note, that this is something that is simple enough that it > makes perfect sense to put into the kernel. There's little point in > wasting the cycles to push that decision to user space. > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver 2010-03-23 14:43 ` Micki Balanga @ 2010-03-24 13:27 ` Mohamed Ikbel Boulabiar [not found] ` <48A28051AC6D7A48B64F28272458190326DEF4@Exchange-IL.n-trig.com> 0 siblings, 1 reply; 10+ messages in thread From: Mohamed Ikbel Boulabiar @ 2010-03-24 13:27 UTC (permalink / raw) To: Micki Balanga Cc: Rafi Rubin, jkosina, chatty, peterhuewe, linux-input, linux-kernel, Henrik Rydberg, Dmitry Torokhov Hi, Do you have any intention to add some more low level tracking in the driver ? I haven't followed all mails, I remember that a small algorithm for tracking was suggested by Rafi Rubin, but don't know if N-Trig developers can push more things inside the driver and provide a contact-id information inside events submission. Thanks, On Tue, Mar 23, 2010 at 3:43 PM, Micki Balanga <micki@n-trig.com> wrote: > N-trig driver can be used directly for Multi-Touch and Pen support. > Furthermore, in the coming weeks we'll provide an additional package > that will improve and enhance the system performance. > This package will support Linux events as well as Message Queue based > API for the benefit of the developers. > > -----Original Message----- > From: Rafi Rubin [mailto:rafi@seas.upenn.edu] > Sent: Monday, March 22, 2010 11:55 PM > To: Micki Balanga > Cc: jkosina@suse.cz; chatty@enac.fr; peterhuewe@gmx.de; > linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; Henrik > Rydberg; Dmitry Torokhov > Subject: Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver > > On 03/22/2010 05:14 PM, Micki Balanga wrote: >> Hi >> first of all i am happy my explanation helps you to understand the >> necessity of fake finger report. >> The algorithm to analyze the information use complex math calculation, >> so it can't be transfer to the driver. >> (the driver should stay simple as possible, main purpose analyze USB >> message and transfer it to Linux events) >> As i mentioned before you talked about glitch a noise, which N-trig >> solution solve. >> The driver implement the necessary events needed by the user, in order >> to analyze touch events. > > I'm not really much of a judge of how to balance kernel vs user land > load. Though I can certainly see why you would want to keep all > proprietary analysis to the user land and thus want to pass through > necessary events. I was "encouraged" earlier to take a deeper look at > what I was writing, and determine if all that I was trying to send was > actually necessary or just me missing something. > > I will look more closely, and perhaps see if I can suggest modifications > > which include the events you need without breaking the existing > protocol. Dmitry seems to be an authority on how input events should be > > used. I'm still just learning myself. > > But this still leaves the point of lets try to keep the split input > devices. It is still a cleaner abstraction than splitting in the user > space code. > >> About a question you raised before about set_feature location, it > should >> be done after the hw_start because >> if the HW start fail there is no reason to send the command. this >> command doesn't change the report descriptor size. > > I'm still not entirely sure of the ordering of things. Users have sent > me the rdesc outputs from a device with 2.59 with and without your code > to enable MT, and it looked to me like the report descriptor was > different. I can try to experiment with that. > > Can you specify conditions or versions which cause this failure? It > would be nice to be able to see for myself, especially since removing > the naming and the quirk will disrupt quite a number of users. > > I do agree that the code should be more robust to bad conditions, so > please try it with: > > list_for_each_entry(hidinput, &hdev->inputs, list) { > + if (hidinput->report == NULL) { > + dev_err(&hdev->dev, "NULL report\n"); > + continue; > + } > > That way we'll have a graceful fallback for your needs without breaking > users. And also, hopefully this will lead to finding any lingering > bugs. > > >> -----Original Message----- >> From: Rafi Rubin [mailto:rafi@seas.upenn.edu] >> Sent: Mon 3/22/2010 10:43 PM >> To: Micki Balanga >> Cc: jkosina@suse.cz; chatty@enac.fr; peterhuewe@gmx.de; >> linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; Henrik > Rydberg >> Subject: Re: [PATCH 1/2] HID: N-trig Add set feature commands to > driver >> >> On 03/22/2010 03:58 PM, Micki Balanga wrote: >> > >> > Hi >> > I would like to add more information about the Fake button. >> > I will explain using this scenario: >> > You touch the sensor with one finger and then remove the finger, >> > Firmware will report six frames with fake fingers,(Indicate end of >> session) >> > The driver will report this as fake fingers (Will send 3 events) > and >> > input_sync >> > to inform user space application that the user removed finger from >> sensor. >> > this information is needed in order to analyze the data received > from >> > N-trig firmware. >> > Micki >> >> Thank you for taking this to a discussion format. >> >> It seems you have raised an issue that is an active discussion for > multi >> touch handling in general and an issue that I have considered for > n-trig >> support in specific. >> >> >> The current published version of the driver does send one more > sequence >> of events after it decides all fingers are off the screen. That final >> sequence is necessary to tell single touch drivers that the tools are >> released (BTN_TOUCH is set to zero, etc). This also resets the active >> contact count to zero for multi touch handlers, which look to see how >> many MT events come from each frame. >> >> I had observed that sometimes the tablet looses contacts semi >> arbitrarily, and we get a zero contact group as a mistake. In the >> patches I sent in early in February you will notice a solution that I >> was considering at the time. I was also playing with correcting for >> events that looked like real contacts but were also just noise. After >> rethinking my patches and reading the multi touch doc in the Documents >> tree, I chose to leave out these corrections. >> >> That being said, I do have a specific patch to handle the set of end > of >> stream events. All that's needed is to count the empty groups and send >> the terminal events only when a counter hits the specified value >> (attached is a tiny patch I wrote when I needed that feature back > really >> quickly when my screen started misbehaving during a meeting). >> >> Note I have submitted that as a patch for 2 reasons. First I couldn't >> be completely sure that there was a specific number of empty groups to >> signal end of stream which would be expected to be maintained over > time. >> And secondly the erroneous termination of stream has not been much of >> a problem in general. >> >> You will note, that this is something that is simple enough that it >> makes perfect sense to put into the kernel. There's little point in >> wasting the cycles to push that decision to user space. >> > > -- > To unsubscribe from this list: send the line "unsubscribe linux-input" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <48A28051AC6D7A48B64F28272458190326DEF4@Exchange-IL.n-trig.com>]
* Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver [not found] ` <48A28051AC6D7A48B64F28272458190326DEF4@Exchange-IL.n-trig.com> @ 2010-03-25 0:25 ` Rafi Rubin 0 siblings, 0 replies; 10+ messages in thread From: Rafi Rubin @ 2010-03-25 0:25 UTC (permalink / raw) To: Micki Balanga Cc: Mohamed Ikbel Boulabiar, jkosina, chatty, peterhuewe, linux-input, linux-kernel, Henrik Rydberg, DmitryTorokhov -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I think there's a large rift in perspective here. Micki: what is your motivation for pushing your code to the mainline kernel. Nobody is stopping you from publishing your own driver stack on your website, as you do with some of your windows drivers and other vendors (nvidia for example) do with their linux drivers. There is much to be said for engaging the community and I think you, your company, and your customers would profit from healthy cooperation. Your requests for blind faith do not really interest me. You talk about algorithms running in closed source modules (which we haven't even seen) that do "stuff". That really doesn't mean much. Why should I or anyone else be interested in algorithms if we don't know what they are supposed to improve? Why should we accept breakage, temporary or permanent, based on your word that its worth it. There's no argument that your status as a developer may give you access to inside information that may improve the overall user experience. But that doesn't justify blind faith from the community. There are many reasons to suspect that your interests do not necessary mesh with the community as a whole. If you have some actual points to make, make them. Just don't expect to convince anyone with vacuous arguments and claims of corporate backing. Micki Balanga wrote: > I as mentioned in the last email > The algorithm to analyze the information use complex math calculation, > so it can't be transfer to the driver. > (the driver should stay simple as possible, main purpose analyze USB > message and transfer it to Linux events) > As i mentioned before you talked about glitch a noise, which N-trig > solution solve. > The driver implement the necessary events needed by the user, in order > to analyze touch events. > In the coming weeks we'll provide an additional package > that will improve and enhance the system performance. > This package will support Linux events as well as Message Queue based > API for the benefit of the developers. You haven't really demonstrated that you can do a better job of de-glitching than we could do with some very _simple_ code in the kernel. As for kernel vs. user space computational burden. Looking for the 6 end of stream events in the kernel costs fewer cycles than emitting the events to let the user space catch that particular signal. Also there is a second set of conditions indicating the pen is active, those can also be caught just as easily, and don't add any additional justification of passing those events through. I don't see why you make a big deal out of message queues, its not even clear that's really such an appropriate medium to feed events downstream. Don't get me wrong, I like message queues they are fun and have their place, and its fun to add them to class projects and watch students misuse them. > -----Original Message----- > From: Mohamed Ikbel Boulabiar [mailto:boulabiar@gmail.com] > Sent: Wed 3/24/2010 3:27 PM > To: Micki Balanga > Cc: Rafi Rubin; jkosina@suse.cz; chatty@enac.fr; peterhuewe@gmx.de; > linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; Henrik > Rydberg; DmitryTorokhov > Subject: Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver > > Hi, > > Do you have any intention to add some more low level tracking in the > driver ? > > I haven't followed all mails, I remember that a small algorithm for > tracking was suggested by Rafi Rubin, but don't know if N-Trig > developers can push more things inside the driver and provide a > contact-id information inside events submission. > > Thanks, I pulled the tracking code while I responding to other issues concerning the problems with my patches. Specifically I removed that code because I read Henrik's protocol documentation more carefully. I think there is still an opportunity to perform partial tracking, but that's another discussion. While it was pretty lightweight I also felt I could do better, both in terms of the computations it already did and to make it take better advantage of the specific scan patterns of the n-trig hardware that I've observed. Its also not entirely clear to me what the intention of the manufacturer is with regards to tracking. If they do intend to clean up the poor tracking in the firmware, then it doesn't really make sense to add it now. One more reason it would be good to have firmware version and possibly some other method to sanity check. - - Rafi > On Tue, Mar 23, 2010 at 3:43 PM, Micki Balanga <micki@n-trig.com> wrote: >> N-trig driver can be used directly for Multi-Touch and Pen support. >> Furthermore, in the coming weeks we'll provide an additional package >> that will improve and enhance the system performance. >> This package will support Linux events as well as Message Queue based >> API for the benefit of the developers. >> >> -----Original Message----- >> From: Rafi Rubin [mailto:rafi@seas.upenn.edu] >> Sent: Monday, March 22, 2010 11:55 PM >> To: Micki Balanga >> Cc: jkosina@suse.cz; chatty@enac.fr; peterhuewe@gmx.de; >> linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; Henrik >> Rydberg; Dmitry Torokhov >> Subject: Re: [PATCH 1/2] HID: N-trig Add set feature commands to driver >> >> On 03/22/2010 05:14 PM, Micki Balanga wrote: >>> Hi >>> first of all i am happy my explanation helps you to understand the >>> necessity of fake finger report. >>> The algorithm to analyze the information use complex math calculation, >>> so it can't be transfer to the driver. >>> (the driver should stay simple as possible, main purpose analyze USB >>> message and transfer it to Linux events) >>> As i mentioned before you talked about glitch a noise, which N-trig >>> solution solve. >>> The driver implement the necessary events needed by the user, in order >>> to analyze touch events. >> >> I'm not really much of a judge of how to balance kernel vs user land >> load. Though I can certainly see why you would want to keep all >> proprietary analysis to the user land and thus want to pass through >> necessary events. I was "encouraged" earlier to take a deeper look at >> what I was writing, and determine if all that I was trying to send was >> actually necessary or just me missing something. >> >> I will look more closely, and perhaps see if I can suggest modifications >> >> which include the events you need without breaking the existing >> protocol. Dmitry seems to be an authority on how input events should be >> >> used. I'm still just learning myself. >> >> But this still leaves the point of lets try to keep the split input >> devices. It is still a cleaner abstraction than splitting in the user >> space code. >> >>> About a question you raised before about set_feature location, it >> should >>> be done after the hw_start because >>> if the HW start fail there is no reason to send the command. this >>> command doesn't change the report descriptor size. >> >> I'm still not entirely sure of the ordering of things. Users have sent >> me the rdesc outputs from a device with 2.59 with and without your code >> to enable MT, and it looked to me like the report descriptor was >> different. I can try to experiment with that. >> >> Can you specify conditions or versions which cause this failure? It >> would be nice to be able to see for myself, especially since removing >> the naming and the quirk will disrupt quite a number of users. >> >> I do agree that the code should be more robust to bad conditions, so >> please try it with: >> >> list_for_each_entry(hidinput, &hdev->inputs, list) { >> + if (hidinput->report == NULL) { >> + dev_err(&hdev->dev, "NULL report\n"); >> + continue; >> + } >> >> That way we'll have a graceful fallback for your needs without breaking >> users. And also, hopefully this will lead to finding any lingering >> bugs. >> >> >>> -----Original Message----- >>> From: Rafi Rubin [mailto:rafi@seas.upenn.edu] >>> Sent: Mon 3/22/2010 10:43 PM >>> To: Micki Balanga >>> Cc: jkosina@suse.cz; chatty@enac.fr; peterhuewe@gmx.de; >>> linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; Henrik >> Rydberg >>> Subject: Re: [PATCH 1/2] HID: N-trig Add set feature commands to >> driver >>> >>> On 03/22/2010 03:58 PM, Micki Balanga wrote: >>> > >>> > Hi >>> > I would like to add more information about the Fake button. >>> > I will explain using this scenario: >>> > You touch the sensor with one finger and then remove the finger, >>> > Firmware will report six frames with fake fingers,(Indicate end of >>> session) >>> > The driver will report this as fake fingers (Will send 3 events) >> and >>> > input_sync >>> > to inform user space application that the user removed finger from >>> sensor. >>> > this information is needed in order to analyze the data received >> from >>> > N-trig firmware. >>> > Micki >>> >>> Thank you for taking this to a discussion format. >>> >>> It seems you have raised an issue that is an active discussion for >> multi >>> touch handling in general and an issue that I have considered for >> n-trig >>> support in specific. >>> >>> >>> The current published version of the driver does send one more >> sequence >>> of events after it decides all fingers are off the screen. That final >>> sequence is necessary to tell single touch drivers that the tools are >>> released (BTN_TOUCH is set to zero, etc). This also resets the active >>> contact count to zero for multi touch handlers, which look to see how >>> many MT events come from each frame. >>> >>> I had observed that sometimes the tablet looses contacts semi >>> arbitrarily, and we get a zero contact group as a mistake. In the >>> patches I sent in early in February you will notice a solution that I >>> was considering at the time. I was also playing with correcting for >>> events that looked like real contacts but were also just noise. After >>> rethinking my patches and reading the multi touch doc in the Documents >>> tree, I chose to leave out these corrections. >>> >>> That being said, I do have a specific patch to handle the set of end >> of >>> stream events. All that's needed is to count the empty groups and send >>> the terminal events only when a counter hits the specified value >>> (attached is a tiny patch I wrote when I needed that feature back >> really >>> quickly when my screen started misbehaving during a meeting). >>> >>> Note I have submitted that as a patch for 2 reasons. First I couldn't >>> be completely sure that there was a specific number of empty groups to >>> signal end of stream which would be expected to be maintained over >> time. >>> And secondly the erroneous termination of stream has not been much of >>> a problem in general. >>> >>> You will note, that this is something that is simple enough that it >>> makes perfect sense to put into the kernel. There's little point in >>> wasting the cycles to push that decision to user space. >>> >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-input" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkuqrXQACgkQwuRiAT9o60/HcACgi5ze2V11OMoDklz/WgxGIR8T J64AnRSoTv96r+LJYnIPBD0QGVjUf9li =7qYp -----END PGP SIGNATURE----- ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2010-03-25 0:25 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-03-22 12:16 [PATCH 1/2] HID: N-trig Add set feature commands to driver micki 2010-03-22 12:16 ` [PATCH 2/2] HID:HID-NTRIG update ntrig_event function micki 2010-03-22 18:06 ` Rafi Rubin 2010-03-22 17:29 ` [PATCH 1/2] HID: N-trig Add set feature commands to driver Rafi Rubin [not found] ` <48A28051AC6D7A48B64F28272458190326DEE8@Exchange-IL.n-trig.com> 2010-03-22 18:17 ` Rafi Rubin [not found] ` <48A28051AC6D7A48B64F28272458190326DEEB@Exchange-IL.n-trig.com> 2010-03-22 20:43 ` Rafi Rubin [not found] ` <48A28051AC6D7A48B64F28272458190326DEEE@Exchange-IL.n-trig.com> 2010-03-22 21:55 ` Rafi Rubin 2010-03-23 14:43 ` Micki Balanga 2010-03-24 13:27 ` Mohamed Ikbel Boulabiar [not found] ` <48A28051AC6D7A48B64F28272458190326DEF4@Exchange-IL.n-trig.com> 2010-03-25 0:25 ` Rafi Rubin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).