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/irq.h> 26 #include <linux/gpio_keys.h> 27 28 #include <asm/gpio.h> 29 30 static irqreturn_t gpio_keys_isr(int irq, void *dev_id) 31 { 32 int i; 33 struct platform_device *pdev = dev_id; 34 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 35 struct input_dev *input = platform_get_drvdata(pdev); 36 37 for (i = 0; i < pdata->nbuttons; i++) { 38 int gpio = pdata->buttons[i].gpio; 39 if (irq == gpio_to_irq(gpio)) { 40 int state = (gpio_get_value(gpio) ? 1 : 0) ^ (pdata->buttons[i].active_low); 41 42 input_report_key(input, pdata->buttons[i].keycode, state); 43 input_sync(input); 44 } 45 } 46 47 return IRQ_HANDLED; 48 } 49 50 static int __devinit gpio_keys_probe(struct platform_device *pdev) 51 { 52 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 53 struct input_dev *input; 54 int i, error; 55 56 input = input_allocate_device(); 57 if (!input) 58 return -ENOMEM; 59 60 platform_set_drvdata(pdev, input); 61 62 input->evbit[0] = BIT(EV_KEY); 63 64 input->name = pdev->name; 65 input->phys = "gpio-keys/input0"; 66 input->cdev.dev = &pdev->dev; 67 input->private = pdata; 68 69 input->id.bustype = BUS_HOST; 70 input->id.vendor = 0x0001; 71 input->id.product = 0x0001; 72 input->id.version = 0x0100; 73 74 for (i = 0; i < pdata->nbuttons; i++) { 75 int code = pdata->buttons[i].keycode; 76 int irq = gpio_to_irq(pdata->buttons[i].gpio); 77 78 set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); 79 error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM, 80 pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys", 81 pdev); 82 if (error) { 83 printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", 84 irq, error); 85 goto fail; 86 } 87 set_bit(code, input->keybit); 88 } 89 90 error = input_register_device(input); 91 if (error) { 92 printk(KERN_ERR "Unable to register gpio-keys input device\n"); 93 goto fail; 94 } 95 96 return 0; 97 98 fail: 99 for (i = i - 1; i >= 0; i--) 100 free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); 101 102 input_free_device(input); 103 104 return error; 105 } 106 107 static int __devexit gpio_keys_remove(struct platform_device *pdev) 108 { 109 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 110 struct input_dev *input = platform_get_drvdata(pdev); 111 int i; 112 113 for (i = 0; i < pdata->nbuttons; i++) { 114 int irq = gpio_to_irq(pdata->buttons[i].gpio); 115 free_irq(irq, pdev); 116 } 117 118 input_unregister_device(input); 119 120 return 0; 121 } 122 123 struct platform_driver gpio_keys_device_driver = { 124 .probe = gpio_keys_probe, 125 .remove = __devexit_p(gpio_keys_remove), 126 .driver = { 127 .name = "gpio-keys", 128 } 129 }; 130 131 static int __init gpio_keys_init(void) 132 { 133 return platform_driver_register(&gpio_keys_device_driver); 134 } 135 136 static void __exit gpio_keys_exit(void) 137 { 138 platform_driver_unregister(&gpio_keys_device_driver); 139 } 140 141 module_init(gpio_keys_init); 142 module_exit(gpio_keys_exit); 143 144 MODULE_LICENSE("GPL"); 145 MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>"); 146 MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs"); 147