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(®_trans, 0, sizeof(reg_trans));
| memset(&data_trans, 0, sizeof(data_trans));
|
| reg_trans.tx_buf = ®_out;
| reg_trans.len = sizeof(u16);
|
| data_trans.tx_buf = buf;
| data_trans.len = len;
|
| spi_message_add_tail(®_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 = ®_out;
| reg_trans.len = sizeof(u16);
| spi_message_add_tail(®_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