aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/atmel_spi.c
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-04-30 03:52:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:31 -0400
commit592e7bf80566bf5ac3ed073d4e198dd5b0824c04 (patch)
tree8e778b8c93a16b11085099214f729b3795fd19a9 /drivers/spi/atmel_spi.c
parentc6495aaabfaa8256c292c54b48ab081f4d86ad79 (diff)
atmel_spi: clean up baud rate divisor calculation
Make the baud rate divisor calculation code a bit more readable and add a few comments. Also fix wrong debug information being displayed when !new_1 and max_speed_hz == 0. [david-b@pacbell.net: fix it] Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com> Cc: "Janesh Ramakrishnan" <jramakrishnan@neuropace.com> Acked-by 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/atmel_spi.c')
-rw-r--r--drivers/spi/atmel_spi.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 02c8e305b14f..e81d59d78910 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -497,7 +497,7 @@ static int atmel_spi_setup(struct spi_device *spi)
497 struct atmel_spi *as; 497 struct atmel_spi *as;
498 u32 scbr, csr; 498 u32 scbr, csr;
499 unsigned int bits = spi->bits_per_word; 499 unsigned int bits = spi->bits_per_word;
500 unsigned long bus_hz, sck_hz; 500 unsigned long bus_hz;
501 unsigned int npcs_pin; 501 unsigned int npcs_pin;
502 int ret; 502 int ret;
503 503
@@ -536,14 +536,25 @@ static int atmel_spi_setup(struct spi_device *spi)
536 return -EINVAL; 536 return -EINVAL;
537 } 537 }
538 538
539 /* speed zero convention is used by some upper layers */ 539 /*
540 * Pre-new_1 chips start out at half the peripheral
541 * bus speed.
542 */
540 bus_hz = clk_get_rate(as->clk); 543 bus_hz = clk_get_rate(as->clk);
544 if (!as->new_1)
545 bus_hz /= 2;
546
541 if (spi->max_speed_hz) { 547 if (spi->max_speed_hz) {
542 /* assume div32/fdiv/mbz == 0 */ 548 /*
543 if (!as->new_1) 549 * Calculate the lowest divider that satisfies the
544 bus_hz /= 2; 550 * constraint, assuming div32/fdiv/mbz == 0.
545 scbr = ((bus_hz + spi->max_speed_hz - 1) 551 */
546 / spi->max_speed_hz); 552 scbr = DIV_ROUND_UP(bus_hz, spi->max_speed_hz);
553
554 /*
555 * If the resulting divider doesn't fit into the
556 * register bitfield, we can't satisfy the constraint.
557 */
547 if (scbr >= (1 << SPI_SCBR_SIZE)) { 558 if (scbr >= (1 << SPI_SCBR_SIZE)) {
548 dev_dbg(&spi->dev, 559 dev_dbg(&spi->dev,
549 "setup: %d Hz too slow, scbr %u; min %ld Hz\n", 560 "setup: %d Hz too slow, scbr %u; min %ld Hz\n",
@@ -551,8 +562,8 @@ static int atmel_spi_setup(struct spi_device *spi)
551 return -EINVAL; 562 return -EINVAL;
552 } 563 }
553 } else 564 } else
565 /* speed zero means "as slow as possible" */
554 scbr = 0xff; 566 scbr = 0xff;
555 sck_hz = bus_hz / scbr;
556 567
557 csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8); 568 csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8);
558 if (spi->mode & SPI_CPOL) 569 if (spi->mode & SPI_CPOL)
@@ -589,7 +600,7 @@ static int atmel_spi_setup(struct spi_device *spi)
589 600
590 dev_dbg(&spi->dev, 601 dev_dbg(&spi->dev,
591 "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n", 602 "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n",
592 sck_hz, bits, spi->mode, spi->chip_select, csr); 603 bus_hz / scbr, bits, spi->mode, spi->chip_select, csr);
593 604
594 spi_writel(as, CSR0 + 4 * spi->chip_select, csr); 605 spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
595 606