From: kettenis Date: Tue, 6 Dec 2022 16:06:32 +0000 (+0000) Subject: For write operations, wait until the transaction completes just like we X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=075e123e780bd5b8c1c8d53f2f08cd15cd4e25bc;p=openbsd For write operations, wait until the transaction completes just like we do after sending the command for a read operation. Fixes issues with doing multiple operations back-to-back. ok patrick@ --- diff --git a/sys/arch/arm64/dev/apliic.c b/sys/arch/arm64/dev/apliic.c index 59e51d2e44a..7358d669b0d 100644 --- a/sys/arch/arm64/dev/apliic.c +++ b/sys/arch/arm64/dev/apliic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: apliic.c,v 1.3 2022/02/14 14:55:53 kettenis Exp $ */ +/* $OpenBSD: apliic.c,v 1.4 2022/12/06 16:06:32 kettenis Exp $ */ /* * Copyright (c) 2021 Patrick Wildt * @@ -152,6 +152,29 @@ apliic_attach(struct device *parent, struct device *self, void *aux) config_found(&sc->sc_dev, &iba, iicbus_print); } +int +apliic_wait(struct apliic_softc *sc) +{ + uint32_t reg; + int timo; + + for (timo = 10; timo > 0; timo--) { + reg = HREAD4(sc, I2C_SMSTA); + if (reg & I2C_SMSTA_XEN) + break; + delay(1000); + } + if (reg & I2C_SMSTA_MTN) + return ENXIO; + if (timo == 0) { + HWRITE4(sc, I2C_SMSTA, reg); + return ETIMEDOUT; + } + + HWRITE4(sc, I2C_SMSTA, I2C_SMSTA_XEN); + return 0; +} + int apliic_acquire_bus(void *cookie, int flags) { @@ -169,12 +192,13 @@ apliic_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmd, { struct apliic_softc *sc = cookie; uint32_t reg; - int i; + int error, i; if (!I2C_OP_STOP_P(op)) return EINVAL; - HWRITE4(sc, I2C_SMSTA, 0xffffffff); + reg = HREAD4(sc, I2C_SMSTA); + HWRITE4(sc, I2C_SMSTA, reg); if (cmdlen > 0) { HWRITE4(sc, I2C_MTXFIFO, I2C_MTXFIFO_START | addr << 1); @@ -191,17 +215,9 @@ apliic_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmd, HWRITE4(sc, I2C_MTXFIFO, I2C_MTXFIFO_START | addr << 1 | 1); HWRITE4(sc, I2C_MTXFIFO, I2C_MTXFIFO_READ | buflen | I2C_MTXFIFO_STOP); - for (i = 10; i > 0; i--) { - delay(1000); - reg = HREAD4(sc, I2C_SMSTA); - if (reg & I2C_SMSTA_XEN) - break; - } - if (reg & I2C_SMSTA_MTN) - return ENXIO; - if (i == 0) - return ETIMEDOUT; - HWRITE4(sc, I2C_SMSTA, I2C_SMSTA_XEN); + error = apliic_wait(sc); + if (error) + return error; for (i = 0; i < buflen; i++) { reg = HREAD4(sc, I2C_MRXFIFO); if (reg & I2C_MRXFIFO_EMPTY) @@ -215,6 +231,9 @@ apliic_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmd, HWRITE4(sc, I2C_MTXFIFO, ((uint8_t *)buf)[i]); HWRITE4(sc, I2C_MTXFIFO, ((uint8_t *)buf)[buflen - 1] | I2C_MTXFIFO_STOP); + error = apliic_wait(sc); + if (error) + return error; } return 0;