驱动
驱动
#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