From ebfde8f2796b7dfd22a2843558dcc4ce0a59ccc1 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 19 Jan 2011 18:07:11 +0000 Subject: [PATCH] hostside: wip test programs etc. for Joytech Neo S gamepad --- hostside/.gitignore | 3 + hostside/Makefile | 2 + hostside/hiddev-ioctl.c | 119 ++++++++++++++++++++++++++++++++++++++++ hostside/hidraw-ioctl.c | 64 +++++++++++++++++++++ hostside/hidraw.h | 89 ++++++++++++++++++++++++++++++ hostside/kdled-ioctl.c | 18 ++++++ neo-s.pl | 20 +++++++ 7 files changed, 315 insertions(+) create mode 100644 hostside/hiddev-ioctl.c create mode 100644 hostside/hidraw-ioctl.c create mode 100644 hostside/hidraw.h create mode 100644 hostside/kdled-ioctl.c create mode 100755 neo-s.pl diff --git a/hostside/.gitignore b/hostside/.gitignore index 7238cd8..b47722d 100644 --- a/hostside/.gitignore +++ b/hostside/.gitignore @@ -28,3 +28,6 @@ record-y.[ch] evdev-manip input-codes.h +dump.* +hiddev-ioctl +hidraw-ioctl +kdled-ioctl diff --git a/hostside/Makefile b/hostside/Makefile index 9bf7609..9cdce76 100644 --- a/hostside/Makefile +++ b/hostside/Makefile @@ -39,6 +39,8 @@ topology-dump: topology-dump.o utils.o $(LAYOUT_DATA).o evdev-manip: evdev-manip.o utils.o $(LIBOOP_OBJS) +hid%-ioctl: $@.o utils.o + gui-plan-bot: gui-plan-%: gui-plan.o utils.o parseutils.o obc.o \ ../layout/ours.dgram-%.plandata.o \ $(LAYOUT_DATA).o $(LIBOOP_OBJS) diff --git a/hostside/hiddev-ioctl.c b/hostside/hiddev-ioctl.c new file mode 100644 index 0000000..d6fd11c --- /dev/null +++ b/hostside/hiddev-ioctl.c @@ -0,0 +1,119 @@ +/**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "common.h" + +#if 0 +static void dump(const void *pu, int l) { + const uint8_t *p= pu; + while (l>0) { + printf("%02x",*p++); + l--; + } + putchar(' '); +} +#endif + +static void report_scan(const char *which, int type) { + struct hiddev_report_info rinfo; + int r, i, j; + int fd=0; + + rinfo.report_type = type; + rinfo.report_id = HID_REPORT_ID_FIRST; + + for (;;) { + r = ioctl(fd, HIDIOCGREPORTINFO, &rinfo); + if (r && errno==EINVAL) break; + if (r) diee("HIDIOCGREPORTINFO"); + + printf("%s type=%08"PRIx32" id=%08"PRIx32" num_fields=%08"PRIx32"\n", + which, rinfo.report_type, rinfo.report_id, rinfo.num_fields); + for (i=0; i < rinfo.num_fields; i++) { + struct hiddev_field_info finfo; + finfo.report_type= rinfo.report_type; + finfo.report_id= rinfo.report_id; + finfo.field_index= i; + r= ioctl(fd, HIDIOCGFIELDINFO, &finfo); + if (r) diee("HIDIOCGFIELDINFO"); + printf("%s type=%08"PRIx32" id=%08"PRIx32" fi=%08"PRIx32 + " maxusage=%08"PRIx32" flags=%08"PRIx32 + " phys=%08"PRIx32"/log=%08"PRIx32"/app=%08"PRIx32 + " log=%08"PRIx32"..%08"PRIx32 + " phys=%08"PRIx32"..%08"PRIx32 + "\n", + which, finfo.report_type, finfo.report_id, finfo.field_index, + finfo.maxusage, finfo.flags, + finfo.physical, finfo.logical, finfo.application, + finfo.logical_minimum, finfo.logical_maximum, + finfo.physical_minimum, finfo.physical_maximum + ); + for (j=0; j < finfo.maxusage; j++) { + struct hiddev_usage_ref uref; + uref.report_type= finfo.report_type; + uref.report_id= finfo.report_id; + uref.field_index= i; + uref.usage_index= j; + r= ioctl(fd, HIDIOCGUCODE, &uref); +//dump(&uref,sizeof(uref)); + r= ioctl(fd, HIDIOCGUSAGE, &uref); +//dump(&uref,sizeof(uref)); + printf("%s type=%08"PRIx32" id=%08"PRIx32" fi=%08"PRIx32 + " ui=%08"PRIx32" uc=%08"PRIx32" val=%08"PRIx32"\n", + which, uref.report_type, uref.report_id, uref.field_index, + uref.usage_index, uref.usage_code, uref.value); + } + } + rinfo.report_id |= HID_REPORT_ID_NEXT; + } +} + +void die_vprintf_hook(const char *fmt, va_list al) { } +void die_hook(void) { } +const char *progname= "hiddev-ioctl"; + +int main(int argc, char **argv) { + int r; + if (!argv[0] || !argv[1]) badusage("too few args"); + const char *act= *++argv; + if (!strcmp(act, "scan")) { + report_scan("input", HID_REPORT_TYPE_INPUT); + report_scan("output", HID_REPORT_TYPE_OUTPUT); + } else if (!strcmp(act, "send")) { + /* type id field val */ + if (!argv[1] || !argv[2] || !argv[3] || !argv[4] + || !argv[5] || !argv[6] || argv[7]) + badusage("wrong # args"); + struct hiddev_usage_ref uref; + struct hiddev_report_info rinfo; + uref.report_type= strtoul(argv[1],0,0); + uref.report_id= strtoul(argv[2],0,0); + uref.field_index= strtoul(argv[3],0,0); + uref.usage_index= strtoul(argv[4],0,0); + uref.usage_code= strtoul(argv[5],0,0); + uref.value= strtol(argv[6],0,0); + rinfo.report_type= uref.report_type; + rinfo.report_id= uref.report_id; + rinfo.num_fields= 0; +// r= ioctl(0, HIDIOCGREPORT, &rinfo); if (r) diee("HIDIOCGREPORT"); +// r= ioctl(0, HIDIOCGUSAGE, &uref); if (r) diee("HIDIOCGUSAGE"); +//dump(&uref,sizeof(uref)); +// printf("%08"PRIx32"...",uref.value); + r= ioctl(0, HIDIOCSUSAGE, &uref); if (r) diee("HIDIOCSUSAGE"); + r= ioctl(0, HIDIOCSREPORT, &rinfo); if (r) diee("HIDIOCSREPORT"); + } else { + badusage("unknown action"); + } + return 0; +} diff --git a/hostside/hidraw-ioctl.c b/hostside/hidraw-ioctl.c new file mode 100644 index 0000000..e5ac44a --- /dev/null +++ b/hostside/hidraw-ioctl.c @@ -0,0 +1,64 @@ +/**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "hidraw.h" + +#include "common.h" + +static void dump(const void *pu, int l) { + const uint8_t *p= pu; + while (l>0) { + printf("%02x",*p++); + l--; + } + putchar(' '); +} + +int main(int argc, char **argv) { + int r, descsz; + + r= ioctl(0, HIDIOCGRDESCSIZE, &descsz); + if (r) { + perror("HIDIOCGRDESCSIZE"); + } else { + printf("%d\n",descsz); + struct { + struct hidraw_report_descriptor d; + unsigned char buf[descsz]; + } d; + d.d.size = descsz; + r= ioctl(0, HIDIOCGRDESC, &d); + if (r) perror("HIDIOCGRDESC"); + else { dump(d.d.value, d.d.size); putchar('\n'); } + } + + struct hidraw_devinfo di; + r= ioctl(0, HIDIOCGRAWINFO, &di); + if (r) perror("HIDIOCGRAWINFO"); + else { + printf("%08"PRIx32" %04"PRIx16" %04"PRIx16"\n", + di.bustype, di.vendor, di.product); + } + + unsigned char buf[PATH_MAX]; + + r= ioctl(0, HIDIOCGRAWNAME(PATH_MAX), buf); + if (r<0) perror("HIDIOCGRAWNAME"); + else printf("%d %.*s\n", r, r,buf); + + r= ioctl(0, HIDIOCGRAWPHYS(PATH_MAX), buf); + if (r<0) perror("HIDIOCGRAWPHYS"); + else printf("%d %.*s\n", r, r,buf); + + return 0; +} diff --git a/hostside/hidraw.h b/hostside/hidraw.h new file mode 100644 index 0000000..dd8d692 --- /dev/null +++ b/hostside/hidraw.h @@ -0,0 +1,89 @@ +#ifndef _HIDRAW_H +#define _HIDRAW_H + +/* + * Copyright (c) 2007 Jiri Kosina + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +struct hidraw_report_descriptor { + __u32 size; + __u8 value[HID_MAX_DESCRIPTOR_SIZE]; +}; + +struct hidraw_devinfo { + __u32 bustype; + __s16 vendor; + __s16 product; +}; + +/* ioctl interface */ +#define HIDIOCGRDESCSIZE _IOR('H', 0x01, int) +#define HIDIOCGRDESC _IOR('H', 0x02, struct hidraw_report_descriptor) +#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo) +#define HIDIOCGRAWNAME(len) _IOC(_IOC_READ, 'H', 0x04, len) +#define HIDIOCGRAWPHYS(len) _IOC(_IOC_READ, 'H', 0x05, len) + +#define HIDRAW_FIRST_MINOR 0 +#define HIDRAW_MAX_DEVICES 64 +/* number of reports to buffer */ +#define HIDRAW_BUFFER_SIZE 64 + + +/* kernel-only API declarations */ +#ifdef __KERNEL__ + +struct hidraw { + unsigned int minor; + int exist; + int open; + wait_queue_head_t wait; + struct hid_device *hid; + struct device *dev; + struct list_head list; +}; + +struct hidraw_report { + __u8 *value; + int len; +}; + +struct hidraw_list { + struct hidraw_report buffer[HIDRAW_BUFFER_SIZE]; + int head; + int tail; + struct fasync_struct *fasync; + struct hidraw *hidraw; + struct list_head node; + struct mutex read_mutex; +}; + +#ifdef CONFIG_HIDRAW +int hidraw_init(void); +void hidraw_exit(void); +void hidraw_report_event(struct hid_device *, u8 *, int); +int hidraw_connect(struct hid_device *); +void hidraw_disconnect(struct hid_device *); +#else +static inline int hidraw_init(void) { return 0; } +static inline void hidraw_exit(void) { } +static inline void hidraw_report_event(struct hid_device *hid, u8 *data, int len) { } +static inline int hidraw_connect(struct hid_device *hid) { return -1; } +static inline void hidraw_disconnect(struct hid_device *hid) { } +#endif + +#endif + +#endif diff --git a/hostside/kdled-ioctl.c b/hostside/kdled-ioctl.c new file mode 100644 index 0000000..c55d5a9 --- /dev/null +++ b/hostside/kdled-ioctl.c @@ -0,0 +1,18 @@ +/**/ + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + uint8_t l; + int r; + r= ioctl(0, KDGETLED, &l); + if (r<0) { perror("KDGETLED"); exit(-1); } + printf("%02x\n", l); + return 0; +} diff --git a/neo-s.pl b/neo-s.pl new file mode 100755 index 0000000..f8f0c37 --- /dev/null +++ b/neo-s.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl +$|=1; +for ($a=0x43; $a<=0x53; $a+=0x10) { + next if $a eq 0x46; +#for ($b=90; $b<=95; $b++) { + $b=0xff; +printf STDERR "%02x %02x\n", $b, $a; +#next if $a eq 0x46; + print pack("c*", 0xff, $b,$a) or die $!; +#} +printf STDERR "---\n"; +#sleep 1;# if !($a & 0x0f); +} + +__END__ + +speed,0x00,0x46 rumble + ??,0x00,0x43 ?? is something to do with mouse acceleration; with ??=0 + no mice visible +0xff,0x00,0x53 swaps things round -- 2.30.2