Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Penmount serial touchscreen driver
0004  *
0005  * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
0006  * Copyright (c) 2011 John Sung <penmount.touch@gmail.com>
0007  *
0008  * Based on ELO driver (drivers/input/touchscreen/elo.c)
0009  * Copyright (c) 2004 Vojtech Pavlik
0010  */
0011 
0012 
0013 #include <linux/errno.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/slab.h>
0017 #include <linux/input.h>
0018 #include <linux/input/mt.h>
0019 #include <linux/serio.h>
0020 
0021 #define DRIVER_DESC "PenMount serial touchscreen driver"
0022 
0023 MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
0024 MODULE_AUTHOR("John Sung <penmount.touch@gmail.com>");
0025 MODULE_DESCRIPTION(DRIVER_DESC);
0026 MODULE_LICENSE("GPL");
0027 
0028 /*
0029  * Definitions & global arrays.
0030  */
0031 
0032 #define PM_MAX_LENGTH   6
0033 #define PM_MAX_MTSLOT   16
0034 #define PM_3000_MTSLOT  2
0035 #define PM_6250_MTSLOT  12
0036 
0037 /*
0038  * Multi-touch slot
0039  */
0040 
0041 struct mt_slot {
0042     unsigned short x, y;
0043     bool active; /* is the touch valid? */
0044 };
0045 
0046 /*
0047  * Per-touchscreen data.
0048  */
0049 
0050 struct pm {
0051     struct input_dev *dev;
0052     struct serio *serio;
0053     int idx;
0054     unsigned char data[PM_MAX_LENGTH];
0055     char phys[32];
0056     unsigned char packetsize;
0057     unsigned char maxcontacts;
0058     struct mt_slot slots[PM_MAX_MTSLOT];
0059     void (*parse_packet)(struct pm *);
0060 };
0061 
0062 /*
0063  * pm_mtevent() sends mt events and also emulates pointer movement
0064  */
0065 
0066 static void pm_mtevent(struct pm *pm, struct input_dev *input)
0067 {
0068     int i;
0069 
0070     for (i = 0; i < pm->maxcontacts; ++i) {
0071         input_mt_slot(input, i);
0072         input_mt_report_slot_state(input, MT_TOOL_FINGER,
0073                 pm->slots[i].active);
0074         if (pm->slots[i].active) {
0075             input_event(input, EV_ABS, ABS_MT_POSITION_X, pm->slots[i].x);
0076             input_event(input, EV_ABS, ABS_MT_POSITION_Y, pm->slots[i].y);
0077         }
0078     }
0079 
0080     input_mt_report_pointer_emulation(input, true);
0081     input_sync(input);
0082 }
0083 
0084 /*
0085  * pm_checkpacket() checks if data packet is valid
0086  */
0087 
0088 static bool pm_checkpacket(unsigned char *packet)
0089 {
0090     int total = 0;
0091     int i;
0092 
0093     for (i = 0; i < 5; i++)
0094         total += packet[i];
0095 
0096     return packet[5] == (unsigned char)~(total & 0xff);
0097 }
0098 
0099 static void pm_parse_9000(struct pm *pm)
0100 {
0101     struct input_dev *dev = pm->dev;
0102 
0103     if ((pm->data[0] & 0x80) && pm->packetsize == ++pm->idx) {
0104         input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]);
0105         input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]);
0106         input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
0107         input_sync(dev);
0108         pm->idx = 0;
0109     }
0110 }
0111 
0112 static void pm_parse_6000(struct pm *pm)
0113 {
0114     struct input_dev *dev = pm->dev;
0115 
0116     if ((pm->data[0] & 0xbf) == 0x30 && pm->packetsize == ++pm->idx) {
0117         if (pm_checkpacket(pm->data)) {
0118             input_report_abs(dev, ABS_X,
0119                     pm->data[2] * 256 + pm->data[1]);
0120             input_report_abs(dev, ABS_Y,
0121                     pm->data[4] * 256 + pm->data[3]);
0122             input_report_key(dev, BTN_TOUCH, pm->data[0] & 0x40);
0123             input_sync(dev);
0124         }
0125         pm->idx = 0;
0126     }
0127 }
0128 
0129 static void pm_parse_3000(struct pm *pm)
0130 {
0131     struct input_dev *dev = pm->dev;
0132 
0133     if ((pm->data[0] & 0xce) == 0x40 && pm->packetsize == ++pm->idx) {
0134         if (pm_checkpacket(pm->data)) {
0135             int slotnum = pm->data[0] & 0x0f;
0136             pm->slots[slotnum].active = pm->data[0] & 0x30;
0137             pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
0138             pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
0139             pm_mtevent(pm, dev);
0140         }
0141         pm->idx = 0;
0142     }
0143 }
0144 
0145 static void pm_parse_6250(struct pm *pm)
0146 {
0147     struct input_dev *dev = pm->dev;
0148 
0149     if ((pm->data[0] & 0xb0) == 0x30 && pm->packetsize == ++pm->idx) {
0150         if (pm_checkpacket(pm->data)) {
0151             int slotnum = pm->data[0] & 0x0f;
0152             pm->slots[slotnum].active = pm->data[0] & 0x40;
0153             pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
0154             pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
0155             pm_mtevent(pm, dev);
0156         }
0157         pm->idx = 0;
0158     }
0159 }
0160 
0161 static irqreturn_t pm_interrupt(struct serio *serio,
0162         unsigned char data, unsigned int flags)
0163 {
0164     struct pm *pm = serio_get_drvdata(serio);
0165 
0166     pm->data[pm->idx] = data;
0167 
0168     pm->parse_packet(pm);
0169 
0170     return IRQ_HANDLED;
0171 }
0172 
0173 /*
0174  * pm_disconnect() is the opposite of pm_connect()
0175  */
0176 
0177 static void pm_disconnect(struct serio *serio)
0178 {
0179     struct pm *pm = serio_get_drvdata(serio);
0180 
0181     serio_close(serio);
0182 
0183     input_unregister_device(pm->dev);
0184     kfree(pm);
0185 
0186     serio_set_drvdata(serio, NULL);
0187 }
0188 
0189 /*
0190  * pm_connect() is the routine that is called when someone adds a
0191  * new serio device that supports PenMount protocol and registers it as
0192  * an input device.
0193  */
0194 
0195 static int pm_connect(struct serio *serio, struct serio_driver *drv)
0196 {
0197     struct pm *pm;
0198     struct input_dev *input_dev;
0199     int max_x, max_y;
0200     int err;
0201 
0202     pm = kzalloc(sizeof(struct pm), GFP_KERNEL);
0203     input_dev = input_allocate_device();
0204     if (!pm || !input_dev) {
0205         err = -ENOMEM;
0206         goto fail1;
0207     }
0208 
0209     pm->serio = serio;
0210     pm->dev = input_dev;
0211     snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys);
0212     pm->maxcontacts = 1;
0213 
0214     input_dev->name = "PenMount Serial TouchScreen";
0215     input_dev->phys = pm->phys;
0216     input_dev->id.bustype = BUS_RS232;
0217     input_dev->id.vendor = SERIO_PENMOUNT;
0218     input_dev->id.product = 0;
0219     input_dev->id.version = 0x0100;
0220     input_dev->dev.parent = &serio->dev;
0221 
0222     input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
0223     input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
0224 
0225     switch (serio->id.id) {
0226     default:
0227     case 0:
0228         pm->packetsize = 5;
0229         pm->parse_packet = pm_parse_9000;
0230         input_dev->id.product = 0x9000;
0231         max_x = max_y = 0x3ff;
0232         break;
0233 
0234     case 1:
0235         pm->packetsize = 6;
0236         pm->parse_packet = pm_parse_6000;
0237         input_dev->id.product = 0x6000;
0238         max_x = max_y = 0x3ff;
0239         break;
0240 
0241     case 2:
0242         pm->packetsize = 6;
0243         pm->parse_packet = pm_parse_3000;
0244         input_dev->id.product = 0x3000;
0245         max_x = max_y = 0x7ff;
0246         pm->maxcontacts = PM_3000_MTSLOT;
0247         break;
0248 
0249     case 3:
0250         pm->packetsize = 6;
0251         pm->parse_packet = pm_parse_6250;
0252         input_dev->id.product = 0x6250;
0253         max_x = max_y = 0x3ff;
0254         pm->maxcontacts = PM_6250_MTSLOT;
0255         break;
0256     }
0257 
0258     input_set_abs_params(pm->dev, ABS_X, 0, max_x, 0, 0);
0259     input_set_abs_params(pm->dev, ABS_Y, 0, max_y, 0, 0);
0260 
0261     if (pm->maxcontacts > 1) {
0262         input_mt_init_slots(pm->dev, pm->maxcontacts, 0);
0263         input_set_abs_params(pm->dev,
0264                      ABS_MT_POSITION_X, 0, max_x, 0, 0);
0265         input_set_abs_params(pm->dev,
0266                      ABS_MT_POSITION_Y, 0, max_y, 0, 0);
0267     }
0268 
0269     serio_set_drvdata(serio, pm);
0270 
0271     err = serio_open(serio, drv);
0272     if (err)
0273         goto fail2;
0274 
0275     err = input_register_device(pm->dev);
0276     if (err)
0277         goto fail3;
0278 
0279     return 0;
0280 
0281  fail3: serio_close(serio);
0282  fail2: serio_set_drvdata(serio, NULL);
0283  fail1: input_free_device(input_dev);
0284     kfree(pm);
0285     return err;
0286 }
0287 
0288 /*
0289  * The serio driver structure.
0290  */
0291 
0292 static const struct serio_device_id pm_serio_ids[] = {
0293     {
0294         .type   = SERIO_RS232,
0295         .proto  = SERIO_PENMOUNT,
0296         .id = SERIO_ANY,
0297         .extra  = SERIO_ANY,
0298     },
0299     { 0 }
0300 };
0301 
0302 MODULE_DEVICE_TABLE(serio, pm_serio_ids);
0303 
0304 static struct serio_driver pm_drv = {
0305     .driver     = {
0306         .name   = "serio-penmount",
0307     },
0308     .description    = DRIVER_DESC,
0309     .id_table   = pm_serio_ids,
0310     .interrupt  = pm_interrupt,
0311     .connect    = pm_connect,
0312     .disconnect = pm_disconnect,
0313 };
0314 
0315 module_serio_driver(pm_drv);