All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -mm 0/5] ASIC3 updates
@ 2008-05-11 17:36 Samuel Ortiz
  2008-05-11 17:36 ` [PATCH -mm 1/5] asic3: gpiolib support Samuel Ortiz
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Samuel Ortiz @ 2008-05-11 17:36 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Kernel ML

Hi Andrew,

This is a 5 ASIC3 patches set for:

- Adding ASIC3 gpiolib support.
- Improving the configuration code.
- Removing the children device registration.
- Improving code style.

Cheers,
Samuel.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH -mm 1/5] asic3: gpiolib support
  2008-05-11 17:36 [PATCH -mm 0/5] ASIC3 updates Samuel Ortiz
@ 2008-05-11 17:36 ` Samuel Ortiz
  2008-05-11 17:36 ` [PATCH -mm 2/5] asic3: Remove children platform data Samuel Ortiz
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Samuel Ortiz @ 2008-05-11 17:36 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Kernel ML, Samuel Ortiz

[-- Attachment #1: asic3-gpiolib.patch --]
[-- Type: text/plain, Size: 10774 bytes --]

ASIC3 is, among other things, a GPIO extender. We should thus have it
supporting the current gpiolib API.

Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
---
 drivers/mfd/asic3.c       |  224 +++++++++++++++++++++++++++++++---------------
 include/linux/mfd/asic3.h |   24 ++--
 2 files changed, 164 insertions(+), 84 deletions(-)

Index: linux-2.6-htc-asic3/drivers/mfd/asic3.c
===================================================================
--- linux-2.6-htc-asic3.orig/drivers/mfd/asic3.c	2008-05-07 16:12:29.000000000 +0200
+++ linux-2.6-htc-asic3/drivers/mfd/asic3.c	2008-05-11 17:30:04.000000000 +0200
@@ -9,7 +9,7 @@
  *
  * Copyright 2001 Compaq Computer Corporation.
  * Copyright 2004-2005 Phil Blundell
- * Copyright 2007 OpenedHand Ltd.
+ * Copyright 2007-2008 OpenedHand Ltd.
  *
  * Authors: Phil Blundell <pb@handhelds.org>,
  *	    Samuel Ortiz <sameo@openedhand.com>
@@ -19,12 +19,26 @@
 #include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/irq.h>
+#include <linux/gpio.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
 
 #include <linux/mfd/asic3.h>
 
+struct asic3 {
+	void __iomem *mapping;
+	unsigned int bus_shift;
+	unsigned int irq_nr;
+	unsigned int irq_base;
+	spinlock_t lock;
+	u16 irq_bothedge[4];
+	struct gpio_chip gpio;
+	struct device *dev;
+};
+
+static int asic3_gpio_get(struct gpio_chip *chip, unsigned offset);
+
 static inline void asic3_write_register(struct asic3 *asic,
 				 unsigned int reg, u32 value)
 {
@@ -251,7 +265,7 @@ static int asic3_gpio_irq_type(unsigned 
 		edge &= ~bit;
 	} else if (type == IRQT_BOTHEDGE) {
 		trigger |= bit;
-		if (asic3_gpio_get_value(asic, irq - asic->irq_base))
+		if (asic3_gpio_get(&asic->gpio, irq - asic->irq_base))
 			edge &= ~bit;
 		else
 			edge |= bit;
@@ -350,6 +364,107 @@ static void asic3_irq_remove(struct plat
 }
 
 /* GPIOs */
+static int asic3_gpio_direction(struct gpio_chip *chip,
+				unsigned offset, int out)
+{
+	u32 mask = ASIC3_GPIO_TO_MASK(offset), out_reg;
+	unsigned int gpio_base;
+	unsigned long flags;
+	struct asic3 *asic;
+
+	asic = container_of(chip, struct asic3, gpio);
+	gpio_base = ASIC3_GPIO_TO_BASE(offset);
+
+	if (gpio_base > ASIC3_GPIO_D_Base) {
+		printk(KERN_ERR "Invalid base (0x%x) for gpio %d\n",
+		       gpio_base, offset);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&asic->lock, flags);
+
+	out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_Direction);
+
+	/* Input is 0, Output is 1 */
+	if (out)
+		out_reg |= mask;
+	else
+		out_reg &= ~mask;
+
+	asic3_write_register(asic, gpio_base + ASIC3_GPIO_Direction, out_reg);
+
+	spin_unlock_irqrestore(&asic->lock, flags);
+
+	return 0;
+
+}
+
+static int asic3_gpio_direction_input(struct gpio_chip *chip,
+				      unsigned offset)
+{
+	return asic3_gpio_direction(chip, offset, 0);
+}
+
+static int asic3_gpio_direction_output(struct gpio_chip *chip,
+				       unsigned offset, int value)
+{
+	return asic3_gpio_direction(chip, offset, 1);
+}
+
+static int asic3_gpio_get(struct gpio_chip *chip,
+			  unsigned offset)
+{
+	unsigned int gpio_base;
+	u32 mask = ASIC3_GPIO_TO_MASK(offset);
+	struct asic3 *asic;
+
+	asic = container_of(chip, struct asic3, gpio);
+	gpio_base = ASIC3_GPIO_TO_BASE(offset);
+
+	if (gpio_base > ASIC3_GPIO_D_Base) {
+		printk(KERN_ERR "Invalid base (0x%x) for gpio %d\n",
+		       gpio_base, offset);
+		return -EINVAL;
+	}
+
+	return asic3_read_register(asic, gpio_base + ASIC3_GPIO_Status) & mask;
+}
+
+static void asic3_gpio_set(struct gpio_chip *chip,
+			   unsigned offset, int value)
+{
+	u32 mask, out_reg;
+	unsigned int gpio_base;
+	unsigned long flags;
+	struct asic3 *asic;
+
+	asic = container_of(chip, struct asic3, gpio);
+	gpio_base = ASIC3_GPIO_TO_BASE(offset);
+
+	if (gpio_base > ASIC3_GPIO_D_Base) {
+		printk(KERN_ERR "Invalid base (0x%x) for gpio %d\n",
+		       gpio_base, offset);
+		return;
+	}
+
+	mask = ASIC3_GPIO_TO_MASK(offset);
+
+	spin_lock_irqsave(&asic->lock, flags);
+
+	out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_Out);
+
+	if (value)
+		out_reg |= mask;
+	else
+		out_reg &= ~mask;
+
+	asic3_write_register(asic, gpio_base + ASIC3_GPIO_Out, out_reg);
+
+	spin_unlock_irqrestore(&asic->lock, flags);
+
+	return;
+}
+
 static inline u32 asic3_get_gpio(struct asic3 *asic, unsigned int base,
 				 unsigned int function)
 {
@@ -368,15 +483,6 @@ static void asic3_set_gpio(struct asic3 
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
-#define asic3_get_gpio_a(asic, fn) \
-	asic3_get_gpio(asic, ASIC3_GPIO_A_Base, ASIC3_GPIO_##fn)
-#define asic3_get_gpio_b(asic, fn) \
-	asic3_get_gpio(asic, ASIC3_GPIO_B_Base, ASIC3_GPIO_##fn)
-#define asic3_get_gpio_c(asic, fn) \
-	asic3_get_gpio(asic, ASIC3_GPIO_C_Base, ASIC3_GPIO_##fn)
-#define asic3_get_gpio_d(asic, fn) \
-	asic3_get_gpio(asic, ASIC3_GPIO_D_Base, ASIC3_GPIO_##fn)
-
 #define asic3_set_gpio_a(asic, fn, bits, val) \
 	asic3_set_gpio(asic, ASIC3_GPIO_A_Base, ASIC3_GPIO_##fn, bits, val)
 #define asic3_set_gpio_b(asic, fn, bits, val) \
@@ -394,54 +500,6 @@ static void asic3_set_gpio(struct asic3 
 	     asic3_set_gpio_d((asic), fn, (bits), (pdata)->gpio_d.field); \
 	} while (0)
 
-int asic3_gpio_get_value(struct asic3 *asic, unsigned gpio)
-{
-	u32 mask = ASIC3_GPIO_bit(gpio);
-
-	switch (gpio >> 4) {
-	case ASIC3_GPIO_BANK_A:
-		return asic3_get_gpio_a(asic, Status) & mask;
-	case ASIC3_GPIO_BANK_B:
-		return asic3_get_gpio_b(asic, Status) & mask;
-	case ASIC3_GPIO_BANK_C:
-		return asic3_get_gpio_c(asic, Status) & mask;
-	case ASIC3_GPIO_BANK_D:
-		return asic3_get_gpio_d(asic, Status) & mask;
-	default:
-		printk(KERN_ERR "%s: invalid GPIO value 0x%x",
-		       __func__, gpio);
-		return -EINVAL;
-	}
-}
-EXPORT_SYMBOL(asic3_gpio_get_value);
-
-void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val)
-{
-	u32 mask = ASIC3_GPIO_bit(gpio);
-	u32 bitval = 0;
-	if (val)
-		bitval = mask;
-
-	switch (gpio >> 4) {
-	case ASIC3_GPIO_BANK_A:
-		asic3_set_gpio_a(asic, Out, mask, bitval);
-		return;
-	case ASIC3_GPIO_BANK_B:
-		asic3_set_gpio_b(asic, Out, mask, bitval);
-		return;
-	case ASIC3_GPIO_BANK_C:
-		asic3_set_gpio_c(asic, Out, mask, bitval);
-		return;
-	case ASIC3_GPIO_BANK_D:
-		asic3_set_gpio_d(asic, Out, mask, bitval);
-		return;
-	default:
-		printk(KERN_ERR "%s: invalid GPIO value 0x%x",
-		       __func__, gpio);
-		return;
-	}
-}
-EXPORT_SYMBOL(asic3_gpio_set_value);
 
 static int asic3_gpio_probe(struct platform_device *pdev)
 {
@@ -472,12 +530,14 @@ static int asic3_gpio_probe(struct platf
 				     alt_function);
 	}
 
-	return 0;
+	return gpiochip_add(&asic->gpio);
 }
 
-static void asic3_gpio_remove(struct platform_device *pdev)
+static int asic3_gpio_remove(struct platform_device *pdev)
 {
-	return;
+	struct asic3 *asic = platform_get_drvdata(pdev);
+
+	return gpiochip_remove(&asic->gpio);
 }
 
 
@@ -488,11 +548,13 @@ static int asic3_probe(struct platform_d
 	struct asic3 *asic;
 	struct resource *mem;
 	unsigned long clksel;
-	int ret;
+	int ret = 0;
 
 	asic = kzalloc(sizeof(struct asic3), GFP_KERNEL);
-	if (!asic)
+	if (asic == NULL) {
+		printk(KERN_ERR "kzalloc failed\n");
 		return -ENOMEM;
+	}
 
 	spin_lock_init(&asic->lock);
 	platform_set_drvdata(pdev, asic);
@@ -502,14 +564,15 @@ static int asic3_probe(struct platform_d
 	if (!mem) {
 		ret = -ENOMEM;
 		printk(KERN_ERR "asic3: no MEM resource\n");
-		goto err_out_1;
+		goto out_free;
 	}
 
+
 	asic->mapping = ioremap(mem->start, PAGE_SIZE);
 	if (!asic->mapping) {
 		ret = -ENOMEM;
 		printk(KERN_ERR "asic3: couldn't ioremap\n");
-		goto err_out_1;
+		goto out_free;
 	}
 
 	asic->irq_base = pdata->irq_base;
@@ -525,9 +588,21 @@ static int asic3_probe(struct platform_d
 	ret = asic3_irq_probe(pdev);
 	if (ret < 0) {
 		printk(KERN_ERR "asic3: couldn't probe IRQs\n");
-		goto err_out_2;
+		goto out_unmap;
+	}
+
+	asic->gpio.base = pdata->gpio_base;
+	asic->gpio.ngpio = ASIC3_NUM_GPIOS;
+	asic->gpio.get = asic3_gpio_get;
+	asic->gpio.set = asic3_gpio_set;
+	asic->gpio.direction_input = asic3_gpio_direction_input;
+	asic->gpio.direction_output = asic3_gpio_direction_output;
+
+	ret = asic3_gpio_probe(pdev);
+	if (ret < 0) {
+		printk(KERN_ERR "GPIO probe failed\n");
+		goto out_irq;
 	}
-	asic3_gpio_probe(pdev);
 
 	if (pdata->children) {
 		int i;
@@ -541,9 +616,13 @@ static int asic3_probe(struct platform_d
 
 	return 0;
 
- err_out_2:
+ out_irq:
+	asic3_irq_remove(pdev);
+
+ out_unmap:
 	iounmap(asic->mapping);
- err_out_1:
+
+ out_free:
 	kfree(asic);
 
 	return ret;
@@ -551,9 +630,12 @@ static int asic3_probe(struct platform_d
 
 static int asic3_remove(struct platform_device *pdev)
 {
+	int ret;
 	struct asic3 *asic = platform_get_drvdata(pdev);
 
-	asic3_gpio_remove(pdev);
+	ret = asic3_gpio_remove(pdev);
+	if (ret < 0)
+		return ret;
 	asic3_irq_remove(pdev);
 
 	asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), 0);
Index: linux-2.6-htc-asic3/include/linux/mfd/asic3.h
===================================================================
--- linux-2.6-htc-asic3.orig/include/linux/mfd/asic3.h	2008-05-07 16:12:40.000000000 +0200
+++ linux-2.6-htc-asic3/include/linux/mfd/asic3.h	2008-05-11 17:34:42.000000000 +0200
@@ -16,16 +16,6 @@
 
 #include <linux/types.h>
 
-struct asic3 {
-	void __iomem *mapping;
-	unsigned int bus_shift;
-	unsigned int irq_nr;
-	unsigned int irq_base;
-	spinlock_t lock;
-	u16 irq_bothedge[4];
-	struct device *dev;
-};
-
 struct asic3_platform_data {
 	struct {
 		u32 dir;
@@ -41,18 +31,19 @@ struct asic3_platform_data {
 
 	unsigned int irq_base;
 
+	unsigned int gpio_base;
+
 	struct platform_device **children;
 	unsigned int n_children;
 };
 
-int asic3_gpio_get_value(struct asic3 *asic, unsigned gpio);
-void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val);
-
 #define ASIC3_NUM_GPIO_BANKS	4
 #define ASIC3_GPIOS_PER_BANK	16
 #define ASIC3_NUM_GPIOS		64
 #define ASIC3_NR_IRQS		ASIC3_NUM_GPIOS + 6
 
+#define ASIC3_TO_GPIO(gpio) (NR_BUILTIN_GPIO + (gpio))
+
 #define ASIC3_GPIO_BANK_A	0
 #define ASIC3_GPIO_BANK_B	1
 #define ASIC3_GPIO_BANK_C	2
@@ -73,6 +64,13 @@ void asic3_gpio_set_value(struct asic3 *
 #define ASIC3_GPIO_C_Base      0x0200
 #define ASIC3_GPIO_D_Base      0x0300
 
+#define ASIC3_GPIO_TO_BANK(gpio) ((gpio) >> 4)
+#define ASIC3_GPIO_TO_BIT(gpio)  ((gpio) - \
+				  (ASIC3_GPIOS_PER_BANK * ((gpio) >> 4)))
+#define ASIC3_GPIO_TO_MASK(gpio) (1 << ASIC3_GPIO_TO_BIT(gpio))
+#define ASIC3_GPIO_TO_BASE(gpio) (ASIC3_GPIO_A_Base + (((gpio) >> 4) * 0x0100))
+#define ASIC3_BANK_TO_BASE(bank) (ASIC3_GPIO_A_Base + ((bank) * 0x100))
+
 #define ASIC3_GPIO_Mask          0x00    /* R/W 0:don't mask */
 #define ASIC3_GPIO_Direction     0x04    /* R/W 0:input */
 #define ASIC3_GPIO_Out           0x08    /* R/W 0:output low */

-- 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH -mm 2/5] asic3: Remove children platform data
  2008-05-11 17:36 [PATCH -mm 0/5] ASIC3 updates Samuel Ortiz
  2008-05-11 17:36 ` [PATCH -mm 1/5] asic3: gpiolib support Samuel Ortiz
