mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
spi: spi-bcm2835: Re-enable HW CS
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
This commit is contained in:
@@ -934,9 +934,57 @@ static void bcm2835_spi_handle_err(struct spi_controller *ctlr,
|
||||
bcm2835_spi_reset_hw(ctlr);
|
||||
}
|
||||
|
||||
static int chip_match_name(struct gpio_chip *chip, void *data)
|
||||
static void bcm2835_spi_set_cs(struct spi_device *spi, bool gpio_level)
|
||||
{
|
||||
return !strcmp(chip->label, data);
|
||||
/*
|
||||
* we can assume that we are "native" as per spi_set_cs
|
||||
* calling us ONLY when cs_gpio is not set
|
||||
* we can also assume that we are CS < 3 as per bcm2835_spi_setup
|
||||
* we would not get called because of error handling there.
|
||||
* the level passed is the electrical level not enabled/disabled
|
||||
* so it has to get translated back to enable/disable
|
||||
* see spi_set_cs in spi.c for the implementation
|
||||
*/
|
||||
|
||||
struct spi_master *master = spi->master;
|
||||
struct bcm2835_spi *bs = spi_master_get_devdata(master);
|
||||
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
|
||||
bool enable;
|
||||
|
||||
/* calculate the enable flag from the passed gpio_level */
|
||||
enable = (spi->mode & SPI_CS_HIGH) ? gpio_level : !gpio_level;
|
||||
|
||||
/* set flags for "reverse" polarity in the registers */
|
||||
if (spi->mode & SPI_CS_HIGH) {
|
||||
/* set the correct CS-bits */
|
||||
cs |= BCM2835_SPI_CS_CSPOL;
|
||||
cs |= BCM2835_SPI_CS_CSPOL0 << spi->chip_select;
|
||||
} else {
|
||||
/* clean the CS-bits */
|
||||
cs &= ~BCM2835_SPI_CS_CSPOL;
|
||||
cs &= ~(BCM2835_SPI_CS_CSPOL0 << spi->chip_select);
|
||||
}
|
||||
|
||||
/* select the correct chip_select depending on disabled/enabled */
|
||||
if (enable) {
|
||||
/* set cs correctly */
|
||||
if (spi->mode & SPI_NO_CS) {
|
||||
/* use the "undefined" chip-select */
|
||||
cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01;
|
||||
} else {
|
||||
/* set the chip select */
|
||||
cs &= ~(BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01);
|
||||
cs |= spi->chip_select;
|
||||
}
|
||||
} else {
|
||||
/* disable CSPOL which puts HW-CS into deselected state */
|
||||
cs &= ~BCM2835_SPI_CS_CSPOL;
|
||||
/* use the "undefined" chip-select as precaution */
|
||||
cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01;
|
||||
}
|
||||
|
||||
/* finally set the calculated flags in SPI_CS */
|
||||
bcm2835_wr(bs, BCM2835_SPI_CS, cs);
|
||||
}
|
||||
|
||||
static int bcm2835_spi_setup(struct spi_device *spi)
|
||||
@@ -1003,6 +1051,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
|
||||
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
ctlr->num_chipselect = 3;
|
||||
ctlr->setup = bcm2835_spi_setup;
|
||||
ctlr->set_cs = bcm2835_spi_set_cs;
|
||||
ctlr->transfer_one = bcm2835_spi_transfer_one;
|
||||
ctlr->handle_err = bcm2835_spi_handle_err;
|
||||
ctlr->prepare_message = bcm2835_spi_prepare_message;
|
||||
|
||||
Reference in New Issue
Block a user