linux/drivers/hid/hid-thrustmaster.c

// SPDX-License-Identifier: GPL-2.0
/*
 * When connected to the machine, the Thrustmaster wheels appear as
 * a «generic» hid gamepad called "Thrustmaster FFB Wheel".
 *
 * When in this mode not every functionality of the wheel, like the force feedback,
 * are available. To enable all functionalities of a Thrustmaster wheel we have to send
 * to it a specific USB CONTROL request with a code different for each wheel.
 *
 * This driver tries to understand which model of Thrustmaster wheel the generic
 * "Thrustmaster FFB Wheel" really is and then sends the appropriate control code.
 *
 * Copyright (c) 2020-2021 Dario Pagani <[email protected]>
 * Copyright (c) 2020-2021 Kim Kuparinen <[email protected]>
 */
#include <linux/hid.h>
#include <linux/usb.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/module.h>

/*
 * These interrupts are used to prevent a nasty crash when initializing the
 * T300RS. Used in thrustmaster_interrupts().
 */
static const u8 setup_0[] =;
static const u8 setup_1[] =;
static const u8 setup_2[] =;
static const u8 setup_3[] =;
static const u8 setup_4[] =;
static const u8 *const setup_arr[] =;
static const unsigned int setup_arr_sizes[] =;
/*
 * This struct contains for each type of
 * Thrustmaster wheel
 *
 * Note: The values are stored in the CPU
 * endianness, the USB protocols always use
 * little endian; the macro cpu_to_le[BIT]()
 * must be used when preparing USB packets
 * and vice-versa
 */
struct tm_wheel_info {};

/*
 * Known wheels.
 * Note: TMX does not work as it requires 2 control packets
 */
static const struct tm_wheel_info tm_wheels_infos[] =;

static const uint8_t tm_wheels_infos_length =;

/*
 * This structs contains (in little endian) the response data
 * of the wheel to the request 73
 *
 * A sufficient research to understand what each field does is not
 * beign conducted yet. The position and meaning of fields are a
 * just a very optimistic guess based on instinct....
 */
struct __packed tm_wheel_response
{};

struct tm_wheel {};

/* The control packet to send to wheel */
static const struct usb_ctrlrequest model_request =;

static const struct usb_ctrlrequest change_request =;

/*
 * On some setups initializing the T300RS crashes the kernel,
 * these interrupts fix that particular issue. So far they haven't caused any
 * adverse effects in other wheels.
 */
static void thrustmaster_interrupts(struct hid_device *hdev)
{}

static void thrustmaster_change_handler(struct urb *urb)
{}

/*
 * Called by the USB subsystem when the wheel responses to our request
 * to get [what it seems to be] the wheel's model.
 *
 * If the model id is recognized then we send an opportune USB CONTROL REQUEST
 * to switch the wheel to its full capabilities
 */
static void thrustmaster_model_handler(struct urb *urb)
{}

static void thrustmaster_remove(struct hid_device *hdev)
{}

/*
 * Function called by HID when a hid Thrustmaster FFB wheel is connected to the host.
 * This function starts the hid dev, tries to allocate the tm_wheel data structure and
 * finally send an USB CONTROL REQUEST to the wheel to get [what it seems to be] its
 * model type.
 */
static int thrustmaster_probe(struct hid_device *hdev, const struct hid_device_id *id)
{}

static const struct hid_device_id thrustmaster_devices[] =;

MODULE_DEVICE_TABLE(hid, thrustmaster_devices);

static struct hid_driver thrustmaster_driver =;

module_hid_driver();

MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_DESCRIPTION();