diff options
author | Varun Wadekar <vwadekar@nvidia.com> | 2010-03-11 11:18:59 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-03-11 22:36:58 -0800 |
commit | 570fbc982f90f7a85e4297a4a1e12785880fdab4 (patch) | |
tree | b6cd5cfaab2cf7cd9399030031039e9c5370ec2e | |
parent | d7410ca658ea62a51163655f000cf20c640c76f9 (diff) |
tegra touch: enable multi-touch
adding multi-touch support to the touch screen driver.
Tested with Gallery3D, Multitouch Visualizer and Multitouch Visualise test apps.
Fod Bug 653317
Change-Id: I2976ab91c06a54de4772d88c3d96d72a753205ed
Reviewed-on: http://git-master/r/834
Tested-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-by: Harry Hong <hhong@nvidia.com>
Tested-by: Harry Hong <hhong@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c | 4 | ||||
-rwxr-xr-x | drivers/input/touchscreen/tegra_odm.c | 171 |
2 files changed, 78 insertions, 97 deletions
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c index 2debb20abf02..c57663299cc8 100644 --- a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c +++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c @@ -96,8 +96,8 @@ static const NvOdmTouchCapabilities TPK_Capabilities = 2, //MaxNumberOfFingerCoordReported; 0, //IsRelativeDataSupported 1, //MaxNumberOfRelativeCoordReported - 1, //MaxNumberOfWidthReported - 1, //MaxNumberOfPressureReported + 15, //MaxNumberOfWidthReported + 255, //MaxNumberOfPressureReported (NvU32)NvOdmTouchGesture_Not_Supported, //Gesture 1, //IsWidthSupported 1, //IsPressureSupported diff --git a/drivers/input/touchscreen/tegra_odm.c b/drivers/input/touchscreen/tegra_odm.c index 1d97ec879022..dde5d5f02909 100755 --- a/drivers/input/touchscreen/tegra_odm.c +++ b/drivers/input/touchscreen/tegra_odm.c @@ -31,6 +31,9 @@ #include <nvodm_services.h> #include <nvodm_touch.h> +#define TOOL_PRESSURE 100 +#define TOOL_WIDTH 8 + struct tegra_touch_driver_data { struct input_dev *input_dev; @@ -109,10 +112,11 @@ static int tegra_touch_thread(void *pdata) struct tegra_touch_driver_data *touch = (struct tegra_touch_driver_data*)pdata; NvOdmTouchCoordinateInfo c = {0}; - NvU32 x[2] = {0}, y[2] = {0}, i = 0, prev_x[2] = {0}, prev_y[2] = {0}; + NvU32 x[2] = {0}, y[2] = {0}, i = 0; + NvU32 Pressure = TOOL_PRESSURE, Width = TOOL_WIDTH; + static NvU32 prev_x[2] = {0}, prev_y[2] = {0}; NvBool bKeepReadingSamples = NV_FALSE; NvU32 fingers = 0; - NvBool ToolDown[2] = {NV_FALSE, NV_FALSE}; NvOdmTouchCapabilities *caps = &touch->caps; NvU32 max_fingers = caps->MaxNumberOfFingerCoordReported; @@ -135,72 +139,29 @@ static int tegra_touch_thread(void *pdata) fingers = c.additionalInfo.Fingers; - /* - * sometimes the HW reports num of fingers greater than - * the max supported. This happens when previously there - * were 2 fingers touching and one of them was lifted. - * We give away the previously stored state for the - * first finger, and the lifted finger is - * sent with flags indicating PEN UP. - */ - if (((fingers == 1) || (fingers>max_fingers)) && - (ToolDown[1] == NV_TRUE)) { - ToolDown[0] = NV_TRUE; - input_report_abs(touch->input_dev, - ABS_X, prev_x[0]); - input_report_abs(touch->input_dev, - ABS_Y, prev_y[0]); - input_report_key(touch->input_dev, - BTN_TOUCH, ToolDown[0]); - ToolDown[1] = NV_FALSE; - input_report_abs(touch->input_dev, - ABS_HAT0X, prev_x[1]); // x - input_report_abs(touch->input_dev, - ABS_HAT0Y, prev_y[1]); // y - input_report_key(touch->input_dev, - BTN_2, ToolDown[1]); - input_sync(touch->input_dev); - } - - if (c.fingerstate & NvOdmTouchSampleIgnore) - goto DoneWithSample; - switch (fingers) { case 0: - for (i=0; i<max_fingers; i++) { - ToolDown[i] = NV_FALSE; - } + x[0] = prev_x[0]; + y[0] = prev_y[0]; + Pressure = 0; break; case 1: - ToolDown[0] = NV_TRUE; - ToolDown[1] = NV_FALSE; + x[0] = c.xcoord; + y[0] = c.ycoord; + Pressure = TOOL_PRESSURE; break; case 2: - for (i=0; i<max_fingers; i++) { - ToolDown[i] = NV_TRUE; + for (i = 0; i < fingers; i++) { + x[i] = c.additionalInfo.multi_XYCoords[i][0]; + y[i] = c.additionalInfo.multi_XYCoords[i][1]; } + Pressure = TOOL_PRESSURE; break; default: /* can occur because of sensor errors */ - c.fingerstate = NvOdmTouchSampleIgnore;; - goto DoneWithSample; - } - - /* from 1 finger to no fingers */ - if ((fingers == 0) && (ToolDown[0] == NV_TRUE)) { x[0] = prev_x[0]; y[0] = prev_y[0]; - ToolDown[0] = NV_FALSE; - } - else if (fingers == 1) { - x[0] = c.xcoord; - y[0] = c.ycoord; - } - else { - for (i = 0; i < fingers; i++) { - x[i] = c.additionalInfo.multi_XYCoords[i][0]; - y[i] = c.additionalInfo.multi_XYCoords[i][1]; - } + fingers = 1; } /* transformation from touch to screen orientation */ @@ -222,27 +183,17 @@ static int tegra_touch_thread(void *pdata) swapv(x[i],y[i]); } - if (c.fingerstate & NvOdmTouchSampleValidFlag) { - input_report_abs(touch->input_dev, ABS_X, x[0]); - input_report_abs(touch->input_dev, ABS_Y, y[0]); - prev_x[0] = x[0]; - prev_y[0] = y[0]; - } + /* report 1st finger's co-ordinates */ + input_report_abs(touch->input_dev, ABS_X, x[0]); + input_report_abs(touch->input_dev, ABS_Y, y[0]); + prev_x[0] = x[0]; + prev_y[0] = y[0]; - if (caps->IsPressureSupported) { - input_report_abs(touch->input_dev, - ABS_PRESSURE, - c.additionalInfo.Pressure[0]); - } - if (caps->IsWidthSupported) { - input_report_abs(touch->input_dev, - ABS_TOOL_WIDTH, - c.additionalInfo.width[0]); - } - - /* Report down or up flag */ + /* Report number of fingers */ + input_report_key(touch->input_dev, + BTN_TOUCH, fingers); input_report_key(touch->input_dev, - BTN_TOUCH, ToolDown[0]); + BTN_2, fingers == 2); /* report co-ordinates for the 2nd finger */ if (fingers == 2) { @@ -250,23 +201,34 @@ static int tegra_touch_thread(void *pdata) ABS_HAT0X, x[1]); // x input_report_abs(touch->input_dev, ABS_HAT0Y, y[1]); // y - input_report_key(touch->input_dev, - BTN_2, ToolDown[1]); prev_x[1] = x[1]; prev_y[1] = y[1]; - } else if (((fingers == 1) || (fingers == 0)) && - (ToolDown[1] == NV_TRUE)) { - ToolDown[1] = NV_FALSE; + } + + input_report_abs(touch->input_dev, + ABS_MT_TOUCH_MAJOR, Pressure); + input_report_abs(touch->input_dev, + ABS_MT_WIDTH_MAJOR, Width); + input_report_abs(touch->input_dev, + ABS_MT_POSITION_X, x[0]); + input_report_abs(touch->input_dev, + ABS_MT_POSITION_Y, y[0]); + input_mt_sync(touch->input_dev); + + /* report co-ordinates for the 2nd finger */ + if (fingers == 2) { + input_report_abs(touch->input_dev, + ABS_MT_TOUCH_MAJOR, Pressure); input_report_abs(touch->input_dev, - ABS_HAT0X, prev_x[1]); // x + ABS_MT_WIDTH_MAJOR, Width); input_report_abs(touch->input_dev, - ABS_HAT0Y, prev_y[1]); // y - input_report_key(touch->input_dev, - BTN_2, ToolDown[1]); + ABS_MT_POSITION_X, x[1]); + input_report_abs(touch->input_dev, + ABS_MT_POSITION_Y, y[1]); + input_mt_sync(touch->input_dev); } input_sync(touch->input_dev); -DoneWithSample: bKeepReadingSamples = NV_FALSE; if (!touch->bPollingMode && !NvOdmTouchHandleInterrupt(touch->hTouchDevice)) { @@ -329,13 +291,21 @@ static int __init tegra_touch_probe(struct platform_device *pdev) /* Will generate sync at the end of all input */ set_bit(EV_SYN, touch->input_dev->evbit); - /* Event is key input type */ set_bit(EV_KEY, touch->input_dev->evbit); - /* virtual key is BTN_TOUCH */ - set_bit(BTN_TOUCH, touch->input_dev->keybit); /* Input values are in absoulte values */ set_bit(EV_ABS, touch->input_dev->evbit); + /* virtual key is BTN_TOUCH */ + set_bit(BTN_TOUCH, touch->input_dev->keybit); + /* virtual key is BTN_2 */ + set_bit(BTN_2, touch->input_dev->keybit); + + /* expose multi-touch capabilities */ + set_bit(ABS_MT_TOUCH_MAJOR, touch->input_dev->keybit); + set_bit(ABS_MT_POSITION_X, touch->input_dev->keybit); + set_bit(ABS_MT_POSITION_Y, touch->input_dev->keybit); + set_bit(ABS_X, touch->input_dev->keybit); + set_bit(ABS_Y, touch->input_dev->keybit); NvOdmTouchDeviceGetCapabilities(touch->hTouchDevice, &touch->caps); @@ -362,17 +332,28 @@ static int __init tegra_touch_probe(struct platform_device *pdev) touch->MaxX, 0, 0); input_set_abs_params(touch->input_dev, ABS_HAT0Y, touch->MinY, touch->MaxY, 0, 0); - - if (caps->IsPressureSupported) - input_set_abs_params(touch->input_dev, ABS_PRESSURE, 0, + input_set_abs_params(touch->input_dev, ABS_MT_POSITION_X, + touch->MinX, touch->MaxX, 0, 0); + input_set_abs_params(touch->input_dev, ABS_MT_POSITION_Y, + touch->MinY, touch->MaxY, 0, 0); + + if (caps->IsPressureSupported) { + input_set_abs_params(touch->input_dev, ABS_MT_TOUCH_MAJOR, + 0, caps->MaxNumberOfPressureReported, 0, 0); + input_set_abs_params(touch->input_dev, ABS_PRESSURE, 0, caps->MaxNumberOfPressureReported, 0, 0); - if (caps->IsWidthSupported) - input_set_abs_params(touch->input_dev, ABS_TOOL_WIDTH, 0, + } + + if (caps->IsWidthSupported) { + input_set_abs_params(touch->input_dev, ABS_TOOL_WIDTH, 0, + caps->MaxNumberOfWidthReported, 0, 0); + input_set_abs_params(touch->input_dev, ABS_MT_WIDTH_MAJOR, 0, caps->MaxNumberOfWidthReported, 0, 0); + } platform_set_drvdata(pdev, touch); - err = input_register_device(input_dev); + err = input_register_device(touch->input_dev); if (err) { pr_err("tegra_touch_probe: Unable to register input device\n"); @@ -396,8 +377,8 @@ err_kthread_create_failed: err_open_failed: NvOdmOsSemaphoreDestroy(touch->semaphore); err_semaphore_create_failed: + input_free_device(touch->input_dev); kfree(touch); - input_free_device(input_dev); return err; } |