1 /* 2 * Driver for keys on GPIO lines capable of generating interrupts. 3 * 4 * Copyright 2005 Phil Blundell 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11 #include <linux/module.h> 12 #include <linux/version.h> 13 14 #include <linux/init.h> 15 #include <linux/fs.h> 16 #include <linux/interrupt.h> 17 #include <linux/irq.h> 18 #include <linux/sched.h> 19 #include <linux/pm.h> 20 #include <linux/sysctl.h> 21 #include <linux/proc_fs.h> 22 #include <linux/delay.h> 23 #include <linux/platform_device.h> 24 #include <linux/input.h> 25 #include <linux/gpio_keys.h> 26 27 #include <asm/gpio.h> 28 29 static irqreturn_t gpio_keys_isr(int irq, void *dev_id) 30 { 31 int i; 32 struct platform_device *pdev = dev_id; 33 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 34 struct input_dev *input = platform_get_drvdata(pdev); 35 36 for (i = 0; i < pdata->nbuttons; i++) { 37 struct gpio_keys_button *button = &pdata->buttons[i]; 38 int gpio = button->gpio; 39 40 if (irq == gpio_to_irq(gpio)) { 41 unsigned int type = button->type ?: EV_KEY; 42 int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low; 43 44 input_event(input, type, button->code, !!state); 45 input_sync(input); 46 return IRQ_HANDLED; 47 } 48 } 49 50 return IRQ_NONE; 51 } 52 53 static int __devinit gpio_keys_probe(struct platform_device *pdev) 54 { 55 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 56 struct input_dev *input; 57 int i, error; 58 int wakeup = 0; 59 60 input = input_allocate_device(); 61 if (!input) 62 return -ENOMEM; 63 64 platform_set_drvdata(pdev, input); 65 66 input->evbit[0] = BIT_MASK(EV_KEY); 67 68 input->name = pdev->name; 69 input->phys = "gpio-keys/input0"; 70 input->dev.parent = &pdev->dev; 71 72 input->id.bustype = BUS_HOST; 73 input->id.vendor = 0x0001; 74 input->id.product = 0x0001; 75 input->id.version = 0x0100; 76 77 for (i = 0; i < pdata->nbuttons; i++) { 78 struct gpio_keys_button *button = &pdata->buttons[i]; 79 int irq; 80 unsigned int type = button->type ?: EV_KEY; 81 82 error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); 83 if (error < 0) { 84 pr_err("gpio-keys: failed to request GPIO %d," 85 " error %d\n", button->gpio, error); 86 goto fail; 87 } 88 89 error = gpio_direction_input(button->gpio); 90 if (error < 0) { 91 pr_err("gpio-keys: failed to configure input" 92 " direction for GPIO %d, error %d\n", 93 button->gpio, error); 94 gpio_free(button->gpio); 95 goto fail; 96 } 97 98 irq = gpio_to_irq(button->gpio); 99 if (irq < 0) { 100 error = irq; 101 pr_err("gpio-keys: Unable to get irq number" 102 " for GPIO %d, error %d\n", 103 button->gpio, error); 104 gpio_free(button->gpio); 105 goto fail; 106 } 107 108 error = request_irq(irq, gpio_keys_isr, 109 IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING | 110 IRQF_TRIGGER_FALLING, 111 button->desc ? button->desc : "gpio_keys", 112 pdev); 113 if (error) { 114 pr_err("gpio-keys: Unable to claim irq %d; error %d\n", 115 irq, error); 116 gpio_free(button->gpio); 117 goto fail; 118 } 119 120 if (button->wakeup) 121 wakeup = 1; 122 123 input_set_capability(input, type, button->code); 124 } 125 126 error = input_register_device(input); 127 if (error) { 128 pr_err("gpio-keys: Unable to register input device, " 129 "error: %d\n", error); 130 goto fail; 131 } 132 133 device_init_wakeup(&pdev->dev, wakeup); 134 135 return 0; 136 137 fail: 138 while (--i >= 0) { 139 free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); 140 gpio_free(pdata->buttons[i].gpio); 141 } 142 143 platform_set_drvdata(pdev, NULL); 144 input_free_device(input); 145 146 return error; 147 } 148 149 static int __devexit gpio_keys_remove(struct platform_device *pdev) 150 { 151 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 152 struct input_dev *input = platform_get_drvdata(pdev); 153 int i; 154 155 device_init_wakeup(&pdev->dev, 0); 156 157 for (i = 0; i < pdata->nbuttons; i++) { 158 int irq = gpio_to_irq(pdata->buttons[i].gpio); 159 free_irq(irq, pdev); 160 gpio_free(pdata->buttons[i].gpio); 161 } 162 163 input_unregister_device(input); 164 165 return 0; 166 } 167 168 169 #ifdef CONFIG_PM 170 static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state) 171 { 172 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 173 int i; 174 175 if (device_may_wakeup(&pdev->dev)) { 176 for (i = 0; i < pdata->nbuttons; i++) { 177 struct gpio_keys_button *button = &pdata->buttons[i]; 178 if (button->wakeup) { 179 int irq = gpio_to_irq(button->gpio); 180 enable_irq_wake(irq); 181 } 182 } 183 } 184 185 return 0; 186 } 187 188 static int gpio_keys_resume(struct platform_device *pdev) 189 { 190 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 191 int i; 192 193 if (device_may_wakeup(&pdev->dev)) { 194 for (i = 0; i < pdata->nbuttons; i++) { 195 struct gpio_keys_button *button = &pdata->buttons[i]; 196 if (button->wakeup) { 197 int irq = gpio_to_irq(button->gpio); 198 disable_irq_wake(irq); 199 } 200 } 201 } 202 203 return 0; 204 } 205 #else 206 #define gpio_keys_suspend NULL 207 #define gpio_keys_resume NULL 208 #endif 209 210 struct platform_driver gpio_keys_device_driver = { 211 .probe = gpio_keys_probe, 212 .remove = __devexit_p(gpio_keys_remove), 213 .suspend = gpio_keys_suspend, 214 .resume = gpio_keys_resume, 215 .driver = { 216 .name = "gpio-keys", 217 .owner = THIS_MODULE, 218 } 219 }; 220 221 static int __init gpio_keys_init(void) 222 { 223 return platform_driver_register(&gpio_keys_device_driver); 224 } 225 226 static void __exit gpio_keys_exit(void) 227 { 228 platform_driver_unregister(&gpio_keys_device_driver); 229 } 230 231 module_init(gpio_keys_init); 232 module_exit(gpio_keys_exit); 233 234 MODULE_LICENSE("GPL"); 235 MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>"); 236 MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs"); 237 MODULE_ALIAS("platform:gpio-keys"); 238