diff options
-rw-r--r-- | arch/blackfin/include/asm/bfin5xx_spi.h | 68 | ||||
-rw-r--r-- | drivers/spi/spi_bfin5xx.c | 40 |
2 files changed, 18 insertions, 90 deletions
diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h index 6f011dac378f..4223cf08ce83 100644 --- a/arch/blackfin/include/asm/bfin5xx_spi.h +++ b/arch/blackfin/include/asm/bfin5xx_spi.h | |||
@@ -11,18 +11,6 @@ | |||
11 | 11 | ||
12 | #define MIN_SPI_BAUD_VAL 2 | 12 | #define MIN_SPI_BAUD_VAL 2 |
13 | 13 | ||
14 | #define SPI_READ 0 | ||
15 | #define SPI_WRITE 1 | ||
16 | |||
17 | #define SPI_CTRL_OFF 0x0 | ||
18 | #define SPI_FLAG_OFF 0x4 | ||
19 | #define SPI_STAT_OFF 0x8 | ||
20 | #define SPI_TXBUFF_OFF 0xc | ||
21 | #define SPI_RXBUFF_OFF 0x10 | ||
22 | #define SPI_BAUD_OFF 0x14 | ||
23 | #define SPI_SHAW_OFF 0x18 | ||
24 | |||
25 | |||
26 | #define BIT_CTL_ENABLE 0x4000 | 14 | #define BIT_CTL_ENABLE 0x4000 |
27 | #define BIT_CTL_OPENDRAIN 0x2000 | 15 | #define BIT_CTL_OPENDRAIN 0x2000 |
28 | #define BIT_CTL_MASTER 0x1000 | 16 | #define BIT_CTL_MASTER 0x1000 |
@@ -53,62 +41,6 @@ | |||
53 | #define BIT_STU_SENDOVER 0x0001 | 41 | #define BIT_STU_SENDOVER 0x0001 |
54 | #define BIT_STU_RECVFULL 0x0020 | 42 | #define BIT_STU_RECVFULL 0x0020 |
55 | 43 | ||
56 | #define CFG_SPI_ENABLE 1 | ||
57 | #define CFG_SPI_DISABLE 0 | ||
58 | |||
59 | #define CFG_SPI_OUTENABLE 1 | ||
60 | #define CFG_SPI_OUTDISABLE 0 | ||
61 | |||
62 | #define CFG_SPI_ACTLOW 1 | ||
63 | #define CFG_SPI_ACTHIGH 0 | ||
64 | |||
65 | #define CFG_SPI_PHASESTART 1 | ||
66 | #define CFG_SPI_PHASEMID 0 | ||
67 | |||
68 | #define CFG_SPI_MASTER 1 | ||
69 | #define CFG_SPI_SLAVE 0 | ||
70 | |||
71 | #define CFG_SPI_SENELAST 0 | ||
72 | #define CFG_SPI_SENDZERO 1 | ||
73 | |||
74 | #define CFG_SPI_RCVFLUSH 1 | ||
75 | #define CFG_SPI_RCVDISCARD 0 | ||
76 | |||
77 | #define CFG_SPI_LSBFIRST 1 | ||
78 | #define CFG_SPI_MSBFIRST 0 | ||
79 | |||
80 | #define CFG_SPI_WORDSIZE16 1 | ||
81 | #define CFG_SPI_WORDSIZE8 0 | ||
82 | |||
83 | #define CFG_SPI_MISOENABLE 1 | ||
84 | #define CFG_SPI_MISODISABLE 0 | ||
85 | |||
86 | #define CFG_SPI_READ 0x00 | ||
87 | #define CFG_SPI_WRITE 0x01 | ||
88 | #define CFG_SPI_DMAREAD 0x02 | ||
89 | #define CFG_SPI_DMAWRITE 0x03 | ||
90 | |||
91 | #define CFG_SPI_CSCLEARALL 0 | ||
92 | #define CFG_SPI_CHIPSEL1 1 | ||
93 | #define CFG_SPI_CHIPSEL2 2 | ||
94 | #define CFG_SPI_CHIPSEL3 3 | ||
95 | #define CFG_SPI_CHIPSEL4 4 | ||
96 | #define CFG_SPI_CHIPSEL5 5 | ||
97 | #define CFG_SPI_CHIPSEL6 6 | ||
98 | #define CFG_SPI_CHIPSEL7 7 | ||
99 | |||
100 | #define CFG_SPI_CS1VALUE 1 | ||
101 | #define CFG_SPI_CS2VALUE 2 | ||
102 | #define CFG_SPI_CS3VALUE 3 | ||
103 | #define CFG_SPI_CS4VALUE 4 | ||
104 | #define CFG_SPI_CS5VALUE 5 | ||
105 | #define CFG_SPI_CS6VALUE 6 | ||
106 | #define CFG_SPI_CS7VALUE 7 | ||
107 | |||
108 | #define CMD_SPI_SET_BAUDRATE 2 | ||
109 | #define CMD_SPI_GET_SYSTEMCLOCK 25 | ||
110 | #define CMD_SPI_SET_WRITECONTINUOUS 26 | ||
111 | |||
112 | #define MAX_CTRL_CS 8 /* cs in spi controller */ | 44 | #define MAX_CTRL_CS 8 /* cs in spi controller */ |
113 | 45 | ||
114 | /* device.platform_data for SSP controller devices */ | 46 | /* device.platform_data for SSP controller devices */ |
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 376f2f09e34c..b3450b78cc50 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -560,8 +560,7 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
560 | struct spi_transfer *previous = NULL; | 560 | struct spi_transfer *previous = NULL; |
561 | struct slave_data *chip = NULL; | 561 | struct slave_data *chip = NULL; |
562 | unsigned int bits_per_word; | 562 | unsigned int bits_per_word; |
563 | u8 width; | 563 | u16 cr, cr_width, dma_width, dma_config; |
564 | u16 cr, dma_width, dma_config; | ||
565 | u32 tranf_success = 1; | 564 | u32 tranf_success = 1; |
566 | u8 full_duplex = 0; | 565 | u8 full_duplex = 0; |
567 | 566 | ||
@@ -642,22 +641,19 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
642 | bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; | 641 | bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; |
643 | if (bits_per_word == 8) { | 642 | if (bits_per_word == 8) { |
644 | drv_data->n_bytes = 1; | 643 | drv_data->n_bytes = 1; |
645 | width = CFG_SPI_WORDSIZE8; | 644 | drv_data->len = transfer->len; |
645 | cr_width = 0; | ||
646 | drv_data->ops = &bfin_transfer_ops_u8; | 646 | drv_data->ops = &bfin_transfer_ops_u8; |
647 | } else { | 647 | } else { |
648 | drv_data->n_bytes = 2; | 648 | drv_data->n_bytes = 2; |
649 | width = CFG_SPI_WORDSIZE16; | 649 | drv_data->len = (transfer->len) >> 1; |
650 | cr_width = BIT_CTL_WORDSIZE; | ||
650 | drv_data->ops = &bfin_transfer_ops_u16; | 651 | drv_data->ops = &bfin_transfer_ops_u16; |
651 | } | 652 | } |
652 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); | 653 | cr = read_CTRL(drv_data) & ~(BIT_CTL_TIMOD | BIT_CTL_WORDSIZE); |
653 | cr |= (width << 8); | 654 | cr |= cr_width; |
654 | write_CTRL(drv_data, cr); | 655 | write_CTRL(drv_data, cr); |
655 | 656 | ||
656 | if (width == CFG_SPI_WORDSIZE16) { | ||
657 | drv_data->len = (transfer->len) >> 1; | ||
658 | } else { | ||
659 | drv_data->len = transfer->len; | ||
660 | } | ||
661 | dev_dbg(&drv_data->pdev->dev, | 657 | dev_dbg(&drv_data->pdev->dev, |
662 | "transfer: drv_data->ops is %p, chip->ops is %p, u8_ops is %p\n", | 658 | "transfer: drv_data->ops is %p, chip->ops is %p, u8_ops is %p\n", |
663 | drv_data->ops, chip->ops, &bfin_transfer_ops_u8); | 659 | drv_data->ops, chip->ops, &bfin_transfer_ops_u8); |
@@ -672,13 +668,12 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
672 | write_BAUD(drv_data, chip->baud); | 668 | write_BAUD(drv_data, chip->baud); |
673 | 669 | ||
674 | write_STAT(drv_data, BIT_STAT_CLR); | 670 | write_STAT(drv_data, BIT_STAT_CLR); |
675 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); | ||
676 | if (drv_data->cs_change) | 671 | if (drv_data->cs_change) |
677 | bfin_spi_cs_active(drv_data, chip); | 672 | bfin_spi_cs_active(drv_data, chip); |
678 | 673 | ||
679 | dev_dbg(&drv_data->pdev->dev, | 674 | dev_dbg(&drv_data->pdev->dev, |
680 | "now pumping a transfer: width is %d, len is %d\n", | 675 | "now pumping a transfer: width is %d, len is %d\n", |
681 | width, transfer->len); | 676 | cr_width, transfer->len); |
682 | 677 | ||
683 | /* | 678 | /* |
684 | * Try to map dma buffer and do a dma transfer. If successful use, | 679 | * Try to map dma buffer and do a dma transfer. If successful use, |
@@ -697,7 +692,7 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
697 | /* config dma channel */ | 692 | /* config dma channel */ |
698 | dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n"); | 693 | dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n"); |
699 | set_dma_x_count(drv_data->dma_channel, drv_data->len); | 694 | set_dma_x_count(drv_data->dma_channel, drv_data->len); |
700 | if (width == CFG_SPI_WORDSIZE16) { | 695 | if (cr_width == BIT_CTL_WORDSIZE) { |
701 | set_dma_x_modify(drv_data->dma_channel, 2); | 696 | set_dma_x_modify(drv_data->dma_channel, 2); |
702 | dma_width = WDSIZE_16; | 697 | dma_width = WDSIZE_16; |
703 | } else { | 698 | } else { |
@@ -786,10 +781,16 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
786 | return; | 781 | return; |
787 | } | 782 | } |
788 | 783 | ||
784 | /* | ||
785 | * We always use SPI_WRITE mode (transfer starts with TDBR write). | ||
786 | * SPI_READ mode (transfer starts with RDBR read) seems to have | ||
787 | * problems with setting up the output value in TDBR prior to the | ||
788 | * start of the transfer. | ||
789 | */ | ||
790 | write_CTRL(drv_data, cr | BIT_CTL_TXMOD); | ||
791 | |||
789 | if (chip->pio_interrupt) { | 792 | if (chip->pio_interrupt) { |
790 | /* use write mode. spi irq should have been disabled */ | 793 | /* SPI irq should have been disabled by now */ |
791 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); | ||
792 | write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); | ||
793 | 794 | ||
794 | /* discard old RX data and clear RXS */ | 795 | /* discard old RX data and clear RXS */ |
795 | bfin_spi_dummy_read(drv_data); | 796 | bfin_spi_dummy_read(drv_data); |
@@ -813,11 +814,6 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
813 | /* IO mode */ | 814 | /* IO mode */ |
814 | dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n"); | 815 | dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n"); |
815 | 816 | ||
816 | /* we always use SPI_WRITE mode. SPI_READ mode | ||
817 | seems to have problems with setting up the | ||
818 | output value in TDBR prior to the transfer. */ | ||
819 | write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); | ||
820 | |||
821 | if (full_duplex) { | 817 | if (full_duplex) { |
822 | /* full duplex mode */ | 818 | /* full duplex mode */ |
823 | BUG_ON((drv_data->tx_end - drv_data->tx) != | 819 | BUG_ON((drv_data->tx_end - drv_data->tx) != |