diff options
author | Wolfgang Muees <wolfgang.mues@auerswald.de> | 2009-04-06 22:00:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-07 11:31:06 -0400 |
commit | 93b61bddc13d9acf1fe341b39d826e80f3182d1e (patch) | |
tree | 54a5b574ada4b619a9cba845bee1e4205d62176c /drivers/spi/spi_bfin5xx.c | |
parent | 42c78b2bf51bafb4cfa98dfecc28dd9b8bcd04b0 (diff) |
Blackfin SPI Driver: Make mmc_spi driver work on Blackfin
1. Rewrite of the non-dma data transfer functions to use only ONE mode
of TIMOD (TIMOD=0x1). With TIMOD=0, it was not possible to set the TX
bit pattern. So the TDBR = 0xFFFF inside the read calls won't work.
2. Clear SPI_RDBR before reading and before duplex transfer.
Otherwise the garbage data in RDBR will get read. Since mmc_spi uses a
lot of duplex transfers, this is the main cause of mmc_spi failure.
3. Poll RXS for transfer completion. Polling SPIF or TXS cannot
guarantee transfer completion. This may interrupt a transfer before it
is finished. Also this may leave garbage data in buffer and affect
next transfer.
[Yi Li <yi.li@analog.com>: add a field "u16 idle_tx_val" in "struct
bfin5xx_spi_chip" to specify the value to transmit if no TX value
is supplied.]
Signed-off-by: Wolfgang Muees <wolfgang.mues@auerswald.de>
Signed-off-by: Yi Li <yi.li@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/spi/spi_bfin5xx.c')
-rw-r--r-- | drivers/spi/spi_bfin5xx.c | 250 |
1 files changed, 108 insertions, 142 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 6aa084e445e6..e1d9eae1fae1 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -45,6 +45,9 @@ MODULE_LICENSE("GPL"); | |||
45 | #define QUEUE_RUNNING 0 | 45 | #define QUEUE_RUNNING 0 |
46 | #define QUEUE_STOPPED 1 | 46 | #define QUEUE_STOPPED 1 |
47 | 47 | ||
48 | /* Value to send if no TX value is supplied */ | ||
49 | #define SPI_IDLE_TXVAL 0x0000 | ||
50 | |||
48 | struct driver_data { | 51 | struct driver_data { |
49 | /* Driver model hookup */ | 52 | /* Driver model hookup */ |
50 | struct platform_device *pdev; | 53 | struct platform_device *pdev; |
@@ -112,6 +115,7 @@ struct chip_data { | |||
112 | u8 cs_change_per_word; | 115 | u8 cs_change_per_word; |
113 | u16 cs_chg_udelay; /* Some devices require > 255usec delay */ | 116 | u16 cs_chg_udelay; /* Some devices require > 255usec delay */ |
114 | u32 cs_gpio; | 117 | u32 cs_gpio; |
118 | u16 idle_tx_val; | ||
115 | void (*write) (struct driver_data *); | 119 | void (*write) (struct driver_data *); |
116 | void (*read) (struct driver_data *); | 120 | void (*read) (struct driver_data *); |
117 | void (*duplex) (struct driver_data *); | 121 | void (*duplex) (struct driver_data *); |
@@ -226,134 +230,126 @@ static void bfin_spi_restore_state(struct driver_data *drv_data) | |||
226 | bfin_spi_cs_active(drv_data, chip); | 230 | bfin_spi_cs_active(drv_data, chip); |
227 | } | 231 | } |
228 | 232 | ||
229 | /* used to kick off transfer in rx mode */ | 233 | /* used to kick off transfer in rx mode and read unwanted RX data */ |
230 | static unsigned short bfin_spi_dummy_read(struct driver_data *drv_data) | 234 | static inline void bfin_spi_dummy_read(struct driver_data *drv_data) |
231 | { | 235 | { |
232 | unsigned short tmp; | 236 | (void) read_RDBR(drv_data); |
233 | tmp = read_RDBR(drv_data); | ||
234 | return tmp; | ||
235 | } | 237 | } |
236 | 238 | ||
237 | static void bfin_spi_null_writer(struct driver_data *drv_data) | 239 | static void bfin_spi_null_writer(struct driver_data *drv_data) |
238 | { | 240 | { |
239 | u8 n_bytes = drv_data->n_bytes; | 241 | u8 n_bytes = drv_data->n_bytes; |
242 | u16 tx_val = drv_data->cur_chip->idle_tx_val; | ||
243 | |||
244 | /* clear RXS (we check for RXS inside the loop) */ | ||
245 | bfin_spi_dummy_read(drv_data); | ||
240 | 246 | ||
241 | while (drv_data->tx < drv_data->tx_end) { | 247 | while (drv_data->tx < drv_data->tx_end) { |
242 | write_TDBR(drv_data, 0); | 248 | write_TDBR(drv_data, tx_val); |
243 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) | ||
244 | cpu_relax(); | ||
245 | drv_data->tx += n_bytes; | 249 | drv_data->tx += n_bytes; |
250 | /* wait until transfer finished. | ||
251 | checking SPIF or TXS may not guarantee transfer completion */ | ||
252 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
253 | cpu_relax(); | ||
254 | /* discard RX data and clear RXS */ | ||
255 | bfin_spi_dummy_read(drv_data); | ||
246 | } | 256 | } |
247 | } | 257 | } |
248 | 258 | ||
249 | static void bfin_spi_null_reader(struct driver_data *drv_data) | 259 | static void bfin_spi_null_reader(struct driver_data *drv_data) |
250 | { | 260 | { |
251 | u8 n_bytes = drv_data->n_bytes; | 261 | u8 n_bytes = drv_data->n_bytes; |
262 | u16 tx_val = drv_data->cur_chip->idle_tx_val; | ||
263 | |||
264 | /* discard old RX data and clear RXS */ | ||
252 | bfin_spi_dummy_read(drv_data); | 265 | bfin_spi_dummy_read(drv_data); |
253 | 266 | ||
254 | while (drv_data->rx < drv_data->rx_end) { | 267 | while (drv_data->rx < drv_data->rx_end) { |
268 | write_TDBR(drv_data, tx_val); | ||
269 | drv_data->rx += n_bytes; | ||
255 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 270 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
256 | cpu_relax(); | 271 | cpu_relax(); |
257 | bfin_spi_dummy_read(drv_data); | 272 | bfin_spi_dummy_read(drv_data); |
258 | drv_data->rx += n_bytes; | ||
259 | } | 273 | } |
260 | } | 274 | } |
261 | 275 | ||
262 | static void bfin_spi_u8_writer(struct driver_data *drv_data) | 276 | static void bfin_spi_u8_writer(struct driver_data *drv_data) |
263 | { | 277 | { |
264 | dev_dbg(&drv_data->pdev->dev, | 278 | /* clear RXS (we check for RXS inside the loop) */ |
265 | "cr8-s is 0x%x\n", read_STAT(drv_data)); | 279 | bfin_spi_dummy_read(drv_data); |
266 | 280 | ||
267 | while (drv_data->tx < drv_data->tx_end) { | 281 | while (drv_data->tx < drv_data->tx_end) { |
268 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 282 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); |
269 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 283 | /* wait until transfer finished. |
284 | checking SPIF or TXS may not guarantee transfer completion */ | ||
285 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
270 | cpu_relax(); | 286 | cpu_relax(); |
271 | ++drv_data->tx; | 287 | /* discard RX data and clear RXS */ |
288 | bfin_spi_dummy_read(drv_data); | ||
272 | } | 289 | } |
273 | |||
274 | /* poll for SPI completion before return */ | ||
275 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
276 | cpu_relax(); | ||
277 | } | 290 | } |
278 | 291 | ||
279 | static void bfin_spi_u8_cs_chg_writer(struct driver_data *drv_data) | 292 | static void bfin_spi_u8_cs_chg_writer(struct driver_data *drv_data) |
280 | { | 293 | { |
281 | struct chip_data *chip = drv_data->cur_chip; | 294 | struct chip_data *chip = drv_data->cur_chip; |
282 | 295 | ||
296 | /* clear RXS (we check for RXS inside the loop) */ | ||
297 | bfin_spi_dummy_read(drv_data); | ||
298 | |||
283 | while (drv_data->tx < drv_data->tx_end) { | 299 | while (drv_data->tx < drv_data->tx_end) { |
284 | bfin_spi_cs_active(drv_data, chip); | 300 | bfin_spi_cs_active(drv_data, chip); |
285 | 301 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); | |
286 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 302 | /* make sure transfer finished before deactiving CS */ |
287 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 303 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
288 | cpu_relax(); | ||
289 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
290 | cpu_relax(); | 304 | cpu_relax(); |
291 | 305 | bfin_spi_dummy_read(drv_data); | |
292 | bfin_spi_cs_deactive(drv_data, chip); | 306 | bfin_spi_cs_deactive(drv_data, chip); |
293 | |||
294 | ++drv_data->tx; | ||
295 | } | 307 | } |
296 | } | 308 | } |
297 | 309 | ||
298 | static void bfin_spi_u8_reader(struct driver_data *drv_data) | 310 | static void bfin_spi_u8_reader(struct driver_data *drv_data) |
299 | { | 311 | { |
300 | dev_dbg(&drv_data->pdev->dev, | 312 | u16 tx_val = drv_data->cur_chip->idle_tx_val; |
301 | "cr-8 is 0x%x\n", read_STAT(drv_data)); | ||
302 | |||
303 | /* poll for SPI completion before start */ | ||
304 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
305 | cpu_relax(); | ||
306 | |||
307 | /* clear TDBR buffer before read(else it will be shifted out) */ | ||
308 | write_TDBR(drv_data, 0xFFFF); | ||
309 | 313 | ||
314 | /* discard old RX data and clear RXS */ | ||
310 | bfin_spi_dummy_read(drv_data); | 315 | bfin_spi_dummy_read(drv_data); |
311 | 316 | ||
312 | while (drv_data->rx < drv_data->rx_end - 1) { | 317 | while (drv_data->rx < drv_data->rx_end) { |
318 | write_TDBR(drv_data, tx_val); | ||
313 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 319 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
314 | cpu_relax(); | 320 | cpu_relax(); |
315 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 321 | *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); |
316 | ++drv_data->rx; | ||
317 | } | 322 | } |
318 | |||
319 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
320 | cpu_relax(); | ||
321 | *(u8 *) (drv_data->rx) = read_SHAW(drv_data); | ||
322 | ++drv_data->rx; | ||
323 | } | 323 | } |
324 | 324 | ||
325 | static void bfin_spi_u8_cs_chg_reader(struct driver_data *drv_data) | 325 | static void bfin_spi_u8_cs_chg_reader(struct driver_data *drv_data) |
326 | { | 326 | { |
327 | struct chip_data *chip = drv_data->cur_chip; | 327 | struct chip_data *chip = drv_data->cur_chip; |
328 | u16 tx_val = chip->idle_tx_val; | ||
329 | |||
330 | /* discard old RX data and clear RXS */ | ||
331 | bfin_spi_dummy_read(drv_data); | ||
328 | 332 | ||
329 | while (drv_data->rx < drv_data->rx_end) { | 333 | while (drv_data->rx < drv_data->rx_end) { |
330 | bfin_spi_cs_active(drv_data, chip); | 334 | bfin_spi_cs_active(drv_data, chip); |
331 | read_RDBR(drv_data); /* kick off */ | 335 | write_TDBR(drv_data, tx_val); |
332 | |||
333 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 336 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
334 | cpu_relax(); | 337 | cpu_relax(); |
335 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 338 | *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); |
336 | cpu_relax(); | ||
337 | |||
338 | *(u8 *) (drv_data->rx) = read_SHAW(drv_data); | ||
339 | bfin_spi_cs_deactive(drv_data, chip); | 339 | bfin_spi_cs_deactive(drv_data, chip); |
340 | |||
341 | ++drv_data->rx; | ||
342 | } | 340 | } |
343 | } | 341 | } |
344 | 342 | ||
345 | static void bfin_spi_u8_duplex(struct driver_data *drv_data) | 343 | static void bfin_spi_u8_duplex(struct driver_data *drv_data) |
346 | { | 344 | { |
347 | /* in duplex mode, clk is triggered by writing of TDBR */ | 345 | /* discard old RX data and clear RXS */ |
346 | bfin_spi_dummy_read(drv_data); | ||
347 | |||
348 | while (drv_data->rx < drv_data->rx_end) { | 348 | while (drv_data->rx < drv_data->rx_end) { |
349 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 349 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); |
350 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
351 | cpu_relax(); | ||
352 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 350 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
353 | cpu_relax(); | 351 | cpu_relax(); |
354 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 352 | *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); |
355 | ++drv_data->rx; | ||
356 | ++drv_data->tx; | ||
357 | } | 353 | } |
358 | } | 354 | } |
359 | 355 | ||
@@ -361,130 +357,102 @@ static void bfin_spi_u8_cs_chg_duplex(struct driver_data *drv_data) | |||
361 | { | 357 | { |
362 | struct chip_data *chip = drv_data->cur_chip; | 358 | struct chip_data *chip = drv_data->cur_chip; |
363 | 359 | ||
360 | /* discard old RX data and clear RXS */ | ||
361 | bfin_spi_dummy_read(drv_data); | ||
362 | |||
364 | while (drv_data->rx < drv_data->rx_end) { | 363 | while (drv_data->rx < drv_data->rx_end) { |
365 | bfin_spi_cs_active(drv_data, chip); | 364 | bfin_spi_cs_active(drv_data, chip); |
366 | 365 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); | |
367 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | ||
368 | |||
369 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
370 | cpu_relax(); | ||
371 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 366 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
372 | cpu_relax(); | 367 | cpu_relax(); |
373 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 368 | *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); |
374 | |||
375 | bfin_spi_cs_deactive(drv_data, chip); | 369 | bfin_spi_cs_deactive(drv_data, chip); |
376 | |||
377 | ++drv_data->rx; | ||
378 | ++drv_data->tx; | ||
379 | } | 370 | } |
380 | } | 371 | } |
381 | 372 | ||
382 | static void bfin_spi_u16_writer(struct driver_data *drv_data) | 373 | static void bfin_spi_u16_writer(struct driver_data *drv_data) |
383 | { | 374 | { |
384 | dev_dbg(&drv_data->pdev->dev, | 375 | /* clear RXS (we check for RXS inside the loop) */ |
385 | "cr16 is 0x%x\n", read_STAT(drv_data)); | 376 | bfin_spi_dummy_read(drv_data); |
386 | 377 | ||
387 | while (drv_data->tx < drv_data->tx_end) { | 378 | while (drv_data->tx < drv_data->tx_end) { |
388 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 379 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
389 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) | ||
390 | cpu_relax(); | ||
391 | drv_data->tx += 2; | 380 | drv_data->tx += 2; |
381 | /* wait until transfer finished. | ||
382 | checking SPIF or TXS may not guarantee transfer completion */ | ||
383 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
384 | cpu_relax(); | ||
385 | /* discard RX data and clear RXS */ | ||
386 | bfin_spi_dummy_read(drv_data); | ||
392 | } | 387 | } |
393 | |||
394 | /* poll for SPI completion before return */ | ||
395 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
396 | cpu_relax(); | ||
397 | } | 388 | } |
398 | 389 | ||
399 | static void bfin_spi_u16_cs_chg_writer(struct driver_data *drv_data) | 390 | static void bfin_spi_u16_cs_chg_writer(struct driver_data *drv_data) |
400 | { | 391 | { |
401 | struct chip_data *chip = drv_data->cur_chip; | 392 | struct chip_data *chip = drv_data->cur_chip; |
402 | 393 | ||
394 | /* clear RXS (we check for RXS inside the loop) */ | ||
395 | bfin_spi_dummy_read(drv_data); | ||
396 | |||
403 | while (drv_data->tx < drv_data->tx_end) { | 397 | while (drv_data->tx < drv_data->tx_end) { |
404 | bfin_spi_cs_active(drv_data, chip); | 398 | bfin_spi_cs_active(drv_data, chip); |
405 | |||
406 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 399 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
407 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) | 400 | drv_data->tx += 2; |
408 | cpu_relax(); | 401 | /* make sure transfer finished before deactiving CS */ |
409 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 402 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
410 | cpu_relax(); | 403 | cpu_relax(); |
411 | 404 | bfin_spi_dummy_read(drv_data); | |
412 | bfin_spi_cs_deactive(drv_data, chip); | 405 | bfin_spi_cs_deactive(drv_data, chip); |
413 | |||
414 | drv_data->tx += 2; | ||
415 | } | 406 | } |
416 | } | 407 | } |
417 | 408 | ||
418 | static void bfin_spi_u16_reader(struct driver_data *drv_data) | 409 | static void bfin_spi_u16_reader(struct driver_data *drv_data) |
419 | { | 410 | { |
420 | dev_dbg(&drv_data->pdev->dev, | 411 | u16 tx_val = drv_data->cur_chip->idle_tx_val; |
421 | "cr-16 is 0x%x\n", read_STAT(drv_data)); | ||
422 | |||
423 | /* poll for SPI completion before start */ | ||
424 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
425 | cpu_relax(); | ||
426 | |||
427 | /* clear TDBR buffer before read(else it will be shifted out) */ | ||
428 | write_TDBR(drv_data, 0xFFFF); | ||
429 | 412 | ||
413 | /* discard old RX data and clear RXS */ | ||
430 | bfin_spi_dummy_read(drv_data); | 414 | bfin_spi_dummy_read(drv_data); |
431 | 415 | ||
432 | while (drv_data->rx < (drv_data->rx_end - 2)) { | 416 | while (drv_data->rx < drv_data->rx_end) { |
417 | write_TDBR(drv_data, tx_val); | ||
433 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 418 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
434 | cpu_relax(); | 419 | cpu_relax(); |
435 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 420 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); |
436 | drv_data->rx += 2; | 421 | drv_data->rx += 2; |
437 | } | 422 | } |
438 | |||
439 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
440 | cpu_relax(); | ||
441 | *(u16 *) (drv_data->rx) = read_SHAW(drv_data); | ||
442 | drv_data->rx += 2; | ||
443 | } | 423 | } |
444 | 424 | ||
445 | static void bfin_spi_u16_cs_chg_reader(struct driver_data *drv_data) | 425 | static void bfin_spi_u16_cs_chg_reader(struct driver_data *drv_data) |
446 | { | 426 | { |
447 | struct chip_data *chip = drv_data->cur_chip; | 427 | struct chip_data *chip = drv_data->cur_chip; |
428 | u16 tx_val = chip->idle_tx_val; | ||
448 | 429 | ||
449 | /* poll for SPI completion before start */ | 430 | /* discard old RX data and clear RXS */ |
450 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
451 | cpu_relax(); | ||
452 | |||
453 | /* clear TDBR buffer before read(else it will be shifted out) */ | ||
454 | write_TDBR(drv_data, 0xFFFF); | ||
455 | |||
456 | bfin_spi_cs_active(drv_data, chip); | ||
457 | bfin_spi_dummy_read(drv_data); | 431 | bfin_spi_dummy_read(drv_data); |
458 | 432 | ||
459 | while (drv_data->rx < drv_data->rx_end - 2) { | 433 | while (drv_data->rx < drv_data->rx_end) { |
460 | bfin_spi_cs_deactive(drv_data, chip); | 434 | bfin_spi_cs_active(drv_data, chip); |
461 | 435 | write_TDBR(drv_data, tx_val); | |
462 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 436 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
463 | cpu_relax(); | 437 | cpu_relax(); |
464 | bfin_spi_cs_active(drv_data, chip); | ||
465 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 438 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); |
466 | drv_data->rx += 2; | 439 | drv_data->rx += 2; |
440 | bfin_spi_cs_deactive(drv_data, chip); | ||
467 | } | 441 | } |
468 | bfin_spi_cs_deactive(drv_data, chip); | ||
469 | |||
470 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
471 | cpu_relax(); | ||
472 | *(u16 *) (drv_data->rx) = read_SHAW(drv_data); | ||
473 | drv_data->rx += 2; | ||
474 | } | 442 | } |
475 | 443 | ||
476 | static void bfin_spi_u16_duplex(struct driver_data *drv_data) | 444 | static void bfin_spi_u16_duplex(struct driver_data *drv_data) |
477 | { | 445 | { |
478 | /* in duplex mode, clk is triggered by writing of TDBR */ | 446 | /* discard old RX data and clear RXS */ |
479 | while (drv_data->tx < drv_data->tx_end) { | 447 | bfin_spi_dummy_read(drv_data); |
448 | |||
449 | while (drv_data->rx < drv_data->rx_end) { | ||
480 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 450 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
481 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 451 | drv_data->tx += 2; |
482 | cpu_relax(); | ||
483 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 452 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
484 | cpu_relax(); | 453 | cpu_relax(); |
485 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 454 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); |
486 | drv_data->rx += 2; | 455 | drv_data->rx += 2; |
487 | drv_data->tx += 2; | ||
488 | } | 456 | } |
489 | } | 457 | } |
490 | 458 | ||
@@ -492,20 +460,18 @@ static void bfin_spi_u16_cs_chg_duplex(struct driver_data *drv_data) | |||
492 | { | 460 | { |
493 | struct chip_data *chip = drv_data->cur_chip; | 461 | struct chip_data *chip = drv_data->cur_chip; |
494 | 462 | ||
495 | while (drv_data->tx < drv_data->tx_end) { | 463 | /* discard old RX data and clear RXS */ |
496 | bfin_spi_cs_active(drv_data, chip); | 464 | bfin_spi_dummy_read(drv_data); |
497 | 465 | ||
466 | while (drv_data->rx < drv_data->rx_end) { | ||
467 | bfin_spi_cs_active(drv_data, chip); | ||
498 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 468 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
499 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 469 | drv_data->tx += 2; |
500 | cpu_relax(); | ||
501 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 470 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
502 | cpu_relax(); | 471 | cpu_relax(); |
503 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 472 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); |
504 | |||
505 | bfin_spi_cs_deactive(drv_data, chip); | ||
506 | |||
507 | drv_data->rx += 2; | 473 | drv_data->rx += 2; |
508 | drv_data->tx += 2; | 474 | bfin_spi_cs_deactive(drv_data, chip); |
509 | } | 475 | } |
510 | } | 476 | } |
511 | 477 | ||
@@ -682,6 +648,13 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
682 | return; | 648 | return; |
683 | } | 649 | } |
684 | 650 | ||
651 | if (transfer->len == 0) { | ||
652 | /* Move to next transfer of this msg */ | ||
653 | message->state = bfin_spi_next_transfer(drv_data); | ||
654 | /* Schedule next transfer tasklet */ | ||
655 | tasklet_schedule(&drv_data->pump_transfers); | ||
656 | } | ||
657 | |||
685 | if (transfer->tx_buf != NULL) { | 658 | if (transfer->tx_buf != NULL) { |
686 | drv_data->tx = (void *)transfer->tx_buf; | 659 | drv_data->tx = (void *)transfer->tx_buf; |
687 | drv_data->tx_end = drv_data->tx + transfer->len; | 660 | drv_data->tx_end = drv_data->tx + transfer->len; |
@@ -837,9 +810,6 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
837 | (unsigned long) (drv_data->rx + | 810 | (unsigned long) (drv_data->rx + |
838 | drv_data->len_in_bytes)); | 811 | drv_data->len_in_bytes)); |
839 | 812 | ||
840 | /* clear tx reg soformer data is not shifted out */ | ||
841 | write_TDBR(drv_data, 0xFFFF); | ||
842 | |||
843 | dma_config |= WNR; | 813 | dma_config |= WNR; |
844 | dma_start_addr = (unsigned long)drv_data->rx; | 814 | dma_start_addr = (unsigned long)drv_data->rx; |
845 | cr |= BIT_CTL_TIMOD_DMA_RX | BIT_CTL_SENDOPT; | 815 | cr |= BIT_CTL_TIMOD_DMA_RX | BIT_CTL_SENDOPT; |
@@ -881,6 +851,11 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
881 | /* IO mode write then read */ | 851 | /* IO mode write then read */ |
882 | dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n"); | 852 | dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n"); |
883 | 853 | ||
854 | /* we always use SPI_WRITE mode. SPI_READ mode | ||
855 | seems to have problems with setting up the | ||
856 | output value in TDBR prior to the transfer. */ | ||
857 | write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); | ||
858 | |||
884 | if (full_duplex) { | 859 | if (full_duplex) { |
885 | /* full duplex mode */ | 860 | /* full duplex mode */ |
886 | BUG_ON((drv_data->tx_end - drv_data->tx) != | 861 | BUG_ON((drv_data->tx_end - drv_data->tx) != |
@@ -888,9 +863,6 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
888 | dev_dbg(&drv_data->pdev->dev, | 863 | dev_dbg(&drv_data->pdev->dev, |
889 | "IO duplex: cr is 0x%x\n", cr); | 864 | "IO duplex: cr is 0x%x\n", cr); |
890 | 865 | ||
891 | /* set SPI transfer mode */ | ||
892 | write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); | ||
893 | |||
894 | drv_data->duplex(drv_data); | 866 | drv_data->duplex(drv_data); |
895 | 867 | ||
896 | if (drv_data->tx != drv_data->tx_end) | 868 | if (drv_data->tx != drv_data->tx_end) |
@@ -900,9 +872,6 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
900 | dev_dbg(&drv_data->pdev->dev, | 872 | dev_dbg(&drv_data->pdev->dev, |
901 | "IO write: cr is 0x%x\n", cr); | 873 | "IO write: cr is 0x%x\n", cr); |
902 | 874 | ||
903 | /* set SPI transfer mode */ | ||
904 | write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); | ||
905 | |||
906 | drv_data->write(drv_data); | 875 | drv_data->write(drv_data); |
907 | 876 | ||
908 | if (drv_data->tx != drv_data->tx_end) | 877 | if (drv_data->tx != drv_data->tx_end) |
@@ -912,9 +881,6 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
912 | dev_dbg(&drv_data->pdev->dev, | 881 | dev_dbg(&drv_data->pdev->dev, |
913 | "IO read: cr is 0x%x\n", cr); | 882 | "IO read: cr is 0x%x\n", cr); |
914 | 883 | ||
915 | /* set SPI transfer mode */ | ||
916 | write_CTRL(drv_data, (cr | CFG_SPI_READ)); | ||
917 | |||
918 | drv_data->read(drv_data); | 884 | drv_data->read(drv_data); |
919 | if (drv_data->rx != drv_data->rx_end) | 885 | if (drv_data->rx != drv_data->rx_end) |
920 | tranf_success = 0; | 886 | tranf_success = 0; |
@@ -934,7 +900,6 @@ static void bfin_spi_pump_transfers(unsigned long data) | |||
934 | } | 900 | } |
935 | /* Schedule next transfer tasklet */ | 901 | /* Schedule next transfer tasklet */ |
936 | tasklet_schedule(&drv_data->pump_transfers); | 902 | tasklet_schedule(&drv_data->pump_transfers); |
937 | |||
938 | } | 903 | } |
939 | } | 904 | } |
940 | 905 | ||
@@ -1092,6 +1057,7 @@ static int bfin_spi_setup(struct spi_device *spi) | |||
1092 | chip->cs_change_per_word = chip_info->cs_change_per_word; | 1057 | chip->cs_change_per_word = chip_info->cs_change_per_word; |
1093 | chip->cs_chg_udelay = chip_info->cs_chg_udelay; | 1058 | chip->cs_chg_udelay = chip_info->cs_chg_udelay; |
1094 | chip->cs_gpio = chip_info->cs_gpio; | 1059 | chip->cs_gpio = chip_info->cs_gpio; |
1060 | chip->idle_tx_val = chip_info->idle_tx_val; | ||
1095 | } | 1061 | } |
1096 | 1062 | ||
1097 | /* translate common spi framework into our register */ | 1063 | /* translate common spi framework into our register */ |