254 строки
8.5 KiB
C
254 строки
8.5 KiB
C
/*
|
|
* (c) 2010, SWD Embedded Systems Limited, http://www.kpda.ru
|
|
*/
|
|
|
|
/*
|
|
* Предостережение:
|
|
*
|
|
* Предоставленный исходный код драйвера devi-hid рекомендуется использовать
|
|
* только для отладочных целей при разработке HID-драйверов. Для всех остальных
|
|
* задач следует использовать штатный системный драйвер devi-hid.
|
|
*
|
|
* В общем случае не существует задач, которые требуется решать в этом драйвере
|
|
* при поддержке нового оборудования (для этого должен быть написан/модифицирован
|
|
* отдельный драйвер ввода или HID-драйвер).
|
|
*/
|
|
|
|
/*
|
|
* control.c
|
|
*
|
|
* The HID USB control combined device/protocol module.
|
|
*
|
|
*/
|
|
#include <sys/devi.h>
|
|
#include "hid.h"
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
#define FLAG_INIT 0x0100
|
|
#define FLAG_RESET 0x0200
|
|
#define FLAG_KIOSK_MODE 0x0400
|
|
#define controlED 1
|
|
#define RELEASED 0
|
|
|
|
/* Protocol module private data */
|
|
struct private_data {
|
|
int flags; /* see valid values before */
|
|
int nDev; /* USB device number */
|
|
int state;
|
|
void * hid_module_handle; /* HID module_handle */
|
|
};
|
|
|
|
|
|
/* forward declarations */
|
|
static int control_init(input_module_t *module);
|
|
static int control_devctrl(input_module_t *module, int event, void *ptr);
|
|
static int control_reset(input_module_t *module);
|
|
static int control_input(input_module_t *module, int num, void *arg);
|
|
static int control_parm(input_module_t *module, int opt, char *optarg);
|
|
static int control_shutdown(input_module_t *module, int delay);
|
|
|
|
|
|
|
|
/* Our protocol module is represented by the following input_module_t data structure */
|
|
|
|
input_module_t control = {
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
DEVI_CLASS_CONTROL | DEVI_MODULE_TYPE_PROTO | DEVI_MODULE_TYPE_DEVICE,
|
|
"control",
|
|
__DATE__,
|
|
"Ku:",
|
|
NULL,
|
|
control_init,
|
|
control_reset,
|
|
control_input,
|
|
NULL,
|
|
NULL,
|
|
control_parm,
|
|
control_devctrl,
|
|
control_shutdown
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Description: callback initialisation function; it is called when input module is */
|
|
/* initialising the input system */
|
|
/* Input : input_module_t * module - pointer to module descriptor */
|
|
/* Output : None */
|
|
/* Return : 0 if OK, otherwise - (-1) */
|
|
int control_init(input_module_t *module)
|
|
{
|
|
struct private_data *dp = module->data;
|
|
|
|
if(!module->data)
|
|
{
|
|
if(!(dp = module->data = _scalloc(sizeof *dp)))
|
|
{
|
|
return (-1);
|
|
}
|
|
}
|
|
|
|
dp -> nDev = HIDD_CONNECT_WILDCARD;
|
|
dp->state = RELEASED;
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
/* Description: this is a callback function for DEVCTRL command processing */
|
|
/* Input : input_module_t * module - pointer to module descriptor */
|
|
/* int event - DEVCTRL command code */
|
|
/* void * ptr - pointer to data exchange block */
|
|
/* Output : None */
|
|
/* Return : 0 if OK, otherwise -1 */
|
|
int control_devctrl(input_module_t *module, int event, void *ptr)
|
|
{
|
|
struct private_data *dp = module->data;
|
|
int rc = 0;
|
|
|
|
switch(event)
|
|
{
|
|
case DEVCTL_GETDEVFLAGS:
|
|
*(unsigned short *)ptr = (dp->flags & FLAGS_GLOBAL);
|
|
break;
|
|
|
|
case DEVCTL_GETPTRBTNS:
|
|
*(unsigned long *)ptr = 5L;
|
|
break;
|
|
|
|
case DEVCTL_GETPTRCOORD:
|
|
*(unsigned char *)ptr='\02';
|
|
break;
|
|
|
|
default:
|
|
rc = devi_hid_devctrl(dp -> hid_module_handle, event, ptr, HIDD_CONNECT_WILDCARD );
|
|
break;
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
|
|
|
|
/* Description: this callback funtion is called when the module is linked into the */
|
|
/* event bus;it is used to set initial module state on the protocol */
|
|
/* level */
|
|
/* Input : input_module_t * module - pointer to module descriptor */
|
|
/* Output : None */
|
|
/* Return : 0 if OK, otherwise -1 */
|
|
int control_reset(input_module_t *module)
|
|
{
|
|
struct private_data *dp = module->data;
|
|
|
|
if(!(dp->flags & FLAG_INIT))
|
|
{
|
|
if(NULL == (dp -> hid_module_handle = devi_hid_register_client(module, dp -> nDev)))
|
|
return (-1);
|
|
}
|
|
|
|
dp->flags |= FLAG_INIT;
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
|
|
/* Description: main protocol processing function. It will be called by the */
|
|
/* device layer to pass it data to process. Its job is to interpret */
|
|
/* the data according to the MS wheel control protocol, create a */
|
|
/* data structure, fill it in and hand it off to the filter layer */
|
|
/* module above it. The protocol is processed using simple state */
|
|
/* machine. State info is kept in module's private data */
|
|
/* Input : input_module_t * module - pointer to module descriptor */
|
|
/* int num - number of bytes to process */
|
|
/* void * arg - raw data to process */
|
|
/* Output : None */
|
|
/* Return : 0 if OK, otherwise -1 */
|
|
/* Comment : driver uses one of two input modules depending on device data */
|
|
/* protocol */
|
|
int control_input(input_module_t *module, int num, void *arg)
|
|
{
|
|
pControl_raw_data_t control_raw_data = (pControl_raw_data_t)arg;
|
|
struct packet_control mp;
|
|
|
|
struct private_data *dp = module->data;
|
|
input_module_t *up = module->up;
|
|
|
|
assert(num == sizeof(control_raw_data_t)); // Desynchronized exchange format
|
|
|
|
if(dp->flags & FLAG_INIT)
|
|
{
|
|
mp.Rx = control_raw_data->Rx;
|
|
mp.Ry = control_raw_data->Ry;
|
|
mp.Rz = control_raw_data->Rz;
|
|
mp.button_state = control_raw_data->button_state;
|
|
}
|
|
|
|
if (verbosity > 1)
|
|
fprintf (stderr, "Device Module Level: Rx:%d, Ry:%d, Rz:%d, Buttons %x\n", mp.Rx, mp.Ry, mp.Rz, mp.button_state);
|
|
|
|
(up->input)(up, 1, &mp);
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Description: this is a callback function for command line parameter processing */
|
|
/* (all valid parameters for device module are listed in control.args) */
|
|
/* Input : input_module_t * module - pointer to module descriptor */
|
|
/* int opt - parameter code */
|
|
/* char * optarg - optional parameter value */
|
|
/* Output : None */
|
|
/* Return : 0 if OK, otherwise -1 */
|
|
/* Comment : we don't accept any parameter for this module at the protocol level */
|
|
int control_parm(input_module_t *module, int opt, char *optarg)
|
|
{
|
|
/* Now empty */
|
|
struct private_data *dp = module->data;
|
|
|
|
switch (opt)
|
|
{
|
|
case 'u':
|
|
{
|
|
if(NULL != optarg)
|
|
dp->nDev = atoi(optarg);
|
|
break;
|
|
}
|
|
case 'K':
|
|
{
|
|
dp->flags |= FLAG_KIOSK_MODE;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
/* Description: this is a callback function which is called when resourse manager */
|
|
/* is shutting down */
|
|
/* Input : input_module_t * module - pointer to module descriptor */
|
|
/* int ms - program doesn't use this parameter */
|
|
/* Output : None */
|
|
/* Return : 0 if OK, otherwise -1 */
|
|
/* Comment : Does nothing for the protocol level */
|
|
int control_shutdown(input_module_t *module, int delay)
|
|
{
|
|
struct private_data *dp = module->data;
|
|
|
|
if( (NULL != dp) && (NULL != dp -> hid_module_handle))
|
|
devi_unregister_hid_client(dp -> hid_module_handle);
|
|
|
|
return (0);
|
|
}
|