Hi

I’ve just started using MRF24J40 on the Freescale i.MX233 CPU, using i.MX233 
Olinuxino Maxi as prototype board.

This CPU does not support full duplex SPI which the current MRF24J40 driver 
requires. I can’t see that it actually needs full duplex though:
it reads and writes in the same request, but not simultaneously.

I’ve created a patch that makes it work on half duplex SPI as well. I’ve yet to 
get the driver to work fully (failed to set up interrupts
etc so far), but the SPI communication seems to work after applying this patch.

diff --git a/drivers/net/ieee802154/mrf24j40.c 
b/drivers/net/ieee802154/mrf24j40.c
index 0632d34..099ba25 100644
--- a/drivers/net/ieee802154/mrf24j40.c
+++ b/drivers/net/ieee802154/mrf24j40.c
@@ -103,7 +103,7 @@ static int write_short_reg(struct mrf24j40 *devrec, u8 reg, 
u8 value)
        struct spi_transfer xfer = {
                .len = 2,
                .tx_buf = devrec->buf,
-               .rx_buf = devrec->buf,
+               .rx_buf = 0,
        };
 
        spi_message_init(&msg);
@@ -126,25 +126,30 @@ static int read_short_reg(struct mrf24j40 *devrec, u8 
reg, u8 *val)
 {
        int ret = -1;
        struct spi_message msg;
-       struct spi_transfer xfer = {
-               .len = 2,
+       struct spi_transfer xfer_addr = {
+               .len = 1,
                .tx_buf = devrec->buf,
+               .rx_buf = 0,
+       };
+       struct spi_transfer xfer_result = {
+               .len = 1,
+               .tx_buf = 0,
                .rx_buf = devrec->buf,
        };
 
        spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
+       spi_message_add_tail(&xfer_addr, &msg);
+       spi_message_add_tail(&xfer_result, &msg);
 
        mutex_lock(&devrec->buffer_mutex);
        devrec->buf[0] = MRF24J40_READSHORT(reg);
-       devrec->buf[1] = 0;
 
        ret = spi_sync(devrec->spi, &msg);
        if (ret)
                dev_err(printdev(devrec),
                        "SPI read Failed for short register 0x%hhx\n", reg);
        else
-               *val = devrec->buf[1];
+               *val = devrec->buf[0];
 
        mutex_unlock(&devrec->buffer_mutex);
        return ret;
@@ -155,27 +160,32 @@ static int read_long_reg(struct mrf24j40 *devrec, u16 
reg, u8 *value)
        int ret;
        u16 cmd;
        struct spi_message msg;
-       struct spi_transfer xfer = {
-               .len = 3,
+       struct spi_transfer xfer_addr = {
+               .len = 2,
                .tx_buf = devrec->buf,
+               .rx_buf = 0,
+       };
+       struct spi_transfer xfer_result = {
+               .len = 1,
+               .tx_buf = 0,
                .rx_buf = devrec->buf,
        };
 
        spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
+       spi_message_add_tail(&xfer_addr, &msg);
+       spi_message_add_tail(&xfer_result, &msg);
 
        cmd = MRF24J40_READLONG(reg);
        mutex_lock(&devrec->buffer_mutex);
        devrec->buf[0] = cmd >> 8 & 0xff;
        devrec->buf[1] = cmd & 0xff;
-       devrec->buf[2] = 0;
 
        ret = spi_sync(devrec->spi, &msg);
        if (ret)
                dev_err(printdev(devrec),
                        "SPI read Failed for long register 0x%hx\n", reg);
        else
-               *value = devrec->buf[2];
+               *value = devrec->buf[0];
 
        mutex_unlock(&devrec->buffer_mutex);
        return ret;
@@ -189,7 +199,7 @@ static int write_long_reg(struct mrf24j40 *devrec, u16 reg, 
u8 val)
        struct spi_transfer xfer = {
                .len = 3,
                .tx_buf = devrec->buf,
-               .rx_buf = devrec->buf,
+               .rx_buf = 0,
        };
 
        spi_message_init(&msg);
@@ -223,14 +233,17 @@ static int write_tx_buf(struct mrf24j40 *devrec, u16 reg,
        struct spi_transfer addr_xfer = {
                .len = 2,
                .tx_buf = devrec->buf,
+               .rx_buf = 0,
        };
        struct spi_transfer lengths_xfer = {
                .len = 2,
                .tx_buf = &lengths, /* TODO: Is DMA really required for SPI? */
+               .rx_buf = 0,
        };
        struct spi_transfer data_xfer = {
                .len = length,
                .tx_buf = data,
+               .rx_buf = 0,
        };
 
        /* Range check the length. 2 bytes are used for the length fields.*/
@@ -271,13 +284,16 @@ static int mrf24j40_read_rx_buf(struct mrf24j40 *devrec,
        struct spi_transfer addr_xfer = {
                .len = 2,
                .tx_buf = &addr,
+               .rx_buf = 0,
        };
        struct spi_transfer data_xfer = {
                .len = 0x0, /* set below */
+               .tx_buf = 0,
                .rx_buf = data,
        };
        struct spi_transfer status_xfer = {
                .len = 2,
+               .tx_buf = 0,
                .rx_buf = &lqi_rssi,
        };
 
Regards,
Jonatan Magnusson


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to