#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
//定义驱动名,驱动设备号
#define DEVICE_NAME "leds"
#define LED_MAJOR 231
//静态长整形数组,存放与这4个LED相连接的GPIO号
static unsigned long led_table [] = {
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB8,
S3C2410_GPB10,
};
//静态整形数组,存放这4个GPIO配置,此处为输出
static unsigned int led_cfg_table [] = {
S3C2410_GPB5_OUTP, //0x01<<10 defined in refg-gpio.h
S3C2410_GPB6_OUTP,
S3C2410_GPB8_OUTP,
S3C2410_GPB10_OUTP,
};
//当应用层ioctl(fd,cmd,arg)被调用时,系统将处理它能识别的命令
//如果系统不能识别该命令,则驱动ioctl将被调用
//如果驱动层ioctl也不能识别,返回-EINVAL
static int s3c2440_leds_ioctl
(
struct inode *inode,
struct file *file,
unsigned int cmd, //命令号
unsigned long arg //参数
)
{
switch(cmd)
{
case 0: //cmd=0,LED灭
case 1: //cmd=1,LED亮
if (arg > 4) {//只有4个LED灯
return -EINVAL;
}
s3c2410_gpio_setpin(led_table[arg], !cmd);//s3c2410_gpio_setpin()函数用于设置GPIO pin电平
//cmd=0,!cmd=1,灯灭
//cmd=1,!cmd=0,灯亮
return 0;//成功操作返回0
default:
return -EINVAL;//错误返回-EINVAL
}
}
//file_operations 是文件操作结构体
//用于存放设备能进行的各种操作的函数指针
static struct file_operations s3c2440_leds_fops =
{
.owner = THIS_MODULE,//为了防止设备在使用的过程中,模块被缷载掉,owner应该设置为THIS_MODULE
.ioctl = s3c2440_leds_ioctl,//ioctl函数指针指向上面的sbc2440_leds_ioctl()函数
};
//初始化LED函数
static int __init s3c2440_leds_init(void)
{
int ret;
int i;
ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c2440_leds_fops);//注册驱动设备号,驱动设备名称,驱动函数地址
if (ret < 0) {
printk(DEVICE_NAME " can't register major number\n");
return ret;
}
devfs_mk_cdev(MKDEV(LED_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME);
for (i = 0; i < 4 ; i++) {
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
s3c2410_gpio_setpin(led_table[i], 1);
}
printk(DEVICE_NAME " initialized\n");
return 0;
}
static void __exit s3c2440_leds_exit(void)
{
devfs_remove(DEVICE_NAME);
unregister_chrdev(LED_MAJOR, DEVICE_NAME);
}
module_init(s3c2440_leds_init);
module_exit(s3c2440_leds_exit);
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
//定义驱动名,驱动设备号
#define DEVICE_NAME "leds"
#define LED_MAJOR 231
//静态长整形数组,存放与这4个LED相连接的GPIO号
static unsigned long led_table [] = {
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB8,
S3C2410_GPB10,
};
//静态整形数组,存放这4个GPIO配置,此处为输出
static unsigned int led_cfg_table [] = {
S3C2410_GPB5_OUTP, //0x01<<10 defined in refg-gpio.h
S3C2410_GPB6_OUTP,
S3C2410_GPB8_OUTP,
S3C2410_GPB10_OUTP,
};
//当应用层ioctl(fd,cmd,arg)被调用时,系统将处理它能识别的命令
//如果系统不能识别该命令,则驱动ioctl将被调用
//如果驱动层ioctl也不能识别,返回-EINVAL
static int s3c2440_leds_ioctl
(
struct inode *inode,
struct file *file,
unsigned int cmd, //命令号
unsigned long arg //参数
)
{
switch(cmd)
{
case 0: //cmd=0,LED灭
case 1: //cmd=1,LED亮
if (arg > 4) {//只有4个LED灯
return -EINVAL;
}
s3c2410_gpio_setpin(led_table[arg], !cmd);//s3c2410_gpio_setpin()函数用于设置GPIO pin电平
//cmd=0,!cmd=1,灯灭
//cmd=1,!cmd=0,灯亮
return 0;//成功操作返回0
default:
return -EINVAL;//错误返回-EINVAL
}
}
//file_operations 是文件操作结构体
//用于存放设备能进行的各种操作的函数指针
static struct file_operations s3c2440_leds_fops =
{
.owner = THIS_MODULE,//为了防止设备在使用的过程中,模块被缷载掉,owner应该设置为THIS_MODULE
.ioctl = s3c2440_leds_ioctl,//ioctl函数指针指向上面的sbc2440_leds_ioctl()函数
};
//初始化LED函数
static int __init s3c2440_leds_init(void)
{
int ret;
int i;
ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c2440_leds_fops);//注册驱动设备号,驱动设备名称,驱动函数地址
if (ret < 0) {
printk(DEVICE_NAME " can't register major number\n");
return ret;
}
devfs_mk_cdev(MKDEV(LED_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME);
for (i = 0; i < 4 ; i++) {
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
s3c2410_gpio_setpin(led_table[i], 1);
}
printk(DEVICE_NAME " initialized\n");
return 0;
}
static void __exit s3c2440_leds_exit(void)
{
devfs_remove(DEVICE_NAME);
unregister_chrdev(LED_MAJOR, DEVICE_NAME);
}
module_init(s3c2440_leds_init);
module_exit(s3c2440_leds_exit);