您的位置:首页 > 运维架构 > Linux

实例:触摸屏驱动-2.用input子系统报告事件 分类: linux_内核_input模型 2013-07-10 09:39 327人阅读 评论(0) 收藏

2013-07-10 09:39 741 查看
触摸屏驱动-2.用input子系统报告事件 2010-10-24
18:05:15

分类: LINUX

插入生成的ko文件后,会生成文件/dev/event0。

手指在触摸屏压下或抬起时,LED亮或灭,执行命令"read_ts /dev/event0"可在终端打印触摸屏的状态。

驱动代码如下:

#include <linux/module.h>

#include <linux/init.h>

#include <linux/ioport.h>

#include <linux/interrupt.h>

#include <linux/input.h>

#include <asm/io.h>

#include <asm/arch/regs-gpio.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("zhanglong");

struct touchscreen {

unsigned long adccon,

adctsc,

adcdly,

adcdat0,

adcdat1,

adcupdn;

struct clk *ts_clk;

int down;

void (*wait4irq)(struct touchscreen *, int); //set
ts in wait-for-irq mode

int (*isdown)(struct touchscreen *); //check
stylus down or not

struct input_dev dev;

};

unsigned long ts_virt;

struct touchscreen s3c2440_ts;

void s3c2440_ts_wait4irq(struct touchscreen *ts, int down)

{

if (down) {

iowrite32( 0x3 | ( 1 << 4) | ( 1 << 6) | (1 << 7) , ts->adctsc);

} else {

iowrite32( 0x3 | ( 1 << 4) | ( 1 << 6) | (1 << 7) | (1 << 8) , ts->adctsc);

}

}

int s3c2440_ts_isdown(struct touchscreen *ts)

{

int down;

down = ioread32(ts->adcupdn);

iowrite32(0, ts->adcupdn);

return (down & 1);

}

irqreturn_t s3c2440_tstc_handle(int irq, struct touchscreen *ts)

{

if(IRQ_TC == irq)

{

if(ts->isdown(ts))

{ //stylus down

ts->wait4irq(ts, 0);

input_report_abs(&ts->dev, ABS_PRESSURE, 1);

s3c2410_gpio_setpin(S3C2410_GPF4, 0); //LED
on

}

else

{ //stylus up

ts->wait4irq(ts, 1);

input_report_abs(&ts->dev, ABS_PRESSURE, 0);

input_sync(&ts->dev);

s3c2410_gpio_setpin(S3C2410_GPF4, 1); //LED
off

}

}

return IRQ_HANDLED;

}

int test_init(void)

{

int ret;

ret = request_mem_region(0x58000000, 0x1000, "s3c2440-ts");

if(NULL == ret)

{

printk("request_mem_region failed .\n");

ret = -EBUSY;

goto err0;

}

ts_virt = ioremap(0x58000000, 0x1000);

s3c2440_ts.down = 0;

s3c2440_ts.adccon = ts_virt;

s3c2440_ts.adctsc = ts_virt + 0x04;

s3c2440_ts.adcdly = ts_virt + 0x08;

s3c2440_ts.adcdat0 = ts_virt + 0x0c;

s3c2440_ts.adcdat1 = ts_virt + 0x10;

s3c2440_ts.adcupdn = ts_virt + 0x14;

//---

s3c2440_ts.wait4irq = s3c2440_ts_wait4irq;

s3c2440_ts.isdown = s3c2440_ts_isdown;

ret = request_irq(IRQ_TC, s3c2440_tstc_handle, 0, "s3c2440-ts", &s3c2440_ts);

if(0 != ret)

{

printk("request irq[1] failed .\n");

ret = -EBUSY;

goto err1;

}

s3c2440_ts.ts_clk = clk_get(NULL, "adc");

clk_use(s3c2440_ts.ts_clk);

clk_enable(s3c2440_ts.ts_clk);

s3c2440_ts.wait4irq(&s3c2440_ts, 1);

s3c2440_ts.dev.evbit[0] = BIT(EV_ABS) | BIT(EV_SYN);

input_set_abs_params(&s3c2440_ts.dev, ABS_PRESSURE, 0, 1, 0, 0);

input_register_device(&s3c2440_ts.dev);

return 0;

err1:

iounmap(ts_virt);

release_mem_region(0x58000000, 0x1000);

err0:

return ret;

}

void test_exit(void)

{

input_unregister_device(&s3c2440_ts.dev);

free_irq(IRQ_TC, &s3c2440_ts);

clk_disable(s3c2440_ts.ts_clk);

clk_unuse(s3c2440_ts.ts_clk);

clk_put(s3c2440_ts.ts_clk);

iounmap(ts_virt);

release_mem_region(0x58000000, 0x1000);

}

module_init(test_init);

module_exit(test_exit);


应用测试文件read_ts.c代码如下:

#include <stdio.h>

#include <fcntl.h>

#include <unistd.h>

#include <linux/input.h>

int main(int argc, char **argv)

{

int fd;

struct input_event evt;

if (argc < 2) {

printf("Usage: %s <file>\n", argv[0]);

return 0;

}

fd = open(argv[1], O_RDWR);

if (fd < 0) {

perror("open failed.\n");

return 0;

}

while(1) {

read(fd, &evt, sizeof(struct input_event));

switch(evt.type) {

case EV_ABS:

printf("touch screen: ");

if (evt.code == ABS_X) {

printf("X: %d\n", evt.value);

} else if (evt.code == ABS_Y) {

printf("Y: %d\n", evt.value);

} else if (evt.code == ABS_PRESSURE) {

char *s;

s = evt.value == 0 ? "up\n" : "down\n";

printf(s);

}

break;

case EV_SYN:

printf("-------------------------\n");

break;

}

}

close(fd);

return 0;

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