0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/errno.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/slab.h>
0019 #include <linux/input.h>
0020 #include <linux/serio.h>
0021
0022 #define DRIVER_DESC "iNexio serial touchscreen driver"
0023
0024 MODULE_AUTHOR("Richard Lemon <richard@codelemon.com>");
0025 MODULE_DESCRIPTION(DRIVER_DESC);
0026 MODULE_LICENSE("GPL");
0027
0028
0029
0030
0031
0032 #define INEXIO_FORMAT_TOUCH_BIT 0x01
0033 #define INEXIO_FORMAT_LENGTH 5
0034 #define INEXIO_RESPONSE_BEGIN_BYTE 0x80
0035
0036
0037 #define INEXIO_MAX_LENGTH 16
0038
0039 #define INEXIO_MIN_XC 0
0040 #define INEXIO_MAX_XC 0x3fff
0041 #define INEXIO_MIN_YC 0
0042 #define INEXIO_MAX_YC 0x3fff
0043
0044 #define INEXIO_GET_XC(data) (((data[1])<<7) | data[2])
0045 #define INEXIO_GET_YC(data) (((data[3])<<7) | data[4])
0046 #define INEXIO_GET_TOUCHED(data) (INEXIO_FORMAT_TOUCH_BIT & data[0])
0047
0048
0049
0050
0051
0052 struct inexio {
0053 struct input_dev *dev;
0054 struct serio *serio;
0055 int idx;
0056 unsigned char data[INEXIO_MAX_LENGTH];
0057 char phys[32];
0058 };
0059
0060 static void inexio_process_data(struct inexio *pinexio)
0061 {
0062 struct input_dev *dev = pinexio->dev;
0063
0064 if (INEXIO_FORMAT_LENGTH == ++pinexio->idx) {
0065 input_report_abs(dev, ABS_X, INEXIO_GET_XC(pinexio->data));
0066 input_report_abs(dev, ABS_Y, INEXIO_GET_YC(pinexio->data));
0067 input_report_key(dev, BTN_TOUCH, INEXIO_GET_TOUCHED(pinexio->data));
0068 input_sync(dev);
0069
0070 pinexio->idx = 0;
0071 }
0072 }
0073
0074 static irqreturn_t inexio_interrupt(struct serio *serio,
0075 unsigned char data, unsigned int flags)
0076 {
0077 struct inexio *pinexio = serio_get_drvdata(serio);
0078
0079 pinexio->data[pinexio->idx] = data;
0080
0081 if (INEXIO_RESPONSE_BEGIN_BYTE&pinexio->data[0])
0082 inexio_process_data(pinexio);
0083 else
0084 printk(KERN_DEBUG "inexio.c: unknown/unsynchronized data from device, byte %x\n",pinexio->data[0]);
0085
0086 return IRQ_HANDLED;
0087 }
0088
0089
0090
0091
0092
0093 static void inexio_disconnect(struct serio *serio)
0094 {
0095 struct inexio *pinexio = serio_get_drvdata(serio);
0096
0097 input_get_device(pinexio->dev);
0098 input_unregister_device(pinexio->dev);
0099 serio_close(serio);
0100 serio_set_drvdata(serio, NULL);
0101 input_put_device(pinexio->dev);
0102 kfree(pinexio);
0103 }
0104
0105
0106
0107
0108
0109
0110
0111 static int inexio_connect(struct serio *serio, struct serio_driver *drv)
0112 {
0113 struct inexio *pinexio;
0114 struct input_dev *input_dev;
0115 int err;
0116
0117 pinexio = kzalloc(sizeof(struct inexio), GFP_KERNEL);
0118 input_dev = input_allocate_device();
0119 if (!pinexio || !input_dev) {
0120 err = -ENOMEM;
0121 goto fail1;
0122 }
0123
0124 pinexio->serio = serio;
0125 pinexio->dev = input_dev;
0126 snprintf(pinexio->phys, sizeof(pinexio->phys), "%s/input0", serio->phys);
0127
0128 input_dev->name = "iNexio Serial TouchScreen";
0129 input_dev->phys = pinexio->phys;
0130 input_dev->id.bustype = BUS_RS232;
0131 input_dev->id.vendor = SERIO_INEXIO;
0132 input_dev->id.product = 0;
0133 input_dev->id.version = 0x0001;
0134 input_dev->dev.parent = &serio->dev;
0135 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
0136 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
0137 input_set_abs_params(pinexio->dev, ABS_X, INEXIO_MIN_XC, INEXIO_MAX_XC, 0, 0);
0138 input_set_abs_params(pinexio->dev, ABS_Y, INEXIO_MIN_YC, INEXIO_MAX_YC, 0, 0);
0139
0140 serio_set_drvdata(serio, pinexio);
0141
0142 err = serio_open(serio, drv);
0143 if (err)
0144 goto fail2;
0145
0146 err = input_register_device(pinexio->dev);
0147 if (err)
0148 goto fail3;
0149
0150 return 0;
0151
0152 fail3: serio_close(serio);
0153 fail2: serio_set_drvdata(serio, NULL);
0154 fail1: input_free_device(input_dev);
0155 kfree(pinexio);
0156 return err;
0157 }
0158
0159
0160
0161
0162
0163 static const struct serio_device_id inexio_serio_ids[] = {
0164 {
0165 .type = SERIO_RS232,
0166 .proto = SERIO_INEXIO,
0167 .id = SERIO_ANY,
0168 .extra = SERIO_ANY,
0169 },
0170 { 0 }
0171 };
0172
0173 MODULE_DEVICE_TABLE(serio, inexio_serio_ids);
0174
0175 static struct serio_driver inexio_drv = {
0176 .driver = {
0177 .name = "inexio",
0178 },
0179 .description = DRIVER_DESC,
0180 .id_table = inexio_serio_ids,
0181 .interrupt = inexio_interrupt,
0182 .connect = inexio_connect,
0183 .disconnect = inexio_disconnect,
0184 };
0185
0186 module_serio_driver(inexio_drv);