[PATCH 2/7] spi-bcm2708: use pinconf to change pin mode

Chris Boot bootc at bootc.net
Sat May 26 17:19:50 EDT 2012


Signed-off-by: Chris Boot <bootc at bootc.net>
---
 drivers/spi/Kconfig       |    2 ++
 drivers/spi/spi-bcm2708.c |   42 ++++++++++++++----------------------------
 2 files changed, 16 insertions(+), 28 deletions(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 937c615..f6958d5 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -77,6 +77,8 @@ config SPI_ATMEL
 config SPI_BCM2708
 	tristate "BCM2708 SPI controller driver (SPI0)"
 	depends on MACH_BCM2708
+	select PINCONF
+	select PINCTRL_BCM2708
 	help
 	  This selects a driver for the Broadcom BCM2708 SPI master (SPI0). This
 	  driver is not compatible with the "Universal SPI Master" or the SPI slave
diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c
index efbad68..75f5fce 100644
--- a/drivers/spi/spi-bcm2708.c
+++ b/drivers/spi/spi-bcm2708.c
@@ -38,6 +38,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/pinctrl/consumer.h>
 
 /* SPI register offsets */
 #define SPI_CS			0x00
@@ -83,6 +84,7 @@ struct bcm2708_spi {
 	void __iomem *base;
 	int irq;
 	struct clk *clk;
+	struct pinctrl *pctl;
 	bool stopping;
 
 	struct list_head queue;
@@ -100,32 +102,6 @@ struct bcm2708_spi_state {
 	u16 cdiv;
 };
 
-/*
- * This function sets the ALT mode on the SPI pins so that we can use them with
- * the SPI hardware.
- *
- * FIXME: This is a hack. Use pinmux / pinctrl.
- */
-static void bcm2708_init_pinmode(void)
-{
-#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
-#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
-
-	int pin;
-	u32 *gpio = ioremap(0x20200000, SZ_16K);
-
-	/* SPI is on GPIO 7..11 */
-	for (pin = 7; pin <= 11; pin++) {
-		INP_GPIO(pin);		/* set mode to GPIO input first */
-		SET_GPIO_ALT(pin, 0);	/* set mode to ALT 0 */
-	}
-
-	iounmap(gpio);
-
-#undef INP_GPIO
-#undef SET_GPIO_ALT
-}
-
 static inline u32 bcm2708_rd(struct bcm2708_spi *bs, unsigned reg)
 {
 	return readl(bs->base + reg);
@@ -447,6 +423,7 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev)
 	struct resource iomem;
 	int irq, err;
 	struct clk *clk;
+	struct pinctrl *pctl;
 	struct spi_master *master;
 	struct bcm2708_spi *bs;
 
@@ -468,13 +445,18 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev)
 		return PTR_ERR(clk);
 	}
 
-	bcm2708_init_pinmode();
+	pctl = pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pctl)) {
+		err = PTR_ERR(pctl);
+		dev_err(&pdev->dev, "could not set up pinctrl: %d\n", err);
+		goto out_clk_put;
+	}
 
 	master = spi_alloc_master(&pdev->dev, sizeof(*bs));
 	if (!master) {
 		dev_err(&pdev->dev, "spi_alloc_master() failed\n");
 		err = -ENOMEM;
-		goto out_clk_put;
+		goto out_pinctrl_put;
 	}
 
 	/* the spi->mode bits understood by this driver: */
@@ -517,6 +499,7 @@ static int __devinit bcm2708_spi_probe(struct platform_device *pdev)
 	bs->iomem = iomem;
 	bs->irq = irq;
 	bs->clk = clk;
+	bs->pctl = pctl;
 	bs->stopping = false;
 
 	err = request_irq(irq, bcm2708_spi_interrupt, 0, dev_name(&pdev->dev),
@@ -551,6 +534,8 @@ out_release_region:
 	release_region(iomem.start, resource_size(&iomem));
 out_master_put:
 	spi_master_put(master);
+out_pinctrl_put:
+	pinctrl_put(pctl);
 out_clk_put:
 	clk_put(clk);
 	return err;
@@ -569,6 +554,7 @@ static int __devexit bcm2708_spi_remove(struct platform_device *pdev)
 
 	flush_work_sync(&bs->work);
 
+	pinctrl_put(bs->pctl);
 	clk_unprepare(bs->clk);
 	clk_put(bs->clk);
 	free_irq(bs->irq, master);
-- 
1.7.10




More information about the linux-rpi-kernel mailing list