* How to extract opcode, addr, dummy and buffer in transfer_one_message()?
@ 2020-06-11 21:37 Stefan Schaeckeler
2020-06-12 7:27 ` Geert Uytterhoeven
0 siblings, 1 reply; 2+ messages in thread
From: Stefan Schaeckeler @ 2020-06-11 21:37 UTC (permalink / raw)
To: linux-spi
Hello linux-spi,
I can implement mem_ops() a/o transfer_one_message().
spi-mem.c:spi_mem_exec_op() will directly pass op to mem_ops->exec_op(). There
I can easily extract opcode, addr, dummy and data buffer. It would probably
look roughly like
exec_op(struct spi_mem *mem, const struct spi_mem_op *op){
dummy = addr = -1;
opcode = op->cmd.opcode;
addrlen=op->addr.nbytes;
if (addrlen)
addr = op->addr.val;
if (op->dummy.nbytes)
dummy = QSPI_DUMMY_CYCLE;
len=op->data.nbytes;
if (len)
if (op->data.dir == SPI_MEM_DATA_IN) {
rxbuf = op->data.buf.in;
is_wr = false;
} else {
txbuf = op->data.buf.out;
is_wr = true;
}
}
That's great. What about transfer_one_message()?
spi-mem.c:spi_mem_exec_op() builds a message consisting of multiple transfers.
If there is no address, dummy or data buffer, then they will not be included in
the transfer array as transfers are created like this
/* op is the first transfer */
tmpbuf[0] = op->cmd.opcode;
xfers[xferpos].tx_buf = tmpbuf;
...
if (op->addr.nbytes) {
/* add addr transfer */
...
}
if (op->dummy.nbytes) {
/* add dummy transfer */
...
}
if (op->data.nbytes) {
/* add data transfer */
...
}
These transfers are then passed as a message consisting of 1 to 4 transfers to
transfer_one_message().
In transfer_one_message(), the first transfer is the opcode. How do I now what
the next transfers represent? Like in the exec_op() example above, I would like
to create and initialize my variables opcode, addr, dummy and read or write
buffer.
Related question: what are the disadvantages of always using mem_ops() and
never transfer_one_message()?
Thanks,
Stefan
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: How to extract opcode, addr, dummy and buffer in transfer_one_message()?
2020-06-11 21:37 How to extract opcode, addr, dummy and buffer in transfer_one_message()? Stefan Schaeckeler
@ 2020-06-12 7:27 ` Geert Uytterhoeven
0 siblings, 0 replies; 2+ messages in thread
From: Geert Uytterhoeven @ 2020-06-12 7:27 UTC (permalink / raw)
To: schaecsn; +Cc: linux-spi
Hi Stefan,
On Thu, Jun 11, 2020 at 11:39 PM Stefan Schaeckeler <schaecsn@gmx.net> wrote:
> I can implement mem_ops() a/o transfer_one_message().
>
> spi-mem.c:spi_mem_exec_op() will directly pass op to mem_ops->exec_op(). There
> I can easily extract opcode, addr, dummy and data buffer. It would probably
> look roughly like
>
> exec_op(struct spi_mem *mem, const struct spi_mem_op *op){
> dummy = addr = -1;
>
> opcode = op->cmd.opcode;
>
> addrlen=op->addr.nbytes;
> if (addrlen)
> addr = op->addr.val;
>
> if (op->dummy.nbytes)
> dummy = QSPI_DUMMY_CYCLE;
>
> len=op->data.nbytes;
> if (len)
> if (op->data.dir == SPI_MEM_DATA_IN) {
> rxbuf = op->data.buf.in;
> is_wr = false;
> } else {
> txbuf = op->data.buf.out;
> is_wr = true;
> }
> }
>
> That's great. What about transfer_one_message()?
>
> spi-mem.c:spi_mem_exec_op() builds a message consisting of multiple transfers.
> If there is no address, dummy or data buffer, then they will not be included in
> the transfer array as transfers are created like this
>
> /* op is the first transfer */
> tmpbuf[0] = op->cmd.opcode;
> xfers[xferpos].tx_buf = tmpbuf;
> ...
>
> if (op->addr.nbytes) {
> /* add addr transfer */
> ...
> }
>
> if (op->dummy.nbytes) {
> /* add dummy transfer */
> ...
> }
>
> if (op->data.nbytes) {
> /* add data transfer */
> ...
> }
>
> These transfers are then passed as a message consisting of 1 to 4 transfers to
> transfer_one_message().
>
> In transfer_one_message(), the first transfer is the opcode. How do I now what
> the next transfers represent? Like in the exec_op() example above, I would like
> to create and initialize my variables opcode, addr, dummy and read or write
> buffer.
The meaning of the transfers depends on the protocol used to talk to
the SPI slave.
The mem_ops() are intended for memory devices. transfer_one_message()
(and transfer_one()) are meant for communicating with generic SPI slaves.
> Related question: what are the disadvantages of always using mem_ops() and
> never transfer_one_message()?
If you do that, your driver cannot talk to SPI slaves that are not supported
by spi_mem, i.e. anything except memory devices.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-06-12 7:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-11 21:37 How to extract opcode, addr, dummy and buffer in transfer_one_message()? Stefan Schaeckeler
2020-06-12 7:27 ` Geert Uytterhoeven
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).