⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpio_key.c

📁 atmel gpio driver for linux-2.6.20
💻 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 + -