Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98b013eb authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

Input: penmount - rework handling of different protocols



Instead of having one large switch based on product ID use pointer to
function actually doing protocol decoding.

Tested-by: default avatarJohn Sung <penmount.touch@gmail.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent bd8f6d2e
Loading
Loading
Loading
Loading
+64 −56
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ struct pm {
	unsigned char packetsize;
	unsigned char maxcontacts;
	struct mt_slot slots[PM_MAX_MTSLOT];
	void (*parse_packet)(struct pm *);
};

/*
@@ -100,18 +101,11 @@ static bool pm_checkpacket(unsigned char *packet)
	return packet[5] == (unsigned char)~(total & 0xff);
}

static irqreturn_t pm_interrupt(struct serio *serio,
		unsigned char data, unsigned int flags)
static void pm_parse_9000(struct pm *pm)
{
	struct pm *pm = serio_get_drvdata(serio);
	struct input_dev *dev = pm->dev;

	pm->data[pm->idx] = data;

	switch (pm->dev->id.product) {
	case 0x9000:
		if (pm->data[0] & 0x80) {
			if (pm->packetsize == ++pm->idx) {
	if ((pm->data[0] & 0x80) && pm->packetsize == ++pm->idx) {
		input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]);
		input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]);
		input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
@@ -119,27 +113,29 @@ static irqreturn_t pm_interrupt(struct serio *serio,
		pm->idx = 0;
	}
}
		break;

	case 0x6000:
		if ((pm->data[0] & 0xbf) == 0x30) {
			if (pm->packetsize == ++pm->idx) {
static void pm_parse_6000(struct pm *pm)
{
	struct input_dev *dev = pm->dev;

	if ((pm->data[0] & 0xbf) == 0x30 && pm->packetsize == ++pm->idx) {
		if (pm_checkpacket(pm->data)) {
			input_report_abs(dev, ABS_X,
					pm->data[2] * 256 + pm->data[1]);
			input_report_abs(dev, ABS_Y,
					pm->data[4] * 256 + pm->data[3]);
					input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
			input_report_key(dev, BTN_TOUCH, pm->data[0] & 0x40);
			input_sync(dev);
		}
		pm->idx = 0;
	}
}
		break;

	case 0x3000:
		if ((pm->data[0] & 0xce) == 0x40) {
			if (pm->packetsize == ++pm->idx) {
static void pm_parse_3000(struct pm *pm)
{
	struct input_dev *dev = pm->dev;

	if ((pm->data[0] & 0xce) == 0x40 && pm->packetsize == ++pm->idx) {
		if (pm_checkpacket(pm->data)) {
			int slotnum = pm->data[0] & 0x0f;
			pm->slots[slotnum].active = pm->data[0] & 0x30;
@@ -150,11 +146,12 @@ static irqreturn_t pm_interrupt(struct serio *serio,
		pm->idx = 0;
	}
}
		break;

	case 0x6250:
		if ((pm->data[0] & 0xb0) == 0x30) {
			if (pm->packetsize == ++pm->idx) {
static void pm_parse_6250(struct pm *pm)
{
	struct input_dev *dev = pm->dev;

	if ((pm->data[0] & 0xb0) == 0x30 && pm->packetsize == ++pm->idx) {
		if (pm_checkpacket(pm->data)) {
			int slotnum = pm->data[0] & 0x0f;
			pm->slots[slotnum].active = pm->data[0] & 0x40;
@@ -165,8 +162,15 @@ static irqreturn_t pm_interrupt(struct serio *serio,
		pm->idx = 0;
	}
}
		break;
	}

static irqreturn_t pm_interrupt(struct serio *serio,
		unsigned char data, unsigned int flags)
{
	struct pm *pm = serio_get_drvdata(serio);

	pm->data[pm->idx] = data;

	pm->parse_packet(pm);

	return IRQ_HANDLED;
}
@@ -227,18 +231,21 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
	default:
	case 0:
		pm->packetsize = 5;
		pm->parse_packet = pm_parse_9000;
		input_dev->id.product = 0x9000;
		max_x = max_y = 0x3ff;
		break;

	case 1:
		pm->packetsize = 6;
		pm->parse_packet = pm_parse_6000;
		input_dev->id.product = 0x6000;
		max_x = max_y = 0x3ff;
		break;

	case 2:
		pm->packetsize = 6;
		pm->parse_packet = pm_parse_3000;
		input_dev->id.product = 0x3000;
		max_x = max_y = 0x7ff;
		pm->maxcontacts = PM_3000_MTSLOT;
@@ -246,6 +253,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)

	case 3:
		pm->packetsize = 6;
		pm->parse_packet = pm_parse_6250;
		input_dev->id.product = 0x6250;
		max_x = max_y = 0x3ff;
		pm->maxcontacts = PM_6250_MTSLOT;