ilitek i2c接口touchscreen驱动

本文介绍ilitek触摸屏的I2C接口驱动,关注数据结构i2c_data及其在内核中的应用,同时涉及中断服务程序ilitek_i2c_isr()的详解。
摘要由CSDN通过智能技术生成

一. data structure.

1. i2c_data 数据结构, 这是代表ilitek触摸屏在kernel里的工作状况的一个数据结构。
里面的各项数据在后面都有各自的用处。

// declare i2c data member

struct i2c_data {

    // input device

        struct input_dev *input_dev;    //输入设备

        // i2c client

        struct i2c_client *client;

        // polling thread

        struct task_struct *thread;     

        // maximum x

        int max_x;

        // maximum y

        int max_y;

    // maximum touch point

    int max_tp;

    // maximum key button

    int max_btn;

        // the total number of x channel

        int x_ch;

        // the total number of y channel

        int y_ch;

        // check whether i2c driver is registered success

        int valid_i2c_register;

        // check whether input driver is registered success

        int valid_input_register;

    // check whether the i2c enter suspend or not

    int stop_polling;

    // read semaphore

    struct semaphore wr_sem;

    // protocol version

    int protocol_ver;

    // valid irq request

    int valid_irq_request;

    // work queue for interrupt use only

    struct workqueue_struct *irq_work_queue;

    // work struct for work queue

    struct work_struct irq_work;



    struct timer_list timer;



    struct completion complete;

#ifdef CONFIG_HAS_EARLYSUSPEND

