Smart210开发板CON14矩阵键盘接口IO电平控制

驱动

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>

#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>


#define DEVICE_NAME "leds"

static int led_gpios[] = {
	S5PV210_GPH2(0),
	S5PV210_GPH2(1),
	S5PV210_GPH2(2),
	S5PV210_GPH2(3),
	S5PV210_GPH3(0),
	S5PV210_GPH3(1),
	S5PV210_GPH3(2),
	S5PV210_GPH3(3),
};

#define LED_NUM		ARRAY_SIZE(led_gpios)


static long mini210_leds_ioctl(struct file *filp, unsigned int cmd,
		unsigned long arg)
{
	switch(cmd) {
		case 0:
		case 1:
			if (arg > LED_NUM) {
				return -EINVAL;
			}

			gpio_set_value(led_gpios[arg], !cmd);
			printk(DEVICE_NAME": %d %d\n", arg, cmd);
			break;

		default:
			return -EINVAL;
	}

	return 0;
}

static struct file_operations mini210_led_dev_fops = {
	.owner			= THIS_MODULE,
	.unlocked_ioctl	= mini210_leds_ioctl,
};

static struct miscdevice mini210_led_dev = {
	.minor			= MISC_DYNAMIC_MINOR,
	.name			= DEVICE_NAME,
	.fops			= &mini210_led_dev_fops,
};

static int __init mini210_led_dev_init(void) {
	int ret;
	int i;

	for (i = 0; i < LED_NUM; i++) {
		ret = gpio_request(led_gpios[i], "LED");
		if (ret) {
			printk("%s: request GPIO %d for LED failed!, ret = %d\n", DEVICE_NAME,
					led_gpios[i], ret);
			return ret;
		}
		if (!ret) {
			printk("%s: request GPIO %d for LED success!, ret = %d\n", DEVICE_NAME,
					led_gpios[i], ret);
		}
		s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT);
		gpio_set_value(led_gpios[i], 1);
	}

	ret = misc_register(&mini210_led_dev);

	printk(DEVICE_NAME"\tinitialized\n");

	return ret;
}

static void __exit mini210_led_dev_exit(void) {
	int i;

	for (i = 0; i < LED_NUM; i++) {
		gpio_free(led_gpios[i]);
	}

	misc_deregister(&mini210_led_dev);
}

module_init(mini210_led_dev_init);
module_exit(mini210_led_dev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");

测试文件

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
	int on;
	int led_no;
	int fd;

	if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 ||
			on < 0 || on > 1 || led_no < 0 || led_no > 7) {
		fprintf(stderr, "Usage: leds 0|1 led_no \n");
		exit(1);
	}

	fd = open("/dev/leds0", 0);
	if (fd < 0) {
		fd = open("/dev/leds", 0);
	}
	if (fd < 0) {
		perror("open device leds");
		exit(1);
	}

	ioctl(fd, on, led_no);
	close(fd);

	return 0;
}

Makefile

# ----------------------------------------------------------------------------
# Makefile for building tapp
#
# Copyright 2010 FriendlyARM (http://www.arm9.net/)
#

ifndef DESTDIR
DESTDIR			   ?= /work/rootfile/rootfs
endif

CFLAGS				= -Wall -O2
CC					= arm-none-linux-gnueabi-gcc
INSTALL				= install

TARGET				= led


all: $(TARGET)

led: led.c
	$(CC) $(CFLAGS) $< -o $@


install: $(TARGET)
	$(INSTALL) $^ $(DESTDIR)

clean distclean:
	rm -rf *.o $(TARGET)


# ----------------------------------------------------------------------------

.PHONY: $(PHONY) install clean distclean

# End of file
# vim: syntax=make