aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi_bfin5xx.c
diff options
context:
space:
mode:
authorBryan Wu <bryan.wu@analog.com>2007-12-05 02:45:14 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-05 12:21:19 -0500
commitfad91c890909aabab0d9858d50f3c8394ee16b21 (patch)
treeff3a82c58e5fbd5c91756ad0846ef31555c08054 /drivers/spi/spi_bfin5xx.c
parent5fec5b5a4ec0d6d8b41c56e3cc7de41063cd4736 (diff)
spi: spi_bfin handles spi_transfer.cs_change
Respect per-transfer cs_change field (protocol tweaking support) by adding and using cs_active/cs_deactive functions. Signed-off-by: Bryan Wu <bryan.wu@analog.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.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.c76
1 files changed, 54 insertions, 22 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 803c5b25db50..c2d51cf3c639 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -115,6 +115,7 @@ struct driver_data {
115 size_t rx_map_len; 115 size_t rx_map_len;
116 size_t tx_map_len; 116 size_t tx_map_len;
117 u8 n_bytes; 117 u8 n_bytes;
118 int cs_change;
118 void (*write) (struct driver_data *); 119 void (*write) (struct driver_data *);
119 void (*read) (struct driver_data *); 120 void (*read) (struct driver_data *);
120 void (*duplex) (struct driver_data *); 121 void (*duplex) (struct driver_data *);
@@ -179,6 +180,26 @@ static int flush(struct driver_data *drv_data)
179 return limit; 180 return limit;
180} 181}
181 182
183/* Chip select operation functions for cs_change flag */
184static void cs_active(struct chip_data *chip)
185{
186 u16 flag = read_FLAG();
187
188 flag |= chip->flag;
189 flag &= ~(chip->flag << 8);
190
191 write_FLAG(flag);
192}
193
194static void cs_deactive(struct chip_data *chip)
195{
196 u16 flag = read_FLAG();
197
198 flag |= (chip->flag << 8);
199
200 write_FLAG(flag);
201}
202
182#define MAX_SPI0_SSEL 7 203#define MAX_SPI0_SSEL 7
183 204
184/* stop controller and re-config current chip*/ 205/* stop controller and re-config current chip*/
@@ -198,7 +219,7 @@ static int restore_state(struct driver_data *drv_data)
198 /* Load the registers */ 219 /* Load the registers */
199 write_CTRL(chip->ctl_reg); 220 write_CTRL(chip->ctl_reg);
200 write_BAUD(chip->baud); 221 write_BAUD(chip->baud);
201 write_FLAG(chip->flag); 222 cs_active(chip);
202 223
203 if (!chip->chip_select_requested) { 224 if (!chip->chip_select_requested) {
204 int i = chip->chip_select_num; 225 int i = chip->chip_select_num;
@@ -273,20 +294,20 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
273 struct chip_data *chip = drv_data->cur_chip; 294 struct chip_data *chip = drv_data->cur_chip;
274 295
275 while (drv_data->tx < drv_data->tx_end) { 296 while (drv_data->tx < drv_data->tx_end) {
276 write_FLAG(chip->flag); 297 cs_active(chip);
277 298
278 write_TDBR(*(u8 *) (drv_data->tx)); 299 write_TDBR(*(u8 *) (drv_data->tx));
279 while (read_STAT() & BIT_STAT_TXS) 300 while (read_STAT() & BIT_STAT_TXS)
280 continue; 301 continue;
281 while (!(read_STAT() & BIT_STAT_SPIF)) 302 while (!(read_STAT() & BIT_STAT_SPIF))
282 continue; 303 continue;
283 write_FLAG(0xFF00 | chip->flag); 304 cs_deactive(chip);
284 305
285 if (chip->cs_chg_udelay) 306 if (chip->cs_chg_udelay)
286 udelay(chip->cs_chg_udelay); 307 udelay(chip->cs_chg_udelay);
287 ++drv_data->tx; 308 ++drv_data->tx;
288 } 309 }
289 write_FLAG(0xFF00); 310 cs_deactive(chip);
290 311
291} 312}
292 313
@@ -318,7 +339,7 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
318 struct chip_data *chip = drv_data->cur_chip; 339 struct chip_data *chip = drv_data->cur_chip;
319 340
320 while (drv_data->rx < drv_data->rx_end) { 341 while (drv_data->rx < drv_data->rx_end) {
321 write_FLAG(chip->flag); 342 cs_active(chip);
322 343
323 read_RDBR(); /* kick off */ 344 read_RDBR(); /* kick off */
324 while (!(read_STAT() & BIT_STAT_RXS)) 345 while (!(read_STAT() & BIT_STAT_RXS))
@@ -326,13 +347,13 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
326 while (!(read_STAT() & BIT_STAT_SPIF)) 347 while (!(read_STAT() & BIT_STAT_SPIF))
327 continue; 348 continue;
328 *(u8 *) (drv_data->rx) = read_SHAW(); 349 *(u8 *) (drv_data->rx) = read_SHAW();
329 write_FLAG(0xFF00 | chip->flag); 350 cs_deactive(chip);
330 351
331 if (chip->cs_chg_udelay) 352 if (chip->cs_chg_udelay)
332 udelay(chip->cs_chg_udelay); 353 udelay(chip->cs_chg_udelay);
333 ++drv_data->rx; 354 ++drv_data->rx;
334 } 355 }
335 write_FLAG(0xFF00); 356 cs_deactive(chip);
336 357
337} 358}
338 359
@@ -356,7 +377,7 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
356 struct chip_data *chip = drv_data->cur_chip; 377 struct chip_data *chip = drv_data->cur_chip;
357 378
358 while (drv_data->rx < drv_data->rx_end) { 379 while (drv_data->rx < drv_data->rx_end) {
359 write_FLAG(chip->flag); 380 cs_active(chip);
360 381
361 382
362 write_TDBR(*(u8 *) (drv_data->tx)); 383 write_TDBR(*(u8 *) (drv_data->tx));
@@ -365,15 +386,14 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
365 while (!(read_STAT() & BIT_STAT_RXS)) 386 while (!(read_STAT() & BIT_STAT_RXS))
366 continue; 387 continue;
367 *(u8 *) (drv_data->rx) = read_RDBR(); 388 *(u8 *) (drv_data->rx) = read_RDBR();
368 write_FLAG(0xFF00 | chip->flag); 389 cs_deactive(chip);
369 390
370 if (chip->cs_chg_udelay) 391 if (chip->cs_chg_udelay)
371 udelay(chip->cs_chg_udelay); 392 udelay(chip->cs_chg_udelay);
372 ++drv_data->rx; 393 ++drv_data->rx;
373 ++drv_data->tx; 394 ++drv_data->tx;
374 } 395 }
375 write_FLAG(0xFF00); 396 cs_deactive(chip);
376
377} 397}
378 398
379static void u16_writer(struct driver_data *drv_data) 399static void u16_writer(struct driver_data *drv_data)
@@ -398,20 +418,20 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
398 struct chip_data *chip = drv_data->cur_chip; 418 struct chip_data *chip = drv_data->cur_chip;
399 419
400 while (drv_data->tx < drv_data->tx_end) { 420 while (drv_data->tx < drv_data->tx_end) {
401 write_FLAG(chip->flag); 421 cs_active(chip);
402 422
403 write_TDBR(*(u16 *) (drv_data->tx)); 423 write_TDBR(*(u16 *) (drv_data->tx));
404 while ((read_STAT() & BIT_STAT_TXS)) 424 while ((read_STAT() & BIT_STAT_TXS))
405 continue; 425 continue;
406 while (!(read_STAT() & BIT_STAT_SPIF)) 426 while (!(read_STAT() & BIT_STAT_SPIF))
407 continue; 427 continue;
408 write_FLAG(0xFF00 | chip->flag); 428 cs_deactive(chip);
409 429
410 if (chip->cs_chg_udelay) 430 if (chip->cs_chg_udelay)
411 udelay(chip->cs_chg_udelay); 431 udelay(chip->cs_chg_udelay);
412 drv_data->tx += 2; 432 drv_data->tx += 2;
413 } 433 }
414 write_FLAG(0xFF00); 434 cs_deactive(chip);
415} 435}
416 436
417static void u16_reader(struct driver_data *drv_data) 437static void u16_reader(struct driver_data *drv_data)
@@ -438,7 +458,7 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
438 struct chip_data *chip = drv_data->cur_chip; 458 struct chip_data *chip = drv_data->cur_chip;
439 459
440 while (drv_data->rx < drv_data->rx_end) { 460 while (drv_data->rx < drv_data->rx_end) {
441 write_FLAG(chip->flag); 461 cs_active(chip);
442 462
443 read_RDBR(); /* kick off */ 463 read_RDBR(); /* kick off */
444 while (!(read_STAT() & BIT_STAT_RXS)) 464 while (!(read_STAT() & BIT_STAT_RXS))
@@ -446,13 +466,13 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
446 while (!(read_STAT() & BIT_STAT_SPIF)) 466 while (!(read_STAT() & BIT_STAT_SPIF))
447 continue; 467 continue;
448 *(u16 *) (drv_data->rx) = read_SHAW(); 468 *(u16 *) (drv_data->rx) = read_SHAW();
449 write_FLAG(0xFF00 | chip->flag); 469 cs_deactive(chip);
450 470
451 if (chip->cs_chg_udelay) 471 if (chip->cs_chg_udelay)
452 udelay(chip->cs_chg_udelay); 472 udelay(chip->cs_chg_udelay);
453 drv_data->rx += 2; 473 drv_data->rx += 2;
454 } 474 }
455 write_FLAG(0xFF00); 475 cs_deactive(chip);
456} 476}
457 477
458static void u16_duplex(struct driver_data *drv_data) 478static void u16_duplex(struct driver_data *drv_data)
@@ -475,7 +495,7 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
475 struct chip_data *chip = drv_data->cur_chip; 495 struct chip_data *chip = drv_data->cur_chip;
476 496
477 while (drv_data->tx < drv_data->tx_end) { 497 while (drv_data->tx < drv_data->tx_end) {
478 write_FLAG(chip->flag); 498 cs_active(chip);
479 499
480 write_TDBR(*(u16 *) (drv_data->tx)); 500 write_TDBR(*(u16 *) (drv_data->tx));
481 while (!(read_STAT() & BIT_STAT_SPIF)) 501 while (!(read_STAT() & BIT_STAT_SPIF))
@@ -483,14 +503,14 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
483 while (!(read_STAT() & BIT_STAT_RXS)) 503 while (!(read_STAT() & BIT_STAT_RXS))
484 continue; 504 continue;
485 *(u16 *) (drv_data->rx) = read_RDBR(); 505 *(u16 *) (drv_data->rx) = read_RDBR();
486 write_FLAG(0xFF00 | chip->flag); 506 cs_deactive(chip);
487 507
488 if (chip->cs_chg_udelay) 508 if (chip->cs_chg_udelay)
489 udelay(chip->cs_chg_udelay); 509 udelay(chip->cs_chg_udelay);
490 drv_data->rx += 2; 510 drv_data->rx += 2;
491 drv_data->tx += 2; 511 drv_data->tx += 2;
492 } 512 }
493 write_FLAG(0xFF00); 513 cs_deactive(chip);
494} 514}
495 515
496/* test if ther is more transfer to be done */ 516/* test if ther is more transfer to be done */
@@ -515,6 +535,7 @@ static void *next_transfer(struct driver_data *drv_data)
515 */ 535 */
516static void giveback(struct driver_data *drv_data) 536static void giveback(struct driver_data *drv_data)
517{ 537{
538 struct chip_data *chip = drv_data->cur_chip;
518 struct spi_transfer *last_transfer; 539 struct spi_transfer *last_transfer;
519 unsigned long flags; 540 unsigned long flags;
520 struct spi_message *msg; 541 struct spi_message *msg;
@@ -534,10 +555,13 @@ static void giveback(struct driver_data *drv_data)
534 555
535 /* disable chip select signal. And not stop spi in autobuffer mode */ 556 /* disable chip select signal. And not stop spi in autobuffer mode */
536 if (drv_data->tx_dma != 0xFFFF) { 557 if (drv_data->tx_dma != 0xFFFF) {
537 write_FLAG(0xFF00); 558 cs_deactive(chip);
538 bfin_spi_disable(drv_data); 559 bfin_spi_disable(drv_data);
539 } 560 }
540 561
562 if (!drv_data->cs_change)
563 cs_deactive(chip);
564
541 if (msg->complete) 565 if (msg->complete)
542 msg->complete(msg->context); 566 msg->complete(msg->context);
543} 567}
@@ -546,6 +570,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
546{ 570{
547 struct driver_data *drv_data = (struct driver_data *)dev_id; 571 struct driver_data *drv_data = (struct driver_data *)dev_id;
548 struct spi_message *msg = drv_data->cur_msg; 572 struct spi_message *msg = drv_data->cur_msg;
573 struct chip_data *chip = drv_data->cur_chip;
549 574
550 dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n"); 575 dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n");
551 clear_dma_irqstat(CH_SPI); 576 clear_dma_irqstat(CH_SPI);
@@ -573,6 +598,9 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
573 598
574 msg->actual_length += drv_data->len_in_bytes; 599 msg->actual_length += drv_data->len_in_bytes;
575 600
601 if (drv_data->cs_change)
602 cs_deactive(chip);
603
576 /* Move to next transfer */ 604 /* Move to next transfer */
577 msg->state = next_transfer(drv_data); 605 msg->state = next_transfer(drv_data);
578 606
@@ -659,6 +687,7 @@ static void pump_transfers(unsigned long data)
659 drv_data->rx_dma = transfer->rx_dma; 687 drv_data->rx_dma = transfer->rx_dma;
660 drv_data->tx_dma = transfer->tx_dma; 688 drv_data->tx_dma = transfer->tx_dma;
661 drv_data->len_in_bytes = transfer->len; 689 drv_data->len_in_bytes = transfer->len;
690 drv_data->cs_change = transfer->cs_change;
662 691
663 width = chip->width; 692 width = chip->width;
664 if (width == CFG_SPI_WORDSIZE16) { 693 if (width == CFG_SPI_WORDSIZE16) {
@@ -683,7 +712,7 @@ static void pump_transfers(unsigned long data)
683 } else { 712 } else {
684 write_BAUD(chip->baud); 713 write_BAUD(chip->baud);
685 } 714 }
686 write_FLAG(chip->flag); 715 cs_active(chip);
687 716
688 dev_dbg(&drv_data->pdev->dev, 717 dev_dbg(&drv_data->pdev->dev,
689 "now pumping a transfer: width is %d, len is %d\n", 718 "now pumping a transfer: width is %d, len is %d\n",
@@ -834,6 +863,9 @@ static void pump_transfers(unsigned long data)
834 /* Update total byte transfered */ 863 /* Update total byte transfered */
835 message->actual_length += drv_data->len; 864 message->actual_length += drv_data->len;
836 865
866 if (drv_data->cs_change)
867 cs_deactive(chip);
868
837 /* Move to next transfer of this msg */ 869 /* Move to next transfer of this msg */
838 message->state = next_transfer(drv_data); 870 message->state = next_transfer(drv_data);
839 } 871 }