platform中的device 、driver的写法

开发环境:OK6410板卡,linux2.6.36 

  Device 和Driver 分成两个文件编写生成两个.ko文件,其中二者的名称必须完全一致;安装驱动成功后会调用driver的probe函数,卸载驱动时会调用driver的remove函数和device 的Release函数。

  

 driver如下:

struct input_dev *button_dev = NULL;
struct timer_list  button_timer;
volatile  struct gpio_keys_button *irq_pd = NULL;
struct gpio_keys_platform_data *platform_data = NULL;

volatile unsigned int __iomem *gpn0_base =NULL;
static irqreturn_t  button_isr(int irq ,void* devid )
{
  //devid 传按键的首地址
  irq_pd = (struct gpio_keys_button*)devid;
  mod_timer(&button_timer,  jiffies+HZ/100);   
  return IRQ_HANDLED;
}
void button_timer_function (unsigned long data)
{
   unsigned int pinval;
   volatile unsigned int __iomem* gpn0_con = gpn0_base;
   volatile unsigned int __iomem* gpn0_dat = gpn0_con+1;
   int index = 0;
   unsigned int con_tmp = 0;
   struct gpio_keys_button  *pdesc = (struct gpio_keys_button  *)irq_pd;
   if(!pdesc) return ;  
   index = pdesc->gpio - S3C64XX_GPN(0);
   con_tmp = *gpn0_con;
   *gpn0_con&= (0x0f<< (2*index)  ); //设置输入模式
   pinval = *gpn0_dat &(  0x00000000 | (0x01 << index) );
   *gpn0_con = con_tmp; //恢复
   pinval>>= index;
   if( !pinval)
   {
           input_event(button_dev , pdesc->type, pdesc->code,pinval);//低电平
           input_event(button_dev, EV_SYN,0,0);       
   }
   else
   {
        input_event(button_dev , pdesc->type, pdesc->code,pinval);//高电平
        input_event(button_dev, EV_SYN,0,0);          
   }   
}
static int kx_key_open(struct input_dev *pdev)
{            
    init_timer(& button_timer);
    //button_timer.expires = jiffies+HZ*5;
    button_timer.function = button_timer_function;
    //button_timer.data = 100;
    add_timer(&button_timer);
    printk("kx_key_open\n"); 
    return 0;
}
 
static void kx_key_release(struct input_dev *dev);

static int __devinit gpio_keys_probe(struct platform_device *pdev)
{    
   int i = 0;
    int err;
    unsigned int irq;    
    platform_data = pdev->dev.platform_data;
       gpn0_base = ioremap(0x7F008830 , 12) ;
    button_dev=input_allocate_device();    
    if(!button_dev)
    {    
        return -ENOMEM;    
    }
    set_bit(EV_KEY,button_dev->evbit);    
    set_bit(EV_SYN,button_dev->evbit);    
    for(i = 0; i< platform_data->nbuttons ; i++)
    {
      set_bit(platform_data->buttons[i].code ,button_dev->keybit);
    }
    
    button_dev->name=pdev->name ;    
    button_dev->phys = "gpio-keys/input0";
    button_dev->dev.parent = &pdev->dev;
    button_dev->open=kx_key_open;    
    button_dev->close=kx_key_release;    
    err=input_register_device(button_dev);    
    if(err)
    {    
      return err;    
    }
     

    for(i = 0; i< platform_data->nbuttons ; i++)
    {    
      irq = gpio_to_irq(platform_data->buttons[i].gpio);     
      err = request_irq( irq ,button_isr,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
      platform_data->buttons[i].desc,&platform_data->buttons[i]);    
    }
    
  printk("---gpio_keys_probe-----\n");
  return 0;

}
static void kx_key_release(struct input_dev *dev)
{

  printk("kx_key_release \n");
}

static int __devexit gpio_keys_remove(struct platform_device *pdev)
{

      int i;
      int irq;
        //注销中断
      for(i = 0; i< platform_data->nbuttons ; i++)
      {                
          irq = gpio_to_irq(platform_data->buttons[i].gpio);
          //disable_irq_nosync(irq);
          free_irq(irq,&platform_data->buttons[i] );
      }
      del_timer(&button_timer); 
      input_unregister_device( button_dev);     
      input_free_device(button_dev ) ;
      iounmap(gpn0_base);

printk("-----gpio_keys_remove\n");
   return 0;
}


static struct platform_driver gpio_keys_device_driver = {
    .probe        = gpio_keys_probe,
    .remove        = __devexit_p(gpio_keys_remove),
     
    .driver        = {
        .name    = "kx-key-pad",
        .owner    = THIS_MODULE,
#ifdef CONFIG_PM
        .pm    = &gpio_keys_pm_ops,
#endif
    }
};

static int __init gpio_keys_init(void)
{
    return platform_driver_register(&gpio_keys_device_driver);
}

static void __exit gpio_keys_exit(void)
{
    platform_driver_unregister(&gpio_keys_device_driver);
}

module_init(gpio_keys_init);
module_exit(gpio_keys_exit);

 

device 如下:

static struct gpio_keys_button kx_buttons[] = {
    {
        .gpio            = S3C64XX_GPN(0),
        .code            = KEY_UP,
        .desc            = "Power",
        .active_low        = 1,
        .debounce_interval    = 5,
        .type                   = EV_KEY,
    },
    {
        .gpio            = S3C64XX_GPN(1),
        .code            = KEY_FN,
        .desc            = "Function",
        .active_low        = 1,
        .debounce_interval    = 5,
        .type                   = EV_KEY,
    },
    {
        .gpio            = S3C64XX_GPN(2),
        .code            = KEY_KPMINUS,
        .desc            = "Minus",
        .active_low        = 1,
        .debounce_interval    = 5,
        .type                   = EV_KEY,
    },
    {
        .gpio            = S3C64XX_GPN(3),
        .code            = KEY_KPPLUS,
        .desc            = "Plus",
        .active_low        = 1,
        .debounce_interval    = 5,
        .type                   = EV_KEY,
    },
    {
        .gpio            = S3C64XX_GPN(4),
        .code            = KEY_ENTER,
        .desc            = "Enter",
        .active_low        = 1,
        .debounce_interval    = 5,
        .type                   = EV_KEY,
    },
    {
        .gpio            = S3C64XX_GPN(5),
        .code            = KEY_ESC,
        .desc            = "Cancel",
        .active_low        = 1,
        .debounce_interval    = 5,
        .type                   = EV_KEY,
    },
};

void plat_key_release(struct device *dev)
{
  printk( "plat_key_release\n");     
}

static struct gpio_keys_platform_data kx_buttons_data  = {
    .buttons    = kx_buttons,
    .nbuttons    = ARRAY_SIZE(kx_buttons),
};

static struct platform_device kx_buttons_device  = {
    .name        = "kx-key-pad",
    .id        = 0,
    .num_resources    = 0,
    .dev        = {
        .platform_data    = &kx_buttons_data,
        .release = &plat_key_release,     
    }
};

static int __init plat_key_dev_init(void)
{    
    platform_device_register(&kx_buttons_device);    return 0;
}

static void __exit plat_key_dev_exit(void)
{
    platform_device_unregister(&kx_buttons_device);
}

module_init(plat_key_dev_init);
module_exit(plat_key_dev_exit);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值