aboutsummaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/da9034-ts.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/da9034-ts.c')
-rw-r--r--drivers/input/touchscreen/da9034-ts.c87
1 files changed, 33 insertions, 54 deletions
diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c
index fa67d782c3c..cf6f4b31db4 100644
--- a/drivers/input/touchscreen/da9034-ts.c
+++ b/drivers/input/touchscreen/da9034-ts.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2006-2008 Marvell International Ltd.
* Fengwei Yin <fengwei.yin@marvell.com>
+ * Bin Yang <bin.yang@marvell.com>
* Eric Miao <eric.miao@marvell.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -12,12 +13,12 @@
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/mfd/da903x.h>
+#include <linux/slab.h>
#define DA9034_MANUAL_CTRL 0x50
#define DA9034_LDO_ADC_EN (1 << 4)
@@ -175,6 +176,16 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
goto err_reset;
touch->state = STATE_STOP;
+
+ /* FIXME: PEN_{UP/DOWN} events are expected to be
+ * available by stopping TSI, but this is found not
+ * always true, delay and simulate such an event
+ * here is more reliable
+ */
+ mdelay(1);
+ da9034_event_handler(touch,
+ is_pen_down(touch) ? EVENT_PEN_DOWN :
+ EVENT_PEN_UP);
break;
case STATE_STOP:
@@ -189,8 +200,6 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
report_pen_up(touch);
touch->state = STATE_IDLE;
}
-
- input_sync(touch->input_dev);
break;
case STATE_WAIT:
@@ -200,8 +209,10 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
if (is_pen_down(touch)) {
start_tsi(touch);
touch->state = STATE_BUSY;
- } else
+ } else {
+ report_pen_up(touch);
touch->state = STATE_IDLE;
+ }
break;
}
return;
@@ -226,16 +237,12 @@ static int da9034_touch_notifier(struct notifier_block *nb,
struct da9034_touch *touch =
container_of(nb, struct da9034_touch, notifier);
- if (event & DA9034_EVENT_PEN_DOWN) {
- if (is_pen_down(touch))
- da9034_event_handler(touch, EVENT_PEN_DOWN);
- else
- da9034_event_handler(touch, EVENT_PEN_UP);
- }
-
if (event & DA9034_EVENT_TSI_READY)
da9034_event_handler(touch, EVENT_TSI_READY);
+ if ((event & DA9034_EVENT_PEN_DOWN) && touch->state == STATE_IDLE)
+ da9034_event_handler(touch, EVENT_PEN_DOWN);
+
return 0;
}
@@ -289,15 +296,16 @@ static void da9034_touch_close(struct input_dev *dev)
}
-static int __devinit da9034_touch_probe(struct platform_device *pdev)
+static int da9034_touch_probe(struct platform_device *pdev)
{
- struct da9034_touch_pdata *pdata = pdev->dev.platform_data;
+ struct da9034_touch_pdata *pdata = dev_get_platdata(&pdev->dev);
struct da9034_touch *touch;
struct input_dev *input_dev;
- int ret;
+ int error;
- touch = kzalloc(sizeof(struct da9034_touch), GFP_KERNEL);
- if (touch == NULL) {
+ touch = devm_kzalloc(&pdev->dev, sizeof(struct da9034_touch),
+ GFP_KERNEL);
+ if (!touch) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
return -ENOMEM;
}
@@ -308,18 +316,18 @@ static int __devinit da9034_touch_probe(struct platform_device *pdev)
touch->interval_ms = pdata->interval_ms;
touch->x_inverted = pdata->x_inverted;
touch->y_inverted = pdata->y_inverted;
- } else
+ } else {
/* fallback into default */
touch->interval_ms = 10;
+ }
INIT_DELAYED_WORK(&touch->tsi_work, da9034_tsi_work);
touch->notifier.notifier_call = da9034_touch_notifier;
- input_dev = input_allocate_device();
+ input_dev = devm_input_allocate_device(&pdev->dev);
if (!input_dev) {
dev_err(&pdev->dev, "failed to allocate input device\n");
- ret = -ENOMEM;
- goto err_free_touch;
+ return -ENOMEM;
}
input_dev->name = pdev->name;
@@ -339,26 +347,9 @@ static int __devinit da9034_touch_probe(struct platform_device *pdev)
touch->input_dev = input_dev;
input_set_drvdata(input_dev, touch);
- ret = input_register_device(input_dev);
- if (ret)
- goto err_free_input;
-
- platform_set_drvdata(pdev, touch);
- return 0;
-
-err_free_input:
- input_free_device(input_dev);
-err_free_touch:
- kfree(touch);
- return ret;
-}
-
-static int __devexit da9034_touch_remove(struct platform_device *pdev)
-{
- struct da9034_touch *touch = platform_get_drvdata(pdev);
-
- input_unregister_device(touch->input_dev);
- kfree(touch);
+ error = input_register_device(input_dev);
+ if (error)
+ return error;
return 0;
}
@@ -369,22 +360,10 @@ static struct platform_driver da9034_touch_driver = {
.owner = THIS_MODULE,
},
.probe = da9034_touch_probe,
- .remove = __devexit_p(da9034_touch_remove),
};
-
-static int __init da9034_touch_init(void)
-{
- return platform_driver_register(&da9034_touch_driver);
-}
-module_init(da9034_touch_init);
-
-static void __exit da9034_touch_exit(void)
-{
- platform_driver_unregister(&da9034_touch_driver);
-}
-module_exit(da9034_touch_exit);
+module_platform_driver(da9034_touch_driver);
MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>, Bin Yang <bin.yang@marvell.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:da9034-touch");