return t->len - count;
}
-int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
-{
- struct spi_bitbang_cs *cs = spi->controller_state;
- u8 bits_per_word;
- u32 hz;
-
- if (t) {
- bits_per_word = t->bits_per_word;
- hz = t->speed_hz;
- } else {
- bits_per_word = 0;
- hz = 0;
- }
-
- /* spi_transfer level calls that work per-word */
- if (!bits_per_word)
- bits_per_word = spi->bits_per_word;
- if (bits_per_word <= 8)
- cs->txrx_bufs = bitbang_txrx_8;
- else if (bits_per_word <= 16)
- cs->txrx_bufs = bitbang_txrx_16;
- else if (bits_per_word <= 32)
- cs->txrx_bufs = bitbang_txrx_32;
- else
- return -EINVAL;
-
- /* nsecs = (clock period)/2 */
- if (!hz)
- hz = spi->max_speed_hz;
- if (hz) {
- cs->nsecs = (1000000000/2) / hz;
- if (cs->nsecs > (MAX_UDELAY_MS * 1000 * 1000))
- return -EINVAL;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(spi_bitbang_setup_transfer);
-
/**
* spi_bitbang_setup - default setup for per-word I/O loops
*/
{
struct spi_bitbang_cs *cs = spi->controller_state;
struct spi_bitbang *bitbang;
- int retval;
- bitbang = spi_master_get_devdata(spi->master);
-
- /* REVISIT: some systems will want to support devices using lsb-first
- * bit encodings on the wire. In pure software that would be trivial,
- * just bitbang_txrx_le_cphaX() routines shifting the other way, and
- * some hardware controllers also have this support.
- */
- if ((spi->mode & SPI_LSB_FIRST) != 0)
+ if (!spi->max_speed_hz)
return -EINVAL;
if (!cs) {
return -ENOMEM;
spi->controller_state = cs;
}
+ bitbang = spi_master_get_devdata(spi->master);
if (!spi->bits_per_word)
spi->bits_per_word = 8;
+ /* spi_transfer level calls that work per-word */
+ if (spi->bits_per_word <= 8)
+ cs->txrx_bufs = bitbang_txrx_8;
+ else if (spi->bits_per_word <= 16)
+ cs->txrx_bufs = bitbang_txrx_16;
+ else if (spi->bits_per_word <= 32)
+ cs->txrx_bufs = bitbang_txrx_32;
+ else
+ return -EINVAL;
+
/* per-word shift register access, in hardware or bitbanging */
cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)];
if (!cs->txrx_word)
return -EINVAL;
- retval = spi_bitbang_setup_transfer(spi, NULL);
- if (retval < 0)
- return retval;
+ /* nsecs = (clock period)/2 */
+ cs->nsecs = (1000000000/2) / (spi->max_speed_hz);
+ if (cs->nsecs > MAX_UDELAY_MS * 1000)
+ return -EINVAL;
- dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n",
+ dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
__FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA),
spi->bits_per_word, 2 * cs->nsecs);
unsigned tmp;
unsigned cs_change;
int status;
- int (*setup_transfer)(struct spi_device *,
- struct spi_transfer *);
m = container_of(bitbang->queue.next, struct spi_message,
queue);
tmp = 0;
cs_change = 1;
status = 0;
- setup_transfer = NULL;
list_for_each_entry (t, &m->transfers, transfer_list) {
if (bitbang->shutdown) {
break;
}
- /* override or restore speed and wordsize */
- if (t->speed_hz || t->bits_per_word) {
- setup_transfer = bitbang->setup_transfer;
- if (!setup_transfer) {
- status = -ENOPROTOOPT;
- break;
- }
- }
- if (setup_transfer) {
- status = setup_transfer(spi, t);
- if (status < 0)
- break;
- }
-
/* set up default clock polarity, and activate chip;
* this implicitly updates clock and spi modes as
* previously recorded for this device via setup().
m->status = status;
m->complete(m->context);
- /* restore speed and wordsize */
- if (setup_transfer)
- setup_transfer(spi, NULL);
-
/* normally deactivate chipselect ... unless no error and
* cs_change has hinted that the next message will probably
* be for this chip too.
{
struct spi_bitbang *bitbang;
unsigned long flags;
- int status = 0;
m->actual_length = 0;
m->status = -EINPROGRESS;
return -ESHUTDOWN;
spin_lock_irqsave(&bitbang->lock, flags);
- if (!spi->max_speed_hz)
- status = -ENETDOWN;
- else {
- list_add_tail(&m->queue, &bitbang->queue);
- queue_work(bitbang->workqueue, &bitbang->work);
- }
+ list_add_tail(&m->queue, &bitbang->queue);
+ queue_work(bitbang->workqueue, &bitbang->work);
spin_unlock_irqrestore(&bitbang->lock, flags);
- return status;
+ return 0;
}
EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
bitbang->use_dma = 0;
bitbang->txrx_bufs = spi_bitbang_bufs;
if (!bitbang->master->setup) {
- if (!bitbang->setup_transfer)
- bitbang->setup_transfer =
- spi_bitbang_setup_transfer;
bitbang->master->setup = spi_bitbang_setup;
bitbang->master->cleanup = spi_bitbang_cleanup;
}