From 40159abb0eaff29e2718dfb6bfa7a0e8eb6f3ea6 Mon Sep 17 00:00:00 2001
From: Michal Demin <michaldemin@gmail.com>
Date: Sat, 29 Jan 2011 17:28:02 +0100
Subject: [PATCH 1/2] Add GPIO driver for Calypso.

Signed-off-by: Michal Demin <michaldemin@gmail.com>
---
 src/target/firmware/board/compal_e86/init.c |   13 +--
 src/target/firmware/board/compal_e88/init.c |   11 +--
 src/target/firmware/board/compal_e99/init.c |   13 +--
 src/target/firmware/board/gta0x/init.c      |    9 +--
 src/target/firmware/calypso/Makefile        |    2 +-
 src/target/firmware/calypso/gpio.c          |  129 +++++++++++++++++++++++++++
 src/target/firmware/include/calypso/gpio.h  |    7 ++
 src/target/firmware/include/gpio.h          |   34 +++++++
 8 files changed, 185 insertions(+), 33 deletions(-)
 create mode 100644 src/target/firmware/calypso/gpio.c
 create mode 100644 src/target/firmware/include/calypso/gpio.h
 create mode 100644 src/target/firmware/include/gpio.h

diff --git a/src/target/firmware/board/compal_e86/init.c b/src/target/firmware/board/compal_e86/init.c
index 92f0e3b..b2d33f3 100644
--- a/src/target/firmware/board/compal_e86/init.c
+++ b/src/target/firmware/board/compal_e86/init.c
@@ -30,6 +30,7 @@
 #include <board.h>
 #include <keypad.h>
 #include <console.h>
+#include <gpio.h>
 #include <flash/cfi_flash.h>
 
 #include <calypso/irq.h>
@@ -46,8 +47,6 @@
 #include <rf/trf6151.h>
 #include <display.h>
 
-#define ARMIO_LATCH_OUT 0xfffe4802
-#define ARMIO_CNTL_REG	0xfffe4804
 #define ASIC_CONF_REG	0xfffef008
 
 static void board_io_init(void)
@@ -64,15 +63,11 @@ static void board_io_init(void)
 
 	/* LCD Set I/O(3) to output mode and enable C140 backlight (IO1) */
 	/* FIXME: Put the display backlight control to backlight.c */
-	reg = readw(ARMIO_CNTL_REG);
-	reg &= ~( (1 << 3) | (1 << 1));
-	writew(reg, ARMIO_CNTL_REG);
+	gpio_config(GPIO_PIN(3) | GPIO_PIN(1), GPIO_MODE_OUTPUT);
 
 	/* LCD Set I/O(3) output low */
-	reg = readw(ARMIO_LATCH_OUT);
-	reg &= ~(1 << 3);
-	reg |= (1 << 1);
-	writew(reg, ARMIO_LATCH_OUT);
+	gpio_write(GPIO_PIN(1), GPIO_SET);
+	gpio_write(GPIO_PIN(3), GPIO_RESET);
 }
 
 void board_init(void)
diff --git a/src/target/firmware/board/compal_e88/init.c b/src/target/firmware/board/compal_e88/init.c
index 5a4f882..7c82b7b 100644
--- a/src/target/firmware/board/compal_e88/init.c
+++ b/src/target/firmware/board/compal_e88/init.c
@@ -29,6 +29,7 @@
 #include <board.h>
 #include <keypad.h>
 #include <console.h>
+#include <gpio.h>
 #include <flash/cfi_flash.h>
 
 #include <calypso/irq.h>
@@ -46,8 +47,6 @@
 #include <rf/trf6151.h>
 #include <display.h>
 
-#define ARMIO_LATCH_OUT 0xfffe4802
-#define ARMIO_CNTL_REG	0xfffe4804
 #define ASIC_CONF_REG	0xfffef008
 
 static void board_io_init(void)
@@ -64,14 +63,10 @@ static void board_io_init(void)
 	writew(reg, ASIC_CONF_REG);
 
 	/* LCD Set I/O(3) to output mode */
-	reg = readw(ARMIO_CNTL_REG);
-	reg &= ~(1 << 3);
-	writew(reg, ARMIO_CNTL_REG);
+	gpio_config(GPIO_PIN(3), GPIO_MODE_OUTPUT);
 
 	/* LCD Set I/O(3) output low */
-	reg = readw(ARMIO_LATCH_OUT);
-	reg &= ~(1 << 3);
-	writew(reg, ARMIO_LATCH_OUT);
+	gpio_write(GPIO_PIN(3), GPIO_RESET);
 }
 
 void board_init(void)
