aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/include/asm/bfin5xx_spi.h68
-rw-r--r--drivers/spi/spi_bfin5xx.c40
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) !=