aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Olbrich <stephanolbrich@gmx.de>2016-02-14 05:04:29 -0500
committerMark Brown <broonie@kernel.org>2016-02-15 15:45:47 -0500
commite9dd4edcc98593bbcdffc0c4f37545b8fd0ad3ea (patch)
tree69d6cc2f8d528c87b0828401659ad6ec3f751965
parentb4e2adef62062cf716d1c81adc12ad6def516f72 (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.c19
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
98struct bcm2835aux_spi { 95struct 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;