[Armadeus-commitlog] armadeus branch, master, updated. latestrelease-41-g91f1368
Brought to you by:
sszy
|
From: Julien B a. A. <ar...@us...> - 2009-08-26 12:51:02
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via 91f1368bf4a8bcdf1536fcd86e948a7ebda7929d (commit)
via ff4f5e528be1e844b9c0cb145cba27dc18709041 (commit)
from d578dd6cff8bcd072cd9f540296237ec5d3724bd (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 91f1368bf4a8bcdf1536fcd86e948a7ebda7929d
Author: Julien Boibessot <jul...@ar...>
Date: Wed Aug 26 14:50:09 2009 +0200
[DEMOS] Adds a small C program to show how to use IOCTL with GPIO driver
commit ff4f5e528be1e844b9c0cb145cba27dc18709041
Author: Julien Boibessot <jul...@ar...>
Date: Tue Aug 25 19:47:50 2009 +0200
[LINUX] gpio: correct deadlock bug + add an IOCTL for setting port Mode
-----------------------------------------------------------------------
Summary of changes:
target/demos/gpio/Makefile | 31 ++++++++++++
target/demos/gpio/blink_led.c | 98 ++++++++++++++++++++++++++++++++++++++
target/linux/modules/gpio/core.c | 43 +++++++++++------
target/linux/modules/gpio/core.h | 2 +
4 files changed, 159 insertions(+), 15 deletions(-)
create mode 100644 target/demos/gpio/Makefile
create mode 100644 target/demos/gpio/blink_led.c
diff --git a/target/demos/gpio/Makefile b/target/demos/gpio/Makefile
new file mode 100644
index 0000000..0e11c39
--- /dev/null
+++ b/target/demos/gpio/Makefile
@@ -0,0 +1,31 @@
+
+ifneq ($(CC),)
+# Locally compiled:
+ARMADEUS_BASE_DIR:=$(shell pwd)/../../..
+include $(ARMADEUS_BASE_DIR)/Makefile.in
+STAGING_DIR:=$(ARMADEUS_BUILD_DIR)/staging_dir/
+INSTALL_DIR:=$(ARMADEUS_ROOTFS_DIR)/usr/bin/
+CC=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-gcc
+DEFINES=-D$(ARMADEUS_BOARD_NAME)
+endif
+
+EXEC_NAME = blink_led
+
+default: $(EXEC_NAME)
+
+all: $(EXEC_NAME)
+
+$(EXEC_NAME): blink_led.c
+ $(CC) $(CFLAGS) $(DEFINES) -Wall -o $@ $^
+
+clean:
+ rm -rf $(EXEC_NAME)
+ rm -rf *.o
+
+install:
+ cp $(EXEC_NAME) $(INSTALL_DIR)/
+
+uninstall:
+ rm -f $(INSTALL_DIR)/$(EXEC_NAME)
+
+.PHONY: clean install uninstall
diff --git a/target/demos/gpio/blink_led.c b/target/demos/gpio/blink_led.c
new file mode 100644
index 0000000..8281e3b
--- /dev/null
+++ b/target/demos/gpio/blink_led.c
@@ -0,0 +1,98 @@
+/*
+ * Small program to show how to use IOCTL with GPIO driver
+ *
+ * Copyright (C) 2009 Julien Boibessot <jul...@ar...>
+ * Inspired by original example from S. Falck
+ * Armadeus Project / Armadeus Systems
+ *
+ * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <linux/ppdev.h>
+
+#ifdef apf9328
+#define LED_GPIO_PORT "/dev/gpio/portD"
+#define LED_PIN 31
+#elif apf27
+#define LED_GPIO_PORT "/dev/gpio/portF"
+#define LED_PIN 14
+#else
+#error Board not defined
+#endif
+
+#define GPIORDDIRECTION _IOR(PP_IOCTL, 0xF0, int)
+#define GPIOWRDIRECTION _IOW(PP_IOCTL, 0xF1, int)
+#define GPIORDDATA _IOR(PP_IOCTL, 0xF2, int)
+#define GPIOWRDATA _IOW(PP_IOCTL, 0xF3, int)
+#define GPIORDMODE _IOR(PP_IOCTL, 0xF4, int)
+#define GPIOWRMODE _IOW(PP_IOCTL, 0xF5, int)
+
+int main(int argc, char **argv)
+{
+ int fd;
+ int i;
+ int portval;
+ unsigned int count = 10;
+
+ if (argc == 2) {
+ count = atoi(argv[1]);
+ }
+
+ printf("Toggling LED %d times \n", count);
+
+ printf("Opening %s\n", LED_GPIO_PORT);
+ if ((fd = open(LED_GPIO_PORT, O_RDWR)) < 0) {
+ perror("Error");
+ exit(1);
+ }
+
+ /* Set LED PIN as GPIO; read/modify/write */
+ ioctl(fd, GPIORDMODE, &portval);
+ portval |= (1 << LED_PIN);
+ ioctl(fd, GPIOWRMODE, &portval);
+
+ /* Set LED GPIO as output; read/modify/write */
+ ioctl(fd, GPIORDDIRECTION, &portval);
+ portval |= (1 << LED_PIN);
+ ioctl(fd, GPIOWRDIRECTION, &portval);
+
+ /* Blink the LED */
+ for (i = 0; i < count; i++) {
+ printf("Led ON\n"); /* pin <- 0 */
+ ioctl(fd, GPIORDDATA, &portval);
+ portval &= ~(1 << LED_PIN);
+ ioctl(fd, GPIOWRDATA, &portval);
+
+ sleep(1);
+
+ printf("Led OFF\n"); /* pin <- 1 */
+ ioctl(fd, GPIORDDATA, &portval);
+ portval |= (1 << LED_PIN);
+ ioctl(fd, GPIOWRDATA, &portval);
+
+ sleep(1);
+ }
+
+ close(fd);
+ exit(0);
+}
diff --git a/target/linux/modules/gpio/core.c b/target/linux/modules/gpio/core.c
index 9e21b25..bc35029 100755
--- a/target/linux/modules/gpio/core.c
+++ b/target/linux/modules/gpio/core.c
@@ -381,7 +381,7 @@ static unsigned int getPortDir(unsigned int aPort)
{
unsigned int port_value = 0;
- /* Get the status of the gpio direction registers TBDNICO */
+ /* Get the status of the GPIO direction registers */
port_value = __raw_readl(VA_GPIO_BASE + MXC_DDIR(aPort));
return port_value;
@@ -626,11 +626,10 @@ static int armadeus_gpio_dev_release(struct inode *inode, struct file *file)
}
/* Handling of IOCTL calls */
-int armadeus_gpio_dev_ioctl( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int armadeus_gpio_dev_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- int err = 0; int ret = 0;
- int value=0;
+ int err = 0, ret = 0, value = 0;
unsigned int minor;
pr_debug(DRIVER_NAME " ## IOCTL received: (0x%x) ##\n", cmd);
@@ -646,7 +645,7 @@ int armadeus_gpio_dev_ioctl( struct inode *inode, struct file *filp,
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
- err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
+ err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
if (err)
return -EFAULT;
@@ -654,11 +653,13 @@ int armadeus_gpio_dev_ioctl( struct inode *inode, struct file *filp,
/* Obtain exclusive access */
if (down_interruptible(&gpio_sema))
return -ERESTARTSYS;
+
/* Extract and test minor */
minor = MINOR(inode->i_rdev);
if (minor < FULL_PORTD_MINOR) {
- printk("IOCTLs are only available on minors representing full port access!\n");
- return -EFAULT;
+ printk("IOCTLs are only available on 'full port' minors !\n");
+ ret = -EFAULT;
+ goto out;
}
switch (cmd) {
@@ -666,31 +667,44 @@ int armadeus_gpio_dev_ioctl( struct inode *inode, struct file *filp,
value = getPortDir(MAX_MINOR - minor);
ret = __put_user(value, (unsigned int *)arg);
break;
-
+
case GPIOWRDIRECTION:
ret = __get_user(value, (unsigned int *)arg);
-
if (ret == 0) {
setPortDir(MAX_MINOR - minor, value);
}
break;
-
+
case GPIORDDATA:
value = readFromPort(MAX_MINOR - minor);
ret = __put_user(value, (unsigned int *)arg);
break;
-
+
case GPIOWRDATA:
ret = __get_user(value, (unsigned int *)arg);
if (ret == 0) {
writeOnPort(MAX_MINOR - minor, value);
}
break;
-
+
+ case GPIORDMODE:
+ value = __raw_readl(VA_GPIO_BASE + MXC_GIUS(MAX_MINOR - minor));
+ ret = __put_user(value, (unsigned int *)arg);
+ break;
+
+ case GPIOWRMODE:
+ ret = __get_user(value, (unsigned int *)arg);
+ if (ret == 0) {
+ setPortMode(MAX_MINOR - minor, value);
+ }
+ break;
+
default:
- return -ENOTTY;
+ printk("IOCTL not supported\n");
+ ret = -ENOTTY;
break;
}
+out:
/* Release exclusive access */
up(&gpio_sema);
@@ -727,7 +741,6 @@ static int armadeus_gpio_proc_read(char *buffer, char **start, off_t offset,
return -ERESTARTSYS;
switch (settings->type) {
-
case MODE:
port_status = __raw_readl(VA_GPIO_BASE + MXC_GIUS(port_ID));
break;
diff --git a/target/linux/modules/gpio/core.h b/target/linux/modules/gpio/core.h
index 68cbe42..2a243aa 100755
--- a/target/linux/modules/gpio/core.h
+++ b/target/linux/modules/gpio/core.h
@@ -32,6 +32,8 @@
#define GPIOWRDIRECTION _IOW(PP_IOCTL, 0xF1, int)
#define GPIORDDATA _IOR(PP_IOCTL, 0xF2, int)
#define GPIOWRDATA _IOW(PP_IOCTL, 0xF3, int)
+#define GPIORDMODE _IOR(PP_IOCTL, 0xF4, int)
+#define GPIOWRMODE _IOW(PP_IOCTL, 0xF5, int)
/* Pretend we're PPDEV for IOCTL */
#include <linux/ppdev.h>
hooks/post-receive
--
armadeus
|