Skip to contentSkip to conversation

ARM: simpad: Add support for GPIO attached hardware

PATCH Superseded Jochen Friedrich 4 participants 12 messages Apr 18, 2011 – Apr 19, 2011

Subsystems (3)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v2 cover ARM: simpad: Add support for GPIO attached hardware

This series enables GPIO API on UCB1x00 and implements the GPIO API on the CS3 latch. The third patch finally registers platform devices for the GPIO attached LED, buttons and I2C bus.

v2: In response to the Linus rant, remove the ARM specific LED
support for simpad hardware instead of supporting it alternatively to the generic LED code.

ARM: simpad: Add ucb1x00 GPIO definitions and register GPIO
ARM: simpad: Cleanup CS3 accessors and add GPIO API
ARM: simpad: add GPIO based device definitions

#1 lore raw

PATCH v2 1/3 ARM:simpad: Add ucb1x00 GPIO definitions and register GPIO

Add ucb1x00 GPIO definitions to simpad.h and add gpio_base to ucb1x00 platform device so the pins are available using the GPIO API.

---
 arch/arm/mach-sa1100/include/mach/simpad.h |   13 +++++++++++++
 arch/arm/mach-sa1100/simpad.c              |    1 +
 2 files changed, 14 insertions(+), 0 deletions(-)
arch/arm/mach-sa1100/include/mach/simpad.h +13 -0
index 9296c45..231550d 100644
@@ -48,6 +48,19 @@
 #define GPIO_SMART_CARD		GPIO_GPIO10
 #define IRQ_GPIO_SMARD_CARD	IRQ_GPIO10
 
+/*--- ucb1x00 GPIO ---*/
+#define SIMPAD_UCB1X00_GPIO_BASE	(GPIO_MAX + 1)
+#define SIMPAD_UCB1X00_GPIO_PROG1	(SIMPAD_UCB1X00_GPIO_BASE)
+#define SIMPAD_UCB1X00_GPIO_PROG2	(SIMPAD_UCB1X00_GPIO_BASE + 1)
+#define SIMPAD_UCB1X00_GPIO_UP		(SIMPAD_UCB1X00_GPIO_BASE + 2)
+#define SIMPAD_UCB1X00_GPIO_DOWN	(SIMPAD_UCB1X00_GPIO_BASE + 3)
+#define SIMPAD_UCB1X00_GPIO_LEFT	(SIMPAD_UCB1X00_GPIO_BASE + 4)
+#define SIMPAD_UCB1X00_GPIO_RIGHT	(SIMPAD_UCB1X00_GPIO_BASE + 5)
+#define SIMPAD_UCB1X00_GPIO_6		(SIMPAD_UCB1X00_GPIO_BASE + 6)
+#define SIMPAD_UCB1X00_GPIO_7		(SIMPAD_UCB1X00_GPIO_BASE + 7)
+#define SIMPAD_UCB1X00_GPIO_HEADSET	(SIMPAD_UCB1X00_GPIO_BASE + 8)
+#define SIMPAD_UCB1X00_GPIO_SPEAKER	(SIMPAD_UCB1X00_GPIO_BASE + 9)
+
 // CS3 Latch is write only, a shadow is necessary
 
 #define CS3BUSTYPE unsigned volatile long
