diff options
| author | 2018-12-23 22:48:19 +0000 | |
|---|---|---|
| committer | 2018-12-23 22:48:19 +0000 | |
| commit | ede2cd4659fc7a98adf78cd8183ff942ff261f5f (patch) | |
| tree | ed3a2931eb6db4d59d0486fd42a54ec29f050ade | |
| parent | Finally, stop abusing .Ss and .Sx to mark up macros, use .Ic instead (diff) | |
| download | wireguard-openbsd-ede2cd4659fc7a98adf78cd8183ff942ff261f5f.tar.xz wireguard-openbsd-ede2cd4659fc7a98adf78cd8183ff942ff261f5f.zip | |
Add support for generating a REPEATED START on operations where we first
write the register address and then read the register data in one go.
ok kettenis@
| -rw-r--r-- | sys/dev/fdt/imxiic.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/sys/dev/fdt/imxiic.c b/sys/dev/fdt/imxiic.c index 54de59ac253..97a42f04544 100644 --- a/sys/dev/fdt/imxiic.c +++ b/sys/dev/fdt/imxiic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imxiic.c,v 1.6 2018/08/20 16:48:47 patrick Exp $ */ +/* $OpenBSD: imxiic.c,v 1.7 2018/12/23 22:48:19 patrick Exp $ */ /* * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se> * @@ -71,7 +71,8 @@ void imxiic_setspeed(struct imxiic_softc *, u_int); int imxiic_intr(void *); int imxiic_wait_intr(struct imxiic_softc *, int, int); int imxiic_wait_state(struct imxiic_softc *, uint32_t, uint32_t); -int imxiic_read(struct imxiic_softc *, int, void *, int); +int imxiic_read(struct imxiic_softc *, int, const void *, int, + void *, int); int imxiic_write(struct imxiic_softc *, int, const void *, int, const void *, int); @@ -234,7 +235,6 @@ imxiic_wait_state(struct imxiic_softc *sc, uint32_t mask, uint32_t value) { uint32_t state; int timeout; - state = HREAD2(sc, I2C_I2SR); for (timeout = 1000; timeout > 0; timeout--) { if (((state = HREAD2(sc, I2C_I2SR)) & mask) == value) return 0; @@ -244,10 +244,22 @@ imxiic_wait_state(struct imxiic_softc *sc, uint32_t mask, uint32_t value) } int -imxiic_read(struct imxiic_softc *sc, int addr, void *data, int len) +imxiic_read(struct imxiic_softc *sc, int addr, const void *cmd, int cmdlen, + void *data, int len) { int i; + if (cmdlen > 0) { + if (imxiic_write(sc, addr, cmd, cmdlen, NULL, 0)) + return (EIO); + + HSET2(sc, I2C_I2CR, I2C_I2CR_RSTA); + delay(1); + if (imxiic_wait_state(sc, I2C_I2SR_IBB, I2C_I2SR_IBB)) + return (EIO); + } + + HCLR2(sc, I2C_I2SR, I2C_I2SR_IIF); HWRITE2(sc, I2C_I2DR, (addr << 1) | 1); if (imxiic_wait_state(sc, I2C_I2SR_IIF, I2C_I2SR_IIF)) @@ -287,6 +299,7 @@ imxiic_write(struct imxiic_softc *sc, int addr, const void *cmd, int cmdlen, { int i; + HCLR2(sc, I2C_I2SR, I2C_I2SR_IIF); HWRITE2(sc, I2C_I2DR, addr << 1); if (imxiic_wait_state(sc, I2C_I2SR_IIF, I2C_I2SR_IIF)) @@ -357,8 +370,6 @@ imxiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, if (!I2C_OP_STOP_P(op)) return EINVAL; - if (I2C_OP_READ_P(op) && cmdlen > 0) - return EINVAL; /* start transaction */ HSET2(sc, I2C_I2CR, I2C_I2CR_MSTA); @@ -373,7 +384,7 @@ imxiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, HSET2(sc, I2C_I2CR, I2C_I2CR_IIEN | I2C_I2CR_MTX | I2C_I2CR_TXAK); if (I2C_OP_READ_P(op)) { - ret = imxiic_read(sc, addr, buf, len); + ret = imxiic_read(sc, addr, cmdbuf, cmdlen, buf, len); } else { ret = imxiic_write(sc, addr, cmdbuf, cmdlen, buf, len); } |
