博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
input子系统
阅读量:7049 次
发布时间:2019-06-28

本文共 6686 字,大约阅读时间需要 22 分钟。

s5pc_gpio_dvr:

#include<linux/init.h>

#include<linux/module.h>
#include<asm/io.h>
#include<linux/irqreturn.h>
#include<linux/slab.h>
#include<linux/input.h>
#include<linux/interrupt.h>
#include<linux/platform_device.h>
#include"gpio.h"

/*构建一个本地结构体*/

struct gpio_device{
struct input_dev *s5pc_input;
void __iomem *gpio_base;
};

static struct gpio_device *s5pc_gpio_dev;

static irqreturn_t buttons_irq(int irq,void *dev_id)

{
unsigned long val;
struct button_key *cur_button=(struct button_key *)dev_id;
/*1.判断是按下还是松开*/
val=readl(s5pc_gpio_dev->gpio_base+0x04)&(0x1<<cur_button->pin_bit);//读GPH0DAT寄存器里面的数据
if(val){
//松开,提交松开事件 1-表示按下 0-表示松开
input_event(s5pc_gpio_dev->s5pc_input,cur_button->type,cur_button->code,0);
input_sync(s5pc_gpio_dev->s5pc_input);
}else{
//按下,提交按下事件
input_event(s5pc_gpio_dev->s5pc_input,cur_button->type,cur_button->code,1);
input_sync(s5pc_gpio_dev->s5pc_input);
}
return IRQ_HANDLED;
}

static int gpio_probe(struct platform_device *pdev)

{
int ret;
int i;
struct resource *res;
struct gpio_platdata *pdata;
struct button_key *button;
int type;

s5pc_gpio_dev=kmalloc(sizeof(struct gpio_device), GFP_KERNEL);

if(s5pc_gpio_dev==NULL){
dev_err(&pdev->dev,"no memory for alloc!\n");
return -ENOMEM;
}

/*1.获取平台数据资源*/

pdata =pdev->dev.platform_data;
if(pdata==NULL){
dev_err(&pdev->dev,"no platform data!\n");
ret =-EFAULT;
goto output0;
}

/*获取IO内存地址资源*/

res =platform_get_resource(pdev,IORESOURCE_MEM,0);
s5pc_gpio_dev->gpio_base=ioremap(res->start, res->end-res->start+1);

/*2.构建一个struct input_dev*/

/*3.分配空间*/
s5pc_gpio_dev->s5pc_input=input_allocate_device();
if(!s5pc_gpio_dev->s5pc_input){
dev_err(&pdev->dev,"no memory for alloc!\n");
ret =-ENOMEM;
goto outpout1;
}

for(i=0;i<pdata->num_buttons;i++){

button =&pdata->buttons[i];
if(button==NULL)
continue;

type =button->type?button->type:EV_KEY;

/*4.设置input_dev*/
/*4.1 设置input_dev能产生哪类事件*/
//__set_bit(type,s5pc_gpio_dev->s5pc_input->evbit);
set_bit(type, s5pc_gpio_dev->s5pc_input->evbit);
/*4.2 设置input_dev能产生哪些事件*/
set_bit(button->code,s5pc_gpio_dev->s5pc_input->keybit);

printk("%s():%d----%d\n",__func__,__LINE__,button->irq);

/*4.3 硬件相关的操作*/

/*4.3.1 注册中断*/
ret=request_irq(button->irq, buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,button->name, button);
if(ret){
dev_err(&pdev->dev,"request irq failed %d\n",button->irq);
ret =-EINVAL;
goto outpout2;
}
}
/*5.注册input_dev*/
ret=input_register_device(s5pc_gpio_dev->s5pc_input);
if (ret) {
dev_err(&pdev->dev, "Unable to register input device, error\n");
goto output3;
}

platform_set_drvdata(pdev, pdata); //dev->p->driver_data = pdata;

return 0;

output3:

input_free_device(s5pc_gpio_dev->s5pc_input);
outpout2:
while(i--)
free_irqbutton(->irq, button);
outpout1:
output0:
kfree(s5pc_gpio_dev);
return ret;
}

static int gpio_remove(struct platform_device *pdev)

{
int i;
struct gpio_platdata *pdata =platform_get_drvdata(pdev); //pdata=dev->p->driver_data
input_free_device(s5pc_gpio_dev->s5pc_input);
for(i=0;i<pdata->num_buttons;i++){
free_irq(pdata->buttons[i].irq, &pdata->buttons[i]);
}
input_unregister_device(s5pc_gpio_dev->s5pc_input);
kfree(s5pc_gpio_dev);
return 0;
}

struct platform_driver s5pc_gpio_driver={

.probe =gpio_probe,
.remove =gpio_remove,
.driver ={
.owner =THIS_MODULE,
.name ="s5pc-gpio",
},
};

static int __init s5pc_gpio_drv_init(void)

{
platform_driver_register(&s5pc_gpio_driver);
return 0;
}

static void __exit s5pc_gpio_drv_exit(void)

{
platform_driver_unregister(&s5pc_gpio_driver);
}

module_init(s5pc_gpio_drv_init);

module_exit(s5pc_gpio_drv_exit);
MODULE_LICENSE("GPL");

 

 gpio_dev.c:

#include<linux/init.h>

#include<linux/module.h>
#include<linux/ioport.h>
#include<linux/input.h>
#include<mach/irqs.h>
#include<linux/platform_device.h>
#include"gpio.h"

