hanvon-linux/hanvon-libusb.c

226 lines
5.3 KiB
C
Raw Normal View History

/*
* =====================================================================================
*
* Filename: hanvon-libusb.c
*
* Description: Libusb GP0504 handler prototype
*
* Version: 0.1
* Created: 08/17/2020 04:05:14 PM
* Revision: none
* Compiler: gcc
*
* Author: surkeh@protonmail.com
*
* =====================================================================================
*/
#include <stdlib.h>
#include <stdio.h>
#include <libusb-1.0/libusb.h>
#define STATE_SUCCESS 0
#define STATE_NOT_FOUND 1
#define UNREF_DEVICE 1
#define KEEP_DEVICE_REF 0
#define VENDOR_ID_HANVON 0x0b57
#define PRODUCT_ID_AM3M 0x8528
#define PRODUCT_ID_AM0806 0x8502
#define PRODUCT_ID_AM0605 0x8503
#define PRODUCT_ID_AM1107 0x8505
#define PRODUCT_ID_AM1209 0x8501
#define PRODUCT_ID_RL0604 0x851f
#define PRODUCT_ID_RL0504 0x851d
#define PRODUCT_ID_GP0806 0x8039
#define PRODUCT_ID_GP0806B 0x8511
#define PRODUCT_ID_GP0605 0x8512
#define PRODUCT_ID_GP0605A 0x803a
#define PRODUCT_ID_GP0504 0x8037
#define PRODUCT_ID_NXS1513 0x8030
#define PRODUCT_ID_GP0906 0x8521
#define PRODUCT_ID_APPIV0906 0x8532
#define AM_PACKET_LEN 10
//static int lbuttons[]={BTN_0,BTN_1,BTN_2,BTN_3}; /* reported on all AMs */
//static int rbuttons[]={BTN_4,BTN_5,BTN_6,BTN_7}; /* reported on AM1107+ */
#define AM_WHEEL_THRESHOLD 4
#define AM_MAX_TILT_X 0x3f
#define AM_MAX_TILT_Y 0x7f
#define AM_MAX_PRESSURE 0x400
struct hanvon {
unsigned char *data;
//dma_addr_t data_dma;
struct input_dev *dev;
struct usb_device *usbdev;
struct urb *irq;
int old_wheel_pos;
char phys[32];
};
2020-08-18 08:44:42 +05:30
void callback(struct libusb_transfer *transfer) {
int i = 0;
for(; i < 10; i++) {
printf("%c, ", transfer -> buffer[i]);
}
printf("placeholder\n");
}
2020-09-03 11:39:12 +05:30
int find_device(libusb_device **list, unsigned int count) {
if (count < 0) {
return -1;
}
int found = -1;
struct libusb_device_descriptor desc;
for (unsigned int i = 0; i < count; i++) {
libusb_device *t = list[i];
libusb_get_device_descriptor(list[i], &desc);
printf( "Dev%u ID %04x:%04x\n", (i), desc.idVendor, desc.idProduct );
if (desc.idVendor == VENDOR_ID_HANVON) {
switch(desc.idProduct) {
default:
break;
case PRODUCT_ID_AM0806:
case PRODUCT_ID_AM0605:
case PRODUCT_ID_AM1107:
case PRODUCT_ID_AM1209:
case PRODUCT_ID_RL0604:
case PRODUCT_ID_RL0504:
case PRODUCT_ID_GP0806:
case PRODUCT_ID_GP0806B:
case PRODUCT_ID_GP0605:
case PRODUCT_ID_GP0605A:
case PRODUCT_ID_GP0504:
case PRODUCT_ID_NXS1513:
case PRODUCT_ID_GP0906:
case PRODUCT_ID_APPIV0906:
return i;
} // end switch
} // end if
} // end for
return found;
}
libusb_device *FindHanvon( libusb_context **context);
int HandleData( void );
int main()
{
2020-09-03 11:39:12 +05:30
#define UNREF_DEVICE 1
#define KEEP_DEVICE_REF 0
2020-09-03 11:39:12 +05:30
libusb_device ** devs;
int r = libusb_init(NULL);
if (r < 0) {
return r;
}
int count = libusb_get_device_list(NULL, &devs);
if (count < 0) {
libusb_exit(NULL);
return count;
}
int index = find_device(devs, count);
if (index < 0) {
printf("Device not plugged in\n");
return 0;
}
printf("Device #%i\n", index);
libusb_device_handle *h;
int state = libusb_open(devs[index], &h);
libusb_free_device_list (devs, UNREF_DEVICE);
if (state < 0 || h == NULL) {
printf(" Something happened, %i.\n", state);
return 0;
}
printf("Got to this point\n");
// Wait and handle interrupts?
struct libusb_transfer tx;
const int ENDPOINT_ADDR = 0x81; // bEndpointAddress from lsusb -v
const unsigned int LEN = 10; // wMaxPacketSize from lsusb -v
unsigned char buffer[LEN];
// assign timeout of 1s, for any action is too much as is
libusb_fill_interrupt_transfer( &tx,
h,
ENDPOINT_ADDR,
buffer,
LEN,
callback,
NULL,
130); // milliseconds
state = libusb_submit_transfer(&tx);
if (state < 0 ) {
return state;
}
for(;;) {
libusb_handle_events(NULL);
}
2020-08-18 08:44:42 +05:30
return state;
}
libusb_device *FindHanvon( libusb_context **context)
{
libusb_device **deviceList;
libusb_device *found = NULL;
ssize_t nDevices = libusb_get_device_list( context[0], &deviceList);
if( nDevices > 0 )
{
struct libusb_device_descriptor description;
for( ssize_t i = 0; i < nDevices; i++ )
{
libusb_device *device = deviceList[i];
libusb_get_device_descriptor(device, &description);
printf( "Dev%u ID %04x:%04x\n", (i + 1), description.idVendor, description.idProduct );
if( description.idVendor == VENDOR_ID_HANVON )
{
switch( description.idProduct )
case PRODUCT_ID_AM0806:
case PRODUCT_ID_AM0605:
case PRODUCT_ID_AM1107:
case PRODUCT_ID_AM1209:
case PRODUCT_ID_RL0604:
case PRODUCT_ID_RL0504:
case PRODUCT_ID_GP0806:
case PRODUCT_ID_GP0806B:
case PRODUCT_ID_GP0605:
case PRODUCT_ID_GP0605A:
case PRODUCT_ID_GP0504:
case PRODUCT_ID_NXS1513:
case PRODUCT_ID_GP0906:
case PRODUCT_ID_APPIV0906:
found = device;
break;
}
}
printf( "\n\n" );
}
libusb_free_device_list( deviceList, UNREF_DEVICE );
return found;
}