首页 > 代码库 > platform 总线input子系统上的按键中断

platform 总线input子系统上的按键中断

什么时候唤醒?

报告事件input_event(dev,x)  input_event(dev,y) input_event(dev,SYN)

--------------------

 

Linux内核中的总线设备驱动

 

总线   include/device.h

Struct bus_type

{

   Name;

   Match;//(匹配规则,匹配设备和设备驱动)

}

注册:bus_register(....)

注销:bus_unregister(。。。);

设备

Struct device{

 Struct bus_type *bus

};

device_register(...);

device_unregister(...);

 

Device.bus =&i2c_bus_type

 

Device_register(...)

 

设备驱动

 

Struct device_driver{

Name;

Probe;

Remove;

 

Struct bus_type *bus

}

Driver_register(...);

Driver_unregister(...);

 

 

 

2,平台设备总线:

 Platform总线 bus_type

总线   driver/base/platform.c

struct bus_type platform_bus_type = {

.name= "platform",

.dev_attrs= platform_dev_attrs,

.match= platform_match,

.uevent= platform_uevent,

.pm= &platform_dev_pm_ops,

};

 

设备

 

 Platform_device_register()

Platform_device

 

 

设备驱动

 

Platform_driver_register

 

Platform_driver

Device_driver

 

 

Platform_match

 两边的name对比

之后probe函数

当有一方注销时

Remove函数会被调用

Gpio_get_value

反思:

平台设备总线架构有什么作用

 

便于你的驱动程序的移植和管理, 2.6以后才出现的

跟最小系统无关的硬件设备都可以按照平台设备架构来编写

 

 

 

Input子系统架构有什么作用

二者之间有什么关系

Input子系统在解决什么问题

平台设备架构在解决什么问题?

 

 

 

内核中自带的按键驱动程序:

     make menuconfig  找到对应的 * help就可以显示路径查找到他们了

例:路径:drivers/input/keyboard变量:CINFIG_KEYBOARD_S3C_GPIO

在路径下的makefile中找到变量找到对应的.o文件

是按照平台总线架构完成的

总线platform,设备,设备驱动gpio。。。。。C

