^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Penmount serial touchscreen driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2011 John Sung <penmount.touch@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Based on ELO driver (drivers/input/touchscreen/elo.c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 2004 Vojtech Pavlik
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/input/mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/serio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define DRIVER_DESC "PenMount serial touchscreen driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) MODULE_AUTHOR("John Sung <penmount.touch@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Definitions & global arrays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PM_MAX_LENGTH 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define PM_MAX_MTSLOT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PM_3000_MTSLOT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PM_6250_MTSLOT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Multi-touch slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct mt_slot {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned short x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) bool active; /* is the touch valid? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Per-touchscreen data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct pm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct input_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct serio *serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned char data[PM_MAX_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) char phys[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned char packetsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned char maxcontacts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct mt_slot slots[PM_MAX_MTSLOT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) void (*parse_packet)(struct pm *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * pm_mtevent() sends mt events and also emulates pointer movement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void pm_mtevent(struct pm *pm, struct input_dev *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) for (i = 0; i < pm->maxcontacts; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) input_mt_slot(input, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) input_mt_report_slot_state(input, MT_TOOL_FINGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) pm->slots[i].active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (pm->slots[i].active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) input_event(input, EV_ABS, ABS_MT_POSITION_X, pm->slots[i].x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) input_event(input, EV_ABS, ABS_MT_POSITION_Y, pm->slots[i].y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) input_mt_report_pointer_emulation(input, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) input_sync(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * pm_checkpacket() checks if data packet is valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static bool pm_checkpacket(unsigned char *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) for (i = 0; i < 5; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) total += packet[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return packet[5] == (unsigned char)~(total & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void pm_parse_9000(struct pm *pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct input_dev *dev = pm->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if ((pm->data[0] & 0x80) && pm->packetsize == ++pm->idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) pm->idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void pm_parse_6000(struct pm *pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct input_dev *dev = pm->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if ((pm->data[0] & 0xbf) == 0x30 && pm->packetsize == ++pm->idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (pm_checkpacket(pm->data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) input_report_abs(dev, ABS_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) pm->data[2] * 256 + pm->data[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) input_report_abs(dev, ABS_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pm->data[4] * 256 + pm->data[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) input_report_key(dev, BTN_TOUCH, pm->data[0] & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) pm->idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void pm_parse_3000(struct pm *pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct input_dev *dev = pm->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if ((pm->data[0] & 0xce) == 0x40 && pm->packetsize == ++pm->idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (pm_checkpacket(pm->data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int slotnum = pm->data[0] & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) pm->slots[slotnum].active = pm->data[0] & 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) pm_mtevent(pm, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) pm->idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static void pm_parse_6250(struct pm *pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct input_dev *dev = pm->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if ((pm->data[0] & 0xb0) == 0x30 && pm->packetsize == ++pm->idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (pm_checkpacket(pm->data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int slotnum = pm->data[0] & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) pm->slots[slotnum].active = pm->data[0] & 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) pm->slots[slotnum].x = pm->data[2] * 256 + pm->data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) pm->slots[slotnum].y = pm->data[4] * 256 + pm->data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) pm_mtevent(pm, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) pm->idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static irqreturn_t pm_interrupt(struct serio *serio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned char data, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct pm *pm = serio_get_drvdata(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) pm->data[pm->idx] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pm->parse_packet(pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * pm_disconnect() is the opposite of pm_connect()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static void pm_disconnect(struct serio *serio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct pm *pm = serio_get_drvdata(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) serio_close(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) input_unregister_device(pm->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) kfree(pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) serio_set_drvdata(serio, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * pm_connect() is the routine that is called when someone adds a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * new serio device that supports PenMount protocol and registers it as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * an input device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int pm_connect(struct serio *serio, struct serio_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct pm *pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int max_x, max_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) pm = kzalloc(sizeof(struct pm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) input_dev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (!pm || !input_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) pm->serio = serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) pm->dev = input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) pm->maxcontacts = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) input_dev->name = "PenMount Serial TouchScreen";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) input_dev->phys = pm->phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) input_dev->id.bustype = BUS_RS232;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) input_dev->id.vendor = SERIO_PENMOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) input_dev->id.product = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) input_dev->id.version = 0x0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) input_dev->dev.parent = &serio->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) switch (serio->id.id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) pm->packetsize = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pm->parse_packet = pm_parse_9000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) input_dev->id.product = 0x9000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) max_x = max_y = 0x3ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) pm->packetsize = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) pm->parse_packet = pm_parse_6000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) input_dev->id.product = 0x6000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) max_x = max_y = 0x3ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pm->packetsize = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) pm->parse_packet = pm_parse_3000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) input_dev->id.product = 0x3000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) max_x = max_y = 0x7ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) pm->maxcontacts = PM_3000_MTSLOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) pm->packetsize = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) pm->parse_packet = pm_parse_6250;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) input_dev->id.product = 0x6250;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) max_x = max_y = 0x3ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) pm->maxcontacts = PM_6250_MTSLOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) input_set_abs_params(pm->dev, ABS_X, 0, max_x, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) input_set_abs_params(pm->dev, ABS_Y, 0, max_y, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (pm->maxcontacts > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) input_mt_init_slots(pm->dev, pm->maxcontacts, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) input_set_abs_params(pm->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ABS_MT_POSITION_X, 0, max_x, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) input_set_abs_params(pm->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ABS_MT_POSITION_Y, 0, max_y, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) serio_set_drvdata(serio, pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) err = serio_open(serio, drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) err = input_register_device(pm->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto fail3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) fail3: serio_close(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) fail2: serio_set_drvdata(serio, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) fail1: input_free_device(input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) kfree(pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * The serio driver structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static const struct serio_device_id pm_serio_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .type = SERIO_RS232,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .proto = SERIO_PENMOUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .id = SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .extra = SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) MODULE_DEVICE_TABLE(serio, pm_serio_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static struct serio_driver pm_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .name = "serio-penmount",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .description = DRIVER_DESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .id_table = pm_serio_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .interrupt = pm_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .connect = pm_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .disconnect = pm_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) module_serio_driver(pm_drv);