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

Commit a3d52136 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input



* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input: (65 commits)
  Input: gpio_keys - add support for switches (EV_SW)
  Input: cobalt_btns - convert to use polldev library
  Input: add skeleton for simple polled devices
  Input: update some documentation
  Input: wistron - fix typo in keymap for Acer TM610
  Input: add input_set_capability() helper
  Input: i8042 - add Fujitsu touchscreen/touchpad PNP IDs
  Input: i8042 - add Panasonic CF-29 to nomux list
  Input: lifebook - split into 2 devices
  Input: lifebook - add signature of Panasonic CF-29
  Input: lifebook - activate 6-byte protocol on select models
  Input: lifebook - work properly on Panasonic CF-18
  Input: cobalt buttons - separate device and driver registration
  Input: ati_remote - make button repeat sensitivity configurable
  Input: pxa27x - do not use deprecated SA_INTERRUPT flag
  Input: ucb1400 - make delays configurable
  Input: misc devices - switch to using input_dev->dev.parent
  Input: joysticks - switch to using input_dev->dev.parent
  Input: touchscreens - switch to using input_dev->dev.parent
  Input: mice - switch to using input_dev->dev.parent
  ...

Fixed up conflicts with core device model removal of "struct subsystem" manually.

Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parents 5b339915 84767d00
Loading
Loading
Loading
Loading
+72 −53
Original line number Diff line number Diff line
$Id: input-programming.txt,v 1.4 2001/05/04 09:47:14 vojtech Exp $

Programming input drivers
~~~~~~~~~~~~~~~~~~~~~~~~~

@@ -20,28 +18,51 @@ pressed or released a BUTTON_IRQ happens. The driver could look like:
#include <asm/irq.h>
#include <asm/io.h>

static struct input_dev *button_dev;

static void button_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
	input_report_key(&button_dev, BTN_1, inb(BUTTON_PORT) & 1);
	input_sync(&button_dev);
	input_report_key(button_dev, BTN_1, inb(BUTTON_PORT) & 1);
	input_sync(button_dev);
}

static int __init button_init(void)
{
	int error;

	if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
                printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
                return -EBUSY;
        }

	button_dev.evbit[0] = BIT(EV_KEY);
	button_dev.keybit[LONG(BTN_0)] = BIT(BTN_0);
	button_dev = input_allocate_device();
	if (!button_dev) {
		printk(KERN_ERR "button.c: Not enough memory\n");
		error = -ENOMEM;
		goto err_free_irq;
	}

	input_register_device(&button_dev);
	button_dev->evbit[0] = BIT(EV_KEY);
	button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);

	error = input_register_device(button_dev);
	if (error) {
		printk(KERN_ERR "button.c: Failed to register device\n");
		goto err_free_dev;
	}

	return 0;

 err_free_dev:
	input_free_device(button_dev);
 err_free_irq:
	free_irq(BUTTON_IRQ, button_interrupt);
	return error;
}

static void __exit button_exit(void)
{
        input_unregister_device(&button_dev);
        input_unregister_device(button_dev);
	free_irq(BUTTON_IRQ, button_interrupt);
}

@@ -58,11 +79,12 @@ In the _init function, which is called either upon module load or when
booting the kernel, it grabs the required resources (it should also check
for the presence of the device).

Then it sets the input bitfields. This way the device driver tells the other
Then it allocates a new input device structure with input_aloocate_device()
and sets up input bitfields. This way the device driver tells the other
parts of the input systems what it is - what events can be generated or
accepted by this input device. Our example device can only generate EV_KEY type
events, and from those only BTN_0 event code. Thus we only set these two
bits. We could have used
accepted by this input device. Our example device can only generate EV_KEY
type events, and from those only BTN_0 event code. Thus we only set these
two bits. We could have used

	set_bit(EV_KEY, button_dev.evbit);
	set_bit(BTN_0, button_dev.keybit);
@@ -76,9 +98,8 @@ Then the example driver registers the input device structure by calling

This adds the button_dev structure to linked lists of the input driver and
calls device handler modules _connect functions to tell them a new input
device has appeared. Because the _connect functions may call kmalloc(,
GFP_KERNEL), which can sleep, input_register_device() must not be called
from an interrupt or with a spinlock held.
device has appeared. input_register_device() may sleep and therefore must
not be called from an interrupt or with a spinlock held.

While in use, the only used function of the driver is

@@ -113,16 +134,10 @@ can use the open and close callback to know when it can stop polling or
release the interrupt and when it must resume polling or grab the interrupt
again. To do that, we would add this to our example driver:

int button_used = 0;

static int button_open(struct input_dev *dev)
{
        if (button_used++)
                return 0;

	if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
                printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
                button_used--;
                return -EBUSY;
        }

@@ -131,20 +146,21 @@ static int button_open(struct input_dev *dev)

static void button_close(struct input_dev *dev)
{
        if (!--button_used)
        free_irq(IRQ_AMIGA_VERTB, button_interrupt);
}

