AnsweredAssumed Answered

Questions on example driver on eCSPI on MX53

Question asked by Michael John on Jul 7, 2017
Latest reply on Mar 30, 2018 by TomE

I've been looking at the mxc_m25p80.c example driver Freescale has for communicating on the eCSPI. I'm trying to write a driver for the Fujitsu mb85rs256 FRAM on a custom board with Linux 2.6.35. I can write and read 32-bits at a time with success, but when I implemented burst mode like in the example driver I've ran into issues.

 

In the example driver, Freescale has written there own function to call the kernel functions for SPI. Freescale called it spi_read_write. Why did Freescale not use a function provided by the kernel (spi_write, spi_read, spi_write_read)?

Also this function does some things I don't understand. They take the length of the byte array and shift it to the left 3 places, and set this as the bits_per_word. Why wouldn't this be the bits_per_word that the slave device expects? They then take the length of the byte array, add 3 to it, divide by 4 and set that as the length of the tx/rx buffer. Why? It's not clear why the Freescale driver is doing this. From what I've gathered it seems bits_per_word is really set to the number of bits in the FIFO and length is really how many levels of the FIFO are used.

 

Here is the snippet of code for reference:

static inline int spi_nor_setup(struct spi_device *spi, u8 bst_len)
{
     spi->bits_per_word = bst_len << 3;

     return spi_setup(spi);
}

#define     SPI_FIFOSIZE          24     /* Bust size in bytes */

static int spi_read_write(struct spi_device *spi, u8 * buf, u32 len)
{
     struct spi_message m;
     struct spi_transfer t;

     if (len > SPI_FIFOSIZE || len <= 0)
          return -1;

     spi_nor_setup(spi, len);

     spi_message_init(&m);
     memset(&t, 0, sizeof t);

     t.tx_buf = buf;
     t.rx_buf = buf;
     t.len = (len + 3) / 4;

     spi_message_add_tail(&t, &m);

     if (spi_sync(spi, &m) != 0) {
          printk(KERN_ERR "%s: error\n", __func__);
          return -1;
     }

     DEBUG(MTD_DEBUG_LEVEL2, "%s: len: 0x%x success\n", __func__, len);

     return 0;

}

 

Another thing I found odd was the order the tx buffer is filled with data to be transmitted. Rather than writing linearly to the byte array it writes in the index order of 3,2,1,0,7,6,5,4,11,10,9,8 .... is this due to how the eCSPI reads the FIFO? (32bit wide, 8 levels deep)

 

I've written a driver for this same FRAM on a platform with a TI am3352 and it was pretty straight forwards to get it working. Looking at this example driver for the MX53 I'm confused on why Freescale did what they did. Any help would be greatly appreciated.

 

Thanks.

Original Attachment has been moved to: mxc_m25p80.c.zip

Outcomes