1
1
Fork 0

Драйвер devh-egalax для ЗОСРВ "Нейтрино" редакции 2020

This commit is contained in:
commit 8365adbd8b
26 changed files with 2037 additions and 0 deletions

3
Makefile Normal file
View File

@ -0,0 +1,3 @@
LIST=hardware
EARLY_DIRS=devu
include recurse.mk

163
README.md Normal file
View File

@ -0,0 +1,163 @@
## Общая структура подсистемы ввода
```
┌───────────────────────────┐
│ │
│ Устройство ввода ◂───────────────────────┐
│ │ │
└─────────────▴─────────────┘ │
│ │
┌─────────────┴─────────────┐ │ Не HID-совместимое
│ │ │ устройство
│ HID-драйвер (devh-*) │ │
│ │ │
└─────────────▴─────────────┘ │
│ │
┌─────────────┴─────────────┐ ┌─────────────┴─────────────┐
│ │ │ │
│ HID-менеджер (io-hid) ◂─── * ───┤ Драйвер ввода (devi-*) ◂───▸ /dev/??? (standalone-режим)
│ │ │ │
└───────────────────────────┘ ▲ └─────────────▴─────────────┘
│ │
│ ┌─────────────▾─────────────┐
Интерфейс libhiddi ─────┘ │ │
│ Оконная оболочка Photon │
│ │
└───────────────────────────┘
```
## Дерево исходных кодов
```
|- devh/
| |- egalax/ - Исходный код HID-драйвера поддержки тачскринов egalax, подключаемых по USB
| |- Makefile - Правила сборки дерева исходников
| `- common.mk - Параметры сборки драйверов
|
`- Makefile - Правила сборки дерева исходников
```
## Сборка драйвера
- Установить и настроить [комплект разработчика](https://help.kpda.ru/help/topic/ru.kpda.doc.dev_tools_ru/html/devkit/devkit.html) для [ЗОСРВ "Нейтрино" редакции 2020](https://help.kpda.ru/help/index.jsp).
- Выполнить команду:
```
make
```
## Запуск драйвера
Вместе с менеджером [io-hid](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/services/io-hid.html):
```
io-hid -d <имя_драйвера|путь к библиотеке> [параметры]
```
С помощью утилиты [mount](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/utils/utils/mount.html):
```
mount -T io-hid <путь к библиотеке> [параметры]
```
## Разработка драйвера
**Дескриптор драйвера:**
```
struct io_hid_dll_entry {
char *name;
int nfuncs;
int (*init)( void *dll_hdl, dispatch_t *dpp, io_hid_self_t *ioh, char *options );
int (*shutdown)( void *dll_hdl );
}
```
**Дескриптор [io-hid](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/services/io-hid.html):**
```
struct io_hid_self_t {
_Uint32t nfuncs;
int (*reg)( void *dll_hdl, io_hid_registrant_t *registrant, int *reg_hdlp );
int (*dereg)( void *dll_hdl );
int (*get_buffer)( int reg_hdlp, void **buffer );
int (*send_report)( int registrant_hdl, void *data, _Uint32t dlen );
}
```
**Инициализация драйвера:**
- Заполнить дескриптор устройства (`io_hid_registrant`)
- Установить обработчики прерываний и инициализировать ресурсы драйвера
- Зарегистрировать драйвер, вызвав функцию `reg()` менеджера [io-hid](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/services/io-hid.html) (содержится в структуре `io_hid_self_t`)
**При получении данных от устройства:**
- Заполнить HID-report
- Передать HID-report менеджеру [io-hid](https://help.kpda.ru/help/topic/ru.kpda.doc.os_ru/html/services/io-hid.html), вызвав функцию `send_report()`
**Дескриптор HID-устройства:**
```
struct io_hid_registrant_t {
_Uint32t flags;
hidd_device_ident_t *device_ident; /* vid, pid */
void *desc; /* binary descriptor */
_Uint16t dlen; /* binary descriptor length */
_Uint8t reserved[2];
void *user_hdl;
io_hid_registrant_funcs_t *funcs; /* callbacks */
_Uint8t reserved2[4];
}
```
**Дескриптор функций драйвера:**
Дескриптор функций драйвера определяет структура `io_hid_registrant_funcs`:
- Подключение/отключение клиента (`client_attach()` / `client_detach()`)
- Управление памятью (`rbuffer_alloc()` / `rbuffer_free()`)
- Чтение/Запись HID пакетов (`report_read()` / `report_write()`)
- Управление частотой обмена (`get_idle()` / `set_idle()`)
- Управление режимом работы (`get_protocol()` / `set_protocol()`)
- Получение дополнительных данных от устройства (`string`, `indexed_string`)
- Перезагрузка устройства (`reset()`)
## Общий принцип работы HID-драйвера
```
┌────────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐
│ Hardware │ │ devh-* │ │ io-hid │ │ devi-hid │ │ Клиент │
└─────┬──────┘ └─────┬────┘ └─────┬────┘ └──────┬─────┘ └─────┬────┘
│ │ │ │ │
│ │ Регистрация │ │ │
│ ├────────────────────────────▸│ │ │
│ │ │ │ │
│ ├──┐ │ │ │
│ │ │ Регистрация │ │ │
│ │ │ обработчиков прерываний │ │ │
│ │◂─┘ │ │ │
│ Прерывание │ │ │ │
├──────────────▸│ Отправка HID-report │ │ │
│ │ с помощью send_report() │ Передача │ │
│ ├────────────────────────────▸│ HID-report │ │
│ │ ├─────────────▸│ enqueue_packet() │
│ │ │ ├───────────────────▸│
│ │ │ │ │
```

2
devh/Makefile Normal file
View File

@ -0,0 +1,2 @@
LIST=CLASS
include recurse.mk

49
devh/common.mk Normal file
View File

@ -0,0 +1,49 @@
#
# (c) 2010-2019, SWD Embedded Systems Limited, http://www.kpda.ru
#
ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)
LIB_VARIANT = $(patsubst dll.,dll,$(subst $(space),.,so $(filter wcc be le,$(VARIANTS))))
EXTRA_CCDEPS = $(wildcard $(PROJECT_ROOT)/*.h $(PRODUCT_ROOT)/hiddi/internals.h )
LDFLAGS += -M
ifeq ($filter usb, $(VARIANTS),,)
NAME=devh
else
EXTRA_SILENT_VARIANTS=usb example egalax touchintl microtouch bt
NAME=devh-$(SECTION)
endif
define PINFO
PINFO DESCRIPTION=
endef
include $(MKFILES_ROOT)/qmacros.mk
TYPE = $(firstword $(filter a o, $(VARIANTS)) o)
ifeq ($filter usb, $(VARIANTS),,)
USEFILE_o = $(SECTION_ROOT)/$(NAME)-$(SECTION).use
else
USEFILE_o = $(SECTION_ROOT)/$(NAME).use
endif
USEFILE_a =
USEFILE = $(USEFILE_$(TYPE))
CCFLAGS_o =
CCFLAGS_a = -g -Dmain=main_$(SECTION)
CCFLAGS += -g $(CCFLAGS_$(TYPE))
CCFLAGS_e2k += -fkernel
CCFLAGS += $(CCFLAGS_$(CPU))
-include $(SECTION_ROOT)/override.mk
include $(MKFILES_ROOT)/qtargets.mk
-include $(SECTION_ROOT)/pinfo.mk

2
devh/egalax/Makefile Normal file
View File

@ -0,0 +1,2 @@
LIST=CPU
include recurse.mk

2
devh/egalax/arm/Makefile Normal file
View File

@ -0,0 +1,2 @@
LIST=VARIANT
include recurse.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

View File

@ -0,0 +1,32 @@
devh-egalax.so Driver for USB Egalax touch devices
Converts Egalax packets into Generic HID packets.
Syntax:
io-hid -d egalax [option[,option ...]] ... &
Options:
wait=num Number of seconds to wait for USB Stack to come up.
upath=path USB stack path. Default is /dev/usb
vendor=0xXXXX Pass in alternative Vendor ID
device=0xXXXX Pass in alternative Device ID
verbose=level Be verbose and output debug information (range 1-5).
noinit Don't initialise the controller.
You shouldn't use this option unless you are certain
that the default protocol your controller is using is
the Egalax protocol.
info Gather more info on the controller. This is only for
general information purposes and simply prints the info
to slog.
NOTE: If using with the usb (devh-usb.so) module you must specify the igndev
option to devh-usb.so and specify the Egalax vendor and device IDs.
Examples:
Start io-hid using the egalax driver.
# io-hid -d egalax &
Start io-hid using the egalax driver at high verbosity and a new stack path.
# io-hid -d egalax verbose=5,upath=/dev/payton-usb/

1578
devh/egalax/egalax.c Normal file

File diff suppressed because it is too large Load Diff

159
devh/egalax/egalax.h Normal file
View File

@ -0,0 +1,159 @@
/*
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
*/
// Module Description: header for HID class driver
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <share.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <termios.h>
#include <sys/io-hid.h>
#include <sys/usbdi.h>
#define UMASS_DEREG_PRIORITY 8
/* EGALAX */
#define USB_VENDOR 0x0eef
#define USB_DEVICE 0x0001
#define TOUCH_CONTROL_EP 1
#define TOUCH_INTIN_EP 2
#define HIDD_BUTTON_LEFT 0x01
#define HIDD_BUTTON_RIGHT 0x02
// HID STATUS DEFINITION
#define USB_DEVICE_IN_USE 0x01
#define TOUCH_CONTROL_EP 1
#define TOUCH_INTIN_EP 2
#define SYNC_BIT 0x80
#define PLAYER_ID_SET 0x20
#define PRESSURE_SET 0x40
/* Request Packet Information */
#define HEADER 0x0A
#define CMD_LENGTH 0x01
/* FIRMWARE Commands */
#define CHECK_ACTIVE 0x41 /* Check to see if the controller is attached (loopback) */
#define REQUEST_FIRMWARE_REVISION 0x44 /* Request Firmware Version */
#define REQUEST_CONTROLLER_INTERFACE 0x45 /* Request Controller Interface, responses are either USB or Serial */
#define REQUEST_CONTROLLER_TYPE 0x46 /* Request Controller type, will return string information on the controller */
#define CALIBRATION_PARAMETERS 0x37
#define SET_RAW_DATA 0x37
#define CALCULATE_CALIB_PARAMETERS_DATA 0xFF
#define SET_REPORT_MODE 0x34 /* Set Report Mode, this will change the mode between raw and calibrated points */
#define RAW_MODE 0x00
#define CALIBRATED_MODE 0x01
#define SET_SENSITIVITY 0x42
#define SET_SENSITIVITY_REPLY 0x58
#define TOGGLE_FILTERS 0x36
#define TOGGLE_FILTERS_DATA 0x0E
#define FILTERS_ENABLED 0x00
#define FILTERS_DISABLED 0x01
#define RESET_CONTROLLER 0x79
/* FIRMWARE RESPONSESE */
#define SET_REPORT_MODE_ACK 0x33
#define MINIMUM_FIRMWARE_REPLY_LENGTH 3
#define RING_BUFFER_SIZE 256
/* Flags */
#define PEN_UP 0x00
#define PEN_DOWN 0x01
#define TOUCH_UNBLOCK 2
#define TOUCH_PRESENT 4
#define TOUCH_IN_SHUTDOWN 8
#define FLAG_NO_INIT 0x10
#define FLAG_GET_CONTROLLER_INFO 0x20
/* ID Report */
#define ID_REPORT_ID 0x0C
typedef struct _report_buf {
_uint16 bytes_left;
_uint8 *report_data;
} report_buffer;
typedef struct hid_descriptor {
_uint8 bLength;
_uint8 bDescriptorType;
_uint16 bcdHID;
_uint8 bCountryCode;
_uint8 bNumDescriptors;
_uint8 bReportDescriptorType;
_uint16 wDescriptorLength;
} hid_descriptor_t;
typedef struct _usb {
TAILQ_ENTRY(_usb) dlink;
usbd_device_instance_t usbd_instance;
struct usbd_connection *connection;
int hid_hdl;
void *hiddi_reg; // handle for use with hiddi
struct usbd_device *device;
_uint32 status;
_uint16 idle_rate;
_uint16 protocol;
struct usbd_pipe *ep_cntl;
struct usbd_pipe *ep_int_in;
struct usbd_pipe *ep_int_out;
_uint32 ep_int_in_size;
_uint32 ep_int_out_size;
_uint8 *ep_int_buf;
struct usbd_urb *urb;
_uint32 report_len;
void *report_data; //report_descriptor data
void *rbuffer;
int coid;
_uint8 ring_buffer[256];
int ring_start, ring_end, ring_buffer_current_size;
} usb_t;
typedef struct _usb_ctrl {
TAILQ_HEAD(,_usb) dlist; // linked list of hid devices
_uint32 cflags;
_uint32 verbose;
_uint8 sensitivity;
_uint16 delay;
_uint32 devno;
_uint32 ndevs; // number of hid devices
_uint8 *path;
void *dll_hdl;
io_hid_self_t *ioh;
struct usbd_connection *connection[5];
_uint16 num_conn;
_uint8 rsvd[2];
// _uint8 controller_command;
_uint8 partial_reply[255];
int partial_reply_expected_len;
int partial_reply_current_len;
int sending_calibration_data;
} usb_ctrl_t;
typedef struct _egalax_data_packet {
_uint8 cmd;
_uint8 num_points;
_uint8 index;
_uint16 x, y;
} egalax_data_packet_t;
int NumCtl = 0;
usb_ctrl_t UsbCtrl[5];

10
devh/egalax/extra.mk Normal file
View File

@ -0,0 +1,10 @@
#
# (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
#
LVARIANT = $(patsubst amanda,-amanda,$(filter amanda, $(VARIANTS)))
LIB_VARIANT = $(patsubst so.,so,$(subst $(space),.,so $(filter wcc be le amanda,$(VARIANTS))))
EXTRA_INCVPATH += $(PROJECT_ROOT)/../devu/usbdi/public
EXTRA_LIBVPATH += $(PROJECT_ROOT)/../devu/usbdi/$(CPU)/$(LIB_VARIANT)/
LD_FLAGS +=
LIBS += usbdi$(LVARIANT)

View File

@ -0,0 +1,2 @@
LIST=VARIANT
include recurse.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

7
devh/egalax/pinfo.mk Normal file
View File

@ -0,0 +1,7 @@
#
# (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
#
define PINFO
PINFO DESCRIPTION=EGALAX HID Driver
endef

2
devh/egalax/ppc/Makefile Normal file
View File

@ -0,0 +1,2 @@
LIST=VARIANT
include recurse.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

2
devh/egalax/x86/Makefile Normal file
View File

@ -0,0 +1,2 @@
LIST=VARIANT
include recurse.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk

View File

@ -0,0 +1,2 @@
include ../../../common.mk
include ../../extra.mk