aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorImre Deak <imre.deak@nokia.com>2006-02-17 13:02:18 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-05-16 17:33:56 -0400
commit4cff33f94fefcce1b3c01a9d1da6bb85fe3cbdfa (patch)
tree0ef6066c4f2c0225517a6402bb04f4b4d56afd4d
parent716f8954fb3029ca2df52a986b60af8d06f093ee (diff)
[PATCH] SPI: per-transfer overrides for wordsize and clocking
Some protocols (like one for some bitmap displays) require different clock speed or word size settings for each transfer in an SPI message. This adds those parameters to struct spi_transfer. They are to be used when they are nonzero; otherwise the defaults from spi_device are to be used. The patch also adds a setup_transfer callback to spi_bitbang, uses it for messages that use those overrides, and implements it so that the pure bitbanging code can help resolve any questions about how it should work. Signed-off-by: Imre Deak <imre.deak@nokia.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/spi/spi_bitbang.c77
-rw-r--r--include/linux/spi/spi.h8
-rw-r--r--include/linux/spi/spi_bitbang.h6
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
141static int
142bitbang_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