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
6 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
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(-)
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;
18 +enum ath79_spi_cs_type {
19 + ATH79_SPI_CS_TYPE_INTERNAL,
20 + ATH79_SPI_CS_TYPE_GPIO,
23 struct ath79_spi_controller_data {
25 + enum ath79_spi_cs_type cs_type;
29 #endif /* _ATH79_SPI_PLATFORM_H */
30 --- a/drivers/spi/spi-ath79.c
31 +++ b/drivers/spi/spi-ath79.c
34 #define DRV_NAME "ath79-spi"
36 +#define ATH79_SPI_CS_LINE_MAX 2
39 struct spi_bitbang bitbang;
41 @@ -62,6 +64,7 @@ static void ath79_spi_chipselect(struct
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;
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);
53 - if (spi->chip_select) {
54 - struct ath79_spi_controller_data *cdata = spi->controller_data;
56 - /* SPI is normally active-low */
57 - gpio_set_value(cdata->gpio, cs_high);
59 + switch (cdata->cs_type) {
60 + case ATH79_SPI_CS_TYPE_INTERNAL:
62 - sp->ioc_base |= AR71XX_SPI_IOC_CS0;
63 + sp->ioc_base |= AR71XX_SPI_IOC_CS(cdata->cs_line);
65 - sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
66 + sp->ioc_base &= ~AR71XX_SPI_IOC_CS(cdata->cs_line);
68 ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
72 + case ATH79_SPI_CS_TYPE_GPIO:
73 + /* SPI is normally active-low */
74 + gpio_set_value(cdata->cs_line, cs_high);
79 static void ath79_spi_enable(struct ath79_spi *sp)
80 @@ -114,24 +118,30 @@ static int ath79_spi_setup_cs(struct spi
82 struct ath79_spi *sp = ath79_spidev_to_sp(spi);
83 struct ath79_spi_controller_data *cdata;
84 + unsigned long flags;
87 cdata = spi->controller_data;
88 - if (spi->chip_select && !cdata)
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)
101 + case ATH79_SPI_CS_TYPE_GPIO:
102 flags = GPIOF_DIR_OUT;
103 if (spi->mode & SPI_CS_HIGH)
104 flags |= GPIOF_INIT_HIGH;
106 flags |= GPIOF_INIT_LOW;
108 - status = gpio_request_one(cdata->gpio, flags,
109 + status = gpio_request_one(cdata->cs_line, flags,
110 dev_name(&spi->dev));
115 @@ -139,11 +149,15 @@ static int ath79_spi_setup_cs(struct spi
117 static void ath79_spi_cleanup_cs(struct spi_device *spi)
119 - struct ath79_spi *sp = ath79_spidev_to_sp(spi);
120 + struct ath79_spi_controller_data *cdata = spi->controller_data;
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 */
129 + case ATH79_SPI_CS_TYPE_GPIO:
130 + gpio_free(cdata->cs_line);
135 @@ -209,6 +223,10 @@ static __devinit int ath79_spi_probe(str
139 + pdata = pdev->dev.platform_data;
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);
150 - pdata = pdev->dev.platform_data;
152 master->setup = ath79_spi_setup;
153 master->cleanup = ath79_spi_cleanup;
155 - master->bus_num = pdata->bus_num;
156 - master->num_chipselect = pdata->num_chipselect;
158 - master->bus_num = -1;
159 - master->num_chipselect = 1;
161 + master->bus_num = pdata->bus_num;
162 + master->num_chipselect = pdata->num_chipselect;
164 sp->bitbang.master = spi_master_get(master);
165 sp->bitbang.chipselect = ath79_spi_chipselect;