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