diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-12-29 03:05:14 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-12-29 03:05:50 -0500 |
commit | 94a544a4e8d05a027613443c529c399c39cc3371 (patch) | |
tree | edada38e93a958a918b5826eaef173b1b92079d1 | |
parent | 496a2e360a34e1f41c336d23947f800216cb9bdf (diff) | |
parent | 21486af0f34d03b813b023d7a2b887b329f60486 (diff) |
Merge branch 'spi' of git://git.linutronix.de/users/bigeasy/soda into spi/next
* 'spi' of git://git.linutronix.de/users/bigeasy/soda into spi/next
spi/pxa2xx: register driver properly
spi/pxa2xx: add support for shared IRQ handler
spi/pxa2xx: Use define for SSSR_TFL_MASK instead of plain numbers
arm/pxa2xx: reorgazine SSP and SPI header files
spi/pxa2xx: Add CE4100 support
spi/pxa2xx: Consider CE4100's FIFO depth
spi/pxa2xx: Add chipselect support for Sodaville
spi/pxa2xx: Modify RX-Tresh instead of busy-loop for the remaining RX bytes.
spi/pxa2xx: pass of_node to spi device and set a parent device
27 files changed, 547 insertions, 138 deletions
diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx index 6bb916d57c95..68a4fe3818a1 100644 --- a/Documentation/spi/pxa2xx +++ b/Documentation/spi/pxa2xx | |||
@@ -19,7 +19,7 @@ Declaring PXA2xx Master Controllers | |||
19 | ----------------------------------- | 19 | ----------------------------------- |
20 | Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a | 20 | Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a |
21 | "platform device". The master configuration is passed to the driver via a table | 21 | "platform device". The master configuration is passed to the driver via a table |
22 | found in arch/arm/mach-pxa/include/mach/pxa2xx_spi.h: | 22 | found in include/linux/spi/pxa2xx_spi.h: |
23 | 23 | ||
24 | struct pxa2xx_spi_master { | 24 | struct pxa2xx_spi_master { |
25 | enum pxa_ssp_type ssp_type; | 25 | enum pxa_ssp_type ssp_type; |
@@ -94,7 +94,7 @@ using the "spi_board_info" structure found in "linux/spi/spi.h". See | |||
94 | 94 | ||
95 | Each slave device attached to the PXA must provide slave specific configuration | 95 | Each slave device attached to the PXA must provide slave specific configuration |
96 | information via the structure "pxa2xx_spi_chip" found in | 96 | information via the structure "pxa2xx_spi_chip" found in |
97 | "arch/arm/mach-pxa/include/mach/pxa2xx_spi.h". The pxa2xx_spi master controller driver | 97 | "include/linux/spi/pxa2xx_spi.h". The pxa2xx_spi master controller driver |
98 | will uses the configuration whenever the driver communicates with the slave | 98 | will uses the configuration whenever the driver communicates with the slave |
99 | device. All fields are optional. | 99 | device. All fields are optional. |
100 | 100 | ||
diff --git a/arch/arm/mach-pxa/cm-x255.c b/arch/arm/mach-pxa/cm-x255.c index f1a7703d771b..93f59f877fc6 100644 --- a/arch/arm/mach-pxa/cm-x255.c +++ b/arch/arm/mach-pxa/cm-x255.c | |||
@@ -17,13 +17,13 @@ | |||
17 | #include <linux/mtd/nand-gpio.h> | 17 | #include <linux/mtd/nand-gpio.h> |
18 | 18 | ||
19 | #include <linux/spi/spi.h> | 19 | #include <linux/spi/spi.h> |
20 | #include <linux/spi/pxa2xx_spi.h> | ||
20 | 21 | ||
21 | #include <asm/mach/arch.h> | 22 | #include <asm/mach/arch.h> |
22 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
23 | #include <asm/mach/map.h> | 24 | #include <asm/mach/map.h> |
24 | 25 | ||
25 | #include <mach/pxa25x.h> | 26 | #include <mach/pxa25x.h> |
26 | #include <mach/pxa2xx_spi.h> | ||
27 | 27 | ||
28 | #include "generic.h" | 28 | #include "generic.h" |
29 | 29 | ||
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index a9926bb75922..b88d601a8090 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c | |||
@@ -19,12 +19,12 @@ | |||
19 | #include <video/mbxfb.h> | 19 | #include <video/mbxfb.h> |
20 | 20 | ||
21 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
22 | #include <linux/spi/pxa2xx_spi.h> | ||
22 | #include <linux/spi/libertas_spi.h> | 23 | #include <linux/spi/libertas_spi.h> |
23 | 24 | ||
24 | #include <mach/pxa27x.h> | 25 | #include <mach/pxa27x.h> |
25 | #include <mach/ohci.h> | 26 | #include <mach/ohci.h> |
26 | #include <mach/mmc.h> | 27 | #include <mach/mmc.h> |
27 | #include <mach/pxa2xx_spi.h> | ||
28 | 28 | ||
29 | #include "generic.h" | 29 | #include "generic.h" |
30 | 30 | ||
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 821229acabe6..3b8dcac2b8fb 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/spi/spi.h> | 28 | #include <linux/spi/spi.h> |
29 | #include <linux/spi/ads7846.h> | 29 | #include <linux/spi/ads7846.h> |
30 | #include <linux/spi/corgi_lcd.h> | 30 | #include <linux/spi/corgi_lcd.h> |
31 | #include <linux/spi/pxa2xx_spi.h> | ||
31 | #include <linux/mtd/sharpsl.h> | 32 | #include <linux/mtd/sharpsl.h> |
32 | #include <linux/input/matrix_keypad.h> | 33 | #include <linux/input/matrix_keypad.h> |
33 | #include <video/w100fb.h> | 34 | #include <video/w100fb.h> |
@@ -48,7 +49,6 @@ | |||
48 | #include <mach/irda.h> | 49 | #include <mach/irda.h> |
49 | #include <mach/mmc.h> | 50 | #include <mach/mmc.h> |
50 | #include <mach/udc.h> | 51 | #include <mach/udc.h> |
51 | #include <mach/pxa2xx_spi.h> | ||
52 | #include <mach/corgi.h> | 52 | #include <mach/corgi.h> |
53 | #include <mach/sharpsl_pm.h> | 53 | #include <mach/sharpsl_pm.h> |
54 | 54 | ||
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index aaa1166df964..c4f9c715be73 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/init.h> | 3 | #include <linux/init.h> |
4 | #include <linux/platform_device.h> | 4 | #include <linux/platform_device.h> |
5 | #include <linux/dma-mapping.h> | 5 | #include <linux/dma-mapping.h> |
6 | #include <linux/spi/pxa2xx_spi.h> | ||
6 | 7 | ||
7 | #include <asm/pmu.h> | 8 | #include <asm/pmu.h> |
8 | #include <mach/udc.h> | 9 | #include <mach/udc.h> |
@@ -12,7 +13,6 @@ | |||
12 | #include <mach/irda.h> | 13 | #include <mach/irda.h> |
13 | #include <mach/ohci.h> | 14 | #include <mach/ohci.h> |
14 | #include <plat/pxa27x_keypad.h> | 15 | #include <plat/pxa27x_keypad.h> |
15 | #include <mach/pxa2xx_spi.h> | ||
16 | #include <mach/camera.h> | 16 | #include <mach/camera.h> |
17 | #include <mach/audio.h> | 17 | #include <mach/audio.h> |
18 | #include <mach/hardware.h> | 18 | #include <mach/hardware.h> |
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index ed0dbfdb22ed..b20b944c337c 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
27 | #include <linux/spi/tdo24m.h> | 27 | #include <linux/spi/tdo24m.h> |
28 | #include <linux/spi/libertas_spi.h> | 28 | #include <linux/spi/libertas_spi.h> |
29 | #include <linux/spi/pxa2xx_spi.h> | ||
29 | #include <linux/power_supply.h> | 30 | #include <linux/power_supply.h> |
30 | #include <linux/apm-emulation.h> | 31 | #include <linux/apm-emulation.h> |
31 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
@@ -46,7 +47,6 @@ | |||
46 | #include <plat/pxa27x_keypad.h> | 47 | #include <plat/pxa27x_keypad.h> |
47 | #include <plat/i2c.h> | 48 | #include <plat/i2c.h> |
48 | #include <mach/camera.h> | 49 | #include <mach/camera.h> |
49 | #include <mach/pxa2xx_spi.h> | ||
50 | 50 | ||
51 | #include "generic.h" | 51 | #include "generic.h" |
52 | #include "devices.h" | 52 | #include "devices.h" |
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 76d93a25bab6..f09526f52152 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/regulator/max1586.h> | 33 | #include <linux/regulator/max1586.h> |
34 | #include <linux/spi/ads7846.h> | 34 | #include <linux/spi/ads7846.h> |
35 | #include <linux/spi/spi.h> | 35 | #include <linux/spi/spi.h> |
36 | #include <linux/spi/pxa2xx_spi.h> | ||
36 | #include <linux/usb/gpio_vbus.h> | 37 | #include <linux/usb/gpio_vbus.h> |
37 | 38 | ||
38 | #include <mach/hardware.h> | 39 | #include <mach/hardware.h> |
@@ -43,7 +44,6 @@ | |||
43 | #include <mach/hx4700.h> | 44 | #include <mach/hx4700.h> |
44 | #include <plat/i2c.h> | 45 | #include <plat/i2c.h> |
45 | #include <mach/irda.h> | 46 | #include <mach/irda.h> |
46 | #include <mach/pxa2xx_spi.h> | ||
47 | 47 | ||
48 | #include <video/platform_lcd.h> | 48 | #include <video/platform_lcd.h> |
49 | #include <video/w100fb.h> | 49 | #include <video/w100fb.h> |
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c index d51ee3d25e70..3ab6fd369584 100644 --- a/arch/arm/mach-pxa/icontrol.c +++ b/arch/arm/mach-pxa/icontrol.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <mach/mxm8x10.h> | 24 | #include <mach/mxm8x10.h> |
25 | 25 | ||
26 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
27 | #include <mach/pxa2xx_spi.h> | 27 | #include <linux/spi/pxa2xx_spi.h> |
28 | #include <linux/can/platform/mcp251x.h> | 28 | #include <linux/can/platform/mcp251x.h> |
29 | 29 | ||
30 | #include "generic.h" | 30 | #include "generic.h" |
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h b/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h deleted file mode 100644 index b87cecd9bbdc..000000000000 --- a/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | #ifndef PXA2XX_SPI_H_ | ||
20 | #define PXA2XX_SPI_H_ | ||
21 | |||
22 | #define PXA2XX_CS_ASSERT (0x01) | ||
23 | #define PXA2XX_CS_DEASSERT (0x02) | ||
24 | |||
25 | /* device.platform_data for SSP controller devices */ | ||
26 | struct pxa2xx_spi_master { | ||
27 | u32 clock_enable; | ||
28 | u16 num_chipselect; | ||
29 | u8 enable_dma; | ||
30 | }; | ||
31 | |||
32 | /* spi_board_info.controller_data for SPI slave devices, | ||
33 | * copied to spi_device.platform_data ... mostly for dma tuning | ||
34 | */ | ||
35 | struct pxa2xx_spi_chip { | ||
36 | u8 tx_threshold; | ||
37 | u8 rx_threshold; | ||
38 | u8 dma_burst_size; | ||
39 | u32 timeout; | ||
40 | u8 enable_loopback; | ||
41 | int gpio_cs; | ||
42 | void (*cs_control)(u32 command); | ||
43 | }; | ||
44 | |||
45 | extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info); | ||
46 | |||
47 | #endif /*PXA2XX_SPI_H_*/ | ||
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 41aa89e35772..8051925d457c 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
25 | #include <linux/spi/pxa2xx_spi.h> | ||
25 | #include <linux/smc91x.h> | 26 | #include <linux/smc91x.h> |
26 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
27 | #include <linux/leds.h> | 28 | #include <linux/leds.h> |
@@ -42,7 +43,6 @@ | |||
42 | #include <mach/pxa300.h> | 43 | #include <mach/pxa300.h> |
43 | #include <mach/pxafb.h> | 44 | #include <mach/pxafb.h> |
44 | #include <mach/mmc.h> | 45 | #include <mach/mmc.h> |
45 | #include <mach/pxa2xx_spi.h> | ||
46 | #include <plat/pxa27x_keypad.h> | 46 | #include <plat/pxa27x_keypad.h> |
47 | #include <mach/littleton.h> | 47 | #include <mach/littleton.h> |
48 | #include <plat/i2c.h> | 48 | #include <plat/i2c.h> |
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 1499493cd070..4a3fe450c20f 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
27 | #include <linux/spi/ads7846.h> | 27 | #include <linux/spi/ads7846.h> |
28 | #include <mach/pxa2xx_spi.h> | 28 | #include <linux/spi/pxa2xx_spi.h> |
29 | 29 | ||
30 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
31 | #include <asm/memory.h> | 31 | #include <asm/memory.h> |
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index c77e8f30a439..a5596f9b17bc 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c | |||
@@ -25,12 +25,12 @@ | |||
25 | #include <linux/mtd/physmap.h> | 25 | #include <linux/mtd/physmap.h> |
26 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
27 | #include <linux/spi/max7301.h> | 27 | #include <linux/spi/max7301.h> |
28 | #include <linux/spi/pxa2xx_spi.h> | ||
28 | #include <linux/leds.h> | 29 | #include <linux/leds.h> |
29 | 30 | ||
30 | #include <asm/mach-types.h> | 31 | #include <asm/mach-types.h> |
31 | #include <asm/mach/arch.h> | 32 | #include <asm/mach/arch.h> |
32 | #include <mach/pxa27x.h> | 33 | #include <mach/pxa27x.h> |
33 | #include <mach/pxa2xx_spi.h> | ||
34 | #include <mach/pcm027.h> | 34 | #include <mach/pcm027.h> |
35 | #include "generic.h" | 35 | #include "generic.h" |
36 | 36 | ||
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 93a191c889df..c05eee326234 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
27 | #include <linux/spi/ads7846.h> | 27 | #include <linux/spi/ads7846.h> |
28 | #include <linux/spi/pxa2xx_spi.h> | ||
28 | #include <linux/mtd/sharpsl.h> | 29 | #include <linux/mtd/sharpsl.h> |
29 | 30 | ||
30 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
@@ -43,7 +44,6 @@ | |||
43 | #include <mach/irda.h> | 44 | #include <mach/irda.h> |
44 | #include <mach/poodle.h> | 45 | #include <mach/poodle.h> |
45 | #include <mach/pxafb.h> | 46 | #include <mach/pxafb.h> |
46 | #include <mach/pxa2xx_spi.h> | ||
47 | #include <plat/i2c.h> | 47 | #include <plat/i2c.h> |
48 | 48 | ||
49 | #include <asm/hardware/scoop.h> | 49 | #include <asm/hardware/scoop.h> |
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index f736119f1ebf..4fd5572f6995 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
24 | #include <linux/spi/ads7846.h> | 24 | #include <linux/spi/ads7846.h> |
25 | #include <linux/spi/corgi_lcd.h> | 25 | #include <linux/spi/corgi_lcd.h> |
26 | #include <linux/mtd/physmap.h> | 26 | #include <linux/spi/pxa2xx_spi.h> |
27 | #include <linux/mtd/sharpsl.h> | 27 | #include <linux/mtd/sharpsl.h> |
28 | #include <linux/input/matrix_keypad.h> | 28 | #include <linux/input/matrix_keypad.h> |
29 | #include <linux/regulator/machine.h> | 29 | #include <linux/regulator/machine.h> |
@@ -41,7 +41,6 @@ | |||
41 | #include <mach/mmc.h> | 41 | #include <mach/mmc.h> |
42 | #include <mach/ohci.h> | 42 | #include <mach/ohci.h> |
43 | #include <mach/pxafb.h> | 43 | #include <mach/pxafb.h> |
44 | #include <mach/pxa2xx_spi.h> | ||
45 | #include <mach/spitz.h> | 44 | #include <mach/spitz.h> |
46 | #include <mach/sharpsl_pm.h> | 45 | #include <mach/sharpsl_pm.h> |
47 | 46 | ||
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index 738adc1773fd..325f6ac6b591 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c | |||
@@ -46,10 +46,10 @@ | |||
46 | #include <plat/i2c.h> | 46 | #include <plat/i2c.h> |
47 | #include <mach/mmc.h> | 47 | #include <mach/mmc.h> |
48 | #include <mach/udc.h> | 48 | #include <mach/udc.h> |
49 | #include <mach/pxa2xx_spi.h> | ||
50 | #include <mach/pxa27x-udc.h> | 49 | #include <mach/pxa27x-udc.h> |
51 | 50 | ||
52 | #include <linux/spi/spi.h> | 51 | #include <linux/spi/spi.h> |
52 | #include <linux/spi/pxa2xx_spi.h> | ||
53 | #include <linux/mfd/da903x.h> | 53 | #include <linux/mfd/da903x.h> |
54 | #include <linux/sht15.h> | 54 | #include <linux/sht15.h> |
55 | 55 | ||
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 0ee1df49606d..7b5765dacbd9 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
33 | #include <linux/pda_power.h> | 33 | #include <linux/pda_power.h> |
34 | #include <linux/spi/spi.h> | 34 | #include <linux/spi/spi.h> |
35 | #include <linux/spi/pxa2xx_spi.h> | ||
35 | #include <linux/input/matrix_keypad.h> | 36 | #include <linux/input/matrix_keypad.h> |
36 | 37 | ||
37 | #include <asm/setup.h> | 38 | #include <asm/setup.h> |
@@ -44,7 +45,6 @@ | |||
44 | #include <mach/mmc.h> | 45 | #include <mach/mmc.h> |
45 | #include <mach/udc.h> | 46 | #include <mach/udc.h> |
46 | #include <mach/tosa_bt.h> | 47 | #include <mach/tosa_bt.h> |
47 | #include <mach/pxa2xx_spi.h> | ||
48 | #include <mach/audio.h> | 48 | #include <mach/audio.h> |
49 | 49 | ||
50 | #include <asm/mach/arch.h> | 50 | #include <asm/mach/arch.h> |
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 565d062f51d5..bdb02a0ae1b7 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <asm/mach/flash.h> | 40 | #include <asm/mach/flash.h> |
41 | 41 | ||
42 | #include <mach/pxa27x.h> | 42 | #include <mach/pxa27x.h> |
43 | #include <mach/pxa2xx_spi.h> | ||
44 | #include <mach/trizeps4.h> | 43 | #include <mach/trizeps4.h> |
45 | #include <mach/audio.h> | 44 | #include <mach/audio.h> |
46 | #include <mach/pxafb.h> | 45 | #include <mach/pxafb.h> |
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index fefde9848d82..1b8b71b3c719 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/z2_battery.h> | 20 | #include <linux/z2_battery.h> |
21 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
22 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
23 | #include <linux/spi/pxa2xx_spi.h> | ||
23 | #include <linux/spi/libertas_spi.h> | 24 | #include <linux/spi/libertas_spi.h> |
24 | #include <linux/spi/lms283gf05.h> | 25 | #include <linux/spi/lms283gf05.h> |
25 | #include <linux/power_supply.h> | 26 | #include <linux/power_supply.h> |
@@ -38,7 +39,6 @@ | |||
38 | #include <mach/pxafb.h> | 39 | #include <mach/pxafb.h> |
39 | #include <mach/mmc.h> | 40 | #include <mach/mmc.h> |
40 | #include <plat/pxa27x_keypad.h> | 41 | #include <plat/pxa27x_keypad.h> |
41 | #include <mach/pxa2xx_spi.h> | ||
42 | 42 | ||
43 | #include <plat/i2c.h> | 43 | #include <plat/i2c.h> |
44 | 44 | ||
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index dea46a2d089b..f5c9f3032c31 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/dm9000.h> | 20 | #include <linux/dm9000.h> |
21 | #include <linux/mmc/host.h> | 21 | #include <linux/mmc/host.h> |
22 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
23 | #include <linux/spi/pxa2xx_spi.h> | ||
23 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
24 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
25 | #include <linux/mtd/physmap.h> | 26 | #include <linux/mtd/physmap.h> |
@@ -41,7 +42,6 @@ | |||
41 | #include <mach/pxa27x-udc.h> | 42 | #include <mach/pxa27x-udc.h> |
42 | #include <mach/udc.h> | 43 | #include <mach/udc.h> |
43 | #include <mach/pxafb.h> | 44 | #include <mach/pxafb.h> |
44 | #include <mach/pxa2xx_spi.h> | ||
45 | #include <mach/mfp-pxa27x.h> | 45 | #include <mach/mfp-pxa27x.h> |
46 | #include <mach/pm.h> | 46 | #include <mach/pm.h> |
47 | #include <mach/audio.h> | 47 | #include <mach/audio.h> |
diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c index c6357e554aba..58b79809d20c 100644 --- a/arch/arm/plat-pxa/ssp.c +++ b/arch/arm/plat-pxa/ssp.c | |||
@@ -28,11 +28,11 @@ | |||
28 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
29 | #include <linux/err.h> | 29 | #include <linux/err.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/spi/pxa2xx_spi.h> | ||
31 | #include <linux/io.h> | 32 | #include <linux/io.h> |
32 | 33 | ||
33 | #include <asm/irq.h> | 34 | #include <asm/irq.h> |
34 | #include <mach/hardware.h> | 35 | #include <mach/hardware.h> |
35 | #include <plat/ssp.h> | ||
36 | 36 | ||
37 | static DEFINE_MUTEX(ssp_lock); | 37 | static DEFINE_MUTEX(ssp_lock); |
38 | static LIST_HEAD(ssp_list); | 38 | static LIST_HEAD(ssp_list); |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 6efac5fd439d..1906840c1113 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -270,12 +270,15 @@ config SPI_PPC4xx | |||
270 | 270 | ||
271 | config SPI_PXA2XX | 271 | config SPI_PXA2XX |
272 | tristate "PXA2xx SSP SPI master" | 272 | tristate "PXA2xx SSP SPI master" |
273 | depends on ARCH_PXA && EXPERIMENTAL | 273 | depends on (ARCH_PXA || (X86_32 && PCI)) && EXPERIMENTAL |
274 | select PXA_SSP | 274 | select PXA_SSP if ARCH_PXA |
275 | help | 275 | help |
276 | This enables using a PXA2xx SSP port as a SPI master controller. | 276 | This enables using a PXA2xx or Sodaville SSP port as a SPI master |
277 | The driver can be configured to use any SSP port and additional | 277 | controller. The driver can be configured to use any SSP port and |
278 | documentation can be found a Documentation/spi/pxa2xx. | 278 | additional documentation can be found a Documentation/spi/pxa2xx. |
279 | |||
280 | config SPI_PXA2XX_PCI | ||
281 | def_bool SPI_PXA2XX && X86_32 && PCI | ||
279 | 282 | ||
280 | config SPI_S3C24XX | 283 | config SPI_S3C24XX |
281 | tristate "Samsung S3C24XX series SPI" | 284 | tristate "Samsung S3C24XX series SPI" |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 7ec375b6c0c3..3a42463c92a4 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_SPI_GPIO) += spi_gpio.o | |||
25 | obj-$(CONFIG_SPI_IMX) += spi_imx.o | 25 | obj-$(CONFIG_SPI_IMX) += spi_imx.o |
26 | obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o | 26 | obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o |
27 | obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o | 27 | obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o |
28 | obj-$(CONFIG_SPI_PXA2XX_PCI) += pxa2xx_spi_pci.o | ||
28 | obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o | 29 | obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o |
29 | obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o | 30 | obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o |
30 | obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o | 31 | obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index e76b1afafe07..95928833855b 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -23,11 +23,11 @@ | |||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/spi/pxa2xx_spi.h> | ||
26 | #include <linux/dma-mapping.h> | 27 | #include <linux/dma-mapping.h> |
27 | #include <linux/spi/spi.h> | 28 | #include <linux/spi/spi.h> |
28 | #include <linux/workqueue.h> | 29 | #include <linux/workqueue.h> |
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <linux/clk.h> | ||
31 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | 33 | ||
@@ -35,9 +35,6 @@ | |||
35 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
36 | #include <asm/delay.h> | 36 | #include <asm/delay.h> |
37 | 37 | ||
38 | #include <mach/dma.h> | ||
39 | #include <plat/ssp.h> | ||
40 | #include <mach/pxa2xx_spi.h> | ||
41 | 38 | ||
42 | MODULE_AUTHOR("Stephen Street"); | 39 | MODULE_AUTHOR("Stephen Street"); |
43 | MODULE_DESCRIPTION("PXA2xx SSP SPI Controller"); | 40 | MODULE_DESCRIPTION("PXA2xx SSP SPI Controller"); |
@@ -46,8 +43,6 @@ MODULE_ALIAS("platform:pxa2xx-spi"); | |||
46 | 43 | ||
47 | #define MAX_BUSES 3 | 44 | #define MAX_BUSES 3 |
48 | 45 | ||
49 | #define RX_THRESH_DFLT 8 | ||
50 | #define TX_THRESH_DFLT 8 | ||
51 | #define TIMOUT_DFLT 1000 | 46 | #define TIMOUT_DFLT 1000 |
52 | 47 | ||
53 | #define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) | 48 | #define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) |
@@ -168,7 +163,10 @@ struct chip_data { | |||
168 | u8 enable_dma; | 163 | u8 enable_dma; |
169 | u8 bits_per_word; | 164 | u8 bits_per_word; |
170 | u32 speed_hz; | 165 | u32 speed_hz; |
171 | int gpio_cs; | 166 | union { |
167 | int gpio_cs; | ||
168 | unsigned int frm; | ||
169 | }; | ||
172 | int gpio_cs_inverted; | 170 | int gpio_cs_inverted; |
173 | int (*write)(struct driver_data *drv_data); | 171 | int (*write)(struct driver_data *drv_data); |
174 | int (*read)(struct driver_data *drv_data); | 172 | int (*read)(struct driver_data *drv_data); |
@@ -181,6 +179,11 @@ static void cs_assert(struct driver_data *drv_data) | |||
181 | { | 179 | { |
182 | struct chip_data *chip = drv_data->cur_chip; | 180 | struct chip_data *chip = drv_data->cur_chip; |
183 | 181 | ||
182 | if (drv_data->ssp_type == CE4100_SSP) { | ||
183 | write_SSSR(drv_data->cur_chip->frm, drv_data->ioaddr); | ||
184 | return; | ||
185 | } | ||
186 | |||
184 | if (chip->cs_control) { | 187 | if (chip->cs_control) { |
185 | chip->cs_control(PXA2XX_CS_ASSERT); | 188 | chip->cs_control(PXA2XX_CS_ASSERT); |
186 | return; | 189 | return; |
@@ -194,6 +197,9 @@ static void cs_deassert(struct driver_data *drv_data) | |||
194 | { | 197 | { |
195 | struct chip_data *chip = drv_data->cur_chip; | 198 | struct chip_data *chip = drv_data->cur_chip; |
196 | 199 | ||
200 | if (drv_data->ssp_type == CE4100_SSP) | ||
201 | return; | ||
202 | |||
197 | if (chip->cs_control) { | 203 | if (chip->cs_control) { |
198 | chip->cs_control(PXA2XX_CS_DEASSERT); | 204 | chip->cs_control(PXA2XX_CS_DEASSERT); |
199 | return; | 205 | return; |
@@ -203,6 +209,25 @@ static void cs_deassert(struct driver_data *drv_data) | |||
203 | gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted); | 209 | gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted); |
204 | } | 210 | } |
205 | 211 | ||
212 | static void write_SSSR_CS(struct driver_data *drv_data, u32 val) | ||
213 | { | ||
214 | void __iomem *reg = drv_data->ioaddr; | ||
215 | |||
216 | if (drv_data->ssp_type == CE4100_SSP) | ||
217 | val |= read_SSSR(reg) & SSSR_ALT_FRM_MASK; | ||
218 | |||
219 | write_SSSR(val, reg); | ||
220 | } | ||
221 | |||
222 | static int pxa25x_ssp_comp(struct driver_data *drv_data) | ||
223 | { | ||
224 | if (drv_data->ssp_type == PXA25x_SSP) | ||
225 | return 1; | ||
226 | if (drv_data->ssp_type == CE4100_SSP) | ||
227 | return 1; | ||
228 | return 0; | ||
229 | } | ||
230 | |||
206 | static int flush(struct driver_data *drv_data) | 231 | static int flush(struct driver_data *drv_data) |
207 | { | 232 | { |
208 | unsigned long limit = loops_per_jiffy << 1; | 233 | unsigned long limit = loops_per_jiffy << 1; |
@@ -214,7 +239,7 @@ static int flush(struct driver_data *drv_data) | |||
214 | read_SSDR(reg); | 239 | read_SSDR(reg); |
215 | } | 240 | } |
216 | } while ((read_SSSR(reg) & SSSR_BSY) && --limit); | 241 | } while ((read_SSSR(reg) & SSSR_BSY) && --limit); |
217 | write_SSSR(SSSR_ROR, reg); | 242 | write_SSSR_CS(drv_data, SSSR_ROR); |
218 | 243 | ||
219 | return limit; | 244 | return limit; |
220 | } | 245 | } |
@@ -224,7 +249,7 @@ static int null_writer(struct driver_data *drv_data) | |||
224 | void __iomem *reg = drv_data->ioaddr; | 249 | void __iomem *reg = drv_data->ioaddr; |
225 | u8 n_bytes = drv_data->n_bytes; | 250 | u8 n_bytes = drv_data->n_bytes; |
226 | 251 | ||
227 | if (((read_SSSR(reg) & 0x00000f00) == 0x00000f00) | 252 | if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK) |
228 | || (drv_data->tx == drv_data->tx_end)) | 253 | || (drv_data->tx == drv_data->tx_end)) |
229 | return 0; | 254 | return 0; |
230 | 255 | ||
@@ -252,7 +277,7 @@ static int u8_writer(struct driver_data *drv_data) | |||
252 | { | 277 | { |
253 | void __iomem *reg = drv_data->ioaddr; | 278 | void __iomem *reg = drv_data->ioaddr; |
254 | 279 | ||
255 | if (((read_SSSR(reg) & 0x00000f00) == 0x00000f00) | 280 | if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK) |
256 | || (drv_data->tx == drv_data->tx_end)) | 281 | || (drv_data->tx == drv_data->tx_end)) |
257 | return 0; | 282 | return 0; |
258 | 283 | ||
@@ -279,7 +304,7 @@ static int u16_writer(struct driver_data *drv_data) | |||
279 | { | 304 | { |
280 | void __iomem *reg = drv_data->ioaddr; | 305 | void __iomem *reg = drv_data->ioaddr; |
281 | 306 | ||
282 | if (((read_SSSR(reg) & 0x00000f00) == 0x00000f00) | 307 | if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK) |
283 | || (drv_data->tx == drv_data->tx_end)) | 308 | || (drv_data->tx == drv_data->tx_end)) |
284 | return 0; | 309 | return 0; |
285 | 310 | ||
@@ -306,7 +331,7 @@ static int u32_writer(struct driver_data *drv_data) | |||
306 | { | 331 | { |
307 | void __iomem *reg = drv_data->ioaddr; | 332 | void __iomem *reg = drv_data->ioaddr; |
308 | 333 | ||
309 | if (((read_SSSR(reg) & 0x00000f00) == 0x00000f00) | 334 | if (((read_SSSR(reg) & SSSR_TFL_MASK) == SSSR_TFL_MASK) |
310 | || (drv_data->tx == drv_data->tx_end)) | 335 | || (drv_data->tx == drv_data->tx_end)) |
311 | return 0; | 336 | return 0; |
312 | 337 | ||
@@ -507,9 +532,9 @@ static void dma_error_stop(struct driver_data *drv_data, const char *msg) | |||
507 | /* Stop and reset */ | 532 | /* Stop and reset */ |
508 | DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; | 533 | DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; |
509 | DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; | 534 | DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; |
510 | write_SSSR(drv_data->clear_sr, reg); | 535 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
511 | write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); | 536 | write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); |
512 | if (drv_data->ssp_type != PXA25x_SSP) | 537 | if (!pxa25x_ssp_comp(drv_data)) |
513 | write_SSTO(0, reg); | 538 | write_SSTO(0, reg); |
514 | flush(drv_data); | 539 | flush(drv_data); |
515 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); | 540 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); |
@@ -529,7 +554,7 @@ static void dma_transfer_complete(struct driver_data *drv_data) | |||
529 | 554 | ||
530 | /* Clear and disable interrupts on SSP and DMA channels*/ | 555 | /* Clear and disable interrupts on SSP and DMA channels*/ |
531 | write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); | 556 | write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); |
532 | write_SSSR(drv_data->clear_sr, reg); | 557 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
533 | DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; | 558 | DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; |
534 | DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; | 559 | DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; |
535 | 560 | ||
@@ -622,7 +647,7 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data) | |||
622 | 647 | ||
623 | /* Clear and disable timeout interrupt, do the rest in | 648 | /* Clear and disable timeout interrupt, do the rest in |
624 | * dma_transfer_complete */ | 649 | * dma_transfer_complete */ |
625 | if (drv_data->ssp_type != PXA25x_SSP) | 650 | if (!pxa25x_ssp_comp(drv_data)) |
626 | write_SSTO(0, reg); | 651 | write_SSTO(0, reg); |
627 | 652 | ||
628 | /* finish this transfer, start the next */ | 653 | /* finish this transfer, start the next */ |
@@ -635,14 +660,26 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data) | |||
635 | return IRQ_NONE; | 660 | return IRQ_NONE; |
636 | } | 661 | } |
637 | 662 | ||
663 | static void reset_sccr1(struct driver_data *drv_data) | ||
664 | { | ||
665 | void __iomem *reg = drv_data->ioaddr; | ||
666 | struct chip_data *chip = drv_data->cur_chip; | ||
667 | u32 sccr1_reg; | ||
668 | |||
669 | sccr1_reg = read_SSCR1(reg) & ~drv_data->int_cr1; | ||
670 | sccr1_reg &= ~SSCR1_RFT; | ||
671 | sccr1_reg |= chip->threshold; | ||
672 | write_SSCR1(sccr1_reg, reg); | ||
673 | } | ||
674 | |||
638 | static void int_error_stop(struct driver_data *drv_data, const char* msg) | 675 | static void int_error_stop(struct driver_data *drv_data, const char* msg) |
639 | { | 676 | { |
640 | void __iomem *reg = drv_data->ioaddr; | 677 | void __iomem *reg = drv_data->ioaddr; |
641 | 678 | ||
642 | /* Stop and reset SSP */ | 679 | /* Stop and reset SSP */ |
643 | write_SSSR(drv_data->clear_sr, reg); | 680 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
644 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); | 681 | reset_sccr1(drv_data); |
645 | if (drv_data->ssp_type != PXA25x_SSP) | 682 | if (!pxa25x_ssp_comp(drv_data)) |
646 | write_SSTO(0, reg); | 683 | write_SSTO(0, reg); |
647 | flush(drv_data); | 684 | flush(drv_data); |
648 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); | 685 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); |
@@ -658,9 +695,9 @@ static void int_transfer_complete(struct driver_data *drv_data) | |||
658 | void __iomem *reg = drv_data->ioaddr; | 695 | void __iomem *reg = drv_data->ioaddr; |
659 | 696 | ||
660 | /* Stop SSP */ | 697 | /* Stop SSP */ |
661 | write_SSSR(drv_data->clear_sr, reg); | 698 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
662 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); | 699 | reset_sccr1(drv_data); |
663 | if (drv_data->ssp_type != PXA25x_SSP) | 700 | if (!pxa25x_ssp_comp(drv_data)) |
664 | write_SSTO(0, reg); | 701 | write_SSTO(0, reg); |
665 | 702 | ||
666 | /* Update total byte transfered return count actual bytes read */ | 703 | /* Update total byte transfered return count actual bytes read */ |
@@ -714,24 +751,34 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data) | |||
714 | } | 751 | } |
715 | 752 | ||
716 | if (drv_data->tx == drv_data->tx_end) { | 753 | if (drv_data->tx == drv_data->tx_end) { |
717 | write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg); | 754 | u32 bytes_left; |
718 | /* PXA25x_SSP has no timeout, read trailing bytes */ | 755 | u32 sccr1_reg; |
719 | if (drv_data->ssp_type == PXA25x_SSP) { | 756 | |
720 | if (!wait_ssp_rx_stall(reg)) | 757 | sccr1_reg = read_SSCR1(reg); |
721 | { | 758 | sccr1_reg &= ~SSCR1_TIE; |
722 | int_error_stop(drv_data, "interrupt_transfer: " | 759 | |
723 | "rx stall failed"); | 760 | /* |
724 | return IRQ_HANDLED; | 761 | * PXA25x_SSP has no timeout, set up rx threshould for the |
725 | } | 762 | * remaing RX bytes. |
726 | if (!drv_data->read(drv_data)) | 763 | */ |
727 | { | 764 | if (pxa25x_ssp_comp(drv_data)) { |
728 | int_error_stop(drv_data, | 765 | |
729 | "interrupt_transfer: " | 766 | sccr1_reg &= ~SSCR1_RFT; |
730 | "trailing byte read failed"); | 767 | |
731 | return IRQ_HANDLED; | 768 | bytes_left = drv_data->rx_end - drv_data->rx; |
769 | switch (drv_data->n_bytes) { | ||
770 | case 4: | ||
771 | bytes_left >>= 1; | ||
772 | case 2: | ||
773 | bytes_left >>= 1; | ||
732 | } | 774 | } |
733 | int_transfer_complete(drv_data); | 775 | |
776 | if (bytes_left > RX_THRESH_DFLT) | ||
777 | bytes_left = RX_THRESH_DFLT; | ||
778 | |||
779 | sccr1_reg |= SSCR1_RxTresh(bytes_left); | ||
734 | } | 780 | } |
781 | write_SSCR1(sccr1_reg, reg); | ||
735 | } | 782 | } |
736 | 783 | ||
737 | /* We did something */ | 784 | /* We did something */ |
@@ -742,14 +789,26 @@ static irqreturn_t ssp_int(int irq, void *dev_id) | |||
742 | { | 789 | { |
743 | struct driver_data *drv_data = dev_id; | 790 | struct driver_data *drv_data = dev_id; |
744 | void __iomem *reg = drv_data->ioaddr; | 791 | void __iomem *reg = drv_data->ioaddr; |
792 | u32 sccr1_reg = read_SSCR1(reg); | ||
793 | u32 mask = drv_data->mask_sr; | ||
794 | u32 status; | ||
795 | |||
796 | status = read_SSSR(reg); | ||
797 | |||
798 | /* Ignore possible writes if we don't need to write */ | ||
799 | if (!(sccr1_reg & SSCR1_TIE)) | ||
800 | mask &= ~SSSR_TFS; | ||
801 | |||
802 | if (!(status & mask)) | ||
803 | return IRQ_NONE; | ||
745 | 804 | ||
746 | if (!drv_data->cur_msg) { | 805 | if (!drv_data->cur_msg) { |
747 | 806 | ||
748 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); | 807 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); |
749 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); | 808 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); |
750 | if (drv_data->ssp_type != PXA25x_SSP) | 809 | if (!pxa25x_ssp_comp(drv_data)) |
751 | write_SSTO(0, reg); | 810 | write_SSTO(0, reg); |
752 | write_SSSR(drv_data->clear_sr, reg); | 811 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
753 | 812 | ||
754 | dev_err(&drv_data->pdev->dev, "bad message state " | 813 | dev_err(&drv_data->pdev->dev, "bad message state " |
755 | "in interrupt handler\n"); | 814 | "in interrupt handler\n"); |
@@ -862,7 +921,7 @@ static unsigned int ssp_get_clk_div(struct ssp_device *ssp, int rate) | |||
862 | { | 921 | { |
863 | unsigned long ssp_clk = clk_get_rate(ssp->clk); | 922 | unsigned long ssp_clk = clk_get_rate(ssp->clk); |
864 | 923 | ||
865 | if (ssp->type == PXA25x_SSP) | 924 | if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP) |
866 | return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8; | 925 | return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8; |
867 | else | 926 | else |
868 | return ((ssp_clk / rate - 1) & 0xfff) << 8; | 927 | return ((ssp_clk / rate - 1) & 0xfff) << 8; |
@@ -1088,7 +1147,7 @@ static void pump_transfers(unsigned long data) | |||
1088 | 1147 | ||
1089 | /* Clear status */ | 1148 | /* Clear status */ |
1090 | cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1; | 1149 | cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1; |
1091 | write_SSSR(drv_data->clear_sr, reg); | 1150 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
1092 | } | 1151 | } |
1093 | 1152 | ||
1094 | /* see if we need to reload the config registers */ | 1153 | /* see if we need to reload the config registers */ |
@@ -1098,7 +1157,7 @@ static void pump_transfers(unsigned long data) | |||
1098 | 1157 | ||
1099 | /* stop the SSP, and update the other bits */ | 1158 | /* stop the SSP, and update the other bits */ |
1100 | write_SSCR0(cr0 & ~SSCR0_SSE, reg); | 1159 | write_SSCR0(cr0 & ~SSCR0_SSE, reg); |
1101 | if (drv_data->ssp_type != PXA25x_SSP) | 1160 | if (!pxa25x_ssp_comp(drv_data)) |
1102 | write_SSTO(chip->timeout, reg); | 1161 | write_SSTO(chip->timeout, reg); |
1103 | /* first set CR1 without interrupt and service enables */ | 1162 | /* first set CR1 without interrupt and service enables */ |
1104 | write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg); | 1163 | write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg); |
@@ -1106,7 +1165,7 @@ static void pump_transfers(unsigned long data) | |||
1106 | write_SSCR0(cr0, reg); | 1165 | write_SSCR0(cr0, reg); |
1107 | 1166 | ||
1108 | } else { | 1167 | } else { |
1109 | if (drv_data->ssp_type != PXA25x_SSP) | 1168 | if (!pxa25x_ssp_comp(drv_data)) |
1110 | write_SSTO(chip->timeout, reg); | 1169 | write_SSTO(chip->timeout, reg); |
1111 | } | 1170 | } |
1112 | 1171 | ||
@@ -1233,14 +1292,13 @@ static int setup(struct spi_device *spi) | |||
1233 | uint tx_thres = TX_THRESH_DFLT; | 1292 | uint tx_thres = TX_THRESH_DFLT; |
1234 | uint rx_thres = RX_THRESH_DFLT; | 1293 | uint rx_thres = RX_THRESH_DFLT; |
1235 | 1294 | ||
1236 | if (drv_data->ssp_type != PXA25x_SSP | 1295 | if (!pxa25x_ssp_comp(drv_data) |
1237 | && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) { | 1296 | && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) { |
1238 | dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d " | 1297 | dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d " |
1239 | "b/w not 4-32 for type non-PXA25x_SSP\n", | 1298 | "b/w not 4-32 for type non-PXA25x_SSP\n", |
1240 | drv_data->ssp_type, spi->bits_per_word); | 1299 | drv_data->ssp_type, spi->bits_per_word); |
1241 | return -EINVAL; | 1300 | return -EINVAL; |
1242 | } | 1301 | } else if (pxa25x_ssp_comp(drv_data) |
1243 | else if (drv_data->ssp_type == PXA25x_SSP | ||
1244 | && (spi->bits_per_word < 4 | 1302 | && (spi->bits_per_word < 4 |
1245 | || spi->bits_per_word > 16)) { | 1303 | || spi->bits_per_word > 16)) { |
1246 | dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d " | 1304 | dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d " |
@@ -1259,7 +1317,17 @@ static int setup(struct spi_device *spi) | |||
1259 | return -ENOMEM; | 1317 | return -ENOMEM; |
1260 | } | 1318 | } |
1261 | 1319 | ||
1262 | chip->gpio_cs = -1; | 1320 | if (drv_data->ssp_type == CE4100_SSP) { |
1321 | if (spi->chip_select > 4) { | ||
1322 | dev_err(&spi->dev, "failed setup: " | ||
1323 | "cs number must not be > 4.\n"); | ||
1324 | kfree(chip); | ||
1325 | return -EINVAL; | ||
1326 | } | ||
1327 | |||
1328 | chip->frm = spi->chip_select; | ||
1329 | } else | ||
1330 | chip->gpio_cs = -1; | ||
1263 | chip->enable_dma = 0; | 1331 | chip->enable_dma = 0; |
1264 | chip->timeout = TIMOUT_DFLT; | 1332 | chip->timeout = TIMOUT_DFLT; |
1265 | chip->dma_burst_size = drv_data->master_info->enable_dma ? | 1333 | chip->dma_burst_size = drv_data->master_info->enable_dma ? |
@@ -1315,7 +1383,7 @@ static int setup(struct spi_device *spi) | |||
1315 | | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); | 1383 | | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); |
1316 | 1384 | ||
1317 | /* NOTE: PXA25x_SSP _could_ use external clocking ... */ | 1385 | /* NOTE: PXA25x_SSP _could_ use external clocking ... */ |
1318 | if (drv_data->ssp_type != PXA25x_SSP) | 1386 | if (!pxa25x_ssp_comp(drv_data)) |
1319 | dev_dbg(&spi->dev, "%ld Hz actual, %s\n", | 1387 | dev_dbg(&spi->dev, "%ld Hz actual, %s\n", |
1320 | clk_get_rate(ssp->clk) | 1388 | clk_get_rate(ssp->clk) |
1321 | / (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)), | 1389 | / (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)), |
@@ -1350,23 +1418,27 @@ static int setup(struct spi_device *spi) | |||
1350 | 1418 | ||
1351 | spi_set_ctldata(spi, chip); | 1419 | spi_set_ctldata(spi, chip); |
1352 | 1420 | ||
1421 | if (drv_data->ssp_type == CE4100_SSP) | ||
1422 | return 0; | ||
1423 | |||
1353 | return setup_cs(spi, chip, chip_info); | 1424 | return setup_cs(spi, chip, chip_info); |
1354 | } | 1425 | } |
1355 | 1426 | ||
1356 | static void cleanup(struct spi_device *spi) | 1427 | static void cleanup(struct spi_device *spi) |
1357 | { | 1428 | { |
1358 | struct chip_data *chip = spi_get_ctldata(spi); | 1429 | struct chip_data *chip = spi_get_ctldata(spi); |
1430 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); | ||
1359 | 1431 | ||
1360 | if (!chip) | 1432 | if (!chip) |
1361 | return; | 1433 | return; |
1362 | 1434 | ||
1363 | if (gpio_is_valid(chip->gpio_cs)) | 1435 | if (drv_data->ssp_type != CE4100_SSP && gpio_is_valid(chip->gpio_cs)) |
1364 | gpio_free(chip->gpio_cs); | 1436 | gpio_free(chip->gpio_cs); |
1365 | 1437 | ||
1366 | kfree(chip); | 1438 | kfree(chip); |
1367 | } | 1439 | } |
1368 | 1440 | ||
1369 | static int __init init_queue(struct driver_data *drv_data) | 1441 | static int __devinit init_queue(struct driver_data *drv_data) |
1370 | { | 1442 | { |
1371 | INIT_LIST_HEAD(&drv_data->queue); | 1443 | INIT_LIST_HEAD(&drv_data->queue); |
1372 | spin_lock_init(&drv_data->lock); | 1444 | spin_lock_init(&drv_data->lock); |
@@ -1454,7 +1526,7 @@ static int destroy_queue(struct driver_data *drv_data) | |||
1454 | return 0; | 1526 | return 0; |
1455 | } | 1527 | } |
1456 | 1528 | ||
1457 | static int __init pxa2xx_spi_probe(struct platform_device *pdev) | 1529 | static int __devinit pxa2xx_spi_probe(struct platform_device *pdev) |
1458 | { | 1530 | { |
1459 | struct device *dev = &pdev->dev; | 1531 | struct device *dev = &pdev->dev; |
1460 | struct pxa2xx_spi_master *platform_info; | 1532 | struct pxa2xx_spi_master *platform_info; |
@@ -1484,6 +1556,10 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1484 | drv_data->pdev = pdev; | 1556 | drv_data->pdev = pdev; |
1485 | drv_data->ssp = ssp; | 1557 | drv_data->ssp = ssp; |
1486 | 1558 | ||
1559 | master->dev.parent = &pdev->dev; | ||
1560 | #ifdef CONFIG_OF | ||
1561 | master->dev.of_node = pdev->dev.of_node; | ||
1562 | #endif | ||
1487 | /* the spi->mode bits understood by this driver: */ | 1563 | /* the spi->mode bits understood by this driver: */ |
1488 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 1564 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
1489 | 1565 | ||
@@ -1500,7 +1576,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1500 | 1576 | ||
1501 | drv_data->ioaddr = ssp->mmio_base; | 1577 | drv_data->ioaddr = ssp->mmio_base; |
1502 | drv_data->ssdr_physical = ssp->phys_base + SSDR; | 1578 | drv_data->ssdr_physical = ssp->phys_base + SSDR; |
1503 | if (ssp->type == PXA25x_SSP) { | 1579 | if (pxa25x_ssp_comp(drv_data)) { |
1504 | drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; | 1580 | drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; |
1505 | drv_data->dma_cr1 = 0; | 1581 | drv_data->dma_cr1 = 0; |
1506 | drv_data->clear_sr = SSSR_ROR; | 1582 | drv_data->clear_sr = SSSR_ROR; |
@@ -1512,7 +1588,8 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1512 | drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR; | 1588 | drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR; |
1513 | } | 1589 | } |
1514 | 1590 | ||
1515 | status = request_irq(ssp->irq, ssp_int, 0, dev_name(dev), drv_data); | 1591 | status = request_irq(ssp->irq, ssp_int, IRQF_SHARED, dev_name(dev), |
1592 | drv_data); | ||
1516 | if (status < 0) { | 1593 | if (status < 0) { |
1517 | dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq); | 1594 | dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq); |
1518 | goto out_error_master_alloc; | 1595 | goto out_error_master_alloc; |
@@ -1561,7 +1638,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1561 | | SSCR0_Motorola | 1638 | | SSCR0_Motorola |
1562 | | SSCR0_DataSize(8), | 1639 | | SSCR0_DataSize(8), |
1563 | drv_data->ioaddr); | 1640 | drv_data->ioaddr); |
1564 | if (drv_data->ssp_type != PXA25x_SSP) | 1641 | if (!pxa25x_ssp_comp(drv_data)) |
1565 | write_SSTO(0, drv_data->ioaddr); | 1642 | write_SSTO(0, drv_data->ioaddr); |
1566 | write_SSPSP(0, drv_data->ioaddr); | 1643 | write_SSPSP(0, drv_data->ioaddr); |
1567 | 1644 | ||
@@ -1723,13 +1800,14 @@ static struct platform_driver driver = { | |||
1723 | .pm = &pxa2xx_spi_pm_ops, | 1800 | .pm = &pxa2xx_spi_pm_ops, |
1724 | #endif | 1801 | #endif |
1725 | }, | 1802 | }, |
1803 | .probe = pxa2xx_spi_probe, | ||
1726 | .remove = pxa2xx_spi_remove, | 1804 | .remove = pxa2xx_spi_remove, |
1727 | .shutdown = pxa2xx_spi_shutdown, | 1805 | .shutdown = pxa2xx_spi_shutdown, |
1728 | }; | 1806 | }; |
1729 | 1807 | ||
1730 | static int __init pxa2xx_spi_init(void) | 1808 | static int __init pxa2xx_spi_init(void) |
1731 | { | 1809 | { |
1732 | return platform_driver_probe(&driver, pxa2xx_spi_probe); | 1810 | return platform_driver_register(&driver); |
1733 | } | 1811 | } |
1734 | subsys_initcall(pxa2xx_spi_init); | 1812 | subsys_initcall(pxa2xx_spi_init); |
1735 | 1813 | ||
diff --git a/drivers/spi/pxa2xx_spi_pci.c b/drivers/spi/pxa2xx_spi_pci.c new file mode 100644 index 000000000000..351d8a375b57 --- /dev/null +++ b/drivers/spi/pxa2xx_spi_pci.c | |||
@@ -0,0 +1,201 @@ | |||
1 | /* | ||
2 | * CE4100's SPI device is more or less the same one as found on PXA | ||
3 | * | ||
4 | */ | ||
5 | #include <linux/pci.h> | ||
6 | #include <linux/platform_device.h> | ||
7 | #include <linux/of_device.h> | ||
8 | #include <linux/spi/pxa2xx_spi.h> | ||
9 | |||
10 | struct awesome_struct { | ||
11 | struct ssp_device ssp; | ||
12 | struct platform_device spi_pdev; | ||
13 | struct pxa2xx_spi_master spi_pdata; | ||
14 | }; | ||
15 | |||
16 | static DEFINE_MUTEX(ssp_lock); | ||
17 | static LIST_HEAD(ssp_list); | ||
18 | |||
19 | struct ssp_device *pxa_ssp_request(int port, const char *label) | ||
20 | { | ||
21 | struct ssp_device *ssp = NULL; | ||
22 | |||
23 | mutex_lock(&ssp_lock); | ||
24 | |||
25 | list_for_each_entry(ssp, &ssp_list, node) { | ||
26 | if (ssp->port_id == port && ssp->use_count == 0) { | ||
27 | ssp->use_count++; | ||
28 | ssp->label = label; | ||
29 | break; | ||
30 | } | ||
31 | } | ||
32 | |||
33 | mutex_unlock(&ssp_lock); | ||
34 | |||
35 | if (&ssp->node == &ssp_list) | ||
36 | return NULL; | ||
37 | |||
38 | return ssp; | ||
39 | } | ||
40 | EXPORT_SYMBOL_GPL(pxa_ssp_request); | ||
41 | |||
42 | void pxa_ssp_free(struct ssp_device *ssp) | ||
43 | { | ||
44 | mutex_lock(&ssp_lock); | ||
45 | if (ssp->use_count) { | ||
46 | ssp->use_count--; | ||
47 | ssp->label = NULL; | ||
48 | } else | ||
49 | dev_err(&ssp->pdev->dev, "device already free\n"); | ||
50 | mutex_unlock(&ssp_lock); | ||
51 | } | ||
52 | EXPORT_SYMBOL_GPL(pxa_ssp_free); | ||
53 | |||
54 | static void plat_dev_release(struct device *dev) | ||
55 | { | ||
56 | struct awesome_struct *as = container_of(dev, | ||
57 | struct awesome_struct, spi_pdev.dev); | ||
58 | |||
59 | of_device_node_put(&as->spi_pdev.dev); | ||
60 | } | ||
61 | |||
62 | static int __devinit ce4100_spi_probe(struct pci_dev *dev, | ||
63 | const struct pci_device_id *ent) | ||
64 | { | ||
65 | int ret; | ||
66 | resource_size_t phys_beg; | ||
67 | resource_size_t phys_len; | ||
68 | struct awesome_struct *spi_info; | ||
69 | struct platform_device *pdev; | ||
70 | struct pxa2xx_spi_master *spi_pdata; | ||
71 | struct ssp_device *ssp; | ||
72 | |||
73 | ret = pci_enable_device(dev); | ||
74 | if (ret) | ||
75 | return ret; | ||
76 | |||
77 | phys_beg = pci_resource_start(dev, 0); | ||
78 | phys_len = pci_resource_len(dev, 0); | ||
79 | |||
80 | if (!request_mem_region(phys_beg, phys_len, | ||
81 | "CE4100 SPI")) { | ||
82 | dev_err(&dev->dev, "Can't request register space.\n"); | ||
83 | ret = -EBUSY; | ||
84 | return ret; | ||
85 | } | ||
86 | |||
87 | spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); | ||
88 | if (!spi_info) { | ||
89 | ret = -ENOMEM; | ||
90 | goto err_kz; | ||
91 | } | ||
92 | ssp = &spi_info->ssp; | ||
93 | pdev = &spi_info->spi_pdev; | ||
94 | spi_pdata = &spi_info->spi_pdata; | ||
95 | |||
96 | pdev->name = "pxa2xx-spi"; | ||
97 | pdev->id = dev->devfn; | ||
98 | pdev->dev.parent = &dev->dev; | ||
99 | pdev->dev.platform_data = &spi_info->spi_pdata; | ||
100 | |||
101 | #ifdef CONFIG_OF | ||
102 | pdev->dev.of_node = dev->dev.of_node; | ||
103 | #endif | ||
104 | pdev->dev.release = plat_dev_release; | ||
105 | |||
106 | spi_pdata->num_chipselect = dev->devfn; | ||
107 | |||
108 | ssp->phys_base = pci_resource_start(dev, 0); | ||
109 | ssp->mmio_base = ioremap(phys_beg, phys_len); | ||
110 | if (!ssp->mmio_base) { | ||
111 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); | ||
112 | ret = -EIO; | ||
113 | goto err_remap; | ||
114 | } | ||
115 | ssp->irq = dev->irq; | ||
116 | ssp->port_id = pdev->id; | ||
117 | ssp->type = PXA25x_SSP; | ||
118 | |||
119 | mutex_lock(&ssp_lock); | ||
120 | list_add(&ssp->node, &ssp_list); | ||
121 | mutex_unlock(&ssp_lock); | ||
122 | |||
123 | pci_set_drvdata(dev, spi_info); | ||
124 | |||
125 | ret = platform_device_register(pdev); | ||
126 | if (ret) | ||
127 | goto err_dev_add; | ||
128 | |||
129 | return ret; | ||
130 | |||
131 | err_dev_add: | ||
132 | pci_set_drvdata(dev, NULL); | ||
133 | mutex_lock(&ssp_lock); | ||
134 | list_del(&ssp->node); | ||
135 | mutex_unlock(&ssp_lock); | ||
136 | iounmap(ssp->mmio_base); | ||
137 | |||
138 | err_remap: | ||
139 | kfree(spi_info); | ||
140 | |||
141 | err_kz: | ||
142 | release_mem_region(phys_beg, phys_len); | ||
143 | |||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | static void __devexit ce4100_spi_remove(struct pci_dev *dev) | ||
148 | { | ||
149 | struct awesome_struct *spi_info; | ||
150 | struct platform_device *pdev; | ||
151 | struct ssp_device *ssp; | ||
152 | |||
153 | spi_info = pci_get_drvdata(dev); | ||
154 | |||
155 | ssp = &spi_info->ssp; | ||
156 | pdev = &spi_info->spi_pdev; | ||
157 | |||
158 | platform_device_unregister(pdev); | ||
159 | |||
160 | iounmap(ssp->mmio_base); | ||
161 | release_mem_region(pci_resource_start(dev, 0), | ||
162 | pci_resource_len(dev, 0)); | ||
163 | |||
164 | mutex_lock(&ssp_lock); | ||
165 | list_del(&ssp->node); | ||
166 | mutex_unlock(&ssp_lock); | ||
167 | |||
168 | pci_set_drvdata(dev, NULL); | ||
169 | pci_disable_device(dev); | ||
170 | kfree(spi_info); | ||
171 | } | ||
172 | |||
173 | static struct pci_device_id ce4100_spi_devices[] __devinitdata = { | ||
174 | |||
175 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, | ||
176 | { }, | ||
177 | }; | ||
178 | MODULE_DEVICE_TABLE(pci, ce4100_spi_devices); | ||
179 | |||
180 | static struct pci_driver ce4100_spi_driver = { | ||
181 | .name = "ce4100_spi", | ||
182 | .id_table = ce4100_spi_devices, | ||
183 | .probe = ce4100_spi_probe, | ||
184 | .remove = __devexit_p(ce4100_spi_remove), | ||
185 | }; | ||
186 | |||
187 | static int __init ce4100_spi_init(void) | ||
188 | { | ||
189 | return pci_register_driver(&ce4100_spi_driver); | ||
190 | } | ||
191 | module_init(ce4100_spi_init); | ||
192 | |||
193 | static void __exit ce4100_spi_exit(void) | ||
194 | { | ||
195 | pci_unregister_driver(&ce4100_spi_driver); | ||
196 | } | ||
197 | module_exit(ce4100_spi_exit); | ||
198 | |||
199 | MODULE_DESCRIPTION("CE4100 PCI-SPI glue code for PXA's driver"); | ||
200 | MODULE_LICENSE("GPL v2"); | ||
201 | MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); | ||
diff --git a/arch/arm/plat-pxa/include/plat/ssp.h b/include/linux/pxa2xx_ssp.h index fe43150690ed..2f691e4e6222 100644 --- a/arch/arm/plat-pxa/include/plat/ssp.h +++ b/include/linux/pxa2xx_ssp.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * ssp.h | 2 | * pxa2xx_ssp.h |
3 | * | 3 | * |
4 | * Copyright (C) 2003 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
5 | * | 5 | * |
@@ -16,8 +16,8 @@ | |||
16 | * PXA3xx SSP1, SSP2, SSP3, SSP4 | 16 | * PXA3xx SSP1, SSP2, SSP3, SSP4 |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #ifndef __ASM_ARCH_SSP_H | 19 | #ifndef __LINUX_SSP_H |
20 | #define __ASM_ARCH_SSP_H | 20 | #define __LINUX_SSP_H |
21 | 21 | ||
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
@@ -71,11 +71,8 @@ | |||
71 | #define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ | 71 | #define SSCR1_SPO (1 << 3) /* Motorola SPI SSPSCLK polarity setting */ |
72 | #define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ | 72 | #define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ |
73 | #define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ | 73 | #define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ |
74 | #define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ | ||
75 | #define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ | ||
76 | #define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ | ||
77 | #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ | ||
78 | 74 | ||
75 | #define SSSR_ALT_FRM_MASK 3 /* Masks the SFRM signal number */ | ||
79 | #define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ | 76 | #define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ |
80 | #define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ | 77 | #define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ |
81 | #define SSSR_BSY (1 << 4) /* SSP Busy */ | 78 | #define SSSR_BSY (1 << 4) /* SSP Busy */ |
@@ -83,6 +80,31 @@ | |||
83 | #define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ | 80 | #define SSSR_RFS (1 << 6) /* Receive FIFO Service Request */ |
84 | #define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ | 81 | #define SSSR_ROR (1 << 7) /* Receive FIFO Overrun */ |
85 | 82 | ||
83 | #ifdef CONFIG_ARCH_PXA | ||
84 | #define RX_THRESH_DFLT 8 | ||
85 | #define TX_THRESH_DFLT 8 | ||
86 | |||
87 | #define SSSR_TFL_MASK (0xf << 8) /* Transmit FIFO Level mask */ | ||
88 | #define SSSR_RFL_MASK (0xf << 12) /* Receive FIFO Level mask */ | ||
89 | |||
90 | #define SSCR1_TFT (0x000003c0) /* Transmit FIFO Threshold (mask) */ | ||
91 | #define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */ | ||
92 | #define SSCR1_RFT (0x00003c00) /* Receive FIFO Threshold (mask) */ | ||
93 | #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */ | ||
94 | |||
95 | #else | ||
96 | |||
97 | #define RX_THRESH_DFLT 2 | ||
98 | #define TX_THRESH_DFLT 2 | ||
99 | |||
100 | #define SSSR_TFL_MASK (0x3 << 8) /* Transmit FIFO Level mask */ | ||
101 | #define SSSR_RFL_MASK (0x3 << 12) /* Receive FIFO Level mask */ | ||
102 | |||
103 | #define SSCR1_TFT (0x000000c0) /* Transmit FIFO Threshold (mask) */ | ||
104 | #define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..4] */ | ||
105 | #define SSCR1_RFT (0x00000c00) /* Receive FIFO Threshold (mask) */ | ||
106 | #define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ | ||
107 | #endif | ||
86 | 108 | ||
87 | /* extra bits in PXA255, PXA26x and PXA27x SSP ports */ | 109 | /* extra bits in PXA255, PXA26x and PXA27x SSP ports */ |
88 | #define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ | 110 | #define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ |
@@ -139,6 +161,7 @@ enum pxa_ssp_type { | |||
139 | PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ | 161 | PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ |
140 | PXA27x_SSP, | 162 | PXA27x_SSP, |
141 | PXA168_SSP, | 163 | PXA168_SSP, |
164 | CE4100_SSP, | ||
142 | }; | 165 | }; |
143 | 166 | ||
144 | struct ssp_device { | 167 | struct ssp_device { |
@@ -183,4 +206,4 @@ static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg) | |||
183 | 206 | ||
184 | struct ssp_device *pxa_ssp_request(int port, const char *label); | 207 | struct ssp_device *pxa_ssp_request(int port, const char *label); |
185 | void pxa_ssp_free(struct ssp_device *); | 208 | void pxa_ssp_free(struct ssp_device *); |
186 | #endif /* __ASM_ARCH_SSP_H */ | 209 | #endif |
diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h new file mode 100644 index 000000000000..d3e1075f7b60 --- /dev/null +++ b/include/linux/spi/pxa2xx_spi.h | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | #ifndef __linux_pxa2xx_spi_h | ||
19 | #define __linux_pxa2xx_spi_h | ||
20 | |||
21 | #include <linux/pxa2xx_ssp.h> | ||
22 | |||
23 | #define PXA2XX_CS_ASSERT (0x01) | ||
24 | #define PXA2XX_CS_DEASSERT (0x02) | ||
25 | |||
26 | /* device.platform_data for SSP controller devices */ | ||
27 | struct pxa2xx_spi_master { | ||
28 | u32 clock_enable; | ||
29 | u16 num_chipselect; | ||
30 | u8 enable_dma; | ||
31 | }; | ||
32 | |||
33 | /* spi_board_info.controller_data for SPI slave devices, | ||
34 | * copied to spi_device.platform_data ... mostly for dma tuning | ||
35 | */ | ||
36 | struct pxa2xx_spi_chip { | ||
37 | u8 tx_threshold; | ||
38 | u8 rx_threshold; | ||
39 | u8 dma_burst_size; | ||
40 | u32 timeout; | ||
41 | u8 enable_loopback; | ||
42 | int gpio_cs; | ||
43 | void (*cs_control)(u32 command); | ||
44 | }; | ||
45 | |||
46 | #ifdef CONFIG_ARCH_PXA | ||
47 | |||
48 | #include <linux/clk.h> | ||
49 | #include <mach/dma.h> | ||
50 | |||
51 | extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info); | ||
52 | |||
53 | #else | ||
54 | /* | ||
55 | * This is the implemtation for CE4100 on x86. ARM defines them in mach/ or | ||
56 | * plat/ include path. | ||
57 | * The CE4100 does not provide DMA support. This bits are here to let the driver | ||
58 | * compile and will never be used. Maybe we get DMA support at a later point in | ||
59 | * time. | ||
60 | */ | ||
61 | |||
62 | #define DCSR(n) (n) | ||
63 | #define DSADR(n) (n) | ||
64 | #define DTADR(n) (n) | ||
65 | #define DCMD(n) (n) | ||
66 | #define DRCMR(n) (n) | ||
67 | |||
68 | #define DCSR_RUN (1 << 31) /* Run Bit */ | ||
69 | #define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch */ | ||
70 | #define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable */ | ||
71 | #define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */ | ||
72 | #define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */ | ||
73 | #define DCSR_ENDINTR (1 << 2) /* End Interrupt */ | ||
74 | #define DCSR_STARTINTR (1 << 1) /* Start Interrupt */ | ||
75 | #define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt */ | ||
76 | |||
77 | #define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable */ | ||
78 | #define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */ | ||
79 | #define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */ | ||
80 | #define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */ | ||
81 | #define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */ | ||
82 | #define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */ | ||
83 | #define DCSR_EORINTR (1 << 9) /* The end of Receive */ | ||
84 | |||
85 | #define DRCMR_MAPVLD (1 << 7) /* Map Valid */ | ||
86 | #define DRCMR_CHLNUM 0x1f /* mask for Channel Number */ | ||
87 | |||
88 | #define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor */ | ||
89 | #define DDADR_STOP (1 << 0) /* Stop */ | ||
90 | |||
91 | #define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */ | ||
92 | #define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */ | ||
93 | #define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */ | ||
94 | #define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */ | ||
95 | #define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ | ||
96 | #define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */ | ||
97 | #define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */ | ||
98 | #define DCMD_BURST8 (1 << 16) /* 8 byte burst */ | ||
99 | #define DCMD_BURST16 (2 << 16) /* 16 byte burst */ | ||
100 | #define DCMD_BURST32 (3 << 16) /* 32 byte burst */ | ||
101 | #define DCMD_WIDTH1 (1 << 14) /* 1 byte width */ | ||
102 | #define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */ | ||
103 | #define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */ | ||
104 | #define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */ | ||
105 | |||
106 | /* | ||
107 | * Descriptor structure for PXA's DMA engine | ||
108 | * Note: this structure must always be aligned to a 16-byte boundary. | ||
109 | */ | ||
110 | |||
111 | typedef enum { | ||
112 | DMA_PRIO_HIGH = 0, | ||
113 | DMA_PRIO_MEDIUM = 1, | ||
114 | DMA_PRIO_LOW = 2 | ||
115 | } pxa_dma_prio; | ||
116 | |||
117 | /* | ||
118 | * DMA registration | ||
119 | */ | ||
120 | |||
121 | static inline int pxa_request_dma(char *name, | ||
122 | pxa_dma_prio prio, | ||
123 | void (*irq_handler)(int, void *), | ||
124 | void *data) | ||
125 | { | ||
126 | return -ENODEV; | ||
127 | } | ||
128 | |||
129 | static inline void pxa_free_dma(int dma_ch) | ||
130 | { | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * The CE4100 does not have the clk framework implemented and SPI clock can | ||
135 | * not be switched on/off or the divider changed. | ||
136 | */ | ||
137 | static inline void clk_disable(struct clk *clk) | ||
138 | { | ||
139 | } | ||
140 | |||
141 | static inline int clk_enable(struct clk *clk) | ||
142 | { | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static inline unsigned long clk_get_rate(struct clk *clk) | ||
147 | { | ||
148 | return 3686400; | ||
149 | } | ||
150 | |||
151 | #endif | ||
152 | #endif | ||
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index b439eee462cb..8ad93ee2e92b 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/pxa2xx_ssp.h> | ||
23 | 24 | ||
24 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
25 | 26 | ||
@@ -33,7 +34,6 @@ | |||
33 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
34 | #include <mach/dma.h> | 35 | #include <mach/dma.h> |
35 | #include <mach/audio.h> | 36 | #include <mach/audio.h> |
36 | #include <plat/ssp.h> | ||
37 | 37 | ||
38 | #include "../../arm/pxa2xx-pcm.h" | 38 | #include "../../arm/pxa2xx-pcm.h" |
39 | #include "pxa-ssp.h" | 39 | #include "pxa-ssp.h" |