diff options
author | Stephan Olbrich <stephanolbrich@gmx.de> | 2016-02-14 05:04:29 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-02-15 15:45:47 -0500 |
commit | e9dd4edcc98593bbcdffc0c4f37545b8fd0ad3ea (patch) | |
tree | 69d6cc2f8d528c87b0828401659ad6ec3f751965 | |
parent | b4e2adef62062cf716d1c81adc12ad6def516f72 (diff) |
spi: bcm2835aux: fix CPOL/CPHA setting
The auxiliary spi supports only CPHA=0 modes as the first bit is
always output to the pin before the first clock cycle. In CPHA=1
modes the first clock edge outputs the second bit hence the slave
can never read the first bit.
Also the CPHA registers switch between clocking data in/out on
rising/falling edge hence depend on the CPOL setting.
Signed-off-by: Stephan Olbrich <stephanolbrich@gmx.de>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/spi-bcm2835aux.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c index a6e25c6c66ca..496f9adb9fc1 100644 --- a/drivers/spi/spi-bcm2835aux.c +++ b/drivers/spi/spi-bcm2835aux.c | |||
@@ -64,9 +64,9 @@ | |||
64 | #define BCM2835_AUX_SPI_CNTL0_VAR_WIDTH 0x00004000 | 64 | #define BCM2835_AUX_SPI_CNTL0_VAR_WIDTH 0x00004000 |
65 | #define BCM2835_AUX_SPI_CNTL0_DOUTHOLD 0x00003000 | 65 | #define BCM2835_AUX_SPI_CNTL0_DOUTHOLD 0x00003000 |
66 | #define BCM2835_AUX_SPI_CNTL0_ENABLE 0x00000800 | 66 | #define BCM2835_AUX_SPI_CNTL0_ENABLE 0x00000800 |
67 | #define BCM2835_AUX_SPI_CNTL0_CPHA_IN 0x00000400 | 67 | #define BCM2835_AUX_SPI_CNTL0_IN_RISING 0x00000400 |
68 | #define BCM2835_AUX_SPI_CNTL0_CLEARFIFO 0x00000200 | 68 | #define BCM2835_AUX_SPI_CNTL0_CLEARFIFO 0x00000200 |
69 | #define BCM2835_AUX_SPI_CNTL0_CPHA_OUT 0x00000100 | 69 | #define BCM2835_AUX_SPI_CNTL0_OUT_RISING 0x00000100 |
70 | #define BCM2835_AUX_SPI_CNTL0_CPOL 0x00000080 | 70 | #define BCM2835_AUX_SPI_CNTL0_CPOL 0x00000080 |
71 | #define BCM2835_AUX_SPI_CNTL0_MSBF_OUT 0x00000040 | 71 | #define BCM2835_AUX_SPI_CNTL0_MSBF_OUT 0x00000040 |
72 | #define BCM2835_AUX_SPI_CNTL0_SHIFTLEN 0x0000003F | 72 | #define BCM2835_AUX_SPI_CNTL0_SHIFTLEN 0x0000003F |
@@ -92,9 +92,6 @@ | |||
92 | #define BCM2835_AUX_SPI_POLLING_LIMIT_US 30 | 92 | #define BCM2835_AUX_SPI_POLLING_LIMIT_US 30 |
93 | #define BCM2835_AUX_SPI_POLLING_JIFFIES 2 | 93 | #define BCM2835_AUX_SPI_POLLING_JIFFIES 2 |
94 | 94 | ||
95 | #define BCM2835_AUX_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ | ||
96 | | SPI_NO_CS) | ||
97 | |||
98 | struct bcm2835aux_spi { | 95 | struct bcm2835aux_spi { |
99 | void __iomem *regs; | 96 | void __iomem *regs; |
100 | struct clk *clk; | 97 | struct clk *clk; |
@@ -389,12 +386,12 @@ static int bcm2835aux_spi_prepare_message(struct spi_master *master, | |||
389 | bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN; | 386 | bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN; |
390 | 387 | ||
391 | /* handle all the modes */ | 388 | /* handle all the modes */ |
392 | if (spi->mode & SPI_CPOL) | 389 | if (spi->mode & SPI_CPOL) { |
393 | bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL; | 390 | bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL; |
394 | if (spi->mode & SPI_CPHA) | 391 | bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_OUT_RISING; |
395 | bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT | | 392 | } else { |
396 | BCM2835_AUX_SPI_CNTL0_CPHA_IN; | 393 | bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_IN_RISING; |
397 | 394 | } | |
398 | bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); | 395 | bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); |
399 | bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); | 396 | bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); |
400 | 397 | ||
@@ -434,7 +431,7 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev) | |||
434 | } | 431 | } |
435 | 432 | ||
436 | platform_set_drvdata(pdev, master); | 433 | platform_set_drvdata(pdev, master); |
437 | master->mode_bits = BCM2835_AUX_SPI_MODE_BITS; | 434 | master->mode_bits = (SPI_CPOL | SPI_CS_HIGH | SPI_NO_CS); |
438 | master->bits_per_word_mask = SPI_BPW_MASK(8); | 435 | master->bits_per_word_mask = SPI_BPW_MASK(8); |
439 | master->num_chipselect = -1; | 436 | master->num_chipselect = -1; |
440 | master->transfer_one = bcm2835aux_spi_transfer_one; | 437 | master->transfer_one = bcm2835aux_spi_transfer_one; |