Skip to content

Commit

Permalink
Merge pull request #1125 from msperl/rpi-4.1.y-spi-bcm2835-patches-fi…
Browse files Browse the repository at this point in the history
…xpolarity

Rpi 4.1.y spi bcm2835 patches clock-polarity issues
  • Loading branch information
popcornmix committed Sep 4, 2015
2 parents 6b30ac8 + d12cb34 commit 5a63610
Showing 1 changed file with 29 additions and 9 deletions.
38 changes: 29 additions & 9 deletions drivers/spi/spi-bcm2835.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
struct spi_device *spi,
struct spi_transfer *tfr,
u32 cs,
unsigned long xfer_time_us)
unsigned long long xfer_time_us)
{
struct bcm2835_spi *bs = spi_master_get_devdata(master);
unsigned long timeout;
Expand Down Expand Up @@ -531,7 +531,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
{
struct bcm2835_spi *bs = spi_master_get_devdata(master);
unsigned long spi_hz, clk_hz, cdiv;
unsigned long spi_used_hz, xfer_time_us;
unsigned long spi_used_hz;
unsigned long long xfer_time_us;
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);

/* set clock */
Expand All @@ -553,13 +554,11 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
spi_used_hz = cdiv ? (clk_hz / cdiv) : (clk_hz / 65536);
bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv);

/* handle all the modes */
/* handle all the 3-wire mode */
if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf))
cs |= BCM2835_SPI_CS_REN;
if (spi->mode & SPI_CPOL)
cs |= BCM2835_SPI_CS_CPOL;
if (spi->mode & SPI_CPHA)
cs |= BCM2835_SPI_CS_CPHA;
else
cs &= ~BCM2835_SPI_CS_REN;

/* for gpio_cs set dummy CS so that no HW-CS get changed
* we can not run this in bcm2835_spi_set_cs, as it does
Expand All @@ -575,9 +574,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
bs->rx_len = tfr->len;

/* calculate the estimated time in us the transfer runs */
xfer_time_us = tfr->len
xfer_time_us = (unsigned long long)tfr->len
* 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */
* 1000000 / spi_used_hz;
* 1000000;
do_div(xfer_time_us, spi_used_hz);

/* for short requests run polling*/
if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US)
Expand All @@ -592,6 +592,25 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs);
}

static int bcm2835_spi_prepare_message(struct spi_master *master,
struct spi_message *msg)
{
struct spi_device *spi = msg->spi;
struct bcm2835_spi *bs = spi_master_get_devdata(master);
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);

cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA);

if (spi->mode & SPI_CPOL)
cs |= BCM2835_SPI_CS_CPOL;
if (spi->mode & SPI_CPHA)
cs |= BCM2835_SPI_CS_CPHA;

bcm2835_wr(bs, BCM2835_SPI_CS, cs);

return 0;
}

static void bcm2835_spi_handle_err(struct spi_master *master,
struct spi_message *msg)
{
Expand Down Expand Up @@ -768,6 +787,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
master->set_cs = bcm2835_spi_set_cs;
master->transfer_one = bcm2835_spi_transfer_one;
master->handle_err = bcm2835_spi_handle_err;
master->prepare_message = bcm2835_spi_prepare_message;
master->dev.of_node = pdev->dev.of_node;

bs = spi_master_get_devdata(master);
Expand Down

0 comments on commit 5a63610

Please sign in to comment.