aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Miao <eric.miao@marvell.com>2009-04-06 22:00:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 11:31:07 -0400
commita7bb3909b3293d503211d7f6af8ed62c1644b686 (patch)
tree7e3cc012c12ff689194333b2ac9988be16df9c55
parentc8fc657e6a114fadf78fdf8103e289a169c91c5d (diff)
spi: pxa2xx_spi: introduce chipselect GPIO to simplify the common cases
Most SPI peripherals use GPIOs as their chip selects, introduce .gpio_cs for this. Signed-off-by: Eric Miao <eric.miao@marvell.com> Cc: David Brownell <david-b@pacbell.net> Cc: Russell King <rmk@arm.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa2xx_spi.h1
-rw-r--r--drivers/spi/pxa2xx_spi.c96
2 files changed, 79 insertions, 18 deletions
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h b/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h
index 2206cb61a9f9..b87cecd9bbdc 100644
--- a/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h
+++ b/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h
@@ -38,6 +38,7 @@ struct pxa2xx_spi_chip {
38 u8 dma_burst_size; 38 u8 dma_burst_size;
39 u32 timeout; 39 u32 timeout;
40 u8 enable_loopback; 40 u8 enable_loopback;
41 int gpio_cs;
41 void (*cs_control)(u32 command); 42 void (*cs_control)(u32 command);
42}; 43};
43 44
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 33fcef3150d4..70ff0072cb8a 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -28,6 +28,7 @@
28#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/clk.h> 30#include <linux/clk.h>
31#include <linux/gpio.h>
31 32
32#include <asm/io.h> 33#include <asm/io.h>
33#include <asm/irq.h> 34#include <asm/irq.h>
@@ -166,6 +167,8 @@ struct chip_data {
166 u8 enable_dma; 167 u8 enable_dma;
167 u8 bits_per_word; 168 u8 bits_per_word;
168 u32 speed_hz; 169 u32 speed_hz;
170 int gpio_cs;
171 int gpio_cs_inverted;
169 int (*write)(struct driver_data *drv_data); 172 int (*write)(struct driver_data *drv_data);
170 int (*read)(struct driver_data *drv_data); 173 int (*read)(struct driver_data *drv_data);
171 void (*cs_control)(u32 command); 174 void (*cs_control)(u32 command);
@@ -173,6 +176,32 @@ struct chip_data {
173 176
174static void pump_messages(struct work_struct *work); 177static void pump_messages(struct work_struct *work);
175 178
179static void cs_assert(struct driver_data *drv_data)
180{
181 struct chip_data *chip = drv_data->cur_chip;
182
183 if (chip->cs_control) {
184 chip->cs_control(PXA2XX_CS_ASSERT);
185 return;
186 }
187
188 if (gpio_is_valid(chip->gpio_cs))
189 gpio_set_value(chip->gpio_cs, chip->gpio_cs_inverted);
190}
191
192static void cs_deassert(struct driver_data *drv_data)
193{
194 struct chip_data *chip = drv_data->cur_chip;
195
196 if (chip->cs_control) {
197 chip->cs_control(PXA2XX_CS_ASSERT);
198 return;
199 }
200
201 if (gpio_is_valid(chip->gpio_cs))
202 gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted);
203}
204
176static int flush(struct driver_data *drv_data) 205static int flush(struct driver_data *drv_data)
177{ 206{
178 unsigned long limit = loops_per_jiffy << 1; 207 unsigned long limit = loops_per_jiffy << 1;
@@ -189,10 +218,6 @@ static int flush(struct driver_data *drv_data)
189 return limit; 218 return limit;
190} 219}
191 220
192static void null_cs_control(u32 command)
193{
194}
195
196static int null_writer(struct driver_data *drv_data) 221static int null_writer(struct driver_data *drv_data)
197{ 222{
198 void __iomem *reg = drv_data->ioaddr; 223 void __iomem *reg = drv_data->ioaddr;
@@ -400,7 +425,6 @@ static void giveback(struct driver_data *drv_data)
400 msg = drv_data->cur_msg; 425 msg = drv_data->cur_msg;
401 drv_data->cur_msg = NULL; 426 drv_data->cur_msg = NULL;
402 drv_data->cur_transfer = NULL; 427 drv_data->cur_transfer = NULL;
403 drv_data->cur_chip = NULL;
404 queue_work(drv_data->workqueue, &drv_data->pump_messages); 428 queue_work(drv_data->workqueue, &drv_data->pump_messages);
405 spin_unlock_irqrestore(&drv_data->lock, flags); 429 spin_unlock_irqrestore(&drv_data->lock, flags);
406 430
@@ -416,7 +440,7 @@ static void giveback(struct driver_data *drv_data)
416 * a message with an error, or next message is for another chip 440 * a message with an error, or next message is for another chip
417 */ 441 */
418 if (!last_transfer->cs_change) 442 if (!last_transfer->cs_change)
419 drv_data->cs_control(PXA2XX_CS_DEASSERT); 443 cs_deassert(drv_data);
420 else { 444 else {
421 struct spi_message *next_msg; 445 struct spi_message *next_msg;
422 446
@@ -445,12 +469,14 @@ static void giveback(struct driver_data *drv_data)
445 if (next_msg && next_msg->spi != msg->spi) 469 if (next_msg && next_msg->spi != msg->spi)
446 next_msg = NULL; 470 next_msg = NULL;
447 if (!next_msg || msg->state == ERROR_STATE) 471 if (!next_msg || msg->state == ERROR_STATE)
448 drv_data->cs_control(PXA2XX_CS_DEASSERT); 472 cs_deassert(drv_data);
449 } 473 }
450 474
451 msg->state = NULL; 475 msg->state = NULL;
452 if (msg->complete) 476 if (msg->complete)
453 msg->complete(msg->context); 477 msg->complete(msg->context);
478
479 drv_data->cur_chip = NULL;
454} 480}
455 481
456static int wait_ssp_rx_stall(void const __iomem *ioaddr) 482static int wait_ssp_rx_stall(void const __iomem *ioaddr)
@@ -887,7 +913,7 @@ static void pump_transfers(unsigned long data)
887 913
888 /* Drop chip select only if cs_change is requested */ 914 /* Drop chip select only if cs_change is requested */
889 if (previous->cs_change) 915 if (previous->cs_change)
890 drv_data->cs_control(PXA2XX_CS_DEASSERT); 916 cs_deassert(drv_data);
891 } 917 }
892 918
893 /* Check for transfers that need multiple DMA segments */ 919 /* Check for transfers that need multiple DMA segments */
@@ -922,7 +948,6 @@ static void pump_transfers(unsigned long data)
922 } 948 }
923 drv_data->n_bytes = chip->n_bytes; 949 drv_data->n_bytes = chip->n_bytes;
924 drv_data->dma_width = chip->dma_width; 950 drv_data->dma_width = chip->dma_width;
925 drv_data->cs_control = chip->cs_control;
926 drv_data->tx = (void *)transfer->tx_buf; 951 drv_data->tx = (void *)transfer->tx_buf;
927 drv_data->tx_end = drv_data->tx + transfer->len; 952 drv_data->tx_end = drv_data->tx + transfer->len;
928 drv_data->rx = transfer->rx_buf; 953 drv_data->rx = transfer->rx_buf;
@@ -1084,11 +1109,7 @@ static void pump_transfers(unsigned long data)
1084 write_SSTO(chip->timeout, reg); 1109 write_SSTO(chip->timeout, reg);
1085 } 1110 }
1086 1111
1087 /* FIXME, need to handle cs polarity, 1112 cs_assert(drv_data);
1088 * this driver uses struct pxa2xx_spi_chip.cs_control to
1089 * specify a CS handling function, and it ignores most
1090 * struct spi_device.mode[s], including SPI_CS_HIGH */
1091 drv_data->cs_control(PXA2XX_CS_ASSERT);
1092 1113
1093 /* after chip select, release the data by enabling service 1114 /* after chip select, release the data by enabling service
1094 * requests and interrupts, without changing any mode bits */ 1115 * requests and interrupts, without changing any mode bits */
@@ -1166,6 +1187,44 @@ static int transfer(struct spi_device *spi, struct spi_message *msg)
1166/* the spi->mode bits understood by this driver: */ 1187/* the spi->mode bits understood by this driver: */
1167#define MODEBITS (SPI_CPOL | SPI_CPHA) 1188#define MODEBITS (SPI_CPOL | SPI_CPHA)
1168 1189
1190static int setup_cs(struct spi_device *spi, struct chip_data *chip,
1191 struct pxa2xx_spi_chip *chip_info)
1192{
1193 int err = 0;
1194
1195 if (chip == NULL || chip_info == NULL)
1196 return 0;
1197
1198 /* NOTE: setup() can be called multiple times, possibly with
1199 * different chip_info, release previously requested GPIO
1200 */
1201 if (gpio_is_valid(chip->gpio_cs))
1202 gpio_free(chip->gpio_cs);
1203
1204 /* If (*cs_control) is provided, ignore GPIO chip select */
1205 if (chip_info->cs_control) {
1206 chip->cs_control = chip_info->cs_control;
1207 return 0;
1208 }
1209
1210 if (gpio_is_valid(chip_info->gpio_cs)) {
1211 err = gpio_request(chip_info->gpio_cs, "SPI_CS");
1212 if (err) {
1213 dev_err(&spi->dev, "failed to request chip select "
1214 "GPIO%d\n", chip_info->gpio_cs);
1215 return err;
1216 }
1217
1218 chip->gpio_cs = chip_info->gpio_cs;
1219 chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH;
1220
1221 err = gpio_direction_output(chip->gpio_cs,
1222 !chip->gpio_cs_inverted);
1223 }
1224
1225 return err;
1226}
1227
1169static int setup(struct spi_device *spi) 1228static int setup(struct spi_device *spi)
1170{ 1229{
1171 struct pxa2xx_spi_chip *chip_info = NULL; 1230 struct pxa2xx_spi_chip *chip_info = NULL;
@@ -1211,7 +1270,7 @@ static int setup(struct spi_device *spi)
1211 return -ENOMEM; 1270 return -ENOMEM;
1212 } 1271 }
1213 1272
1214 chip->cs_control = null_cs_control; 1273 chip->gpio_cs = -1;
1215 chip->enable_dma = 0; 1274 chip->enable_dma = 0;
1216 chip->timeout = TIMOUT_DFLT; 1275 chip->timeout = TIMOUT_DFLT;
1217 chip->dma_burst_size = drv_data->master_info->enable_dma ? 1276 chip->dma_burst_size = drv_data->master_info->enable_dma ?
@@ -1225,8 +1284,6 @@ static int setup(struct spi_device *spi)
1225 /* chip_info isn't always needed */ 1284 /* chip_info isn't always needed */
1226 chip->cr1 = 0; 1285 chip->cr1 = 0;
1227 if (chip_info) { 1286 if (chip_info) {
1228 if (chip_info->cs_control)
1229 chip->cs_control = chip_info->cs_control;
1230 if (chip_info->timeout) 1287 if (chip_info->timeout)
1231 chip->timeout = chip_info->timeout; 1288 chip->timeout = chip_info->timeout;
1232 if (chip_info->tx_threshold) 1289 if (chip_info->tx_threshold)
@@ -1308,13 +1365,16 @@ static int setup(struct spi_device *spi)
1308 1365
1309 spi_set_ctldata(spi, chip); 1366 spi_set_ctldata(spi, chip);
1310 1367
1311 return 0; 1368 return setup_cs(spi, chip, chip_info);
1312} 1369}
1313 1370
1314static void cleanup(struct spi_device *spi) 1371static void cleanup(struct spi_device *spi)
1315{ 1372{
1316 struct chip_data *chip = spi_get_ctldata(spi); 1373 struct chip_data *chip = spi_get_ctldata(spi);
1317 1374
1375 if (gpio_is_valid(chip->gpio_cs))
1376 gpio_free(chip->gpio_cs);
1377
1318 kfree(chip); 1378 kfree(chip);
1319} 1379}
1320 1380