设为首页 加入收藏

TOP

i2c 驱动编程接口(五)
2012-12-06 13:36:39 来源: 作者: 【 】 浏览:1308
Tags:i2c  驱动 编程 接口

 

    2、reset 接口

    最近因为平台的i2c总线经常发生死锁,用逻辑分析仪检测发现通常为SDA和SCL都被拉低,于是在i2c-core中加入了reset机制,总体思路如下:

    (1)在i2c.driver和i2c.adapter的结构中加入reset接口,即每一个i2c设备都可以注册reset函数,每条i2c总线都有相应的reset接口

    (2)当发生死锁时,首先根据i2c-timeout的信息获取当前通信的设备地址和总线编号,然后依次执行当前总线下所有i2c设备的reset函数,再尝试发送是否成功;如果总线仍然处于死锁状态则执行i2c.adapter的reset函数;如果总线还是处于死锁状态就重启机器;总共3层reset机制

    (3)i2c.driver的reset函数一般操作设备的reset pin或者电源(需要根据硬件设计进行相应操作)

    (4)i2c.adapter的reset函数首选进行SCL的模拟解锁方案,然后再是操作整个总线上设备的电源(需要根据硬件设计进行相应操作)

    (5)重启是最后的一层机制,此时无法恢复设备的正常使用就只能重启了

    因为i2c.adapter层的需要,在i2c-core中加入了遍历当前总线所有设备并执行设备reset函数的接口i2c_reset_device:

    [cpp]

    /**

    * i2c_reset_device - reset I2C device when bus dead

    * @adapter: the adapter being reset

    * @addr: the device address

    */

    static int __i2c_reset_device(struct device *dev, void *addrp)

    {

    struct i2c_client *client = to_i2c_client(dev);

    int addr = *(int *)addrp;

    if (client && client->driver && client->driver->reset)

    return client->driver->reset();

    return 0;

    }

    int i2c_reset_device(struct i2c_adapter *adapter, int addr)

    {

    return device_for_each_child(&adapter->dev, &addr, __i2c_reset_device);

    }

    EXPORT_SYMBOL(i2c_reset_device);

    需要注意的是i2c.driver的reset函数返回值需要为0,不然device_for_each_child不会继续后面的遍历.用GPIO模拟SCL解锁的参考代码如下:

    [cpp]

    static int i2c_reset_adapter(void)

    {

    int counter = 0;

    gpio_request(I2C_BUS_DATA, “gpioxx”);

    gpio_request(I2C_BUS_CLK, “gpioxx”);

    /* try to recover I2C bus */

    gpio_direction_input(I2C_BUS_DATA);

    if (!__gpio_get_value(I2C_BUS_DATA)) {

    while((!__gpio_get_value(I2C_BUS_DATA)) && ++counter < 10)

    {

    udelay(5);

    gpio_direction_output(I2C_BUS_CLK, 1);

    udelay(5);

    gpio_direction_output(I2C_BUS_CLK, 0);

    }

    i2c_err(“try to recover i2c bus, retry times are %d\n”,counter);

    if (counter < 10) {

    udelay(5);

    gpio_direction_output(I2C_BUS_DATA, 0);

    udelay(5);

    gpio_direction_output(I2C_BUS_CLK, 1);

    udelay(5);

    gpio_direction_output(I2C_BUS_DATA, 1);

    msleep(10);

    } else {

    i2c_err(“try to recover i2c bus failed!\n”);

    }

    }

    gpio_free(I2C_BUS_DATA);

    gpio_free(I2C_BUS_CLK);

    return 0;

    }

        

首页 上一页 2 3 4 5 下一页 尾页 5/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇小议C++中const的实现机制 下一篇C++获取zip文件列表

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: