diff options
author | Bryan Wu <bryan.wu@analog.com> | 2007-12-05 02:45:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-05 12:21:20 -0500 |
commit | 092e1fdaf35126475aef0dc70f4a2ce4f2f43052 (patch) | |
tree | 260533dc1aa4fb1e448ae3cc29c30d92c6363efb /drivers | |
parent | 003d922618150eaab53936f57ba8a61f2b601486 (diff) |
Blackfin SPI driver: reconfigure speed_hz and bits_per_word in each spi transfer
- reconfigure SPI baud from speed_hz of each spi transfer
- according to spi_transfer.bits_per_word to reprogram register and setup
correct SPI operation handlers
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/spi_bfin5xx.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index d6e9812538c4..22697b812205 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -234,10 +234,8 @@ static int restore_state(struct driver_data *drv_data) | |||
234 | dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n"); | 234 | dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n"); |
235 | 235 | ||
236 | /* Load the registers */ | 236 | /* Load the registers */ |
237 | write_BAUD(drv_data, chip->baud); | ||
238 | chip->ctl_reg &= (~BIT_CTL_TIMOD); | ||
239 | chip->ctl_reg |= (chip->width << 8); | ||
240 | write_CTRL(drv_data, chip->ctl_reg); | 237 | write_CTRL(drv_data, chip->ctl_reg); |
238 | write_BAUD(drv_data, chip->baud); | ||
241 | 239 | ||
242 | bfin_spi_enable(drv_data); | 240 | bfin_spi_enable(drv_data); |
243 | cs_active(drv_data, chip); | 241 | cs_active(drv_data, chip); |
@@ -679,6 +677,7 @@ static void pump_transfers(unsigned long data) | |||
679 | message = drv_data->cur_msg; | 677 | message = drv_data->cur_msg; |
680 | transfer = drv_data->cur_transfer; | 678 | transfer = drv_data->cur_transfer; |
681 | chip = drv_data->cur_chip; | 679 | chip = drv_data->cur_chip; |
680 | |||
682 | /* | 681 | /* |
683 | * if msg is error or done, report it back using complete() callback | 682 | * if msg is error or done, report it back using complete() callback |
684 | */ | 683 | */ |
@@ -736,15 +735,48 @@ static void pump_transfers(unsigned long data) | |||
736 | drv_data->len_in_bytes = transfer->len; | 735 | drv_data->len_in_bytes = transfer->len; |
737 | drv_data->cs_change = transfer->cs_change; | 736 | drv_data->cs_change = transfer->cs_change; |
738 | 737 | ||
739 | width = chip->width; | 738 | /* Bits per word setup */ |
739 | switch (transfer->bits_per_word) { | ||
740 | case 8: | ||
741 | drv_data->n_bytes = 1; | ||
742 | width = CFG_SPI_WORDSIZE8; | ||
743 | drv_data->read = chip->cs_change_per_word ? | ||
744 | u8_cs_chg_reader : u8_reader; | ||
745 | drv_data->write = chip->cs_change_per_word ? | ||
746 | u8_cs_chg_writer : u8_writer; | ||
747 | drv_data->duplex = chip->cs_change_per_word ? | ||
748 | u8_cs_chg_duplex : u8_duplex; | ||
749 | break; | ||
750 | |||
751 | case 16: | ||
752 | drv_data->n_bytes = 2; | ||
753 | width = CFG_SPI_WORDSIZE16; | ||
754 | drv_data->read = chip->cs_change_per_word ? | ||
755 | u16_cs_chg_reader : u16_reader; | ||
756 | drv_data->write = chip->cs_change_per_word ? | ||
757 | u16_cs_chg_writer : u16_writer; | ||
758 | drv_data->duplex = chip->cs_change_per_word ? | ||
759 | u16_cs_chg_duplex : u16_duplex; | ||
760 | break; | ||
761 | |||
762 | default: | ||
763 | /* No change, the same as default setting */ | ||
764 | drv_data->n_bytes = chip->n_bytes; | ||
765 | width = chip->width; | ||
766 | drv_data->write = drv_data->tx ? chip->write : null_writer; | ||
767 | drv_data->read = drv_data->rx ? chip->read : null_reader; | ||
768 | drv_data->duplex = chip->duplex ? chip->duplex : null_writer; | ||
769 | break; | ||
770 | } | ||
771 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); | ||
772 | cr |= (width << 8); | ||
773 | write_CTRL(drv_data, cr); | ||
774 | |||
740 | if (width == CFG_SPI_WORDSIZE16) { | 775 | if (width == CFG_SPI_WORDSIZE16) { |
741 | drv_data->len = (transfer->len) >> 1; | 776 | drv_data->len = (transfer->len) >> 1; |
742 | } else { | 777 | } else { |
743 | drv_data->len = transfer->len; | 778 | drv_data->len = transfer->len; |
744 | } | 779 | } |
745 | drv_data->write = drv_data->tx ? chip->write : null_writer; | ||
746 | drv_data->read = drv_data->rx ? chip->read : null_reader; | ||
747 | drv_data->duplex = chip->duplex ? chip->duplex : null_writer; | ||
748 | dev_dbg(&drv_data->pdev->dev, "transfer: ", | 780 | dev_dbg(&drv_data->pdev->dev, "transfer: ", |
749 | "drv_data->write is %p, chip->write is %p, null_wr is %p\n", | 781 | "drv_data->write is %p, chip->write is %p, null_wr is %p\n", |
750 | drv_data->write, chip->write, null_writer); | 782 | drv_data->write, chip->write, null_writer); |
@@ -753,6 +785,12 @@ static void pump_transfers(unsigned long data) | |||
753 | message->state = RUNNING_STATE; | 785 | message->state = RUNNING_STATE; |
754 | dma_config = 0; | 786 | dma_config = 0; |
755 | 787 | ||
788 | /* Speed setup (surely valid because already checked) */ | ||
789 | if (transfer->speed_hz) | ||
790 | write_BAUD(drv_data, hz_to_spi_baud(transfer->speed_hz)); | ||
791 | else | ||
792 | write_BAUD(drv_data, chip->baud); | ||
793 | |||
756 | write_STAT(drv_data, BIT_STAT_CLR); | 794 | write_STAT(drv_data, BIT_STAT_CLR); |
757 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); | 795 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); |
758 | cs_active(drv_data, chip); | 796 | cs_active(drv_data, chip); |