diff options
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/Kconfig | 7 | ||||
-rw-r--r-- | drivers/input/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/misc/apanel.c | 81 | ||||
-rw-r--r-- | drivers/input/misc/pcf50633-input.c | 132 | ||||
-rw-r--r-- | drivers/input/mouse/pxa930_trkball.c | 4 | ||||
-rw-r--r-- | drivers/input/touchscreen/da9034-ts.c | 1 |
7 files changed, 171 insertions, 57 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index f6e9f39a527..c3c8b9bc40a 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -65,7 +65,7 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and /* * Scancode to keycode tables. These are just the default setting, and - * are loadable via an userland utility. + * are loadable via a userland utility. */ static const unsigned short atkbd_set2_keycode[512] = { diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 199055db508..67e5553f699 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -220,4 +220,11 @@ config HP_SDC_RTC Say Y here if you want to support the built-in real time clock of the HP SDC controller. +config INPUT_PCF50633_PMU + tristate "PCF50633 PMU events" + depends on MFD_PCF50633 + help + Say Y to include support for delivering PMU events via input + layer on NXP PCF50633. + endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index d7db2aeb8a9..bb62e6efacf 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_APANEL) += apanel.o obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o +obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c index d82f7f727f7..71b82434264 100644 --- a/drivers/input/misc/apanel.c +++ b/drivers/input/misc/apanel.c @@ -57,7 +57,7 @@ static enum apanel_chip device_chip[APANEL_DEV_MAX]; struct apanel { struct input_polled_dev *ipdev; - struct i2c_client client; + struct i2c_client *client; unsigned short keymap[MAX_PANEL_KEYS]; u16 nkeys; u16 led_bits; @@ -66,16 +66,7 @@ struct apanel { }; -static int apanel_probe(struct i2c_adapter *, int, int); - -/* for now, we only support one address */ -static unsigned short normal_i2c[] = {0, I2C_CLIENT_END}; -static unsigned short ignore = I2C_CLIENT_END; -static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_i2c, - .probe = &ignore, - .ignore = &ignore, -}; +static int apanel_probe(struct i2c_client *, const struct i2c_device_id *); static void report_key(struct input_dev *input, unsigned keycode) { @@ -103,12 +94,12 @@ static void apanel_poll(struct input_polled_dev *ipdev) s32 data; int i; - data = i2c_smbus_read_word_data(&ap->client, cmd); + data = i2c_smbus_read_word_data(ap->client, cmd); if (data < 0) return; /* ignore errors (due to ACPI??) */ /* write back to clear latch */ - i2c_smbus_write_word_data(&ap->client, cmd, 0); + i2c_smbus_write_word_data(ap->client, cmd, 0); if (!data) return; @@ -124,7 +115,7 @@ static void led_update(struct work_struct *work) { struct apanel *ap = container_of(work, struct apanel, led_work); - i2c_smbus_write_word_data(&ap->client, 0x10, ap->led_bits); + i2c_smbus_write_word_data(ap->client, 0x10, ap->led_bits); } static void mail_led_set(struct led_classdev *led, @@ -140,7 +131,7 @@ static void mail_led_set(struct led_classdev *led, schedule_work(&ap->led_work); } -static int apanel_detach_client(struct i2c_client *client) +static int apanel_remove(struct i2c_client *client) { struct apanel *ap = i2c_get_clientdata(client); @@ -148,43 +139,33 @@ static int apanel_detach_client(struct i2c_client *client) led_classdev_unregister(&ap->mail_led); input_unregister_polled_device(ap->ipdev); - i2c_detach_client(&ap->client); input_free_polled_device(ap->ipdev); return 0; } -/* Function is invoked for every i2c adapter. */ -static int apanel_attach_adapter(struct i2c_adapter *adap) -{ - dev_dbg(&adap->dev, APANEL ": attach adapter id=%d\n", adap->id); - - /* Our device is connected only to i801 on laptop */ - if (adap->id != I2C_HW_SMBUS_I801) - return -ENODEV; - - return i2c_probe(adap, &addr_data, apanel_probe); -} - static void apanel_shutdown(struct i2c_client *client) { - apanel_detach_client(client); + apanel_remove(client); } +static struct i2c_device_id apanel_id[] = { + { "fujitsu_apanel", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, apanel_id); + static struct i2c_driver apanel_driver = { .driver = { .name = APANEL, }, - .attach_adapter = &apanel_attach_adapter, - .detach_client = &apanel_detach_client, + .probe = &apanel_probe, + .remove = &apanel_remove, .shutdown = &apanel_shutdown, + .id_table = apanel_id, }; static struct apanel apanel = { - .client = { - .driver = &apanel_driver, - .name = APANEL, - }, .keymap = { [0] = KEY_MAIL, [1] = KEY_WWW, @@ -204,7 +185,8 @@ static struct apanel apanel = { }; /* NB: Only one panel on the i2c. */ -static int apanel_probe(struct i2c_adapter *bus, int address, int kind) +static int apanel_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct apanel *ap; struct input_polled_dev *ipdev; @@ -212,9 +194,6 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind) u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8; int i, err = -ENOMEM; - dev_dbg(&bus->dev, APANEL ": probe adapter %p addr %d kind %d\n", - bus, address, kind); - ap = &apanel; ipdev = input_allocate_polled_device(); @@ -222,18 +201,13 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind) goto out1; ap->ipdev = ipdev; - ap->client.adapter = bus; - ap->client.addr = address; - - i2c_set_clientdata(&ap->client, ap); + ap->client = client; - err = i2c_attach_client(&ap->client); - if (err) - goto out2; + i2c_set_clientdata(client, ap); - err = i2c_smbus_write_word_data(&ap->client, cmd, 0); + err = i2c_smbus_write_word_data(client, cmd, 0); if (err) { - dev_warn(&ap->client.dev, APANEL ": smbus write error %d\n", + dev_warn(&client->dev, APANEL ": smbus write error %d\n", err); goto out3; } @@ -246,7 +220,7 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind) idev->name = APANEL_NAME " buttons"; idev->phys = "apanel/input0"; idev->id.bustype = BUS_HOST; - idev->dev.parent = &ap->client.dev; + idev->dev.parent = &client->dev; set_bit(EV_KEY, idev->evbit); @@ -264,7 +238,7 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind) INIT_WORK(&ap->led_work, led_update); if (device_chip[APANEL_DEV_LED] != CHIP_NONE) { - err = led_classdev_register(&ap->client.dev, &ap->mail_led); + err = led_classdev_register(&client->dev, &ap->mail_led); if (err) goto out4; } @@ -273,8 +247,6 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind) out4: input_unregister_polled_device(ipdev); out3: - i2c_detach_client(&ap->client); -out2: input_free_polled_device(ipdev); out1: return err; @@ -301,6 +273,7 @@ static int __init apanel_init(void) void __iomem *bios; const void __iomem *p; u8 devno; + unsigned char i2c_addr; int found = 0; bios = ioremap(0xF0000, 0x10000); /* Can't fail */ @@ -313,7 +286,7 @@ static int __init apanel_init(void) /* just use the first address */ p += 8; - normal_i2c[0] = readb(p+3) >> 1; + i2c_addr = readb(p + 3) >> 1; for ( ; (devno = readb(p)) & 0x7f; p += 4) { unsigned char method, slave, chip; @@ -322,7 +295,7 @@ static int __init apanel_init(void) chip = readb(p + 2); slave = readb(p + 3) >> 1; - if (slave != normal_i2c[0]) { + if (slave != i2c_addr) { pr_notice(APANEL ": only one SMBus slave " "address supported, skiping device...\n"); continue; diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c new file mode 100644 index 00000000000..039dcb00ebd --- /dev/null +++ b/drivers/input/misc/pcf50633-input.c @@ -0,0 +1,132 @@ +/* NXP PCF50633 Input Driver + * + * (C) 2006-2008 by Openmoko, Inc. + * Author: Balaji Rao <balajirrao@openmoko.org> + * All rights reserved. + * + * Broken down from monstrous PCF50633 driver mainly by + * Harald Welte, Andy Green and Werner Almesberger + * + * 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. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/input.h> + +#include <linux/mfd/pcf50633/core.h> + +#define PCF50633_OOCSTAT_ONKEY 0x01 +#define PCF50633_REG_OOCSTAT 0x12 +#define PCF50633_REG_OOCMODE 0x10 + +struct pcf50633_input { + struct pcf50633 *pcf; + struct input_dev *input_dev; +}; + +static void +pcf50633_input_irq(int irq, void *data) +{ + struct pcf50633_input *input; + int onkey_released; + + input = data; + + /* We report only one event depending on the key press status */ + onkey_released = pcf50633_reg_read(input->pcf, PCF50633_REG_OOCSTAT) + & PCF50633_OOCSTAT_ONKEY; + + if (irq == PCF50633_IRQ_ONKEYF && !onkey_released) + input_report_key(input->input_dev, KEY_POWER, 1); + else if (irq == PCF50633_IRQ_ONKEYR && onkey_released) + input_report_key(input->input_dev, KEY_POWER, 0); + + input_sync(input->input_dev); +} + +static int __devinit pcf50633_input_probe(struct platform_device *pdev) +{ + struct pcf50633_input *input; + struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data; + struct input_dev *input_dev; + int ret; + + + input = kzalloc(sizeof(*input), GFP_KERNEL); + if (!input) + return -ENOMEM; + + input_dev = input_allocate_device(); + if (!input_dev) { + kfree(input); + return -ENOMEM; + } + + platform_set_drvdata(pdev, input); + input->pcf = pdata->pcf; + input->input_dev = input_dev; + + input_dev->name = "PCF50633 PMU events"; + input_dev->id.bustype = BUS_I2C; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR); + set_bit(KEY_POWER, input_dev->keybit); + + ret = input_register_device(input_dev); + if (ret) { + input_free_device(input_dev); + kfree(input); + return ret; + } + pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR, + pcf50633_input_irq, input); + pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF, + pcf50633_input_irq, input); + + return 0; +} + +static int __devexit pcf50633_input_remove(struct platform_device *pdev) +{ + struct pcf50633_input *input = platform_get_drvdata(pdev); + + pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYR); + pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYF); + + input_unregister_device(input->input_dev); + kfree(input); + + return 0; +} + +static struct platform_driver pcf50633_input_driver = { + .driver = { + .name = "pcf50633-input", + }, + .probe = pcf50633_input_probe, + .remove = __devexit_p(pcf50633_input_remove), +}; + +static int __init pcf50633_input_init(void) +{ + return platform_driver_register(&pcf50633_input_driver); +} +module_init(pcf50633_input_init); + +static void __exit pcf50633_input_exit(void) +{ + platform_driver_unregister(&pcf50633_input_driver); +} +module_exit(pcf50633_input_exit); + +MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); +MODULE_DESCRIPTION("PCF50633 input driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pcf50633-input"); diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index a0f45c4fc19..d297accf9a7 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c @@ -186,7 +186,7 @@ static int __devinit pxa930_trkball_probe(struct platform_device *pdev) error = request_irq(irq, pxa930_trkball_interrupt, IRQF_DISABLED, pdev->name, trkball); if (error) { - dev_err(&pdev->dev, "failed to request irq: %d\n", ret); + dev_err(&pdev->dev, "failed to request irq: %d\n", error); goto failed_free_io; } @@ -227,7 +227,7 @@ failed_free_io: iounmap(trkball->mmio_base); failed: kfree(trkball); - return ret; + return error; } static int __devexit pxa930_trkball_remove(struct platform_device *pdev) diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c index 4342e77814b..fa67d782c3c 100644 --- a/drivers/input/touchscreen/da9034-ts.c +++ b/drivers/input/touchscreen/da9034-ts.c @@ -16,6 +16,7 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/input.h> +#include <linux/workqueue.h> #include <linux/mfd/da903x.h> #define DA9034_MANUAL_CTRL 0x50 |