#include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> #include <mach/regs-gpio.h> #include <mach/hardware.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/delay.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #include <linux/list.h> #include <linux/pci.h> #include <linux/gpio.h> #include <asm/uaccess.h> #include <asm/atomic.h> #include <asm/unistd.h> #define DEVICE_NAME "leds" // at /proc/devices 设备名称 #define LEDS_MAJOR 231 //主设备号 static unsigned long led_table [] = { S3C2410_GPB(5), //要使用的GPIO S3C2410_GPB(6), S3C2410_GPB(7), S3C2410_GPB(8), }; static unsigned int led_cfg_table [] = { S3C2410_GPIO_OUTPUT, //配置引脚功能 S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, }; static int sbc2440_leds_ioctl( struct inode *inode, //设备节点 struct file *file, unsigned int cmd, //命令 unsigned long arg)//端口 { switch(cmd) { case 0://打开和关闭两种状态 case 1: if (arg >=4) {//只有4个LED,超过4个就报错 return -EINVAL; } s3c2410_gpio_setpin(led_table[arg], !cmd);//发出控制命令 return 0; default://若不是0,1则报错 return -EINVAL; } } static struct file_operations dev_fops = {//用于存放设备操作函数的指针 .owner = THIS_MODULE,//防止模块在使用的过程中被卸载掉 .ioctl = sbc2440_leds_ioctl,//ioctl指向该函数供上层调用 }; static struct miscdevice misc = {//是杂项设备结构体,供注册使用 .minor = LEDS_MAJOR, .name = DEVICE_NAME, .fops = &dev_fops, }; static int __init dev_init(void)//内联函数只是在初始化时有效 { int ret; int i; for (i = 0; i < 4; i++) { s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);//全部设置为输出 s3c2410_gpio_setpin(led_table[i], 1);//全部设置为1 } ret = misc_register(&misc);//注册杂项设备 printk (DEVICE_NAME" initialized ");//初始化完成 return ret; } static void __exit dev_exit(void) { misc_deregister(&misc);//注销该设备 } module_init(dev_init);//模块初始化,调用dev_init module_exit(dev_exit);//模块注销调用dec_exit MODULE_LICENSE("GPL");//注册通行证 使用GPL协议 MODULE_AUTHOR("ARM Inc.");//作者