arch/arm/mach-sa1100/simpad.c +1 -0
index cfb7607..718b802 100644
@@ -132,6 +132,7 @@ static struct resource simpad_flash_resources [] = {
 static struct mcp_plat_data simpad_mcp_data = {
 	.mccr0		= MCCR0_ADM,
 	.sclk_rate	= 11981000,
+	.gpio_base	= SIMPAD_UCB1X00_GPIO_BASE,
 };
 
 
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH v2 2/3 ARM:simpad: Cleanup CS3 accessors.

In reply to Jochen Friedrich

- prepend CS3 accessors by simpad_ to indicate they are specific to simpad devices.
- use spinlock to protect shadow register.
- implement 8 read-only pins.
- use readl/writel macros so barriers are used where necessary.
- register CS3 as GPIO controller with 24 pins (16 output only and 8 input only).

---
 arch/arm/mach-sa1100/include/mach/simpad.h |   81 ++++++++++++++------
 arch/arm/mach-sa1100/leds-simpad.c         |    7 +-
 arch/arm/mach-sa1100/simpad.c              |  115 ++++++++++++++++++++++------
 drivers/pcmcia/sa1100_simpad.c             |   30 +++----
 4 files changed, 165 insertions(+), 68 deletions(-)
arch/arm/mach-sa1100/include/mach/simpad.h +58 -23
index 231550d..db28118 100644
@@ -61,32 +61,67 @@
 #define SIMPAD_UCB1X00_GPIO_HEADSET	(SIMPAD_UCB1X00_GPIO_BASE + 8)
 #define SIMPAD_UCB1X00_GPIO_SPEAKER	(SIMPAD_UCB1X00_GPIO_BASE + 9)
 
-// CS3 Latch is write only, a shadow is necessary
+/*--- CS3 Latch ---*/
+#define SIMPAD_CS3_GPIO_BASE		(GPIO_MAX + 11)
+#define SIMPAD_CS3_VCC_5V_EN		(SIMPAD_CS3_GPIO_BASE)
+#define SIMPAD_CS3_VCC_3V_EN		(SIMPAD_CS3_GPIO_BASE + 1)
+#define SIMPAD_CS3_EN1			(SIMPAD_CS3_GPIO_BASE + 2)
+#define SIMPAD_CS3_EN0			(SIMPAD_CS3_GPIO_BASE + 3)
+#define SIMPAD_CS3_DISPLAY_ON		(SIMPAD_CS3_GPIO_BASE + 4)
+#define SIMPAD_CS3_PCMCIA_BUFF_DIS	(SIMPAD_CS3_GPIO_BASE + 5)
+#define SIMPAD_CS3_MQ_RESET		(SIMPAD_CS3_GPIO_BASE + 6)
+#define SIMPAD_CS3_PCMCIA_RESET		(SIMPAD_CS3_GPIO_BASE + 7)
+#define SIMPAD_CS3_DECT_POWER_ON	(SIMPAD_CS3_GPIO_BASE + 8)
+#define SIMPAD_CS3_IRDA_SD		(SIMPAD_CS3_GPIO_BASE + 9)
+#define SIMPAD_CS3_RS232_ON		(SIMPAD_CS3_GPIO_BASE + 10)
+#define SIMPAD_CS3_SD_MEDIAQ		(SIMPAD_CS3_GPIO_BASE + 11)
+#define SIMPAD_CS3_LED2_ON		(SIMPAD_CS3_GPIO_BASE + 12)
+#define SIMPAD_CS3_IRDA_MODE		(SIMPAD_CS3_GPIO_BASE + 13)
+#define SIMPAD_CS3_ENABLE_5V		(SIMPAD_CS3_GPIO_BASE + 14)
+#define SIMPAD_CS3_RESET_SIMCARD	(SIMPAD_CS3_GPIO_BASE + 15)
+
+#define SIMPAD_CS3_PCMCIA_BVD1		(SIMPAD_CS3_GPIO_BASE + 16)
+#define SIMPAD_CS3_PCMCIA_BVD2		(SIMPAD_CS3_GPIO_BASE + 17)
+#define SIMPAD_CS3_PCMCIA_VS1		(SIMPAD_CS3_GPIO_BASE + 18)
+#define SIMPAD_CS3_PCMCIA_VS2		(SIMPAD_CS3_GPIO_BASE + 19)
+#define SIMPAD_CS3_LOCK_IND		(SIMPAD_CS3_GPIO_BASE + 20)
+#define SIMPAD_CS3_CHARGING_STATE	(SIMPAD_CS3_GPIO_BASE + 21)
+#define SIMPAD_CS3_PCMCIA_SHORT		(SIMPAD_CS3_GPIO_BASE + 22)
+#define SIMPAD_CS3_GPIO_23		(SIMPAD_CS3_GPIO_BASE + 23)
 
-#define CS3BUSTYPE unsigned volatile long
 #define CS3_BASE        0xf1000000
 
-#define VCC_5V_EN       0x0001 // For 5V PCMCIA
-#define VCC_3V_EN       0x0002 // FOR 3.3V PCMCIA
-#define EN1             0x0004 // This is only for EPROM's
-#define EN0             0x0008 // Both should be enable for 3.3V or 5V
-#define DISPLAY_ON      0x0010
-#define PCMCIA_BUFF_DIS 0x0020
-#define MQ_RESET        0x0040
-#define PCMCIA_RESET    0x0080
-#define DECT_POWER_ON   0x0100
-#define IRDA_SD         0x0200 // Shutdown for powersave
-#define RS232_ON        0x0400
-#define SD_MEDIAQ       0x0800 // Shutdown for powersave
-#define LED2_ON         0x1000
-#define IRDA_MODE       0x2000 // Fast/Slow IrDA mode
-#define ENABLE_5V       0x4000 // Enable 5V circuit
-#define RESET_SIMCARD   0x8000
-
-#define RS232_ENABLE    0x0440
-#define PCMCIAMASK      0x402f
-
-
+long simpad_get_cs3_ro(void);
+long simpad_get_cs3_shadow(void);
+void simpad_set_cs3_bit(int value);
+void simpad_clear_cs3_bit(int value);
+
+#define VCC_5V_EN	0x0001 /* For 5V PCMCIA */
+#define VCC_3V_EN	0x0002 /* FOR 3.3V PCMCIA */
+#define EN1		0x0004 /* This is only for EPROM's */
+#define EN0		0x0008 /* Both should be enable for 3.3V or 5V */
+#define DISPLAY_ON	0x0010
+#define PCMCIA_BUFF_DIS	0x0020
+#define MQ_RESET	0x0040
+#define PCMCIA_RESET	0x0080
+#define DECT_POWER_ON	0x0100
+#define IRDA_SD		0x0200 /* Shutdown for powersave */
+#define RS232_ON	0x0400
+#define SD_MEDIAQ	0x0800 /* Shutdown for powersave */
+#define LED2_ON		0x1000
+#define IRDA_MODE	0x2000 /* Fast/Slow IrDA mode */
+#define ENABLE_5V	0x4000 /* Enable 5V circuit */
+#define RESET_SIMCARD	0x8000
+
+#define PCMCIA_BVD1	0x01
+#define PCMCIA_BVD2	0x02
+#define PCMCIA_VS1	0x04
+#define PCMCIA_VS2	0x08
+#define LOCK_IND	0x10
+#define CHARGING_STATE	0x20
+#define PCMCIA_SHORT	0x40
+
+/*--- Battery ---*/
 struct simpad_battery {
 	unsigned char ac_status;	/* line connected yes/no */
 	unsigned char status;		/* battery loading yes/no */
arch/arm/mach-sa1100/leds-simpad.c +2 -5
index d50f4ee..d25784c 100644
@@ -22,9 +22,6 @@ static unsigned int hw_led_state;
 #define	LED_GREEN	(1)
 #define	LED_MASK	(1)
 
-extern void set_cs3_bit(int value);
-extern void clear_cs3_bit(int value);     
-
 void simpad_leds_event(led_event_t evt)
 {
 	switch (evt)
@@ -93,8 +90,8 @@ void simpad_leds_event(led_event_t evt)
 	}
 
 	if  (led_state & LED_STATE_ENABLED)
-		set_cs3_bit(LED2_ON);
+		simpad_set_cs3_bit(LED2_ON);
 	else 
-	        clear_cs3_bit(LED2_ON);
+		simpad_clear_cs3_bit(LED2_ON);
 }
 
arch/arm/mach-sa1100/simpad.c +92 -23

178 lines not on this page · raw message

drivers/pcmcia/sa1100_simpad.c +13 -17
index c998f7a..540320d 100644
@@ -15,10 +15,6 @@
 #include <mach/simpad.h>
 #include "sa1100_generic.h"
  
-extern long get_cs3_shadow(void);
-extern void set_cs3_bit(int value); 
-extern void clear_cs3_bit(int value);
-
 static struct pcmcia_irqs irqs[] = {
 	{ 1, IRQ_GPIO_CF_CD, "CF_CD" },
 };
@@ -26,7 +22,7 @@ static struct pcmcia_irqs irqs[] = {
 static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 
-	clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+	simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
 	skt->socket.pci_irq = IRQ_GPIO_CF_IRQ;
 
@@ -38,8 +34,8 @@ static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
 
 	/* Disable CF bus: */
-	//set_cs3_bit(PCMCIA_BUFF_DIS);
-	clear_cs3_bit(PCMCIA_RESET);       
+	/*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/
+	simpad_clear_cs3_bit(PCMCIA_RESET);
 }
 
 static void
@@ -47,15 +43,15 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 			   struct pcmcia_state *state)
 {
 	unsigned long levels = GPLR;
-	long cs3reg = get_cs3_shadow();
+	long cs3reg = simpad_get_cs3_shadow();
 
 	state->detect=((levels & GPIO_CF_CD)==0)?1:0;
 	state->ready=(levels & GPIO_CF_IRQ)?1:0;
 	state->bvd1=1; /* Not available on Simpad. */
 	state->bvd2=1; /* Not available on Simpad. */
 	state->wrprot=0; /* Not available on Simpad. */
-  
-	if((cs3reg & 0x0c) == 0x0c) {
+
+	if ((cs3reg & 0x0c) == 0x0c) {
 		state->vs_3v=0;
 		state->vs_Xv=0;
 	} else {
@@ -75,23 +71,23 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 	/* Murphy: see table of MIC2562a-1 */
 	switch (state->Vcc) {
 	case 0:
-		clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+		simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 		break;
 
 	case 33:  
-		clear_cs3_bit(VCC_3V_EN|EN1);
-		set_cs3_bit(VCC_5V_EN|EN0);
+		simpad_clear_cs3_bit(VCC_3V_EN|EN1);
+		simpad_set_cs3_bit(VCC_5V_EN|EN0);
 		break;
 
 	case 50:
-		clear_cs3_bit(VCC_5V_EN|EN1);
-		set_cs3_bit(VCC_3V_EN|EN0);
+		simpad_clear_cs3_bit(VCC_5V_EN|EN1);
+		simpad_set_cs3_bit(VCC_3V_EN|EN0);
 		break;
 
 	default:
 		printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
 			__func__, state->Vcc);
-		clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
+		simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 		local_irq_restore(flags);
 		return -1;
 	}
@@ -110,7 +106,7 @@ static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
 static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
 	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-	set_cs3_bit(PCMCIA_RESET);
+	simpad_set_cs3_bit(PCMCIA_RESET);
 }
 
 static struct pcmcia_low_level simpad_pcmcia_ops = { 
Signature · 1 line
1.7.4.1
#3 lore raw

PATCH v2 2/3 ARM:simpad: Cleanup CS3 accessors.

Hi Jochen,

Quoted 8 lines · Jochen Friedrich

- prepend CS3 accessors by simpad_ to indicate they are specific to simpad devices.
- use spinlock to protect shadow register.
- implement 8 read-only pins.
- use readl/writel macros so barriers are used where necessary.
- register CS3 as GPIO controller with 24 pins (16 output only and 8 input only).

I think the basic-mmio-gpio driver (drivers/gpio/basic_mmio_gpio.c) should cover the GPIO controller portion of this (including the shadowing etc). This may need a few other bits (simpad_uart_pm(), simpad_map_io() etc) converting over to use the GPIO API though.

Jamie

#4 lore raw

PATCH v2 2/3 ARM:simpad: Cleanup CS3 accessors.

Hi Jamie,

Quoted 6 lines
Quoted 2 lines

- register CS3 as GPIO controller with 24 pins
(16 output only and 8 input only).

I think the basic-mmio-gpio driver (drivers/gpio/basic_mmio_gpio.c) should cover the GPIO controller portion of this (including the shadowing etc).

I'll have a look at this. Last time I checked, a single virtual address for a wite-only/read-only register pair was not supported, but this might have changed.

Quoted 2 lines

This may need a few other bits (simpad_uart_pm(), simpad_map_io() etc) converting over to use the GPIO API though.

Yes. In particular the UART and PCMCIA stuff needs to be converted. OTOH, this would make some board specific stuff obsolete and would help to reduce the arch/arm/* mess some more ;-).

Unfortunately, my Simpad doesn't have a PCMCIA slot, so it's hard for me to test this.

Thanks,
Jochen

#5 lore raw

PATCH v2 2/3 ARM:simpad: Cleanup CS3 accessors.

Quoted 5 lines · Jochen Friedrich

Unfortunately, my Simpad doesn't have a PCMCIA slot, so it's hard for me to test this.

Thanks,
Jochen

Hi Jochen,

I have a simpad with pcmcia slot so I could test it.

Bye Henning

#6 lore raw

PATCH v2 2/3 ARM:simpad: Cleanup CS3 accessors.

In reply to Jochen Friedrich
Quoted 5 lines · Jochen Friedrich

Hi Jamie,

Quoted 3 lines
Quoted 2 lines

- register CS3 as GPIO controller with 24 pins
(16 output only and 8 input only).

Quoted 7 lines
Quoted 3 lines

I think the basic-mmio-gpio driver (drivers/gpio/basic_mmio_gpio.c) should cover the GPIO controller portion of this (including the shadowing etc).

I'll have a look at this. Last time I checked, a single virtual address for a wite-only/read-only register pair was not supported, but this might have changed.

You should just be able to specify a single resource named "dat" and you'll be good to go. The current driver in mainline detects the number of GPIO's based on the register width (so it would detect 32 GPIO's in your case), but I have some patches posted on lkml that allow this to be overridden. These patches also add support for direction registers which it looks like you may need.

Jamie

#7 lore raw

PATCH v2 2/3 ARM:simpad: Cleanup CS3 accessors.

Hi Jamie,

Quoted 6 lines
Quoted 3 lines

I'll have a look at this. Last time I checked, a single virtual address for a wite-only/read-only register pair was not supported, but this might have changed.

You should just be able to specify a single resource named "dat" and you'll be good to go.

Not really. The "CS3" register on the simpad device is a 16bit register which hat 16 write-only pins and 8 independent read-only pins (no direction register, at all). It is implemented using 3 TTL logic chips. More information about this strange stuff can be found at:
http://opensimpad.org/index.php/Wiring#CS3_latch

I'm not sure if handling such a corner-case in the generic driver makes sense. However, i'm convinced that moving away from the simpad specific API to the GPIO API and removing all the platform specific UART and PCMCIA glue code by a generic GPIO one does make sense, in particular as the FDT has a nice way to assign GPIO functions to other subsystems.

Thanks,
Jochen

#8 lore raw

PATCH v2 2/3 ARM:simpad: Cleanup CS3 accessors.

Quoted 6 lines · Jochen Friedrich

Hi Jamie,

Quoted 4 lines
Quoted 3 lines

I'll have a look at this. Last time I checked, a single virtual address for a wite-only/read-only register pair was not supported, but this might have changed.

Quoted 7 lines
Quoted 2 lines

You should just be able to specify a single resource named "dat" and you'll be good to go.

Not really. The "CS3" register on the simpad device is a 16bit register which hat 16 write-only pins and 8 independent read-only pins (no direction register, at all). It is implemented using 3 TTL logic chips.

Ahh, I misread that bit.

Quoted 5 lines

More information about this strange stuff can be found at:
http://opensimpad.org/index.php/Wiring#CS3_latch

I'm not sure if handling such a corner-case in the generic driver makes sense.

I think I agree with you - it's more like two gpio_chip's using a single register and I would guess that it isn't too common a scenario.

Jamie

#9 lore raw

PATCH v2 3/3 ARM:simpad: add GPIO based device definitions.

In reply to Jochen Friedrich

Register LED, keyboard, polled keyboard and I2C platform devices based on GPIOs.

V2: Remove the legacy ARM LED code for simpad devices.

---
 arch/arm/mach-sa1100/Makefile      |    1 -
 arch/arm/mach-sa1100/leds-simpad.c |   97 ------------------------------------
 arch/arm/mach-sa1100/simpad.c      |   95 ++++++++++++++++++++++++++++++++++-
 3 files changed, 94 insertions(+), 99 deletions(-)
 delete mode 100644 arch/arm/mach-sa1100/leds-simpad.c
arch/arm/mach-sa1100/Makefile +0 -1
index 41252d2..0063178 100644
@@ -45,7 +45,6 @@ obj-$(CONFIG_SA1100_PLEB)		+= pleb.o
 obj-$(CONFIG_SA1100_SHANNON)		+= shannon.o
 
 obj-$(CONFIG_SA1100_SIMPAD)		+= simpad.o
-led-$(CONFIG_SA1100_SIMPAD)		+= leds-simpad.o
 
 # LEDs support
 obj-$(CONFIG_LEDS) += $(led-y)
arch/arm/mach-sa1100/leds-simpad.c deleted +0 -97

97 lines not on this page · raw message

arch/arm/mach-sa1100/simpad.c +94 -1

113 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#10 lore raw

PATCH v2 3/3 ARM:simpad: add GPIO based device definitions.

Quoted 4 lines · Jochen Friedrich

Register LED, keyboard, polled keyboard and I2C platform devices based on GPIOs.

V2: Remove the legacy ARM LED code for simpad devices.

Yeah, that looks like a good move! IMO, legacy ARM leds code should go away, as we have now proper generic LED subsystem, and the sooner we convert all legacy users to leds-class drivers, the better.

Quoted 7 lines
---
 arch/arm/mach-sa1100/Makefile      |    1 -
 arch/arm/mach-sa1100/leds-simpad.c |   97 ------------------------------------
 arch/arm/mach-sa1100/simpad.c      |   95 ++++++++++++++++++++++++++++++++++-
 3 files changed, 94 insertions(+), 99 deletions(-)
 delete mode 100644 arch/arm/mach-sa1100/leds-simpad.c

But, while removing leds-simpad.c, it seems you forgot to update both Makefile and corresponding entries in leds.[ch], so I suspect it will break build with CONFIG_LEDS=y.

And, while you're at it, it's probably a good idea to move all these LED changes into separate patch, and not to mix them with gpio-keys/i2c/etc devices registration.

Signature · 2 lines
Best regards,
Dmitry "MAD" Artamonow
#11 lore raw

PATCH v2 3/3 ARM:simpad: add GPIO based device definitions.

Hi Dmitry,

Quoted 9 lines
Quoted 5 lines
  arch/arm/mach-sa1100/Makefile      |    1 -
  arch/arm/mach-sa1100/leds-simpad.c |   97 ------------------------------------
  arch/arm/mach-sa1100/simpad.c      |   95 ++++++++++++++++++++++++++++++++++-
  3 files changed, 94 insertions(+), 99 deletions(-)

delete mode 100644 arch/arm/mach-sa1100/leds-simpad.c

But, while removing leds-simpad.c, it seems you forgot to update both Makefile and corresponding entries in leds.[ch], so I suspect it will break build with CONFIG_LEDS=y.

Thanks for the review. I'll update my patch.

Quoted 3 lines

And, while you're at it, it's probably a good idea to move all these LED changes into separate patch, and not to mix them with gpio-keys/i2c/etc devices registration.

I'll seperate the LED stuff from the rest of the patch.

Thanks,
Jochen