aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuotao Fu <l.fu@pengutronix.de>2009-11-13 04:41:17 -0500
committerGrant Likely <grant.likely@secretlab.ca>2009-12-08 20:48:13 -0500
commitb8d4e2ce60b63294e3408d1c5211b8a8dc4af095 (patch)
tree39fc865075d3828f0891434b482948245738021e
parentd65aea99bd9e1d2e9560c5fff6c512d93c4a78d5 (diff)
mpc52xx_spi: add gpio chipselect
This one enables the mpc52xx_spi driver for usage of user defined gpio lines as chipselect. This way we can control some more spi devices than only one V2 Changes: * preinitialize the gpio as output in probe function and call gpio_set_value in the chip select function instead of calling direction_output every time. * initialize the gpio line with output high, since we don't support CS_HIGH in the driver currently any way. change gpio value setting to default active low in chip select call. * free the gpio array while error or removing. Signed-off-by: Luotao Fu <l.fu@pengutronix.de> Acked-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--drivers/spi/mpc52xx_spi.c64
1 files changed, 60 insertions, 4 deletions
diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c
index 64862cfda19e..97beba2895e7 100644
--- a/drivers/spi/mpc52xx_spi.c
+++ b/drivers/spi/mpc52xx_spi.c
@@ -21,6 +21,7 @@
21#include <linux/spi/mpc52xx_spi.h> 21#include <linux/spi/mpc52xx_spi.h>
22#include <linux/of_spi.h> 22#include <linux/of_spi.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/of_gpio.h>
24#include <asm/time.h> 25#include <asm/time.h>
25#include <asm/mpc52xx.h> 26#include <asm/mpc52xx.h>
26 27
@@ -79,7 +80,6 @@ struct mpc52xx_spi {
79 spinlock_t lock; 80 spinlock_t lock;
80 struct work_struct work; 81 struct work_struct work;
81 82
82
83 /* Details of current transfer (length, and buffer pointers) */ 83 /* Details of current transfer (length, and buffer pointers) */
84 struct spi_message *message; /* current message */ 84 struct spi_message *message; /* current message */
85 struct spi_transfer *transfer; /* current transfer */ 85 struct spi_transfer *transfer; /* current transfer */
@@ -89,6 +89,8 @@ struct mpc52xx_spi {
89 u8 *rx_buf; 89 u8 *rx_buf;
90 const u8 *tx_buf; 90 const u8 *tx_buf;
91 int cs_change; 91 int cs_change;
92 int gpio_cs_count;
93 unsigned int *gpio_cs;
92}; 94};
93 95
94/* 96/*
@@ -96,7 +98,13 @@ struct mpc52xx_spi {
96 */ 98 */
97static void mpc52xx_spi_chipsel(struct mpc52xx_spi *ms, int value) 99static void mpc52xx_spi_chipsel(struct mpc52xx_spi *ms, int value)
98{ 100{
99 out_8(ms->regs + SPI_PORTDATA, value ? 0 : 0x08); 101 int cs;
102
103 if (ms->gpio_cs_count > 0) {
104 cs = ms->message->spi->chip_select;
105 gpio_set_value(ms->gpio_cs[cs], value ? 0 : 1);
106 } else
107 out_8(ms->regs + SPI_PORTDATA, value ? 0 : 0x08);
100} 108}
101 109
102/* 110/*
@@ -390,8 +398,9 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
390 struct spi_master *master; 398 struct spi_master *master;
391 struct mpc52xx_spi *ms; 399 struct mpc52xx_spi *ms;
392 void __iomem *regs; 400 void __iomem *regs;
393 int rc;
394 u8 ctrl1; 401 u8 ctrl1;
402 int rc, i = 0;
403 int gpio_cs;
395 404
396 /* MMIO registers */ 405 /* MMIO registers */
397 dev_dbg(&op->dev, "probing mpc5200 SPI device\n"); 406 dev_dbg(&op->dev, "probing mpc5200 SPI device\n");
@@ -426,8 +435,8 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
426 rc = -ENOMEM; 435 rc = -ENOMEM;
427 goto err_alloc; 436 goto err_alloc;
428 } 437 }
438
429 master->bus_num = -1; 439 master->bus_num = -1;
430 master->num_chipselect = 1;
431 master->setup = mpc52xx_spi_setup; 440 master->setup = mpc52xx_spi_setup;
432 master->transfer = mpc52xx_spi_transfer; 441 master->transfer = mpc52xx_spi_transfer;
433 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; 442 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
@@ -441,6 +450,40 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
441 ms->irq1 = irq_of_parse_and_map(op->node, 1); 450 ms->irq1 = irq_of_parse_and_map(op->node, 1);
442 ms->state = mpc52xx_spi_fsmstate_idle; 451 ms->state = mpc52xx_spi_fsmstate_idle;
443 ms->ipb_freq = mpc5xxx_get_bus_frequency(op->node); 452 ms->ipb_freq = mpc5xxx_get_bus_frequency(op->node);
453 ms->gpio_cs_count = of_gpio_count(op->node);
454 if (ms->gpio_cs_count > 0) {
455 master->num_chipselect = ms->gpio_cs_count;
456 ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int),
457 GFP_KERNEL);
458 if (!ms->gpio_cs) {
459 rc = -ENOMEM;
460 goto err_alloc;
461 }
462
463 for (i = 0; i < ms->gpio_cs_count; i++) {
464 gpio_cs = of_get_gpio(op->node, i);
465 if (gpio_cs < 0) {
466 dev_err(&op->dev,
467 "could not parse the gpio field "
468 "in oftree\n");
469 rc = -ENODEV;
470 goto err_gpio;
471 }
472
473 rc = gpio_request(gpio_cs, dev_name(&op->dev));
474 if (rc) {
475 dev_err(&op->dev,
476 "can't request spi cs gpio #%d "
477 "on gpio line %d\n", i, gpio_cs);
478 goto err_gpio;
479 }
480
481 gpio_direction_output(gpio_cs, 1);
482 ms->gpio_cs[i] = gpio_cs;
483 }
484 } else
485 master->num_chipselect = 1;
486
444 spin_lock_init(&ms->lock); 487 spin_lock_init(&ms->lock);
445 INIT_LIST_HEAD(&ms->queue); 488 INIT_LIST_HEAD(&ms->queue);
446 INIT_WORK(&ms->work, mpc52xx_spi_wq); 489 INIT_WORK(&ms->work, mpc52xx_spi_wq);
@@ -477,6 +520,12 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op,
477 err_register: 520 err_register:
478 dev_err(&ms->master->dev, "initialization failed\n"); 521 dev_err(&ms->master->dev, "initialization failed\n");
479 spi_master_put(master); 522 spi_master_put(master);
523 err_gpio:
524 while (i-- > 0)
525 gpio_free(ms->gpio_cs[i]);
526
527 if (ms->gpio_cs != NULL)
528 kfree(ms->gpio_cs);
480 err_alloc: 529 err_alloc:
481 err_init: 530 err_init:
482 iounmap(regs); 531 iounmap(regs);
@@ -487,10 +536,17 @@ static int __devexit mpc52xx_spi_remove(struct of_device *op)
487{ 536{
488 struct spi_master *master = dev_get_drvdata(&op->dev); 537 struct spi_master *master = dev_get_drvdata(&op->dev);
489 struct mpc52xx_spi *ms = spi_master_get_devdata(master); 538 struct mpc52xx_spi *ms = spi_master_get_devdata(master);
539 int i;
490 540
491 free_irq(ms->irq0, ms); 541 free_irq(ms->irq0, ms);
492 free_irq(ms->irq1, ms); 542 free_irq(ms->irq1, ms);
493 543
544 for (i = 0; i < ms->gpio_cs_count; i++)
545 gpio_free(ms->gpio_cs[i]);
546
547 if (ms->gpio_cs != NULL)
548 kfree(ms->gpio_cs);
549
494 spi_unregister_master(master); 550 spi_unregister_master(master);
495 spi_master_put(master); 551 spi_master_put(master);
496 iounmap(ms->regs); 552 iounmap(ms->regs);