Path: blob/master/drivers/input/touchscreen/touchright.c
15109 views
/*1* Touchright serial touchscreen driver2*3* Copyright (c) 2006 Rick Koch <[email protected]>4*5* Based on MicroTouch driver (drivers/input/touchscreen/mtouch.c)6* Copyright (c) 2004 Vojtech Pavlik7* and Dan Streetman <[email protected]>8*/910/*11* This program is free software; you can redistribute it and/or modify it12* under the terms of the GNU General Public License version 2 as published13* by the Free Software Foundation.14*/1516#include <linux/errno.h>17#include <linux/kernel.h>18#include <linux/module.h>19#include <linux/slab.h>20#include <linux/input.h>21#include <linux/serio.h>22#include <linux/init.h>2324#define DRIVER_DESC "Touchright serial touchscreen driver"2526MODULE_AUTHOR("Rick Koch <[email protected]>");27MODULE_DESCRIPTION(DRIVER_DESC);28MODULE_LICENSE("GPL");2930/*31* Definitions & global arrays.32*/3334#define TR_FORMAT_TOUCH_BIT 0x0135#define TR_FORMAT_STATUS_BYTE 0x4036#define TR_FORMAT_STATUS_MASK ~TR_FORMAT_TOUCH_BIT3738#define TR_LENGTH 53940#define TR_MIN_XC 041#define TR_MAX_XC 0x1ff42#define TR_MIN_YC 043#define TR_MAX_YC 0x1ff4445/*46* Per-touchscreen data.47*/4849struct tr {50struct input_dev *dev;51struct serio *serio;52int idx;53unsigned char data[TR_LENGTH];54char phys[32];55};5657static irqreturn_t tr_interrupt(struct serio *serio,58unsigned char data, unsigned int flags)59{60struct tr *tr = serio_get_drvdata(serio);61struct input_dev *dev = tr->dev;6263tr->data[tr->idx] = data;6465if ((tr->data[0] & TR_FORMAT_STATUS_MASK) == TR_FORMAT_STATUS_BYTE) {66if (++tr->idx == TR_LENGTH) {67input_report_abs(dev, ABS_X,68(tr->data[1] << 5) | (tr->data[2] >> 1));69input_report_abs(dev, ABS_Y,70(tr->data[3] << 5) | (tr->data[4] >> 1));71input_report_key(dev, BTN_TOUCH,72tr->data[0] & TR_FORMAT_TOUCH_BIT);73input_sync(dev);74tr->idx = 0;75}76}7778return IRQ_HANDLED;79}8081/*82* tr_disconnect() is the opposite of tr_connect()83*/8485static void tr_disconnect(struct serio *serio)86{87struct tr *tr = serio_get_drvdata(serio);8889input_get_device(tr->dev);90input_unregister_device(tr->dev);91serio_close(serio);92serio_set_drvdata(serio, NULL);93input_put_device(tr->dev);94kfree(tr);95}9697/*98* tr_connect() is the routine that is called when someone adds a99* new serio device that supports the Touchright protocol and registers it as100* an input device.101*/102103static int tr_connect(struct serio *serio, struct serio_driver *drv)104{105struct tr *tr;106struct input_dev *input_dev;107int err;108109tr = kzalloc(sizeof(struct tr), GFP_KERNEL);110input_dev = input_allocate_device();111if (!tr || !input_dev) {112err = -ENOMEM;113goto fail1;114}115116tr->serio = serio;117tr->dev = input_dev;118snprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys);119120input_dev->name = "Touchright Serial TouchScreen";121input_dev->phys = tr->phys;122input_dev->id.bustype = BUS_RS232;123input_dev->id.vendor = SERIO_TOUCHRIGHT;124input_dev->id.product = 0;125input_dev->id.version = 0x0100;126input_dev->dev.parent = &serio->dev;127input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);128input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);129input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0);130input_set_abs_params(tr->dev, ABS_Y, TR_MIN_YC, TR_MAX_YC, 0, 0);131132serio_set_drvdata(serio, tr);133134err = serio_open(serio, drv);135if (err)136goto fail2;137138err = input_register_device(tr->dev);139if (err)140goto fail3;141142return 0;143144fail3: serio_close(serio);145fail2: serio_set_drvdata(serio, NULL);146fail1: input_free_device(input_dev);147kfree(tr);148return err;149}150151/*152* The serio driver structure.153*/154155static struct serio_device_id tr_serio_ids[] = {156{157.type = SERIO_RS232,158.proto = SERIO_TOUCHRIGHT,159.id = SERIO_ANY,160.extra = SERIO_ANY,161},162{ 0 }163};164165MODULE_DEVICE_TABLE(serio, tr_serio_ids);166167static struct serio_driver tr_drv = {168.driver = {169.name = "touchright",170},171.description = DRIVER_DESC,172.id_table = tr_serio_ids,173.interrupt = tr_interrupt,174.connect = tr_connect,175.disconnect = tr_disconnect,176};177178/*179* The functions for inserting/removing us as a module.180*/181182static int __init tr_init(void)183{184return serio_register_driver(&tr_drv);185}186187static void __exit tr_exit(void)188{189serio_unregister_driver(&tr_drv);190}191192module_init(tr_init);193module_exit(tr_exit);194195196