@ 2008-05-11 17:36 ` Samuel Ortiz
  2008-05-11 17:36 ` [PATCH -mm 3/5] asic3: New gpio configuration code Samuel Ortiz
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Samuel Ortiz @ 2008-05-11 17:36 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Kernel ML, Samuel Ortiz

[-- Attachment #1: asic3-keys_pdata.patch --]
[-- Type: text/plain, Size: 1442 bytes --]

Platform devices should be dynamically allocated, and each supported
device should have its own platform data.
For now we just remove this buggy code.

Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
---
 drivers/mfd/asic3.c       |    8 --------
 include/linux/mfd/asic3.h |    3 ---
 2 files changed, 11 deletions(-)

Index: linux-2.6-htc-asic3/drivers/mfd/asic3.c
===================================================================
--- linux-2.6-htc-asic3.orig/drivers/mfd/asic3.c	2008-05-11 17:30:04.000000000 +0200
+++ linux-2.6-htc-asic3/drivers/mfd/asic3.c	2008-05-11 17:38:45.000000000 +0200
@@ -604,14 +604,6 @@ static int asic3_probe(struct platform_d
 		goto out_irq;
 	}
 
-	if (pdata->children) {
-		int i;
-		for (i = 0; i < pdata->n_children; i++) {
-			pdata->children[i]->dev.parent = &pdev->dev;
-			platform_device_register(pdata->children[i]);
-		}
-	}
-
 	printk(KERN_INFO "ASIC3 Core driver\n");
 
 	return 0;
Index: linux-2.6-htc-asic3/include/linux/mfd/asic3.h
===================================================================
--- linux-2.6-htc-asic3.orig/include/linux/mfd/asic3.h	2008-05-11 17:34:42.000000000 +0200
+++ linux-2.6-htc-asic3/include/linux/mfd/asic3.h	2008-05-11 17:37:17.000000000 +0200
@@ -32,9 +32,6 @@ struct asic3_platform_data {
 	unsigned int irq_base;
 
 	unsigned int gpio_base;
-
-	struct platform_device **children;
-	unsigned int n_children;
 };
 
 #define ASIC3_NUM_GPIO_BANKS	4

-- 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH -mm 3/5] asic3: New gpio configuration code
  2008-05-11 17:36 [PATCH -mm 0/5] ASIC3 updates Samuel Ortiz
  2008-05-11 17:36 ` [PATCH -mm 1/5] asic3: gpiolib support Samuel Ortiz
  2008-05-11 17:36 ` [PATCH -mm 2/5] asic3: Remove children platform data Samuel Ortiz
@ 2008-05-11 17:36 ` Samuel Ortiz
  2008-06-21 14:43   ` pHilipp Zabel
  2008-05-11 17:36 ` [PATCH -mm 4/5] asic3: use dev_* macros Samuel Ortiz
  2008-05-11 17:36 ` [PATCH -mm 5/5] asic3: Use uppercase only for macros and defines Samuel Ortiz
  4 siblings, 1 reply; 8+ messages in thread
From: Samuel Ortiz @ 2008-05-11 17:36 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Kernel ML, Samuel Ortiz

[-- Attachment #1: asic3-gpio_config.patch --]
[-- Type: text/plain, Size: 6885 bytes --]

The ASIC3 GPIO configuration code is a bit obscure and hardly readable.
This patch changes it so that it is now more readable and understandable,
by being more explicit.

Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
---
 drivers/mfd/asic3.c       |   99 +++++++++++++++++++---------------------------
 include/linux/mfd/asic3.h |   34 +++++++++++----
 2 files changed, 67 insertions(+), 66 deletions(-)

Index: linux-2.6-htc-asic3/drivers/mfd/asic3.c
===================================================================
--- linux-2.6-htc-asic3.orig/drivers/mfd/asic3.c	2008-05-11 17:47:15.000000000 +0200
+++ linux-2.6-htc-asic3/drivers/mfd/asic3.c	2008-05-11 18:20:35.000000000 +0200
@@ -465,69 +465,54 @@ static void asic3_gpio_set(struct gpio_c
 	return;
 }
 
-static inline u32 asic3_get_gpio(struct asic3 *asic, unsigned int base,
-				 unsigned int function)
+static int asic3_gpio_probe(struct platform_device *pdev,
+			    u16 *gpio_config, int num)
 {
-	return asic3_read_register(asic, base + function);
-}
-
-static void asic3_set_gpio(struct asic3 *asic, unsigned int base,
-			   unsigned int function, u32 bits, u32 val)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&asic->lock, flags);
-	val |= (asic3_read_register(asic, base + function) & ~bits);
-
-	asic3_write_register(asic, base + function, val);
-	spin_unlock_irqrestore(&asic->lock, flags);
-}
-
-#define asic3_set_gpio_a(asic, fn, bits, val) \
-	asic3_set_gpio(asic, ASIC3_GPIO_A_Base, ASIC3_GPIO_##fn, bits, val)
-#define asic3_set_gpio_b(asic, fn, bits, val) \
-	asic3_set_gpio(asic, ASIC3_GPIO_B_Base, ASIC3_GPIO_##fn, bits, val)
-#define asic3_set_gpio_c(asic, fn, bits, val) \
-	asic3_set_gpio(asic, ASIC3_GPIO_C_Base, ASIC3_GPIO_##fn, bits, val)
-#define asic3_set_gpio_d(asic, fn, bits, val) \
-	asic3_set_gpio(asic, ASIC3_GPIO_D_Base, ASIC3_GPIO_##fn, bits, val)
-
-#define asic3_set_gpio_banks(asic, fn, bits, pdata, field) 		  \
-	do {								  \
-	     asic3_set_gpio_a((asic), fn, (bits), (pdata)->gpio_a.field); \
-	     asic3_set_gpio_b((asic), fn, (bits), (pdata)->gpio_b.field); \
-	     asic3_set_gpio_c((asic), fn, (bits), (pdata)->gpio_c.field); \
-	     asic3_set_gpio_d((asic), fn, (bits), (pdata)->gpio_d.field); \
-	} while (0)
-
-
-static int asic3_gpio_probe(struct platform_device *pdev)
-{
-	struct asic3_platform_data *pdata = pdev->dev.platform_data;
 	struct asic3 *asic = platform_get_drvdata(pdev);
+	u16 alt_reg[ASIC3_NUM_GPIO_BANKS];
+	u16 out_reg[ASIC3_NUM_GPIO_BANKS];
+	u16 dir_reg[ASIC3_NUM_GPIO_BANKS];
+	int i;
+
+	memset(alt_reg, 0, ASIC3_NUM_GPIO_BANKS);
+	memset(out_reg, 0, ASIC3_NUM_GPIO_BANKS);
+	memset(dir_reg, 0, ASIC3_NUM_GPIO_BANKS);
 
+	/* Enable all GPIOs */
 	asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, Mask), 0xffff);
 	asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, Mask), 0xffff);
 	asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, Mask), 0xffff);
 	asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, Mask), 0xffff);
 
