История изменений
Исправление Zubok, (текущая версия) :
А есть ли шансы запуститься на kbd драйвере?
Никаких. И на libinput тоже, похоже. Я совсем не знаком с его внутренностями, но и там видно, что на уровень EV_MSC/MSC_SCAN спуск происходит в очень специфичных случаях, специфичных для конкретного устройства. В основном же там тоже EV_KEY обрабатывается. Я отвечаю на слово «запуститься», так как вообще дописать на Си можно и запуститься :) Я считаю, что реализация драйвера, который у тебя, недостаточна. Слишком сырые данные он выдает. И драйвер должен посылать EV_KEY. А EV_MSC/MSC_SCAN он за компанию шлет. Можно, конечно, написать какой-то такой модуль, который обрабатывает эти события MSC, создает виртуальное устройство /dev/input/event и шлет уже там нормальный вывод. Но это в любом случае писанина и костылина. Вот бы увидеть исходник твоего драйвера.
Однако вот я выше давал ссылку на драйвер tca8418_keypad, который сейчас в ядре есть. И там такое:
https://github.com/torvalds/linux/blob/a9c9a6f741cdaa2fa9ba24a790db8d07295761...
static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
{
struct input_dev *input = keypad_data->input;
unsigned short *keymap = input->keycode;
int error, col, row;
u8 reg, state, code;
do {
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®);
if (error < 0) {
dev_err(&keypad_data->client->dev,
"unable to read REG_KEY_EVENT_A\n");
break;
}
/* Assume that key code 0 signifies empty FIFO */
if (reg <= 0)
break;
state = reg & KEY_EVENT_VALUE;
code = reg & KEY_EVENT_CODE;
row = code / TCA8418_MAX_COLS;
col = code % TCA8418_MAX_COLS;
row = (col) ? row : row - 1;
col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
input_event(input, EV_MSC, MSC_SCAN, code);
input_report_key(input, keymap[сode], state);
} while (1);
input_sync(input);
}
Вот что я тут вижу. Он читает матрицу, получает сканкод, а потом вызывает input_report_key, которая по сканкоду формирует keymap. Насколько я понимаю (а я это вижу в первый раз в жизни), он как раз в этом месте пошлет какой-то EV_KEY. Но я могу ошибаться.
См. радел 1.3
https://www.kernel.org/doc/Documentation/input/input-programming.txt
1.3 Basic event types ~~~~~~~~~~~~~~~~~~~~~ The most simple event type is EV_KEY, which is used for keys and buttons. It's reported to the input system via: input_report_key(struct input_dev *dev, int code, int value) See linux/input.h for the allowable values of code (from 0 to KEY_MAX). Value is interpreted as a truth value, ie any nonzero value means key pressed, zero value means key released. The input code generates events only in case the value is different from before.
То есть вот идея пока такая - попробовать поставить ядро для твоей архитектуры вот с этим драйвером tca8418_keypad и поглядеть, что получается. Мне кажется, что это косо-криво может заработать.
Исходная версия Zubok, :
А есть ли шансы запуститься на kbd драйвере?
Никаких. И на libinput тоже, похоже. Я совсем не знаком с его внутренностями, но и там видно, что на уровень EV_MSC/MSC_SCAN спуск происходит в очень специфичных случаях, специфичных для конкретного устройства. В основном же там тоже EV_KEY обрабатывается. Я отвечаю на слово «запуститься», так как вообще дописать на Си можно и запуститься :) Я считаю, что реализация драйвера, который у тебя, недостаточна. Слишком сырые данные он выдает. И драйвер должен посылать EV_KEY. А EV_MSC/MSC_SCAN он за компанию шлет. Можно, конечно, написать какой-то такой модуль, который обрабатывает эти события MSC, создает виртуальное устройство /dev/input/event и шлет уже там нормальный вывод. Но это в любом случае писанина и костылина. Вот бы увидеть исходник твоего драйвера.
Однако вот я выше давал ссылку на драйвер tca8418_keypad, который сейчас в ядре есть. И там такое:
https://github.com/torvalds/linux/blob/a9c9a6f741cdaa2fa9ba24a790db8d07295761...
static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
{
struct input_dev *input = keypad_data->input;
unsigned short *keymap = input->keycode;
int error, col, row;
u8 reg, state, code;
do {
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®);
if (error < 0) {
dev_err(&keypad_data->client->dev,
"unable to read REG_KEY_EVENT_A\n");
break;
}
/* Assume that key code 0 signifies empty FIFO */
if (reg <= 0)
break;
state = reg & KEY_EVENT_VALUE;
code = reg & KEY_EVENT_CODE;
row = code / TCA8418_MAX_COLS;
col = code % TCA8418_MAX_COLS;
row = (col) ? row : row - 1;
col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
input_event(input, EV_MSC, MSC_SCAN, code);
input_report_key(input, keymap[сode], state)[/b];
} while (1);
input_sync(input);
}
Вот что я тут вижу. Он читает матрицу, получает сканкод, а потом вызывает input_report_key, которая по сканкоду формирует keymap. Насколько я понимаю (а я это вижу в первый раз в жизни), он как раз в этом месте пошлет какой-то EV_KEY. Но я могу ошибаться.
См. радел 1.3
https://www.kernel.org/doc/Documentation/input/input-programming.txt
1.3 Basic event types ~~~~~~~~~~~~~~~~~~~~~ The most simple event type is EV_KEY, which is used for keys and buttons. It's reported to the input system via: input_report_key(struct input_dev *dev, int code, int value) See linux/input.h for the allowable values of code (from 0 to KEY_MAX). Value is interpreted as a truth value, ie any nonzero value means key pressed, zero value means key released. The input code generates events only in case the value is different from before.
То есть вот идея пока такая - попробовать поставить ядро для твоей архитектуры вот с этим драйвером tca8418_keypad и поглядеть, что получается. Мне кажется, что это косо-криво может заработать.