libertas SPI Interface and the GPIO / chipselect issue

Sebastian Andrzej Siewior bigeasy at linutronix.de
Fri May 22 10:44:18 EDT 2009


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?

Sebastian



More information about the libertas-dev mailing list