Hello, I have a question regarding the SPI spi_write_then_read function. 2011/6/20 Hubert Feurstein > This commit adds the following spi transfer functions: > - spi_write > - spi_read > - spi_write_then_read > - spi_w8r8 > > The code has been ported from the linux kernel. > > Signed-off-by: Hubert Feurstein > --- > drivers/spi/spi.c | 41 +++++++++++++++++++++++++++++ > include/spi/spi.h | 74 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 115 insertions(+), 0 deletions(-) > > diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c > index 588c263..6456897 100644 > --- a/drivers/spi/spi.c > +++ b/drivers/spi/spi.c > @@ -195,3 +195,44 @@ int spi_sync(struct spi_device *spi, struct > spi_message *message) > return spi->master->transfer(spi, message); > } > > +/** > + * spi_write_then_read - SPI synchronous write followed by read > + * @spi: device with which data will be exchanged > + * @txbuf: data to be written > + * @n_tx: size of txbuf, in bytes > + * @rxbuf: buffer into which data will be read > + * @n_rx: size of rxbuf, in bytes > + * Context: can sleep > + * > + * This performs a half duplex MicroWire style transaction with the > + * device, sending txbuf and then reading rxbuf. The return value > + * is zero for success, else a negative errno status code. > + * This call may only be used from a context that may sleep. > + */ > +int spi_write_then_read(struct spi_device *spi, > + const void *txbuf, unsigned n_tx, > Could you explain me why const is used here ? > + void *rxbuf, unsigned n_rx) > +{ > + int status; > + struct spi_message message; > + struct spi_transfer x[2]; > + > + spi_message_init(&message); > + memset(x, 0, sizeof x); > Here we set everything to zero, including rx/tx buffer pointers. > + if (n_tx) { > + x[0].len = n_tx; > + spi_message_add_tail(&x[0], &message); > + } > + if (n_rx) { > + x[1].len = n_rx; > + spi_message_add_tail(&x[1], &message); > + } > + > + x[0].tx_buf = txbuf; > + x[1].rx_buf = rxbuf; > We still have x[0].rx_buf = 0 and x[1].tx_buf = 0 > + > + /* do the i/o */ > + status = spi_sync(spi, &message); > Then we call spi_sync then master->transfer. In this last function we have: list_for_each_entry (t, &mesg->transfers, transfer_list) { const u32 *txbuf = t->tx_buf; <--- point to zero when x[1] right ????? u32 *rxbuf = t->rx_buf; <--- point to zero when x[0] right ????? int i = 0; while(i < t->len >> 2) { rxbuf[i] = imx->xchg_single(imx, txbuf[i]); i++; } } What am I missing ??? > + return status; > +} > +EXPORT_SYMBOL(spi_write_then_read); > diff --git a/include/spi/spi.h b/include/spi/spi.h > index c76f3b7..ac2013a 100644 > --- a/include/spi/spi.h > +++ b/include/spi/spi.h > @@ -349,6 +349,80 @@ static inline int spi_register_board_info(struct > spi_board_info const *info, > } > #endif > > +/** > + * spi_write - SPI synchronous write > + * @spi: device to which data will be written > + * @buf: data buffer > + * @len: data buffer size > + * Context: can sleep > + * > + * This writes the buffer and returns zero or a negative error code. > + * Callable only from contexts that can sleep. > + */ > +static inline int > +spi_write(struct spi_device *spi, const void *buf, size_t len) > +{ > + struct spi_transfer t = { > + .tx_buf = buf, > + .len = len, > + }; > + struct spi_message m; > + > + spi_message_init(&m); > + spi_message_add_tail(&t, &m); > + return spi_sync(spi, &m); > +} > + > +/** > + * spi_read - SPI synchronous read > + * @spi: device from which data will be read > + * @buf: data buffer > + * @len: data buffer size > + * Context: can sleep > + * > + * This reads the buffer and returns zero or a negative error code. > + * Callable only from contexts that can sleep. > + */ > +static inline int > +spi_read(struct spi_device *spi, void *buf, size_t len) > +{ > + struct spi_transfer t = { > + .rx_buf = buf, > + .len = len, > + }; > + struct spi_message m; > + > + spi_message_init(&m); > + spi_message_add_tail(&t, &m); > + return spi_sync(spi, &m); > +} > + > +/* this copies txbuf and rxbuf data; for small transfers only! */ > +extern int spi_write_then_read(struct spi_device *spi, > + const void *txbuf, unsigned n_tx, > + void *rxbuf, unsigned n_rx); > + > +/** > + * spi_w8r8 - SPI synchronous 8 bit write followed by 8 bit read > + * @spi: device with which data will be exchanged > + * @cmd: command to be written before data is read back > + * Context: can sleep > + * > + * This returns the (unsigned) eight bit number returned by the > + * device, or else a negative error code. Callable only from > + * contexts that can sleep. > + */ > +static inline ssize_t spi_w8r8(struct spi_device *spi, u8 cmd) > +{ > + ssize_t status; > + u8 result; > + > + status = spi_write_then_read(spi, &cmd, 1, &result, 1); > + > + /* return negative errno or unsigned value */ > + return (status < 0) ? status : result; > +} > + > #endif /* DOXYGEN_SHOULD_SKIP_THIS */ > > #endif /* __INCLUDE_SPI_H */ > -- > 1.7.4.1 > > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox Franck.