X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fspi%2Fspi_bitbang.c;fp=drivers%2Fspi%2Fspi_bitbang.c;h=f037e5593269e8a79f700e7acf917919e0b13762;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=a23862ef72b26cac0685cc22963d321e0919039c;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index a23862ef7..f037e5593 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include @@ -137,45 +138,6 @@ static unsigned bitbang_txrx_32( 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 */ @@ -183,16 +145,8 @@ int spi_bitbang_setup(struct spi_device *spi) { 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) { @@ -201,20 +155,32 @@ int spi_bitbang_setup(struct spi_device *spi) 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); @@ -280,8 +246,6 @@ static void bitbang_work(void *_bitbang) 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); @@ -298,7 +262,6 @@ static void bitbang_work(void *_bitbang) tmp = 0; cs_change = 1; status = 0; - setup_transfer = NULL; list_for_each_entry (t, &m->transfers, transfer_list) { if (bitbang->shutdown) { @@ -306,20 +269,6 @@ static void bitbang_work(void *_bitbang) 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(). @@ -376,10 +325,6 @@ static void bitbang_work(void *_bitbang) 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. @@ -403,7 +348,6 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) { struct spi_bitbang *bitbang; unsigned long flags; - int status = 0; m->actual_length = 0; m->status = -EINPROGRESS; @@ -413,15 +357,11 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) 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); @@ -466,9 +406,6 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) 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; }