Root/target/linux/ar71xx/patches-3.2/207-spi-ath79-make-chipselect-logic-more-flexible.patch

1From b875f877d06acb852342636db4c3d1e6c9fe01ba Mon Sep 17 00:00:00 2001
2From: Gabor Juhos <juhosg@openwrt.org>
3Date: Wed, 11 Jan 2012 22:25:11 +0100
4Subject: [PATCH 7/7] spi/ath79: make chipselect logic more flexible
5
6Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
7---
8 .../include/asm/mach-ath79/ath79_spi_platform.h | 8 ++-
9 drivers/spi/spi-ath79.c | 65 +++++++++++--------
10 2 files changed, 45 insertions(+), 28 deletions(-)
11
12--- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
13+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
14@@ -16,8 +16,14 @@ struct ath79_spi_platform_data {
15     unsigned num_chipselect;
16 };
17 
18+enum ath79_spi_cs_type {
19+ ATH79_SPI_CS_TYPE_INTERNAL,
20+ ATH79_SPI_CS_TYPE_GPIO,
21+};
22+
23 struct ath79_spi_controller_data {
24- unsigned gpio;
25+ enum ath79_spi_cs_type cs_type;
26+ unsigned cs_line;
27 };
28 
29 #endif /* _ATH79_SPI_PLATFORM_H */
30--- a/drivers/spi/spi-ath79.c
31+++ b/drivers/spi/spi-ath79.c
32@@ -30,6 +30,8 @@
33 
34 #define DRV_NAME "ath79-spi"
35 
36+#define ATH79_SPI_CS_LINE_MAX 2
37+
38 struct ath79_spi {
39     struct spi_bitbang bitbang;
40     u32 ioc_base;
41@@ -62,6 +64,7 @@ static void ath79_spi_chipselect(struct
42 {
43     struct ath79_spi *sp = ath79_spidev_to_sp(spi);
44     int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
45+ struct ath79_spi_controller_data *cdata = spi->controller_data;
46 
47     if (is_active) {
48         /* set initial clock polarity */
49@@ -73,20 +76,21 @@ static void ath79_spi_chipselect(struct
50         ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
51     }
52 
53- if (spi->chip_select) {
54- struct ath79_spi_controller_data *cdata = spi->controller_data;
55-
56- /* SPI is normally active-low */
57- gpio_set_value(cdata->gpio, cs_high);
58- } else {
59+ switch (cdata->cs_type) {
60+ case ATH79_SPI_CS_TYPE_INTERNAL:
61         if (cs_high)
62- sp->ioc_base |= AR71XX_SPI_IOC_CS0;
63+ sp->ioc_base |= AR71XX_SPI_IOC_CS(cdata->cs_line);
64         else
65- sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
66+ sp->ioc_base &= ~AR71XX_SPI_IOC_CS(cdata->cs_line);
67 
68         ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
69- }
70+ break;
71 
72+ case ATH79_SPI_CS_TYPE_GPIO:
73+ /* SPI is normally active-low */
74+ gpio_set_value(cdata->cs_line, cs_high);
75+ break;
76+ }
77 }
78 
79 static void ath79_spi_enable(struct ath79_spi *sp)
80@@ -113,24 +117,30 @@ static void ath79_spi_disable(struct ath
81 static int ath79_spi_setup_cs(struct spi_device *spi)
82 {
83     struct ath79_spi_controller_data *cdata;
84+ unsigned long flags;
85     int status;
86 
87     cdata = spi->controller_data;
88- if (spi->chip_select && !cdata)
89+ if (!cdata)
90         return -EINVAL;
91 
92     status = 0;
93- if (spi->chip_select) {
94- unsigned long flags;
95+ switch (cdata->cs_type) {
96+ case ATH79_SPI_CS_TYPE_INTERNAL:
97+ if (cdata->cs_line > ATH79_SPI_CS_LINE_MAX)
98+ status = -EINVAL;
99+ break;
100 
101+ case ATH79_SPI_CS_TYPE_GPIO:
102         flags = GPIOF_DIR_OUT;
103         if (spi->mode & SPI_CS_HIGH)
104             flags |= GPIOF_INIT_HIGH;
105         else
106             flags |= GPIOF_INIT_LOW;
107 
108- status = gpio_request_one(cdata->gpio, flags,
109+ status = gpio_request_one(cdata->cs_line, flags,
110                       dev_name(&spi->dev));
111+ break;
112     }
113 
114     return status;
115@@ -138,9 +148,15 @@ static int ath79_spi_setup_cs(struct spi
116 
117 static void ath79_spi_cleanup_cs(struct spi_device *spi)
118 {
119- if (spi->chip_select) {
120- struct ath79_spi_controller_data *cdata = spi->controller_data;
121- gpio_free(cdata->gpio);
122+ struct ath79_spi_controller_data *cdata = spi->controller_data;
123+
124+ switch (cdata->cs_type) {
125+ case ATH79_SPI_CS_TYPE_INTERNAL:
126+ /* nothing to do */
127+ break;
128+ case ATH79_SPI_CS_TYPE_GPIO:
129+ gpio_free(cdata->cs_line);
130+ break;
131     }
132 }
133 
134@@ -206,6 +222,10 @@ static __devinit int ath79_spi_probe(str
135     struct resource *r;
136     int ret;
137 
138+ pdata = pdev->dev.platform_data;
139+ if (!pdata)
140+ return -EINVAL;
141+
142     master = spi_alloc_master(&pdev->dev, sizeof(*sp));
143     if (master == NULL) {
144         dev_err(&pdev->dev, "failed to allocate spi master\n");
145@@ -215,17 +235,10 @@ static __devinit int ath79_spi_probe(str
146     sp = spi_master_get_devdata(master);
147     platform_set_drvdata(pdev, sp);
148 
149- pdata = pdev->dev.platform_data;
150-
151     master->setup = ath79_spi_setup;
152     master->cleanup = ath79_spi_cleanup;
153- if (pdata) {
154- master->bus_num = pdata->bus_num;
155- master->num_chipselect = pdata->num_chipselect;
156- } else {
157- master->bus_num = -1;
158- master->num_chipselect = 1;
159- }
160+ master->bus_num = pdata->bus_num;
161+ master->num_chipselect = pdata->num_chipselect;
162 
163     sp->bitbang.master = spi_master_get(master);
164     sp->bitbang.chipselect = ath79_spi_chipselect;
165

Archive Download this file



interactive