From: Phil Elwell Date: Wed, 24 Jun 2015 13:10:44 +0000 (+0100) Subject: spi-bcm2835: Support pin groups other than 7-11 X-Git-Tag: Ubuntu-raspi2-4.13.0-1015.16~303 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=b00a0743026711f388fd436d1a9d428158fdd340;p=mirror_ubuntu-artful-kernel.git spi-bcm2835: Support pin groups other than 7-11 The spi-bcm2835 driver automatically uses GPIO chip-selects due to some unreliability of the native ones. In doing so it chooses the same pins as the native chip-selects would use, but the existing code always uses pins 7 and 8, wherever the SPI function is mapped. Search the pinctrl group assigned to the driver for pins that correspond to native chip-selects, and use those for GPIO chip- selects. Signed-off-by: Phil Elwell --- diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index f35cc10772f6..5dfe20ffc286 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -688,6 +688,8 @@ static int bcm2835_spi_setup(struct spi_device *spi) { int err; struct gpio_chip *chip; + struct device_node *pins; + u32 pingroup_index; /* * sanity checking the native-chipselects */ @@ -704,15 +706,42 @@ static int bcm2835_spi_setup(struct spi_device *spi) "setup: only two native chip-selects are supported\n"); return -EINVAL; } - /* now translate native cs to GPIO */ - - /* get the gpio chip for the base */ - chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); - if (!chip) - return 0; - /* and calculate the real CS */ - spi->cs_gpio = chip->base + 8 - spi->chip_select; + /* now translate native cs to GPIO */ + /* first look for chip select pins in the devices pin groups */ + for (pingroup_index = 0; + (pins = of_parse_phandle(spi->master->dev.of_node, + "pinctrl-0", + pingroup_index)) != 0; + pingroup_index++) { + u32 pin; + u32 pin_index; + for (pin_index = 0; + of_property_read_u32_index(pins, + "brcm,pins", + pin_index, + &pin) == 0; + pin_index++) { + if (((spi->chip_select == 0) && + ((pin == 8) || (pin == 36) || (pin == 46))) || + ((spi->chip_select == 1) && + ((pin == 7) || (pin == 35)))) { + spi->cs_gpio = pin; + break; + } + } + of_node_put(pins); + } + /* if that fails, assume GPIOs 7-11 are used */ + if (!gpio_is_valid(spi->cs_gpio) ) { + /* get the gpio chip for the base */ + chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); + if (!chip) + return 0; + + /* and calculate the real CS */ + spi->cs_gpio = chip->base + 8 - spi->chip_select; + } /* and set up the "mode" and level */ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n",