summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Miori <memoryS60@gmail.com>2015-01-04 15:13:41 +0100
committerGerrit Rockbox <gerrit@rockbox.org>2015-01-29 20:28:59 +0100
commitf35d63bc216e59ba1eecfb138e23915521716128 (patch)
tree2c0566993b6a417850355dea8c3ed202ac44e2fd
parent6879dec6ece3c0797c5df16c9dd494b3dc3a1329 (diff)
downloadrockbox-f35d63b.tar.gz
rockbox-f35d63b.tar.bz2
rockbox-f35d63b.zip
ypr0/ypr1: GPIO handling API refactoring
The GPIO APIs for ypr0 and ypr1 targets was messy, requiring a direct communication via several ioctls calls. Since it is planned to add support to other devices, more GPIO are going to be used. For that reason the functions shall be clear and easy to use. Change-Id: Ia2304335e1fed1305cc2c4320bd4c097e13079be
-rw-r--r--firmware/target/hosted/samsungypr/gpio-ypr.c94
-rw-r--r--firmware/target/hosted/samsungypr/gpio-ypr.h25
-rw-r--r--firmware/target/hosted/samsungypr/ypr0/button-ypr0.c27
-rw-r--r--firmware/target/hosted/samsungypr/ypr0/system-ypr0.c7
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/button-ypr1.c15
5 files changed, 139 insertions, 29 deletions
diff --git a/firmware/target/hosted/samsungypr/gpio-ypr.c b/firmware/target/hosted/samsungypr/gpio-ypr.c
index e5abc4cdc9..d6a19da34f 100644
--- a/firmware/target/hosted/samsungypr/gpio-ypr.c
+++ b/firmware/target/hosted/samsungypr/gpio-ypr.c
@@ -8,7 +8,7 @@
*
* Module wrapper for GPIO, using kernel module of Samsung YP-R0/YP-R1
*
- * Copyright (c) 2011 Lorenzo Miori
+ * Copyright (c) 2011-2015 Lorenzo Miori
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,16 +23,42 @@
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
-#include <gpio-ypr.h> /* includes common ioctl device definitions */
#include <sys/ioctl.h>
+#include "panic.h"
+#include "gpio-ypr.h" /* includes common ioctl device definitions */
+
static int gpio_dev = 0;
+#ifdef GPIO_DEBUG
+// 3 banks of 32 pins
+static const char *pin_use[3][32];
+
+void gpio_acquire(unsigned bank, unsigned pin, const char *name)
+{
+ if(pin_use[bank][pin] != NULL && pin_use[bank][pin] != name)
+ panicf("acquire B%dP%02d for %s, was %s!", bank, pin, name, pin_use[bank][pin]);
+ pin_use[bank][pin] = name;
+}
+
+void gpio_release(unsigned bank, unsigned pin, const char *name)
+{
+ if(pin_use[bank][pin] != NULL && pin_use[bank][pin] != name)
+ panicf("release B%dP%02d for %s: was %s!", bank, pin, name, pin_use[bank][pin]);
+ pin_use[bank][pin] = NULL;
+}
+
+const char *gpio_blame(unsigned bank, unsigned pin)
+{
+ return pin_use[bank][pin];
+}
+#endif
+
void gpio_init(void)
{
gpio_dev = open(GPIO_DEVICE, O_RDONLY);
if (gpio_dev < 0)
- printf("GPIO device open error!");
+ panicf("GPIO device open error!");
}
void gpio_close(void)
@@ -41,8 +67,68 @@ void gpio_close(void)
close(gpio_dev);
}
-int gpio_control(int request, int num, int mode, int val)
+static int gpio_control(int request, int num, int mode, int val)
{
struct gpio_info r = { .num = num, .mode = mode, .val = val, };
return ioctl(gpio_dev, request, &r);
}
+
+void gpio_set_iomux(int pin, int iomux)
+{
+ if (gpio_control(DEV_CTRL_GPIO_SET_MUX, pin, iomux, 0) != 0)
+ {
+ panicf("Unable to set iomux to pin %d", pin);
+ }
+}
+
+void gpio_free_iomux(int pin, int iomux)
+{
+ if (gpio_control(DEV_CTRL_GPIO_UNSET_MUX, pin, iomux, 0) != 0)
+ {
+ panicf("Unable to free iomux to pin %d", pin);
+ }
+}
+
+void gpio_set_pad(int pin, int type)
+{
+ if (gpio_control(DEV_CTRL_GPIO_SET_TYPE, pin, type, 0) != 0)
+ {
+ panicf("Unable to set pad to pin %d", pin);
+ }
+}
+
+void gpio_direction_output(int pin)
+{
+ if (gpio_control(DEV_CTRL_GPIO_SET_OUTPUT, pin, 0, 0) != 0)
+ {
+ panicf("Unable to set output direction to pin %d", pin);
+ }
+}
+
+void gpio_direction_input(int pin)
+{
+ if (gpio_control(DEV_CTRL_GPIO_SET_INPUT, pin, 0, 0) != 0)
+ {
+ panicf("Unable to set input direction to pin %d", pin);
+ }
+}
+
+bool gpio_get(int pin)
+{
+ return gpio_control(DEV_CTRL_GPIO_GET_VAL, pin, 0, 0);
+}
+
+void gpio_set(int pin, bool value)
+{
+ int ret = -1;
+
+ if (value)
+ ret = gpio_control(DEV_CTRL_GPIO_SET_HIGH, pin, 0, 0);
+ else
+ ret = gpio_control(DEV_CTRL_GPIO_SET_LOW, pin, 0, 0);
+
+ if (ret != 0)
+ {
+ panicf("Unable to set input direction to pin %d", pin);
+ }
+}
diff --git a/firmware/target/hosted/samsungypr/gpio-ypr.h b/firmware/target/hosted/samsungypr/gpio-ypr.h
index c10991e20c..c7214de6c0 100644
--- a/firmware/target/hosted/samsungypr/gpio-ypr.h
+++ b/firmware/target/hosted/samsungypr/gpio-ypr.h
@@ -24,6 +24,20 @@
/* Specifies device name and ioctl magic */
#include "gpio-target.h"
#include "sys/ioctl.h"
+#include "stdbool.h"
+
+// set to debug pinctrl use
+#define GPIO_DEBUG
+
+#ifdef GPIO_DEBUG
+void imx233_pinctrl_acquire(unsigned bank, unsigned pin, const char *name);
+void imx233_pinctrl_release(unsigned bank, unsigned pin, const char *name);
+const char *imx233_pinctrl_blame(unsigned bank, unsigned pin);
+#else
+#define imx233_pinctrl_acquire(...)
+#define imx233_pinctrl_release(...)
+#define imx233_pinctrl_get_pin_use(...) NULL
+#endif
struct gpio_info {
int num;
@@ -193,9 +207,16 @@ enum
PAD_CTL_DRV_VOT_HIGH = 0x1 << 13,
};
+/* Driver-related functions */
void gpio_init(void);
void gpio_close(void);
-int gpio_control_struct(int request, struct gpio_info pin);
-int gpio_control(int request, int num, int mode, int val);
+/* Exported API */
+void gpio_set_iomux(int pin, int iomux);
+void gpio_free_iomux(int pin, int iomux);
+void gpio_set_pad(int pin, int type);
+void gpio_direction_output(int pin);
+void gpio_direction_input(int pin);
+bool gpio_get(int pin);
+void gpio_set(int pin, bool value);
#endif
diff --git a/firmware/target/hosted/samsungypr/ypr0/button-ypr0.c b/firmware/target/hosted/samsungypr/ypr0/button-ypr0.c
index 08aacd18c6..860ad50cae 100644
--- a/firmware/target/hosted/samsungypr/ypr0/button-ypr0.c
+++ b/firmware/target/hosted/samsungypr/ypr0/button-ypr0.c
@@ -31,31 +31,31 @@ int button_read_device(void)
int key = BUTTON_NONE;
/* Check for all the keys */
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_USER_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_USER_KEY)) {
key |= BUTTON_USER;
}
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_CENTRAL_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_CENTRAL_KEY)) {
key |= BUTTON_SELECT;
}
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_UP_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_UP_KEY)) {
key |= BUTTON_UP;
}
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_DOWN_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_DOWN_KEY)) {
key |= BUTTON_DOWN;
}
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_LEFT_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_LEFT_KEY)) {
key |= BUTTON_LEFT;
}
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_RIGHT_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_RIGHT_KEY)) {
key |= BUTTON_RIGHT;
}
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_MENU_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_MENU_KEY)) {
key |= BUTTON_MENU;
}
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_BACK_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_BACK_KEY)) {
key |= BUTTON_BACK;
}
- if (gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_POWER_KEY, 0, 0)) {
+ if (gpio_get(GPIO_POWER_KEY)) {
key |= BUTTON_POWER;
}
@@ -65,14 +65,15 @@ int button_read_device(void)
bool headphones_inserted(void)
{
/* GPIO low - 0 - means headphones inserted */
- return !gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_HEADPHONE_SENSE, 0, 0);
+ return !gpio_get(GPIO_HEADPHONE_SENSE);
}
void button_init_device(void)
{
/* Setup GPIO pin for headphone sense, copied from OF */
- gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_HEADPHONE_SENSE, CONFIG_SION, PAD_CTL_47K_PU);
- gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_HEADPHONE_SENSE, CONFIG_SION, PAD_CTL_47K_PU);
+ gpio_set_iomux(GPIO_HEADPHONE_SENSE, CONFIG_GPIO);
+ gpio_set_pad(GPIO_HEADPHONE_SENSE, PAD_CTL_47K_PU);
+ gpio_direction_input(GPIO_HEADPHONE_SENSE);
/* No need to initialize any GPIO pin, since this is done loading the r0Btn module */
}
@@ -82,6 +83,6 @@ void button_init_device(void)
void button_close_device(void)
{
/* Don't know the precise meaning, but it's done as in the OF, so copied there */
- gpio_control(DEV_CTRL_GPIO_UNSET_MUX, GPIO_HEADPHONE_SENSE, CONFIG_SION, 0);
+ gpio_free_iomux(GPIO_HEADPHONE_SENSE, CONFIG_GPIO);
}
#endif /* BUTTON_DRIVER_CLOSE */
diff --git a/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c b/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c
index 9cc307073b..2544174252 100644
--- a/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c
+++ b/firmware/target/hosted/samsungypr/ypr0/system-ypr0.c
@@ -88,7 +88,7 @@ bool hostfs_present(IF_MD_NONVOID(int drive))
{
#ifdef HAVE_MULTIDRIVE
if (drive > 0) /* Active LOW */
- return (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_SD_SENSE, 0, 0));
+ return (!gpio_get(GPIO_SD_SENSE));
else
#endif
return true; /* internal: always present */
@@ -229,8 +229,9 @@ static void NORETURN_ATTR sd_thread(void)
int hostfs_init(void)
{
/* Setup GPIO pin for microSD sense, copied from OF */
- gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_SD_SENSE, CONFIG_DEFAULT, 0);
- gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_SD_SENSE, CONFIG_DEFAULT, 0);
+ gpio_set_iomux(GPIO_SD_SENSE, CONFIG_DEFAULT);
+ gpio_set_pad(GPIO_SD_SENSE, PAD_CTL_SRE_SLOW);
+ gpio_direction_input(GPIO_SD_SENSE);
#ifdef HAVE_MULTIDRIVE
if (storage_present(IF_MD(1)))
mount_sd();
diff --git a/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c
index d12b8486b6..26755716f4 100644
--- a/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c
+++ b/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c
@@ -45,13 +45,13 @@ int button_read_device(int *data)
struct mcs5000_raw_data touchpad_data;
/* Check for all the keys */
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_VOL_UP_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_VOL_UP_KEY)) {
key |= BUTTON_VOL_UP;
}
- if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_VOL_DOWN_KEY, 0, 0)) {
+ if (!gpio_get(GPIO_VOL_DOWN_KEY)) {
key |= BUTTON_VOL_DOWN;
}
- if (gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_POWER_KEY, 0, 0)) {
+ if (gpio_get(GPIO_POWER_KEY)) {
key |= BUTTON_POWER;
}
@@ -99,7 +99,7 @@ void touchscreen_enable_device(bool en)
bool headphones_inserted(void)
{
/* GPIO low - 0 - means headphones inserted */
- return !gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_HEADPHONE_SENSE, 0, 0);
+ return !gpio_get(GPIO_HEADPHONE_SENSE);
}
void button_init_device(void)
@@ -107,8 +107,9 @@ void button_init_device(void)
/* Setup GPIO pin for headphone sense, copied from OF
* Pins for the other buttons are already set up by OF button module
*/
- gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_HEADPHONE_SENSE, 4, 0);
- gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_HEADPHONE_SENSE, 4, 0);
+ gpio_set_iomux(GPIO_HEADPHONE_SENSE, CONFIG_ALT4);
+ gpio_set_pad(GPIO_HEADPHONE_SENSE, PAD_CTL_SRE_SLOW);
+ gpio_direction_input(GPIO_HEADPHONE_SENSE);
/* Turn on touchscreen */
mcs5000_init();
@@ -120,7 +121,7 @@ void button_init_device(void)
/* I'm not sure it's called at shutdown...give a check! */
void button_close_device(void)
{
- gpio_control(DEV_CTRL_GPIO_UNSET_MUX, GPIO_HEADPHONE_SENSE, 0, 0);
+ gpio_free_iomux(GPIO_HEADPHONE_SENSE, CONFIG_ALT4);
/* Turn off touchscreen device */
mcs5000_shutdown();