一 input系统结构

在linux系统中 鼠标、键盘、蜂鸣器、触摸屏、传感器等设备都是输入设备,这些设备通过输入子系统接收或发送数据到用户态。输入子系统又叫 input 子系统,其构建非常灵活,只需要调用一些简单的函数,就可以将一个输入设备的功能呈现给应用程序。


二 驱动层

传感器作为一种输入设备,也是通过input系统把其数据上报给系统,或者通过input系统得到用户的配置信息。这里以传感器为例学习input driver层。从代码角度来看sensor工作流程如下(以地磁传感器akm09911为例):

module_init(akm_compass_init);

static int __init    akm_compass_init(void)

{

    pr_info("AKMcompass driver: initialize.");

    returni2c_add_driver(&akm_compass_driver);

}

结构体akm_compass_driver定义如下:

static struct i2c_driverakm_compass_driver = {

    .probe     = akm_compass_probe,

    .remove       = akm_compass_remove,

    .id_table  = akm_compass_id,

    .driver= {

       .name  = AKM_I2C_NAME,

       .owner  = THIS_MODULE,

       .of_match_table= akm09911_match_table,

       .pm    = &akm_compass_pm_ops,

    },

};

int akm_compass_probe(structi2c_client *client, const struct i2c_device_id *id)

{………

err =akm_compass_parse_dt(&client->dev, s_akm);

………

err = akm_compass_power_init(s_akm,1);

………

err =akm_compass_power_set(s_akm, 1);

………

err = akm_compass_input_init(&s_akm->input);

………

err = request_threaded_irq( s_akm->irq,NULL,akm_compass_irq,

IRQF_TRIGGER_HIGH|IRQF_ONESHOT, dev_name(&client->dev),  s_akm);

………

INIT_DELAYED_WORK(&s_akm->dwork,akm_dev_poll);

………}

在akm_compass_probe()调用akm_compass_input_init()akm_dev_poll()其中akm_compass_input_init()完成input类型设备的申请、初始化和注册。代码示例如下:

static intakm_compass_input_init( struct input_dev**input)

{………

*input = input_allocate_device();

………

input_set_abs_params(*input,ABS_X,-32768, 32767, 0, 0);

………

err = input_register_device(*input);

………}

int input_register_device(structinput_dev *dev)

{//注册一个input设备到input core系统,该函数主要完成的功能如下:

…………

error = device_add(&dev->dev);

//1 设备添加到设备阶层;

…………

list_add_tail(&dev->node,&input_dev_list);

//2 将 input_dev 加入 input_dev_list 链表中,input_dev_list 链表中包含//了系统中所有的 input_dev 设备;

list_for_each_entry(handler,&input_handler_list, node)     input_attach_handler(dev,handler);

//3input_handler_list链表中的hander与input_dev_list链表中的device//进行匹配;

…………

}

akm_dev_poll()完成读取sensor数据,调用input接口向上报数据。示例代码如下:

static void akm_dev_poll(struct work_struct*work)

{………

ret =akm_report_data(akm);

………}

static int akm_report_data(structakm_compass_data *akm)

{………

input_report_abs(akm->input, ABS_X,mag_x);

         input_report_abs(akm->input,ABS_Y, mag_y);

         input_report_abs(akm->input,ABS_Z, mag_z);

         input_sync(akm->input);

………}

input_report_abs()直接调用input_event(),input_event()属于input 核心层函数,详见第三部分核心层。


Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