📄 gpio_key.c
字号:
/* * Driver for keys on GPIO lines capable of generating interrupts. * * Copyright 2005 Phil Blundell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <linux/module.h>#include <linux/version.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/interrupt.h>#include <linux/irq.h>#include <linux/sched.h>#include <linux/pm.h>#include <linux/sysctl.h>#include <linux/proc_fs.h>#include <linux/delay.h>#include <linux/platform_device.h>#include <linux/input.h>#include <linux/irq.h>#include <linux/gpio_keys.h>#include <asm/gpio.h>#define AT_GPIO_MODULE "AT_GPIO"#define TRACE \ printk("%s: %s(): line %d\n", AT_GPIO_MODULE, __FUNCTION__, __LINE__)/** * input_set_capability - mark device as capable of a certain event * @dev: device that is capable of emitting or accepting event * @type: type of the event (EV_KEY, EV_REL, etc...) * @code: event code * * In addition to setting up corresponding bit in appropriate capability * bitmap the function also adjusts dev->evbit. *//* 记录本设备对于哪些事件感兴趣(对其进行处理)*/void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code){ TRACE; switch (type) { case EV_KEY: __set_bit(code, dev->keybit);//比如按键,应该对哪些键值的按键进行处理(对于其它按键不予理睬) break; case EV_REL: __set_bit(code, dev->relbit); break; case EV_ABS: __set_bit(code, dev->absbit); break; case EV_MSC: __set_bit(code, dev->mscbit); break; case EV_SW: __set_bit(code, dev->swbit); break; case EV_LED: __set_bit(code, dev->ledbit); break; case EV_SND: __set_bit(code, dev->sndbit); break; case EV_FF: __set_bit(code, dev->ffbit); break; default: printk(KERN_ERR "input_set_capability: unknown type %u (code %u)\n", type, code); dump_stack(); return; } __set_bit(type, dev->evbit);//感觉和前面重复了(前面一经配置过一次了)}EXPORT_SYMBOL(input_set_capability);static struct gpio_plat_data{unsigned int flags;};static struct file_operations gpio_key={ .owner = THIS_MODULE,};static struct cdev *gpio_keys;#define gpio_PLATF_16BITONLY 0x0008static struct gpio_plat_data gpio_platdata = { .flags = gpio_PLATF_16BITONLY,};static struct platform_device gpio_device = { .name = "gpio", .id = 0, .num_resources = 0, .resource = NULL, .dev = { .platform_data = &gpio_platdata, }};struct platform_device *pdev;static irqreturn_t gpio_keys_isr(int irq, void *dev_id){ int i; struct platform_device *pdev = dev_id; struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; struct input_dev *input = platform_get_drvdata(pdev); TRACE; for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; int gpio = button->gpio; if (irq == gpio_to_irq(gpio)) { unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low; input_event(input, type, button->code, !!state); input_sync(input); } } TRACE; printk("return IRQ_HANDLED is :%x \n",IRQ_HANDLED); return IRQ_HANDLED;}static int __exit gpio_keys_remove(void){ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; struct input_dev *input = platform_get_drvdata(pdev); int i; TRACE; for (i = 0; i < pdata->nbuttons; i++) { int irq = gpio_to_irq(pdata->buttons[i].gpio); free_irq(irq, pdev); } input_unregister_device(input); return 0;}struct platform_driver gpio_keys_device_driver = {// .probe = gpio_keys_probe, .remove = __devexit_p(gpio_keys_remove), .driver = { .name = "gpio-keys", .owner = THIS_MODULE, }};struct platform_device dev;struct gpio_keys_platform_data data;static int __init gpio_keys_init(void){ struct platform_device *pdev=&dev; struct gpio_keys_platform_data *pdata = pdev->dev.platform_data =&data; TRACE; struct input_dev *input; int i, error; TRACE; platform_device_register(&gpio_device); input = input_allocate_device(); if (!input) return -ENOMEM; TRACE; platform_set_drvdata(pdev, input);// platform_set_drvdata(pdata, input); TRACE;// cdev_init(gpio_keys,&gpio_key); input->evbit[0] = BIT(EV_KEY); TRACE; input->name = pdev->name; input->phys = "gpio-keys/input0";// input->dev.parent = &pdev->dev; input->cdev.parent = &pdev->dev; TRACE; input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; input->id.product = 0x0001; input->id.version = 0x0100; TRACE; pdata->nbuttons =4; TRACE;/* pdata->buttons[0].gpio =AT91_PIN_PA24; pdata->buttons[1].gpio =AT91_PIN_PA25; pdata->buttons[2].gpio =AT91_PIN_PA28; pdata->buttons[3].gpio =AT91_PIN_PA29; TRACE; pdata->buttons[0].code = KEY_A; pdata->buttons[1].code = KEY_B; pdata->buttons[2].code = KEY_C; pdata->buttons[3].code = KEY_D; TRACE; pdata->buttons[0].type = EV_KEY; pdata->buttons[1].type = EV_KEY; pdata->buttons[2].type = EV_KEY; pdata->buttons[3].type = EV_KEY; TRACE;*/ for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; switch (i){ case 0: button->gpio =AT91_PIN_PA24; button->code =KEY_A; TRACE; break; case 1: button->gpio =AT91_PIN_PA25; button->code =KEY_B; TRACE; break; case 2: button->gpio =AT91_PIN_PA28; button->code =KEY_C; TRACE; break;
case 3: button->gpio =AT91_PIN_PA29; button->code =KEY_D; TRACE; break; } int irq = gpio_to_irq(button->gpio); unsigned int type = button->type ?: EV_KEY; set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM, button->desc ? button->desc : "gpio_keys", pdev); if (error) { printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", irq, error); goto fail; } TRACE; input_set_capability(input, type, button->code); } error = input_register_device(input); if (error) { printk(KERN_ERR "Unable to register gpio-keys input device\n"); goto fail; } return 0; fail: for (i = i - 1; i >= 0; i--) free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); input_free_device(input); return error;}#if 0static void __exit gpio_keys_exit(void){ platform_driver_unregister(&gpio_keys_device_driver);}#endifmodule_init(gpio_keys_init);module_exit(gpio_keys_remove);MODULE_LICENSE("GPL");MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>");MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -