~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/spi/spi_bfin5xx.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
425
425
        struct bfin_spi_slave_data *chip = drv_data->cur_chip;
426
426
        struct spi_message *msg = drv_data->cur_msg;
427
427
        int n_bytes = drv_data->n_bytes;
 
428
        int loop = 0;
428
429
 
429
430
        /* wait until transfer finished. */
430
431
        while (!(read_STAT(drv_data) & BIT_STAT_RXS))
435
436
                /* last read */
436
437
                if (drv_data->rx) {
437
438
                        dev_dbg(&drv_data->pdev->dev, "last read\n");
438
 
                        if (n_bytes == 2)
439
 
                                *(u16 *) (drv_data->rx) = read_RDBR(drv_data);
440
 
                        else if (n_bytes == 1)
441
 
                                *(u8 *) (drv_data->rx) = read_RDBR(drv_data);
 
439
                        if (n_bytes % 2) {
 
440
                                u16 *buf = (u16 *)drv_data->rx;
 
441
                                for (loop = 0; loop < n_bytes / 2; loop++)
 
442
                                        *buf++ = read_RDBR(drv_data);
 
443
                        } else {
 
444
                                u8 *buf = (u8 *)drv_data->rx;
 
445
                                for (loop = 0; loop < n_bytes; loop++)
 
446
                                        *buf++ = read_RDBR(drv_data);
 
447
                        }
442
448
                        drv_data->rx += n_bytes;
443
449
                }
444
450
 
458
464
        if (drv_data->rx && drv_data->tx) {
459
465
                /* duplex */
460
466
                dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n");
461
 
                if (drv_data->n_bytes == 2) {
462
 
                        *(u16 *) (drv_data->rx) = read_RDBR(drv_data);
463
 
                        write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
464
 
                } else if (drv_data->n_bytes == 1) {
465
 
                        *(u8 *) (drv_data->rx) = read_RDBR(drv_data);
466
 
                        write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
 
467
                if (n_bytes % 2) {
 
468
                        u16 *buf = (u16 *)drv_data->rx;
 
469
                        u16 *buf2 = (u16 *)drv_data->tx;
 
470
                        for (loop = 0; loop < n_bytes / 2; loop++) {
 
471
                                *buf++ = read_RDBR(drv_data);
 
472
                                write_TDBR(drv_data, *buf2++);
 
473
                        }
 
474
                } else {
 
475
                        u8 *buf = (u8 *)drv_data->rx;
 
476
                        u8 *buf2 = (u8 *)drv_data->tx;
 
477
                        for (loop = 0; loop < n_bytes; loop++) {
 
478
                                *buf++ = read_RDBR(drv_data);
 
479
                                write_TDBR(drv_data, *buf2++);
 
480
                        }
467
481
                }
468
482
        } else if (drv_data->rx) {
469
483
                /* read */
470
484
                dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n");
471
 
                if (drv_data->n_bytes == 2)
472
 
                        *(u16 *) (drv_data->rx) = read_RDBR(drv_data);
473
 
                else if (drv_data->n_bytes == 1)
474
 
                        *(u8 *) (drv_data->rx) = read_RDBR(drv_data);
475
 
                write_TDBR(drv_data, chip->idle_tx_val);
 
485
                if (n_bytes % 2) {
 
486
                        u16 *buf = (u16 *)drv_data->rx;
 
487
                        for (loop = 0; loop < n_bytes / 2; loop++) {
 
488
                                *buf++ = read_RDBR(drv_data);
 
489
                                write_TDBR(drv_data, chip->idle_tx_val);
 
490
                        }
 
491
                } else {
 
492
                        u8 *buf = (u8 *)drv_data->rx;
 
493
                        for (loop = 0; loop < n_bytes; loop++) {
 
494
                                *buf++ = read_RDBR(drv_data);
 
495
                                write_TDBR(drv_data, chip->idle_tx_val);
 
496
                        }
 
497
                }
476
498
        } else if (drv_data->tx) {
477
499
                /* write */
478
500
                dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n");
479
 
                bfin_spi_dummy_read(drv_data);
480
 
                if (drv_data->n_bytes == 2)
481
 
                        write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
482
 
                else if (drv_data->n_bytes == 1)
483
 
                        write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
 
501
                if (n_bytes % 2) {
 
502
                        u16 *buf = (u16 *)drv_data->tx;
 
503
                        for (loop = 0; loop < n_bytes / 2; loop++) {
 
504
                                read_RDBR(drv_data);
 
505
                                write_TDBR(drv_data, *buf++);
 
506
                        }
 
507
                } else {
 
508
                        u8 *buf = (u8 *)drv_data->tx;
 
509
                        for (loop = 0; loop < n_bytes; loop++) {
 
510
                                read_RDBR(drv_data);
 
511
                                write_TDBR(drv_data, *buf++);
 
512
                        }
 
513
                }
484
514
        }
485
515
 
486
516
        if (drv_data->tx)
623
653
                message->state = bfin_spi_next_transfer(drv_data);
624
654
                /* Schedule next transfer tasklet */
625
655
                tasklet_schedule(&drv_data->pump_transfers);
 
656
                return;
626
657
        }
627
658
 
628
659
        if (transfer->tx_buf != NULL) {
650
681
        drv_data->cs_change = transfer->cs_change;
651
682
 
652
683
        /* Bits per word setup */
653
 
        bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word;
654
 
        if (bits_per_word == 8) {
655
 
                drv_data->n_bytes = 1;
 
684
        bits_per_word = transfer->bits_per_word ? :
 
685
                message->spi->bits_per_word ? : 8;
 
686
        if (bits_per_word % 16 == 0) {
 
687
                drv_data->n_bytes = bits_per_word/8;
 
688
                drv_data->len = (transfer->len) >> 1;
 
689
                cr_width = BIT_CTL_WORDSIZE;
 
690
                drv_data->ops = &bfin_bfin_spi_transfer_ops_u16;
 
691
        } else if (bits_per_word % 8 == 0) {
 
692
                drv_data->n_bytes = bits_per_word/8;
656
693
                drv_data->len = transfer->len;
657
694
                cr_width = 0;
658
695
                drv_data->ops = &bfin_bfin_spi_transfer_ops_u8;
659
 
        } else if (bits_per_word == 16) {
660
 
                drv_data->n_bytes = 2;
661
 
                drv_data->len = (transfer->len) >> 1;
662
 
                cr_width = BIT_CTL_WORDSIZE;
663
 
                drv_data->ops = &bfin_bfin_spi_transfer_ops_u16;
664
696
        } else {
665
697
                dev_err(&drv_data->pdev->dev, "transfer: unsupported bits_per_word\n");
666
698
                message->status = -EINVAL;
815
847
                if (drv_data->tx == NULL)
816
848
                        write_TDBR(drv_data, chip->idle_tx_val);
817
849
                else {
818
 
                        if (bits_per_word == 8)
819
 
                                write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
820
 
                        else
821
 
                                write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
 
850
                        int loop;
 
851
                        if (bits_per_word % 16 == 0) {
 
852
                                u16 *buf = (u16 *)drv_data->tx;
 
853
                                for (loop = 0; loop < bits_per_word / 16;
 
854
                                                loop++) {
 
855
                                        write_TDBR(drv_data, *buf++);
 
856
                                }
 
857
                        } else if (bits_per_word % 8 == 0) {
 
858
                                u8 *buf = (u8 *)drv_data->tx;
 
859
                                for (loop = 0; loop < bits_per_word / 8; loop++)
 
860
                                        write_TDBR(drv_data, *buf++);
 
861
                        }
 
862
 
822
863
                        drv_data->tx += drv_data->n_bytes;
823
864
                }
824
865
 
865
906
                        "IO write error!\n");
866
907
                message->state = ERROR_STATE;
867
908
        } else {
868
 
                /* Update total byte transfered */
 
909
                /* Update total byte transferred */
869
910
                message->actual_length += drv_data->len_in_bytes;
870
911
                /* Move to next transfer of this msg */
871
912
                message->state = bfin_spi_next_transfer(drv_data);
1031
1072
                chip->ctl_reg &= bfin_ctl_reg;
1032
1073
        }
1033
1074
 
1034
 
        if (spi->bits_per_word != 8 && spi->bits_per_word != 16) {
 
1075
        if (spi->bits_per_word % 8) {
1035
1076
                dev_err(&spi->dev, "%d bits_per_word is not supported\n",
1036
1077
                                spi->bits_per_word);
1037
1078
                goto error;
1244
1285
         * friends on every SPI message. Do this instead
1245
1286
         */
1246
1287
        drv_data->running = false;
1247
 
        while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
 
1288
        while ((!list_empty(&drv_data->queue) || drv_data->busy) && limit--) {
1248
1289
                spin_unlock_irqrestore(&drv_data->lock, flags);
1249
1290
                msleep(10);
1250
1291
                spin_lock_irqsave(&drv_data->lock, flags);