Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157153909
D44021.id134821.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D44021.id134821.diff
View Options
diff --git a/sys/dev/iicbus/controller/vybrid/vf_i2c.c b/sys/dev/iicbus/controller/vybrid/vf_i2c.c
--- a/sys/dev/iicbus/controller/vybrid/vf_i2c.c
+++ b/sys/dev/iicbus/controller/vybrid/vf_i2c.c
@@ -132,11 +132,9 @@
int
vf_i2c_attach_common(device_t dev)
{
- struct i2c_softc *sc;
+ struct i2c_softc *sc = device_get_softc(dev);
int error;
- sc = device_get_softc(dev);
-
vf_i2c_dbg(sc, "i2c attach common\n");
mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);
@@ -165,6 +163,7 @@
}
sc->iicbus = device_add_child(dev, "iicbus", -1);
+
if (sc->iicbus == NULL) {
device_printf(dev, "could not add iicbus child");
mtx_destroy(&sc->mutex);
@@ -210,24 +209,6 @@
return (0);
}
-/* Wait for transfer interrupt flag */
-static int
-wait_for_iif(struct i2c_softc *sc)
-{
- int retry;
-
- retry = 1000;
- while (retry --) {
- if (READ1(sc, I2C_IBSR) & IBSR_IBIF) {
- WRITE1(sc, I2C_IBSR, IBSR_IBIF);
- return (IIC_NOERR);
- }
- DELAY(10);
- }
-
- return (IIC_ETIMEOUT);
-}
-
/* Wait for free bus */
static int
wait_for_nibb(struct i2c_softc *sc)
@@ -249,14 +230,23 @@
wait_for_icf(struct i2c_softc *sc)
{
int retry;
+ uint8_t ibsr;
+ vf_i2c_dbg(sc, "i2c wait for transfer complete + interrupt flag\n");
retry = 1000;
while (retry --) {
- if (READ1(sc, I2C_IBSR) & IBSR_TCF) {
- if (READ1(sc, I2C_IBSR) & IBSR_IBIF) {
- WRITE1(sc, I2C_IBSR, IBSR_IBIF);
- return (IIC_NOERR);
+ ibsr=READ1(sc, I2C_IBSR);
+
+ if (ibsr & IBSR_IBIF) {
+ WRITE1(sc, I2C_IBSR, IBSR_IBIF);
+
+ if (ibsr & IBSR_IBAL) {
+ WRITE1(sc, I2C_IBSR, IBSR_IBAL);
+ return (IIC_EBUSBSY);
}
+
+ if (ibsr & IBSR_TCF)
+ return (IIC_NOERR);
}
DELAY(10);
}
@@ -286,30 +276,24 @@
mtx_lock(&sc->mutex);
- WRITE1(sc, I2C_IBAD, slave);
-
if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0) {
+ vf_i2c_dbg(sc, "cant i2c repeat start: bus is no longer busy\n");
mtx_unlock(&sc->mutex);
return (IIC_EBUSERR);
}
- /* Set repeated start condition */
- DELAY(10);
-
reg = READ1(sc, I2C_IBCR);
reg |= (IBCR_RSTA | IBCR_IBIE);
WRITE1(sc, I2C_IBCR, reg);
- DELAY(10);
-
/* Write target address - LSB is R/W bit */
WRITE1(sc, I2C_IBDR, slave);
- error = wait_for_iif(sc);
+ error = wait_for_icf(sc);
if (!tx_acked(sc)) {
- vf_i2c_dbg(sc,
- "cant i2c start: missing ACK after slave addres\n");
+ mtx_unlock(&sc->mutex);
+ vf_i2c_dbg(sc, "cant i2c repeat start: missing ACK after slave address\n");
return (IIC_ENOACK);
}
@@ -334,27 +318,32 @@
mtx_lock(&sc->mutex);
- WRITE1(sc, I2C_IBAD, slave);
+ error = wait_for_nibb(sc);
+
+ /* Reset controller if bus still busy */
+ if (error == IIC_ETIMEOUT) {
+ WRITE1(sc, I2C_IBCR, IBCR_MDIS);
+ DELAY(1000);
+ WRITE1(sc, I2C_IBCR, IBCR_NOACK);
+ error = wait_for_nibb(sc);
+ }
- if (READ1(sc, I2C_IBSR) & IBSR_IBB) {
+ if (error != 0) {
mtx_unlock(&sc->mutex);
- vf_i2c_dbg(sc, "cant i2c start: IIC_EBUSBSY\n");
- return (IIC_EBUSERR);
+ vf_i2c_dbg(sc, "cant i2c start: %i\n", error);
+ return (error);
}
/* Set start condition */
- reg = (IBCR_MSSL | IBCR_NOACK | IBCR_IBIE);
+ reg = (IBCR_MSSL | IBCR_NOACK | IBCR_IBIE | IBCR_TXRX);
WRITE1(sc, I2C_IBCR, reg);
- DELAY(100);
-
- reg |= (IBCR_TXRX);
- WRITE1(sc, I2C_IBCR, reg);
+ WRITE1(sc, I2C_IBSR, IBSR_IBIF);
/* Write target address - LSB is R/W bit */
WRITE1(sc, I2C_IBDR, slave);
- error = wait_for_iif(sc);
+ error = wait_for_icf(sc);
if (error != 0) {
mtx_unlock(&sc->mutex);
vf_i2c_dbg(sc, "cant i2c start: iif error\n");
@@ -363,8 +352,7 @@
mtx_unlock(&sc->mutex);
if (!tx_acked(sc)) {
- vf_i2c_dbg(sc,
- "cant i2c start: missing QACK after slave addres\n");
+ vf_i2c_dbg(sc, "cant i2c start: missing ACK after slave address\n");
return (IIC_ENOACK);
}
@@ -382,16 +370,9 @@
mtx_lock(&sc->mutex);
- WRITE1(sc, I2C_IBCR, IBCR_NOACK | IBCR_IBIE);
+ if ((READ1(sc, I2C_IBCR) & IBCR_MSSL) != 0)
+ WRITE1(sc, I2C_IBCR, IBCR_NOACK | IBCR_IBIE);
- DELAY(100);
-
- /* Reset controller if bus still busy after STOP */
- if (wait_for_nibb(sc) == IIC_ETIMEOUT) {
- WRITE1(sc, I2C_IBCR, IBCR_MDIS);
- DELAY(1000);
- WRITE1(sc, I2C_IBCR, IBCR_NOACK);
- }
mtx_unlock(&sc->mutex);
return (IIC_NOERR);
@@ -452,25 +433,12 @@
vf_i2c_dbg(sc, "i2c reset\n");
- switch (speed) {
- case IIC_FAST:
- case IIC_SLOW:
- case IIC_UNKNOWN:
- case IIC_FASTEST:
- default:
- break;
- }
-
mtx_lock(&sc->mutex);
WRITE1(sc, I2C_IBCR, IBCR_MDIS);
- DELAY(1000);
-
i2c_update_div_val(dev);
WRITE1(sc, I2C_IBCR, 0x0); /* Enable i2c */
- DELAY(1000);
-
mtx_unlock(&sc->mutex);
return (IIC_NOERR);
@@ -491,37 +459,38 @@
mtx_lock(&sc->mutex);
if (len) {
+
if (len == 1)
- WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL | \
- IBCR_NOACK);
+ WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL | IBCR_NOACK);
else
WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL);
/* dummy read */
READ1(sc, I2C_IBDR);
- DELAY(1000);
- }
- while (*read < len) {
- error = wait_for_icf(sc);
- if (error != 0) {
- mtx_unlock(&sc->mutex);
- return (error);
- }
+ while (*read < len) {
+ error = wait_for_icf(sc);
- if ((*read == len - 2) && last) {
- /* NO ACK on last byte */
- WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL | \
- IBCR_NOACK);
- }
+ if (error != 0) {
+ mtx_unlock(&sc->mutex);
+ return (error);
+ }
- if ((*read == len - 1) && last) {
- /* Transfer done, remove master bit */
- WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_NOACK);
- }
+ if (last ) {
+
+ if (*read == len - 2) {
+ /* NO ACK on last byte */
+ WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL | IBCR_NOACK);
+
+ } else if (*read == len - 1) {
+ /* Transfer done, remove master bit */
+ WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_NOACK);
+ }
+ }
- *buf++ = READ1(sc, I2C_IBDR);
- (*read)++;
+ *buf++ = READ1(sc, I2C_IBDR);
+ (*read)++;
+ }
}
mtx_unlock(&sc->mutex);
@@ -544,7 +513,8 @@
while (*sent < len) {
WRITE1(sc, I2C_IBDR, *buf++);
- error = wait_for_iif(sc);
+ error = wait_for_icf(sc);
+
if (error != 0) {
mtx_unlock(&sc->mutex);
return (error);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, May 19, 8:14 PM (3 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33327039
Default Alt Text
D44021.id134821.diff (6 KB)
Attached To
Mode
D44021: Revamping the existing Vybrid I2C Controller Driver to Include Support for the QorIQ LX2160A Controller
Attached
Detach File
Event Timeline
Log In to Comment