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

Commit 31581066 authored by Richard Purdie's avatar Richard Purdie Committed by Linus Torvalds
Browse files

[PATCH] Input: Add a new switch event type



The corgi keyboard has need of a switch event type with slightly type to the
input system as recommended by the input maintainer.

Signed-off-by: default avatarRichard Purdie <rpurdie@rpsys.net>
Cc: Vojtech Pavlik <vojtech@suse.cz>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 41b1bce8
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -393,6 +393,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
						case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
						case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
						case EV_FF:  bits = dev->ffbit;  len = FF_MAX;  break;
						case EV_SW:  bits = dev->swbit;  len = SW_MAX;  break;
						default: return -EINVAL;
					}
					len = NBITS(len) * sizeof(long);
@@ -421,6 +422,13 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
					return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
				}

				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) {
					int len;
					len = NBITS(SW_MAX) * sizeof(long);
					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
					return copy_to_user(p, dev->sw, len) ? -EFAULT : len;
				}

				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
					int len;
					if (!dev->name) return -ENOENT;
+11 −0
Original line number Diff line number Diff line
@@ -89,6 +89,15 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in

			break;

		case EV_SW:

			if (code > SW_MAX || !test_bit(code, dev->swbit) || !!test_bit(code, dev->sw) == value)
				return;

			change_bit(code, dev->sw);

			break;

		case EV_ABS:

			if (code > ABS_MAX || !test_bit(code, dev->absbit))
@@ -402,6 +411,7 @@ static void input_call_hotplug(char *verb, struct input_dev *dev)
	SPRINTF_BIT_A2(ledbit, "LED=", LED_MAX, EV_LED);
	SPRINTF_BIT_A2(sndbit, "SND=", SND_MAX, EV_SND);
	SPRINTF_BIT_A2(ffbit,  "FF=",  FF_MAX, EV_FF);
	SPRINTF_BIT_A2(swbit,  "SW=",  SW_MAX, EV_SW);

	envp[i++] = NULL;

@@ -490,6 +500,7 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int
		SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
		SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
		SPRINTF_BIT_B2(ffbit,  "FF=",  FF_MAX, EV_FF);
		SPRINTF_BIT_B2(swbit,  "SW=",  SW_MAX, EV_SW);

		len += sprintf(buf + len, "\n");

+5 −4
Original line number Diff line number Diff line
@@ -249,9 +249,8 @@ static void corgikbd_hinge_timer(unsigned long data)
		if (hinge_count >= HINGE_STABLE_COUNT) {
			spin_lock_irqsave(&corgikbd_data->lock, flags);

			input_report_key(&corgikbd_data->input, corgikbd_data->keycode[125], (sharpsl_hinge_state == 0x00));
			input_report_key(&corgikbd_data->input, corgikbd_data->keycode[126], (sharpsl_hinge_state == 0x08));
			input_report_key(&corgikbd_data->input, corgikbd_data->keycode[127], (sharpsl_hinge_state == 0x0c));
			input_report_switch(&corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
			input_report_switch(&corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
			input_sync(&corgikbd_data->input);

			spin_unlock_irqrestore(&corgikbd_data->lock, flags);
@@ -321,7 +320,7 @@ static int __init corgikbd_probe(struct device *dev)
	corgikbd->input.id.vendor = 0x0001;
	corgikbd->input.id.product = 0x0001;
	corgikbd->input.id.version = 0x0100;
	corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR);
	corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
	corgikbd->input.keycode = corgikbd->keycode;
	corgikbd->input.keycodesize = sizeof(unsigned char);
	corgikbd->input.keycodemax = ARRAY_SIZE(corgikbd_keycode);
@@ -330,6 +329,8 @@ static int __init corgikbd_probe(struct device *dev)
	for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
		set_bit(corgikbd->keycode[i], corgikbd->input.keybit);
	clear_bit(0, corgikbd->input.keybit);
	set_bit(SW_0, corgikbd->input.swbit);
	set_bit(SW_1, corgikbd->input.swbit);

	input_register_device(&corgikbd->input);
	mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL);
+25 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ struct input_absinfo {
#define EVIOCGKEY(len)		_IOC(_IOC_READ, 'E', 0x18, len)		/* get global keystate */
#define EVIOCGLED(len)		_IOC(_IOC_READ, 'E', 0x19, len)		/* get all LEDs */
#define EVIOCGSND(len)		_IOC(_IOC_READ, 'E', 0x1a, len)		/* get all sounds status */
#define EVIOCGSW(len)		_IOC(_IOC_READ, 'E', 0x1b, len)		/* get all switch states */

#define EVIOCGBIT(ev,len)	_IOC(_IOC_READ, 'E', 0x20 + ev, len)	/* get event bits */
#define EVIOCGABS(abs)		_IOR('E', 0x40 + abs, struct input_absinfo)		/* get abs value/limits */
@@ -86,6 +87,7 @@ struct input_absinfo {
#define EV_REL			0x02
#define EV_ABS			0x03
#define EV_MSC			0x04
#define EV_SW			0x05
#define EV_LED			0x11
#define EV_SND			0x12
#define EV_REP			0x14
@@ -550,6 +552,20 @@ struct input_absinfo {
#define ABS_MISC		0x28
#define ABS_MAX			0x3f

/*
 * Switch events
 */

#define SW_0		0x00
#define SW_1		0x01
#define SW_2		0x02
#define SW_3		0x03
#define SW_4		0x04
#define SW_5		0x05
#define SW_6		0x06
#define SW_7		0x07
#define SW_MAX		0x0f

/*
 * Misc events
 */
@@ -824,6 +840,7 @@ struct input_dev {
	unsigned long ledbit[NBITS(LED_MAX)];
	unsigned long sndbit[NBITS(SND_MAX)];
	unsigned long ffbit[NBITS(FF_MAX)];
	unsigned long swbit[NBITS(SW_MAX)];
	int ff_effects_max;

	unsigned int keycodemax;
@@ -844,6 +861,7 @@ struct input_dev {
	unsigned long key[NBITS(KEY_MAX)];
	unsigned long led[NBITS(LED_MAX)];
	unsigned long snd[NBITS(SND_MAX)];
	unsigned long sw[NBITS(SW_MAX)];

	int absmax[ABS_MAX + 1];
	int absmin[ABS_MAX + 1];
@@ -886,6 +904,7 @@ struct input_dev {
#define INPUT_DEVICE_ID_MATCH_LEDBIT	0x200
#define INPUT_DEVICE_ID_MATCH_SNDBIT	0x400
#define INPUT_DEVICE_ID_MATCH_FFBIT	0x800
#define INPUT_DEVICE_ID_MATCH_SWBIT	0x1000

#define INPUT_DEVICE_ID_MATCH_DEVICE\
	(INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)
@@ -906,6 +925,7 @@ struct input_device_id {
	unsigned long ledbit[NBITS(LED_MAX)];
	unsigned long sndbit[NBITS(SND_MAX)];
	unsigned long ffbit[NBITS(FF_MAX)];
	unsigned long swbit[NBITS(SW_MAX)];

	unsigned long driver_info;
};
@@ -998,6 +1018,11 @@ static inline void input_report_ff_status(struct input_dev *dev, unsigned int co
	input_event(dev, EV_FF_STATUS, code, value);
}

static inline void input_report_switch(struct input_dev *dev, unsigned int code, int value)
{
	input_event(dev, EV_SW, code, !!value);
}

static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
{
	dev->regs = regs;