dieselburner opened a new issue #1356:
URL: https://github.com/apache/incubator-nuttx/issues/1356


   **Issue:**
   
   Currently there's a misalignment in MTD drivers, where some drivers are 
written exclusively for QSPI interfaces, while others are using standard SPI. 
As you know, (nearly?) all QuadSPI controller implementations allows you to use 
QSPI in a standard SPI way, and opposite, all QSPI devices that I have seen 
(I've seen things you people wouldn't believe (C)) are able to operate in a 
standard SPI mode.
   
   **Example:**
   
   1. [m25qxxx 
driver](https://github.com/apache/incubator-nuttx/blob/master/drivers/mtd/n25qxxx.c)
 is using QSPI_* functions, which means currently it is impossible to use this 
particular driver with standard SPI interface.
   
   ```c
   static int n25qxxx_command_write(FAR struct qspi_dev_s *qspi, uint8_t cmd,
                                    FAR const void *buffer, size_t buflen)
   {
     struct qspi_cmdinfo_s cmdinfo;
   
     finfo("CMD: %02x buflen: %lu\n", cmd, (unsigned long)buflen);
   
     cmdinfo.flags   = QSPICMD_WRITEDATA;
     cmdinfo.addrlen = 0;
     cmdinfo.cmd     = cmd;
     cmdinfo.buflen  = buflen;
     cmdinfo.addr    = 0;
     cmdinfo.buffer  = (FAR void *)buffer;
   
     return QSPI_COMMAND(qspi, &cmdinfo);
   }
   ```
   
   2. [gd5d 
driver](https://github.com/apache/incubator-nuttx/blob/master/drivers/mtd/gd5f.c)
 is using SPI_* commands, which means currently it is impossible to use this 
particular driver with QSPI interface, even though this NAND chip supports QSPI.
   
   ```c
   static bool gd5f_execute_write(FAR struct gd5f_dev_s *priv, uint32_t 
pageaddress)
   {
     const uint32_t row = pageaddress >> priv->pageshift;
   
     /* Select this FLASH part */
   
     SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
   
     /* Send the Program Execute instruction */
   
     SPI_SEND(priv->dev, GD5F_PROGRAM_EXECUTE);
     SPI_SEND(priv->dev, (row >> 16) & 0xff);
     SPI_SEND(priv->dev, (row >> 8) & 0xff);
     SPI_SEND(priv->dev, row & 0xff);
   
     /* De-select the FLASH */
   
     SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
   
     return gd5f_waitstatus(priv, GD5F_SR_P_FAIL, false);
   }
   ```
   
   **Solution:**
   
   Ideally having some sort of a common `ops` structure that is initialized by 
SPI/QSPI/other_transport drivers, which then is used in MTD (and other) device 
drivers, by simply calling appropriate callbacks without caring what transport 
is being used. That's pretty much the same way how these kind of things are 
implemented in Linux kernel.
   
   ```c
   struct spi_nor_controller_ops {
           int (*prepare)(struct spi_nor *nor);
           void (*unprepare)(struct spi_nor *nor);
           int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, size_t len);
           int (*write_reg)(struct spi_nor *nor, u8 opcode, const u8 *buf,
                            size_t len);
   
           ssize_t (*read)(struct spi_nor *nor, loff_t from, size_t len, u8 
*buf);
           ssize_t (*write)(struct spi_nor *nor, loff_t to, size_t len,
                            const u8 *buf);
           int (*erase)(struct spi_nor *nor, loff_t offs);
   };
   ```


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to