/*************************LED驱动*************************/
-
#include <linux/init.h>
-
#include <linux/module.h>
-
#include <linux/fs.h>
-
#include <linux/device.h>
-
#include <linux/cdev.h>
-
#include <linux/slab.h>
-
#include <linux/gpio.h>
-
#include <plat/gpio-cfg.h>
-
#include <asm/uaccess.h>
-
#include <asm/io.h>
-
-
-
#define PA_GPC0CON 0xE0200060//LED 寄存器的基地址
-
-
volatile unsigned int *GPC0CON;
-
volatile unsigned int *GPC0DAT;
-
-
//设计设备对象
-
struct s5p210_led{
-
struct cdev *c_dev;//cdev结构体描述一个字符设备
-
struct class *cls;//设备结点类结构体
-
struct device *dev;//设备属性结构体
-
dev_t devno;//设备节点
-
};
-
-
static struct s5p210_led *led_dev;
-
static int ret = -1;
-
-
int led_open(struct inode *inode, struct file *filp)
-
{//实现硬件的初始化
-
-
#if 0
-
//GPIO配置为输出
-
*GPC0CON &= ~(0xFF<<12);
-
*GPC0CON |= (0x11<<12);
-
//LED输出为低
-
*GPC0DAT &= ~0x18;
-
printk(KERN_INFO"----%s--------\n", __FUNCTION__);
-
#else
-
/*申请某个GPIO管脚*/
-
gpio_request(S5PV210_GPC0(3),"led0");
-
gpio_request(S5PV210_GPC0(4),"led1");
-
/*配置某个管脚为输入功能*/
-
s3c_gpio_cfgpin(S5PV210_GPC0(3),S3C_GPIO_OUTPUT);
-
s3c_gpio_cfgpin(S5PV210_GPC0(4),S3C_GPIO_OUTPUT);
-
-
#endif
-
-
return 0;
-
}
-
-
ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *ofs)
-
{
-
int get_ret = 0;
-
int led_signal=0;
-
-
get_ret = copy_from_user(&led_signal,buf,1);
-
if(get_ret == 0)
-
{
-
if(!led_signal)
-
{//亮
-
//*GPC0DAT &= ~0x18;
-
gpio_direction_output(S5PV210_GPC0(3),1);
-
gpio_direction_output(S5PV210_GPC0(4),1);
-
}
-
else
-
{//灭
-
//*GPC0DAT |= 0x18;
-
gpio_direction_output(S5PV210_GPC0(3),0);
-
gpio_direction_output(S5PV210_GPC0(4),0);
-
}
-
}
-
return get_ret?-EFAULT:size;
-
-
printk(KERN_INFO"----%s--------\n", __FUNCTION__);
-
}
-
ssize_t led_read (struct file *filp, char __user *buf, size_t size, loff_t *ofs)
-
{
-
printk(KERN_INFO"----%s--------\n", __FUNCTION__);
-
return 0;
-
}
-
int led_close(struct inode *inode, struct file *filp)
-
{
-
printk(KERN_INFO"----%s--------\n", __FUNCTION__);
-
return 0;
-
}
-
long ioctl(struct file *filp, unsigned int argc, unsigned long argv)
-
{
-
if(argc ==19870322)
-
{
-
-
//*GPC0DAT &= ~0x10;
-
//*GPC0DAT |= 0x08;
-
gpio_direction_output(S5PV210_GPC0(3),1);
-
gpio_direction_output(S5PV210_GPC0(4),0);
-
}
-
if(argv==610428)
-
{
-
//*GPC0DAT &= ~0x08;
-
//*GPC0DAT |= 0x10;
-
gpio_direction_output(S5PV210_GPC0(3),0);
-
gpio_direction_output(S5PV210_GPC0(4),1);
-
}
-
printk(KERN_INFO"----%s--------\n", __FUNCTION__);
-
return 0;
-
}
-
-
-
//驱动文件为用户空间提供的操作函数(函数)
-
struct file_operations led_file={
-
.owner = THIS_MODULE,
-
.open = led_open,
-
.write = led_write,
-
.read = led_read,
-
.release= led_close,
-
.unlocked_ioctl = ioctl,
-
};
-
-
static int __init led_init(void)
-
{
-
//加载驱动过程
-
//1.为设备分配一个空间
-
led_dev = kmalloc(sizeof(struct s5p210_led),GFP_KERNEL);
-
-
if(NULL == led_dev)
-
{
-
printk(KERN_ERR"kmalloc error!\n");
-
return -ENOMEM;
-
}
-
//2.申请设备号(自动申请设备号)
-
ret = register_chrdev(0,"s5pv210_led_drv",&led_file);
-
if(ret <=0)
-
{
-
printk(KERN_ERR"register_chrdev!\n");
-
ret = -EINVAL;
-
goto err_1;
-
}
-
//返回的主设备号ret
-
led_dev->devno = MKDEV(ret,0);
-
//3.创建与用户空间关联的文件
-
led_dev->cls = class_create(THIS_MODULE,"s5pv_led_class");
-
if(!led_dev->cls)
-
{
-
ret = PTR_ERR(led_dev->cls);
-
goto err_2;
-
}
-
led_dev->dev = device_create(led_dev->cls,NULL,led_dev->devno,NULL,"s5pv210_led_drv");
-
if(!led_dev->dev)
-
{
-
ret = PTR_ERR(led_dev->dev);
-
goto err_3;
-
}
-
//4.为硬件申请内存资源虚拟地址
-
/*GPC0CON = ioremap(PA_GPC0CON,24);
-
if(NULL == GPC0CON)
-
{
-
ret = -ENOMEM;
-
goto err_4;
-
}
-
GPC0DAT = GPC0CON +1;
-
*/
-
printk(KERN_INFO"----%s--------\n", __FUNCTION__);
-
return 0;
-
//err_4:
-
// device_destroy(led_dev->cls,led_dev->devno);
-
err_3:
-
class_destroy(led_dev->cls);
-
err_2:
-
unregister_chrdev(MAJOR(led_dev->devno),"led_drv");
-
err_1:
-
kfree(led_dev);
-
return ret;
-
-
}
-
static void __exit led_exit(void)
-
{
-
//释放申请的资源
-
//iounmap(GPC0CON);
-
kfree(led_dev);
-
unregister_chrdev(MAJOR(led_dev->devno),"led_drv");
-
device_destroy(led_dev->cls,led_dev->devno);
-
class_destroy(led_dev->cls);
-
printk(KERN_INFO"----%s--------\n", __FUNCTION__);
-
}
-
-
-
-
//模块加载卸载函数
-
module_init(led_init);
-
module_exit(led_exit);
-
MODULE_LICENSE("GPL");
/*************************LED驱动*************************/
/*************************LED驱动*************************/
/*********************LED驱动测试程序*********************************/
-
#include<stdio.h>
-
#include<errno.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
#include <stropts.h>
-
-
int main(int argc ,char *argv[])
-
{
-
int fd = -1;
-
int on =1;
-
int off = 0;
-
fd = open("/dev/s5pv210_led_drv",O_RDWR);
-
if(fd ==-1)
-
{
-
perror("open");
-
return -1;
-
}
-
while(1)
-
{
-
//write(fd,&on,1);
-
//sleep(1);
-
//write(fd,&off,1);
-
//sleep(1);
-
ioctl(fd,19870322,1);
-
sleep(1);
-
ioctl(fd,1,610428);
-
sleep(1);
-
-
}
-
return 0;
-
}
阅读(1746) | 评论(0) | 转发(0) |