diff options
-rw-r--r-- | drivers/spi/spi_bitbang.c | 77 | ||||
-rw-r--r-- | include/linux/spi/spi.h | 8 | ||||
-rw-r--r-- | include/linux/spi/spi_bitbang.h | 6 |
3 files changed, 77 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 | } |
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index b05f1463a267..caa4665e3fa2 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
@@ -31,6 +31,7 @@ extern struct bus_type spi_bus_type; | |||
31 | * @master: SPI controller used with the device. | 31 | * @master: SPI controller used with the device. |
32 | * @max_speed_hz: Maximum clock rate to be used with this chip | 32 | * @max_speed_hz: Maximum clock rate to be used with this chip |
33 | * (on this board); may be changed by the device's driver. | 33 | * (on this board); may be changed by the device's driver. |
34 | * The spi_transfer.speed_hz can override this for each transfer. | ||
34 | * @chip-select: Chipselect, distinguishing chips handled by "master". | 35 | * @chip-select: Chipselect, distinguishing chips handled by "master". |
35 | * @mode: The spi mode defines how data is clocked out and in. | 36 | * @mode: The spi mode defines how data is clocked out and in. |
36 | * This may be changed by the device's driver. | 37 | * This may be changed by the device's driver. |
@@ -38,6 +39,7 @@ extern struct bus_type spi_bus_type; | |||
38 | * like eight or 12 bits are common. In-memory wordsizes are | 39 | * like eight or 12 bits are common. In-memory wordsizes are |
39 | * powers of two bytes (e.g. 20 bit samples use 32 bits). | 40 | * powers of two bytes (e.g. 20 bit samples use 32 bits). |
40 | * This may be changed by the device's driver. | 41 | * This may be changed by the device's driver. |
42 | * The spi_transfer.bits_per_word can override this for each transfer. | ||
41 | * @irq: Negative, or the number passed to request_irq() to receive | 43 | * @irq: Negative, or the number passed to request_irq() to receive |
42 | * interrupts from this device. | 44 | * interrupts from this device. |
43 | * @controller_state: Controller's runtime state | 45 | * @controller_state: Controller's runtime state |
@@ -268,6 +270,10 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); | |||
268 | * @tx_dma: DMA address of tx_buf, if spi_message.is_dma_mapped | 270 | * @tx_dma: DMA address of tx_buf, if spi_message.is_dma_mapped |
269 | * @rx_dma: DMA address of rx_buf, if spi_message.is_dma_mapped | 271 | * @rx_dma: DMA address of rx_buf, if spi_message.is_dma_mapped |
270 | * @len: size of rx and tx buffers (in bytes) | 272 | * @len: size of rx and tx buffers (in bytes) |
273 | * @speed_hz: Select a speed other then the device default for this | ||
274 | * transfer. If 0 the default (from spi_device) is used. | ||
275 | * @bits_per_word: select a bits_per_word other then the device default | ||
276 | * for this transfer. If 0 the default (from spi_device) is used. | ||
271 | * @cs_change: affects chipselect after this transfer completes | 277 | * @cs_change: affects chipselect after this transfer completes |
272 | * @delay_usecs: microseconds to delay after this transfer before | 278 | * @delay_usecs: microseconds to delay after this transfer before |
273 | * (optionally) changing the chipselect status, then starting | 279 | * (optionally) changing the chipselect status, then starting |
@@ -322,7 +328,9 @@ struct spi_transfer { | |||
322 | dma_addr_t rx_dma; | 328 | dma_addr_t rx_dma; |
323 | 329 | ||
324 | unsigned cs_change:1; | 330 | unsigned cs_change:1; |
331 | u8 bits_per_word; | ||
325 | u16 delay_usecs; | 332 | u16 delay_usecs; |
333 | u32 speed_hz; | ||
326 | 334 | ||
327 | struct list_head transfer_list; | 335 | struct list_head transfer_list; |
328 | }; | 336 | }; |
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index c961fe9bf3eb..c954557b757c 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h | |||
@@ -30,6 +30,12 @@ struct spi_bitbang { | |||
30 | 30 | ||
31 | struct spi_master *master; | 31 | struct spi_master *master; |
32 | 32 | ||
33 | /* setup_transfer() changes clock and/or wordsize to match settings | ||
34 | * for this transfer; zeroes restore defaults from spi_device. | ||
35 | */ | ||
36 | int (*setup_transfer)(struct spi_device *spi, | ||
37 | struct spi_transfer *t); | ||
38 | |||
33 | void (*chipselect)(struct spi_device *spi, int is_on); | 39 | void (*chipselect)(struct spi_device *spi, int is_on); |
34 | #define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */ | 40 | #define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */ |
35 | #define BITBANG_CS_INACTIVE 0 | 41 | #define BITBANG_CS_INACTIVE 0 |