Hello, I have a question regarding the SPI spi_write_then_read function.<br><br><div class="gmail_quote">2011/6/20 Hubert Feurstein <span dir="ltr">&lt;<a href="mailto:h.feurstein@gmail.com">h.feurstein@gmail.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">This commit adds the following spi transfer functions:<br>
  - spi_write<br>
  - spi_read<br>
  - spi_write_then_read<br>
  - spi_w8r8<br>
<br>
The code has been ported from the linux kernel.<br>
<br>
Signed-off-by: Hubert Feurstein &lt;<a href="mailto:h.feurstein@gmail.com">h.feurstein@gmail.com</a>&gt;<br>
---<br>
 drivers/spi/spi.c |   41 +++++++++++++++++++++++++++++<br>
 include/spi/spi.h |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++++<br>
 2 files changed, 115 insertions(+), 0 deletions(-)<br>
<br>
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c<br>
index 588c263..6456897 100644<br>
--- a/drivers/spi/spi.c<br>
+++ b/drivers/spi/spi.c<br>
@@ -195,3 +195,44 @@ int spi_sync(struct spi_device *spi, struct spi_message *message)<br>
        return spi-&gt;master-&gt;transfer(spi, message);<br>
 }<br>
<br>
+/**<br>
+ * spi_write_then_read - SPI synchronous write followed by read<br>
+ * @spi: device with which data will be exchanged<br>
+ * @txbuf: data to be written<br>
+ * @n_tx: size of txbuf, in bytes<br>
+ * @rxbuf: buffer into which data will be read<br>
+ * @n_rx: size of rxbuf, in bytes<br>
+ * Context: can sleep<br>
+ *<br>
+ * This performs a half duplex MicroWire style transaction with the<br>
+ * device, sending txbuf and then reading rxbuf.  The return value<br>
+ * is zero for success, else a negative errno status code.<br>
+ * This call may only be used from a context that may sleep.<br>
+ */<br>
+int spi_write_then_read(struct spi_device *spi,<br>
+               const void *txbuf, unsigned n_tx,<br></blockquote><div><br></div><div>Could you explain me why const is used here ?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

+               void *rxbuf, unsigned n_rx)<br>
+{<br>
+       int                     status;<br>
+       struct spi_message      message;<br>
+       struct spi_transfer     x[2];<br>
+<br>
+       spi_message_init(&amp;message);<br>
+       memset(x, 0, sizeof x);<br></blockquote><div><br></div><div>Here we set everything to zero, including rx/tx buffer pointers.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

+       if (n_tx) {<br>
+               x[0].len = n_tx;<br>
+               spi_message_add_tail(&amp;x[0], &amp;message);<br>
+       }<br>
+       if (n_rx) {<br>
+               x[1].len = n_rx;<br>
+               spi_message_add_tail(&amp;x[1], &amp;message);<br>
+       }<br>
+<br>
+       x[0].tx_buf = txbuf;<br>
+       x[1].rx_buf = rxbuf;<br></blockquote><div><br></div><div>We still have x[0].rx_buf = 0 and x[1].tx_buf = 0</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

+<br>
+       /* do the i/o */<br>
+       status = spi_sync(spi, &amp;message);<br></blockquote><div><br></div><div>Then we call spi_sync then master-&gt;transfer. In this last function we have:</div><div><br></div><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><span class="Apple-tab-span" style="white-space:pre">        </span>list_for_each_entry (t, &amp;mesg-&gt;transfers, transfer_list) {</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><span class="Apple-tab-span" style="white-space:pre">                </span>const u32 *txbuf = t-&gt;tx_buf;  &lt;--- point to zero </font><span class="Apple-style-span" style="font-family: &#39;courier new&#39;, monospace; ">when x[1] </span><span class="Apple-style-span" style="font-family: &#39;courier new&#39;, monospace; ">right ?????</span></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><span class="Apple-tab-span" style="white-space:pre">                </span>u32 *rxbuf = t-&gt;rx_buf;        &lt;--- </font><span class="Apple-style-span" style="font-family: &#39;courier new&#39;, monospace; ">point to zero when </span><span class="Apple-style-span" style="font-family: &#39;courier new&#39;, monospace; ">x[0] </span><span class="Apple-style-span" style="font-family: &#39;courier new&#39;, monospace; ">right ?????</span></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><span class="Apple-tab-span" style="white-space:pre">                </span>int i = 0;</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><span class="Apple-tab-span" style="white-space:pre">                </span>while(i &lt; t-&gt;len &gt;&gt; 2) {</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><span class="Apple-tab-span" style="white-space:pre">                        </span>rxbuf[i] = imx-&gt;xchg_single(imx, txbuf[i]);</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><span class="Apple-tab-span" style="white-space:pre">                        </span>i++;</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><span class="Apple-tab-span" style="white-space:pre">                </span>}</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div>
</div><div><br></div><div>What am I missing ???</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
+       return status;<br>
+}<br>
+EXPORT_SYMBOL(spi_write_then_read);<br>
diff --git a/include/spi/spi.h b/include/spi/spi.h<br>
index c76f3b7..ac2013a 100644<br>
--- a/include/spi/spi.h<br>
+++ b/include/spi/spi.h<br>
@@ -349,6 +349,80 @@ static inline int spi_register_board_info(struct spi_board_info const *info,<br>
 }<br>
 #endif<br>
<br>
+/**<br>
+ * spi_write - SPI synchronous write<br>
+ * @spi: device to which data will be written<br>
+ * @buf: data buffer<br>
+ * @len: data buffer size<br>
+ * Context: can sleep<br>
+ *<br>
+ * This writes the buffer and returns zero or a negative error code.<br>
+ * Callable only from contexts that can sleep.<br>
+ */<br>
+static inline int<br>
+spi_write(struct spi_device *spi, const void *buf, size_t len)<br>
+{<br>
+       struct spi_transfer     t = {<br>
+                       .tx_buf         = buf,<br>
+                       .len            = len,<br>
+               };<br>
+       struct spi_message      m;<br>
+<br>
+       spi_message_init(&amp;m);<br>
+       spi_message_add_tail(&amp;t, &amp;m);<br>
+       return spi_sync(spi, &amp;m);<br>
+}<br>
+<br>
+/**<br>
+ * spi_read - SPI synchronous read<br>
+ * @spi: device from which data will be read<br>
+ * @buf: data buffer<br>
+ * @len: data buffer size<br>
+ * Context: can sleep<br>
+ *<br>
+ * This reads the buffer and returns zero or a negative error code.<br>
+ * Callable only from contexts that can sleep.<br>
+ */<br>
+static inline int<br>
+spi_read(struct spi_device *spi, void *buf, size_t len)<br>
+{<br>
+       struct spi_transfer     t = {<br>
+                       .rx_buf         = buf,<br>
+                       .len            = len,<br>
+               };<br>
+       struct spi_message      m;<br>
+<br>
+       spi_message_init(&amp;m);<br>
+       spi_message_add_tail(&amp;t, &amp;m);<br>
+       return spi_sync(spi, &amp;m);<br>
+}<br>
+<br>
+/* this copies txbuf and rxbuf data; for small transfers only! */<br>
+extern int spi_write_then_read(struct spi_device *spi,<br>
+               const void *txbuf, unsigned n_tx,<br>
+               void *rxbuf, unsigned n_rx);<br>
+<br>
+/**<br>
+ * spi_w8r8 - SPI synchronous 8 bit write followed by 8 bit read<br>
+ * @spi: device with which data will be exchanged<br>
+ * @cmd: command to be written before data is read back<br>
+ * Context: can sleep<br>
+ *<br>
+ * This returns the (unsigned) eight bit number returned by the<br>
+ * device, or else a negative error code.  Callable only from<br>
+ * contexts that can sleep.<br>
+ */<br>
+static inline ssize_t spi_w8r8(struct spi_device *spi, u8 cmd)<br>
+{<br>
+       ssize_t                 status;<br>
+       u8                      result;<br>
+<br>
+       status = spi_write_then_read(spi, &amp;cmd, 1, &amp;result, 1);<br>
+<br>
+       /* return negative errno or unsigned value */<br>
+       return (status &lt; 0) ? status : result;<br>
+}<br>
+<br>
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */<br>
<br>
 #endif /* __INCLUDE_SPI_H */<br>
<font color="#888888">--<br>
1.7.4.1<br>
<br>
<br>
_______________________________________________<br>
barebox mailing list<br>
<a href="mailto:barebox@lists.infradead.org">barebox@lists.infradead.org</a><br>
<a href="http://lists.infradead.org/mailman/listinfo/barebox" target="_blank">http://lists.infradead.org/mailman/listinfo/barebox</a></font></blockquote><div><br></div><div><br></div><div>Franck. </div></div><br>