^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Force feedback support for Mayflash game controller adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * These devices are manufactured by Mayflash but identify themselves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * using the vendor ID of DragonRise Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Tested with:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 0079:1801 "DragonRise Inc. Mayflash PS3 Game Controller Adapter"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * 0079:1803 "DragonRise Inc. Mayflash Wireless Sensor DolphinBar"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 0079:1843 "DragonRise Inc. Mayflash GameCube Game Controller Adapter"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * 0079:1844 "DragonRise Inc. Mayflash GameCube Game Controller Adapter (v04)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * The following adapters probably work too, but need to be tested:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * 0079:1800 "DragonRise Inc. Mayflash WIIU Game Controller Adapter"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Copyright (c) 2016-2017 Marcel Hasler <mahasler@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/hid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "hid-ids.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct mf_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static int mf_play(struct input_dev *dev, void *data, struct ff_effect *effect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct hid_device *hid = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct mf_device *mf = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int strong, weak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) strong = effect->u.rumble.strong_magnitude;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) weak = effect->u.rumble.weak_magnitude;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) dbg_hid("Called with 0x%04x 0x%04x.\n", strong, weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) strong = strong * 0xff / 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) weak = weak * 0xff / 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dbg_hid("Running with 0x%02x 0x%02x.\n", strong, weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) mf->report->field[0]->value[0] = weak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) mf->report->field[0]->value[1] = strong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) hid_hw_request(hid, mf->report, HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static int mf_init(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct mf_device *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct list_head *report_list =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) &hid->report_enum[HID_OUTPUT_REPORT].report_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct list_head *report_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct list_head *input_ptr = &hid->inputs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct hid_input *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct input_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Setup each of the four inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) list_for_each(report_ptr, report_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) report = list_entry(report_ptr, struct hid_report, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (report->maxfield < 1 || report->field[0]->report_count < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) hid_err(hid, "Invalid report, this should never happen!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (list_is_last(input_ptr, &hid->inputs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) hid_err(hid, "Missing input, this should never happen!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) input_ptr = input_ptr->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) input = list_entry(input_ptr, struct hid_input, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) mf = kzalloc(sizeof(struct mf_device), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) dev = input->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) set_bit(FF_RUMBLE, dev->ffbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) error = input_ff_create_memless(dev, mf, mf_play);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) kfree(mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) mf->report = report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) mf->report->field[0]->value[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mf->report->field[0]->value[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) hid_hw_request(hid, mf->report, HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) hid_info(hid, "Force feedback for HJZ Mayflash game controller "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) "adapters by Marcel Hasler <mahasler@gmail.com>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static int mf_probe(struct hid_device *hid, const struct hid_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) dev_dbg(&hid->dev, "Mayflash HID hardware probe...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* Apply quirks as needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) hid->quirks |= id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) error = hid_parse(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) hid_err(hid, "HID parse failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) error = hid_hw_start(hid, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) hid_err(hid, "HID hw start failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) error = mf_init(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) hid_err(hid, "Force feedback init failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) hid_hw_stop(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static const struct hid_device_id mf_devices[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .driver_data = HID_QUIRK_MULTI_INPUT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .driver_data = HID_QUIRK_MULTI_INPUT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .driver_data = HID_QUIRK_MULTI_INPUT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .driver_data = 0 }, /* No quirk required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .driver_data = HID_QUIRK_MULTI_INPUT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) MODULE_DEVICE_TABLE(hid, mf_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static struct hid_driver mf_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .name = "hid_mf",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .id_table = mf_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .probe = mf_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) module_hid_driver(mf_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) MODULE_LICENSE("GPL");