http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/archive/2005/09/msg00117.html

Re: [microblaze-uclinux] GPIO in /dev/gpio



I'm working on GPIO as well.  I have been using the following in
vendors/Xilinx/uclinux-auto/Makefile

ifdef CONFIG_XILINX_GPIO
DEVICES +=      \
        gpio,c,10,185
endif

Note that you do not need multiple entries in /dev/ for multiple gpios
instances since the GPIO adapter multiplexes accesses to more than 1 GPIO. 
I have used the attached program to successfully read GPIO but don't have
writes working yet.  I can use xmd to successfully write the gpios so I
think its a software issue somewhere.

The adapter in the current version of uclinux is much different than the one
in the latest PPC tree.  Nothing jumps out at me as an issue though:
http://ppc.bkbits.net:8080/linuxppc-2.4/src/drivers/char//xilinx_gpio?nav=src/drivers/char/

Let me know if you are successful so we can feed these changes back into the
distro.

Paul

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/ibm_ocp_gpio.h>

static void
usage(char *argv0)
{
	char *basename = strrchr(argv0, '/');
	if (!basename)
		basename = argv0;

	fprintf(stderr,
		"Usage: %s [-d DEVICE] [-n DEV_INSTANCE] [-m MASK] COMMAND\n"
		"  where COMMAND is one of:\n"
		"    -i           Input value from GPIO and print it\n"
		"    -o VALUE     Output value to GPIO\n"
		"    -t VALUE     Set tristate to value\n"
		"    -c           Cylon test pattern\n"
		"    -k           KIT test pattern\n"
		"  DEVICE indicates which GPIO driver to talk to (default is /dev/gpio)\n"
		"  DEV_INSTANCE indicates which GPIO interface to talk to (default is
zero)\n"
		"  MASK is ANDed with the value (default is all ones)\n"
		, basename);

	exit(2);
}

static const unsigned long cylon[] = {
	0x80000000, 0x40000000, 0x20000000, 0x10000000,
	0x08000000, 0x04000000, 0x02000000, 0x01000000,
	0x00800000, 0x00400000, 0x00200000, 0x00100000,
	0x00080000, 0x00040000, 0x00020000, 0x00010000,
	0x00008000, 0x00004000, 0x00002000, 0x00001000,
	0x00000800, 0x00000400, 0x00000200, 0x00000100,
	0x00000080, 0x00000040, 0x00000020, 0x00000010,
	0x00000008, 0x00000004, 0x00000002, 0x00000001,
		    0x00000002, 0x00000004, 0x00000008,
	0x00000010, 0x00000020, 0x00000040, 0x00000080,
	0x00000100, 0x00000200, 0x00000400, 0x00000800,
	0x00001000, 0x00002000, 0x00004000, 0x00008000,
	0x00010000, 0x00020000, 0x00040000, 0x00080000,
	0x00100000, 0x00200000, 0x00400000, 0x00800000,
	0x01000000, 0x02000000, 0x04000000, 0x08000000,
	0x10000000, 0x20000000, 0x40000000
};
static const unsigned long kit[] = {
	0x80000000, 0xc0000000,
	0xe0000000, 0x70000000, 0x38000000, 0x1c000000,
	0x0e000000, 0x07000000, 0x03800000, 0x01c00000,
	0x00e00000, 0x00700000, 0x00380000, 0x001c0000,
	0x000e0000, 0x00070000, 0x00038000, 0x0001c000,
	0x0000e000, 0x00007000, 0x00003800, 0x00001c00,
	0x00000e00, 0x00000700, 0x00000380, 0x000001c0,
	0x000000e0, 0x00000070, 0x00000038, 0x0000001c,
	0x0000000e, 0x00000007, 0x00000003, 0x00000001,
		    0x00000003, 0x00000007, 0x0000000e,
	0x0000001c, 0x00000038, 0x00000070, 0x000000e0,
	0x000001c0, 0x00000380, 0x00000700, 0x00000e00,
	0x00001c00, 0x00003800, 0x00007000, 0x0000e000,
	0x0001c000, 0x00038000, 0x00070000, 0x000e0000,
	0x001c0000, 0x00380000, 0x00700000, 0x00e00000,
	0x01c00000, 0x03800000, 0x07000000, 0x0e000000,
	0x1c000000, 0x38000000, 0x70000000, 0xe0000000,
	0xc0000000
};
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))

