[PATCH 4/7] i2c-bcm2708: use pinconf to change pin mode
Chris Boot
bootc at bootc.net
Sat May 26 17:19:52 EDT 2012
Signed-off-by: Chris Boot <bootc at bootc.net>
---
drivers/i2c/busses/Kconfig | 2 ++
drivers/i2c/busses/i2c-bcm2708.c | 42 +++++++++++++-------------------------
2 files changed, 16 insertions(+), 28 deletions(-)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index b59372d..d091251 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -312,6 +312,8 @@ config I2C_AU1550
config I2C_BCM2708
tristate "BCM2708 BSC"
depends on MACH_BCM2708
+ select PINCONF
+ select PINCTRL_BCM2708
help
Enabling this option will add BSC (Broadcom Serial Controller)
support for the BCM2708. BSC is a Broadcom proprietary bus compatible
diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c
index 2ecae2a..785b892 100644
--- a/drivers/i2c/busses/i2c-bcm2708.c
+++ b/drivers/i2c/busses/i2c-bcm2708.c
@@ -37,6 +37,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_i2c.h>
+#include <linux/pinctrl/consumer.h>
/* BSC register offsets */
#define BSC_C 0x00
@@ -83,6 +84,7 @@ struct bcm2708_i2c {
void __iomem *base;
int irq;
struct clk *clk;
+ struct pinctrl *pctl;
unsigned long bus_hz;
struct completion done;
@@ -93,32 +95,6 @@ struct bcm2708_i2c {
bool error;
};
-/*
- * This function sets the ALT mode on the I2C pins so that we can use them with
- * the BSC hardware.
- *
- * FIXME: This is a hack. Use pinmux / pinctrl.
- */
-static void bcm2708_i2c_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);
-
- /* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */
- for (pin = 0; pin <= 3; 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_i2c *bi, unsigned reg)
{
return readl(bi->base + reg);
@@ -259,6 +235,7 @@ static int __devinit bcm2708_i2c_probe(struct platform_device *pdev)
struct resource iomem;
int irq, err = -ENOMEM;
struct clk *clk;
+ struct pinctrl *pctl;
struct bcm2708_i2c *bi;
struct i2c_adapter *adap;
@@ -280,11 +257,16 @@ static int __devinit bcm2708_i2c_probe(struct platform_device *pdev)
return PTR_ERR(clk);
}
- bcm2708_i2c_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;
+ }
bi = kzalloc(sizeof(*bi), GFP_KERNEL);
if (!bi)
- goto out_clk_put;
+ goto out_pinctrl_put;
platform_set_drvdata(pdev, bi);
@@ -314,6 +296,7 @@ static int __devinit bcm2708_i2c_probe(struct platform_device *pdev)
bi->iomem = iomem;
bi->irq = irq;
bi->clk = clk;
+ bi->pctl = pctl;
err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED,
dev_name(&pdev->dev), bi);
@@ -348,6 +331,8 @@ out_release_region:
release_region(iomem.start, resource_size(&iomem));
out_free_bi:
kfree(bi);
+out_pinctrl_put:
+ pinctrl_put(pctl);
out_clk_put:
clk_put(clk);
return err;
@@ -363,6 +348,7 @@ static int __devexit bcm2708_i2c_remove(struct platform_device *pdev)
free_irq(bi->irq, bi);
iounmap(bi->base);
release_region(bi->iomem.start, resource_size(&bi->iomem));
+ pinctrl_put(bi->pctl);
clk_unprepare(bi->clk);
clk_put(bi->clk);
kfree(bi);
--
1.7.10
More information about the linux-rpi-kernel
mailing list