现在的位置: 首页 > 综合 > 正文

实例:触摸屏驱动-2.用input子系统报告事件

2018年02月07日 ⁄ 综合 ⁄ 共 4294字 ⁄ 字号 评论关闭

分类: 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) | (<< 7) , ts->adctsc);

    } else {

        iowrite32( 0x3 | ( 1 << 4) | ( 1 << 6) | (<< 7) | (<< 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(!= 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;
}


抱歉!评论已关闭.