aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/atmel_spi.c
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2009-01-06 17:41:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 18:59:19 -0500
commit5ee36c989831ab720eee282521462cce0a3c4900 (patch)
treeae9e07d024bfa1d5f360aafc6401e3797350a7f5 /drivers/spi/atmel_spi.c
parent5bfa26ca1332780dfeeabafd7f169fc6fb48ba30 (diff)
spi: atmel_spi update chipselect handling
This solves several issues: * It fixes the wrong idle clock polarity issue in a cleaner and less expensive way. * It handles the AT32AP7000 errata "SPI Chip Select 0 BITS field overrides other Chip Selects". Other chips, e.g. AT91SAM9261, have similar issues. Currently, the AT91RM9200 code path is left alone. But it might be interesting to try the same technique on RM9200 using a different CSR register. [dbrownell@users.sourceforge.net: restore debug message for activation] Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/spi/atmel_spi.c')
-rw-r--r--drivers/spi/atmel_spi.c93
1 files changed, 67 insertions, 26 deletions
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index b4f7f1c286e1..5e39bac9c51b 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -51,6 +51,12 @@ struct atmel_spi {
51 dma_addr_t buffer_dma; 51 dma_addr_t buffer_dma;
52}; 52};
53 53
54/* Controller-specific per-slave state */
55struct atmel_spi_device {
56 unsigned int npcs_pin;
57 u32 csr;
58};
59
54#define BUFFER_SIZE PAGE_SIZE 60#define BUFFER_SIZE PAGE_SIZE
55#define INVALID_DMA_ADDRESS 0xffffffff 61#define INVALID_DMA_ADDRESS 0xffffffff
56 62
@@ -89,39 +95,58 @@ static bool atmel_spi_is_v2(void)
89 * Master on Chip Select 0.") No workaround exists for that ... so for 95 * Master on Chip Select 0.") No workaround exists for that ... so for
90 * nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH, 96 * nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH,
91 * and (c) will trigger that first erratum in some cases. 97 * and (c) will trigger that first erratum in some cases.
98 *
99 * TODO: Test if the atmel_spi_is_v2() branch below works on
100 * AT91RM9200 if we use some other register than CSR0. However, don't
101 * do this unconditionally since AP7000 has an errata where the BITS
102 * field in CSR0 overrides all other CSRs.
92 */ 103 */
93 104
94static void cs_activate(struct atmel_spi *as, struct spi_device *spi) 105static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
95{ 106{
96 unsigned gpio = (unsigned) spi->controller_data; 107 struct atmel_spi_device *asd = spi->controller_state;
97 unsigned active = spi->mode & SPI_CS_HIGH; 108 unsigned active = spi->mode & SPI_CS_HIGH;
98 u32 mr; 109 u32 mr;
99 int i;
100 u32 csr;
101 u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
102
103 /* Make sure clock polarity is correct */
104 for (i = 0; i < spi->master->num_chipselect; i++) {
105 csr = spi_readl(as, CSR0 + 4 * i);
106 if ((csr ^ cpol) & SPI_BIT(CPOL))
107 spi_writel(as, CSR0 + 4 * i, csr ^ SPI_BIT(CPOL));
108 }
109 110
110 mr = spi_readl(as, MR); 111 if (atmel_spi_is_v2()) {
111 mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr); 112 /*
113 * Always use CSR0. This ensures that the clock
114 * switches to the correct idle polarity before we
115 * toggle the CS.
116 */
117 spi_writel(as, CSR0, asd->csr);
118 spi_writel(as, MR, SPI_BF(PCS, 0x0e) | SPI_BIT(MODFDIS)
119 | SPI_BIT(MSTR));
120 mr = spi_readl(as, MR);
121 gpio_set_value(asd->npcs_pin, active);
122 } else {
123 u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
124 int i;
125 u32 csr;
126
127 /* Make sure clock polarity is correct */
128 for (i = 0; i < spi->master->num_chipselect; i++) {
129 csr = spi_readl(as, CSR0 + 4 * i);
130 if ((csr ^ cpol) & SPI_BIT(CPOL))
131 spi_writel(as, CSR0 + 4 * i,
132 csr ^ SPI_BIT(CPOL));
133 }
134
135 mr = spi_readl(as, MR);
136 mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr);
137 if (spi->chip_select != 0)
138 gpio_set_value(asd->npcs_pin, active);
139 spi_writel(as, MR, mr);
140 }
112 141
113 dev_dbg(&spi->dev, "activate %u%s, mr %08x\n", 142 dev_dbg(&spi->dev, "activate %u%s, mr %08x\n",
114 gpio, active ? " (high)" : "", 143 asd->npcs_pin, active ? " (high)" : "",
115 mr); 144 mr);
116
117 if (atmel_spi_is_v2() || spi->chip_select != 0)
118 gpio_set_value(gpio, active);
119 spi_writel(as, MR, mr);
120} 145}
121 146
122static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) 147static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
123{ 148{
124 unsigned gpio = (unsigned) spi->controller_data; 149 struct atmel_spi_device *asd = spi->controller_state;
125 unsigned active = spi->mode & SPI_CS_HIGH; 150 unsigned active = spi->mode & SPI_CS_HIGH;
126 u32 mr; 151 u32 mr;
127 152
@@ -135,11 +160,11 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
135 } 160 }
136 161
137 dev_dbg(&spi->dev, "DEactivate %u%s, mr %08x\n", 162 dev_dbg(&spi->dev, "DEactivate %u%s, mr %08x\n",
138 gpio, active ? " (low)" : "", 163 asd->npcs_pin, active ? " (low)" : "",
139 mr); 164 mr);
140 165
141 if (atmel_spi_is_v2() || spi->chip_select != 0) 166 if (atmel_spi_is_v2() || spi->chip_select != 0)
142 gpio_set_value(gpio, !active); 167 gpio_set_value(asd->npcs_pin, !active);
143} 168}
144 169
145static inline int atmel_spi_xfer_is_last(struct spi_message *msg, 170static inline int atmel_spi_xfer_is_last(struct spi_message *msg,
@@ -511,6 +536,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
511static int atmel_spi_setup(struct spi_device *spi) 536static int atmel_spi_setup(struct spi_device *spi)
512{ 537{
513 struct atmel_spi *as; 538 struct atmel_spi *as;
539 struct atmel_spi_device *asd;
514 u32 scbr, csr; 540 u32 scbr, csr;
515 unsigned int bits = spi->bits_per_word; 541 unsigned int bits = spi->bits_per_word;
516 unsigned long bus_hz; 542 unsigned long bus_hz;
@@ -595,11 +621,20 @@ static int atmel_spi_setup(struct spi_device *spi)
595 621
596 /* chipselect must have been muxed as GPIO (e.g. in board setup) */ 622 /* chipselect must have been muxed as GPIO (e.g. in board setup) */
597 npcs_pin = (unsigned int)spi->controller_data; 623 npcs_pin = (unsigned int)spi->controller_data;
598 if (!spi->controller_state) { 624 asd = spi->controller_state;
625 if (!asd) {
626 asd = kzalloc(sizeof(struct atmel_spi_device), GFP_KERNEL);
627 if (!asd)
628 return -ENOMEM;
629
599 ret = gpio_request(npcs_pin, spi->dev.bus_id); 630 ret = gpio_request(npcs_pin, spi->dev.bus_id);
600 if (ret) 631 if (ret) {
632 kfree(asd);
601 return ret; 633 return ret;
602 spi->controller_state = (void *)npcs_pin; 634 }
635
636 asd->npcs_pin = npcs_pin;
637 spi->controller_state = asd;
603 gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH)); 638 gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH));
604 } else { 639 } else {
605 unsigned long flags; 640 unsigned long flags;
@@ -611,11 +646,14 @@ static int atmel_spi_setup(struct spi_device *spi)
611 spin_unlock_irqrestore(&as->lock, flags); 646 spin_unlock_irqrestore(&as->lock, flags);
612 } 647 }
613 648
649 asd->csr = csr;
650
614 dev_dbg(&spi->dev, 651 dev_dbg(&spi->dev,
615 "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n", 652 "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n",
616 bus_hz / scbr, bits, spi->mode, spi->chip_select, csr); 653 bus_hz / scbr, bits, spi->mode, spi->chip_select, csr);
617 654
618 spi_writel(as, CSR0 + 4 * spi->chip_select, csr); 655 if (!atmel_spi_is_v2())
656 spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
619 657
620 return 0; 658 return 0;
621} 659}
@@ -690,10 +728,11 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
690static void atmel_spi_cleanup(struct spi_device *spi) 728static void atmel_spi_cleanup(struct spi_device *spi)
691{ 729{
692 struct atmel_spi *as = spi_master_get_devdata(spi->master); 730 struct atmel_spi *as = spi_master_get_devdata(spi->master);
731 struct atmel_spi_device *asd = spi->controller_state;
693 unsigned gpio = (unsigned) spi->controller_data; 732 unsigned gpio = (unsigned) spi->controller_data;
694 unsigned long flags; 733 unsigned long flags;
695 734
696 if (!spi->controller_state) 735 if (!asd)
697 return; 736 return;
698 737
699 spin_lock_irqsave(&as->lock, flags); 738 spin_lock_irqsave(&as->lock, flags);
@@ -703,7 +742,9 @@ static void atmel_spi_cleanup(struct spi_device *spi)
703 } 742 }
704 spin_unlock_irqrestore(&as->lock, flags); 743 spin_unlock_irqrestore(&as->lock, flags);
705 744
745 spi->controller_state = NULL;
706 gpio_free(gpio); 746 gpio_free(gpio);
747 kfree(asd);
707} 748}
708 749
709/*-------------------------------------------------------------------------*/ 750/*-------------------------------------------------------------------------*/