hid: move proper hat switch handling from ps4dshock to hgame

Generic "DirectInput" HID gamepads need this handling too.

Reviewed by:	wulf
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D31398
This commit is contained in:
Greg V 2021-08-16 23:18:09 +03:00 committed by Vladimir Kondratyev
parent cb910670ac
commit 51b2216114
3 changed files with 37 additions and 33 deletions

View File

@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$");
{ HIDMAP_KEY_RANGE(HUP_BUTTON, number_from, number_to, code) }
#define HGAME_MAP_ABS(usage, code) \
{ HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code) }
#define HGAME_MAP_GCB(usage, callback) \
{ HIDMAP_ANY_CB(HUP_GENERIC_DESKTOP, HUG_##usage, callback) }
#define HGAME_MAP_CRG(usage_from, usage_to, callback) \
{ HIDMAP_ANY_CB_RANGE(HUP_GENERIC_DESKTOP, \
HUG_##usage_from, HUG_##usage_to, callback) }
@ -66,7 +68,7 @@ static const struct hidmap_item hgame_map[] = {
HGAME_MAP_ABS(RX, ABS_RX),
HGAME_MAP_ABS(RY, ABS_RY),
HGAME_MAP_ABS(RZ, ABS_RZ),
HGAME_MAP_ABS(HAT_SWITCH, ABS_HAT0X),
HGAME_MAP_GCB(HAT_SWITCH, hgame_hat_switch_cb),
HGAME_MAP_CRG(D_PAD_UP, D_PAD_LEFT, hgame_dpad_cb),
HGAME_MAP_BRG(17, 57, BTN_TRIGGER_HAPPY),
HGAME_FINALCB( hgame_final_cb),
@ -79,6 +81,36 @@ static const struct hid_device_id hgame_devs[] = {
HID_DRIVER_INFO(HUG_GAME_PAD) },
};
int
hgame_hat_switch_cb(HIDMAP_CB_ARGS)
{
static const struct { int32_t x; int32_t y; } hat_switch_map[] = {
{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0},
{-1, -1},{0, 0}
};
struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
u_int idx;
switch (HIDMAP_CB_GET_STATE()) {
case HIDMAP_CB_IS_ATTACHING:
evdev_support_event(evdev, EV_ABS);
evdev_support_abs(evdev, ABS_HAT0X, -1, 1, 0, 0, 0);
evdev_support_abs(evdev, ABS_HAT0Y, -1, 1, 0, 0, 0);
break;
case HIDMAP_CB_IS_RUNNING:
idx = MIN(nitems(hat_switch_map) - 1, (u_int)ctx.data);
evdev_push_abs(evdev, ABS_HAT0X, hat_switch_map[idx].x);
evdev_push_abs(evdev, ABS_HAT0Y, hat_switch_map[idx].y);
break;
default:
break;
}
return (0);
}
/*
* Emulate the hat switch report via the D-pad usages
* found on XInput/XBox style devices

View File

@ -31,6 +31,7 @@
#include <dev/hid/hidmap.h>
hidmap_cb_t hgame_hat_switch_cb;
hidmap_cb_t hgame_dpad_cb;
hidmap_cb_t hgame_final_cb;

View File

@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <dev/evdev/evdev.h>
#define HID_DEBUG_VAR ps4dshock_debug
#include <dev/hid/hgame.h>
#include <dev/hid/hid.h>
#include <dev/hid/hidbus.h>
#include <dev/hid/hidquirk.h>
@ -588,7 +589,6 @@ static const uint8_t ps4dshock_rdesc[] = {
#define PS4DS_OUTPUT_REPORT5_SIZE 32
#define PS4DS_OUTPUT_REPORT11_SIZE 78
static hidmap_cb_t ps4dshock_hat_switch_cb;
static hidmap_cb_t ps4dshock_final_cb;
static hidmap_cb_t ps4dsacc_data_cb;
static hidmap_cb_t ps4dsacc_tstamp_cb;
@ -743,7 +743,7 @@ static const struct hidmap_item ps4dshock_map[] = {
PS4DS_MAP_BTN(13, BTN_MODE),
/* Click button is handled by touchpad driver */
/* PS4DS_MAP_BTN(14, BTN_LEFT), */
PS4DS_MAP_GCB(HAT_SWITCH, ps4dshock_hat_switch_cb),
PS4DS_MAP_GCB(HAT_SWITCH, hgame_hat_switch_cb),
PS4DS_FINALCB( ps4dshock_final_cb),
};
static const struct hidmap_item ps4dsacc_map[] = {
@ -787,36 +787,6 @@ static const struct hid_device_id ps4dsmtp_devs[] = {
HID_TLC(HUP_DIGITIZERS, HUD_TOUCHPAD) },
};
static int
ps4dshock_hat_switch_cb(HIDMAP_CB_ARGS)
{
static const struct { int32_t x; int32_t y; } hat_switch_map[] = {
{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0},
{-1, -1},{0, 0}
};
struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
u_int idx;
switch (HIDMAP_CB_GET_STATE()) {
case HIDMAP_CB_IS_ATTACHING:
evdev_support_event(evdev, EV_ABS);
evdev_support_abs(evdev, ABS_HAT0X, -1, 1, 0, 0, 0);
evdev_support_abs(evdev, ABS_HAT0Y, -1, 1, 0, 0, 0);
break;
case HIDMAP_CB_IS_RUNNING:
idx = MIN(nitems(hat_switch_map) - 1, (u_int)ctx.data);
evdev_push_abs(evdev, ABS_HAT0X, hat_switch_map[idx].x);
evdev_push_abs(evdev, ABS_HAT0Y, hat_switch_map[idx].y);
break;
default:
break;
}
return (0);
}
static int
ps4dshock_final_cb(HIDMAP_CB_ARGS)
{
@ -1414,6 +1384,7 @@ DRIVER_MODULE(ps4dshock, hidbus, ps4dshock_driver, ps4dshock_devclass, NULL, 0);
MODULE_DEPEND(ps4dshock, hid, 1, 1, 1);
MODULE_DEPEND(ps4dshock, hidbus, 1, 1, 1);
MODULE_DEPEND(ps4dshock, hidmap, 1, 1, 1);
MODULE_DEPEND(ps4dshock, hgame, 1, 1, 1);
MODULE_DEPEND(ps4dshock, evdev, 1, 1, 1);
MODULE_VERSION(ps4dshock, 1);
HID_PNP_INFO(ps4dshock_devs);