    struct early_suspend early_suspend;

#endif

};


 

  1. 2. dev_data.
    // device data
    
    struct dev_data {
    
            // device number
    
            dev_t devno;
    
            // character device
    
            struct cdev cdev;
    
            // class device
    
            struct class *class;
    
    };
    


  1. 3.  global variables. 声明上述2数据结构的全局变量:
    // global variables
    
    static struct i2c_data i2c;
    
    static struct dev_data dev;
    
    static char DBG_FLAG;
    
    static char Report_Flag;
    
    
    

  1. 二、设备驱动:

    1. init/exit
    /* set init and exit function for this module */
    
    module_init(ilitek_init);
    
    module_exit(ilitek_exit);
    ilitek_init:
    
    
    /*
    
    description
    
        initiali function for driver to invoke.
    
    parameters
    
    
    
        nothing
    
    return
    
        status
    
    */
    
    static int
    
    ilitek_init(
    
        void)
    
    {
    
        int ret = 0;
    
    
    
        printk(ILITEK_DEBUG_LEVEL "%s\n", __func__);
    
    
    
        // initialize global variable
    
            memset(&dev, 0, sizeof(struct dev_data));  //dev 变量 置为0
    
            memset(&i2c, 0, sizeof(struct i2c_data));  //i2c 变量 置为0
    
    
    
        // initialize mutex object
    
    #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)     //判断linux版本
    
        init_MUTEX(&i2c.wr_sem);             //初始化 信号量
    
    #else
    
        sema_init(&i2c.wr_sem,1);            //新版初始化信号量方式
    
    #endif
    
    
    
        i2c.wr_sem.count = 1;                //使用的信号量个数
    
    
    
        // register i2c device
    
        ret = ilitek_i2c_register_device();   //注册I2C设备
    
        if(ret < 0){
    
            printk(ILITEK_ERROR_LEVEL "%s, register i2c device, error\n", __func__);
    
            return ret;
    
        }
    
    
    
        // allocate character device driver buffer
    
        ret = alloc_chrdev_region(&dev.devno, 0, 1, ILITEK_FILE_DRIVER_NAME);  //分配字符设备驱动空间
    
            if(ret){
    
                printk(ILITEK_ERROR_LEVEL "%s, can't allocate chrdev\n", __func__);
    
            return ret;
    
        }
    
            printk(ILITEK_DEBUG_LEVEL "%s, register chrdev(%d, %d)\n", __func__, MAJOR(dev.devno), MINOR(dev.devno));
    
    
    
        // initialize character device driver
    
        cdev_init(&dev.cdev, &ilitek_fops);     //初始化字符设备驱动
    
        dev.cdev.owner = THIS_MODULE;
    
            ret = cdev_add(&dev.cdev, dev.devno, 1);   //添加字符设备
    
            if(ret < 0){
    
                printk(ILITEK_ERROR_LEVEL "%s, add character device error, ret %d\n", __func__, ret);
    
            return ret;
    
        }
    
        dev.class = class_create(THIS_MODULE, ILITEK_FILE_DRIVER_NAME);   //建立class 类。
    
        if(IS_ERR(dev.class)){
    
                printk(ILITEK_ERROR_LEVEL "%s, create class, error\n", __func__);
    
            return ret;
    
            }
    
        device_create(dev.class, NULL, dev.devno, NULL, "ilitek_ctrl");   //建立设备
    
        Report_Flag=0;
    
        return 0;
    
    }


  1. ilitek_exit
    /*
    
        description
    
            driver exit function
    
        parameters
    
            none
    
        return
    
            nothing
    
        */
    
        static void
    
        ilitek_exit(
    
            void)
    
        {
    
        #ifdef CONFIG_HAS_EARLYSUSPEND //判断系统是否支持early suspend 模式
    
            unregister_early_suspend(&i2c.early_suspend); //如果支持,则注销early suspend.
    
        #endif
    
            // delete i2c driver
    
            if(i2c.client->irq != 0){
    
                    if(i2c.valid_irq_request != 0){
    
                            free_irq(i2c.client->irq, &i2c); //释放中断
    
                            printk(ILITEK_DEBUG_LEVEL "%s, free irq\n", __func__);
    
                            if(i2c.irq_work_queue){
    
                                    destroy_workqueue(i2c.irq_work_queue); //释放工作队列
    
                                    printk(ILITEK_DEBUG_LEVEL "%s, destory work queue\n", __func__);
    
                            }
    
                    }
    
            }
    
            else{
    
                    if(i2c.thread != NULL){
    
                            kthread_stop(i2c.thread); //停止i2c thread。
    
                            printk(ILITEK_DEBUG_LEVEL "%s, stop i2c thread\n", __func__);
    
                    }
    
            }
    
                if(i2c.valid_i2c_register != 0){
    
                        i2c_del_driver(&ilitek_i2c_driver); //删除i2c驱动。
    
                        printk(ILITEK_DEBUG_LEVEL "%s, delete i2c driver\n", __func__);
    
                }
    
                if(i2c.valid_input_register != 0){
    
                        input_unregister_device(i2c.input_dev); //注销设备。
    
                        printk(ILITEK_DEBUG_LEVEL "%s, unregister i2c input device\n", __func__);
    
                }
    
            // delete characte
参考资源链接:[ilitek电容屏驱动程序分析](https://wenku.csdn.net/doc/6q5ocgvzyr?utm_source=wenku_answer2doc_content) 为了深入理解ilitek电容屏驱动在Android平台上使用I2C接口实现中断触发的机制,我强烈建议您查阅《ilitek电容屏驱动程序分析》。这份资料详细解释了驱动程序的内部工作原理,特别是I2C通信协议和中断触发机制。 首先,ilitek电容屏驱动使用I2C接口与触摸屏硬件进行通信。I2C是一种双向串行总线,它允许与多个从设备进行数据交换。在驱动程序中,I2C主控制器负责发送和接收数据,而电容屏作为一个从设备,响应来自主控制器的命令。 当用户进行触摸操作时,电容屏会产生一个中断信号,通过I2C接口传递给处理器。中断信号触发了一个预先设定的中断服务程序(ISR),该程序会唤醒系统处理触控事件。在中断服务程序中,驱动程序会读取I2C总线上的数据包,这些数据包包含了触摸点的位置、压力值等信息。 接着,驱动程序处理这些数据,并将其转换成适用于Android输入子系统的事件。例如,触摸点的位置会被转换成屏幕坐标,然后封装成一个input事件发送给系统的输入子系统。输入子系统再将这些事件传递给相应的应用程序进行处理,比如触控画面的缩放、滚动等。 ilitek驱动程序还支持多点触控,这意味着它可以识别多个触摸点,并为每个触摸点生成独立的事件。为了实现这一点,驱动程序必须能够快速且准确地处理来自电容屏的中断信号,并且能够在多个触摸点之间正确地区分和同步数据。 为了提高效率,中断触发机制通常与轮询机制结合使用。轮询机制允许驱动程序定期检查电容屏的状态,即使在没有触摸活动时也能及时检测到新的触控事件。这种轮询与中断的结合使用,可以确保驱动程序对用户交互的响应既迅速又准确。 通过阅读《ilitek电容屏驱动程序分析》,您将能够更全面地了解这些技术细节,并学习如何在Linux内核下编程分析和调试电容屏驱动程序。这对于开发Android平台上的电容屏驱动程序具有重要的指导意义。 参考资源链接:[ilitek电容屏驱动程序分析](https://wenku.csdn.net/doc/6q5ocgvzyr?utm_source=wenku_answer2doc_content)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值