[ar71xx] refresh 3.2 patches
[openwrt/svn-archive/archive.git] / target / linux / ar71xx / patches-3.2 / 207-spi-ath79-make-chipselect-logic-more-flexible.patch
1 From b875f877d06acb852342636db4c3d1e6c9fe01ba Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Wed, 11 Jan 2012 22:25:11 +0100
4 Subject: [PATCH 7/7] spi/ath79: make chipselect logic more flexible
5
6 Signed-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 @@ -114,24 +118,30 @@ static int ath79_spi_setup_cs(struct spi
81 {
82 struct ath79_spi *sp = ath79_spidev_to_sp(spi);
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 @@ -139,11 +149,15 @@ static int ath79_spi_setup_cs(struct spi
116
117 static void ath79_spi_cleanup_cs(struct spi_device *spi)
118 {
119 - struct ath79_spi *sp = ath79_spidev_to_sp(spi);
120 + struct ath79_spi_controller_data *cdata = spi->controller_data;
121
122 - if (spi->chip_select) {
123 - struct ath79_spi_controller_data *cdata = spi->controller_data;
124 - gpio_free(cdata->gpio);
125 + switch (cdata->cs_type) {
126 + case ATH79_SPI_CS_TYPE_INTERNAL:
127 + /* nothing to do */
128 + break;
129 + case ATH79_SPI_CS_TYPE_GPIO:
130 + gpio_free(cdata->cs_line);
131 + break;
132 }
133 }
134
135 @@ -209,6 +223,10 @@ static __devinit int ath79_spi_probe(str
136 struct resource *r;
137 int ret;
138
139 + pdata = pdev->dev.platform_data;
140 + if (!pdata)
141 + return -EINVAL;
142 +
143 master = spi_alloc_master(&pdev->dev, sizeof(*sp));
144 if (master == NULL) {
145 dev_err(&pdev->dev, "failed to allocate spi master\n");
146 @@ -218,17 +236,10 @@ static __devinit int ath79_spi_probe(str
147 sp = spi_master_get_devdata(master);
148 platform_set_drvdata(pdev, sp);
149
150 - pdata = pdev->dev.platform_data;
151 -
152 master->setup = ath79_spi_setup;
153 master->cleanup = ath79_spi_cleanup;
154 - if (pdata) {
155 - master->bus_num = pdata->bus_num;
156 - master->num_chipselect = pdata->num_chipselect;
157 - } else {
158 - master->bus_num = -1;
159 - master->num_chipselect = 1;
160 - }
161 + master->bus_num = pdata->bus_num;
162 + master->num_chipselect = pdata->num_chipselect;
163
164 sp->bitbang.master = spi_master_get(master);
165 sp->bitbang.chipselect = ath79_spi_chipselect;