diff --git a/src/target/firmware/board/compal_e99/init.c b/src/target/firmware/board/compal_e99/init.c
index 47725a9..a8b8759 100644
--- a/src/target/firmware/board/compal_e99/init.c
+++ b/src/target/firmware/board/compal_e99/init.c
@@ -30,6 +30,7 @@
 #include <board.h>
 #include <keypad.h>
 #include <console.h>
+#include <gpio.h>
 #include <flash/cfi_flash.h>
 
 #include <calypso/irq.h>
@@ -46,8 +47,6 @@
 #include <rf/trf6151.h>
 #include <display.h>
 
-#define ARMIO_LATCH_OUT 0xfffe4802
-#define ARMIO_CNTL_REG	0xfffe4804
 #define ASIC_CONF_REG	0xfffef008
 
 static void board_io_init(void)
@@ -64,15 +63,11 @@ static void board_io_init(void)
 
 	/* LCD Set I/O(3) to output mode and enable C155 backlight (IO1) */
 	/* FIXME: Put the display backlight control to backlight.c */
-	reg = readw(ARMIO_CNTL_REG);
-	reg &= ~( (1 << 3) | (1 << 1));
-	writew(reg, ARMIO_CNTL_REG);
+	gpio_config(GPIO_PIN(3) | GPIO_PIN(1), GPIO_MODE_OUTPUT);
 
 	/* LCD Set I/O(3) output low */
-	reg = readw(ARMIO_LATCH_OUT);
-	reg &= ~(1 << 3);
-	reg |= (1 << 1);
-	writew(reg, ARMIO_LATCH_OUT);
+	gpio_write(GPIO_PIN(1), GPIO_SET);
+	gpio_write(GPIO_PIN(3), GPIO_RESET);
 }
 
 void board_init(void)
diff --git a/src/target/firmware/board/gta0x/init.c b/src/target/firmware/board/gta0x/init.c
index 573b763..33e39ad 100644
--- a/src/target/firmware/board/gta0x/init.c
+++ b/src/target/firmware/board/gta0x/init.c
@@ -29,6 +29,7 @@
 #include <board.h>
 #include <keypad.h>
 #include <console.h>
+#include <gpio.h>
 #include <flash/cfi_flash.h>
 
 #include <calypso/irq.h>
@@ -64,14 +65,10 @@ static void board_io_init(void)
 	writew(reg, ASIC_CONF_REG);
 
 	/* LCD Set I/O(3) to output mode */
-	reg = readw(ARMIO_CNTL_REG);
-	reg &= ~(1 << 3);
-	writew(reg, ARMIO_CNTL_REG);
+	gpio_config(GPIO_PIN(3), GPIO_MODE_OUTPUT);
 
 	/* LCD Set I/O(3) output low */
-	reg = readw(ARMIO_LATCH_OUT);
-	reg &= ~(1 << 3);
-	writew(reg, ARMIO_LATCH_OUT);
+	gpio_write(GPIO_PIN(3), GPIO_RESET);
 }
 
 void board_init(void)
diff --git a/src/target/firmware/calypso/Makefile b/src/target/firmware/calypso/Makefile
index 8fcad7b..2bf1b63 100644
--- a/src/target/firmware/calypso/Makefile
+++ b/src/target/firmware/calypso/Makefile
@@ -1,4 +1,4 @@
 
 LIBRARIES+=calypso
 calypso_DIR=calypso