struct resource s5pc_gpio_resource[]={

[0] ={
.start =S5PC100_PA_BUTTON,
.end =S5PC100_PA_BUTTON +SZ_8 -1,
.flags =IORESOURCE_MEM,
},
};

struct button_key s5pc_buttons[]={

[0]={
.type =EV_KEY,
.code =KEY_1,
.name ="k1",
//.gpio =S5PC100_GPH0(1);
.irq =IRQ_EINT(1),
.pin_bit =1,
},
[1]={
.type =EV_KEY,
.code =KEY_2,
.name ="k2",
//.gpio =S5PC100_GPH0(2);
.irq =IRQ_EINT(2),
.pin_bit=2,
},
[2]={
.type =EV_KEY,
.code =KEY_3,
.name ="k3",
//.gpio =S5PC100_GPH0(3);
.irq =IRQ_EINT(3),
.pin_bit=3,
},
[3]={
.type =EV_KEY,
.code =KEY_4,
.name ="k4",
//.gpio =S5PC100_GPH0(4);
.irq =IRQ_EINT(4),
.pin_bit=4,
},
[4]={
.type =EV_KEY,
.code =KEY_5,
.name ="k5",
//.gpio =S5PC100_GPH0(6);
.irq =IRQ_EINT(6),
.pin_bit=6,
},
[5]={
.type =EV_KEY,
.code =KEY_6,
.name ="k6",
//.gpio =S5PC100_GPH0(7);
.irq =IRQ_EINT(7),
.pin_bit=7,
},
};

struct gpio_platdata s5pc_gpio_cfg ={

.buttons =s5pc_buttons,
.num_buttons =6,
};

static void gpio_release(struct device *dev)

{
}

struct platform_device s5pc_gpio_device={

.name ="s5pc-gpio",
.id =-1,
.num_resources =ARRAY_SIZE(s5pc_gpio_resource),
.resource =s5pc_gpio_resource,
.dev ={
.release =gpio_release,
.platform_data =&s5pc_gpio_cfg,
},
};

static int __init s5pc_gpio_dev_init(void)

{
platform_device_register(&s5pc_gpio_device);
return 0;
}

static void __exit s5pc_gpio_dev_exit(void)

{
platform_device_unregister(&s5pc_gpio_device);
}

module_init(s5pc_gpio_dev_init);

module_exit(s5pc_gpio_dev_exit);
MODULE_LICENSE("GPL");

 

 

test:

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <linux/input.h>

int main(int argc,char **argv)

{
int fd;
struct input_event *input;
fd =open("/dev/event0",O_RDWR);
if(fd<0){
perror("open failed");
exit(1);
}

input=malloc(sizeof(struct input_event));

if(read(fd,input,sizeof(struct input_event))!=sizeof(struct input_event)){

perror("read failed");
exit(1);
}
printf("type =%d\n",input->type);

switch(input->code){

case KEY_1:
if(input->value){
printf("k1 pressed!\n");
}else{
printf("k1 released!\n");
}
break;
case KEY_2:
if(input->value){
printf("k2 pressed!\n");
}else{
printf("k2 released!\n");
}
break;
case KEY_3:
if(input->value){
printf("k3 pressed!\n");
}else{
printf("k3 released!\n");
}
break;
case KEY_4:
if(input->value){
printf("k4 pressed!\n");
}else{
printf("k4 released!\n");
}
break;
case KEY_5:
if(input->value){
printf("k5 pressed!\n");
}else{
printf("k5 released!\n");
}
break;
case KEY_6:
if(input->value){
printf("k6 pressed!\n");
}else{
printf("k6 released!\n");
}
break;
}

close(fd);

return 0;
}

 

 

gpio.h:

#ifndef __ASM_ARM_GPIO_H

#define __ASM_ARM_GPIO_H

#define S5PC100_PA_BUTTON 0xE0300C00

#define SZ_8 0x00000008

/*封装一个按键结构体*/

struct button_key{
int type; //事件类型
int code; //事件码
char *name; //名字
//int gpio; //管脚
int irq;
int pin_bit;
};

/*封装一个平台数据结构体*/

struct gpio_platdata{
struct button_key *buttons;
int num_buttons;
};

#endif

 

转载于:https://www.cnblogs.com/weat/p/3493150.html

你可能感兴趣的文章
VI使用技巧
查看>>
优化LibreOffice如此简单
查看>>
win7 休眠功能的开启与关闭
查看>>
区块链技术正在由金融领域走向传统制造领域
查看>>
线程分离
查看>>
HP-UNIX下Oracle 10g RAC安装失败,清理环境,重新安装
查看>>
使用ORM框架,必须迁就数据库的设计吗?
查看>>
MapReduce的手机流量统计的案例
查看>>
[ACM_几何] Wall
查看>>
一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-基于接口驱动的数据层...
查看>>
通过Map 3D API读取线状要素的节点坐标
查看>>
[Android Traffic] android 流量计算方法
查看>>
Linux查看CPU和内存使用情况【转】
查看>>
linux内核编程笔记【原创】
查看>>
Nifi flow 备份恢复
查看>>
现代软件工程 第三章 【软件工程师的成长】练习与讨论
查看>>
xmlhttprequest 缓存问题
查看>>
交换函数的陷阱——VB2005
查看>>
ORACLE一句话问答(一)
查看>>
C++Directx11开发笔记六:3D空间坐标系变换,绘制3D图形动画
查看>>