From 11ae9325150c77551b1c6176130d24110d451fc5 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Wed, 23 Jun 2021 13:39:13 +0000 Subject: Make sure the bus is idle before starting a transfer. ok deraadt@ --- sys/dev/fdt/ociic.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/sys/dev/fdt/ociic.c b/sys/dev/fdt/ociic.c index 736514dc535..a184acf1a32 100644 --- a/sys/dev/fdt/ociic.c +++ b/sys/dev/fdt/ociic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ociic.c,v 1.1 2021/06/16 12:37:24 kettenis Exp $ */ +/* $OpenBSD: ociic.c,v 1.2 2021/06/23 13:39:12 kettenis Exp $ */ /* * Copyright (c) 2021 Mark Kettenis * @@ -188,6 +188,26 @@ ociic_release_bus(void *cookie, int flags) ociic_clr(sc, I2C_CTR, I2C_CTR_EN); } +int +ociic_unbusy(struct ociic_softc *sc) +{ + uint8_t stat; + int timo; + + for (timo = 50000; timo > 0; timo--) { + stat = ociic_read(sc, I2C_SR); + if ((stat & I2C_SR_BUSY) == 0) + break; + delay(10); + } + if (timo == 0) { + ociic_write(sc, I2C_CR, I2C_CR_STO); + return ETIMEDOUT; + } + + return 0; +} + int ociic_wait(struct ociic_softc *sc, int ack) { @@ -226,6 +246,10 @@ ociic_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmd, struct ociic_softc *sc = cookie; int error, i; + error = ociic_unbusy(sc); + if (error) + return error; + if (cmdlen > 0) { ociic_write(sc, I2C_TXR, addr << 1); ociic_write(sc, I2C_CR, I2C_CR_STA | I2C_CR_WR); -- cgit v1.2.3