根据driver中的namedevice device没有.c文件在machine_init调用platform_add_devices添加deviceplatform_add_devices中有driver_register(

 

     

 

   Platform_driver_register

  ->driver_register

  ->bus_add_driver

  ->driver_attach

->bus_for_each_dev(drv->bus,NULL,drv,__driver_attch)

->__driver_attch

->driver_match_device

->driver_probe_device

->really_probe

->drv->probe

 

  

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/cdev.h>

#include <linux/device.h>

#include <linux/interrupt.h>

#include <linux/stat.h>

#include <linux/slab.h>

 

//#include <linux/unicore.h>

 

#include <linux/gpio.h>

#include <linux/moduleparam.h>

#include <linux/kdev_t.h>

#include <linux/delay.h>

#include <linux/wait.h>

#include <linux/sched.h>

#include <linux/input.h>

 

#include <linux/platform_device.h>

#include <mach/regs-gpio.h>

 

#include <linux/regulator/consumer.h>

#include <linux/delay.h>

 

 

#include <linux/interrupt.h>

#include <linux/irq.h>

 

 

 

#include <mach/gpio-exynos4.h>

 

#include <asm/gpio.h>

#include <asm/io.h>

 

#include <plat/gpio-cfg.h>

#define GPX1_1_IRQ S3C_GPIO_SFN(0xF)

#define DRIVER_NAME "button_irq"

 

MODULE_LICENSE("Dual BSD/GPL");

/*声明是开源的,没有内核版本限制*/

MODULE_AUTHOR("songmao");

/*声明作者*/

 

struct input_dev *my_input=NULL;

 

struct timer_list pin_timer;

 

struct pin_desc

{

    int irq;

unsigned int pin;

char *name;

char *label;

unsigned int value;

};

struct pin_desc pindesc[]={

     {IRQ_EINT(9),EXYNOS4_GPX1(2),"key_home","EINT9",KEY_HOME},

};

 

volatile struct pin_desc *irq_pd = NULL;

 

static irqreturn_t plat_irq_handled (int irq,void *dev_id)

{

     irq_pd = (volatile struct pin_desc *)dev_id;

 

     mod_timer(&pin_timer,jiffies+HZ/100);

 

     return IRQ_HANDLED;

}

 

static void pin_timer_functions(unsigned int data)

{

    unsigned int pinval = 0;

struct pin_desc *pindescs = (volatile struct pin_desc *)irq_pd;

 

if(!pindescs)

{

     return 0;


}

 

unsigned int con_temp = 0;

    con_temp=gpio_get_value(pindescs->pin);

if(con_temp)

{

     input_event(my_input,EV_KEY,pindesc[0].value,0);

 input_event(my_input,EV_SYN,pindesc[0].value,0);

}

else

{

   printk(KERN_WARNING "My_plat_irq:no input_event");

}




}

static int my_plat_irq_probe(struct platform_device *dev)

{

 

int ret=0;

    my_input=input_allocate_device();

if(my_input==NULL)

{

     printk(KERN_ERR "My_plat_irq: Failure is input_allocate_device ");

}

printk(KERN_INFO"My_plat_irq: Success is input_allocate_device ");

 

    

    set_bit(EV_KEY,my_input->evbit);

    set_bit(EV_SYN,my_input->evbit);

    set_bit(KEY_HOME,my_input->keybit);

 

my_input->name = "my_inpt_irq";

 

ret=input_register_device(&my_input);

    if(ret<0)

    {

           printk(KERN_ERR"My_plat_irq:Failure is input_register_device");

   goto fail_input_register;

    }

printk(KERN_INFO"My_plat_irq:Success is input_register_device");

 

ret = gpio_request(pindesc[0].pin,pindesc[0].label);

if(ret)

{

       printk(KERN_ERR"My_plat_irq:Failure is gpio_request");

   goto fail_gpio_request;

}

    printk(KERN_INFO"My_plat_irq:Success is gpio_request");


s3c_gpio_cfgpin(pindesc[0].pin,GPX1_1_IRQ);

s3c_gpio_setpull(pindesc[0].pin,S3C_GPIO_PULL_UP);


 

ret=request_irq(pindesc[0].irq,plat_irq_handled,IRQF_TRIGGER_FALLING,pindesc[0].name,pindesc);

    if(ret<0)

    {

           printk(KERN_ERR"My_plat_irq:Failure is request_irq");

   goto fail_request_irq;

    }

 

init_timer(&pin_timer);

pin_timer.function = pin_timer_functions;

add_timer(&pin_timer);


    return 0;

 

fail_request_irq:

 

gpio_free(pindesc[0].pin);

 

 

fail_gpio_request:

 

    input_unregister_device(&my_input);

 

fail_input_register:


input_free_device(&my_input);

 

 

}

static int my_plat_irq_remove(struct platform_device *dev)

{

 

    return 0;

}

 

static struct platform_driver my_plat_irq = {

    .probe=my_plat_irq_probe,

.remove=my_plat_irq_remove,

.driver = {

                .name = DRIVER_NAME,

                .owner = THIS_MODULE,

        },


 

    /*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 (*resume)(struct platform_device *);

struct device_driver driver;

const struct platform_device_id *id_table;   */

 

};

 

 

static int __init init_my_plat_irq(void)

{

    int ret;

ret = platform_driver_register( &my_plat_irq);

return 0;

}

static void __exit exit_my_plat_irq (void)

{

gpio_free(pindesc[0].pin);


input_unregister_device(&my_input);


input_free_device(&my_input);

}

 

module(init_my_plat_irq);

module(exit_my_plat_irq);

 


本文出自 “毛散人” 博客,请务必保留此出处http://songmao.blog.51cto.com/11700139/1879941

platform 总线input子系统上的按键中断