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中的name找device device没有.c文件在machine_init调用platform_add_devices添加device,platform_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);

时间: 2024-12-20 17:50:10

platform 总线input子系统上的按键中断的相关文章

Linux input 子系统应用之按键驱动

硬件平台:s5pv210 软件平台:Linux2.6.35.7 应用程序:inputk2_app.c #include <stdio.h> #include <fcntl.h> #include <linux/input.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char** argv) { int fd; int count; int i = 0; int

ARM实验5 —— 按键中断实验

key_int按键中断实验 实验内容: 通过开发板上的按键中断控制led灯并打印信息. 通过简单事例说明猎户座4412处理器的GIC中断处理的应用,设置key2按键连接的引脚为中断模式,当识别按键被按下时进入相应的中断处理函数 实验目的: 熟悉开发环境的使用 掌握猎户座4412处理器的中断过程及编程. 实验平台: fs4412开发板,eclipse,secureCRT. 实验步骤: 1.查看key2在开发板的位置: 2.查看UART_RING在核心板的位置: 3.查看GPX1在芯片手册的位置:

ARM Linux 驱动Input子系统之按键驱动测试

上一篇已经谈过,在现内核的中引入设备树之后对于内核驱动的编写,主要集中在硬件接口的配置上了即xxxx.dts文件的编写. 在自己的开发板上移植按键驱动: 1.根据开发板的原理图 确定按键的硬件接口为:GPIO2_2.GPIO2_3.GPIO2_5.GPIO0_30. 修改dts文件使其与原理图的按键接口一致. gpio_buttons: [email protected]0 { compatible = "gpio-keys"; #address-cells = <1>;

总结INPUT子系统设计(重要)

INPUT子系统 一:什么是Input子系统? (应用场景,用途) 二:怎么设计Input子系统的程序? (分配一个输入设备——注册一个输入设备——上报输入事件——注销一个输入设备——释放一个输入设备) 三:Input子系统需要知道哪些? (涉及的重要数据结构(input_dev,input_handle,input_handler),中断的相关知识) 四:一个自带按键驱动分析 (linux-4.5/drivers/input/keyboard下的amikbd.c ) 五:模拟实现案例 (通过e

linux kernel input 子系统分析

Linux 内核为了处理各种不同类型的的输入设备 , 比如说鼠标 , 键盘 , 操纵杆 , 触摸屏 , 设计并实现了一个对上层应用统一的试图的抽象层 , 即是Linux 输入子系统 . 输入子系统的层次结构体如下 从底层到上层 , input 子系统由 设备驱动层 , 核心层 , 以及事件处理层3个部分组成 当一个鼠标移动, 一个按键按下或弹起 , 它都需要从底层设备驱动-->核心层-->事件处理层 -->用户空间 , 层层上报 , 一直到运用程序. 应用这个input  子系统有如下优

input子系统(二)

二.内核代码 2.1输入子系统设备驱动层 我们先从设备驱动层进行讲解 首先设备驱动层调用input_allocate_device进行申请input_dev结构体,接着对该结构体进行赋值,然后调用input_register_device进行注册设备.同时我们在open函数里定义中断函数,中断函数里实现input_report_key的操作,向核心层报告按键消息. 通过上面分析我们主要关注input_allocate_device.input_register_device和input_repo

linux input输入子系统分析《四》:input子系统整体流程全面分析

1      input输入子系统整体流程 本节分析input子系统在内核中的实现,包括输入子系统(Input Core),事件处理层(Event Handler)和设备驱动层.由于上节代码讲解了设备驱动层的写法,因此在开头部分会从设备驱动层做为线索,分析输入子系统和事件处理层是如何配合的,最后从用户角度出发,从"/dev/input/*"接口如何使用输入子系统提供的服务. 既然需要详细分析,有一个这样的流程图能够帮助我们在被绕进代码的过程中,找到出口,你能够知道你现在位于代码框架的什

input子系统详解2

上一节大概了解了输入子系统的流程 这一节认真追踪一下代码 input.c: input_init(void)函数 1 static int __init input_init(void) 2 { 3 int err; 4 5 err = class_register(&input_class); 6 if (err) { 7 printk(KERN_ERR "input: unable to register input_dev class\n"); 8 return err;

input子系统详解

一.初识linux输入子系统 linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(InputCore)和输入子系统设备驱动层. 对于输入子系统设备驱动层而言,主要实现对硬件设备的读写访问,中断设置,并把硬件产生的事件转换为核心层定义的规范提交给事件处理层.即将底层的硬件输入转化为统一事件形式,想输入核心(Input Core)汇报. 对于核心层而言,为设备驱动层提供了规范和接口.设备驱动