Chinaunix首页 | 论坛 | 博客
  • 博客访问: 52976
  • 博文数量: 13
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 62
  • 用 户 组: 普通用户
  • 注册时间: 2015-12-09 10:03
个人简介

c,c++

文章分类

全部博文(13)

文章存档

2018年(1)

2016年(2)

2015年(10)

我的朋友

分类: LINUX

2018-08-28 18:06:47


    移植的目标平台为海思3531,移植驱动前,先找FAE索要linux平台的驱动源码。拿到源码后,在驱动模块入口函数ft5x0x_ts_init中通过i2c_new_device向i2c总线注册触摸屏设备,前提是触摸屏IC得支持使用I2C接口通信。简要记录一下碰到的问题及解决过程:

1. 编译驱动源码后,不能执行自己的probe函数

解决过程:
按照平台设备驱动的框架,首先定义一个i2c_board_info结构体,其中I2C_BOARD_INFO中的.name与i2c_driver结构体中的drvier->name一致。如下
static struct i2c_driver ft5x0x_ts_driver = {
    .probe        = ft5x0x_ts_probe,
    .remove        = __devexit_p(ft5x0x_ts_remove),
    .id_table    = ft5x0x_ts_id,
    .driver    = {
        .name    = "ft5x0x_ts",
        .owner    = THIS_MODULE,
    },
};

static struct i2c_board_info __initdata fts_i2c_board_info[] = {
{
I2C_BOARD_INFO("ft5x0x_ts", 0x70),
.irq = IRQ_EINT(6),
},
};
此时,一般情况下,如果内核中的板级驱动初始化代码中如果使用了i2c_register_board_info来注册设备信息,则可以将上述I2C_BOARD_INFO("ft5x0x_ts", 0x70)信息扩充到板级驱动代码中的i2c_board_info结构体中,只需定义i2c_driver结构体然后在模块入口函数中调用i2c_add_driver,并传入i2c_driver结构体指针,如下:
    
    i2c_add_driver(&ft5x0x_ts_driver);
然后平台驱动将会自动匹配并调用自定义的probe函数。如果板级驱动初始化代码中没有使用i2c_register_board_info注册设备信息,此时仍然可以通过以下方式注册i2c设备:
     struct i2c_adapter *i2c_adap;
     int busNum = 0 ;
     i2c_adap = i2c_get_adapter(busNum);//这里要实验的触摸屏是挂接在第1条I2C-0总线上的,所以这里的参数是0
     if (!i2c_adap) {
     pr_err("failed to get adapter i2c%d\n", busNum);
     return -ENODEV;
}
this_client = i2c_new_device(i2c_adap, fts_i2c_board_info);//设置和注册i2c_client结构体
 ret = i2c_add_driver(&ft5x0x_ts_driver);
 printk("ret=%d\n",ret);

i2c_put_adapter(i2c_adap);
  
通过调用i2c_new_device接口,设备将注册到内核并创建i2c_client结构体。然后调用      i2c_add_driver接口来与I2C总线驱动进行匹配,若名称一致,匹配成功后执行自定义的  probe函数。

2. probe函数中申请中断返回-1,不能触发中断,中断触发后终端无响应

解决过程:
       NO1. 
        查询错误码,-1表示操作不允许.猜想是中断号不正确,查阅海思3531硬件手册,在request_irq中填入正确的中断号,错误依旧.后来发现更改中断触发方式,将flags设置为0后,中断可以申请成功了.对比了海思驱动代码中的用法,确实也将flags设置为0.由此,猜想中断触发方式无须内核处理,由驱动根据硬件平台设置即可.相反设置了标志位,但内核中并无实现,由此产生错误.
       NO2.
        至于中断申请成功后,点击触摸屏后不能进入中断处理函数的问题,首先按照硬件手册确认中断GPIO管脚配置情况,发现配置有问题,更改配置后,问题解决,点击触摸屏后便立即进入了中断处理函数.
       NO3.
       中断处理函数中,一般需要禁止中断,将disable_irq接口更改为disable_irq_nosync后,问题解决.

3. 触摸屏数据读取不到

驱动源码中的数据读取函数为标准的i2c_transfer接口重新封装实现的,触摸屏数据有多个数据,采用一次性读取多个字节数据的方式.通常利用i2c_transfer按照I2c协议,首先向触摸屏IC写入1个字节的将要读取的寄存器序列的首地址,然后通过i2c_transfer接口接收N个字节的数据.如下:
    int ret;
    struct i2c_msg msgs[] = {
        {
            .addr    = this_client->addr,
            .flags    = 0,
            .len    = 1,
            .buf    = rxdata,
        },
        {
            .addr    = this_client->addr,
            .flags    = I2C_M_RD,
            .len    = length,
            .buf    = rxdata,
        },
    };
    //msleep(1);
    ret = i2c_transfer(this_client->adapter, msgs, 2);
    if (ret < 0)
        pr_err("msg %s i2c read error: %d\n", __func__, ret);
    
    return ret;
    
    但在海思3531上采用此种办法时出现错误,似乎不支持i2c_transfer的1个字节的传输指令.重写多字节读取接口,采用每次读一个字节数据,连续读取N次的办法后,问题解决.

for(i = 0; i < length; i++)
{
         int result = 0;
result = ft5x0x_read_reg(start_addr+i, rxdata+i);
if(result >= 0)
{

     ret += result;

          }
}

4. 触摸屏触点坐标与显示屏坐标不一致

询问FAE得知可以通过升级触摸屏IC固件来解决.好比重新校准.

5. 驱动ko卸载后再次加载后,驱动无法正常工作

  原因:触摸IC复位没有成功.
     解决办法: 复位后,将复位管脚电平复原为高电平
     RESET_PIN = 0; // 复位
     mdelay(5);
     RESET_PIN = 1; // 还原
     mdelay(5);

  
    


阅读(2304) | 评论(0) | 转发(0) |
0

上一篇:miniGUI3.0.12安装方法收拾

下一篇:没有了

给主人留下些什么吧!~~