1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Lorenzo Miori 2015-01-04 15:13:41 +01:00 committed by Gerrit Rockbox
parent 6879dec6ec
commit f35d63bc21
5 changed files with 139 additions and 29 deletions

View file

@ -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);
}
}

View file

@ -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

View file

@ -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 */

View file

@ -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();

View file

@ -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();