ilitek i2c接口touchscreen驱动

本文介绍ilitek触摸屏的I2C接口驱动,关注数据结构i2c_data及其在内核中的应用,同时涉及中断服务程序ilitek_i2c_isr()的详解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 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); //注销设备。
    
               
<think>我们正在讨论将ILitek触摸屏驱动移植到MTK平台。这是一个嵌入式Linux驱动移植任务。以下步骤是通用的移植指南,具体细节可能需要根据硬件和内核版本调整。 ### 1. 获取ILitek触摸屏驱动源码 通常从ILitek供应商处获取驱动源码,可能是独立模块或集成到内核中的补丁形式。确保获得与你的触摸屏型号匹配的驱动版本。 ### 2. 分析MTK平台现有触摸驱动框架 MTK平台通常使用Linux Input子系统。检查: - 设备树(Device Tree)中触摸屏节点定义 - 现有触摸驱动(如`mediatek/kernel/drivers/input/touchscreen/`目录) - 确认MTK平台使用的内核版本(`uname -r`) ### 3. 集成ILitek驱动到内核 假设驱动为独立模块: - 将源码放入`drivers/input/touchscreen/ilitek/` - 修改`drivers/input/touchscreen/Makefile`,添加: ```makefile obj-$(CONFIG_TOUCHSCREEN_ILITEK) += ilitek/ ``` - 修改`drivers/input/touchscreen/Kconfig`,添加配置选项: ```kconfig config TOUCHSCREEN_ILITEK tristate "ILITEK I2C Touchscreen" depends on I2C help Say Y here to enable ILITEK I2C touchscreen support. ``` ### 4. 设备树配置 在设备树中(如`arch/arm64/boot/dts/mediatek/mtXXXX-your-board.dts`)添加I2C节点: ```dts &i2c0 { ilitek@41 { compatible = "ilitek,ili2120"; reg = <0x41>; interrupt-parent = <&pio>; interrupts = <6 IRQ_TYPE_EDGE_FALLING>; // 根据实际GPIO修改 reset-gpios = <&pio 5 0>; // 复位GPIO }; }; ``` 注意:`compatible`字符串必须与驱动中的匹配。 ### 5. 驱动适配关键点 - **中断处理**:确保驱动使用正确的IRQ触发方式(如`IRQF_TRIGGER_FALLING`) - **电源管理**:实现`resume/suspend`回调 - **I2C通信**:检查驱动中的I2C操作函数(如`i2c_transfer`)是否适配MTK的I2C控制器 - **输入子系统注册**:确保正确设置`input_dev`的坐标范围、事件类型(`EV_ABS`等) ### 6. 编译配置 在内核配置中启用驱动: ```bash make menuconfig ``` 路径:`Device Drivers -> Input device support -> Touchscreens -> <*> ILITEK I2C Touchscreen` ### 7. 调试技巧 - 查看I2C设备:`i2cdetect -l` 然后 `i2cdump -f -y 0 0x41`(假设I2C0总线) - 查看输入事件:`evtest /dev/input/eventX` - 内核日志:`dmesg | grep ilitek` §§相关问题§§ 1. 如何解决ILitek驱动与MTK I2C控制器的兼容性问题? 2. 触摸屏校准在驱动中如何实现? 3. 移植后触摸坐标反向或偏移如何调整?</think>### MTK平台 ILitek触摸屏驱动移植指南 #### 一、移植准备阶段 1. **环境确认** - 获取MTK平台SDK(如MT6765/MT6873等) - 确认内核版本:`cat /proc/version` - 准备ILitek驱动包(通常包含`.c`、`.h`文件和`Makefile`) 2. **硬件接口验证** ```c // 检查I2C/SPI接口兼容性(示例) struct i2c_adapter *adapter = i2c_get_adapter(0); if (!adapter) { printk(KERN_ERR "I2C adapter not found"); return -ENODEV; } ``` #### 二、驱动集成步骤 1. **源码整合** - 将ILitek驱动文件放入MTK内核目录: `mediatek/kernel/drivers/input/touchscreen/ilitek/` - 修改Makefile: ```makefile obj-$(CONFIG_TOUCHSCREEN_ILITEK) += ilitek_ts.o ilitek_platform.o ``` 2. **设备树配置** ```dts &i2c1 { ilitek@41 { compatible = "ilitek,ili9881"; reg = <0x41>; interrupt-parent = <&pio>; interrupts = <6 IRQ_TYPE_EDGE_FALLING>; // GPIO6 reset-gpio = <&pio 15 0>; // GPIO15 vdd-supply = <&mt_pmic_vtp_ldo_reg>; }; }; ``` 3. **电源管理适配** ```c static int ili_power_supply_init(struct device *dev) { // MTK PMIC配置 regulator = regulator_get(dev, "vdd"); if (IS_ERR(regulator)) { dev_err(dev, "Failed to get vdd regulator"); return PTR_ERR(regulator); } regulator_set_voltage(regulator, 2800000, 3300000); } ``` #### 三、关键适配点 1. **中断处理** ```c static irqreturn_t ili_irq_handler(int irq, void *dev_id) { struct ili_data *ts = dev_id; disable_irq_nosync(ts->irq); queue_work(ts->workqueue, &ts->work); return IRQ_HANDLED; } ``` 2. **触摸坐标转换** ```c static void ili_report_points(struct input_dev *input) { // MTK屏幕分辨率适配 input_report_abs(input, ABS_MT_POSITION_X, x * 1080 / 1024); input_report_abs(input, ABS_MT_POSITION_Y, y * 2246 / 2048); } ``` 3. **固件升级机制** ```c #ifdef CONFIG_MTK_FW_UPGRADE static int ili_fw_update(struct device *dev) { // 使用MTK平台flash工具 ret = mtk_flash_write(flash_addr, fw_data, fw_size); } #endif ``` #### 四、调试与测试 1. **日志分析工具** ```bash adb shell "echo 8 > /proc/sys/kernel/printk" adb logcat | grep -i ilitek ``` 2. **I2C通信检测** ```bash i2cdetect -y 1 # 扫描I2C1总线设备 i2cdump -f -y 1 0x41 # 读取ILitek寄存器 ``` 3. **输入事件验证** ```bash getevent -lt # 查看原始触摸数据流 ``` > **注意事项** > - 确保MTK的I2C时钟频率与ILitek规格书匹配(通常400kHz) > - 休眠唤醒时需重新加载固件:`ili_resume()`中调用初始化函数 > - 若出现坐标抖动,需调整`filter_level`参数[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值