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; |
