古詩詞大全網 - 成語用法 - input event2怎麽使用

input event2怎麽使用

1.定義的結構體繼承input_dev

struct bma150_data {

struct i2c_client *bma150_client;

struct bma150_platform_data *platform_data;

int IRQ;

atomic_t delay;

unsigned char mode;

struct input_dev *input;

struct bma150acc value;

struct mutex value_mutex;

struct mutex mode_mutex;

struct delayed_work work;

struct work_struct irq_work;

};

2.給input_dev指定名字和總線類型,對input事件類型可以參考下面代碼

EV_MSC 類型參考下面的

set_bit(EV_MSC, dev->evbit);

set_bit(MSC_RAW, dev->mscbit);

EV_ABS類型參考下面的

input->evbit[0] = BIT(EV_ABS);

input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);

input_set_capability實際調用的也是__set_bit,

input_set_abs_params調用實際上也是set_bit,對於參數(dev,axis,min,max,fuzz,flat) fuzz有濾波作用,min,max代表範圍,axis表示了坐標軸,flat暫時不知到用途

3.通過input_register_device(dev)註冊input設備

static int bma150_input_init(struct bma150_data *bma150)

{

struct input_dev *dev;

int err;

dev = input_allocate_device();

if (!dev)

return -ENOMEM;

dev->name = SENSOR_NAME;

dev->id.bustype = BUS_I2C;

input_set_capability(dev, EV_ABS, ABS_MISC);

input_set_abs_params(dev, ABS_X, ABSMIN_2G, ABSMAX_2G, 0, 0);

input_set_abs_params(dev, ABS_Y, ABSMIN_2G, ABSMAX_2G, 0, 0);

input_set_abs_params(dev, ABS_Z, ABSMIN_2G, ABSMAX_2G, 0, 0);

input_set_drvdata(dev, bma150);

err = input_register_device(dev);

if (err < 0) {

input_free_device(dev);

return err;

}

bma150->input = dev;

return 0;

}

據說可以指定input號

dev->phys = "bma150/input0";

dev->id.bustype = BUS_HOST;

4.在中斷函數或者工作隊列中調用input_event上報事件

static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)

{

input_event(dev, EV_ABS, code, value);

}

input_event函數說明,input調用input_handle_event

對各種事件類型的處理主要體現在input_handle_event函數上

static void input_handle_event(struct input_dev *dev,

unsigned int type, unsigned int code, int value)

{

int disposition = INPUT_IGNORE_EVENT;//忽略事件

switch (type) {

case EV_SYN:

switch (code) {

case SYN_CONFIG:

disposition = INPUT_PASS_TO_ALL;//傳給設備和handle處理

break;

case SYN_REPORT:

if (!dev->sync) {

dev->sync = true;

disposition = INPUT_PASS_TO_HANDLERS;//傳給handle處理 同步事件

}

break;

case SYN_MT_REPORT:

dev->sync = false;

disposition = INPUT_PASS_TO_HANDLERS;//傳給handle處理 多點觸摸

break;

}

break;

case EV_KEY:

if (is_event_supported(code, dev->keybit, KEY_MAX) &&

!!test_bit(code, dev->key) != value) {

if (value != 2) {

__change_bit(code, dev->key);

if (value)

input_start_autorepeat(dev, code);

else

input_stop_autorepeat(dev);

}

disposition = INPUT_PASS_TO_HANDLERS;

}

break;

case EV_SW://耳機事件

if (is_event_supported(code, dev->swbit, SW_MAX) &&

!!test_bit(code, dev->sw) != value) {

__change_bit(code, dev->sw);

disposition = INPUT_PASS_TO_HANDLERS;

}

break;

case EV_ABS:

if (is_event_supported(code, dev->absbit, ABS_MAX))

disposition = input_handle_abs_event(dev, code, &value);//這裏調用的input_handle_abs_event會將上次值和這次值相同的事件過濾掉

break;

case EV_REL:

if (is_event_supported(code, dev->relbit, REL_MAX) && value)

disposition = INPUT_PASS_TO_HANDLERS;

break;

case EV_MSC:

if (is_event_supported(code, dev->mscbit, MSC_MAX))

disposition = INPUT_PASS_TO_ALL;

break;

case EV_LED:

if (is_event_supported(code, dev->ledbit, LED_MAX) &&

!!test_bit(code, dev->led) != value) {

__change_bit(code, dev->led);

disposition = INPUT_PASS_TO_ALL;

}

break;

case EV_SND:

if (is_event_supported(code, dev->sndbit, SND_MAX)) {

if (!!test_bit(code, dev->snd) != !!value)

__change_bit(code, dev->snd);

disposition = INPUT_PASS_TO_ALL;

}

break;

case EV_REP:

if (code <= REP_MAX && value >= 0 && dev->rep[code] != value) {

dev->rep[code] = value;

disposition = INPUT_PASS_TO_ALL;

}

break;

case EV_FF:

if (value >= 0)

disposition = INPUT_PASS_TO_ALL;

break;

case EV_PWR:

disposition = INPUT_PASS_TO_ALL;

break;

}

if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)

dev->sync = false;

if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)

dev->event(dev, type, code, value);

if (disposition & INPUT_PASS_TO_HANDLERS)

input_pass_event(dev, type, code, value);

}

/**

* input_event() - report new input event

* @dev: device that generated the event

* @type: type of the event

* @code: event code

* @value: value of the event

*

* This function should be used by drivers implementing various input

* devices to report input events. See also input_inject_event().

*

* NOTE: input_event() may be safely used right after input device was

* allocated with input_allocate_device(), even before it is registered

* with input_register_device(), but the event will not reach any of the

* input handlers. Such early invocation of input_event() may be used

* to 'seed' initial state of a switch or initial position of absolute

* axis, etc.

*/

void input_event(struct input_dev *dev,

unsigned int type, unsigned int code, int value)

{

unsigned long flags;

if (is_event_supported(type, dev->evbit, EV_MAX)) {

spin_lock_irqsave(&dev->event_lock, flags);

add_input_randomness(type, code, value);

input_handle_event(dev, type, code, value);

spin_unlock_irqrestore(&dev->event_lock, flags);

}

}

EXPORT_SYMBOL(input_event);

static int input_handle_abs_event(struct input_dev *dev,

unsigned int code, int *pval)

{

bool is_mt_event;

int *pold;

if (code == ABS_MT_SLOT) {//多點觸摸信號

/*

* "Stage" the event; we'll flush it later, when we

* get actual touch data.

*/

if (*pval >= 0 && *pval < dev->mtsize)

dev->slot = *pval;

return INPUT_IGNORE_EVENT;

}

is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST;//多點觸摸事件值

if (!is_mt_event) {//不是多點觸摸值,舊將上次值保存在pold裏面

pold = &dev->absinfo[code].value;

} else if (dev->mt) {

struct input_mt_slot *mtslot = &dev->mt[dev->slot];

pold = &mtslot->abs[code - ABS_MT_FIRST];

} else {

/*

* Bypass filtering for multi-touch events when

* not employing slots.

*/

pold = NULL;

}

if (pold) {

*pval = input_defuzz_abs_event(*pval, *pold,//fuzz為0時,返回值為pold本身

dev->absinfo[code].fuzz);//這裏fuzz是在2中設置類型時傳入的參數input_set_abs_params(dev,axis,min,max.fuzz,flat)

if (*pold == *pval)

return INPUT_IGNORE_EVENT;

*pold = *pval;

}

/* Flush pending "slot" event */

if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {

input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);

input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);

}

return INPUT_PASS_TO_HANDLERS;

}