linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* SPI: DUAL/QUAD support
@ 2013-07-04 11:36 yuhang wang
  2013-07-04 13:00 ` Johannes Stezenbach
  2013-07-04 14:36 ` Mark Brown
  0 siblings, 2 replies; 27+ messages in thread
From: yuhang wang @ 2013-07-04 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

Thanks for your reply.
I have added the kerneldoc into the patch below to explain the "DUAL"
and "QUAD" modes.
Hope for your suggestions.

Documentation/spi/spi-dual_quad |  102 +++++++++++++++++++++++++++++++++++++++
 drivers/mtd/devices/m25p80.c    |    2 +
 drivers/spi/spi.c               |    2 +
 include/linux/spi/spi.h         |    8 +++
 4 files changed, 114 insertions(+)
 create mode 100644 Documentation/spi/spi-dual_quad

diff --git a/Documentation/spi/spi-dual_quad b/Documentation/spi/spi-dual_quad
new file mode 100644
index 0000000..06a2f9e
--- /dev/null
+++ b/Documentation/spi/spi-dual_quad
@@ -0,0 +1,102 @@
+spi-dual_quad: make spi support DUAL/QUAD
+============================================
+
+Description
+----------------------
+DUAL/QUAD means spi can transfer in 2bits/4bits at the same time.
+These spi controllers provide 8 data lines(4-tx and 4-rx). User can
+choose tranfer mode(SINGLE/DUAL/QUAD) by setting the certain register.
+Though SPI is a serial interface, some spi controllers can support
+transmitting and receiving in DUAL and QUAD modes aimed to improve
+the performance. Also as spi slave lots of flashes do support this attribute,
+such as serial-norflash in spansion company.
+
+Serial-flash such as s25fl129p in spansion company.
+In common way, the flash has two data pins(IO0,IO1) supporting SINGLE/DUAL.
+The flash also can work in QUAD mode, there are still other two
pins(HOLD,W#)which
+in other usage will be regarded as data pins.
+
+The members added below is used to provide the transfer information from slave
+to master. Thus spi controller driver can distinguish the transfer mode(SINGLE
+/DUAL/QUAD) and set the certain controlling register.
+
+
+Members added
+----------------------
+struct spi_device {
++       u8     rx_bitwidth;
++       u8     tx_bitwidth;
+}
+
+struct spi_transfer {
++       u8     bitwidth;
++#define        SPI_BITWIDTH_SINGLE     0x01; /* 1bit transfer */
++#define        SPI_BITWIDTH_DUAL       0x02; /* 2bits transfer */
++#define        SPI_BITWIDTH_QUAD       0x03; /* 4bits transfer */
+}
+
+struct spi_board_info {
++       u8     rx_bitwidth;
++       u8     tx_bitwidth;
+}
+
+
+How to use the added members
+----------------------
+
+DECLARE SLAVE DEVICES
+
+Normally your arch/.../mach-*/board-*.c files would provide a small table
+listing the SPI devices on each board.  Details refered to "spi-summary".
+At the same time, if your slave device support DUAL/QUAD transfer, you can
+set as below:
+
+       static struct spi_board_info spi_board_info[] __initdata = {
+       {
+               .modalias       = "xxxxx",
+               .......
+               .chip_select    = 0,
+               .rx_bitwidth = SPI_BITWIDTH_DUAL,
+               .tx_bitwidth = SPI_BITWIDTH_QUAD,
+       },
+       };
+
+ORGANISE SPI PACKAGE
+
+When your slave is registered by:
+
+       spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+rx_bitwidth and tx_bitwidth members will be delivered into "struct spi_device".
+Thus the flash driver can notice the tranfer mode that user has appointed.
+Flash driver receives the data from the uplayer and organise the spi_transfer
+package as below:
+
+       ......
+       struct spi_transfer t[2];
+       struct spi_message m;
+       spi_message_init(&m);
+       memset(t, 0, (sizeof t));
+       ......
+       t[0].rx_buf = buf;
+       t[0].len = len;
+       t[0].bitwidth = spi->rx_bitwidth/spi->tx_bitwidth;
+       spi_message_add_tail(&t[0], &m);
+       ......
+       spi_sync(spi, &m);
+       ......
+
+finally, spi controller driver will deal with the spi_tranfer package.
+Controller driver will pick the bitwidth member out due to which set
the transfer
+mode register.
+
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 5b6b072..1411678 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -354,6 +354,7 @@ static int m25p80_read(struct mtd_info *mtd,
loff_t from, size_t len,

        t[1].rx_buf = buf;
        t[1].len = len;
+       t[1].bitwidth = flash->spi->rx_bitwidth;
        spi_message_add_tail(&t[1], &m);

        mutex_lock(&flash->lock);
@@ -409,6 +410,7 @@ static int m25p80_write(struct mtd_info *mtd,
loff_t to, size_t len,
        spi_message_add_tail(&t[0], &m);

        t[1].tx_buf = buf;
+       t[1].bitwidth = flash->spi->tx_bitwidth;
        spi_message_add_tail(&t[1], &m);

        mutex_lock(&flash->lock);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 004b10f..cd99022 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -452,6 +452,8 @@ struct spi_device *spi_new_device(struct spi_master *master,
        proxy->irq = chip->irq;
        strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias));
        proxy->dev.platform_data = (void *) chip->platform_data;
+       proxy->rx_bitwidth = chip->rx_bitwidth;
+       proxy->tx_bitwidth = chip->tx_bitwidth;
        proxy->controller_data = chip->controller_data;
        proxy->controller_state = NULL;

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 38c2b92..ddcf308 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -93,6 +93,8 @@ struct spi_device {
        void                    *controller_data;
        char                    modalias[SPI_NAME_SIZE];
        int                     cs_gpio;        /* chip select gpio */
+       u8                      rx_bitwidth;
+       u8                      tx_bitwidth;

        /*
         * likely need more hooks for more protocol options affecting how
@@ -511,6 +513,10 @@ struct spi_transfer {
        dma_addr_t      rx_dma;

        unsigned        cs_change:1;
+       u8              bitwidth;
+#define        SPI_BITWIDTH_SINGLE     0x01; /* 1bit transfer */
+#define        SPI_BITWIDTH_DUAL       0x02; /* 2bits transfer */
+#define        SPI_BITWIDTH_QUAD       0x03; /* 4bits transfer */
        u8              bits_per_word;
        u16             delay_usecs;
        u32             speed_hz;
@@ -859,6 +865,8 @@ struct spi_board_info {
         * where the default of SPI_CS_HIGH = 0 is wrong.
         */
        u8              mode;
+       u8              rx_bitwidth;
+       u8              tx_bitwidth;

        /* ... may need additional spi_device chip config data here.
         * avoid stuff protocol drivers can set; but include stuff

--
1.7.9.5

Best regards

^ permalink raw reply related	[flat|nested] 27+ messages in thread
* SPI : DUAL/QUAD support
@ 2013-07-04  7:07 王宇航
  2013-07-04  9:00 ` Mark Brown
  0 siblings, 1 reply; 27+ messages in thread
From: 王宇航 @ 2013-07-04  7:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

Now some SPI controllers and Slave Devices have supported
DUAL and QUAD transfer mode. But SPI controller driver in kernel
has no member to deliver this information from Slave to Master.
So in my opinion, adding transfer mode members to deal with the problem.

In my SPI system, slave device is a Nor-Flash chip(s25fl129p) which
use m25p80 driver. My patch below aims to make spi controller know
the way that the slave want.

Firstly user provides the SPI slave information into spi_board_info,
including tx_bitwidth and rx_bitwidth. When the SPI slave is registered,
information in spi_board_info is delivered to spi_device. Then SPI slave
driver will add the transfer mode information into the spi_tranfer package
and send it out to SPI controller driver. SPI controller driver will
analyse the transfer package and set the certain transfer mode to
its register.

This patch do not support device tree....


Signed-off-by: wangyuhang <wangyuhang2014@gmail.com>
---
 drivers/mtd/devices/m25p80.c |    2 ++
 drivers/spi/spi.c            |    2 ++
 include/linux/spi/spi.h      |    8 ++++++++
 3 files changed, 12 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 5b6b072..1411678 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -354,6 +354,7 @@ static int m25p80_read(struct mtd_info *mtd,
loff_t from, size_t len,

        t[1].rx_buf = buf;
        t[1].len = len;
+       t[1].bitwidth = flash->spi->rx_bitwidth;
        spi_message_add_tail(&t[1], &m);

        mutex_lock(&flash->lock);
@@ -409,6 +410,7 @@ static int m25p80_write(struct mtd_info *mtd,
loff_t to, size_t len,
        spi_message_add_tail(&t[0], &m);

        t[1].tx_buf = buf;
+       t[1].bitwidth = flash->spi->tx_bitwidth;
        spi_message_add_tail(&t[1], &m);

        mutex_lock(&flash->lock);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 004b10f..cd99022 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -452,6 +452,8 @@ struct spi_device *spi_new_device(struct spi_master *master,
        proxy->irq = chip->irq;
        strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias));
        proxy->dev.platform_data = (void *) chip->platform_data;
+       proxy->rx_bitwidth = chip->rx_bitwidth;
+       proxy->tx_bitwidth = chip->tx_bitwidth;
        proxy->controller_data = chip->controller_data;
        proxy->controller_state = NULL;

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 38c2b92..ddcf308 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -93,6 +93,8 @@ struct spi_device {
        void                    *controller_data;
        char                    modalias[SPI_NAME_SIZE];
        int                     cs_gpio;        /* chip select gpio */
+       u8                      rx_bitwidth;
+       u8                      tx_bitwidth;

        /*
         * likely need more hooks for more protocol options affecting how
@@ -511,6 +513,10 @@ struct spi_transfer {
        dma_addr_t      rx_dma;

        unsigned        cs_change:1;
+       u8              bitwidth;
+#define        SPI_BITWIDTH_SINGLE     0x01; /* 1bit transfer */
+#define        SPI_BITWIDTH_DUAL       0x02; /* 2bits transfer */
+#define        SPI_BITWIDTH_QUAD       0x03; /* 4bits transfer */
        u8              bits_per_word;
        u16             delay_usecs;
        u32             speed_hz;
@@ -859,6 +865,8 @@ struct spi_board_info {
         * where the default of SPI_CS_HIGH = 0 is wrong.
         */
        u8              mode;
+       u8              rx_bitwidth;
+       u8              tx_bitwidth;

        /* ... may need additional spi_device chip config data here.
         * avoid stuff protocol drivers can set; but include stuff
--
1.7.9.5

Best regards
Jay

^ permalink raw reply related	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2013-07-05 15:41 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-04 11:36 SPI: DUAL/QUAD support yuhang wang
2013-07-04 13:00 ` Johannes Stezenbach
2013-07-04 14:58   ` Thomas.Betker at rohde-schwarz.com
2013-07-04 15:49     ` Mark Brown
2013-07-04 16:04       ` Thomas.Betker at rohde-schwarz.com
2013-07-05  6:25         ` yuhang wang
2013-07-05  6:45           ` Gupta, Pekon
2013-07-05  7:35             ` Johannes Stezenbach
2013-07-05  7:41               ` Sourav Poddar
2013-07-05  8:04               ` Gupta, Pekon
2013-07-05  7:40           ` Sourav Poddar
2013-07-05  8:48             ` yuhang wang
2013-07-05  8:55               ` Sourav Poddar
2013-07-05  9:07                 ` yuhang wang
2013-07-05  9:08                   ` Sourav Poddar
2013-07-05  9:17                     ` yuhang wang
2013-07-05  9:27                       ` Sourav Poddar
2013-07-05 10:24                         ` yuhang wang
2013-07-05 14:34                           ` Johannes Stezenbach
2013-07-05 15:41                             ` yuhang wang
2013-07-04 14:36 ` Mark Brown
2013-07-04 18:06   ` Johannes Stezenbach
2013-07-04 19:12     ` Mark Brown
2013-07-05  9:41       ` yuhang wang
2013-07-05 10:12         ` Mark Brown
  -- strict thread matches above, loose matches on Subject: below --
2013-07-04  7:07 SPI : " 王宇航
2013-07-04  9:00 ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).