-	asic3_set_gpio_a(asic, SleepMask, 0xffff, 0xffff);
-	asic3_set_gpio_b(asic, SleepMask, 0xffff, 0xffff);
-	asic3_set_gpio_c(asic, SleepMask, 0xffff, 0xffff);
-	asic3_set_gpio_d(asic, SleepMask, 0xffff, 0xffff);
-
-	if (pdata) {
-		asic3_set_gpio_banks(asic, Out, 0xffff, pdata, init);
-		asic3_set_gpio_banks(asic, Direction, 0xffff, pdata, dir);
-		asic3_set_gpio_banks(asic, SleepMask, 0xffff, pdata,
-				     sleep_mask);
-		asic3_set_gpio_banks(asic, SleepOut, 0xffff, pdata, sleep_out);
-		asic3_set_gpio_banks(asic, BattFaultOut, 0xffff, pdata,
-				     batt_fault_out);
-		asic3_set_gpio_banks(asic, SleepConf, 0xffff, pdata,
-				     sleep_conf);
-		asic3_set_gpio_banks(asic, AltFunction, 0xffff, pdata,
-				     alt_function);
+	for (i = 0; i < num; i++) {
+		u8 alt, pin, dir, init, bank_num, bit_num;
+		u16 config = gpio_config[i];
+
+		pin = ASIC3_CONFIG_GPIO_PIN(config);
+		alt = ASIC3_CONFIG_GPIO_ALT(config);
+		dir = ASIC3_CONFIG_GPIO_DIR(config);
+		init = ASIC3_CONFIG_GPIO_INIT(config);
+
+		bank_num = ASIC3_GPIO_TO_BANK(pin);
+		bit_num = ASIC3_GPIO_TO_BIT(pin);
+
+		alt_reg[bank_num] |= (alt << bit_num);
+		out_reg[bank_num] |= (init << bit_num);
+		dir_reg[bank_num] |= (dir << bit_num);
+	}
+
+	for (i = 0; i < ASIC3_NUM_GPIO_BANKS; i++) {
+		asic3_write_register(asic,
+				     ASIC3_BANK_TO_BASE(i) +
+				     ASIC3_GPIO_Direction,
+				     dir_reg[i]);
+		asic3_write_register(asic,
+				     ASIC3_BANK_TO_BASE(i) + ASIC3_GPIO_Out,
+				     out_reg[i]);
+		asic3_write_register(asic,
+				     ASIC3_BANK_TO_BASE(i) +
+				     ASIC3_GPIO_AltFunction,
+				     alt_reg[i]);
 	}
 
 	return gpiochip_add(&asic->gpio);
@@ -598,7 +583,9 @@ static int asic3_probe(struct platform_d
 	asic->gpio.direction_input = asic3_gpio_direction_input;
 	asic->gpio.direction_output = asic3_gpio_direction_output;
 
-	ret = asic3_gpio_probe(pdev);
+	ret = asic3_gpio_probe(pdev,
+			       pdata->gpio_config,
+			       pdata->gpio_config_num);
 	if (ret < 0) {
 		printk(KERN_ERR "GPIO probe failed\n");
 		goto out_irq;
Index: linux-2.6-htc-asic3/include/linux/mfd/asic3.h
===================================================================
--- linux-2.6-htc-asic3.orig/include/linux/mfd/asic3.h	2008-05-11 17:47:15.000000000 +0200
+++ linux-2.6-htc-asic3/include/linux/mfd/asic3.h	2008-05-11 18:12:07.000000000 +0200
@@ -8,7 +8,7 @@
  * published by the Free Software Foundation.
  *
  * Copyright 2001 Compaq Computer Corporation.
- * Copyright 2007 OpendHand.
+ * Copyright 2007-2008 OpenedHand Ltd.
  */
 
 #ifndef __ASIC3_H__
@@ -17,15 +17,8 @@
 #include <linux/types.h>
 
 struct asic3_platform_data {
-	struct {
-		u32 dir;
-		u32 init;
-		u32 sleep_mask;
-		u32 sleep_out;
-		u32 batt_fault_out;
-		u32 sleep_conf;
-		u32 alt_function;
-	} gpio_a, gpio_b, gpio_c, gpio_d;
+	u16 *gpio_config;
+	unsigned int gpio_config_num;
 
 	unsigned int bus_shift;
 
@@ -86,6 +79,27 @@ struct asic3_platform_data {
 					  */
 #define ASIC3_GPIO_Status        0x30    /* R   Pin status */
 
+/*
+ * ASIC3 GPIO config
+ *
+ * Bits 0..6   gpio number
+ * Bits 7..13  Alternate function
+ * Bit  14     Direction
+ * Bit  15     Initial value
+ *
+ */
+#define ASIC3_CONFIG_GPIO_PIN(config) ((config) & 0x7f)
+#define ASIC3_CONFIG_GPIO_ALT(config)  (((config) & (0x7f << 7)) >> 7)
+#define ASIC3_CONFIG_GPIO_DIR(config)  ((config & (1 << 14)) >> 14)
+#define ASIC3_CONFIG_GPIO_INIT(config) ((config & (1 << 15)) >> 15)
+#define ASIC3_CONFIG_GPIO(gpio, alt, dir, init) (((gpio) & 0x7f) \
+	| (((alt) & 0x7f) << 7) | (((dir) & 0x1) << 14) \
+	| (((init) & 0x1) << 15))
+#define ASIC3_CONFIG_GPIO_DEFAULT(gpio, dir, init) \
+	ASIC3_CONFIG_GPIO((gpio), 0, (dir), (init))
+#define ASIC3_CONFIG_GPIO_DEFAULT_OUT(gpio, init) \
+	ASIC3_CONFIG_GPIO((gpio), 0, 1, (init))
+
 #define ASIC3_SPI_Base		      0x0400
 #define ASIC3_SPI_Control               0x0000
 #define ASIC3_SPI_TxData                0x0004

-- 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH -mm 4/5] asic3: use dev_* macros
  2008-05-11 17:36 [PATCH -mm 0/5] ASIC3 updates Samuel Ortiz
                   ` (2 preceding siblings ...)
  2008-05-11 17:36 ` [PATCH -mm 3/5] asic3: New gpio configuration code Samuel Ortiz
@ 2008-05-11 17:36 ` Samuel Ortiz
  2008-05-11 17:36 ` [PATCH -mm 5/5] asic3: Use uppercase only for macros and defines Samuel Ortiz
  4 siblings, 0 replies; 8+ messages in thread
From: Samuel Ortiz @ 2008-05-11 17:36 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Kernel ML, Samuel Ortiz

[-- Attachment #1: asic3-dbg.patch --]
[-- Type: text/plain, Size: 3329 bytes --]

We replace the various printks, and use the dev_* macros instead.

Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
---
 drivers/mfd/asic3.c |   27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

Index: linux-2.6-htc-asic3/drivers/mfd/asic3.c
===================================================================
--- linux-2.6-htc-asic3.orig/drivers/mfd/asic3.c	2008-05-11 17:57:40.000000000 +0200
+++ linux-2.6-htc-asic3/drivers/mfd/asic3.c	2008-05-11 18:03:52.000000000 +0200
@@ -145,8 +145,7 @@ static void asic3_irq_demux(unsigned int
 	}
 
 	if (iter >= MAX_ASIC_ISR_LOOPS)
-		printk(KERN_ERR "%s: interrupt processing overrun\n",
-		       __func__);
+		dev_err(asic->dev, "interrupt processing overrun\n");
 }
 
 static inline int asic3_irq_to_bank(struct asic3 *asic, int irq)
@@ -282,7 +281,7 @@ static int asic3_gpio_irq_type(unsigned 
 		 * be careful to not unmask them if mask was also called.
 		 * Probably need internal state for mask.
 		 */
-		printk(KERN_NOTICE "asic3: irq type not changed.\n");
+		dev_notice(asic->dev, "irq type not changed\n");
 	}
 	asic3_write_register(asic, bank + ASIC3_GPIO_LevelTrigger,
 			     level);
@@ -376,8 +375,8 @@ static int asic3_gpio_direction(struct g
 	gpio_base = ASIC3_GPIO_TO_BASE(offset);
 
 	if (gpio_base > ASIC3_GPIO_D_Base) {
-		printk(KERN_ERR "Invalid base (0x%x) for gpio %d\n",
-		       gpio_base, offset);
+		dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n",
+			gpio_base, offset);
 		return -EINVAL;
 	}
 
@@ -422,8 +421,8 @@ static int asic3_gpio_get(struct gpio_ch
 	gpio_base = ASIC3_GPIO_TO_BASE(offset);
 
 	if (gpio_base > ASIC3_GPIO_D_Base) {
-		printk(KERN_ERR "Invalid base (0x%x) for gpio %d\n",
-		       gpio_base, offset);
+		dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n",
+			gpio_base, offset);
 		return -EINVAL;
 	}
 
@@ -442,8 +441,8 @@ static void asic3_gpio_set(struct gpio_c
 	gpio_base = ASIC3_GPIO_TO_BASE(offset);
 
 	if (gpio_base > ASIC3_GPIO_D_Base) {
-		printk(KERN_ERR "Invalid base (0x%x) for gpio %d\n",
-		       gpio_base, offset);
+		dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n",
+			gpio_base, offset);
 		return;
 	}
 
@@ -548,7 +547,7 @@ static int asic3_probe(struct platform_d
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mem) {
 		ret = -ENOMEM;
-		printk(KERN_ERR "asic3: no MEM resource\n");
+		dev_err(asic->dev, "no MEM resource\n");
 		goto out_free;
 	}
 
@@ -556,7 +555,7 @@ static int asic3_probe(struct platform_d
 	asic->mapping = ioremap(mem->start, PAGE_SIZE);
 	if (!asic->mapping) {
 		ret = -ENOMEM;
-		printk(KERN_ERR "asic3: couldn't ioremap\n");
+		dev_err(asic->dev, "Couldn't ioremap\n");
 		goto out_free;
 	}
 
@@ -572,7 +571,7 @@ static int asic3_probe(struct platform_d
 
 	ret = asic3_irq_probe(pdev);
 	if (ret < 0) {
-		printk(KERN_ERR "asic3: couldn't probe IRQs\n");
+		dev_err(asic->dev, "Couldn't probe IRQs\n");
 		goto out_unmap;
 	}
 
@@ -587,11 +586,11 @@ static int asic3_probe(struct platform_d
 			       pdata->gpio_config,
 			       pdata->gpio_config_num);
 	if (ret < 0) {
-		printk(KERN_ERR "GPIO probe failed\n");
+		dev_err(asic->dev, "GPIO probe failed\n");
 		goto out_irq;
 	}
 
-	printk(KERN_INFO "ASIC3 Core driver\n");
+	dev_info(asic->dev, "ASIC3 Core driver\n");
 
 	return 0;
 

-- 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH -mm 5/5] asic3: Use uppercase only for macros and defines.
  2008-05-11 17:36 [PATCH -mm 0/5] ASIC3 updates Samuel Ortiz
                   ` (3 preceding siblings ...)
  2008-05-11 17:36 ` [PATCH -mm 4/5] asic3: use dev_* macros Samuel Ortiz
@ 2008-05-11 17:36 ` Samuel Ortiz
  4 siblings, 0 replies; 8+ messages in thread
From: Samuel Ortiz @ 2008-05-11 17:36 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Kernel ML, Samuel Ortiz

[-- Attachment #1: asic3-macro_uppercase.patch --]
[-- Type: text/plain, Size: 14505 bytes --]

Let's be consistent and use uppercase only, for both macro and defines.

Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
---
 drivers/mfd/asic3.c       |   88 +++++++++++++++++++++++-----------------------
 include/linux/mfd/asic3.h |   54 ++++++++++++++--------------
 2 files changed, 71 insertions(+), 71 deletions(-)

Index: linux-2.6-htc-asic3/include/linux/mfd/asic3.h
===================================================================
--- linux-2.6-htc-asic3.orig/include/linux/mfd/asic3.h	2008-05-11 18:21:11.000000000 +0200
+++ linux-2.6-htc-asic3/include/linux/mfd/asic3.h	2008-05-11 18:21:28.000000000 +0200
@@ -45,39 +45,39 @@ struct asic3_platform_data {
 /* All offsets below are specified with this address bus shift */
 #define ASIC3_DEFAULT_ADDR_SHIFT 2
 
-#define ASIC3_OFFSET(base, reg) (ASIC3_##base##_Base + ASIC3_##base##_##reg)
+#define ASIC3_OFFSET(base, reg) (ASIC3_##base##_BASE + ASIC3_##base##_##reg)
 #define ASIC3_GPIO_OFFSET(base, reg) \
-	(ASIC3_GPIO_##base##_Base + ASIC3_GPIO_##reg)
+	(ASIC3_GPIO_##base##_BASE + ASIC3_GPIO_##reg)
 
-#define ASIC3_GPIO_A_Base      0x0000
-#define ASIC3_GPIO_B_Base      0x0100
-#define ASIC3_GPIO_C_Base      0x0200
-#define ASIC3_GPIO_D_Base      0x0300
+#define ASIC3_GPIO_A_BASE      0x0000
+#define ASIC3_GPIO_B_BASE      0x0100
+#define ASIC3_GPIO_C_BASE      0x0200
+#define ASIC3_GPIO_D_BASE      0x0300
 
 #define ASIC3_GPIO_TO_BANK(gpio) ((gpio) >> 4)
 #define ASIC3_GPIO_TO_BIT(gpio)  ((gpio) - \
 				  (ASIC3_GPIOS_PER_BANK * ((gpio) >> 4)))
 #define ASIC3_GPIO_TO_MASK(gpio) (1 << ASIC3_GPIO_TO_BIT(gpio))
-#define ASIC3_GPIO_TO_BASE(gpio) (ASIC3_GPIO_A_Base + (((gpio) >> 4) * 0x0100))
-#define ASIC3_BANK_TO_BASE(bank) (ASIC3_GPIO_A_Base + ((bank) * 0x100))
+#define ASIC3_GPIO_TO_BASE(gpio) (ASIC3_GPIO_A_BASE + (((gpio) >> 4) * 0x0100))
+#define ASIC3_BANK_TO_BASE(bank) (ASIC3_GPIO_A_BASE + ((bank) * 0x100))
 
-#define ASIC3_GPIO_Mask          0x00    /* R/W 0:don't mask */
-#define ASIC3_GPIO_Direction     0x04    /* R/W 0:input */
-#define ASIC3_GPIO_Out           0x08    /* R/W 0:output low */
-#define ASIC3_GPIO_TriggerType   0x0c    /* R/W 0:level */
-#define ASIC3_GPIO_EdgeTrigger   0x10    /* R/W 0:falling */
-#define ASIC3_GPIO_LevelTrigger  0x14    /* R/W 0:low level detect */
-#define ASIC3_GPIO_SleepMask     0x18    /* R/W 0:don't mask in sleep mode */
-#define ASIC3_GPIO_SleepOut      0x1c    /* R/W level 0:low in sleep mode */
-#define ASIC3_GPIO_BattFaultOut  0x20    /* R/W level 0:low in batt_fault */
-#define ASIC3_GPIO_IntStatus     0x24    /* R/W 0:none, 1:detect */
-#define ASIC3_GPIO_AltFunction   0x28	 /* R/W 1:LED register control */
-#define ASIC3_GPIO_SleepConf     0x2c    /*
+#define ASIC3_GPIO_MASK          0x00    /* R/W 0:don't mask */
+#define ASIC3_GPIO_DIRECTION     0x04    /* R/W 0:input */
+#define ASIC3_GPIO_OUT           0x08    /* R/W 0:output low */
+#define ASIC3_GPIO_TRIGGER_TYPE  0x0c    /* R/W 0:level */
+#define ASIC3_GPIO_EDGE_TRIGGER  0x10    /* R/W 0:falling */
+#define ASIC3_GPIO_LEVEL_TRIGGER 0x14    /* R/W 0:low level detect */
+#define ASIC3_GPIO_SLEEP_MASK    0x18    /* R/W 0:don't mask in sleep mode */
+#define ASIC3_GPIO_SLEEP_OUT     0x1c    /* R/W level 0:low in sleep mode */
+#define ASIC3_GPIO_BAT_FAULT_OUT 0x20    /* R/W level 0:low in batt_fault */
+#define ASIC3_GPIO_INT_STATUS    0x24    /* R/W 0:none, 1:detect */
+#define ASIC3_GPIO_ALT_FUNCTION  0x28	 /* R/W 1:LED register control */
+#define ASIC3_GPIO_SLEEP_CONF    0x2c    /*
 					  * R/W bit 1: autosleep
 					  * 0: disable gposlpout in normal mode,
 					  * enable gposlpout in sleep mode.
 					  */
-#define ASIC3_GPIO_Status        0x30    /* R   Pin status */
+#define ASIC3_GPIO_STATUS        0x30    /* R   Pin status */
 
 /*
  * ASIC3 GPIO config
@@ -137,7 +137,7 @@ struct asic3_platform_data {
 #define LED_AUTOSTOP	(1 << 5) /* LED ON/OFF auto stop 0:disable, 1:enable */
 #define LED_ALWAYS	(1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */
 
-#define ASIC3_CLOCK_Base		0x0A00
+#define ASIC3_CLOCK_BASE	   0x0A00
 #define ASIC3_CLOCK_CDEX           0x00
 #define ASIC3_CLOCK_SEL            0x04
 
@@ -168,12 +168,12 @@ struct asic3_platform_data {
 #define CLOCK_SEL_CX            (1 << 2)
 
 
-#define ASIC3_INTR_Base		0x0B00
+#define ASIC3_INTR_BASE		0x0B00
 
-#define ASIC3_INTR_IntMask       0x00  /* Interrupt mask control */
-#define ASIC3_INTR_PIntStat      0x04  /* Peripheral interrupt status */
-#define ASIC3_INTR_IntCPS        0x08  /* Interrupt timer clock pre-scale */
-#define ASIC3_INTR_IntTBS        0x0c  /* Interrupt timer set */
+#define ASIC3_INTR_INT_MASK       0x00  /* Interrupt mask control */
+#define ASIC3_INTR_P_INT_STAT     0x04  /* Peripheral interrupt status */
+#define ASIC3_INTR_INT_CPS        0x08  /* Interrupt timer clock pre-scale */
+#define ASIC3_INTR_INT_TBS        0x0c  /* Interrupt timer set */
 
 #define ASIC3_INTMASK_GINTMASK    (1 << 0)  /* Global INTs mask 1:enable */
 #define ASIC3_INTMASK_GINTEL      (1 << 1)  /* 1: rising edge, 0: hi level */
Index: linux-2.6-htc-asic3/drivers/mfd/asic3.c
===================================================================
--- linux-2.6-htc-asic3.orig/drivers/mfd/asic3.c	2008-05-11 18:21:12.000000000 +0200
+++ linux-2.6-htc-asic3/drivers/mfd/asic3.c	2008-05-11 18:22:48.000000000 +0200
@@ -55,8 +55,8 @@ static inline u32 asic3_read_register(st
 
 /* IRQs */
 #define MAX_ASIC_ISR_LOOPS    20
-#define ASIC3_GPIO_Base_INCR \
-	(ASIC3_GPIO_B_Base - ASIC3_GPIO_A_Base)
+#define ASIC3_GPIO_BASE_INCR \
+	(ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE)
 
 static void asic3_irq_flip_edge(struct asic3 *asic,
 				u32 base, int bit)
@@ -66,10 +66,10 @@ static void asic3_irq_flip_edge(struct a
 
 	spin_lock_irqsave(&asic->lock, flags);
 	edge = asic3_read_register(asic,
-				   base + ASIC3_GPIO_EdgeTrigger);
+				   base + ASIC3_GPIO_EDGE_TRIGGER);
 	edge ^= bit;
 	asic3_write_register(asic,
-			     base + ASIC3_GPIO_EdgeTrigger, edge);
+			     base + ASIC3_GPIO_EDGE_TRIGGER, edge);
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
@@ -89,7 +89,7 @@ static void asic3_irq_demux(unsigned int
 
 		spin_lock_irqsave(&asic->lock, flags);
 		status = asic3_read_register(asic,
-					     ASIC3_OFFSET(INTR, PIntStat));
+					     ASIC3_OFFSET(INTR, P_INT_STAT));
 		spin_unlock_irqrestore(&asic->lock, flags);
 
 		/* Check all ten register bits */
@@ -101,17 +101,17 @@ static void asic3_irq_demux(unsigned int
 			if (status & (1 << bank)) {
 				unsigned long base, istat;
 
-				base = ASIC3_GPIO_A_Base
-				       + bank * ASIC3_GPIO_Base_INCR;
+				base = ASIC3_GPIO_A_BASE
+				       + bank * ASIC3_GPIO_BASE_INCR;
 
 				spin_lock_irqsave(&asic->lock, flags);
 				istat = asic3_read_register(asic,
 							    base +
-							    ASIC3_GPIO_IntStatus);
+							    ASIC3_GPIO_INT_STATUS);
 				/* Clearing IntStatus */
 				asic3_write_register(asic,
 						     base +
-						     ASIC3_GPIO_IntStatus, 0);
+						     ASIC3_GPIO_INT_STATUS, 0);
 				spin_unlock_irqrestore(&asic->lock, flags);
 
 				for (i = 0; i < ASIC3_GPIOS_PER_BANK; i++) {
@@ -154,7 +154,7 @@ static inline int asic3_irq_to_bank(stru
 
 	n = (irq - asic->irq_base) >> 4;
 
-	return (n * (ASIC3_GPIO_B_Base - ASIC3_GPIO_A_Base));
+	return (n * (ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE));
 }
 
 static inline int asic3_irq_to_index(struct asic3 *asic, int irq)
@@ -172,9 +172,9 @@ static void asic3_mask_gpio_irq(unsigned
 	index = asic3_irq_to_index(asic, irq);
 
 	spin_lock_irqsave(&asic->lock, flags);
-	val = asic3_read_register(asic, bank + ASIC3_GPIO_Mask);
+	val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK);
 	val |= 1 << index;
-	asic3_write_register(asic, bank + ASIC3_GPIO_Mask, val);
+	asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val);
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
@@ -186,15 +186,15 @@ static void asic3_mask_irq(unsigned int 
 
 	spin_lock_irqsave(&asic->lock, flags);
 	regval = asic3_read_register(asic,
-				     ASIC3_INTR_Base +
-				     ASIC3_INTR_IntMask);
+				     ASIC3_INTR_BASE +
+				     ASIC3_INTR_INT_MASK);
 
 	regval &= ~(ASIC3_INTMASK_MASK0 <<
 		    (irq - (asic->irq_base + ASIC3_NUM_GPIOS)));
 
 	asic3_write_register(asic,
-			     ASIC3_INTR_Base +
-			     ASIC3_INTR_IntMask,
+			     ASIC3_INTR_BASE +
+			     ASIC3_INTR_INT_MASK,
 			     regval);
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
@@ -209,9 +209,9 @@ static void asic3_unmask_gpio_irq(unsign
 	index = asic3_irq_to_index(asic, irq);
 
 	spin_lock_irqsave(&asic->lock, flags);
-	val = asic3_read_register(asic, bank + ASIC3_GPIO_Mask);
+	val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK);
 	val &= ~(1 << index);
-	asic3_write_register(asic, bank + ASIC3_GPIO_Mask, val);
+	asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val);
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
 
@@ -223,15 +223,15 @@ static void asic3_unmask_irq(unsigned in
 
 	spin_lock_irqsave(&asic->lock, flags);
 	regval = asic3_read_register(asic,
-				     ASIC3_INTR_Base +
-				     ASIC3_INTR_IntMask);
+				     ASIC3_INTR_BASE +
+				     ASIC3_INTR_INT_MASK);
 
 	regval |= (ASIC3_INTMASK_MASK0 <<
 		   (irq - (asic->irq_base + ASIC3_NUM_GPIOS)));
 
 	asic3_write_register(asic,
-			     ASIC3_INTR_Base +
-			     ASIC3_INTR_IntMask,
+			     ASIC3_INTR_BASE +
+			     ASIC3_INTR_INT_MASK,
 			     regval);
 	spin_unlock_irqrestore(&asic->lock, flags);
 }
@@ -249,11 +249,11 @@ static int asic3_gpio_irq_type(unsigned 
 
 	spin_lock_irqsave(&asic->lock, flags);
 	level = asic3_read_register(asic,
-				    bank + ASIC3_GPIO_LevelTrigger);
+				    bank + ASIC3_GPIO_LEVEL_TRIGGER);
 	edge = asic3_read_register(asic,
-				   bank + ASIC3_GPIO_EdgeTrigger);
+				   bank + ASIC3_GPIO_EDGE_TRIGGER);
 	trigger = asic3_read_register(asic,
-				      bank + ASIC3_GPIO_TriggerType);
+				      bank + ASIC3_GPIO_TRIGGER_TYPE);
 	asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit;
 
 	if (type == IRQT_RISING) {
@@ -283,11 +283,11 @@ static int asic3_gpio_irq_type(unsigned 
 		 */
 		dev_notice(asic->dev, "irq type not changed\n");
 	}
-	asic3_write_register(asic, bank + ASIC3_GPIO_LevelTrigger,
+	asic3_write_register(asic, bank + ASIC3_GPIO_LEVEL_TRIGGER,
 			     level);
-	asic3_write_register(asic, bank + ASIC3_GPIO_EdgeTrigger,
+	asic3_write_register(asic, bank + ASIC3_GPIO_EDGE_TRIGGER,
 			     edge);
-	asic3_write_register(asic, bank + ASIC3_GPIO_TriggerType,
+	asic3_write_register(asic, bank + ASIC3_GPIO_TRIGGER_TYPE,
 			     trigger);
 	spin_unlock_irqrestore(&asic->lock, flags);
 	return 0;
@@ -336,7 +336,7 @@ static int asic3_irq_probe(struct platfo
 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 	}
 
-	asic3_write_register(asic, ASIC3_OFFSET(INTR, IntMask),
+	asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK),
 			     ASIC3_INTMASK_GINTMASK);
 
 	set_irq_chained_handler(asic->irq_nr, asic3_irq_demux);
@@ -374,7 +374,7 @@ static int asic3_gpio_direction(struct g
 	asic = container_of(chip, struct asic3, gpio);
 	gpio_base = ASIC3_GPIO_TO_BASE(offset);
 
-	if (gpio_base > ASIC3_GPIO_D_Base) {
+	if (gpio_base > ASIC3_GPIO_D_BASE) {
 		dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n",
 			gpio_base, offset);
 		return -EINVAL;
@@ -382,7 +382,7 @@ static int asic3_gpio_direction(struct g
 
 	spin_lock_irqsave(&asic->lock, flags);
 
-	out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_Direction);
+	out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_DIRECTION);
 
 	/* Input is 0, Output is 1 */
 	if (out)
@@ -390,7 +390,7 @@ static int asic3_gpio_direction(struct g
 	else
 		out_reg &= ~mask;
 
-	asic3_write_register(asic, gpio_base + ASIC3_GPIO_Direction, out_reg);
+	asic3_write_register(asic, gpio_base + ASIC3_GPIO_DIRECTION, out_reg);
 
 	spin_unlock_irqrestore(&asic->lock, flags);
 
@@ -420,13 +420,13 @@ static int asic3_gpio_get(struct gpio_ch
 	asic = container_of(chip, struct asic3, gpio);
 	gpio_base = ASIC3_GPIO_TO_BASE(offset);
 
-	if (gpio_base > ASIC3_GPIO_D_Base) {
+	if (gpio_base > ASIC3_GPIO_D_BASE) {
 		dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n",
 			gpio_base, offset);
 		return -EINVAL;
 	}
 
-	return asic3_read_register(asic, gpio_base + ASIC3_GPIO_Status) & mask;
+	return asic3_read_register(asic, gpio_base + ASIC3_GPIO_STATUS) & mask;
 }
 
 static void asic3_gpio_set(struct gpio_chip *chip,
@@ -440,7 +440,7 @@ static void asic3_gpio_set(struct gpio_c
 	asic = container_of(chip, struct asic3, gpio);
 	gpio_base = ASIC3_GPIO_TO_BASE(offset);
 
-	if (gpio_base > ASIC3_GPIO_D_Base) {
+	if (gpio_base > ASIC3_GPIO_D_BASE) {
 		dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n",
 			gpio_base, offset);
 		return;
@@ -450,14 +450,14 @@ static void asic3_gpio_set(struct gpio_c
 
 	spin_lock_irqsave(&asic->lock, flags);
 
-	out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_Out);
+	out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_OUT);
 
 	if (value)
 		out_reg |= mask;
 	else
 		out_reg &= ~mask;
 
-	asic3_write_register(asic, gpio_base + ASIC3_GPIO_Out, out_reg);
+	asic3_write_register(asic, gpio_base + ASIC3_GPIO_OUT, out_reg);
 
 	spin_unlock_irqrestore(&asic->lock, flags);
 
@@ -478,10 +478,10 @@ static int asic3_gpio_probe(struct platf
 	memset(dir_reg, 0, ASIC3_NUM_GPIO_BANKS);
 
 	/* Enable all GPIOs */
-	asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, Mask), 0xffff);
-	asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, Mask), 0xffff);
-	asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, Mask), 0xffff);
-	asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, Mask), 0xffff);
+	asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, MASK), 0xffff);
+	asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, MASK), 0xffff);
+	asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, MASK), 0xffff);
+	asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, MASK), 0xffff);
 
 	for (i = 0; i < num; i++) {
 		u8 alt, pin, dir, init, bank_num, bit_num;
@@ -503,14 +503,14 @@ static int asic3_gpio_probe(struct platf
 	for (i = 0; i < ASIC3_NUM_GPIO_BANKS; i++) {
 		asic3_write_register(asic,
 				     ASIC3_BANK_TO_BASE(i) +
-				     ASIC3_GPIO_Direction,
+				     ASIC3_GPIO_DIRECTION,
 				     dir_reg[i]);
 		asic3_write_register(asic,
-				     ASIC3_BANK_TO_BASE(i) + ASIC3_GPIO_Out,
+				     ASIC3_BANK_TO_BASE(i) + ASIC3_GPIO_OUT,
 				     out_reg[i]);
 		asic3_write_register(asic,
 				     ASIC3_BANK_TO_BASE(i) +
-				     ASIC3_GPIO_AltFunction,
+				     ASIC3_GPIO_ALT_FUNCTION,
 				     alt_reg[i]);
 	}
 

-- 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH -mm 3/5] asic3: New gpio configuration code
  2008-05-11 17:36 ` [PATCH -mm 3/5] asic3: New gpio configuration code Samuel Ortiz
@ 2008-06-21 14:43   ` pHilipp Zabel
  2008-06-23 10:13     ` Samuel Ortiz
  0 siblings, 1 reply; 8+ messages in thread
From: pHilipp Zabel @ 2008-06-21 14:43 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: Andrew Morton, Linux Kernel ML

On Sun, May 11, 2008 at 7:36 PM, Samuel Ortiz <sameo@openedhand.com> wrote:
> The ASIC3 GPIO configuration code is a bit obscure and hardly readable.
> This patch changes it so that it is now more readable and understandable,
> by being more explicit.
>
> Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
> ---
>  drivers/mfd/asic3.c       |   99 +++++++++++++++++++---------------------------
>  include/linux/mfd/asic3.h |   34 +++++++++++----
>  2 files changed, 67 insertions(+), 66 deletions(-)
>
> Index: linux-2.6-htc-asic3/drivers/mfd/asic3.c
> ===================================================================
> --- linux-2.6-htc-asic3.orig/drivers/mfd/asic3.c        2008-05-11 17:47:15.000000000 +0200
> +++ linux-2.6-htc-asic3/drivers/mfd/asic3.c     2008-05-11 18:20:35.000000000 +0200
> @@ -465,69 +465,54 @@ static void asic3_gpio_set(struct gpio_c
>        return;
>  }
>
> -static inline u32 asic3_get_gpio(struct asic3 *asic, unsigned int base,
> -                                unsigned int function)
> +static int asic3_gpio_probe(struct platform_device *pdev,
> +                           u16 *gpio_config, int num)
>  {
> -       return asic3_read_register(asic, base + function);
> -}
> -
> -static void asic3_set_gpio(struct asic3 *asic, unsigned int base,
> -                          unsigned int function, u32 bits, u32 val)
> -{
> -       unsigned long flags;
> -
> -       spin_lock_irqsave(&asic->lock, flags);
> -       val |= (asic3_read_register(asic, base + function) & ~bits);
> -
> -       asic3_write_register(asic, base + function, val);
> -       spin_unlock_irqrestore(&asic->lock, flags);
> -}
> -
> -#define asic3_set_gpio_a(asic, fn, bits, val) \
> -       asic3_set_gpio(asic, ASIC3_GPIO_A_Base, ASIC3_GPIO_##fn, bits, val)
> -#define asic3_set_gpio_b(asic, fn, bits, val) \
> -       asic3_set_gpio(asic, ASIC3_GPIO_B_Base, ASIC3_GPIO_##fn, bits, val)
> -#define asic3_set_gpio_c(asic, fn, bits, val) \
> -       asic3_set_gpio(asic, ASIC3_GPIO_C_Base, ASIC3_GPIO_##fn, bits, val)
> -#define asic3_set_gpio_d(asic, fn, bits, val) \
> -       asic3_set_gpio(asic, ASIC3_GPIO_D_Base, ASIC3_GPIO_##fn, bits, val)
> -
> -#define asic3_set_gpio_banks(asic, fn, bits, pdata, field)               \
> -       do {                                                              \
> -            asic3_set_gpio_a((asic), fn, (bits), (pdata)->gpio_a.field); \
> -            asic3_set_gpio_b((asic), fn, (bits), (pdata)->gpio_b.field); \
> -            asic3_set_gpio_c((asic), fn, (bits), (pdata)->gpio_c.field); \
> -            asic3_set_gpio_d((asic), fn, (bits), (pdata)->gpio_d.field); \
> -       } while (0)
> -
> -
> -static int asic3_gpio_probe(struct platform_device *pdev)
> -{
> -       struct asic3_platform_data *pdata = pdev->dev.platform_data;
>        struct asic3 *asic = platform_get_drvdata(pdev);
> +       u16 alt_reg[ASIC3_NUM_GPIO_BANKS];
> +       u16 out_reg[ASIC3_NUM_GPIO_BANKS];
> +       u16 dir_reg[ASIC3_NUM_GPIO_BANKS];
> +       int i;
> +
> +       memset(alt_reg, 0, ASIC3_NUM_GPIO_BANKS);
> +       memset(out_reg, 0, ASIC3_NUM_GPIO_BANKS);
> +       memset(dir_reg, 0, ASIC3_NUM_GPIO_BANKS);

Those should be
       memset(alt_reg, 0, ASIC3_NUM_GPIO_BANKS*sizeof(u16));
       memset(out_reg, 0, ASIC3_NUM_GPIO_BANKS*sizeof(u16));
       memset(dir_reg, 0, ASIC3_NUM_GPIO_BANKS*sizeof(u16));

With that change,
Tested-by: Philipp Zabel <philipp.zabel@gmail.com>

This is the configuration I'm using for hx4700 currently:

u16 asic3_gpio_config[] = {
	/* ASIC3 GPIO banks A and B along with some of C and D
	   implement the buffering for the CF slot. */
	ASIC3_CONFIG_GPIO(0, 1, 1, 0),
	ASIC3_CONFIG_GPIO(1, 1, 1, 0),
	ASIC3_CONFIG_GPIO(2, 1, 1, 0),
	ASIC3_CONFIG_GPIO(3, 1, 1, 0),
	ASIC3_CONFIG_GPIO(4, 1, 1, 0),
	ASIC3_CONFIG_GPIO(5, 1, 1, 0),
	ASIC3_CONFIG_GPIO(6, 1, 1, 0),
	ASIC3_CONFIG_GPIO(7, 1, 1, 0),
	ASIC3_CONFIG_GPIO(8, 1, 1, 0),
	ASIC3_CONFIG_GPIO(9, 1, 1, 0),
	ASIC3_CONFIG_GPIO(10, 1, 1, 0),
	ASIC3_CONFIG_GPIO(11, 1, 1, 0),
	ASIC3_CONFIG_GPIO(12, 1, 1, 0),
	ASIC3_CONFIG_GPIO(13, 1, 1, 0),
	ASIC3_CONFIG_GPIO(14, 1, 1, 0),
	ASIC3_CONFIG_GPIO(15, 1, 1, 0),

	ASIC3_CONFIG_GPIO(16, 1, 1, 0),
	ASIC3_CONFIG_GPIO(17, 1, 1, 0),
	ASIC3_CONFIG_GPIO(18, 1, 1, 0),
	ASIC3_CONFIG_GPIO(19, 1, 1, 0),
	ASIC3_CONFIG_GPIO(20, 1, 1, 0),
	ASIC3_CONFIG_GPIO(21, 1, 1, 0),
	ASIC3_CONFIG_GPIO(22, 1, 1, 0),
	ASIC3_CONFIG_GPIO(23, 1, 1, 0),
	ASIC3_CONFIG_GPIO(24, 1, 1, 0),
	ASIC3_CONFIG_GPIO(25, 1, 1, 0),
	ASIC3_CONFIG_GPIO(26, 1, 1, 0),
	ASIC3_CONFIG_GPIO(27, 1, 1, 0),
	ASIC3_CONFIG_GPIO(28, 1, 1, 0),
	ASIC3_CONFIG_GPIO(29, 1, 1, 0),
	ASIC3_CONFIG_GPIO(30, 1, 1, 0),
	ASIC3_CONFIG_GPIO(31, 1, 1, 0),

	/* GPIOC - CF, LEDs, SD */
	ASIC3_CONFIG_GPIO(32,1,1,0),	/* GPIOC_LED_RED */
	ASIC3_CONFIG_GPIO(33,1,1,0),	/* GPIOC_LED_GREEN */
	ASIC3_CONFIG_GPIO(34,1,1,0),	/* GPIOC_LED_BLUE */
	ASIC3_CONFIG_GPIO(35,0,0,0),	/* GPIOC_nSD_CS */
	ASIC3_CONFIG_GPIO(36,1,0,0),	/* GPIOC_CF_nCD */
	ASIC3_CONFIG_GPIO(37,1,1,0),	/* GPIOC_nCIOW */
	ASIC3_CONFIG_GPIO(38,1,1,0),	/* GPIOC_nCIOR */
	ASIC3_CONFIG_GPIO(39,1,0,0),	/* GPIOC_nPCE1 */
	ASIC3_CONFIG_GPIO(40,1,0,0),	/* GPIOC_nPCE2 */
	ASIC3_CONFIG_GPIO(41,1,0,0),	/* GPIOC_nPOE */
	ASIC3_CONFIG_GPIO(42,1,0,0),	/* GPIOC_CF_nPWE */
	ASIC3_CONFIG_GPIO(43,1,0,0),	/* GPIOC_PSKTSEL */
	ASIC3_CONFIG_GPIO(44,1,0,0),	/* GPIOC_nPREG */
	ASIC3_CONFIG_GPIO(45,1,1,0),	/* GPIOC_nPWAIT */
	ASIC3_CONFIG_GPIO(46,1,1,0),	/* GPIOC_nPIOS16 */
	ASIC3_CONFIG_GPIO(47,1,0,0),	/* GPIOC_nPIOR */

	/* GPIOD: all inputs */
	ASIC3_CONFIG_GPIO_DEFAULT(48,0,0),	/* GPIOD_CPU_SS_INT */
	ASIC3_CONFIG_GPIO_DEFAULT(49,0,0),	/* GPIOD_nKEY_AP2 */
	ASIC3_CONFIG_GPIO_DEFAULT(50,0,0),	/* GPIOD_BLUETOOTH_WAKEUP */
	ASIC3_CONFIG_GPIO_DEFAULT(51,0,0),	/* GPIOD_nKEY_AP4 */
	ASIC3_CONFIG_GPIO_DEFAULT(52,0,0),	/* GPIOD_CF_nCD */
	ASIC3_CONFIG_GPIO_DEFAULT(53,0,0),	/* GPIOD_nPIO */
	ASIC3_CONFIG_GPIO_DEFAULT(54,0,0),	/* GPIOD_nKEY_RECORD */
	ASIC3_CONFIG_GPIO_DEFAULT(55,0,0),	/* GPIOD_nSDIO_DETECT */
	ASIC3_CONFIG_GPIO_DEFAULT(56,0,0),	/* GPIOD_COM_DCD */
	ASIC3_CONFIG_GPIO_DEFAULT(57,0,0),	/* GPIOD_nAC_IN */
	ASIC3_CONFIG_GPIO_DEFAULT(58,0,0),	/* GPIOD_nSDIO_IRQ */
	ASIC3_CONFIG_GPIO(59,1,0,0),		/* GPIOD_nCIOIS16 */
	ASIC3_CONFIG_GPIO(60,1,0,0),		/* GPIOD_nCWAIT */
	ASIC3_CONFIG_GPIO_DEFAULT(61,0,0),	/* GPIOD_CF_RNB */
	ASIC3_CONFIG_GPIO_DEFAULT(62,0,0),	/* GPIOD_nUSBC_DETECT */
	ASIC3_CONFIG_GPIO(63,1,0,0),		/* GPIOD_ASIC3_nPIOW */
};

Do you think it would make sense to include constants for the
alternate functions like
#define ASIC3_GPIO32_LED0 ASIC3_CONFIG_GPIO(32,1,1,0)
#define ASIC3_GPIO43_PSKTSEL ASIC3_CONFIG_GPIO(43,1,0,0)
etc. in asic3.h?

How does the array look like that you use for Universal?

> +       /* Enable all GPIOs */
>        asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, Mask), 0xffff);
>        asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, Mask), 0xffff);
>        asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, Mask), 0xffff);
>        asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, Mask), 0xffff);
>
> -       asic3_set_gpio_a(asic, SleepMask, 0xffff, 0xffff);
> -       asic3_set_gpio_b(asic, SleepMask, 0xffff, 0xffff);
> -       asic3_set_gpio_c(asic, SleepMask, 0xffff, 0xffff);
> -       asic3_set_gpio_d(asic, SleepMask, 0xffff, 0xffff);
> -
> -       if (pdata) {
> -               asic3_set_gpio_banks(asic, Out, 0xffff, pdata, init);
> -               asic3_set_gpio_banks(asic, Direction, 0xffff, pdata, dir);
> -               asic3_set_gpio_banks(asic, SleepMask, 0xffff, pdata,
> -                                    sleep_mask);
> -               asic3_set_gpio_banks(asic, SleepOut, 0xffff, pdata, sleep_out);
> -               asic3_set_gpio_banks(asic, BattFaultOut, 0xffff, pdata,
> -                                    batt_fault_out);
> -               asic3_set_gpio_banks(asic, SleepConf, 0xffff, pdata,
> -                                    sleep_conf);
> -               asic3_set_gpio_banks(asic, AltFunction, 0xffff, pdata,
> -                                    alt_function);
> +       for (i = 0; i < num; i++) {
> +               u8 alt, pin, dir, init, bank_num, bit_num;
> +               u16 config = gpio_config[i];
> +
> +               pin = ASIC3_CONFIG_GPIO_PIN(config);
> +               alt = ASIC3_CONFIG_GPIO_ALT(config);
> +               dir = ASIC3_CONFIG_GPIO_DIR(config);
> +               init = ASIC3_CONFIG_GPIO_INIT(config);
> +
> +               bank_num = ASIC3_GPIO_TO_BANK(pin);
> +               bit_num = ASIC3_GPIO_TO_BIT(pin);
> +
> +               alt_reg[bank_num] |= (alt << bit_num);
> +               out_reg[bank_num] |= (init << bit_num);
> +               dir_reg[bank_num] |= (dir << bit_num);
> +       }
> +
> +       for (i = 0; i < ASIC3_NUM_GPIO_BANKS; i++) {
> +               asic3_write_register(asic,
> +                                    ASIC3_BANK_TO_BASE(i) +
> +                                    ASIC3_GPIO_Direction,
> +                                    dir_reg[i]);
> +               asic3_write_register(asic,
> +                                    ASIC3_BANK_TO_BASE(i) + ASIC3_GPIO_Out,
> +                                    out_reg[i]);
> +               asic3_write_register(asic,
> +                                    ASIC3_BANK_TO_BASE(i) +
> +                                    ASIC3_GPIO_AltFunction,
> +                                    alt_reg[i]);
>        }
>
>        return gpiochip_add(&asic->gpio);
> @@ -598,7 +583,9 @@ static int asic3_probe(struct platform_d
>        asic->gpio.direction_input = asic3_gpio_direction_input;
>        asic->gpio.direction_output = asic3_gpio_direction_output;
>
> -       ret = asic3_gpio_probe(pdev);
> +       ret = asic3_gpio_probe(pdev,
> +                              pdata->gpio_config,
> +                              pdata->gpio_config_num);
>        if (ret < 0) {
>                printk(KERN_ERR "GPIO probe failed\n");
>                goto out_irq;
> Index: linux-2.6-htc-asic3/include/linux/mfd/asic3.h
> ===================================================================
> --- linux-2.6-htc-asic3.orig/include/linux/mfd/asic3.h  2008-05-11 17:47:15.000000000 +0200
> +++ linux-2.6-htc-asic3/include/linux/mfd/asic3.h       2008-05-11 18:12:07.000000000 +0200
> @@ -8,7 +8,7 @@
>  * published by the Free Software Foundation.
>  *
>  * Copyright 2001 Compaq Computer Corporation.
> - * Copyright 2007 OpendHand.
> + * Copyright 2007-2008 OpenedHand Ltd.
>  */
>
>  #ifndef __ASIC3_H__
> @@ -17,15 +17,8 @@
>  #include <linux/types.h>
>
>  struct asic3_platform_data {
> -       struct {
> -               u32 dir;
> -               u32 init;
> -               u32 sleep_mask;
> -               u32 sleep_out;
> -               u32 batt_fault_out;
> -               u32 sleep_conf;
> -               u32 alt_function;
> -       } gpio_a, gpio_b, gpio_c, gpio_d;
> +       u16 *gpio_config;
> +       unsigned int gpio_config_num;
>
>        unsigned int bus_shift;
>
> @@ -86,6 +79,27 @@ struct asic3_platform_data {
>                                          */
>  #define ASIC3_GPIO_Status        0x30    /* R   Pin status */
>
> +/*
> + * ASIC3 GPIO config
> + *
> + * Bits 0..6   gpio number
> + * Bits 7..13  Alternate function
> + * Bit  14     Direction
> + * Bit  15     Initial value
> + *
> + */
> +#define ASIC3_CONFIG_GPIO_PIN(config) ((config) & 0x7f)
> +#define ASIC3_CONFIG_GPIO_ALT(config)  (((config) & (0x7f << 7)) >> 7)
> +#define ASIC3_CONFIG_GPIO_DIR(config)  ((config & (1 << 14)) >> 14)
> +#define ASIC3_CONFIG_GPIO_INIT(config) ((config & (1 << 15)) >> 15)
> +#define ASIC3_CONFIG_GPIO(gpio, alt, dir, init) (((gpio) & 0x7f) \
> +       | (((alt) & 0x7f) << 7) | (((dir) & 0x1) << 14) \
> +       | (((init) & 0x1) << 15))
> +#define ASIC3_CONFIG_GPIO_DEFAULT(gpio, dir, init) \
> +       ASIC3_CONFIG_GPIO((gpio), 0, (dir), (init))
> +#define ASIC3_CONFIG_GPIO_DEFAULT_OUT(gpio, init) \
> +       ASIC3_CONFIG_GPIO((gpio), 0, 1, (init))
> +
>  #define ASIC3_SPI_Base               0x0400
>  #define ASIC3_SPI_Control               0x0000
>  #define ASIC3_SPI_TxData                0x0004
>
> --
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

regards
Philipp

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH -mm 3/5] asic3: New gpio configuration code
  2008-06-21 14:43   ` pHilipp Zabel
@ 2008-06-23 10:13     ` Samuel Ortiz
  0 siblings, 0 replies; 8+ messages in thread
From: Samuel Ortiz @ 2008-06-23 10:13 UTC (permalink / raw)
  To: pHilipp Zabel; +Cc: Andrew Morton, Linux Kernel ML

On Sat, Jun 21, 2008 at 04:43:08PM +0200, pHilipp Zabel wrote:
> On Sun, May 11, 2008 at 7:36 PM, Samuel Ortiz <sameo@openedhand.com> wrote:
> > The ASIC3 GPIO configuration code is a bit obscure and hardly readable.
> > This patch changes it so that it is now more readable and understandable,
> > by being more explicit.
> >
> > Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
> > ---
> >  drivers/mfd/asic3.c       |   99 +++++++++++++++++++---------------------------
> >  include/linux/mfd/asic3.h |   34 +++++++++++----
> >  2 files changed, 67 insertions(+), 66 deletions(-)
> >
> > Index: linux-2.6-htc-asic3/drivers/mfd/asic3.c
> > ===================================================================
> > --- linux-2.6-htc-asic3.orig/drivers/mfd/asic3.c        2008-05-11 17:47:15.000000000 +0200
> > +++ linux-2.6-htc-asic3/drivers/mfd/asic3.c     2008-05-11 18:20:35.000000000 +0200
> > @@ -465,69 +465,54 @@ static void asic3_gpio_set(struct gpio_c
> >        return;
> >  }
> >
> > -static inline u32 asic3_get_gpio(struct asic3 *asic, unsigned int base,
> > -                                unsigned int function)
> > +static int asic3_gpio_probe(struct platform_device *pdev,
> > +                           u16 *gpio_config, int num)
> >  {
> > -       return asic3_read_register(asic, base + function);
> > -}
> > -
> > -static void asic3_set_gpio(struct asic3 *asic, unsigned int base,
> > -                          unsigned int function, u32 bits, u32 val)
> > -{
> > -       unsigned long flags;
> > -
> > -       spin_lock_irqsave(&asic->lock, flags);
> > -       val |= (asic3_read_register(asic, base + function) & ~bits);
> > -
> > -       asic3_write_register(asic, base + function, val);
> > -       spin_unlock_irqrestore(&asic->lock, flags);
> > -}
> > -
> > -#define asic3_set_gpio_a(asic, fn, bits, val) \
> > -       asic3_set_gpio(asic, ASIC3_GPIO_A_Base, ASIC3_GPIO_##fn, bits, val)
> > -#define asic3_set_gpio_b(asic, fn, bits, val) \
> > -       asic3_set_gpio(asic, ASIC3_GPIO_B_Base, ASIC3_GPIO_##fn, bits, val)
> > -#define asic3_set_gpio_c(asic, fn, bits, val) \
> > -       asic3_set_gpio(asic, ASIC3_GPIO_C_Base, ASIC3_GPIO_##fn, bits, val)
> > -#define asic3_set_gpio_d(asic, fn, bits, val) \
> > -       asic3_set_gpio(asic, ASIC3_GPIO_D_Base, ASIC3_GPIO_##fn, bits, val)
> > -
> > -#define asic3_set_gpio_banks(asic, fn, bits, pdata, field)               \
> > -       do {                                                              \
> > -            asic3_set_gpio_a((asic), fn, (bits), (pdata)->gpio_a.field); \
> > -            asic3_set_gpio_b((asic), fn, (bits), (pdata)->gpio_b.field); \
> > -            asic3_set_gpio_c((asic), fn, (bits), (pdata)->gpio_c.field); \
> > -            asic3_set_gpio_d((asic), fn, (bits), (pdata)->gpio_d.field); \
> > -       } while (0)
> > -
> > -
> > -static int asic3_gpio_probe(struct platform_device *pdev)
> > -{
> > -       struct asic3_platform_data *pdata = pdev->dev.platform_data;
> >        struct asic3 *asic = platform_get_drvdata(pdev);
> > +       u16 alt_reg[ASIC3_NUM_GPIO_BANKS];
> > +       u16 out_reg[ASIC3_NUM_GPIO_BANKS];
> > +       u16 dir_reg[ASIC3_NUM_GPIO_BANKS];
> > +       int i;
> > +
> > +       memset(alt_reg, 0, ASIC3_NUM_GPIO_BANKS);
> > +       memset(out_reg, 0, ASIC3_NUM_GPIO_BANKS);
> > +       memset(dir_reg, 0, ASIC3_NUM_GPIO_BANKS);
> 
> Those should be
>        memset(alt_reg, 0, ASIC3_NUM_GPIO_BANKS*sizeof(u16));
>        memset(out_reg, 0, ASIC3_NUM_GPIO_BANKS*sizeof(u16));
>        memset(dir_reg, 0, ASIC3_NUM_GPIO_BANKS*sizeof(u16));
> 
> With that change,
> Tested-by: Philipp Zabel <philipp.zabel@gmail.com>
Ah, right, thanks a lot. I'll forward it to Andrew, whenever I'm done with
setting my MFD git tree.

 
> Do you think it would make sense to include constants for the
> alternate functions like
> #define ASIC3_GPIO32_LED0 ASIC3_CONFIG_GPIO(32,1,1,0)
> #define ASIC3_GPIO43_PSKTSEL ASIC3_CONFIG_GPIO(43,1,0,0)
> etc. in asic3.h?
Hmm, not sure you want to hard code the alt function here. On the universal,
most of them are set to 0 it seems.
I think it would make sense to have something like that though:

#define ASIC3_GPIO15_LCD_POWER5(alt) ASIC3_CONFIG_GPIO(15, (alt), 1, 0)
 
> How does the array look like that you use for Universal?
This is my (probably incomplete still) asic3 config for the universal:

static u16 asic3_gpio_config[] = {
	/* Bank A */
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_LCD_PWR5_ON,     1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_FLASHLIGHT,      0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_UNKNOWNA9,       0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_SPK_PWR2_ON,     0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_UNKNOWNA4,       0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_EARPHONE_PWR_ON, 0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_AUDIO_PWR_ON,    0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_SPK_PWR1_ON,     0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_I2C_EN,          1),

	/* Bank B */
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_CODEC_PDN,       1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_LCD_PWR3_ON,     1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_BB_RESET2,       0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_CHARGE_EN,       0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_USB_PUEN,        1),

	/* Bank C */
	ASIC3_CONFIG_GPIO(GPIO_LED_BTWIFI, 1, 1, 0),
	ASIC3_CONFIG_GPIO(GPIO_LED_RED,    1, 1, 0),
	ASIC3_CONFIG_GPIO(GPIO_LED_GREEN,  1, 1, 0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_WIFI_RESET,      1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_WIFI_PWR1_ON,    1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_BT_RESET,        1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_UNKNOWNC8,       0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_LCD_PWR1_ON,     1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_LCD_PWR2_ON,     1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_BT_PWR_ON,       1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_CHARGE_ON,       1),

	/* Bank D */
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_WIFI_PWR2_ON,    1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_HW_REBOOT,       0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_BB_RESET1,       0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_UNKNOWND9,       0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_VIBRA_PWR_ON,    0),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_WIFI_PWR3_ON,    1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_FL_PWR_ON,       1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_LCD_PWR4_ON,     1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_BL_KEYP_PWR_ON,  1),
	ASIC3_CONFIG_GPIO_DEFAULT_OUT(GPIO_BL_KEYB_PWR_ON,  1),
};


> 
> > +       /* Enable all GPIOs */
> >        asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, Mask), 0xffff);
> >        asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, Mask), 0xffff);
> >        asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, Mask), 0xffff);
> >        asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, Mask), 0xffff);
> >
> > -       asic3_set_gpio_a(asic, SleepMask, 0xffff, 0xffff);
> > -       asic3_set_gpio_b(asic, SleepMask, 0xffff, 0xffff);
> > -       asic3_set_gpio_c(asic, SleepMask, 0xffff, 0xffff);
> > -       asic3_set_gpio_d(asic, SleepMask, 0xffff, 0xffff);
> > -
> > -       if (pdata) {
> > -               asic3_set_gpio_banks(asic, Out, 0xffff, pdata, init);
> > -               asic3_set_gpio_banks(asic, Direction, 0xffff, pdata, dir);
> > -               asic3_set_gpio_banks(asic, SleepMask, 0xffff, pdata,
> > -                                    sleep_mask);
> > -               asic3_set_gpio_banks(asic, SleepOut, 0xffff, pdata, sleep_out);
> > -               asic3_set_gpio_banks(asic, BattFaultOut, 0xffff, pdata,
> > -                                    batt_fault_out);
> > -               asic3_set_gpio_banks(asic, SleepConf, 0xffff, pdata,
> > -                                    sleep_conf);
> > -               asic3_set_gpio_banks(asic, AltFunction, 0xffff, pdata,
> > -                                    alt_function);
> > +       for (i = 0; i < num; i++) {
> > +               u8 alt, pin, dir, init, bank_num, bit_num;
> > +               u16 config = gpio_config[i];
> > +
> > +               pin = ASIC3_CONFIG_GPIO_PIN(config);
> > +               alt = ASIC3_CONFIG_GPIO_ALT(config);
> > +               dir = ASIC3_CONFIG_GPIO_DIR(config);
> > +               init = ASIC3_CONFIG_GPIO_INIT(config);
> > +
> > +               bank_num = ASIC3_GPIO_TO_BANK(pin);
> > +               bit_num = ASIC3_GPIO_TO_BIT(pin);
> > +
> > +               alt_reg[bank_num] |= (alt << bit_num);
> > +               out_reg[bank_num] |= (init << bit_num);
> > +               dir_reg[bank_num] |= (dir << bit_num);
> > +       }
> > +
> > +       for (i = 0; i < ASIC3_NUM_GPIO_BANKS; i++) {
> > +               asic3_write_register(asic,
> > +                                    ASIC3_BANK_TO_BASE(i) +
> > +                                    ASIC3_GPIO_Direction,
> > +                                    dir_reg[i]);
> > +               asic3_write_register(asic,
> > +                                    ASIC3_BANK_TO_BASE(i) + ASIC3_GPIO_Out,
> > +                                    out_reg[i]);
> > +               asic3_write_register(asic,
> > +                                    ASIC3_BANK_TO_BASE(i) +
> > +                                    ASIC3_GPIO_AltFunction,
> > +                                    alt_reg[i]);
> >        }
> >
> >        return gpiochip_add(&asic->gpio);
> > @@ -598,7 +583,9 @@ static int asic3_probe(struct platform_d
> >        asic->gpio.direction_input = asic3_gpio_direction_input;
> >        asic->gpio.direction_output = asic3_gpio_direction_output;
> >
> > -       ret = asic3_gpio_probe(pdev);
> > +       ret = asic3_gpio_probe(pdev,
> > +                              pdata->gpio_config,
> > +                              pdata->gpio_config_num);
> >        if (ret < 0) {
> >                printk(KERN_ERR "GPIO probe failed\n");
> >                goto out_irq;
> > Index: linux-2.6-htc-asic3/include/linux/mfd/asic3.h
> > ===================================================================
> > --- linux-2.6-htc-asic3.orig/include/linux/mfd/asic3.h  2008-05-11 17:47:15.000000000 +0200
> > +++ linux-2.6-htc-asic3/include/linux/mfd/asic3.h       2008-05-11 18:12:07.000000000 +0200
> > @@ -8,7 +8,7 @@
> >  * published by the Free Software Foundation.
> >  *
> >  * Copyright 2001 Compaq Computer Corporation.
> > - * Copyright 2007 OpendHand.
> > + * Copyright 2007-2008 OpenedHand Ltd.
> >  */
> >
> >  #ifndef __ASIC3_H__
> > @@ -17,15 +17,8 @@
> >  #include <linux/types.h>
> >
> >  struct asic3_platform_data {
> > -       struct {
> > -               u32 dir;
> > -               u32 init;
> > -               u32 sleep_mask;
> > -               u32 sleep_out;
> > -               u32 batt_fault_out;
> > -               u32 sleep_conf;
> > -               u32 alt_function;
> > -       } gpio_a, gpio_b, gpio_c, gpio_d;
> > +       u16 *gpio_config;
> > +       unsigned int gpio_config_num;
> >
> >        unsigned int bus_shift;
> >
> > @@ -86,6 +79,27 @@ struct asic3_platform_data {
> >                                          */
> >  #define ASIC3_GPIO_Status        0x30    /* R   Pin status */
> >
> > +/*
> > + * ASIC3 GPIO config
> > + *
> > + * Bits 0..6   gpio number
> > + * Bits 7..13  Alternate function
> > + * Bit  14     Direction
> > + * Bit  15     Initial value
> > + *
> > + */
> > +#define ASIC3_CONFIG_GPIO_PIN(config) ((config) & 0x7f)
> > +#define ASIC3_CONFIG_GPIO_ALT(config)  (((config) & (0x7f << 7)) >> 7)
> > +#define ASIC3_CONFIG_GPIO_DIR(config)  ((config & (1 << 14)) >> 14)
> > +#define ASIC3_CONFIG_GPIO_INIT(config) ((config & (1 << 15)) >> 15)
> > +#define ASIC3_CONFIG_GPIO(gpio, alt, dir, init) (((gpio) & 0x7f) \
> > +       | (((alt) & 0x7f) << 7) | (((dir) & 0x1) << 14) \
> > +       | (((init) & 0x1) << 15))
> > +#define ASIC3_CONFIG_GPIO_DEFAULT(gpio, dir, init) \
> > +       ASIC3_CONFIG_GPIO((gpio), 0, (dir), (init))
> > +#define ASIC3_CONFIG_GPIO_DEFAULT_OUT(gpio, init) \
> > +       ASIC3_CONFIG_GPIO((gpio), 0, 1, (init))
> > +
> >  #define ASIC3_SPI_Base               0x0400
> >  #define ASIC3_SPI_Control               0x0000
> >  #define ASIC3_SPI_TxData                0x0004
> >
> > --
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> >
> 
> regards
> Philipp

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-06-23 10:13 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-11 17:36 [PATCH -mm 0/5] ASIC3 updates Samuel Ortiz
2008-05-11 17:36 ` [PATCH -mm 1/5] asic3: gpiolib support Samuel Ortiz
2008-05-11 17:36 ` [PATCH -mm 2/5] asic3: Remove children platform data Samuel Ortiz
2008-05-11 17:36 ` [PATCH -mm 3/5] asic3: New gpio configuration code Samuel Ortiz
2008-06-21 14:43   ` pHilipp Zabel
2008-06-23 10:13     ` Samuel Ortiz
2008-05-11 17:36 ` [PATCH -mm 4/5] asic3: use dev_* macros Samuel Ortiz
2008-05-11 17:36 ` [PATCH -mm 5/5] asic3: Use uppercase only for macros and defines Samuel Ortiz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.