- UID
- 810482
|
【飞凌】platform_device + miscdevice 模式的LED驱动程序
本文转引自 飞凌嵌入式 Linux技术交流区 www.witech.com.cn
感谢作者朋友的分享精神!
这是我最近学习Linux驱动模型的成果,发出来大家共同学习一下,该程序还有很多缺陷,希望高手能不吝赐教
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include<linux/init.h>
#include<linux/module.h>
#include<asm/io.h>
#include<linux/miscdevice.h>
#include<linux/ioctl.h>
#include<linux/device.h>
#include<linux/platform_device.h>
MODULE_AUTHOR("YUZIQIANG");
MODULE_DESCRIPTION("LEDS DRIVE");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
#define DEV_NAME "FL2440LED"
#define LED_MAGIC 'L'
#define LED_ON _IOW(LED_MAGIC,0,int)
#define LED_OFF _IOW(LED_MAGIC,1,int)
#define LED_MINOR 125
#define LED_MAJOR 10
#define LED_CON 0
#define LED_DAT 4
#define LED_UP 8
int major;
dev_t devNu;
struct cdev ledCdev ;
void *ledbase;
ssize_t led_read(struct file *filp,char __user *buffer,size_t size,loff_t *offset);
ssize_t led_write(struct file *filp,const char __user *buffer,size_t size,loff_t *offset);
int led_open(struct inode *inode,struct file *filp);
int led_release(struct inode *inode,struct file *filp);
int led_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);
static int led_probe(struct platform_device *pdev);
static int led_remove(struct platform_device *pdev);
struct resource s3c_led_resource[] ={
[0]={
.start = 0x56000010,
.end = 0x5600001b,
.flags = IORESOURCE_MEM,
}
};
struct file_operations led_opt ={
.owner = THIS_MODULE,
.ioctl = led_ioctl,
.open = led_open,
.read = led_read,
.write = led_write,
.release = led_release,
};
static struct miscdevice misc_led ={
.minor = LED_MINOR,
.name = "led",
.fops = &led_opt,
};
struct platform_device ledDevice= {
.name = "led",
.id = -1,//why
.num_resources = ARRAY_SIZE(s3c_led_resource),
.resource = s3c_led_resource,
.dev = {
.release = led_release,
}
};
struct platform_driver ledDriver ={
.probe = led_probe,
.remove = led_remove,
.driver = {
.owner = THIS_MODULE,
.name = "led",
}
};
int led_open(struct inode *inode,struct file *filp)
{
//GPBCON = 0x55555555;
writel(0x55555555,ledbase+LED_CON);
//GPBUP = 0xffffffff;
writel(0,ledbase+LED_UP);
writel(0,ledbase+LED_DAT);
//GPBDAT = 0x00000000;
printk("\nopen success \n");
return 0;
}
ssize_t led_read(struct file *filp,char __user *buffer,size_t size,loff_t *offset)
{
return 0;
}
ssize_t led_write(struct file *filp,const char __user *buffer,size_t size,loff_t *offset)
{
return 0;
}
int led_release(struct inode *inode,struct file *filp)
{
return 0;
}
int led_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
unsigned long tmp;
int pin=0;
///check the command is in the right form
if(arg>4||arg<1)
return -1;
if(_IOC_NR(cmd)>1||_IOC_NR(cmd)<0)
return -1;
if(arg==1)
pin=5;
else if(arg==2)
pin = 6;
else if(arg==3)
pin=8;
else if(arg==4)
pin=10;
else pin= 0;
do {
if(cmd==LED_ON)
{
tmp = readl(ledbase+LED_DAT);
tmp &=(~(1<<pin));
writel(tmp,ledbase +LED_DAT);
}
else if(cmd==LED_OFF)
{
tmp = readl(ledbase+LED_DAT);
tmp |=(1<<pin);
writel(tmp,ledbase +LED_DAT);
}
else
printk("command error");
break;
}
while(0);
///command switch |
|