From 77686517977e77d101c8a7b397717df00a88922b Mon Sep 17 00:00:00 2001 From: Sundar R Iyer Date: Sun, 5 Sep 2010 12:18:47 -0700 Subject: Input: add support for PowerOn button on the AB8500 MFD Add the PowerOn (PonKey) button support to detect power on/off events. Acked-by: Linus Walleij Signed-off-by: Sundar R Iyer Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 10 +++ drivers/input/misc/Makefile | 1 + drivers/input/misc/ab8500-ponkey.c | 157 +++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 drivers/input/misc/ab8500-ponkey.c (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index b49e23379723..b99b8cbde02f 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -22,6 +22,16 @@ config INPUT_88PM860X_ONKEY To compile this driver as a module, choose M here: the module will be called 88pm860x_onkey. +config INPUT_AB8500_PONKEY + tristate "AB8500 Pon (PowerOn) Key" + depends on AB8500_CORE + help + Say Y here to use the PowerOn Key for ST-Ericsson's AB8500 + Mix-Sig PMIC. + + To compile this driver as a module, choose M here: the module + will be called ab8500-ponkey. + config INPUT_AD714X tristate "Analog Devices AD714x Capacitance Touch Sensor" help diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 19ccca78fa76..1fe1f6c8b737 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -5,6 +5,7 @@ # Each configuration option enables a list of files. obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o +obj-$(CONFIG_INPUT_AB8500_PONKEY) += ab8500-ponkey.o obj-$(CONFIG_INPUT_AD714X) += ad714x.o obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c new file mode 100644 index 000000000000..98f8ede504b8 --- /dev/null +++ b/drivers/input/misc/ab8500-ponkey.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Author: Sundar Iyer for ST-Ericsson + * + * AB8500 Power-On Key handler + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * struct ab8500_ponkey - ab8500 ponkey information + * @input_dev: pointer to input device + * @ab8500: ab8500 parent + * @irq_dbf: irq number for falling transition + * @irq_dbr: irq number for rising transition + */ +struct ab8500_ponkey { + struct input_dev *idev; + struct ab8500 *ab8500; + int irq_dbf; + int irq_dbr; +}; + +/* AB8500 gives us an interrupt when ONKEY is held */ +static irqreturn_t ab8500_ponkey_handler(int irq, void *data) +{ + struct ab8500_ponkey *ponkey = data; + + if (irq == ponkey->irq_dbf) + input_report_key(ponkey->idev, KEY_POWER, true); + else if (irq == ponkey->irq_dbr) + input_report_key(ponkey->idev, KEY_POWER, false); + + input_sync(ponkey->idev); + + return IRQ_HANDLED; +} + +static int __devinit ab8500_ponkey_probe(struct platform_device *pdev) +{ + struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); + struct ab8500_ponkey *ponkey; + struct input_dev *input; + int irq_dbf, irq_dbr; + int error; + + irq_dbf = platform_get_irq_byname(pdev, "ONKEY_DBF"); + if (irq_dbf < 0) { + dev_err(&pdev->dev, "No IRQ for ONKEY_DBF, error=%d\n", irq_dbf); + return irq_dbf; + } + + irq_dbr = platform_get_irq_byname(pdev, "ONKEY_DBR"); + if (irq_dbr < 0) { + dev_err(&pdev->dev, "No IRQ for ONKEY_DBR, error=%d\n", irq_dbr); + return irq_dbr; + } + + ponkey = kzalloc(sizeof(struct ab8500_ponkey), GFP_KERNEL); + input = input_allocate_device(); + if (!ponkey || !input) { + error = -ENOMEM; + goto err_free_mem; + } + + ponkey->idev = input; + ponkey->ab8500 = ab8500; + ponkey->irq_dbf = irq_dbf; + ponkey->irq_dbr = irq_dbr; + + input->name = "AB8500 POn(PowerOn) Key"; + input->dev.parent = &pdev->dev; + + input_set_capability(input, EV_KEY, KEY_POWER); + + error = request_any_context_irq(ponkey->irq_dbf, ab8500_ponkey_handler, + 0, "ab8500-ponkey-dbf", ponkey); + if (error < 0) { + dev_err(ab8500->dev, "Failed to request dbf IRQ#%d: %d\n", + ponkey->irq_dbf, error); + goto err_free_mem; + } + + error = request_any_context_irq(ponkey->irq_dbr, ab8500_ponkey_handler, + 0, "ab8500-ponkey-dbr", ponkey); + if (error < 0) { + dev_err(ab8500->dev, "Failed to request dbr IRQ#%d: %d\n", + ponkey->irq_dbr, error); + goto err_free_dbf_irq; + } + + error = input_register_device(ponkey->idev); + if (error) { + dev_err(ab8500->dev, "Can't register input device: %d\n", error); + goto err_free_dbr_irq; + } + + platform_set_drvdata(pdev, ponkey); + return 0; + +err_free_dbr_irq: + free_irq(ponkey->irq_dbf, ponkey); +err_free_dbf_irq: + free_irq(ponkey->irq_dbf, ponkey); +err_free_mem: + input_free_device(input); + kfree(ponkey); + + return error; +} + +static int __devexit ab8500_ponkey_remove(struct platform_device *pdev) +{ + struct ab8500_ponkey *ponkey = platform_get_drvdata(pdev); + + free_irq(ponkey->irq_dbf, ponkey); + free_irq(ponkey->irq_dbr, ponkey); + input_unregister_device(ponkey->idev); + kfree(ponkey); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver ab8500_ponkey_driver = { + .driver = { + .name = "ab8500-poweron-key", + .owner = THIS_MODULE, + }, + .probe = ab8500_ponkey_probe, + .remove = __devexit_p(ab8500_ponkey_remove), +}; + +static int __init ab8500_ponkey_init(void) +{ + return platform_driver_register(&ab8500_ponkey_driver); +} +module_init(ab8500_ponkey_init); + +static void __exit ab8500_ponkey_exit(void) +{ + platform_driver_unregister(&ab8500_ponkey_driver); +} +module_exit(ab8500_ponkey_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Sundar Iyer "); +MODULE_DESCRIPTION("ST-Ericsson AB8500 Power-ON(Pon) Key driver"); -- cgit v1.2.3 From 1f7930c55e1c1a2b6d5793a1002b31590356558c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 15 Sep 2010 19:36:34 -0700 Subject: Input: ati_remote2 - switch to using new keycode interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch the code to use new style of getkeycode and setkeycode methods to allow retrieving and setting keycodes not only by their scancodes but also by index. Acked-by: Ville Syrjälä Tested-by: Jarod Wilson Tested-by: Ville Syrjälä Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ati_remote2.c | 93 ++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 28 deletions(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 23257652b8e8..0b0e9be63542 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -483,51 +483,88 @@ static void ati_remote2_complete_key(struct urb *urb) } static int ati_remote2_getkeycode(struct input_dev *idev, - unsigned int scancode, unsigned int *keycode) + struct input_keymap_entry *ke) { struct ati_remote2 *ar2 = input_get_drvdata(idev); unsigned int mode; - int index; + int offset; + unsigned int index; + unsigned int scancode; + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + index = ke->index; + if (index >= ATI_REMOTE2_MODES * + ARRAY_SIZE(ati_remote2_key_table)) + return -EINVAL; + + mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); + offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); + scancode = (mode << 8) + ati_remote2_key_table[offset].hw_code; + } else { + if (input_scancode_to_scalar(ke, &scancode)) + return -EINVAL; + + mode = scancode >> 8; + if (mode > ATI_REMOTE2_PC) + return -EINVAL; + + offset = ati_remote2_lookup(scancode & 0xff); + if (offset < 0) + return -EINVAL; + + index = mode * ARRAY_SIZE(ati_remote2_key_table) + offset; + } - mode = scancode >> 8; - if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) - return -EINVAL; + ke->keycode = ar2->keycode[mode][offset]; + ke->len = sizeof(scancode); + memcpy(&ke->scancode, &scancode, sizeof(scancode)); + ke->index = index; - index = ati_remote2_lookup(scancode & 0xFF); - if (index < 0) - return -EINVAL; - - *keycode = ar2->keycode[mode][index]; return 0; } static int ati_remote2_setkeycode(struct input_dev *idev, - unsigned int scancode, unsigned int keycode) + const struct input_keymap_entry *ke, + unsigned int *old_keycode) { struct ati_remote2 *ar2 = input_get_drvdata(idev); - unsigned int mode, old_keycode; - int index; - - mode = scancode >> 8; - if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) - return -EINVAL; - - index = ati_remote2_lookup(scancode & 0xFF); - if (index < 0) - return -EINVAL; + unsigned int mode; + int offset; + unsigned int index; + unsigned int scancode; + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) { + if (ke->index >= ATI_REMOTE2_MODES * + ARRAY_SIZE(ati_remote2_key_table)) + return -EINVAL; + + mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); + offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); + } else { + if (input_scancode_to_scalar(ke, &scancode)) + return -EINVAL; + + mode = scancode >> 8; + if (mode > ATI_REMOTE2_PC) + return -EINVAL; + + offset = ati_remote2_lookup(scancode & 0xff); + if (offset < 0) + return -EINVAL; + } - old_keycode = ar2->keycode[mode][index]; - ar2->keycode[mode][index] = keycode; - __set_bit(keycode, idev->keybit); + *old_keycode = ar2->keycode[mode][offset]; + ar2->keycode[mode][offset] = ke->keycode; + __set_bit(ke->keycode, idev->keybit); for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { - if (ar2->keycode[mode][index] == old_keycode) + if (ar2->keycode[mode][index] == *old_keycode) return 0; } } - __clear_bit(old_keycode, idev->keybit); + __clear_bit(*old_keycode, idev->keybit); return 0; } @@ -575,8 +612,8 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) idev->open = ati_remote2_open; idev->close = ati_remote2_close; - idev->getkeycode = ati_remote2_getkeycode; - idev->setkeycode = ati_remote2_setkeycode; + idev->getkeycode_new = ati_remote2_getkeycode; + idev->setkeycode_new = ati_remote2_setkeycode; idev->name = ar2->name; idev->phys = ar2->phys; -- cgit v1.2.3 From 6792cbbb254712a8c0fa8a4c97c8d521c7c41c28 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Wed, 29 Sep 2010 18:53:35 -0700 Subject: Input: return -ENOMEM in select drivers when memory allocation fails Instead of using -1 let's start using proper error codes. Signed-off-by: Davidlohr Bueso Signed-off-by: Dmitry Torokhov --- drivers/input/misc/powermate.c | 2 +- drivers/input/mouse/elantech.c | 2 +- drivers/input/mouse/synaptics.c | 2 +- drivers/input/mouse/trackpoint.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index bf170f6b4422..f45947190e4f 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c @@ -280,7 +280,7 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev pm->configcr = kmalloc(sizeof(*(pm->configcr)), GFP_KERNEL); if (!pm->configcr) - return -1; + return -ENOMEM; return 0; } diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 48311204ba51..04d9bf320a4f 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -699,7 +699,7 @@ int elantech_init(struct psmouse *psmouse) psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); if (!etd) - return -1; + return -ENOMEM; etd->parity[0] = 1; for (i = 1; i < 256; i++) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 96b70a43515f..a79bc362dde5 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -731,7 +731,7 @@ int synaptics_init(struct psmouse *psmouse) psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); if (!priv) - return -1; + return -ENOMEM; psmouse_reset(psmouse); diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 0643e49ca603..54b2fa892e19 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -303,7 +303,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); if (!psmouse->private) - return -1; + return -ENOMEM; psmouse->vendor = "IBM"; psmouse->name = "TrackPoint"; -- cgit v1.2.3 From c5fb514d2f0496ce58caed63bceb05fac40324b3 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Sun, 24 Oct 2010 21:48:11 -0700 Subject: Input: ab8500-ponkey - fix IRQ freeing in error path Looks like an obvious typo to me. Signed-off-by: Nicolas Kaiser Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ab8500-ponkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index 98f8ede504b8..3d3288a78fdc 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c @@ -107,7 +107,7 @@ static int __devinit ab8500_ponkey_probe(struct platform_device *pdev) return 0; err_free_dbr_irq: - free_irq(ponkey->irq_dbf, ponkey); + free_irq(ponkey->irq_dbr, ponkey); err_free_dbf_irq: free_irq(ponkey->irq_dbf, ponkey); err_free_mem: -- cgit v1.2.3