You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
1.9 KiB
71 lines
1.9 KiB
8 years ago
|
From: Felix Fietkau <nbd@nbd.name>
|
||
|
Date: Fri, 9 Dec 2016 20:09:16 +0100
|
||
|
Subject: [PATCH] spi: spi-ath79: support multiple internal chip select
|
||
|
lines
|
||
|
|
||
|
Several devices with multiple flash chips use the internal chip select
|
||
|
lines. Don't assume that chip select 1 and above are GPIO lines.
|
||
|
|
||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||
|
---
|
||
|
|
||
|
--- a/drivers/spi/spi-ath79.c
|
||
|
+++ b/drivers/spi/spi-ath79.c
|
||
|
@@ -78,14 +78,16 @@ static void ath79_spi_chipselect(struct
|
||
|
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
|
||
|
}
|
||
|
|
||
|
- if (spi->chip_select) {
|
||
|
+ if (gpio_is_valid(spi->cs_gpio)) {
|
||
|
/* SPI is normally active-low */
|
||
|
gpio_set_value(spi->cs_gpio, cs_high);
|
||
|
} else {
|
||
|
+ u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select);
|
||
|
+
|
||
|
if (cs_high)
|
||
|
- sp->ioc_base |= AR71XX_SPI_IOC_CS0;
|
||
|
+ sp->ioc_base |= cs_bit;
|
||
|
else
|
||
|
- sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
|
||
|
+ sp->ioc_base &= ~cs_bit;
|
||
|
|
||
|
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
|
||
|
}
|
||
|
@@ -118,11 +120,8 @@ static int ath79_spi_setup_cs(struct spi
|
||
|
struct ath79_spi *sp = ath79_spidev_to_sp(spi);
|
||
|
int status;
|
||
|
|
||
|
- if (spi->chip_select && !gpio_is_valid(spi->cs_gpio))
|
||
|
- return -EINVAL;
|
||
|
-
|
||
|
status = 0;
|
||
|
- if (spi->chip_select) {
|
||
|
+ if (gpio_is_valid(spi->cs_gpio)) {
|
||
|
unsigned long flags;
|
||
|
|
||
|
flags = GPIOF_DIR_OUT;
|
||
|
@@ -134,10 +133,12 @@ static int ath79_spi_setup_cs(struct spi
|
||
|
status = gpio_request_one(spi->cs_gpio, flags,
|
||
|
dev_name(&spi->dev));
|
||
|
} else {
|
||
|
+ u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select);
|
||
|
+
|
||
|
if (spi->mode & SPI_CS_HIGH)
|
||
|
- sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
|
||
|
+ sp->ioc_base &= ~cs_bit;
|
||
|
else
|
||
|
- sp->ioc_base |= AR71XX_SPI_IOC_CS0;
|
||
|
+ sp->ioc_base |= cs_bit;
|
||
|
|
||
|
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
|
||
|
}
|
||
|
@@ -147,7 +148,7 @@ static int ath79_spi_setup_cs(struct spi
|
||
|
|
||
|
static void ath79_spi_cleanup_cs(struct spi_device *spi)
|
||
|
{
|
||
|
- if (spi->chip_select) {
|
||
|
+ if (gpio_is_valid(spi->cs_gpio)) {
|
||
|
gpio_free(spi->cs_gpio);
|
||
|
}
|
||
|
}
|