diff options
Diffstat (limited to 'drivers/spi/spi_bitbang.c')
-rw-r--r-- | drivers/spi/spi_bitbang.c | 77 |
1 files changed, 63 insertions, 14 deletions
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index f037e5593269..0525c99118c3 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c | |||
@@ -138,6 +138,43 @@ static unsigned bitbang_txrx_32( | |||
138 | return t->len - count; | 138 | return t->len - count; |
139 | } | 139 | } |
140 | 140 | ||
141 | static int | ||
142 | bitbang_transfer_setup(struct spi_device *spi, struct spi_transfer *t) | ||
143 | { | ||
144 | struct spi_bitbang_cs *cs = spi->controller_state; | ||
145 | u8 bits_per_word; | ||
146 | u32 hz; | ||
147 | |||
148 | if (t) { | ||
149 | bits_per_word = t->bits_per_word; | ||
150 | hz = t->speed_hz; | ||
151 | } else { | ||
152 | bits_per_word = 0; | ||
153 | hz = 0; | ||
154 | } | ||
155 | |||
156 | /* spi_transfer level calls that work per-word */ | ||
157 | if (!bits_per_word) | ||
158 | bits_per_word = spi->bits_per_word; | ||
159 | if (bits_per_word <= 8) | ||
160 | cs->txrx_bufs = bitbang_txrx_8; | ||
161 | else if (bits_per_word <= 16) | ||
162 | cs->txrx_bufs = bitbang_txrx_16; | ||
163 | else if (bits_per_word <= 32) | ||
164 | cs->txrx_bufs = bitbang_txrx_32; | ||
165 | else | ||
166 | return -EINVAL; | ||
167 | |||
168 | /* nsecs = (clock period)/2 */ | ||
169 | if (!hz) | ||
170 | hz = spi->max_speed_hz; | ||
171 | cs->nsecs = (1000000000/2) / hz; | ||
172 | if (cs->nsecs > MAX_UDELAY_MS * 1000) | ||
173 | return -EINVAL; | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
141 | /** | 178 | /** |
142 | * spi_bitbang_setup - default setup for per-word I/O loops | 179 | * spi_bitbang_setup - default setup for per-word I/O loops |
143 | */ | 180 | */ |
@@ -145,6 +182,7 @@ int spi_bitbang_setup(struct spi_device *spi) | |||
145 | { | 182 | { |
146 | struct spi_bitbang_cs *cs = spi->controller_state; | 183 | struct spi_bitbang_cs *cs = spi->controller_state; |
147 | struct spi_bitbang *bitbang; | 184 | struct spi_bitbang *bitbang; |
185 | int retval; | ||
148 | 186 | ||
149 | if (!spi->max_speed_hz) | 187 | if (!spi->max_speed_hz) |
150 | return -EINVAL; | 188 | return -EINVAL; |
@@ -160,25 +198,14 @@ int spi_bitbang_setup(struct spi_device *spi) | |||
160 | if (!spi->bits_per_word) | 198 | if (!spi->bits_per_word) |
161 | spi->bits_per_word = 8; | 199 | spi->bits_per_word = 8; |
162 | 200 | ||
163 | /* spi_transfer level calls that work per-word */ | ||
164 | if (spi->bits_per_word <= 8) | ||
165 | cs->txrx_bufs = bitbang_txrx_8; | ||
166 | else if (spi->bits_per_word <= 16) | ||
167 | cs->txrx_bufs = bitbang_txrx_16; | ||
168 | else if (spi->bits_per_word <= 32) | ||
169 | cs->txrx_bufs = bitbang_txrx_32; | ||
170 | else | ||
171 | return -EINVAL; | ||
172 | |||
173 | /* per-word shift register access, in hardware or bitbanging */ | 201 | /* per-word shift register access, in hardware or bitbanging */ |
174 | cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; | 202 | cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; |
175 | if (!cs->txrx_word) | 203 | if (!cs->txrx_word) |
176 | return -EINVAL; | 204 | return -EINVAL; |
177 | 205 | ||
178 | /* nsecs = (clock period)/2 */ | 206 | retval = bitbang_transfer_setup(spi, NULL); |
179 | cs->nsecs = (1000000000/2) / (spi->max_speed_hz); | 207 | if (retval < 0) |
180 | if (cs->nsecs > MAX_UDELAY_MS * 1000) | 208 | return retval; |
181 | return -EINVAL; | ||
182 | 209 | ||
183 | dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", | 210 | dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", |
184 | __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA), | 211 | __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA), |
@@ -246,6 +273,8 @@ static void bitbang_work(void *_bitbang) | |||
246 | unsigned tmp; | 273 | unsigned tmp; |
247 | unsigned cs_change; | 274 | unsigned cs_change; |
248 | int status; | 275 | int status; |
276 | int (*setup_transfer)(struct spi_device *, | ||
277 | struct spi_transfer *); | ||
249 | 278 | ||
250 | m = container_of(bitbang->queue.next, struct spi_message, | 279 | m = container_of(bitbang->queue.next, struct spi_message, |
251 | queue); | 280 | queue); |
@@ -262,6 +291,7 @@ static void bitbang_work(void *_bitbang) | |||
262 | tmp = 0; | 291 | tmp = 0; |
263 | cs_change = 1; | 292 | cs_change = 1; |
264 | status = 0; | 293 | status = 0; |
294 | setup_transfer = NULL; | ||
265 | 295 | ||
266 | list_for_each_entry (t, &m->transfers, transfer_list) { | 296 | list_for_each_entry (t, &m->transfers, transfer_list) { |
267 | if (bitbang->shutdown) { | 297 | if (bitbang->shutdown) { |
@@ -269,6 +299,20 @@ static void bitbang_work(void *_bitbang) | |||
269 | break; | 299 | break; |
270 | } | 300 | } |
271 | 301 | ||
302 | /* override or restore speed and wordsize */ | ||
303 | if (t->speed_hz || t->bits_per_word) { | ||
304 | setup_transfer = bitbang->setup_transfer; | ||
305 | if (!setup_transfer) { | ||
306 | status = -ENOPROTOOPT; | ||
307 | break; | ||
308 | } | ||
309 | } | ||
310 | if (setup_transfer) { | ||
311 | status = setup_transfer(spi, t); | ||
312 | if (status < 0) | ||
313 | break; | ||
314 | } | ||
315 | |||
272 | /* set up default clock polarity, and activate chip; | 316 | /* set up default clock polarity, and activate chip; |
273 | * this implicitly updates clock and spi modes as | 317 | * this implicitly updates clock and spi modes as |
274 | * previously recorded for this device via setup(). | 318 | * previously recorded for this device via setup(). |
@@ -325,6 +369,10 @@ static void bitbang_work(void *_bitbang) | |||
325 | m->status = status; | 369 | m->status = status; |
326 | m->complete(m->context); | 370 | m->complete(m->context); |
327 | 371 | ||
372 | /* restore speed and wordsize */ | ||
373 | if (setup_transfer) | ||
374 | setup_transfer(spi, NULL); | ||
375 | |||
328 | /* normally deactivate chipselect ... unless no error and | 376 | /* normally deactivate chipselect ... unless no error and |
329 | * cs_change has hinted that the next message will probably | 377 | * cs_change has hinted that the next message will probably |
330 | * be for this chip too. | 378 | * be for this chip too. |
@@ -406,6 +454,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) | |||
406 | bitbang->use_dma = 0; | 454 | bitbang->use_dma = 0; |
407 | bitbang->txrx_bufs = spi_bitbang_bufs; | 455 | bitbang->txrx_bufs = spi_bitbang_bufs; |
408 | if (!bitbang->master->setup) { | 456 | if (!bitbang->master->setup) { |
457 | bitbang->setup_transfer = bitbang_transfer_setup; | ||
409 | bitbang->master->setup = spi_bitbang_setup; | 458 | bitbang->master->setup = spi_bitbang_setup; |
410 | bitbang->master->cleanup = spi_bitbang_cleanup; | 459 | bitbang->master->cleanup = spi_bitbang_cleanup; |
411 | } | 460 | } |