android 修改iic速度,[RK3288][Android6.0] I2C默认传输速率及修改

Platform: Rockchip

OS: Android 6.0

Kernel: 3.10.92

RK对应的i2c controller驱动在

kernel/drivers/i2c/busses/i2c-rockchip.c

对应的传输函数是rockchip_i2c_xfer():

static const struct i2c_algorithm rockchip_i2c_algorithm = {

.master_xfer = rockchip_i2c_xfer,

.functionality = rockchip_i2c_func,

};代码上一般会直接调用i2c_master_send或者i2c_master_recv

i2c_master_send|i2c_master_recv ->    i2c_transfer -> adap->algo->master_xfer -> rockchip_i2c_xfer

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,但会有类似如下警告:

rockchip_i2c ff170000.i2c: Warning: addr[0x0050] msg[0].scl_rate( = 0Khz) is too low

!

修改:

dts也没有提供相对应的property来修改scl rate,因此只能在代码中修改了,例如:

diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c

index 2baeec5..bf090b4 100644

--- a/drivers/misc/eeprom/at24.c

+++ b/drivers/misc/eeprom/at24.c

@@ -213,11 +213,14 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,

msg[0].addr = client->addr;

msg[0].buf = msgbuf;

msg[0].len = i;

+              msg[0].scl_rate = 100*1000;

+

msg[1].addr = client->addr;

msg[1].flags = I2C_M_RD;

msg[1].buf = buf;

msg[1].len = count;

+               msg[1].scl_rate = 100*1000;         }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值