diff options
Diffstat (limited to 'drivers/spi/atmel_spi.c')
-rw-r--r-- | drivers/spi/atmel_spi.c | 93 |
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 */ | ||
55 | struct 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 | ||
94 | static void cs_activate(struct atmel_spi *as, struct spi_device *spi) | 105 | static 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 | ||
122 | static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) | 147 | static 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 | ||
145 | static inline int atmel_spi_xfer_is_last(struct spi_message *msg, | 170 | static inline int atmel_spi_xfer_is_last(struct spi_message *msg, |
@@ -511,6 +536,7 @@ atmel_spi_interrupt(int irq, void *dev_id) | |||
511 | static int atmel_spi_setup(struct spi_device *spi) | 536 | static 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) | |||
690 | static void atmel_spi_cleanup(struct spi_device *spi) | 728 | static 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 | /*-------------------------------------------------------------------------*/ |