aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch80
1 files changed, 80 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch b/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch
new file mode 100644
index 0000000000..d8cac64e81
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch
@@ -0,0 +1,80 @@
+From 33b150a792ccde6eded4240dea0e3ec784b07d7c Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 15 Jan 2019 12:39:50 +0000
+Subject: [PATCH] spi: spi-bcm2835: Re-enable HW CS
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/spi/spi-bcm2835.c | 53 +++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 51 insertions(+), 2 deletions(-)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -1169,9 +1169,57 @@ static void bcm2835_spi_handle_err(struc
+ 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)
+@@ -1289,6 +1337,7 @@ static int bcm2835_spi_probe(struct plat
+ ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
+ ctlr->num_chipselect = BCM2835_SPI_NUM_CS;
+ 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;