Driver for keys on GPIO using input-subsystem way
2013-01-15 18:16
323 查看
/**
* Driver for keys on GPIO using input-subsystem way
*/
Driver Test:
----------------------------------------------------------driver---------------------------------------------------------------
#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 DRIVER_NAME "czinputsubsys_keys"
static struct input_dev *czinput_dev;
//tips: why no static?
struct czkey_desc {
unsigned char * name;
int irq;
int pin;
int code;
};
//gpio_to_irq(S3C2410_GPF1) is wrong!
static struct czkey_desc aczkey_desc[4] = {
{"L", IRQ_EINT1, S3C2410_GPF1, KEY_L},
{"S", IRQ_EINT4, S3C2410_GPF4, KEY_S},
{"ENTER", IRQ_EINT2, S3C2410_GPF2, KEY_ENTER},
{"LEFTSHIFT", IRQ_EINT0, S3C2410_GPF0, KEY_LEFTSHIFT},
};
static irqreturn_t czinputsubsys_keys_isr(int irq, void *dev_id)
{
printk("driver:czinputsubsys_keys_isr in\n");
struct czkey_desc *pczkey_desc = (struct czkey_desc *)dev_id;
int state = (gpio_get_value(pczkey_desc->pin) ? 1 : 0);
// input_event(czinput_dev, czinput_dev->evbit[0], pczkey_desc->code, state);
if(state){
input_event(czinput_dev, EV_KEY, pczkey_desc->code, 1);//untest 2013.01.15
printk("driver:czinputsubsys_keys_isr key state:%d\n",state);
}
else
{
input_event(czinput_dev, EV_KEY, pczkey_desc->code, 0);//untest 2013.01.15
printk("driver:czinputsubsys_keys_isr key state:%d\n",state);
}
input_sync(czinput_dev);
return IRQ_HANDLED;
}
static int czinputsubsys_keys_init(void)
{
printk("driver:czinputsubsys_key_init in\n");
int error;
int i ;
czinput_dev = input_allocate_device();
if (!czinput_dev){
printk(KERN_ERR "Cannot request keypad device\n");
return -ENOMEM;}
else
printk("Can request keypad device\n");
//czinput_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
//czinput_dev->keybit[0] = BIT(KEY_L) | BIT(KEY_S) | BIT(KEY_ENTER) | BIT(KEY_LEFTSHIFT);
//czinput_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
set_bit(EV_KEY, czinput_dev->evbit);//untest 2013.01.15
set_bit(KEY_ENTER, czinput_dev->keybit);
set_bit(KEY_L, czinput_dev->keybit);
set_bit(KEY_S, czinput_dev->keybit);
set_bit(KEY_LEFTSHIFT, czinput_dev->keybit);
czinput_dev->name = DRIVER_NAME;
//czinput_dev->phys = "gpio-keys/input0";
//czinput_dev->dev.parent = &pdev->dev;
//czinput_dev->id.bustype = BUS_HOST;
//czinput_dev->id.vendor = 0x0001;
//czinput_dev->id.product = 0x0001;
//czinput_dev->id.version = 0x0100;
error = input_register_device(czinput_dev);
if (error)
printk(KERN_ERR "Unable to register gpio-keys input device\n");
else
printk(KERN_ERR "able to register gpio-keys input device\n");
//for(i=0;i<4;i++)
// set_irq_type(aczkey_desc[i].irq, IRQ_TYPE_EDGE_BOTH);
//tips: about KERN_ERR?; about IRQF_SAMPLE_RANDOM
//tips: about IRQT_BOTHEDGE is the right way
for(i=0;i<4;i++){
error = request_irq(aczkey_desc[i].irq, czinputsubsys_keys_isr, IRQT_BOTHEDGE,
aczkey_desc[i].name,&aczkey_desc[i]);
if (error)
printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n",aczkey_desc[i].irq, error);
else
printk("gpio-keys: able to claim irq %d\n",aczkey_desc[i].irq);
}
return 0;
}
static void czinputsubsys_keys_exit(void)
{
printk("driver:czinputsubsys_key_exit in\n");
int i;
for(i=0;i<4;i++)
free_irq(aczkey_desc[i].irq, &aczkey_desc[i]);
input_unregister_device(czinput_dev);
return;
}
module_init(czinputsubsys_keys_init);
module_exit(czinputsubsys_keys_exit);
MODULE_AUTHOR("chaozang(cz) <zangchao.cn@gmail.com>, copy frm teacher:weidongshan,thanks so much!");
MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
MODULE_LICENSE("GPL");
----------------------------------------------------test commands----------------------------------------------------------
# exec 0</dev/tty1
-------------------------------------------------
Contact:
zangchao.cn@gmail.com
* Driver for keys on GPIO using input-subsystem way
*/
Driver Test:
----------------------------------------------------------driver---------------------------------------------------------------
#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 DRIVER_NAME "czinputsubsys_keys"
static struct input_dev *czinput_dev;
//tips: why no static?
struct czkey_desc {
unsigned char * name;
int irq;
int pin;
int code;
};
//gpio_to_irq(S3C2410_GPF1) is wrong!
static struct czkey_desc aczkey_desc[4] = {
{"L", IRQ_EINT1, S3C2410_GPF1, KEY_L},
{"S", IRQ_EINT4, S3C2410_GPF4, KEY_S},
{"ENTER", IRQ_EINT2, S3C2410_GPF2, KEY_ENTER},
{"LEFTSHIFT", IRQ_EINT0, S3C2410_GPF0, KEY_LEFTSHIFT},
};
static irqreturn_t czinputsubsys_keys_isr(int irq, void *dev_id)
{
printk("driver:czinputsubsys_keys_isr in\n");
struct czkey_desc *pczkey_desc = (struct czkey_desc *)dev_id;
int state = (gpio_get_value(pczkey_desc->pin) ? 1 : 0);
// input_event(czinput_dev, czinput_dev->evbit[0], pczkey_desc->code, state);
if(state){
input_event(czinput_dev, EV_KEY, pczkey_desc->code, 1);//untest 2013.01.15
printk("driver:czinputsubsys_keys_isr key state:%d\n",state);
}
else
{
input_event(czinput_dev, EV_KEY, pczkey_desc->code, 0);//untest 2013.01.15
printk("driver:czinputsubsys_keys_isr key state:%d\n",state);
}
input_sync(czinput_dev);
return IRQ_HANDLED;
}
static int czinputsubsys_keys_init(void)
{
printk("driver:czinputsubsys_key_init in\n");
int error;
int i ;
czinput_dev = input_allocate_device();
if (!czinput_dev){
printk(KERN_ERR "Cannot request keypad device\n");
return -ENOMEM;}
else
printk("Can request keypad device\n");
//czinput_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
//czinput_dev->keybit[0] = BIT(KEY_L) | BIT(KEY_S) | BIT(KEY_ENTER) | BIT(KEY_LEFTSHIFT);
//czinput_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
set_bit(EV_KEY, czinput_dev->evbit);//untest 2013.01.15
set_bit(KEY_ENTER, czinput_dev->keybit);
set_bit(KEY_L, czinput_dev->keybit);
set_bit(KEY_S, czinput_dev->keybit);
set_bit(KEY_LEFTSHIFT, czinput_dev->keybit);
czinput_dev->name = DRIVER_NAME;
//czinput_dev->phys = "gpio-keys/input0";
//czinput_dev->dev.parent = &pdev->dev;
//czinput_dev->id.bustype = BUS_HOST;
//czinput_dev->id.vendor = 0x0001;
//czinput_dev->id.product = 0x0001;
//czinput_dev->id.version = 0x0100;
error = input_register_device(czinput_dev);
if (error)
printk(KERN_ERR "Unable to register gpio-keys input device\n");
else
printk(KERN_ERR "able to register gpio-keys input device\n");
//for(i=0;i<4;i++)
// set_irq_type(aczkey_desc[i].irq, IRQ_TYPE_EDGE_BOTH);
//tips: about KERN_ERR?; about IRQF_SAMPLE_RANDOM
//tips: about IRQT_BOTHEDGE is the right way
for(i=0;i<4;i++){
error = request_irq(aczkey_desc[i].irq, czinputsubsys_keys_isr, IRQT_BOTHEDGE,
aczkey_desc[i].name,&aczkey_desc[i]);
if (error)
printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n",aczkey_desc[i].irq, error);
else
printk("gpio-keys: able to claim irq %d\n",aczkey_desc[i].irq);
}
return 0;
}
static void czinputsubsys_keys_exit(void)
{
printk("driver:czinputsubsys_key_exit in\n");
int i;
for(i=0;i<4;i++)
free_irq(aczkey_desc[i].irq, &aczkey_desc[i]);
input_unregister_device(czinput_dev);
return;
}
module_init(czinputsubsys_keys_init);
module_exit(czinputsubsys_keys_exit);
MODULE_AUTHOR("chaozang(cz) <zangchao.cn@gmail.com>, copy frm teacher:weidongshan,thanks so much!");
MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
MODULE_LICENSE("GPL");
----------------------------------------------------test commands----------------------------------------------------------
# exec 0</dev/tty1
-------------------------------------------------
Contact:
zangchao.cn@gmail.com
相关文章推荐
- Matlab出现On Startup: Error using eval undefined function 'workspacefunc' for input arguments of type
- Data transfer from GPIO port to RAM buffer using DMA upon receiving a trigger signal on the timer capture input channel.
- Matlab出现On Startup: Error using eval undefined function 'workspacefunc' for input arguments of type
- How To: set udev rule for setting the disk permission on ASM disks when using multipath on Linux 6.x
- Unity Application Block Hands-on Lab for Enter-Lib 5.0:Lab 3-Using a Configuration File[Translation]
- critical steps for by setup 12c rac on vmware exsi using dns(no gns)
- TensorFlow for Hackers (Part VI) - Human Activity Recognition using LSTMs on Android
- ASSETWriterInput for making Video from UIImages on Iphone Issues
- Search Engine Optimization for Flash: Best practices for using Flash on the web
- 20.1.3.Loading a JDBC Driver: Using Class.forName()[用Class.forName()]来加载JDBC Driver
- Troubleshooting tips for using Java on Windows 8
- Forefront TMG 2010: Using malware inspection and URL filtering for FTP on access rules
- android.os.NetworkOnMainThreadException,Failed to find provider info for com.android.inputmethod.lat
- Tip for using Fiddler on localhost
- 在大于32GB或64GB容量的SD卡上使用NOOB安装树莓派 - Using NOOB on SD cards larger than 32GB or 64GB for Raspberry Pi
- Unity Application Block Hands-on Lab for Enter-Lib 5.0:Lab 2-Using the Configuration API[Translation]
- Step-By-Step Guide To Create Physical Standby On Normal File System For ASM Primary using RMAN
- Tips and tricks for using WebDriver
- Step-By-Step Guide To Create Physical Standby On Normal File System For ASM Primary using RMAN (文档 I
- I.MX6 gpio-keys driver hacking