国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

查看: 3884|回復(fù): 0
打印 上一主題 下一主題

【飛凌】platform_device + miscdevice 模式的LED驅(qū)動程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2010-7-30 12:46:42 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
關(guān)鍵詞: device , LED , platform , 飛凌 , 模式
本文轉(zhuǎn)引自 飛凌嵌入式 Linux技術(shù)交流區(qū) www.witech.com.cn
感謝作者朋友的分享精神!
這是我最近學習Linux驅(qū)動模型的成果,發(fā)出來大家共同學習一下,該程序還有很多缺陷,希望高手能不吝賜教
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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<                                 writel(tmp,ledbase +LED_DAT);
                                }
                        else if(cmd==LED_OFF)
                        {
                                tmp        =        readl(ledbase+LED_DAT);
                                tmp |=(1<                                 writel(tmp,ledbase +LED_DAT);
                                }
                        else
                                printk("command error");
                        break;
                        }
                        while(0);
///command switch
/*
        switch (arg) {
                case 1:
                        if(cmd==LED_ON)
                        {
                                tmp        =        readl(ledbase+LED_DAT);
                                tmp &=(~(1<<5));
                                writel(tmp,ledbase +LED_DAT);
                                }
                        else if(cmd==LED_OFF)
                        {
                                tmp        =        readl(ledbase+LED_DAT);
                                tmp |=(1<<5);
                                writel(tmp,ledbase +LED_DAT);
                                }
                        else
                                printk("command error");
                        break;
                case 2:
                        if(cmd==LED_ON)
                        {
                                tmp        =        readl(ledbase+LED_DAT);
                                tmp &=(~(1<<6));
                                writel(tmp,ledbase +LED_DAT);
                                }
                        else if(cmd==LED_OFF)
                        {
                                tmp        =        readl(ledbase+LED_DAT);
                                tmp |=(1<<6);
                                writel(tmp,ledbase +LED_DAT);
                                }
                        else
                                printk("command error");
                        break;
                case 3:
                        if(cmd==LED_ON)
                        {
                                tmp        =        readl(ledbase+LED_DAT);
                                tmp &=(~(1<<8));
                                writel(tmp,ledbase +LED_DAT);
                                }
                        else if(cmd==LED_OFF)
                        {
                                tmp        =        readl(ledbase+LED_DAT);
                                tmp |=(1<<8);
                                writel(tmp,ledbase +LED_DAT);
                                }
                        else
                                printk("command error");
                        break;
                case 4:
                        if(cmd==LED_ON)
                        {
                                tmp        =        readl(ledbase+LED_DAT);
                                tmp &=(~(1<<10));
                                writel(tmp,ledbase +LED_DAT);
                                }
                        else if(cmd==LED_OFF)
                        {
                                tmp        =        readl(ledbase+LED_DAT);
                                tmp |=(1<<10);
                                writel(tmp,ledbase +LED_DAT);
                                }
                        else
                                printk("command error");
                        break;
                default :
                        printk("error");
                                break;
                }
                */
        return 0;
}
static int led_probe(struct platform_device *pdev)
{
        struct resource *res;
        struct device *dev;
        int size;
        int ret;
        dev=&pdev->dev;
        printk("\nMatch success");
        res=        platform_get_resource(pdev,IORESOURCE_MEM,0);
        if(res==NULL)
        {
                dev_err(dev,"no memory resource specified\n");
                return -ENOENT;
                }
        size        =        res->end-res->start +1;
        ledbase        =        ioremap(res->start,size);
        if(ledbase==NULL)
        {
        dev_err(dev,"fail to ioremap() region\n");
        ret=-EINVAL;
        goto err_req;
        }
        ret=misc_register(&misc_led);
        if(ret)
        {
                dev_err(dev,"cannot register led  miscdev ");
                goto err_misc;
                }
        err_misc:
                iounmap(ledbase);
        err_req:

        return ret;
        }

static int led_remove(struct platform_device *pdev)
{
        //iounmap(ledbase);這一句有問題,加上就會出現(xiàn)oops
        misc_deregister(&misc_led);
        return 0;
        }
        
int __init ledInit(void)
{
        //int ret;
         //struct class *ledClass = class_create(THIS_MODULE,"ledClass");
        //alloc_chrdev_region(&devNu,0,1,DEV_NAME);
        major = LED_MAJOR;
        printk("\nMAJOR is %d\n",major);
        devNu        =        MKDEV(LED_MAJOR,LED_MINOR);
        //regist miscdevice
        //misc_register(&misc_led);
        //cdev_init(&ledCdev,&led_opt);
        //ledCdev.owner = THIS_MODULE;
        //ledCdev.ops = &led_opt;
        //cdev_add(&ledCdev,devNu,1);
        //AUTOMATIC CREATE DEVICE FILE IN /dev
        platform_device_register(&ledDevice);
        platform_driver_register(&ledDriver);
        //device_create(ledClass,NULL,devNu,NULL,"led");
        //在platform_device的總線中注冊設(shè)備時,會自動在/dev/下面生成設(shè)備文件,
        //所以在這里若果在調(diào)用device_create就會出錯
        //在platform_device_register中會創(chuàng)建/dev/下面的設(shè)備文件
        //并且在調(diào)用platform_device_unregister的時候也會自動刪除/dev/下面創(chuàng)建的設(shè)備文件。
        return 0;
}
void __exit ledExit(void)
{
        //cdev_del(&ledCdev);
        //unregister_chrdev_region(devNu,1);
        
        //misc_deregister(&misc_led);
        platform_driver_unregister(&ledDriver);
        platform_device_unregister(&ledDevice);
        
}
module_init(ledInit);
module_exit(ledExit);
PS:
雖然有點大材小用,但是用來熟悉platform——device還是不錯的。
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 精品四虎免费观看国产高清午夜 | 最新精品国偷自产在线91 | 伊人久久久综在合线久久在播 | 久久99国产乱子伦精品免费 | 日本精品久久久一区二区三区 | 爽好舒服宝贝添奶吻戏 | 日本欧美韩国专区 | 四虎国产精品免费五月天 | 性色aⅴ闺蜜一区二区三区 性色a v 一区 | 亚洲视频五区 | 成人亚洲网站 | aaa在线观看视频高清视频 | 免费特黄一区二区三区视频一 | aⅴ在线免费观看 | 欧美综合自拍亚洲综合图片区 | 国产精品久久久亚洲第一牛牛 | 亚洲区视频 | 欧美片网站 | 99香蕉国产线观看免费 | 欧美在线视频一区 | 日日夜夜狠狠 | 愉拍自拍视频在线播放 | 国产精品亚洲国产三区 | 国产人成精品午夜在线观看 | 91视频一区二区三区 | 精品卡1卡2卡三卡免费网站视频 | 一级做a爰性色毛片免费 | a亚洲欧美中文日韩在线v日本 | 一级特黄特黄的大片免费 | 四虎影音在线观看 | 干干操| 四虎影院www| 九九热精品视频在线播放 | 欧美一级视频在线高清观看 | 欧美xxxxx性开放 | 亚洲天堂久 | 最新更新国内自拍视频 | 在线一区视频 | 精品卡通动漫在线观看视频一区 | 国产一区二区三区高清 | 日本www网站 |