diff options
-rw-r--r-- | Documentation/spi/ep93xx_spi | 105 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/edb93xx.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/simone.c | 63 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/vision_ep9307.c | 88 | ||||
-rw-r--r-- | drivers/spi/spi-ep93xx.c | 139 | ||||
-rw-r--r-- | include/linux/platform_data/spi-ep93xx.h | 17 |
6 files changed, 74 insertions, 369 deletions
diff --git a/Documentation/spi/ep93xx_spi b/Documentation/spi/ep93xx_spi deleted file mode 100644 index 832ddce6e5fb..000000000000 --- a/Documentation/spi/ep93xx_spi +++ /dev/null | |||
@@ -1,105 +0,0 @@ | |||
1 | Cirrus EP93xx SPI controller driver HOWTO | ||
2 | ========================================= | ||
3 | |||
4 | ep93xx_spi driver brings SPI master support for EP93xx SPI controller. Chip | ||
5 | selects are implemented with GPIO lines. | ||
6 | |||
7 | NOTE: If possible, don't use SFRMOUT (SFRM1) signal as a chip select. It will | ||
8 | not work correctly (it cannot be controlled by software). Use GPIO lines | ||
9 | instead. | ||
10 | |||
11 | Sample configuration | ||
12 | ==================== | ||
13 | |||
14 | Typically driver configuration is done in platform board files (the files under | ||
15 | arch/arm/mach-ep93xx/*.c). In this example we configure MMC over SPI through | ||
16 | this driver on TS-7260 board. You can adapt the code to suit your needs. | ||
17 | |||
18 | This example uses EGPIO9 as SD/MMC card chip select (this is wired in DIO1 | ||
19 | header on the board). | ||
20 | |||
21 | You need to select CONFIG_MMC_SPI to use mmc_spi driver. | ||
22 | |||
23 | arch/arm/mach-ep93xx/ts72xx.c: | ||
24 | |||
25 | ... | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/spi/spi.h> | ||
28 | |||
29 | #include <linux/platform_data/spi-ep93xx.h> | ||
30 | |||
31 | /* this is our GPIO line used for chip select */ | ||
32 | #define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO9 | ||
33 | |||
34 | static int ts72xx_mmc_spi_setup(struct spi_device *spi) | ||
35 | { | ||
36 | int err; | ||
37 | |||
38 | err = gpio_request(MMC_CHIP_SELECT_GPIO, spi->modalias); | ||
39 | if (err) | ||
40 | return err; | ||
41 | |||
42 | gpio_direction_output(MMC_CHIP_SELECT_GPIO, 1); | ||
43 | |||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static void ts72xx_mmc_spi_cleanup(struct spi_device *spi) | ||
48 | { | ||
49 | gpio_set_value(MMC_CHIP_SELECT_GPIO, 1); | ||
50 | gpio_direction_input(MMC_CHIP_SELECT_GPIO); | ||
51 | gpio_free(MMC_CHIP_SELECT_GPIO); | ||
52 | } | ||
53 | |||
54 | static void ts72xx_mmc_spi_cs_control(struct spi_device *spi, int value) | ||
55 | { | ||
56 | gpio_set_value(MMC_CHIP_SELECT_GPIO, value); | ||
57 | } | ||
58 | |||
59 | static struct ep93xx_spi_chip_ops ts72xx_mmc_spi_ops = { | ||
60 | .setup = ts72xx_mmc_spi_setup, | ||
61 | .cleanup = ts72xx_mmc_spi_cleanup, | ||
62 | .cs_control = ts72xx_mmc_spi_cs_control, | ||
63 | }; | ||
64 | |||
65 | static struct spi_board_info ts72xx_spi_devices[] __initdata = { | ||
66 | { | ||
67 | .modalias = "mmc_spi", | ||
68 | .controller_data = &ts72xx_mmc_spi_ops, | ||
69 | /* | ||
70 | * We use 10 MHz even though the maximum is 7.4 MHz. The driver | ||
71 | * will limit it automatically to max. frequency. | ||
72 | */ | ||
73 | .max_speed_hz = 10 * 1000 * 1000, | ||
74 | .bus_num = 0, | ||
75 | .chip_select = 0, | ||
76 | .mode = SPI_MODE_0, | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | static struct ep93xx_spi_info ts72xx_spi_info = { | ||
81 | .num_chipselect = ARRAY_SIZE(ts72xx_spi_devices), | ||
82 | }; | ||
83 | |||
84 | static void __init ts72xx_init_machine(void) | ||
85 | { | ||
86 | ... | ||
87 | ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices, | ||
88 | ARRAY_SIZE(ts72xx_spi_devices)); | ||
89 | } | ||
90 | |||
91 | The driver can use DMA for the transfers also. In this case ts72xx_spi_info | ||
92 | becomes: | ||
93 | |||
94 | static struct ep93xx_spi_info ts72xx_spi_info = { | ||
95 | .num_chipselect = ARRAY_SIZE(ts72xx_spi_devices), | ||
96 | .use_dma = true; | ||
97 | }; | ||
98 | |||
99 | Note that CONFIG_EP93XX_DMA should be enabled as well. | ||
100 | |||
101 | Thanks to | ||
102 | ========= | ||
103 | Martin Guy, H. Hartley Sweeten and others who helped me during development of | ||
104 | the driver. Simplemachines.it donated me a Sim.One board which I used testing | ||
105 | the driver on EP9307. | ||
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index ad92d9f7e4df..0ac176386789 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/gpio.h> | ||
31 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
32 | #include <linux/i2c-gpio.h> | 31 | #include <linux/i2c-gpio.h> |
33 | #include <linux/spi/spi.h> | 32 | #include <linux/spi/spi.h> |
@@ -106,33 +105,10 @@ static struct cs4271_platform_data edb93xx_cs4271_data = { | |||
106 | .gpio_nreset = -EINVAL, /* filled in later */ | 105 | .gpio_nreset = -EINVAL, /* filled in later */ |
107 | }; | 106 | }; |
108 | 107 | ||
109 | static int edb93xx_cs4271_hw_setup(struct spi_device *spi) | ||
110 | { | ||
111 | return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6, | ||
112 | GPIOF_OUT_INIT_HIGH, spi->modalias); | ||
113 | } | ||
114 | |||
115 | static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi) | ||
116 | { | ||
117 | gpio_free(EP93XX_GPIO_LINE_EGPIO6); | ||
118 | } | ||
119 | |||
120 | static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value) | ||
121 | { | ||
122 | gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value); | ||
123 | } | ||
124 | |||
125 | static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = { | ||
126 | .setup = edb93xx_cs4271_hw_setup, | ||
127 | .cleanup = edb93xx_cs4271_hw_cleanup, | ||
128 | .cs_control = edb93xx_cs4271_hw_cs_control, | ||
129 | }; | ||
130 | |||
131 | static struct spi_board_info edb93xx_spi_board_info[] __initdata = { | 108 | static struct spi_board_info edb93xx_spi_board_info[] __initdata = { |
132 | { | 109 | { |
133 | .modalias = "cs4271", | 110 | .modalias = "cs4271", |
134 | .platform_data = &edb93xx_cs4271_data, | 111 | .platform_data = &edb93xx_cs4271_data, |
135 | .controller_data = &edb93xx_cs4271_hw, | ||
136 | .max_speed_hz = 6000000, | 112 | .max_speed_hz = 6000000, |
137 | .bus_num = 0, | 113 | .bus_num = 0, |
138 | .chip_select = 0, | 114 | .chip_select = 0, |
@@ -140,8 +116,13 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = { | |||
140 | }, | 116 | }, |
141 | }; | 117 | }; |
142 | 118 | ||
119 | static int edb93xx_spi_chipselects[] __initdata = { | ||
120 | EP93XX_GPIO_LINE_EGPIO6, | ||
121 | }; | ||
122 | |||
143 | static struct ep93xx_spi_info edb93xx_spi_info __initdata = { | 123 | static struct ep93xx_spi_info edb93xx_spi_info __initdata = { |
144 | .num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info), | 124 | .chipselect = edb93xx_spi_chipselects, |
125 | .num_chipselect = ARRAY_SIZE(edb93xx_spi_chipselects), | ||
145 | }; | 126 | }; |
146 | 127 | ||
147 | static void __init edb93xx_register_spi(void) | 128 | static void __init edb93xx_register_spi(void) |
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index 7bb540c421ee..c7a40f245892 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c | |||
@@ -49,56 +49,6 @@ static struct ep93xxfb_mach_info __initdata simone_fb_info = { | |||
49 | #define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0 | 49 | #define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0 |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes | ||
53 | * low between multi-message command blocks. From v1.4, it uses a GPIO instead. | ||
54 | * v1.3 parts will still work, since the signal on SFRMOUT is automatic. | ||
55 | */ | ||
56 | #define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1 | ||
57 | |||
58 | /* | ||
59 | * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal, | ||
60 | * you can leave these empty and pass NULL as .controller_data. | ||
61 | */ | ||
62 | |||
63 | static int simone_mmc_spi_setup(struct spi_device *spi) | ||
64 | { | ||
65 | unsigned int gpio = MMC_CHIP_SELECT_GPIO; | ||
66 | int err; | ||
67 | |||
68 | err = gpio_request(gpio, spi->modalias); | ||
69 | if (err) | ||
70 | return err; | ||
71 | |||
72 | err = gpio_direction_output(gpio, 1); | ||
73 | if (err) { | ||
74 | gpio_free(gpio); | ||
75 | return err; | ||
76 | } | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static void simone_mmc_spi_cleanup(struct spi_device *spi) | ||
82 | { | ||
83 | unsigned int gpio = MMC_CHIP_SELECT_GPIO; | ||
84 | |||
85 | gpio_set_value(gpio, 1); | ||
86 | gpio_direction_input(gpio); | ||
87 | gpio_free(gpio); | ||
88 | } | ||
89 | |||
90 | static void simone_mmc_spi_cs_control(struct spi_device *spi, int value) | ||
91 | { | ||
92 | gpio_set_value(MMC_CHIP_SELECT_GPIO, value); | ||
93 | } | ||
94 | |||
95 | static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = { | ||
96 | .setup = simone_mmc_spi_setup, | ||
97 | .cleanup = simone_mmc_spi_cleanup, | ||
98 | .cs_control = simone_mmc_spi_cs_control, | ||
99 | }; | ||
100 | |||
101 | /* | ||
102 | * MMC card detection GPIO setup. | 52 | * MMC card detection GPIO setup. |
103 | */ | 53 | */ |
104 | 54 | ||
@@ -152,7 +102,6 @@ static struct mmc_spi_platform_data simone_mmc_spi_data = { | |||
152 | static struct spi_board_info simone_spi_devices[] __initdata = { | 102 | static struct spi_board_info simone_spi_devices[] __initdata = { |
153 | { | 103 | { |
154 | .modalias = "mmc_spi", | 104 | .modalias = "mmc_spi", |
155 | .controller_data = &simone_mmc_spi_ops, | ||
156 | .platform_data = &simone_mmc_spi_data, | 105 | .platform_data = &simone_mmc_spi_data, |
157 | /* | 106 | /* |
158 | * We use 10 MHz even though the maximum is 3.7 MHz. The driver | 107 | * We use 10 MHz even though the maximum is 3.7 MHz. The driver |
@@ -165,8 +114,18 @@ static struct spi_board_info simone_spi_devices[] __initdata = { | |||
165 | }, | 114 | }, |
166 | }; | 115 | }; |
167 | 116 | ||
117 | /* | ||
118 | * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes | ||
119 | * low between multi-message command blocks. From v1.4, it uses a GPIO instead. | ||
120 | * v1.3 parts will still work, since the signal on SFRMOUT is automatic. | ||
121 | */ | ||
122 | static int simone_spi_chipselects[] __initdata = { | ||
123 | EP93XX_GPIO_LINE_EGPIO1, | ||
124 | }; | ||
125 | |||
168 | static struct ep93xx_spi_info simone_spi_info __initdata = { | 126 | static struct ep93xx_spi_info simone_spi_info __initdata = { |
169 | .num_chipselect = ARRAY_SIZE(simone_spi_devices), | 127 | .chipselect = simone_spi_chipselects, |
128 | .num_chipselect = ARRAY_SIZE(simone_spi_chipselects), | ||
170 | .use_dma = 1, | 129 | .use_dma = 1, |
171 | }; | 130 | }; |
172 | 131 | ||
diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index 5cced5988498..1daf9441058c 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c | |||
@@ -175,33 +175,9 @@ static struct cs4271_platform_data vision_cs4271_data = { | |||
175 | .gpio_nreset = EP93XX_GPIO_LINE_H(2), | 175 | .gpio_nreset = EP93XX_GPIO_LINE_H(2), |
176 | }; | 176 | }; |
177 | 177 | ||
178 | static int vision_cs4271_hw_setup(struct spi_device *spi) | ||
179 | { | ||
180 | return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6, | ||
181 | GPIOF_OUT_INIT_HIGH, spi->modalias); | ||
182 | } | ||
183 | |||
184 | static void vision_cs4271_hw_cleanup(struct spi_device *spi) | ||
185 | { | ||
186 | gpio_free(EP93XX_GPIO_LINE_EGPIO6); | ||
187 | } | ||
188 | |||
189 | static void vision_cs4271_hw_cs_control(struct spi_device *spi, int value) | ||
190 | { | ||
191 | gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value); | ||
192 | } | ||
193 | |||
194 | static struct ep93xx_spi_chip_ops vision_cs4271_hw = { | ||
195 | .setup = vision_cs4271_hw_setup, | ||
196 | .cleanup = vision_cs4271_hw_cleanup, | ||
197 | .cs_control = vision_cs4271_hw_cs_control, | ||
198 | }; | ||
199 | |||
200 | /************************************************************************* | 178 | /************************************************************************* |
201 | * SPI Flash | 179 | * SPI Flash |
202 | *************************************************************************/ | 180 | *************************************************************************/ |
203 | #define VISION_SPI_FLASH_CS EP93XX_GPIO_LINE_EGPIO7 | ||
204 | |||
205 | static struct mtd_partition vision_spi_flash_partitions[] = { | 181 | static struct mtd_partition vision_spi_flash_partitions[] = { |
206 | { | 182 | { |
207 | .name = "SPI bootstrap", | 183 | .name = "SPI bootstrap", |
@@ -224,68 +200,20 @@ static struct flash_platform_data vision_spi_flash_data = { | |||
224 | .nr_parts = ARRAY_SIZE(vision_spi_flash_partitions), | 200 | .nr_parts = ARRAY_SIZE(vision_spi_flash_partitions), |
225 | }; | 201 | }; |
226 | 202 | ||
227 | static int vision_spi_flash_hw_setup(struct spi_device *spi) | ||
228 | { | ||
229 | return gpio_request_one(VISION_SPI_FLASH_CS, GPIOF_INIT_HIGH, | ||
230 | spi->modalias); | ||
231 | } | ||
232 | |||
233 | static void vision_spi_flash_hw_cleanup(struct spi_device *spi) | ||
234 | { | ||
235 | gpio_free(VISION_SPI_FLASH_CS); | ||
236 | } | ||
237 | |||
238 | static void vision_spi_flash_hw_cs_control(struct spi_device *spi, int value) | ||
239 | { | ||
240 | gpio_set_value(VISION_SPI_FLASH_CS, value); | ||
241 | } | ||
242 | |||
243 | static struct ep93xx_spi_chip_ops vision_spi_flash_hw = { | ||
244 | .setup = vision_spi_flash_hw_setup, | ||
245 | .cleanup = vision_spi_flash_hw_cleanup, | ||
246 | .cs_control = vision_spi_flash_hw_cs_control, | ||
247 | }; | ||
248 | |||
249 | /************************************************************************* | 203 | /************************************************************************* |
250 | * SPI SD/MMC host | 204 | * SPI SD/MMC host |
251 | *************************************************************************/ | 205 | *************************************************************************/ |
252 | #define VISION_SPI_MMC_CS EP93XX_GPIO_LINE_G(2) | ||
253 | #define VISION_SPI_MMC_WP EP93XX_GPIO_LINE_F(0) | ||
254 | #define VISION_SPI_MMC_CD EP93XX_GPIO_LINE_EGPIO15 | ||
255 | |||
256 | static struct mmc_spi_platform_data vision_spi_mmc_data = { | 206 | static struct mmc_spi_platform_data vision_spi_mmc_data = { |
257 | .detect_delay = 100, | 207 | .detect_delay = 100, |
258 | .powerup_msecs = 100, | 208 | .powerup_msecs = 100, |
259 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 209 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
260 | .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, | 210 | .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, |
261 | .cd_gpio = VISION_SPI_MMC_CD, | 211 | .cd_gpio = EP93XX_GPIO_LINE_EGPIO15, |
262 | .cd_debounce = 1, | 212 | .cd_debounce = 1, |
263 | .ro_gpio = VISION_SPI_MMC_WP, | 213 | .ro_gpio = EP93XX_GPIO_LINE_F(0), |
264 | .caps2 = MMC_CAP2_RO_ACTIVE_HIGH, | 214 | .caps2 = MMC_CAP2_RO_ACTIVE_HIGH, |
265 | }; | 215 | }; |
266 | 216 | ||
267 | static int vision_spi_mmc_hw_setup(struct spi_device *spi) | ||
268 | { | ||
269 | return gpio_request_one(VISION_SPI_MMC_CS, GPIOF_INIT_HIGH, | ||
270 | spi->modalias); | ||
271 | } | ||
272 | |||
273 | static void vision_spi_mmc_hw_cleanup(struct spi_device *spi) | ||
274 | { | ||
275 | gpio_free(VISION_SPI_MMC_CS); | ||
276 | } | ||
277 | |||
278 | static void vision_spi_mmc_hw_cs_control(struct spi_device *spi, int value) | ||
279 | { | ||
280 | gpio_set_value(VISION_SPI_MMC_CS, value); | ||
281 | } | ||
282 | |||
283 | static struct ep93xx_spi_chip_ops vision_spi_mmc_hw = { | ||
284 | .setup = vision_spi_mmc_hw_setup, | ||
285 | .cleanup = vision_spi_mmc_hw_cleanup, | ||
286 | .cs_control = vision_spi_mmc_hw_cs_control, | ||
287 | }; | ||
288 | |||
289 | /************************************************************************* | 217 | /************************************************************************* |
290 | * SPI Bus | 218 | * SPI Bus |
291 | *************************************************************************/ | 219 | *************************************************************************/ |
@@ -293,7 +221,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { | |||
293 | { | 221 | { |
294 | .modalias = "cs4271", | 222 | .modalias = "cs4271", |
295 | .platform_data = &vision_cs4271_data, | 223 | .platform_data = &vision_cs4271_data, |
296 | .controller_data = &vision_cs4271_hw, | ||
297 | .max_speed_hz = 6000000, | 224 | .max_speed_hz = 6000000, |
298 | .bus_num = 0, | 225 | .bus_num = 0, |
299 | .chip_select = 0, | 226 | .chip_select = 0, |
@@ -301,7 +228,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { | |||
301 | }, { | 228 | }, { |
302 | .modalias = "sst25l", | 229 | .modalias = "sst25l", |
303 | .platform_data = &vision_spi_flash_data, | 230 | .platform_data = &vision_spi_flash_data, |
304 | .controller_data = &vision_spi_flash_hw, | ||
305 | .max_speed_hz = 20000000, | 231 | .max_speed_hz = 20000000, |
306 | .bus_num = 0, | 232 | .bus_num = 0, |
307 | .chip_select = 1, | 233 | .chip_select = 1, |
@@ -309,7 +235,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { | |||
309 | }, { | 235 | }, { |
310 | .modalias = "mmc_spi", | 236 | .modalias = "mmc_spi", |
311 | .platform_data = &vision_spi_mmc_data, | 237 | .platform_data = &vision_spi_mmc_data, |
312 | .controller_data = &vision_spi_mmc_hw, | ||
313 | .max_speed_hz = 20000000, | 238 | .max_speed_hz = 20000000, |
314 | .bus_num = 0, | 239 | .bus_num = 0, |
315 | .chip_select = 2, | 240 | .chip_select = 2, |
@@ -317,8 +242,15 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { | |||
317 | }, | 242 | }, |
318 | }; | 243 | }; |
319 | 244 | ||
245 | static int vision_spi_chipselects[] __initdata = { | ||
246 | EP93XX_GPIO_LINE_EGPIO6, | ||
247 | EP93XX_GPIO_LINE_EGPIO7, | ||
248 | EP93XX_GPIO_LINE_G(2), | ||
249 | }; | ||
250 | |||
320 | static struct ep93xx_spi_info vision_spi_master __initdata = { | 251 | static struct ep93xx_spi_info vision_spi_master __initdata = { |
321 | .num_chipselect = ARRAY_SIZE(vision_spi_board_info), | 252 | .chipselect = vision_spi_chipselects, |
253 | .num_chipselect = ARRAY_SIZE(vision_spi_chipselects), | ||
322 | .use_dma = 1, | 254 | .use_dma = 1, |
323 | }; | 255 | }; |
324 | 256 | ||
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 17a6387e20b5..b5d766064b7b 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
31 | #include <linux/gpio.h> | ||
31 | #include <linux/spi/spi.h> | 32 | #include <linux/spi/spi.h> |
32 | 33 | ||
33 | #include <linux/platform_data/dma-ep93xx.h> | 34 | #include <linux/platform_data/dma-ep93xx.h> |
@@ -107,16 +108,6 @@ struct ep93xx_spi { | |||
107 | void *zeropage; | 108 | void *zeropage; |
108 | }; | 109 | }; |
109 | 110 | ||
110 | /** | ||
111 | * struct ep93xx_spi_chip - SPI device hardware settings | ||
112 | * @spi: back pointer to the SPI device | ||
113 | * @ops: private chip operations | ||
114 | */ | ||
115 | struct ep93xx_spi_chip { | ||
116 | const struct spi_device *spi; | ||
117 | struct ep93xx_spi_chip_ops *ops; | ||
118 | }; | ||
119 | |||
120 | /* converts bits per word to CR0.DSS value */ | 111 | /* converts bits per word to CR0.DSS value */ |
121 | #define bits_per_word_to_dss(bpw) ((bpw) - 1) | 112 | #define bits_per_word_to_dss(bpw) ((bpw) - 1) |
122 | 113 | ||
@@ -229,104 +220,36 @@ static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi, | |||
229 | return -EINVAL; | 220 | return -EINVAL; |
230 | } | 221 | } |
231 | 222 | ||
232 | static void ep93xx_spi_cs_control(struct spi_device *spi, bool control) | 223 | static void ep93xx_spi_cs_control(struct spi_device *spi, bool enable) |
233 | { | ||
234 | struct ep93xx_spi_chip *chip = spi_get_ctldata(spi); | ||
235 | int value = (spi->mode & SPI_CS_HIGH) ? control : !control; | ||
236 | |||
237 | if (chip->ops && chip->ops->cs_control) | ||
238 | chip->ops->cs_control(spi, value); | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * ep93xx_spi_setup() - setup an SPI device | ||
243 | * @spi: SPI device to setup | ||
244 | * | ||
245 | * This function sets up SPI device mode, speed etc. Can be called multiple | ||
246 | * times for a single device. Returns %0 in case of success, negative error in | ||
247 | * case of failure. When this function returns success, the device is | ||
248 | * deselected. | ||
249 | */ | ||
250 | static int ep93xx_spi_setup(struct spi_device *spi) | ||
251 | { | 224 | { |
252 | struct ep93xx_spi *espi = spi_master_get_devdata(spi->master); | 225 | if (spi->mode & SPI_CS_HIGH) |
253 | struct ep93xx_spi_chip *chip; | 226 | enable = !enable; |
254 | 227 | ||
255 | chip = spi_get_ctldata(spi); | 228 | if (gpio_is_valid(spi->cs_gpio)) |
256 | if (!chip) { | 229 | gpio_set_value(spi->cs_gpio, !enable); |
257 | dev_dbg(&espi->pdev->dev, "initial setup for %s\n", | ||
258 | spi->modalias); | ||
259 | |||
260 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
261 | if (!chip) | ||
262 | return -ENOMEM; | ||
263 | |||
264 | chip->spi = spi; | ||
265 | chip->ops = spi->controller_data; | ||
266 | |||
267 | if (chip->ops && chip->ops->setup) { | ||
268 | int ret = chip->ops->setup(spi); | ||
269 | |||
270 | if (ret) { | ||
271 | kfree(chip); | ||
272 | return ret; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | spi_set_ctldata(spi, chip); | ||
277 | } | ||
278 | |||
279 | ep93xx_spi_cs_control(spi, false); | ||
280 | return 0; | ||
281 | } | 230 | } |
282 | 231 | ||
283 | /** | ||
284 | * ep93xx_spi_cleanup() - cleans up master controller specific state | ||
285 | * @spi: SPI device to cleanup | ||
286 | * | ||
287 | * This function releases master controller specific state for given @spi | ||
288 | * device. | ||
289 | */ | ||
290 | static void ep93xx_spi_cleanup(struct spi_device *spi) | ||
291 | { | ||
292 | struct ep93xx_spi_chip *chip; | ||
293 | |||
294 | chip = spi_get_ctldata(spi); | ||
295 | if (chip) { | ||
296 | if (chip->ops && chip->ops->cleanup) | ||
297 | chip->ops->cleanup(spi); | ||
298 | spi_set_ctldata(spi, NULL); | ||
299 | kfree(chip); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | /** | ||
304 | * ep93xx_spi_chip_setup() - configures hardware according to given @chip | ||
305 | * @espi: ep93xx SPI controller struct | ||
306 | * @chip: chip specific settings | ||
307 | * @speed_hz: transfer speed | ||
308 | * @bits_per_word: transfer bits_per_word | ||
309 | */ | ||
310 | static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, | 232 | static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, |
311 | const struct ep93xx_spi_chip *chip, | 233 | struct spi_device *spi, |
312 | u32 speed_hz, u8 bits_per_word) | 234 | struct spi_transfer *xfer) |
313 | { | 235 | { |
314 | u8 dss = bits_per_word_to_dss(bits_per_word); | 236 | u8 dss = bits_per_word_to_dss(xfer->bits_per_word); |
315 | u8 div_cpsr = 0; | 237 | u8 div_cpsr = 0; |
316 | u8 div_scr = 0; | 238 | u8 div_scr = 0; |
317 | u16 cr0; | 239 | u16 cr0; |
318 | int err; | 240 | int err; |
319 | 241 | ||
320 | err = ep93xx_spi_calc_divisors(espi, speed_hz, &div_cpsr, &div_scr); | 242 | err = ep93xx_spi_calc_divisors(espi, xfer->speed_hz, |
243 | &div_cpsr, &div_scr); | ||
321 | if (err) | 244 | if (err) |
322 | return err; | 245 | return err; |
323 | 246 | ||
324 | cr0 = div_scr << SSPCR0_SCR_SHIFT; | 247 | cr0 = div_scr << SSPCR0_SCR_SHIFT; |
325 | cr0 |= (chip->spi->mode & (SPI_CPHA|SPI_CPOL)) << SSPCR0_MODE_SHIFT; | 248 | cr0 |= (spi->mode & (SPI_CPHA | SPI_CPOL)) << SSPCR0_MODE_SHIFT; |
326 | cr0 |= dss; | 249 | cr0 |= dss; |
327 | 250 | ||
328 | dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", | 251 | dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", |
329 | chip->spi->mode, div_cpsr, div_scr, dss); | 252 | spi->mode, div_cpsr, div_scr, dss); |
330 | dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); | 253 | dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); |
331 | 254 | ||
332 | ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr); | 255 | ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr); |
@@ -603,12 +526,11 @@ static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, | |||
603 | struct spi_message *msg, | 526 | struct spi_message *msg, |
604 | struct spi_transfer *t) | 527 | struct spi_transfer *t) |
605 | { | 528 | { |
606 | struct ep93xx_spi_chip *chip = spi_get_ctldata(msg->spi); | ||
607 | int err; | 529 | int err; |
608 | 530 | ||
609 | msg->state = t; | 531 | msg->state = t; |
610 | 532 | ||
611 | err = ep93xx_spi_chip_setup(espi, chip, t->speed_hz, t->bits_per_word); | 533 | err = ep93xx_spi_chip_setup(espi, msg->spi, t); |
612 | if (err) { | 534 | if (err) { |
613 | dev_err(&espi->pdev->dev, | 535 | dev_err(&espi->pdev->dev, |
614 | "failed to setup chip for transfer\n"); | 536 | "failed to setup chip for transfer\n"); |
@@ -863,8 +785,13 @@ static int ep93xx_spi_probe(struct platform_device *pdev) | |||
863 | struct resource *res; | 785 | struct resource *res; |
864 | int irq; | 786 | int irq; |
865 | int error; | 787 | int error; |
788 | int i; | ||
866 | 789 | ||
867 | info = dev_get_platdata(&pdev->dev); | 790 | info = dev_get_platdata(&pdev->dev); |
791 | if (!info) { | ||
792 | dev_err(&pdev->dev, "missing platform data\n"); | ||
793 | return -EINVAL; | ||
794 | } | ||
868 | 795 | ||
869 | irq = platform_get_irq(pdev, 0); | 796 | irq = platform_get_irq(pdev, 0); |
870 | if (irq < 0) { | 797 | if (irq < 0) { |
@@ -882,14 +809,36 @@ static int ep93xx_spi_probe(struct platform_device *pdev) | |||
882 | if (!master) | 809 | if (!master) |
883 | return -ENOMEM; | 810 | return -ENOMEM; |
884 | 811 | ||
885 | master->setup = ep93xx_spi_setup; | ||
886 | master->transfer_one_message = ep93xx_spi_transfer_one_message; | 812 | master->transfer_one_message = ep93xx_spi_transfer_one_message; |
887 | master->cleanup = ep93xx_spi_cleanup; | ||
888 | master->bus_num = pdev->id; | 813 | master->bus_num = pdev->id; |
889 | master->num_chipselect = info->num_chipselect; | ||
890 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 814 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
891 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); | 815 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); |
892 | 816 | ||
817 | master->num_chipselect = info->num_chipselect; | ||
818 | master->cs_gpios = devm_kzalloc(&master->dev, | ||
819 | sizeof(int) * master->num_chipselect, | ||
820 | GFP_KERNEL); | ||
821 | if (!master->cs_gpios) { | ||
822 | error = -ENOMEM; | ||
823 | goto fail_release_master; | ||
824 | } | ||
825 | |||
826 | for (i = 0; i < master->num_chipselect; i++) { | ||
827 | master->cs_gpios[i] = info->chipselect[i]; | ||
828 | |||
829 | if (!gpio_is_valid(master->cs_gpios[i])) | ||
830 | continue; | ||
831 | |||
832 | error = devm_gpio_request_one(&pdev->dev, master->cs_gpios[i], | ||
833 | GPIOF_OUT_INIT_HIGH, | ||
834 | "ep93xx-spi"); | ||
835 | if (error) { | ||
836 | dev_err(&pdev->dev, "could not request cs gpio %d\n", | ||
837 | master->cs_gpios[i]); | ||
838 | goto fail_release_master; | ||
839 | } | ||
840 | } | ||
841 | |||
893 | platform_set_drvdata(pdev, master); | 842 | platform_set_drvdata(pdev, master); |
894 | 843 | ||
895 | espi = spi_master_get_devdata(master); | 844 | espi = spi_master_get_devdata(master); |
diff --git a/include/linux/platform_data/spi-ep93xx.h b/include/linux/platform_data/spi-ep93xx.h index 9bb63ac13f04..171a271c2cbd 100644 --- a/include/linux/platform_data/spi-ep93xx.h +++ b/include/linux/platform_data/spi-ep93xx.h | |||
@@ -5,25 +5,14 @@ struct spi_device; | |||
5 | 5 | ||
6 | /** | 6 | /** |
7 | * struct ep93xx_spi_info - EP93xx specific SPI descriptor | 7 | * struct ep93xx_spi_info - EP93xx specific SPI descriptor |
8 | * @num_chipselect: number of chip selects on this board, must be | 8 | * @chipselect: array of gpio numbers to use as chip selects |
9 | * at least one | 9 | * @num_chipselect: ARRAY_SIZE(chipselect) |
10 | * @use_dma: use DMA for the transfers | 10 | * @use_dma: use DMA for the transfers |
11 | */ | 11 | */ |
12 | struct ep93xx_spi_info { | 12 | struct ep93xx_spi_info { |
13 | int *chipselect; | ||
13 | int num_chipselect; | 14 | int num_chipselect; |
14 | bool use_dma; | 15 | bool use_dma; |
15 | }; | 16 | }; |
16 | 17 | ||
17 | /** | ||
18 | * struct ep93xx_spi_chip_ops - operation callbacks for SPI slave device | ||
19 | * @setup: setup the chip select mechanism | ||
20 | * @cleanup: cleanup the chip select mechanism | ||
21 | * @cs_control: control the device chip select | ||
22 | */ | ||
23 | struct ep93xx_spi_chip_ops { | ||
24 | int (*setup)(struct spi_device *spi); | ||
25 | void (*cleanup)(struct spi_device *spi); | ||
26 | void (*cs_control)(struct spi_device *spi, int value); | ||
27 | }; | ||
28 | |||
29 | #endif /* __ASM_MACH_EP93XX_SPI_H */ | 18 | #endif /* __ASM_MACH_EP93XX_SPI_H */ |