Re: How to extract opcode, addr, dummy and buffer in transfer_one_message()?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Stefan,

On Thu, Jun 11, 2020 at 11:39 PM Stefan Schaeckeler <schaecsn@xxxxxxx> 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@xxxxxxxxxxxxxx

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



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux