platform之led驱动分析及测试程序

本文介绍了Linux中的Platform总线机制,它是用于嵌入式系统中管理SoC上独立外设控制器的机制。通过定义特定的结构体并调用注册函数,设备和驱动可以在Platform总线上进行注册。平台设备和驱动的结构体以及注册注销函数进行了说明。此外,还提供了一个平台LED驱动的代码示例,展示了如何控制LED的开关和闪烁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是paltform总线:

个现实的linux设备和驱动通常都需要挂接在一种总线上,比较常见的总线有USBPCI总线等。但是,在嵌入式系统里面,SoC系统中集成的独立的外设控制器、挂接在SoC内存空间的外设却不依附与此类总线。基于这样的背景下,2.6内核加入了platform虚拟总线。platform机制将设备本身的资源注册进内核,有内核统一管理,在驱动程序使用这些资源时使用统一的接口,这样提高了程序的可移植性。



platform总线上注册设备和驱动,只要定义指定的结构体后调用platform给出的注册函数就可以了


linux在系统启动时就注册了platform总线,看内核代码:

/*drivers/base/platform.c*/
 static int platform_match(struct device *dev, struct device_driver *drv)
 {
     struct platform_device *pdev;

     pdev = container_of(dev, struct platform_device, dev);
     return (strcmp(pdev->name, drv->name) == 0); //配对函数检验名字是否一致
 }
。。。。。
 struct bus_type platform_bus_type = {
     .name = "platform", //定义了总线名字为platform,总线注册后新建目录sys/bus/platform
    .dev_attrs = platform_dev_attrs,
     .match = platform_match, //指定配对函数
     .uevent = platform_uevent,
     .pm = PLATFORM_PM_OPS_PTR,
 };


总线中定义了成员名字和match函数,当有总线或者设备注册到platform总线时,内核自动调用match函数


platform设备对应的结构体paltform_device

/*linux/platform_device.h*/
 struct platform_device {
    const char * name; //设备的名字,这将代替device->dev_id,用作sys/device下显示的目录名
    int id; //设备id,用于给插入给该总线并且具有相同name的设备编号,如果只有一个设备的话填-1。
     struct device dev; //结构体中内嵌的device结构体。
     u32 num_resources; //资源数。
    struct resource * resource; //用于存放资源的数组。
 };



platform_device的注册和注销使用以下函数:

/*drivers/base/platform.c*/
 int platform_device_register(struct platform_device *pdev) //同样的,需要判断返回值
。。。
 void platform_device_unregister(struct platform_device *pdev)


会在/sys/device/目录下创建一个以name命名的目录,并且创建软连接到/sys/bus/platform/device下。


platform驱动对应的结构体paltform_driver

/*linux/platform_device.h*/
 struct platform_driver {
    int (*probe)(struct platform_device *);
    int (*remove)(struct platform_device *);
    void (*shutdown)(struct platform_device *);
     int (*suspend)(struct platform_device *, pm_message_t state);
     int (*suspend_late)(struct platform_device *, pm_message_t state);
     int (*resume_early)(struct platform_device *);
    int (*resume)(struct platform_device *);
     struct device_driver driver;
 };



platform_driver结构体内嵌了device_driver,并且实现了probremove等操作。其实,当内核需要调用probe函数时,它会调用driver->probe,在dricer->probe中再调用platform_driver->probe


platform_driver的注册和注销使用以下函数:

/*drivers/base/platform.c*/
 int platform_driver_register(struct platform_driver *drv)
。。。。。
 void platform_driver_unregister(struct platform_driver *drv)


注册成功后内核会在/sys/bus/platform/driver/目录下创建一个名字为driver->name的目录。


更多详细的关于platform或者platled的了解可以参考

http://blog.chinaunix.net/uid-25014876-id-111745.html

http://blog.youkuaiyun.com/zouleideboke/article/details/68969544

platform_LED驱动的代码:

#include "s3c_driver.h"  
  
#define DRV_AUTHOR                "fanmaolin <fanmaolinn@gmail.com>"  
#define DRV_DESC                  "S3C24XX LED driver"  
  
/* Driver version*/  
#define DRV_MAJOR_VER             1  
#define DRV_MINOR_VER             0  
#define DRV_REVER_VER             0  
  
#define DEV_NAME                  DEV_LED_NAME  
#ifndef DEV_MAJOR  
#define DEV_MAJOR                 0 /*  dynamic major by default */   
#endif  
  
#define TIMER_TIMEOUT             40  
  
static int debug = DISABLE;  
static int dev_major = DEV_MAJOR;  
static int dev_minor = 0;  
  
  
/* ============================ Platform Device part ===============================*/  
/*  LED hardware informtation structure*/  
struct s3c_led_info  
{  
    unsigned char           num;              /* The LED number  */  
    unsigned int            gpio;             /* Which GPIO the LED used */    
    unsigned char           active_level;     /* The GPIO pin level(HIGHLEVEL or LOWLEVEL) to turn on or off  */  
    unsigned char           status;           /* Current LED status: OFF/ON */  
    unsigned char           blink;            /* Blink or not */             
};  
  
/*  The LED platform device private data structure */  
struct s3c_led_platform_data  
{  
    struct s3c_led_info    *leds;  
    int                     nleds;  
};  
  
  
/*  LED hardware informtation data*/   
static struct s3c_led_info  s3c_leds[] = {  
    [0] = {  
        .num = 1,  
        .gpio = S3C2410_GPB(5),  
        .active_level = LOWLEVEL,  
        .status = OFF,  
        .blink = ENABLE,  
    },  
    [1] = {  
        .num = 2,  
        .gpio = S3C2410_GPB(6),  
        .active_level = LOWLEVEL,  
        .status = OFF,  
        .blink = DISABLE,  
    },  
    [2] = {  
        .num = 3,  
        .gpio = S3C2410_GPB(8),  
        .active_level = LOWLEVEL,  
        .status = OFF,  
        .blink = DISABLE,  
    },  
    [3] = {   
        .num = 4,  
        .gpio = S3C2410_GPB(10),  
        .active_level = LOWLEVEL,  
        .status = OFF,  
        .blink = DISABLE,  
    },   
};  
  
/*  The LED platform device private data */  
static struct s3c_led_platform_data s3c_led_data = {  			//定义LED灯的结构体信息  
    .leds = s3c_leds,  //LED灯的每条信息 
    .nleds = ARRAY_SIZE(s3c_leds),  //灯数
};  
  
struct led_device  
{  
    struct s3c_led_platform_data    *data;  
    struct cdev                     cdev;  
    struct class                    *dev_class;  
    struct timer_list               blink_timer;  
} led_device;  
  
static void platform_led_release(struct device * dev)  //撤销LED灯的函数  
{  
    int i;  
    struct s3c_led_platform_data *pdata = dev->platform_data;   
  
    dbg_print("%s():%d\n", __FUNCTION__,__LINE__);  
  
    /* Turn all LED off */  
    for(i=0; i<pdata->nleds; i++)  
    {  
         s3c2410_gpio_setpin(pdata->leds[i].gpio, ~pdata->leds[i].active_level);   
    }  
}  
  
static struct platform_device s3c_led_device = { 							//定义设备结构体 
    .name    = "s3c_led",  
    .id      = 1,  
    .dev     =   
    {  
        .platform_data = &s3c_led_data,   
        .release = platform_led_release,  
    },  
};  
  
  
  
/* ===================== led device driver part ===========================*/  
  
void led_timer_handler(unsigned long data)  
{   
    int  i;   
    struct s3c_led_platform_data *pdata = (struct s3c_led_platform_data *)data;  
  
    for(i=0; i<pdata->nleds; i++)   
    {   
        if(ON == pdata->leds[i].status)  
        {  
              s3c2410_gpio_setpin(pdata->leds[i].gpio, pdata->leds[i].active_level);   
        }  
        else  
        {  
              s3c2410_gpio_setpin(pdata->leds[i].gpio, ~pdata->leds[i].active_level);   
        }  
  
        if(ENABLE == pdata->leds[i].blink )  /* LED should blink */  
        {  
            /* Switch status between 0 and 1 to turn LED ON or off */  
            pdata->leds[i].status = pdata->leds[i].status ^ 0x01;    
        }  
  
        mod_timer(&(led_device.blink_timer), jiffies + TIMER_TIMEOUT);  //闪烁时间设置
    }  
}  
  
  
static int led_open(struct inode *inode, struct file *file)  //LED开启函数 
{   
    struct led_device *pdev ;  
    struct s3c_led_platform_data *pdata;  
  
    pdev = container_of(inode->i_cdev,struct led_device, cdev);  
	 /*container_of 在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针, 
就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址*/ 
    pdata = pdev->data;  
  
    file->private_data = pdata;  
  
    return 0;  
}  
  
  
static int led_release(struct inode *inode, struct file *file)  //关闭led
{   
    return 0;  
}  
  
static void print_led_help(void)  //help信息
{  
    printk("Follow is the ioctl() command for LED driver:\n");  
    printk("Enable Driver debug command: %u\n", SET_DRV_DEBUG);  
    printk("Get Driver verion  command : %u\n", GET_DRV_VER);  
    printk("Turn LED on command        : %u\n", LED_ON);  
    printk("Turn LED off command       : %u\n", LED_OFF);  
    printk("Turn LED blink command     : %u\n", LED_BLINK);  
}  
  
/* compatible with kernel version >=2.6.38*/  
static long led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)  
{   
    struct s3c_led_platform_data *pdata = file->private_data;  
  
    switch (cmd)  
    {  
        case SET_DRV_DEBUG:  
            dbg_print("%s driver debug now.\n", DISABLE == arg ? "Disable" : "Enable");  
            debug = (0==arg) ? DISABLE : ENABLE;  
            break;  
        case GET_DRV_VER:  
            print_version(DRV_VERSION);  
            return DRV_VERSION;  
  
        case LED_OFF:  
            if(pdata->nleds <= arg)  
            {  
               printk("LED%ld doesn't exist\n", arg);    
               return -ENOTTY;  
            }  
            pdata->leds[arg].status = OFF;  
            pdata->leds[arg].blink = DISABLE;  
            break;  
  
        case LED_ON:  
            if(pdata->nleds <= arg)  
            {  
               printk("LED%ld doesn't exist\n", arg);    
               return -ENOTTY;  
            }  
            pdata->leds[arg].status = ON;  
            pdata->leds[arg].blink = DISABLE;  
            break;  
  
        case LED_BLINK:  
            if(pdata->nleds <= arg)  
            {  
               printk("LED%ld doesn't exist\n", arg);    
               return -ENOTTY;  
            }  
            pdata->leds[arg].blink = ENABLE;  
            pdata->leds[arg].status = ON;  
            break;  
  
        default:   
            dbg_print("%s driver don't support ioctl command=%d\n", DEV_NAME, cmd);   
            print_led_help();  
            return -EINVAL;  
  
    }  
    return 0;  
}  
  
  
static struct file_operations led_fops = {   
    .owner = THIS_MODULE,   
    .open = led_open,   
    .release = led_release,   
    .unlocked_ioctl = led_ioctl, /* compatible with kernel version >=2.6.38*/  
};  
  
  
static int s3c_led_probe(struct platform_device *dev) //设备和驱动相互识别是调用由内核把platform_device传到probe函数  
{  
    struct s3c_led_platform_data *pdata = dev->dev.platform_data;   
    int result = 0;  
    int i;  
    dev_t devno;  
  
    /* Initialize the LED status */  
    for(i=0; i<pdata->nleds; i++)  
    {  
         s3c2410_gpio_cfgpin(pdata->leds[i].gpio, S3C2410_GPIO_OUTPUT);  
         if(ON == pdata->leds[i].status)  
         {  
            s3c2410_gpio_setpin(pdata->leds[i].gpio, pdata->leds[i].active_level);   
         }  
         else  
         {  
            s3c2410_gpio_setpin(pdata->leds[i].gpio, ~pdata->leds[i].active_level);   
         }  
    }  
  
    /*  Alloc the device for driver */  
    if (0 != dev_major)   
    {   
        devno = MKDEV(dev_major, dev_minor);   
        result = register_chrdev_region(devno, 1, DEV_NAME);   
    }   
    else   //动态分配主次设备号 
    {   
        result = alloc_chrdev_region(&devno, dev_minor, 1, DEV_NAME);   
        dev_major = MAJOR(devno);   
    }  
  
    /* Alloc for device major failure */   
    if (result < 0)   
    {   
        printk("%s driver can't get major %d\n", DEV_NAME, dev_major);   
        return result;   
    }  
  
    /* Initialize button structure and register cdev*/  
    memset(&led_device, 0, sizeof(led_device));  
    led_device.data = dev->dev.platform_data;  
    cdev_init (&(led_device.cdev), &led_fops);  
    led_device.cdev.owner  = THIS_MODULE;  
  
    result = cdev_add (&(led_device.cdev), devno , 1);   
    if (result)   
    {   
        printk (KERN_NOTICE "error %d add %s device", result, DEV_NAME);   
        goto ERROR;   
    }   
      
    led_device.dev_class = class_create(THIS_MODULE, DEV_NAME);   
    if(IS_ERR(led_device.dev_class))   
    {   
        printk("%s driver create class failture\n",DEV_NAME);   
        result =  -ENOMEM;   
        goto ERROR;   
    }  
  
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)       
   
  
    device_create(led_device.dev_class, NULL, MKDEV(dev_major,0), NULL, DEV_NAME);  
  
#else  
    device_create (led_device.dev_class, NULL, MKDEV(dev_major,0), DEV_NAME);  
#endif  
  
    /*  Initial the LED blink timer 初始化闪烁定时器 */  
    init_timer(&(led_device.blink_timer));  
    led_device.blink_timer.function = led_timer_handler;  
    led_device.blink_timer.data = (unsigned long)pdata;  
    led_device.blink_timer.expires  = jiffies + TIMER_TIMEOUT;//jiffies为当前时间  
    add_timer(&(led_device.blink_timer));   
  
    printk("S3C %s driver version %d.%d.%d initiliazed.\n", DEV_NAME, DRV_MAJOR_VER, DRV_MINOR_VER, DRV_REVER_VER);   
  
    return 0;  
                 
  
ERROR:   
    printk("S3C %s driver version %d.%d.%d install failure.\n", DEV_NAME, DRV_MAJOR_VER, DRV_MINOR_VER, DRV_REVER_VER);   
    cdev_del(&(led_device.cdev));   
  
    unregister_chrdev_region(devno, 1);   
    return result;  
  
}  
  
static int s3c_led_remove(struct platform_device *dev)  //释放主次设备号给Linux内核
{  
    dev_t devno = MKDEV(dev_major, dev_minor);  
  
    del_timer(&(led_device.blink_timer));  
  
    cdev_del(&(led_device.cdev));   
    //for()  
    device_destroy(led_device.dev_class, devno);   
    class_destroy(led_device.dev_class);   
      
    unregister_chrdev_region(devno, 1);   
    printk("S3C %s driver removed\n", DEV_NAME);  
  
    return 0;  
}  
  
  
static struct platform_driver s3c_led_driver = {   //定义总线驱动结构体 
    .probe      = s3c_led_probe,   //注册设备主次设备号
    .remove     = s3c_led_remove,   
    .driver     = {   
        .name       = "s3c_led",   
        .owner      = THIS_MODULE,   
    },  
};  
  
  
static int __init s3c_led_init(void)  
{  
   int       ret = 0;  
  
   ret = platform_device_register(&s3c_led_device);  
   if(ret)  
   {  
        printk(KERN_ERR "%s:%d: Can't register platform device %d\n", __FUNCTION__,__LINE__, ret);   
        goto fail_reg_plat_dev;  
   }  
   dbg_print("Regist S3C LED Platform Device successfully.\n");  
  
   ret = platform_driver_register(&s3c_led_driver);  
   if(ret)  
   {  
        printk(KERN_ERR "%s:%d: Can't register platform driver %d\n", __FUNCTION__,__LINE__, ret);   
        goto fail_reg_plat_drv;  
   }  
   dbg_print("Regist S3C LED Platform Driver successfully.\n");  
  
   return 0;  
  
fail_reg_plat_drv:  
   platform_driver_unregister(&s3c_led_driver);  
fail_reg_plat_dev:  
   return ret;  
}  
  
  
static void s3c_led_exit(void)  
{  
    dbg_print("%s():%d remove LED platform drvier\n", __FUNCTION__,__LINE__);  
    platform_driver_unregister(&s3c_led_driver);  
    dbg_print("%s():%d remove LED platform device\n", __FUNCTION__,__LINE__);  
    platform_device_unregister(&s3c_led_device);  
}  
  
module_init(s3c_led_init);  
module_exit(s3c_led_exit);  
  
module_param(debug, int, S_IRUGO);  
module_param(dev_major, int, S_IRUGO);  
module_param(dev_minor, int, S_IRUGO);  
  
MODULE_AUTHOR(DRV_AUTHOR);  
MODULE_DESCRIPTION(DRV_DESC);  
MODULE_LICENSE("GPL");  
MODULE_ALIAS("platform:S3C24XX_led");  

Makefile:

obj-m:=plat_led.c  
C=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc  
KDIR?=/home/fanmaolin/fl2440/kernel/linux-3.0  
obj-m:=plat_led.o  
   
default:  
        $(MAKE) -C $(KDIR) M=`pwd` modules  
        make clean  
   
clean:  
        rm -f *.o *mod.c *.order *.symvers  


make


测试程序vim plat_ioctl.c:

 1 /*********************************************************************************
  2  *      Copyright:  (C) 2017 fanmaolin<fanmaolinn@gmail.com>
  3  *                  All rights reserved.
  4  *
  5  *       Filename:  plat_testled.c
  6  *    Description:  This file 
  7  *                 
  8  *        Version:  1.0.0(03/25/2017)
  9  *         Author:  fanmaolin <fanmaolinn@gmail.com>
        
 10  *      ChangeLog:  1, Release initial version on "03/25/2017 05:24:09 PM"
 11  *                 
 12  ********************************************************************************/
 13 
 14 #include <stdio.h>
 15 #include <stdarg.h>
 16 #include <fcntl.h>
 17 #include <sys/types.h>
 18 #include <errno.h>
 19 #include <sys/ioctl.h>
 20 #include <sys/stat.h>
 21 #include <unistd.h>
 22 #include <stdlib.h>
 23 #define PLATDRV_MAGIC             0x60  
 24 #define LED_OFF                   _IO (PLATDRV_MAGIC, 0x18)  
 25 #define LED_ON                    _IO (PLATDRV_MAGIC, 0x19)  
 26 #define LED_BLINK                 _IO (PLATDRV_MAGIC, 0x1A)  
 27 #define  DEVNAMELEN 10  
 28 int main (int argc,char **argv)
 29 {
 30         int fd;
 31         fd=open("dev/led",O_RDWR);
 32         ioctl(fd,LED_ON,0);
 33         ioctl(fd,LED_BLINK,1);
 34         ioctl(fd,LED_ON,2);
 35         ioctl(fd,LED_BLINK,4);
 36         close(fd);
 37         return 0;
 38 }


[fanmaolin@Centeros platform]$ /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc plat_testled.c 

编译后在开发板上操作,与之前不同的是这一次程序中有了自动挂载的代码

   
    led_device.dev_class = class_create(THIS_MODULE, DEV_NAME);   
    if(IS_ERR(led_device.dev_class))   
    {   
        printk("%s driver create class failture\n",DEV_NAME);   
        result =  -ENOMEM;   
        goto ERROR;   
    }  
  
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)       
   
  
    device_create(led_device.dev_class, NULL, MKDEV(dev_major,0), NULL, DEV_NAME);  
  
#else  
    device_create (led_device.dev_class, NULL, MKDEV(dev_major,0), DEV_NAME);  
#endif  
  



>: tftp -gr a.out 192.168.1.2
a.out                100% |*******************************|  5139   0:00:00 ETA

>: insmod plat_led.ko 
S3C led driver version 1.0.0 initiliazed.
>: ./a.out 

你会看到1、3灯常亮,2、4灯闪烁

问题总结分析:

[fanmaolin@Centeros platform]$ make
make -C /home/fanmaolin/fl2440/kernel/linux-3.0   M=`pwd` modules 
make[1]: Entering directory `/home/fanmaolin/fl2440/kernel/linux-3.0'
  CC [M]  /home/fanmaolin/fl2440/driver/led/platform/plat_led.o
/home/fanmaolin/fl2440/driver/led/platform/plat_led.c:1:26: fatal error: s3c_driver.h: No such file or directory
compilation terminated.
make[2]: *** [/home/fanmaolin/fl2440/driver/led/platform/plat_led.o] Error 1
make[1]: *** [_module_/home/fanmaolin/fl2440/driver/led/platform] Error 2
make[1]: Leaving directory `/home/fanmaolin/fl2440/kernel/linux-3.0'
make: *** [default] Error 2
缺少部分头文件,加在当前目录下即可参考http://blueshaw.blog.163.com/blog/static/21633118120138249298645/头文件的有关知识

s3c_drive.h:

#ifndef __S3C_DRIVER_H  
#define __S3C_DRIVER_H  
  
#include <linux/version.h>  
#include <linux/kernel.h>  
#include <linux/errno.h>  
#include <linux/init.h>  
#include <linux/slab.h>  
#include <linux/module.h>  
#include <linux/kref.h>  
#include <linux/spinlock.h>  
#include <asm/uaccess.h>  
#include <linux/mutex.h>  
#include <linux/delay.h>  
#include <linux/fs.h>  
#include <linux/device.h>  
#include <linux/i2c.h>  
#include <linux/string.h>  
#include <linux/bcd.h>  
#include <linux/miscdevice.h>  
#include <linux/poll.h>  
#include <linux/irq.h>  
#include <linux/interrupt.h>  
#include <linux/sysfs.h>  
#include <linux/proc_fs.h>  
#include <linux/rtc.h>  
#include <linux/spinlock.h>  
#include <linux/usb.h>  
#include <asm/uaccess.h>  
#include <asm/delay.h>  
#include <linux/syscalls.h>  /* For sys_access*/  
#include <linux/platform_device.h>  
#include <linux/unistd.h>  
#include <linux/tty.h>  
#include <linux/tty_flip.h>  
#include <linux/serial.h>  
#include <linux/serial_core.h>  
#include <linux/irq.h>  
#include <mach/regs-gpio.h>  
  
  
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)  
#include <mach/hardware.h>  
#include <mach/gpio.h>  
#include <asm/irq.h>  
#else  
#include <asm-arm/irq.h>  
#include <asm/arch/gpio.h>  
#include <asm/arch/hardware.h>  
#endif  
#include "plat_ioctl.h"  
  
/* =========================================================================== 
 *  *         S3C24XX device driver common macro definition 
 *   *===========================================================================*/  
  
#define ENPULLUP                    1  
#define DISPULLUP                   0  
  
#define HIGHLEVEL                   1  
#define LOWLEVEL                    0  
  
#define INPUT                       1  
#define OUTPUT                      0  
  
#define OFF                         0  
#define ON                          1  
  
#define ENABLE                      1  
#define DISABLE                     0  
  
#define TRUE                        1  
#define FALSE                       0  
  
/* =========================================================================== 
 *  *         S3C24XX device driver name and Major number define 
 *   *===========================================================================*/  
  
  
#define DEV_LED_NAME                "led"  
#define DEV_LED_MAJOR               203  
  
#define DEV_BUTTON_NAME             "button"  
#define DEV_BUTTON_MAJOR            "211"  
  
#define DEV_ADC_NAME                "adc"  
#define DEV_ADC_MAJOR               "212"  
  
/*  ***** Bit Operate Define *****/  
#define SET_BIT(data, i)   ((data) |=  (1 << (i)))    /*   Set the bit "i" in "data" to 1  */  
#define CLR_BIT(data, i)   ((data) &= ~(1 << (i)))    /*   Clear the bit "i" in "data" to 0 */  
#define NOT_BIT(data, i)   ((data) ^=  (1 << (i)))    /*   Inverse the bit "i" in "data"  */  
#define GET_BIT(data, i)   ((data) >> (i) & 1)        /*   Get the value of bit "i"  in "data" */  
#define L_SHIFT(data, i)   ((data) << (i))            /*   Shift "data" left for "i" bit  */  
#define R_SHIFT(data, i)   ((data) >> (i))            /*   Shift "data" Right for "i" bit  */  
  
  
/* =========================================================================== 
 *  *         S3C24XX device driver common function definition 
 *   *===========================================================================*/  
  
#define SLEEP(x)    {DECLARE_WAIT_QUEUE_HEAD (stSleep); if (10 > x) mdelay ((x * 1000)); \  
                        else wait_event_interruptible_timeout (stSleep, 0, (x / 10));}  
  
#define VERSION_CODE(a,b,c)       ( ((a)<<16) + ((b)<<8) + (c))  
#define DRV_VERSION               VERSION_CODE(DRV_MAJOR_VER, DRV_MINOR_VER, DRV_REVER_VER)  
#define MAJOR_VER(a)              ((a)>>16&0xFF)  
#define MINOR_VER(a)              ((a)>>8&0xFF)  
#define REVER_VER(a)              ((a)&0xFF)  
  
#define dbg_print(format,args...) if(DISABLE!=debug) \  
        {printk("[kernel] ");printk(format, ##args);}  
  
static inline void print_version(int version)  
{  
#ifdef __KERNEL__  
        printk("%d.%d.%d\n", MAJOR_VER(version), MINOR_VER(version), REVER_VER(version));  
#else  
        printf("%d.%d.%d\n", MAJOR_VER(version), MINOR_VER(version), REVER_VER(version));  
#endif  
}  
  
  
#endif /* __S3C_DRIVER_H */  

plat_ioctl.h:

  1. #ifndef __PLAT_IOCTL_H  
  2. #define __PLAT_IOCTL_H  
  3.   
  4. #include <asm/ioctl.h>  
  5.   
  6. /*=========================================================================== 
  7.  *  *                Common ioctl command definition 
  8.  *   *===========================================================================*/  
  9.   
  10. #define PLATDRV_MAGIC           0x60  
  11.   
  12. /*=========================================================================== 
  13.  *  *                 ioctl command for all the drivers 0x01~0x0F 
  14.  *   *===========================================================================*/  
  15.   
  16. /*args is enable or disable*/  
  17. #define SET_DRV_DEBUG               _IO (PLATDRV_MAGIC, 0x01)  
  18. #define GET_DRV_VER                 _IO (PLATDRV_MAGIC, 0x02)  
  19.   
  20. /*=========================================================================== 
  21.  *  *                 ioctl command for few ioctl() cmd driver 0x10~0x2F 
  22.  *   *===========================================================================*/  
  23.   
  24. /* LED driver */  
  25. #define LED_OFF                     _IO (PLATDRV_MAGIC, 0x18)  
  26. #define LED_ON                      _IO (PLATDRV_MAGIC, 0x19)  
  27. #define LED_BLINK                   _IO (PLATDRV_MAGIC, 0x1A)  
  28. #define ADC_SET_CHANNEL             _IO (PLATDRV_MAGIC, 0x1B)  
  29.   
  30. /*=========================================================================== 
  31.  *  *                   ioctl command for GPRS driver 0x30~0x4F 
  32.  *   *===========================================================================*/  
  33. #define GPRS_POWERDOWN              _IO (PLATDRV_MAGIC, 0x30)  
  34. #define GPRS_POWERON                _IO (PLATDRV_MAGIC, 0x31)  
  35. #define GPRS_RESET                  _IO (PLATDRV_MAGIC, 0x32)  
  36. #define GPRS_POWERMON               _IO (PLATDRV_MAGIC, 0x33)  
  37. #define GPRS_CHK_SIMDOOR            _IO (PLATDRV_MAGIC, 0x36)  
  38. #define GPRS_SET_DTR                _IO (PLATDRV_MAGIC, 0x37)  
  39. #define GPRS_SET_RTS                _IO (PLATDRV_MAGIC, 0x38)  
  40. #define GPRS_GET_RING               _IO (PLATDRV_MAGIC, 0x39)  
  41. #define SET_PWUP_TIME               _IO (PLATDRV_MAGIC, 0x3A)  
  42. #define SET_PWDOWN_TIME             _IO (PLATDRV_MAGIC, 0x3B)  
  43. #define SET_RESET_TIME              _IO (PLATDRV_MAGIC, 0x3C)  
  44. #define GPRS_CHK_MODEL              _IO (PLATDRV_MAGIC, 0x3E)  
  45.   
  46. /*=========================================================================== 
  47.  *  *                   ioctl command for EEPROM driver 0x50~0x5F 
  48.  *   *===========================================================================*/  
  49. #define LL_POWEROFF                 _IO (PLATDRV_MAGIC, 0x50)  
  50. #define LL_POWERON                  _IO (PLATDRV_MAGIC, 0x51)  
  51. #define LL_STOP                     _IO (PLATDRV_MAGIC, 0x52)  
  52. #define LL_START                    _IO (PLATDRV_MAGIC, 0x53)  
  53. #define LL_READ                     _IO (PLATDRV_MAGIC, 0x54)  
  54. #define LL_WRITE                    _IO (PLATDRV_MAGIC, 0x55)  
  55. #define LL_DATALOW                  _IO (PLATDRV_MAGIC, 0x56)  
  56. #define LL_ACKNAK                   _IO (PLATDRV_MAGIC, 0x57)  
  57.   
  58.   
  59. #endif                          /* __PLAT_IOCTL_H */  







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值