int
main(int argc, char **argv)
{
	extern char *optarg;
	char *cptr;
	enum { NONE, IN, OUT, TRISTATE, CYLON, KIT } operation = NONE;
	char *devfile = "/dev/gpio";
	struct ibm_gpio_ioctl_data ioctl_data;
	int i, fd;

	ioctl_data.device = 0;
	ioctl_data.data = ""
	ioctl_data.mask = ~0;

	while ((i = getopt(argc, argv, "d:n:m:io:t:ck")) != EOF) {
		switch (i) {
		case 'd':
			devfile = optarg;
			break;
		case 'n':
			ioctl_data.device = strtoul(optarg, &cptr, 0);
			if (cptr == optarg)
				usage(argv[0]);
			break;
		case 'm':
			ioctl_data.mask = strtoul(optarg, &cptr, 0);
			if (cptr == optarg)
				usage(argv[0]);
			break;
		case 'i':
			operation = IN;
			break;
		case 'o':
			operation = OUT;
			ioctl_data.data = "" &cptr, 0);
			if (cptr == optarg)
				usage(argv[0]);
			break;
		case 't':
			operation = TRISTATE;
			ioctl_data.data = "" &cptr, 0);
			if (cptr == optarg)
				usage(argv[0]);
			break;
		case 'c':
			operation = CYLON;
			break;
		case 'k':
			operation = KIT;
			break;
		case '?':
			usage(argv[0]);
		}
	}

	if (optind < argc || operation == NONE) {
		usage(argv[0]);
	}

	if ((fd = open(devfile, O_RDWR)) == -1) {
		perror(devfile);
		exit(1);
	}

	switch (operation) {
	case IN:
		if (ioctl(fd, IBMGPIO_IN, &ioctl_data) == -1) {
			perror(devfile);
			exit(1);
		}
		printf("0x%08X\n", ioctl_data.data);
		break;
	case OUT:
		if (ioctl(fd, IBMGPIO_OUT, &ioctl_data) == -1) {
			perror(devfile);
			exit(1);
		}
		break;
	case TRISTATE:
		if (ioctl(fd, IBMGPIO_TRISTATE, &ioctl_data) == -1) {
			perror(devfile);
			exit(1);
		}
		break;
	case CYLON:
#define CYLON_DELAY_USECS (10000)
		for (;;) {
			for (i=0; i<ARRAY_SIZE(cylon); i++) {
				ioctl_data.data = ""
				if (ioctl(fd, IBMGPIO_OUT, &ioctl_data) == -1) {
					perror(devfile);
					exit(1);
				}
				usleep(CYLON_DELAY_USECS);
			}
		}
		break;
	case KIT:
#define KIT_DELAY_USECS (10000)
		ioctl_data.data = ""
		if (ioctl(fd, IBMGPIO_OUT, &ioctl_data) == -1) {
			perror(devfile);
			exit(1);
		}
		usleep(KIT_DELAY_USECS);
		for (;;) {
			for (i=0; i<ARRAY_SIZE(kit); i++) {
				ioctl_data.data = ""
				if (ioctl(fd, IBMGPIO_OUT, &ioctl_data) == -1) {
					perror(devfile);
					exit(1);
				}
				usleep(KIT_DELAY_USECS);
			}
		}
		break;
	}
	close(fd);
	return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Quoting Arnaud Lagger <[email protected]>:
> Dear all,
>
> I'm trying to use the GPIO, as in gpio_test but /dev/gpio doesn't appear
> in uClinux.
>
> So I added:
>
> ----
>
> ifdef CONFIG_XILINX_GPIO
> DEVICES +=   \
> 	gpio,c,185,0	gpio1,c,185,1	gpio2,c,185,2	\
> 	gpio3,c,185,3	gpio4,c,185,4	gpio5,c,185,5	\
> 	gpio6,c,185,6	gpio7,c,185,7	gpio8,c,185,8	\
> 	gpio9,c,185,9	gpio10,c,185,10	gpio11,c,185,11	\
> 	gpio12,c,185,12	gpio13,c,185,13	gpio14,c,185,14	\
> 	gpio15,c,185,15	gpio16,c,185,16	gpio17,c,185,17	\
> 	gpio18,c,185,18	gpio19,c,185,19	gpio20,c,185,20	\
> 	gpio21,c,185,21	gpio22,c,185,22	gpio23,c,185,23
> endif
>
> ----
>
> in vendors/Xilinx/uclinux-auto/Makefile
>
> and /dev/gpio appears but it cannot be opened (with for instance
> open("/dev/gpio", O_RDWR))!
>
> Any idea?
>
> Thanks,
>
> Arnaud Lagger

Reply via email to