s3c2410按键驱动完整版
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/* 2410 中断按键驱动
*基于s3c2410的16个按键驱动,采用中断的方式,实现了阻塞和非阻塞,并用定时*器进行了消抖处理消抖,也实现的异步通知,POLL机制,每个源文件我都加了比较*详细的注释。各位刚刚学习ARM/Linux *驱动的同学可以参考。
*/
// button_irq_driver .c 驱动源文件
// button_irq_test.c 应用程序---按键测试(open可实现阻塞和非阻塞)
// button_poll_test.c 应用程序---poll机制按键测试
// button_fasync.c 应用程序---异步通知方式按键测试
/* button_irq_driver .c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static unsigned int buttons_major = 0;
//本地结构体,表示一个按键
struct fsbuttons_cdev{
struct cdev *buttons_cdev; //按键设备结构体
struct class *buttons_class;//所属类
unsigned int key_buttons; //按键管脚电?1 /0
wait_queue_head_t buttons_wq;
struct timer_list button_timer;
};
static struct fsbuttons_cdev *fs_buttons ;
//构建一个结构体,用来描述中断管脚
struct fspin{
int irq;
int pin;
char *name;
int num;
int row_input;
int row_output;
int int_put;
int key_val;
};
static struct fspin fspin_desc[4]={
{IRQ_EINT0, S3C2410_GPF0, "row0", 0,
S3C2410_GPF0_INP, S3C2410_GPF0_OUTP, S3C2410_GPF0_EINT0},
{IRQ_EINT2, S3C2410_GPF2, "row1", 1,
S3C2410_GPF2_INP, S3C2410_GPF2_OUTP, S3C2410_GPF2_EINT2},
{IRQ_EINT11, S3C2410_GPG3, "row2", 2,
S3C2410_GPG3_INP, S3C2410_GPG3_OUTP, S3C2410_GPG3_EINT11}, {IRQ_EINT19, S3C2410_GPG11, "row3", 3,
S3C2410_GPG11_INP, S3C2410_GPG11_OUTP,
S3C2410_GPG11_EINT19},
};
struct pin_col {
int pin;
int col_input;
int col_output;
};
static struct pin_col col_line[4] = {
{S3C2410_GPE11, S3C2410_GPE11_INP, S3C2410_GPE11_OUTP}, {S3C2410_GPG6, S3C2410_GPG6_INP, S3C2410_GPG6_OUTP},
{S3C2410_GPE13, S3C2410_GPE13_INP, S3C2410_GPE13_OUTP}, {S3C2410_GPG2, S3C2410_GPG2_INP, S3C2410_GPG2_OUTP}, };
static int key_comfirm[4][4]={
{10,11,12,16},
{7,8,9,15},
{4,5,6,14},
{1,2,3,13},
};
/*构建异步通知注册函数用到的结构体*/
struct fasync_struct *fsbuttons_fasync;
struct fspin *cur_pin;
static void set_col_output(void)
{
int i;
for(i = 0;i<4;i++){
s3c2410_gpio_cfgpin(col_line[i].pin, col_line[i].col_output);
s3c2410_gpio_setpin(col_line[i].pin,0);
}
}
static void set_col_input(void)
{
int i;
for(i = 0;i<4;i++){
s3c2410_gpio_cfgpin(col_line[i].pin, col_line[i].col_input);
s3c2410_gpio_pullup(col_line[i].pin, 0);//上拉
}
}
//void (*function)(unsigned long);
static irqreturn_t button_timer_fun(unsigned long data)
{
int i;
unsigned int val_sec;
int row;
int col =-1;
if(!cur_pin)
return IRQ_NONE;
val_sec = s3c2410_gpio_getpin(cur_pin->pin);
if(val_sec != cur_pin->key_val)
return IRQ_NONE;
row = cur_pin->num;