Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92
RK对应的i2c controller驱动在
kernel/drivers/i2c/busses/i2c-rockchip.cstatic const struct i2c_algorithm rockchip_i2c_algorithm = {
.master_xfer = rockchip_i2c_xfer,
.functionality = rockchip_i2c_func,
};
代码上一般会直接调用i2c_master_send或者i2c_master_recv
int i2c_master_send(const struct i2c_client *client, const char *buf, int count)
{
......
#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
msg.scl_rate = 100 * 1000;
#endif
ret = i2c_transfer(adap, &msg, 1);
......
}
int i2c_master_recv(const struct i2c_client *client, char *buf, int count)
{
......
#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
msg.scl_rate = 100 * 1000;
#endif
ret = i2c_transfer(adap, &msg, 1);
......
}
EXPORT_SYMBOL(i2c_master_recv);
这种情况下默认是i2c的传输速率设的是100kHz.而有些地方会直接调用i2c_transfer(), 比如at24.c中
static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
unsigned offset, size_t count)
{
......
default:
i = 0;
if (at24->chip.flags & AT24_FLAG_ADDR16)
msgbuf[i++] = offset >> 8;
msgbuf[i++] = offset;
msg[0].addr = client->addr;
msg[0].buf = msgbuf;
msg[0].len = i;
msg[1].addr = client->addr;
msg[1].flags = I2C_M_RD;
msg[1].buf = buf;
msg[1].len = count;
}
......
default:
status = i2c_transfer(client->adapter, msg, 2);
if (status == 2)
status = count;
}
......
return -ETIMEDOUT;
}
这种情况,最终也是调用rockchip_i2c_xfer().
static int rockchip_i2c_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
......
#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
if (msgs[0].scl_rate <= 400000 && msgs[0].scl_rate >= 10000)
scl_rate = msgs[0].scl_rate;
else if (msgs[0].scl_rate > 400000) {
dev_warn_ratelimited(i2c->dev, "Warning: addr[0x%04x] msg[0].scl_rate( = %dKhz) is too high!",
msgs[0].addr, msgs[0].scl_rate/1000);
scl_rate = 400000;
} else {
dev_warn_ratelimited(i2c->dev, "Warning: addr[0x%04x] msg[0].scl_rate( = %dKhz) is too low!",
msgs[0].addr, msgs[0].scl_rate/1000);
scl_rate = 100000;
}
rockchip_i2c_set_clk(i2c, scl_rate);
#endif
i2c_dbg(i2c->dev, "i2c transfer start: addr: 0x%04x, scl_reate: %ldKhz, len: %d\n", msgs[0].addr, scl_rate/1000, num);
ret = rockchip_i2c_doxfer(i2c, msgs, num);
i2c_dbg(i2c->dev, "i2c transfer stop: addr: 0x%04x, state: %d, ret: %d\n", msgs[0].addr, ret, i2c->state);
......
}
但是这时驱动设置scl rate,虽然默认也是100kHz,但会有类似如下警告:
修改: