) {
for (j=0;j<4;j++)
gpio_set_value(led_table[j],0);
mdelay(400); //delay 400ms
for (j=0;j<4;j++)
gpio_set_value(led_table[j],1);
mdelay(400);
}break;
}caseIOCTL_LED_ALLON:
printk("in the IOCTL_LED_ALLON!!\n");//设置指定引脚的输出电平为0
leds_all_on();break;caseIOCTL_LED_ALLOFF:
printk("in the IOCTL_LED_ALLOFF!!\n");//设置指定引脚的输出电平为1
leds_all_off();break;default:
printk("in the default!!\n");return -EINVAL;
}return 0;
}/*这个结构是字符设备驱动程序的核心
* 当应用程序操作设备文件时所调用的open、read、write等函数,
* 最终会调用这个结构中指定的对应函数*/
static struct file_operations leds_fops ={
.owner= THIS_MODULE, /*这是一个宏,推向编译模块时自动创建的__this_module变量*/.open=leds_open,
.unlocked_ioctl=leds_ioctl,
};/** Set up the cdev structure for a device.*/
static void led_setup_cdev(struct cdev *dev, intminor,struct file_operations *fops)
{int err, devno =MKDEV(led_major, minor);
cdev_init(dev, fops);
dev->owner =THIS_MODULE;
dev->ops =fops;
err= cdev_add (dev, devno, 1);/*Fail gracefully if need be*/
if(err)
printk (KERN_NOTICE"Error %d adding Led%d", err, minor);
}/** 执行“insmod leds.ko”命令时就会调用这个函数*/
static int __init leds_init(void)
{intresult;
dev_t dev= MKDEV(led_major, 0);char dev_name[]="led"; /*加载模式后,执行”cat /proc/devices”命令看到的设备名称*/
/*gpio_request*/
inti,ret;for (i = 0; i < LED_NUM; i++)
{
ret=gpio_request(led_table[i],"LED");if(ret)//注意,是ret
{
printk("%s:request GPIO %d for LED failed,ret= %d\n",dev_name,led_table[i],ret);returnret;
}
s3c_gpio_cfgpin(led_table[i],S3C_GPIO_SFN(1));//output
gpio_set_value(led_table[i],1);
}/*Figure out our device number.*/
if(led_major)
result= register_chrdev_region(dev, 1, dev_name);else{
result= alloc_chrdev_region(&dev, 0, 1, dev_name);
led_major=MAJOR(dev);
}if (result < 0) {
printk(KERN_WARNING"leds: unable to get major %d\n", led_major);returnresult;
}if (led_major == 0)
led_major=result;/*Now set up cdev.*/led_setup_cdev(&LedDevs, 0, &leds_fops);/*udev机制可以自动添加设备节点,只需要添加xxx_class这个类,以及device_create()*/led_class= class_create(THIS_MODULE, "led_class");/*在sys目录下创建xx_class这个类,/sys/class/~*/device_create(led_class, NULL, LedDevs.dev, dev_name, dev_name);/*自动创建设备/dev/$DEVICE_NAME*/printk("Led device installed, with major %d\n", led_major);
printk("The device name is: %s\n", dev_name);return 0;
}/** 执行”rmmod leds”命令时就会调用这个函数*/
static void __exit leds_exit(void)
{/*gpio_free*/
inti;for (i = 0; i < LED_NUM; i++)
{
gpio_free(led_table[i]);
}/*卸载驱动程序*/cdev_del(&LedDevs);
unregister_chrdev_region(MKDEV(led_major,0), 1);
printk("Led device uninstalled\n");
}/*这两行指定驱动程序的初始化函数和卸载函数*/module_init(leds_init);
module_exit(leds_exit);/*描述驱动程序的一些信息,不是必须的*/MODULE_AUTHOR(""); //驱动程序的作者
MODULE_DESCRIPTION("LED Driver"); //一些描述信息
MODULE_LICENSE("Dual BSD/GPL"); //遵循的协议