brcm47xx: add code to generate images for some netgear devices
[openwrt.git] / target / linux / ar71xx / patches-3.3 / 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 @@ -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;
This page took 0.046902 seconds and 5 git commands to generate.