-calypso_SRCS=arm.c clock.c delay.c dma.c dsp.c du.c i2c.c irq.c rtc.c sim.c spi.c tpu.c tsp.c keypad.c misc.c timer.c backlight.c uart.c uwire.c
+calypso_SRCS=arm.c clock.c delay.c dma.c dsp.c du.c i2c.c irq.c rtc.c sim.c spi.c tpu.c tsp.c keypad.c gpio.c misc.c timer.c backlight.c uart.c uwire.c
diff --git a/src/target/firmware/calypso/gpio.c b/src/target/firmware/calypso/gpio.c
new file mode 100644
index 0000000..109d67b
--- /dev/null
+++ b/src/target/firmware/calypso/gpio.c
@@ -0,0 +1,129 @@
+/* Driver for the GPIOs on the TI Calypso */
+
+/* (C) 2010 by Michal Demin <michal.demin@gmail.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <defines.h>
+#include <debug.h>
+#include <delay.h>
+#include <memory.h>
+#include <keypad.h>
+#include <gpio.h>
+
+#include <calypso/keypad.h>
+#include <calypso/gpio.h>
+
+
+#define ARMIO_LATCH_IN  0xfffe4800
+#define ARMIO_LATCH_OUT 0xfffe4802
+#define ARMIO_CNTL_REG  0xfffe4804
+
+#define GPIO_EVENT_MODE_REG 0xfffe4814
+
+
+static gpio_handler_t gpio_handler = NULL;
+
+void gpio_isr(void)
+{
+	if (gpio_handler) {
+		gpio_handler();
+	}
+}
+
+void gpio_set_handler(gpio_handler_t handler, uint16_t gpio, enum gpio_int_mode m)
+{
+	uint16_t reg;
+
+	if (m >= GPIO_INT_BOTH) {
+		printd("Unsuported gpio interrupt mode \n");
+		return;
+	}
+
+	gpio_config(GPIO_PIN(gpio), GPIO_MODE_INPUT);
+
+	reg = 1;
+	reg |= (gpio & 0xf) << 1;
+	reg |= (m & 1) << 6;
+
+	printd("event mode %02x\n", reg);
+	writew(reg, GPIO_EVENT_MODE_REG);
+
+	gpio_handler = handler;
+
+	keypad_unmask_irq(GPIO_INT);
+}
+
+void gpio_config(uint16_t pins, enum gpio_io_mode m)
+{
+	uint16_t reg;
+
+	reg = readw(ARMIO_CNTL_REG);
+
+	if (m == GPIO_MODE_INPUT) {
+		reg |= pins;
+	} else {
+		reg &= ~pins;
+	}
+
+	writew(reg, ARMIO_CNTL_REG);
+}
+
+void gpio_write(uint16_t pins, enum gpio_state s)
+{
+	uint16_t reg;
+	uint16_t tmp;
+
+	reg = readw(ARMIO_LATCH_OUT);
+
+	if (s == GPIO_SET) {
+		reg |= pins;
+	} else if (s == GPIO_RESET) {
+		reg &= ~pins;
+	} else if (s == GPIO_TOGGLE) {
+		/* new states for all pins */
+		tmp = reg ^ pins;
+
+		/* remove states for pins */
+		reg &= ~pins;
+
+		/* apply new states only for pins */
+		reg = tmp & pins;
+	} else {
+		printd("GPIO write type %d unknown\n", s);
+	}
+
+	writew(reg, ARMIO_LATCH_OUT);
+}
+
+int gpio_read(uint16_t pins)
+{
+	uint16_t reg;
+
+	reg = readw(ARMIO_LATCH_IN);
+
+	if (reg & pins)
+		return GPIO_SET;
+
+	return GPIO_RESET;
+}
+
diff --git a/src/target/firmware/include/calypso/gpio.h b/src/target/firmware/include/calypso/gpio.h
new file mode 100644
index 0000000..f165675
--- /dev/null
+++ b/src/target/firmware/include/calypso/gpio.h
@@ -0,0 +1,7 @@
+#ifndef _CALYPSO_GPIO_H
+#define _CALYPSO_GPIO_H
+
+void gpio_isr(void);
+
+#endif
+
diff --git a/src/target/firmware/include/gpio.h b/src/target/firmware/include/gpio.h
new file mode 100644
index 0000000..5a17d3b
--- /dev/null
+++ b/src/target/firmware/include/gpio.h
@@ -0,0 +1,34 @@
+#ifndef _GPIO_H
+#define _GPIO_H
+
+#include <stdint.h>
+
+#define GPIO_PIN(x) (1 << (x))
+
+enum gpio_io_mode {
+	GPIO_MODE_OUTPUT = 0,
+	GPIO_MODE_INPUT = 1
+};
+
+enum gpio_int_mode {
+	GPIO_INT_FALLING = 0,
+	GPIO_INT_RISING,
+	GPIO_INT_BOTH
+};
+
+enum gpio_state {
+	GPIO_RESET = 0,
+	GPIO_SET = 1,
+	/* special case for write */
+	GPIO_TOGGLE = 2
+};
+
+void gpio_config(uint16_t pins, enum gpio_io_mode m);
+void gpio_write(uint16_t pins, enum gpio_state s);
+int gpio_read(uint16_t pins);
+
+typedef void (*gpio_handler_t)(void);
+
+void gpio_set_handler(gpio_handler_t handler, uint16_t gpio, enum gpio_int_mode m);
+
+#endif
-- 
1.7.3.1

