Date: | 2010-04-24 12:23:01 (13 years 7 months ago) |
---|---|
Author: | Lars C. |
Commit: | 1ee508478f093692d56f588fbff6bdbc7c856ae9 |
Message: | gpio spi 3wire |
Files: |
drivers/spi/spi_bitbang.c (1 diff) drivers/spi/spi_gpio.c (9 diffs) include/linux/spi/spi_bitbang.h (1 diff) |
Change Details
drivers/spi/spi_bitbang.c | ||
---|---|---|
335 | 335 | */ |
336 | 336 | if (!m->is_dma_mapped) |
337 | 337 | t->rx_dma = t->tx_dma = 0; |
338 | if ((spi->mode & SPI_3WIRE) && bitbang->set_direction) | |
339 | bitbang->set_direction(spi, t->tx_buf != NULL); | |
338 | 340 | status = bitbang->txrx_bufs(spi, t); |
339 | 341 | } |
340 | 342 | if (status > 0) |
drivers/spi/spi_gpio.c | ||
---|---|---|
45 | 45 | struct spi_bitbang bitbang; |
46 | 46 | struct spi_gpio_platform_data pdata; |
47 | 47 | struct platform_device *pdev; |
48 | ||
49 | int miso_pin; | |
48 | 50 | }; |
49 | 51 | |
50 | 52 | /*----------------------------------------------------------------------*/ |
... | ... | |
88 | 90 | |
89 | 91 | /*----------------------------------------------------------------------*/ |
90 | 92 | |
91 | static inline const struct spi_gpio_platform_data * __pure | |
92 | spi_to_pdata(const struct spi_device *spi) | |
93 | static inline const struct spi_gpio * __pure | |
94 | spi_to_spi_gpio(const struct spi_device *spi) | |
93 | 95 | { |
94 | 96 | const struct spi_bitbang *bang; |
95 | const struct spi_gpio *spi_gpio; | |
96 | 97 | |
97 | 98 | bang = spi_master_get_devdata(spi->master); |
98 | spi_gpio = container_of(bang, struct spi_gpio, bitbang); | |
99 | return &spi_gpio->pdata; | |
99 | return container_of(bang, struct spi_gpio, bitbang); | |
100 | 100 | } |
101 | 101 | |
102 | /* this is #defined to avoid unused-variable warnings when inlining */ | |
103 | #define pdata spi_to_pdata(spi) | |
102 | #define pdata &(spi_to_spi_gpio(spi)->pdata) | |
104 | 103 | |
105 | 104 | static inline void setsck(const struct spi_device *spi, int is_on) |
106 | 105 | { |
... | ... | |
114 | 113 | |
115 | 114 | static inline int getmiso(const struct spi_device *spi) |
116 | 115 | { |
117 | return !!gpio_get_value(SPI_MISO_GPIO); | |
116 | return !!gpio_get_value(spi_to_spi_gpio(spi)->miso_pin); | |
118 | 117 | } |
119 | 118 | |
120 | #undef pdata | |
121 | 119 | |
122 | 120 | /* |
123 | 121 | * NOTE: this clocks "as fast as we can". It "should" be a function of the |
... | ... | |
173 | 171 | static void spi_gpio_chipselect(struct spi_device *spi, int is_active) |
174 | 172 | { |
175 | 173 | unsigned long cs = (unsigned long) spi->controller_data; |
174 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | |
176 | 175 | |
177 | 176 | /* set initial clock polarity */ |
178 | if (is_active) | |
177 | if (is_active) { | |
179 | 178 | setsck(spi, spi->mode & SPI_CPOL); |
179 | if (spi->mode & SPI_3WIRE) | |
180 | spi_gpio->miso_pin = SPI_MOSI_GPIO; | |
181 | else | |
182 | spi_gpio->miso_pin = SPI_MISO_GPIO; | |
183 | } | |
180 | 184 | |
181 | 185 | if (cs != SPI_GPIO_NO_CHIPSELECT) { |
182 | 186 | /* SPI is normally active-low */ |
... | ... | |
192 | 196 | if (spi->bits_per_word > 32) |
193 | 197 | return -EINVAL; |
194 | 198 | |
199 | if (!(spi->mode & SPI_3WIRE) && !gpio_is_valid(SPI_MISO_GPIO)) | |
200 | return -EINVAL; | |
201 | ||
195 | 202 | if (!spi->controller_state) { |
196 | 203 | if (cs != SPI_GPIO_NO_CHIPSELECT) { |
197 | 204 | status = gpio_request(cs, dev_name(&spi->dev)); |
... | ... | |
209 | 216 | return status; |
210 | 217 | } |
211 | 218 | |
219 | static void spi_gpio_set_direction(struct spi_device *spi, bool is_tx) | |
220 | { | |
221 | if (is_tx) | |
222 | gpio_direction_output(SPI_MISO_GPIO, 0); | |
223 | else | |
224 | gpio_direction_input(SPI_MISO_GPIO); | |
225 | } | |
226 | ||
227 | #undef pdata | |
228 | ||
212 | 229 | static void spi_gpio_cleanup(struct spi_device *spi) |
213 | 230 | { |
214 | 231 | unsigned long cs = (unsigned long) spi->controller_data; |
... | ... | |
243 | 260 | if (value) |
244 | 261 | goto done; |
245 | 262 | |
246 | value = spi_gpio_alloc(SPI_MISO_GPIO, label, true); | |
263 | value = spi_gpio_alloc(SPI_SCK_GPIO, label, false); | |
247 | 264 | if (value) |
248 | 265 | goto free_mosi; |
249 | 266 | |
250 | value = spi_gpio_alloc(SPI_SCK_GPIO, label, false); | |
251 | if (value) | |
252 | goto free_miso; | |
267 | if (gpio_is_valid(SPI_MISO_GPIO)) { | |
268 | value = spi_gpio_alloc(SPI_MISO_GPIO, label, true); | |
269 | if (value) | |
270 | goto free_sck; | |
271 | } | |
253 | 272 | |
254 | 273 | goto done; |
255 | 274 | |
256 | free_miso: | |
257 | gpio_free(SPI_MISO_GPIO); | |
275 | free_sck: | |
276 | gpio_free(SPI_SCK_GPIO); | |
258 | 277 | free_mosi: |
259 | 278 | gpio_free(SPI_MOSI_GPIO); |
260 | 279 | done: |
... | ... | |
302 | 321 | spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; |
303 | 322 | spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3; |
304 | 323 | spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer; |
305 | spi_gpio->bitbang.flags = SPI_CS_HIGH; | |
324 | spi_gpio->bitbang.set_direction = spi_gpio_set_direction; | |
325 | spi_gpio->bitbang.flags = SPI_CS_HIGH | SPI_3WIRE; | |
306 | 326 | |
307 | 327 | status = spi_bitbang_start(&spi_gpio->bitbang); |
308 | 328 | if (status < 0) { |
309 | 329 | spi_master_put(spi_gpio->bitbang.master); |
310 | 330 | gpio_free: |
311 | gpio_free(SPI_MISO_GPIO); | |
331 | if (gpio_is_valid(SPI_MOSI_GPIO)) | |
332 | gpio_free(SPI_MISO_GPIO); | |
312 | 333 | gpio_free(SPI_MOSI_GPIO); |
313 | 334 | gpio_free(SPI_SCK_GPIO); |
314 | 335 | spi_master_put(master); |
... | ... | |
332 | 353 | |
333 | 354 | platform_set_drvdata(pdev, NULL); |
334 | 355 | |
335 | gpio_free(SPI_MISO_GPIO); | |
356 | if (gpio_is_valid(SPI_MISO_GPIO)) | |
357 | gpio_free(SPI_MISO_GPIO); | |
336 | 358 | gpio_free(SPI_MOSI_GPIO); |
337 | 359 | gpio_free(SPI_SCK_GPIO); |
338 | 360 |
include/linux/spi/spi_bitbang.h | ||
---|---|---|
52 | 52 | u32 (*txrx_word[4])(struct spi_device *spi, |
53 | 53 | unsigned nsecs, |
54 | 54 | u32 word, u8 bits); |
55 | ||
56 | void (*set_direction)(struct spi_device *, bool is_tx); | |
55 | 57 | }; |
56 | 58 | |
57 | 59 | /* you can call these default bitbang->master methods from your custom |
Branches:
ben-wpan
ben-wpan-stefan
5396a9238205f20f811ea57898980d3ca82df0b6
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9