Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

input: PCF50633 input driver

Signed-off-by: Balaji Rao <balajirrao@openmoko.org>
Cc: Andy Green <andy@openmoko.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@openedhand.com>

authored by

Balaji Rao and committed by
Samuel Ortiz
1851b06a f5714dc9

+140
+7
drivers/input/misc/Kconfig
··· 220 220 Say Y here if you want to support the built-in real time clock 221 221 of the HP SDC controller. 222 222 223 + config INPUT_PCF50633_PMU 224 + tristate "PCF50633 PMU events" 225 + depends on MFD_PCF50633 226 + help 227 + Say Y to include support for delivering PMU events via input 228 + layer on NXP PCF50633. 229 + 223 230 endif
+1
drivers/input/misc/Makefile
··· 21 21 obj-$(CONFIG_INPUT_UINPUT) += uinput.o 22 22 obj-$(CONFIG_INPUT_APANEL) += apanel.o 23 23 obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o 24 + obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
+132
drivers/input/misc/pcf50633-input.c
··· 1 + /* NXP PCF50633 Input Driver 2 + * 3 + * (C) 2006-2008 by Openmoko, Inc. 4 + * Author: Balaji Rao <balajirrao@openmoko.org> 5 + * All rights reserved. 6 + * 7 + * Broken down from monstrous PCF50633 driver mainly by 8 + * Harald Welte, Andy Green and Werner Almesberger 9 + * 10 + * This program is free software; you can redistribute it and/or modify it 11 + * under the terms of the GNU General Public License as published by the 12 + * Free Software Foundation; either version 2 of the License, or (at your 13 + * option) any later version. 14 + * 15 + */ 16 + 17 + #include <linux/kernel.h> 18 + #include <linux/module.h> 19 + #include <linux/init.h> 20 + #include <linux/device.h> 21 + #include <linux/platform_device.h> 22 + #include <linux/input.h> 23 + 24 + #include <linux/mfd/pcf50633/core.h> 25 + 26 + #define PCF50633_OOCSTAT_ONKEY 0x01 27 + #define PCF50633_REG_OOCSTAT 0x12 28 + #define PCF50633_REG_OOCMODE 0x10 29 + 30 + struct pcf50633_input { 31 + struct pcf50633 *pcf; 32 + struct input_dev *input_dev; 33 + }; 34 + 35 + static void 36 + pcf50633_input_irq(int irq, void *data) 37 + { 38 + struct pcf50633_input *input; 39 + int onkey_released; 40 + 41 + input = data; 42 + 43 + /* We report only one event depending on the key press status */ 44 + onkey_released = pcf50633_reg_read(input->pcf, PCF50633_REG_OOCSTAT) 45 + & PCF50633_OOCSTAT_ONKEY; 46 + 47 + if (irq == PCF50633_IRQ_ONKEYF && !onkey_released) 48 + input_report_key(input->input_dev, KEY_POWER, 1); 49 + else if (irq == PCF50633_IRQ_ONKEYR && onkey_released) 50 + input_report_key(input->input_dev, KEY_POWER, 0); 51 + 52 + input_sync(input->input_dev); 53 + } 54 + 55 + static int __devinit pcf50633_input_probe(struct platform_device *pdev) 56 + { 57 + struct pcf50633_input *input; 58 + struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data; 59 + struct input_dev *input_dev; 60 + int ret; 61 + 62 + 63 + input = kzalloc(sizeof(*input), GFP_KERNEL); 64 + if (!input) 65 + return -ENOMEM; 66 + 67 + input_dev = input_allocate_device(); 68 + if (!input_dev) { 69 + kfree(input); 70 + return -ENOMEM; 71 + } 72 + 73 + platform_set_drvdata(pdev, input); 74 + input->pcf = pdata->pcf; 75 + input->input_dev = input_dev; 76 + 77 + input_dev->name = "PCF50633 PMU events"; 78 + input_dev->id.bustype = BUS_I2C; 79 + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR); 80 + set_bit(KEY_POWER, input_dev->keybit); 81 + 82 + ret = input_register_device(input_dev); 83 + if (ret) { 84 + input_free_device(input_dev); 85 + kfree(input); 86 + return ret; 87 + } 88 + pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR, 89 + pcf50633_input_irq, input); 90 + pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF, 91 + pcf50633_input_irq, input); 92 + 93 + return 0; 94 + } 95 + 96 + static int __devexit pcf50633_input_remove(struct platform_device *pdev) 97 + { 98 + struct pcf50633_input *input = platform_get_drvdata(pdev); 99 + 100 + pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYR); 101 + pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYF); 102 + 103 + input_unregister_device(input->input_dev); 104 + kfree(input); 105 + 106 + return 0; 107 + } 108 + 109 + static struct platform_driver pcf50633_input_driver = { 110 + .driver = { 111 + .name = "pcf50633-input", 112 + }, 113 + .probe = pcf50633_input_probe, 114 + .remove = __devexit_p(pcf50633_input_remove), 115 + }; 116 + 117 + static int __init pcf50633_input_init(void) 118 + { 119 + return platform_driver_register(&pcf50633_input_driver); 120 + } 121 + module_init(pcf50633_input_init); 122 + 123 + static void __exit pcf50633_input_exit(void) 124 + { 125 + platform_driver_unregister(&pcf50633_input_driver); 126 + } 127 + module_exit(pcf50633_input_exit); 128 + 129 + MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); 130 + MODULE_DESCRIPTION("PCF50633 input driver"); 131 + MODULE_LICENSE("GPL"); 132 + MODULE_ALIAS("platform:pcf50633-input");