static int __init button_init(void)
{
	...
	button_dev.open = button_open;
	button_dev.close = button_close;
	button_dev->open = button_open;
	button_dev->close = button_close;
	...
}

Note the button_used variable - we have to track how many times the open
function was called to know when exactly our device stops being used.
Note that input core keeps track of number of users for the device and
makes sure that dev->open() is called only when the first user connects
to the device and that dev->close() is called when the very last user
disconnects. Calls to both callbacks are serialized.

The open() callback should return a 0 in case of success or any nonzero value
in case of failure. The close() callback (which is void) must always succeed.
@@ -187,6 +203,10 @@ the ABS_X axis:
	button_dev.absfuzz[ABS_X] = 4;
	button_dev.absflat[ABS_X] = 8;

Or, you can just say:

	input_set_abs_params(button_dev, ABS_X, 0, 255, 4, 8);

This setting would be appropriate for a joystick X axis, with the minimum of
0, maximum of 255 (which the joystick *must* be able to reach, no problem if
it sometimes reports more, but it must be able to always reach the min and
@@ -197,14 +217,7 @@ If you don't need absfuzz and absflat, you can set them to zero, which mean
that the thing is precise and always returns to exactly the center position
(if it has any).

1.4 The void *private field
~~~~~~~~~~~~~~~~~~~~~~~~~~~

This field in the input structure can be used to point to any private data
structures in the input device driver, in case the driver handles more than
one device. You'll need it in the open and close callbacks.

1.5 NBITS(), LONG(), BIT()
1.4 NBITS(), LONG(), BIT()
~~~~~~~~~~~~~~~~~~~~~~~~~~

These three macros from input.h help some bitfield computations:
@@ -213,13 +226,9 @@ These three macros from input.h help some bitfield computations:
	LONG(x)  - returns the index in the array in longs for bit x
	BIT(x)   - returns the index in a long for bit x

1.6 The number, id* and name fields
1.5 The id* and name fields
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The dev->number is assigned by the input system to the input device when it
is registered. It has no use except for identifying the device to the user
in system messages.

The dev->name should be set before registering the input device by the input
device driver. It's a string like 'Generic button device' containing a
user friendly name of the device.
@@ -234,15 +243,25 @@ driver.

The id and name fields can be passed to userland via the evdev interface.

1.7 The keycode, keycodemax, keycodesize fields
1.6 The keycode, keycodemax, keycodesize fields
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

These two fields will be used for any input devices that report their data
as scancodes. If not all scancodes can be known by autodetection, they may
need to be set by userland utilities. The keycode array then is an array
used to map from scancodes to input system keycodes. The keycode max will
contain the size of the array and keycodesize the size of each entry in it
(in bytes).
These three fields should be used by input devices that have dense keymaps.
The keycode is an array used to map from scancodes to input system keycodes.
The keycode max should contain the size of the array and keycodesize the
size of each entry in it (in bytes).

Userspace can query and alter current scancode to keycode mappings using
EVIOCGKEYCODE and EVIOCSKEYCODE ioctls on corresponding evdev interface.
When a device has all 3 aforementioned fields filled in, the driver may
rely on kernel's default implementation of setting and querying keycode
mappings.

1.7 dev->getkeycode() and dev->setkeycode()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
getkeycode() and setkeycode() callbacks allow drivers to override default
keycode/keycodesize/keycodemax mapping mechanism provided by input core
and implement sparse keycode maps.

1.8 Key autorepeat
~~~~~~~~~~~~~~~~~~
@@ -266,7 +285,7 @@ direction - from the system to the input device driver. If your input device
driver can handle these events, it has to set the respective bits in evbit,
*and* also the callback routine:

	button_dev.event = button_event;
	button_dev->event = button_event;

int button_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
{
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
# Makefile for the Cobalt micro systems family specific parts of the kernel
#

obj-y	 := irq.o reset.o setup.o
obj-y	 := irq.o reset.o setup.o buttons.o

obj-$(CONFIG_PCI)		+= pci.o
obj-$(CONFIG_EARLY_PRINTK)	+= console.o
+54 −0
Original line number Diff line number Diff line
/*
 *  Cobalt buttons platform device.
 *
 *  Copyright (C) 2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <linux/platform_device.h>
#include <linux/errno.h>
#include <linux/init.h>

static struct resource cobalt_buttons_resource __initdata = {
	.start	= 0x1d000000,
	.end	= 0x1d000003,
	.flags	= IORESOURCE_MEM,
};

static __init int cobalt_add_buttons(void)
{
	struct platform_device *pd;
	int error;

	pd = platform_device_alloc("Cobalt buttons", -1);
	if (!pd)
		return -ENOMEM;

	error = platform_device_add_resources(pd, &cobalt_buttons_resource, 1);
	if (error)
		goto err_free_device;

	error = platform_device_add(pd);
	if (error)
		goto err_free_device;

	return 0;

 err_free_device:
	platform_device_put(pd);
	return error;
}
device_initcall(cobalt_add_buttons);
+44 −57
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@
#include <linux/input.h>
#include <linux/reboot.h>

static void kbd_disconnect(struct input_handle *handle);
extern void ctrl_alt_del(void);

/*
@@ -159,65 +158,41 @@ static int sysrq_alt_use;
static int sysrq_alt;

/*
 * Translation of scancodes to keycodes. We set them on only the first attached
 * keyboard - for per-keyboard setting, /dev/input/event is more useful.
 * Translation of scancodes to keycodes. We set them on only the first
 * keyboard in the list that accepts the scancode and keycode.
 * Explanation for not choosing the first attached keyboard anymore:
 *  USB keyboards for example have two event devices: one for all "normal"
 *  keys and one for extra function keys (like "volume up", "make coffee",
 *  etc.). So this means that scancodes for the extra function keys won't
 *  be valid for the first event device, but will be for the second.
 */
int getkeycode(unsigned int scancode)
{
	struct list_head *node;
	struct input_dev *dev = NULL;
	struct input_handle *handle;
	int keycode;
	int error = -ENODEV;

	list_for_each(node, &kbd_handler.h_list) {
		struct input_handle *handle = to_handle_h(node);
		if (handle->dev->keycodesize) {
			dev = handle->dev;
			break;
	list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
		error = handle->dev->getkeycode(handle->dev, scancode, &keycode);
		if (!error)
			return keycode;
	}
	}

	if (!dev)
		return -ENODEV;

	if (scancode >= dev->keycodemax)
		return -EINVAL;

	return INPUT_KEYCODE(dev, scancode);
	return error;
}

int setkeycode(unsigned int scancode, unsigned int keycode)
{
	struct list_head *node;
	struct input_dev *dev = NULL;
	unsigned int i, oldkey;
	struct input_handle *handle;
	int error = -ENODEV;

	list_for_each(node, &kbd_handler.h_list) {
		struct input_handle *handle = to_handle_h(node);
		if (handle->dev->keycodesize) {
			dev = handle->dev;
	list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
		error = handle->dev->setkeycode(handle->dev, scancode, keycode);
		if (!error)
			break;
	}
	}

	if (!dev)
		return -ENODEV;

	if (scancode >= dev->keycodemax)
		return -EINVAL;
	if (keycode < 0 || keycode > KEY_MAX)
		return -EINVAL;
	if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
		return -EINVAL;

	oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);

	clear_bit(oldkey, dev->keybit);
	set_bit(keycode, dev->keybit);

	for (i = 0; i < dev->keycodemax; i++)
		if (INPUT_KEYCODE(dev,i) == oldkey)
			set_bit(oldkey, dev->keybit);

	return 0;
	return error;
}

/*
@@ -225,10 +200,9 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
 */
static void kd_nosound(unsigned long ignored)
{
	struct list_head *node;
	struct input_handle *handle;

	list_for_each(node, &kbd_handler.h_list) {
		struct input_handle *handle = to_handle_h(node);
	list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
		if (test_bit(EV_SND, handle->dev->evbit)) {
			if (test_bit(SND_TONE, handle->dev->sndbit))
				input_inject_event(handle, EV_SND, SND_TONE, 0);
@@ -1161,7 +1135,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)

	if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
		if (emulate_raw(vc, keycode, !down << 7))
			if (keycode < BTN_MISC)
			if (keycode < BTN_MISC && printk_ratelimit())
				printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);

#ifdef CONFIG_MAGIC_SYSRQ	       /* Handle the SysRq Hack */
@@ -1285,11 +1259,11 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
 * likes it, it can open it and get events from it. In this (kbd_connect)
 * function, we should decide which VT to bind that keyboard to initially.
 */
static struct input_handle *kbd_connect(struct input_handler *handler,
					struct input_dev *dev,
static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
			const struct input_device_id *id)
{
	struct input_handle *handle;
	int error;
	int i;

	for (i = KEY_RESERVED; i < BTN_MISC; i++)
@@ -1297,24 +1271,37 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
			break;

	if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
		return NULL;
		return -ENODEV;

	handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
	if (!handle)
		return NULL;
		return -ENOMEM;

	handle->dev = dev;
	handle->handler = handler;
	handle->name = "kbd";

	input_open_device(handle);
	error = input_register_handle(handle);
	if (error)
		goto err_free_handle;

	error = input_open_device(handle);
	if (error)
		goto err_unregister_handle;

	return handle;
	return 0;

 err_unregister_handle:
	input_unregister_handle(handle);
 err_free_handle:
	kfree(handle);
	return error;
}

static void kbd_disconnect(struct input_handle *handle)
{
	input_close_device(handle);
	input_unregister_handle(handle);
	kfree(handle);
}

+0 −1
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@ obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
obj-$(CONFIG_INPUT_JOYDEV)	+= joydev.o
obj-$(CONFIG_INPUT_EVDEV)	+= evdev.o
obj-$(CONFIG_INPUT_TSDEV)	+= tsdev.o
obj-$(CONFIG_INPUT_POWER)	+= power.o
obj-$(CONFIG_INPUT_EVBUG)	+= evbug.o

obj-$(CONFIG_INPUT_KEYBOARD)	+= keyboard/
Loading