From: Stelian Pop <stelian@popies.net>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Andrew Morton <akpm@osdl.org>, Linus Torvalds <torvalds@osdl.org>
Subject: [PATCH 4/8] sonypi: rework input support
Date: Thu, 28 Oct 2004 12:08:24 +0200 [thread overview]
Message-ID: <20041028100823.GE3893@crusoe.alcove-fr> (raw)
In-Reply-To: <20041028100525.GA3893@crusoe.alcove-fr>
===================================================================
ChangeSet@1.2194, 2004-10-27 17:32:21+02:00, stelian@popies.net
sonypi: rework input support
* feed most of special keys through the input subsystem
* initialize two separate input devices: a mouse like one for
the jogdial and a keyboard like one for the special keys
* add support for SONYPI_EVENT_FNKEY_RELEASED
Many people participated in a way or another to this patch,
including Daniel K. <daniel@cluded.net>, Bastien Nocera <hadess@hadess.net>,
Dmitry Torokhov <dtor@mail.ru> and Vojtech Pavlik <vojtech@suse.cz>.
Signed-off-by: Stelian Pop <stelian@popies.net>
===================================================================
drivers/char/sonypi.c | 169 ++++++++++++++++++++++++++++++++++++++-----------
drivers/char/sonypi.h | 62 +++++++++++++----
include/linux/input.h | 22 ++++++
include/linux/sonypi.h | 1
4 files changed, 205 insertions(+), 49 deletions(-)
===================================================================
diff -Nru a/drivers/char/sonypi.c b/drivers/char/sonypi.c
--- a/drivers/char/sonypi.c 2004-10-28 11:06:42 +02:00
+++ b/drivers/char/sonypi.c 2004-10-28 11:06:42 +02:00
@@ -309,6 +309,27 @@
sonypi_device.bluetooth_power = state;
}
+static void input_keyrelease(void *data)
+{
+ struct input_dev *input_dev;
+ int key;
+
+ while (1) {
+ if (kfifo_get(sonypi_device.input_fifo,
+ (unsigned char *)&input_dev,
+ sizeof(input_dev)) != sizeof(input_dev))
+ return;
+ if (kfifo_get(sonypi_device.input_fifo,
+ (unsigned char *)&key,
+ sizeof(key)) != sizeof(key))
+ return;
+
+ msleep(10);
+ input_report_key(input_dev, key, 0);
+ input_sync(input_dev);
+ }
+}
+
/* Interrupt handler: some event is available */
static irqreturn_t sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) {
u8 v1, v2, event = 0;
@@ -345,22 +366,51 @@
printk(KERN_INFO
"sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
-#ifdef SONYPI_USE_INPUT
if (useinput) {
- struct input_dev *jog_dev = &sonypi_device.jog_dev;
- if (event == SONYPI_EVENT_JOGDIAL_PRESSED)
- input_report_key(jog_dev, BTN_MIDDLE, 1);
- else if (event == SONYPI_EVENT_ANYBUTTON_RELEASED)
- input_report_key(jog_dev, BTN_MIDDLE, 0);
- else if ((event == SONYPI_EVENT_JOGDIAL_UP) ||
- (event == SONYPI_EVENT_JOGDIAL_UP_PRESSED))
- input_report_rel(jog_dev, REL_WHEEL, 1);
- else if ((event == SONYPI_EVENT_JOGDIAL_DOWN) ||
- (event == SONYPI_EVENT_JOGDIAL_DOWN_PRESSED))
- input_report_rel(jog_dev, REL_WHEEL, -1);
- input_sync(jog_dev);
+ struct input_dev *input_jog_dev = &sonypi_device.input_jog_dev;
+ struct input_dev *input_key_dev = &sonypi_device.input_key_dev;
+ switch (event) {
+ case SONYPI_EVENT_JOGDIAL_UP:
+ case SONYPI_EVENT_JOGDIAL_UP_PRESSED:
+ input_report_rel(input_jog_dev, REL_WHEEL, 1);
+ break;
+ case SONYPI_EVENT_JOGDIAL_DOWN:
+ case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED:
+ input_report_rel(input_jog_dev, REL_WHEEL, -1);
+ break;
+ case SONYPI_EVENT_JOGDIAL_PRESSED: {
+ int key = BTN_MIDDLE;
+ input_report_key(input_jog_dev, key, 1);
+ kfifo_put(sonypi_device.input_fifo,
+ (unsigned char *)&input_jog_dev,
+ sizeof(input_jog_dev));
+ kfifo_put(sonypi_device.input_fifo,
+ (unsigned char *)&key, sizeof(key));
+ break;
+ }
+ case SONYPI_EVENT_FNKEY_RELEASED:
+ /* Nothing, not all VAIOs generate this event */
+ break;
+ }
+ input_sync(input_jog_dev);
+
+ for (i = 0; sonypi_inputkeys[i].sonypiev; i++) {
+ int key;
+
+ if (event != sonypi_inputkeys[i].sonypiev)
+ continue;
+
+ key = sonypi_inputkeys[i].inputev;
+ input_report_key(input_key_dev, key, 1);
+ kfifo_put(sonypi_device.input_fifo,
+ (unsigned char *)&input_key_dev,
+ sizeof(input_key_dev));
+ kfifo_put(sonypi_device.input_fifo,
+ (unsigned char *)&key, sizeof(key));
+ }
+ input_sync(input_key_dev);
+ schedule_work(&sonypi_device.input_work);
}
-#endif /* SONYPI_USE_INPUT */
kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
@@ -764,6 +814,62 @@
goto out3;
}
+ if (useinput) {
+ /* Initialize the Input Drivers: jogdial */
+ int i;
+ sonypi_device.input_jog_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] =
+ BIT(BTN_MIDDLE);
+ sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL);
+ sonypi_device.input_jog_dev.name =
+ (char *) kmalloc(sizeof(SONYPI_JOG_INPUTNAME), GFP_KERNEL);
+ if (!sonypi_device.input_jog_dev.name) {
+ printk(KERN_ERR "sonypi: kmalloc failed\n");
+ ret = -ENOMEM;
+ goto out_inkmallocinput1;
+ }
+ sprintf(sonypi_device.input_jog_dev.name, SONYPI_JOG_INPUTNAME);
+ sonypi_device.input_jog_dev.id.bustype = BUS_ISA;
+ sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY;
+
+ input_register_device(&sonypi_device.input_jog_dev);
+ printk(KERN_INFO "%s input method installed.\n",
+ sonypi_device.input_jog_dev.name);
+
+ /* Initialize the Input Drivers: special keys */
+ sonypi_device.input_key_dev.evbit[0] = BIT(EV_KEY);
+ for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
+ if (sonypi_inputkeys[i].inputev)
+ set_bit(sonypi_inputkeys[i].inputev,
+ sonypi_device.input_key_dev.keybit);
+ sonypi_device.input_key_dev.name =
+ (char *) kmalloc(sizeof(SONYPI_KEY_INPUTNAME), GFP_KERNEL);
+ if (!sonypi_device.input_key_dev.name) {
+ printk(KERN_ERR "sonypi: kmalloc failed\n");
+ ret = -ENOMEM;
+ goto out_inkmallocinput2;
+ }
+ sprintf(sonypi_device.input_key_dev.name, SONYPI_KEY_INPUTNAME);
+ sonypi_device.input_key_dev.id.bustype = BUS_ISA;
+ sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY;
+
+ input_register_device(&sonypi_device.input_key_dev);
+ printk(KERN_INFO "%s input method installed.\n",
+ sonypi_device.input_key_dev.name);
+
+ sonypi_device.input_fifo_lock = SPIN_LOCK_UNLOCKED;
+ sonypi_device.input_fifo =
+ kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
+ &sonypi_device.input_fifo_lock);
+ if (IS_ERR(sonypi_device.input_fifo)) {
+ printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
+ ret = PTR_ERR(sonypi_device.input_fifo);
+ goto out_infifo;
+ }
+
+ INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL);
+ }
+
sonypi_device.pdev = platform_device_register_simple("sonypi", -1,
NULL, 0);
if (IS_ERR(sonypi_device.pdev)) {
@@ -795,26 +901,18 @@
printk(KERN_INFO "sonypi: device allocated minor is %d\n",
sonypi_misc_device.minor);
-#ifdef SONYPI_USE_INPUT
- if (useinput) {
- /* Initialize the Input Drivers: */
- sonypi_device.jog_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- sonypi_device.jog_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
- sonypi_device.jog_dev.relbit[0] = BIT(REL_WHEEL);
- sonypi_device.jog_dev.name = (char *) kmalloc(
- sizeof(SONYPI_INPUTNAME), GFP_KERNEL);
- sprintf(sonypi_device.jog_dev.name, SONYPI_INPUTNAME);
- sonypi_device.jog_dev.id.bustype = BUS_ISA;
- sonypi_device.jog_dev.id.vendor = PCI_VENDOR_ID_SONY;
-
- input_register_device(&sonypi_device.jog_dev);
- printk(KERN_INFO "%s installed.\n", sonypi_device.jog_dev.name);
- }
-#endif /* SONYPI_USE_INPUT */
-
return 0;
out_platformdev:
+ kfifo_free(sonypi_device.input_fifo);
+out_infifo:
+ input_unregister_device(&sonypi_device.input_key_dev);
+ kfree(sonypi_device.input_key_dev.name);
+out_inkmallocinput2:
+ input_unregister_device(&sonypi_device.input_jog_dev);
+ kfree(sonypi_device.input_jog_dev.name);
+out_inkmallocinput1:
+ free_irq(sonypi_device.irq, sonypi_irq);
out3:
release_region(sonypi_device.ioport1, sonypi_device.region_size);
out2:
@@ -832,12 +930,13 @@
platform_device_unregister(sonypi_device.pdev);
-#ifdef SONYPI_USE_INPUT
if (useinput) {
- input_unregister_device(&sonypi_device.jog_dev);
- kfree(sonypi_device.jog_dev.name);
+ input_unregister_device(&sonypi_device.input_key_dev);
+ kfree(sonypi_device.input_key_dev.name);
+ input_unregister_device(&sonypi_device.input_jog_dev);
+ kfree(sonypi_device.input_jog_dev.name);
+ kfifo_free(sonypi_device.input_fifo);
}
-#endif /* SONYPI_USE_INPUT */
free_irq(sonypi_device.irq, sonypi_irq);
release_region(sonypi_device.ioport1, sonypi_device.region_size);
diff -Nru a/drivers/char/sonypi.h b/drivers/char/sonypi.h
--- a/drivers/char/sonypi.h 2004-10-28 11:06:42 +02:00
+++ b/drivers/char/sonypi.h 2004-10-28 11:06:42 +02:00
@@ -222,6 +222,7 @@
{ 0x1a, SONYPI_EVENT_FNKEY_F10 },
{ 0x1b, SONYPI_EVENT_FNKEY_F11 },
{ 0x1c, SONYPI_EVENT_FNKEY_F12 },
+ { 0x1f, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x21, SONYPI_EVENT_FNKEY_1 },
{ 0x22, SONYPI_EVENT_FNKEY_2 },
{ 0x31, SONYPI_EVENT_FNKEY_D },
@@ -340,17 +341,48 @@
#define SONYPI_BUF_SIZE 128
-/* We enable input subsystem event forwarding if the input
- * subsystem is compiled in, but only if sonypi is not into the
- * kernel and input as a module... */
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
-#if ! (defined(CONFIG_SONYPI) && defined(CONFIG_INPUT_MODULE))
-#define SONYPI_USE_INPUT
-#endif
-#endif
-
-/* The name of the Jog Dial for the input device drivers */
-#define SONYPI_INPUTNAME "Sony VAIO Jog Dial"
+/* The name of the devices for the input device drivers */
+#define SONYPI_JOG_INPUTNAME "Sony Vaio Jogdial"
+#define SONYPI_KEY_INPUTNAME "Sony Vaio Keys"
+
+/* Correspondance table between sonypi events and input layer events */
+struct {
+ int sonypiev;
+ int inputev;
+} sonypi_inputkeys[] = {
+ { SONYPI_EVENT_CAPTURE_PRESSED, KEY_CAMERA },
+ { SONYPI_EVENT_FNKEY_ONLY, KEY_FN },
+ { SONYPI_EVENT_FNKEY_ESC, KEY_FN_ESC },
+ { SONYPI_EVENT_FNKEY_F1, KEY_FN_F1 },
+ { SONYPI_EVENT_FNKEY_F2, KEY_FN_F2 },
+ { SONYPI_EVENT_FNKEY_F3, KEY_FN_F3 },
+ { SONYPI_EVENT_FNKEY_F4, KEY_FN_F4 },
+ { SONYPI_EVENT_FNKEY_F5, KEY_FN_F5 },
+ { SONYPI_EVENT_FNKEY_F6, KEY_FN_F6 },
+ { SONYPI_EVENT_FNKEY_F7, KEY_FN_F7 },
+ { SONYPI_EVENT_FNKEY_F8, KEY_FN_F8 },
+ { SONYPI_EVENT_FNKEY_F9, KEY_FN_F9 },
+ { SONYPI_EVENT_FNKEY_F10, KEY_FN_F10 },
+ { SONYPI_EVENT_FNKEY_F11, KEY_FN_F11 },
+ { SONYPI_EVENT_FNKEY_F12, KEY_FN_F12 },
+ { SONYPI_EVENT_FNKEY_1, KEY_FN_1 },
+ { SONYPI_EVENT_FNKEY_2, KEY_FN_2 },
+ { SONYPI_EVENT_FNKEY_D, KEY_FN_D },
+ { SONYPI_EVENT_FNKEY_E, KEY_FN_E },
+ { SONYPI_EVENT_FNKEY_F, KEY_FN_F },
+ { SONYPI_EVENT_FNKEY_S, KEY_FN_S },
+ { SONYPI_EVENT_FNKEY_B, KEY_FN_B },
+ { SONYPI_EVENT_BLUETOOTH_PRESSED, KEY_BLUE },
+ { SONYPI_EVENT_BLUETOOTH_ON, KEY_BLUE },
+ { SONYPI_EVENT_PKEY_P1, KEY_PROG1 },
+ { SONYPI_EVENT_PKEY_P2, KEY_PROG2 },
+ { SONYPI_EVENT_PKEY_P3, KEY_PROG3 },
+ { SONYPI_EVENT_BACK_PRESSED, KEY_BACK },
+ { SONYPI_EVENT_HELP_PRESSED, KEY_HELP },
+ { SONYPI_EVENT_ZOOM_PRESSED, KEY_ZOOM },
+ { SONYPI_EVENT_THUMBPHRASE_PRESSED, BTN_THUMB },
+ { 0, 0 },
+};
struct sonypi_device {
struct pci_dev *dev;
@@ -370,9 +402,11 @@
struct fasync_struct *fifo_async;
int open_count;
int model;
-#ifdef SONYPI_USE_INPUT
- struct input_dev jog_dev;
-#endif
+ struct input_dev input_jog_dev;
+ struct input_dev input_key_dev;
+ struct work_struct input_work;
+ struct kfifo *input_fifo;
+ spinlock_t input_fifo_lock;
};
#define ITERATIONS_LONG 10000
diff -Nru a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h 2004-10-28 11:06:42 +02:00
+++ b/include/linux/input.h 2004-10-28 11:06:42 +02:00
@@ -473,6 +473,28 @@
#define KEY_INS_LINE 0x1c2
#define KEY_DEL_LINE 0x1c3
+#define KEY_FN 0x1d0
+#define KEY_FN_ESC 0x1d1
+#define KEY_FN_F1 0x1d2
+#define KEY_FN_F2 0x1d3
+#define KEY_FN_F3 0x1d4
+#define KEY_FN_F4 0x1d5
+#define KEY_FN_F5 0x1d6
+#define KEY_FN_F6 0x1d7
+#define KEY_FN_F7 0x1d8
+#define KEY_FN_F8 0x1d9
+#define KEY_FN_F9 0x1da
+#define KEY_FN_F10 0x1db
+#define KEY_FN_F11 0x1dc
+#define KEY_FN_F12 0x1dd
+#define KEY_FN_1 0x1de
+#define KEY_FN_2 0x1df
+#define KEY_FN_D 0x1e0
+#define KEY_FN_E 0x1e1
+#define KEY_FN_F 0x1e2
+#define KEY_FN_S 0x1e3
+#define KEY_FN_B 0x1e4
+
#define KEY_MAX 0x1ff
/*
diff -Nru a/include/linux/sonypi.h b/include/linux/sonypi.h
--- a/include/linux/sonypi.h 2004-10-28 11:06:42 +02:00
+++ b/include/linux/sonypi.h 2004-10-28 11:06:42 +02:00
@@ -96,6 +96,7 @@
#define SONYPI_EVENT_ANYBUTTON_RELEASED 56
#define SONYPI_EVENT_BATTERY_INSERT 57
#define SONYPI_EVENT_BATTERY_REMOVE 58
+#define SONYPI_EVENT_FNKEY_RELEASED 59
/* get/set brightness */
#define SONYPI_IOCGBRT _IOR('v', 0, __u8)
next prev parent reply other threads:[~2004-10-28 10:17 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-10-28 10:05 [PATCH 0/8] sonypi driver update Stelian Pop
2004-10-28 10:06 ` [PATCH 1/8] sonypi: module related fixes Stelian Pop
2004-10-28 10:07 ` [PATCH 2/8] sonypi: replace homebrew queue with kfifo Stelian Pop
2004-10-28 10:07 ` [PATCH 3/8] sonypi: power management related fixes Stelian Pop
2004-10-28 10:08 ` Stelian Pop [this message]
2004-10-29 10:10 ` [PATCH 4/8] sonypi: rework input support Pavel Machek
2004-10-29 10:41 ` Stelian Pop
2004-10-31 11:30 ` Pavel Machek
2004-10-28 10:08 ` [PATCH 5/8] sonypi: make CONFIG_SONYPI depend on CONFIG_INPUT Stelian Pop
2004-10-28 10:09 ` [PATCH 6/8] sonypi: don't suppose the bluetooth subsystem is initialy off Stelian Pop
2004-10-28 10:09 ` [PATCH 7/8] sonypi: whitespace and coding style fixes Stelian Pop
2004-10-28 10:10 ` [PATCH 8/8] sonypi: bump up the version number Stelian Pop
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20041028100823.GE3893@crusoe.alcove-fr \
--to=stelian@popies.net \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®