1. 程式人生 > >[RK3288][Android6.0] 除錯筆記 --- 測試I2C裝置正常傳輸方法

[RK3288][Android6.0] 除錯筆記 --- 測試I2C裝置正常傳輸方法

Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92

rk在驅動層做了一個通用i2c測試程式碼提供給上層快速測試i2c外設是否傳輸正常.

測試使用方法:
#echo [0-5] > /dev/i2c_detect    //0-5表示i2c number號,不過i2c5需要修改下驅動,預設只支援到i2c4.
例如我的i2c2接的是audio codec:
&i2c2 {
    status = "okay";
    rt5631: [email protected] {
        compatible = "rt5631";
        reg = <0x1a>;
    };
};
[email protected]:/ # echo 2 > /dev/i2c_detect
kernel log出列印:
I2c2 slave list:   0x1a
而audio codec的地址就是0x1a.

驅動關鍵點說明:
kernel/drivers/i2c/buses/i2c-rockchip.c:
static ssize_t i2c_detect_write(struct file *file,
            const char __user *buf, size_t count, loff_t *offset)
{
    char nr_buf[8];
    int nr = 0, ret;
    /*只支援到i2c4, 如果要支援i2c5,那麼要改成5.*/
    if (count > 4)
        return -EFAULT;
    ret = copy_from_user(nr_buf, buf, count);
    if (ret < 0)
        return -EFAULT;

    sscanf(nr_buf, "%d", &nr);
    /*這裡得改成6. */
    if (nr >= 5 || nr < 0)
        return -EFAULT;

    slave_detect(nr);

    return count;
}

static void slave_detect(int nr)
{
    int ret = 0;
    unsigned short addr;
    char val[8];
    char buf[6 * 0x80 + 20];
    struct i2c_client client;

    memset(buf, 0, 6 * 0x80 + 20);

    sprintf(buf, "I2c%d slave list: ", nr);
    do {
        /*掃描0x01~0x80地址範圍的裝置.*/
        for (addr = 0x01; addr < 0x80; addr++) {
            detect_set_client(&client, addr, nr);
            /*讀取一個位元組.*/
            ret = detect_read(&client, val, 1);
            if (ret > 0)
                sprintf(buf, "%s  0x%02x", buf, addr);
        }
        /*列印掃描到的裝置地址.*/
        printk("%s\n", buf);
    }
    while (0);
}

static int detect_read(struct i2c_client *client, char *buf, int len)
{
    struct i2c_msg msg;

    msg.addr = client->addr;
    msg.flags = client->flags | I2C_M_RD;
    msg.buf = buf;
    msg.len = len;
    /*以100kHz的速率讀取*/
#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
    msg.scl_rate = 100 * 1000;
#endif

    return i2c_transfer(client->adapter, &msg, 1);
}