aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ar71xx/patches-4.1/206-spi-ath79-make-chipselect-logic-more-flexible.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2015-07-19 17:58:40 +0000
committerFelix Fietkau <nbd@openwrt.org>2015-07-19 17:58:40 +0000
commit78b1a6b773aaebdeff6f6b43df98598749e44930 (patch)
tree1cacb1c7de856ee70af780d86e6c70b9559bb247 /target/linux/ar71xx/patches-4.1/206-spi-ath79-make-chipselect-logic-more-flexible.patch
parentd26e8d9439052ed8f433b6ffb15a5f0c54712121 (diff)
downloadupstream-78b1a6b773aaebdeff6f6b43df98598749e44930.tar.gz
upstream-78b1a6b773aaebdeff6f6b43df98598749e44930.tar.bz2
upstream-78b1a6b773aaebdeff6f6b43df98598749e44930.zip
ar71xx: add 4.1 support
Signed-off-by: Roman Yeryomin <roman@advem.lv> SVN-Revision: 46426
Diffstat (limited to 'target/linux/ar71xx/patches-4.1/206-spi-ath79-make-chipselect-logic-more-flexible.patch')
-rw-r--r--target/linux/ar71xx/patches-4.1/206-spi-ath79-make-chipselect-logic-more-flexible.patch191
1 files changed, 191 insertions, 0 deletions
diff --git a/target/linux/ar71xx/patches-4.1/206-spi-ath79-make-chipselect-logic-more-flexible.patch b/target/linux/ar71xx/patches-4.1/206-spi-ath79-make-chipselect-logic-more-flexible.patch
new file mode 100644
index 0000000000..76c067a2ea
--- /dev/null
+++ b/target/linux/ar71xx/patches-4.1/206-spi-ath79-make-chipselect-logic-more-flexible.patch
@@ -0,0 +1,191 @@
+From 7008284716403237f6bc7d7590b3ed073555bd56 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Wed, 11 Jan 2012 22:25:11 +0100
+Subject: [PATCH 34/34] spi/ath79: make chipselect logic more flexible
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ arch/mips/ath79/mach-pb44.c | 6 ++
+ .../include/asm/mach-ath79/ath79_spi_platform.h | 8 ++-
+ drivers/spi/spi-ath79.c | 67 +++++++++++++-------
+ 8 files changed, 88 insertions(+), 23 deletions(-)
+
+--- a/arch/mips/ath79/mach-pb44.c
++++ b/arch/mips/ath79/mach-pb44.c
+@@ -87,12 +87,18 @@ static struct gpio_keys_button pb44_gpio
+ }
+ };
+
++static struct ath79_spi_controller_data pb44_spi0_data = {
++ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
++ .cs_line = 0,
++};
++
+ static struct spi_board_info pb44_spi_info[] = {
+ {
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 25000000,
+ .modalias = "m25p64",
++ .controller_data = &pb44_spi0_data,
+ },
+ };
+
+--- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
++++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
+@@ -16,8 +16,14 @@ struct ath79_spi_platform_data {
+ unsigned num_chipselect;
+ };
+
++enum ath79_spi_cs_type {
++ ATH79_SPI_CS_TYPE_INTERNAL,
++ ATH79_SPI_CS_TYPE_GPIO,
++};
++
+ struct ath79_spi_controller_data {
+- unsigned gpio;
++ enum ath79_spi_cs_type cs_type;
++ unsigned cs_line;
+ };
+
+ #endif /* _ATH79_SPI_PLATFORM_H */
+--- a/drivers/spi/spi-ath79.c
++++ b/drivers/spi/spi-ath79.c
+@@ -33,6 +33,8 @@
+ #define ATH79_SPI_RRW_DELAY_FACTOR 12000
+ #define MHZ (1000 * 1000)
+
++#define ATH79_SPI_CS_LINE_MAX 2
++
+ struct ath79_spi {
+ struct spi_bitbang bitbang;
+ u32 ioc_base;
+@@ -67,6 +69,7 @@ static void ath79_spi_chipselect(struct
+ {
+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+ int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
++ struct ath79_spi_controller_data *cdata = spi->controller_data;
+
+ if (is_active) {
+ /* set initial clock polarity */
+@@ -78,20 +81,24 @@ static void ath79_spi_chipselect(struct
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+ }
+
+- if (spi->chip_select) {
+- struct ath79_spi_controller_data *cdata = spi->controller_data;
+-
+- /* SPI is normally active-low */
+- gpio_set_value(cdata->gpio, cs_high);
+- } else {
++ switch (cdata->cs_type) {
++ case ATH79_SPI_CS_TYPE_INTERNAL:
+ if (cs_high)
+- sp->ioc_base |= AR71XX_SPI_IOC_CS0;
++ sp->ioc_base |= AR71XX_SPI_IOC_CS(cdata->cs_line);
+ else
+- sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
++ sp->ioc_base &= ~AR71XX_SPI_IOC_CS(cdata->cs_line);
+
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+- }
++ break;
+
++ case ATH79_SPI_CS_TYPE_GPIO:
++ /* SPI is normally active-low */
++ if (gpio_cansleep(cdata->cs_line))
++ gpio_set_value_cansleep(cdata->cs_line, cs_high);
++ else
++ gpio_set_value(cdata->cs_line, cs_high);
++ break;
++ }
+ }
+
+ static void ath79_spi_enable(struct ath79_spi *sp)
+@@ -118,24 +125,30 @@ static void ath79_spi_disable(struct ath
+ static int ath79_spi_setup_cs(struct spi_device *spi)
+ {
+ struct ath79_spi_controller_data *cdata;
++ unsigned long flags;
+ int status;
+
+ cdata = spi->controller_data;
+- if (spi->chip_select && !cdata)
++ if (!cdata)
+ return -EINVAL;
+
+ status = 0;
+- if (spi->chip_select) {
+- unsigned long flags;
++ switch (cdata->cs_type) {
++ case ATH79_SPI_CS_TYPE_INTERNAL:
++ if (cdata->cs_line > ATH79_SPI_CS_LINE_MAX)
++ status = -EINVAL;
++ break;
+
++ case ATH79_SPI_CS_TYPE_GPIO:
+ flags = GPIOF_DIR_OUT;
+ if (spi->mode & SPI_CS_HIGH)
+ flags |= GPIOF_INIT_LOW;
+ else
+ flags |= GPIOF_INIT_HIGH;
+
+- status = gpio_request_one(cdata->gpio, flags,
++ status = gpio_request_one(cdata->cs_line, flags,
+ dev_name(&spi->dev));
++ break;
+ }
+
+ return status;
+@@ -143,9 +156,19 @@ static int ath79_spi_setup_cs(struct spi
+
+ static void ath79_spi_cleanup_cs(struct spi_device *spi)
+ {
+- if (spi->chip_select) {
+- struct ath79_spi_controller_data *cdata = spi->controller_data;
+- gpio_free(cdata->gpio);
++ struct ath79_spi_controller_data *cdata;
++
++ cdata = spi->controller_data;
++ if (!cdata)
++ return;
++
++ switch (cdata->cs_type) {
++ case ATH79_SPI_CS_TYPE_INTERNAL:
++ /* nothing to do */
++ break;
++ case ATH79_SPI_CS_TYPE_GPIO:
++ gpio_free(cdata->cs_line);
++ break;
+ }
+ }
+
+@@ -210,6 +233,10 @@ static int ath79_spi_probe(struct platfo
+ unsigned long rate;
+ int ret;
+
++ pdata = pdev->dev.platform_data;
++ if (!pdata)
++ return -EINVAL;
++
+ master = spi_alloc_master(&pdev->dev, sizeof(*sp));
+ if (master == NULL) {
+ dev_err(&pdev->dev, "failed to allocate spi master\n");
+@@ -219,15 +246,11 @@ static int ath79_spi_probe(struct platfo
+ sp = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, sp);
+
+- pdata = dev_get_platdata(&pdev->dev);
+-
+ master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
+ master->setup = ath79_spi_setup;
+ master->cleanup = ath79_spi_cleanup;
+- if (pdata) {
+- master->bus_num = pdata->bus_num;
+- master->num_chipselect = pdata->num_chipselect;
+- }
++ master->bus_num = pdata->bus_num;
++ master->num_chipselect = pdata->num_chipselect;
+
+ sp->bitbang.master = master;
+ sp->bitbang.chipselect = ath79_spi_chipselect;