diff options
Diffstat (limited to 'drivers/input/touchscreen/mp900_ts.c')
-rw-r--r-- | drivers/input/touchscreen/mp900_ts.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/mp900_ts.c b/drivers/input/touchscreen/mp900_ts.c new file mode 100644 index 00000000000000..0c73b4f929c758 --- /dev/null +++ b/drivers/input/touchscreen/mp900_ts.c @@ -0,0 +1,160 @@ +/* drivers/input/touchscreen/mp900_ts.c + * + * input driver for the NEC MobilePro900/c touchscreen + * + * 2010(c) Yulay Rakhmangulov <yulayr@gmail.com> + * based on (c) 2007 mp900_kbd.c driver by + * Michael Petchkovsky <mkpetch@internode.on.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/input.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/workqueue.h> +#include <linux/platform_device.h> +#include <mach/pic-pxa2xx.h> + +#define PFX "mp900-ts: " + +static struct input_dev *dev_ts; + +static inline void request_touch_scan(void) +{ + unsigned char cmd = PIC_TS_SCAN_REQUEST; + send_to_pic(&cmd, 1); +} + +static inline void disable_touchscreen(void) +{ + unsigned char cmd = PIC_DISABLE_TOUCHSCREEN; + send_to_pic(&cmd, 1); +} + +static void update_position(const unsigned char *buf) +{ + int x, y; + + x = 256 * buf[0] + buf[1]; + y = 256 * buf[2] + buf[3]; + + input_report_key(dev_ts, BTN_TOUCH, 1); + input_report_abs(dev_ts, ABS_X, x); + input_report_abs(dev_ts, ABS_Y, y); + input_report_abs(dev_ts, ABS_PRESSURE, 1); + input_sync(dev_ts); +} + +static void notify_pen_lifted(void) +{ + disable_touchscreen(); + + input_report_key(dev_ts, BTN_TOUCH, 0); + input_report_abs(dev_ts, ABS_PRESSURE, 0); + input_sync(dev_ts); + + request_touch_scan(); +} + +static struct pic_touchscreen_ops touchscreen_ops = { + .update_position = update_position, + .notify_pen_lifted = notify_pen_lifted +}; + +#ifdef CONFIG_PM +static int suspend_touchscreen(struct device *dev) +{ + disable_touchscreen(); + return 0; +} + +static int resume_touchscreen(struct device *dev) +{ + request_touch_scan(); + return 0; +} + +static const struct dev_pm_ops mp900_ts_pm_ops = { + .suspend = suspend_touchscreen, + .resume = resume_touchscreen, +}; +#endif + +static int __devinit mp900_ts_probe(struct platform_device *pdev) +{ + int ret = 0; + + printk(KERN_INFO PFX "initializing touchscreen\n"); + + /* Touchscreen */ + dev_ts = input_allocate_device(); + dev_ts->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + dev_ts->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + set_bit(BTN_TOUCH, dev_ts->keybit); + + /* Not generic values, will need adjusting */ + dev_ts->absmin[ABS_X] = 32; + dev_ts->absmin[ABS_Y] = 96; + dev_ts->absmax[ABS_X] = 1004; + dev_ts->absmax[ABS_Y] = 792; + dev_ts->name = "MobilePro900/c touchscreen"; + dev_ts->phys = "mp900-ts/input0"; + dev_ts->dev.parent = &pdev->dev; + + ret = input_register_device(dev_ts); + if (ret) { + printk(KERN_ERR PFX "failed to register touch device!\n"); + return ret; + } + + pic_register_device(PIC_TOUCHSCREEN, (void *)&touchscreen_ops); + + request_touch_scan(); + return 0; +} + +static int __devexit mp900_ts_remove(struct platform_device *pdev) +{ + pic_unregister_device(PIC_TOUCHSCREEN, (void *)&touchscreen_ops); + + input_unregister_device(dev_ts); + + printk(KERN_INFO PFX "touchscreen device removed\n"); + return 0; +} + +static struct platform_driver mp900_ts_driver = { + .probe = mp900_ts_probe, + .remove = __devexit_p(mp900_ts_remove), + + .driver = { + .name = "mp900-ts", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &mp900_ts_pm_ops, +#endif + }, +}; + +static int __init mp900_ts_init(void) +{ + return platform_driver_register(&mp900_ts_driver); +} + +static void __exit mp900_ts_exit(void) +{ + platform_driver_unregister(&mp900_ts_driver); +} + +module_init(mp900_ts_init); +module_exit(mp900_ts_exit); + +MODULE_AUTHOR("Yulay Rakhmangulov"); +MODULE_DESCRIPTION("MobilePro900/c touchscreen driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:mp900-ts"); |