libertas SPI Interface and the GPIO / chipselect issue

Andrey Yurovsky andrey at cozybit.com
Fri May 22 12:42:16 EDT 2009


On Fri, May 22, 2009 at 7:44 AM, Sebastian Andrzej Siewior
<bigeasy at linutronix.de> wrote:
> Hi Colin,
>
> in your spi communication you have something like:
>  - chipselect down
>  - spi msg 1 via spi_write()
>  - spi msg 2 via spi_write()
>  - chipselect up
>
> I do understand, that the chip requires having the chip select down for
> the entire transfer and you want to avoid, to copy the message into a
> temporary buffer.
> My chipselect is not a GPIO but in register space of my SPI controller
> so it will get very nasty to provide a GPIO interface
> What about the following sollution:
>
> |         spi_message_init(&m);
> |         memset(&reg_trans, 0, sizeof(reg_trans));
> |         memset(&data_trans, 0, sizeof(data_trans));
> |
> |         reg_trans.tx_buf = &reg_out;
> |         reg_trans.len = sizeof(u16);
> |
> |         data_trans.tx_buf = buf;
> |         data_trans.len = len;
> |
> |         spi_message_add_tail(&reg_trans, &m);
> |         spi_message_add_tail(&data_trans, &m);
> |
> |         return spi_sync(card->spi, &m);
>
> If I'm not mistaken, the chipselect has to remain active for the
> transfer of the whole message (which includes two transfers) unless
> spi_message->cs_change requests otherwise.
> This will also shorten your read routine a little, the main part:
> |        reg_trans.tx_buf = &reg_out;
> |        reg_trans.len = sizeof(u16);
> |        spi_message_add_tail(&reg_trans, &m);
> |
> |        delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay :
> |                                                card->spu_reg_delay;
> |        if (card->use_dummy_writes) {
> |                dummy_trans.len = delay / 8;
> |                spi_message_add_tail(&dummy_trans, &m);
> |        } else {
> |                reg_trans.delay_usecs = 10;
> |        }
> |
> |        data_trans.rx_buf = buf;
> |        data_trans.len = len;
> |        spi_message_add_tail(&data_trans, &m);
>
> Any comments on this?

Hi Sebastian.  We're indeed working on converting the transfers to
spi_async() for other reasons, but that's an interesting point.  For
GSPI we require "transaction"-style chip select, and if all
controllers can do that, we're fine, however many of the ones I've
seen toggle the chip select every X bytes, where X is the register
size (8, 16, or 32-bit) regardless of how the host sees it.

 -Andrey



More information about the libertas-dev mailing list