diff options
author | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2009-01-06 17:41:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-06 18:59:19 -0500 |
commit | 5bfa26ca1332780dfeeabafd7f169fc6fb48ba30 (patch) | |
tree | e03fa31c53e5d97077dfd932cb5a62dcc44ef2c4 /drivers/spi/atmel_spi.c | |
parent | d29389de0b0ee1715333bafc6ac3f22a75aa4313 (diff) |
atmel_spi: clean up SPIv1 quirk handling
Currently, we have a flag called "new_1" which is basically equivalent
to cpu_is_at91rm9200(). The latter is also called directly a few places.
Clean up this mess by introducing a atmel_spi_v2() function for
determining the controller version, and move all version dependent code
over to use it. This allows us to remove the new_1 flag.
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.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 8abae4ad0fa5..b4f7f1c286e1 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c | |||
@@ -30,13 +30,6 @@ | |||
30 | * The core SPI transfer engine just talks to a register bank to set up | 30 | * The core SPI transfer engine just talks to a register bank to set up |
31 | * DMA transfers; transfer queue progress is driven by IRQs. The clock | 31 | * DMA transfers; transfer queue progress is driven by IRQs. The clock |
32 | * framework provides the base clock, subdivided for each spi_device. | 32 | * framework provides the base clock, subdivided for each spi_device. |
33 | * | ||
34 | * Newer controllers, marked with "new_1" flag, have: | ||
35 | * - CR.LASTXFER | ||
36 | * - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero) | ||
37 | * - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs) | ||
38 | * - SPI_CSRx.CSAAT | ||
39 | * - SPI_CSRx.SBCR allows faster clocking | ||
40 | */ | 33 | */ |
41 | struct atmel_spi { | 34 | struct atmel_spi { |
42 | spinlock_t lock; | 35 | spinlock_t lock; |
@@ -45,7 +38,6 @@ struct atmel_spi { | |||
45 | int irq; | 38 | int irq; |
46 | struct clk *clk; | 39 | struct clk *clk; |
47 | struct platform_device *pdev; | 40 | struct platform_device *pdev; |
48 | unsigned new_1:1; | ||
49 | struct spi_device *stay; | 41 | struct spi_device *stay; |
50 | 42 | ||
51 | u8 stopping; | 43 | u8 stopping; |
@@ -63,6 +55,23 @@ struct atmel_spi { | |||
63 | #define INVALID_DMA_ADDRESS 0xffffffff | 55 | #define INVALID_DMA_ADDRESS 0xffffffff |
64 | 56 | ||
65 | /* | 57 | /* |
58 | * Version 2 of the SPI controller has | ||
59 | * - CR.LASTXFER | ||
60 | * - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero) | ||
61 | * - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs) | ||
62 | * - SPI_CSRx.CSAAT | ||
63 | * - SPI_CSRx.SBCR allows faster clocking | ||
64 | * | ||
65 | * We can determine the controller version by reading the VERSION | ||
66 | * register, but I haven't checked that it exists on all chips, and | ||
67 | * this is cheaper anyway. | ||
68 | */ | ||
69 | static bool atmel_spi_is_v2(void) | ||
70 | { | ||
71 | return !cpu_is_at91rm9200(); | ||
72 | } | ||
73 | |||
74 | /* | ||
66 | * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby | 75 | * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby |
67 | * they assume that spi slave device state will not change on deselect, so | 76 | * they assume that spi slave device state will not change on deselect, so |
68 | * that automagic deselection is OK. ("NPCSx rises if no data is to be | 77 | * that automagic deselection is OK. ("NPCSx rises if no data is to be |
@@ -105,7 +114,7 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) | |||
105 | gpio, active ? " (high)" : "", | 114 | gpio, active ? " (high)" : "", |
106 | mr); | 115 | mr); |
107 | 116 | ||
108 | if (!(cpu_is_at91rm9200() && spi->chip_select == 0)) | 117 | if (atmel_spi_is_v2() || spi->chip_select != 0) |
109 | gpio_set_value(gpio, active); | 118 | gpio_set_value(gpio, active); |
110 | spi_writel(as, MR, mr); | 119 | spi_writel(as, MR, mr); |
111 | } | 120 | } |
@@ -129,7 +138,7 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) | |||
129 | gpio, active ? " (low)" : "", | 138 | gpio, active ? " (low)" : "", |
130 | mr); | 139 | mr); |
131 | 140 | ||
132 | if (!(cpu_is_at91rm9200() && spi->chip_select == 0)) | 141 | if (atmel_spi_is_v2() || spi->chip_select != 0) |
133 | gpio_set_value(gpio, !active); | 142 | gpio_set_value(gpio, !active); |
134 | } | 143 | } |
135 | 144 | ||
@@ -536,19 +545,16 @@ static int atmel_spi_setup(struct spi_device *spi) | |||
536 | } | 545 | } |
537 | 546 | ||
538 | /* see notes above re chipselect */ | 547 | /* see notes above re chipselect */ |
539 | if (cpu_is_at91rm9200() | 548 | if (!atmel_spi_is_v2() |
540 | && spi->chip_select == 0 | 549 | && spi->chip_select == 0 |
541 | && (spi->mode & SPI_CS_HIGH)) { | 550 | && (spi->mode & SPI_CS_HIGH)) { |
542 | dev_dbg(&spi->dev, "setup: can't be active-high\n"); | 551 | dev_dbg(&spi->dev, "setup: can't be active-high\n"); |
543 | return -EINVAL; | 552 | return -EINVAL; |
544 | } | 553 | } |
545 | 554 | ||
546 | /* | 555 | /* v1 chips start out at half the peripheral bus speed. */ |
547 | * Pre-new_1 chips start out at half the peripheral | ||
548 | * bus speed. | ||
549 | */ | ||
550 | bus_hz = clk_get_rate(as->clk); | 556 | bus_hz = clk_get_rate(as->clk); |
551 | if (!as->new_1) | 557 | if (!atmel_spi_is_v2()) |
552 | bus_hz /= 2; | 558 | bus_hz /= 2; |
553 | 559 | ||
554 | if (spi->max_speed_hz) { | 560 | if (spi->max_speed_hz) { |
@@ -755,8 +761,6 @@ static int __init atmel_spi_probe(struct platform_device *pdev) | |||
755 | goto out_free_buffer; | 761 | goto out_free_buffer; |
756 | as->irq = irq; | 762 | as->irq = irq; |
757 | as->clk = clk; | 763 | as->clk = clk; |
758 | if (!cpu_is_at91rm9200()) | ||
759 | as->new_1 = 1; | ||
760 | 764 | ||
761 | ret = request_irq(irq, atmel_spi_interrupt, 0, | 765 | ret = request_irq(irq, atmel_spi_interrupt, 0, |
762 | pdev->dev.bus_id, master); | 766 | pdev->dev.bus_id, master); |