0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/device.h>
0021 #include <linux/hid.h>
0022 #include <linux/module.h>
0023 #include <linux/kernel.h>
0024
0025 #include "hid-ids.h"
0026
0027 #define SAITEK_FIX_PS1000 0x0001
0028 #define SAITEK_RELEASE_MODE_RAT7 0x0002
0029 #define SAITEK_RELEASE_MODE_MMO7 0x0004
0030
0031 struct saitek_sc {
0032 unsigned long quirks;
0033 int mode;
0034 };
0035
0036 static int saitek_probe(struct hid_device *hdev,
0037 const struct hid_device_id *id)
0038 {
0039 unsigned long quirks = id->driver_data;
0040 struct saitek_sc *ssc;
0041 int ret;
0042
0043 ssc = devm_kzalloc(&hdev->dev, sizeof(*ssc), GFP_KERNEL);
0044 if (ssc == NULL) {
0045 hid_err(hdev, "can't alloc saitek descriptor\n");
0046 return -ENOMEM;
0047 }
0048
0049 ssc->quirks = quirks;
0050 ssc->mode = -1;
0051
0052 hid_set_drvdata(hdev, ssc);
0053
0054 ret = hid_parse(hdev);
0055 if (ret) {
0056 hid_err(hdev, "parse failed\n");
0057 return ret;
0058 }
0059
0060 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
0061 if (ret) {
0062 hid_err(hdev, "hw start failed\n");
0063 return ret;
0064 }
0065
0066 return 0;
0067 }
0068
0069 static __u8 *saitek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
0070 unsigned int *rsize)
0071 {
0072 struct saitek_sc *ssc = hid_get_drvdata(hdev);
0073
0074 if ((ssc->quirks & SAITEK_FIX_PS1000) && *rsize == 137 &&
0075 rdesc[20] == 0x09 && rdesc[21] == 0x33 &&
0076 rdesc[94] == 0x81 && rdesc[95] == 0x03 &&
0077 rdesc[110] == 0x81 && rdesc[111] == 0x03) {
0078
0079 hid_info(hdev, "Fixing up Saitek PS1000 report descriptor\n");
0080
0081
0082 rdesc[20] = 0x15;
0083 rdesc[21] = 0x00;
0084
0085
0086 rdesc[95] = 0x02;
0087 rdesc[111] = 0x02;
0088
0089 }
0090 return rdesc;
0091 }
0092
0093 static int saitek_raw_event(struct hid_device *hdev,
0094 struct hid_report *report, u8 *raw_data, int size)
0095 {
0096 struct saitek_sc *ssc = hid_get_drvdata(hdev);
0097
0098 if (ssc->quirks & SAITEK_RELEASE_MODE_RAT7 && size == 7) {
0099
0100 int mode = -1;
0101 if (raw_data[1] & 0x01)
0102 mode = 0;
0103 else if (raw_data[1] & 0x02)
0104 mode = 1;
0105 else if (raw_data[1] & 0x04)
0106 mode = 2;
0107
0108
0109 raw_data[1] &= ~0x07;
0110
0111 if (mode != ssc->mode) {
0112 hid_dbg(hdev, "entered mode %d\n", mode);
0113 if (ssc->mode != -1) {
0114
0115 raw_data[1] |= 0x04;
0116 }
0117 ssc->mode = mode;
0118 }
0119 } else if (ssc->quirks & SAITEK_RELEASE_MODE_MMO7 && size == 8) {
0120
0121
0122 int mode = -1;
0123 if (raw_data[1] & 0x80)
0124 mode = 0;
0125 else if (raw_data[2] & 0x01)
0126 mode = 1;
0127 else if (raw_data[2] & 0x02)
0128 mode = 2;
0129
0130
0131 raw_data[1] &= ~0x80;
0132 raw_data[2] &= ~0x03;
0133
0134 if (mode != ssc->mode) {
0135 hid_dbg(hdev, "entered mode %d\n", mode);
0136 if (ssc->mode != -1) {
0137
0138
0139
0140
0141 raw_data[1] |= 0x80;
0142 }
0143 ssc->mode = mode;
0144 }
0145 }
0146
0147 return 0;
0148 }
0149
0150 static int saitek_event(struct hid_device *hdev, struct hid_field *field,
0151 struct hid_usage *usage, __s32 value)
0152 {
0153 struct saitek_sc *ssc = hid_get_drvdata(hdev);
0154 struct input_dev *input = field->hidinput->input;
0155
0156 if (usage->type == EV_KEY && value &&
0157 (((ssc->quirks & SAITEK_RELEASE_MODE_RAT7) &&
0158 usage->code - BTN_MOUSE == 10) ||
0159 ((ssc->quirks & SAITEK_RELEASE_MODE_MMO7) &&
0160 usage->code - BTN_MOUSE == 15))) {
0161
0162 input_report_key(input, usage->code, 1);
0163
0164
0165 input_report_key(input, usage->code, 0);
0166
0167 return 1;
0168 }
0169
0170 return 0;
0171 }
0172
0173 static const struct hid_device_id saitek_devices[] = {
0174 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000),
0175 .driver_data = SAITEK_FIX_PS1000 },
0176 { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5),
0177 .driver_data = SAITEK_RELEASE_MODE_RAT7 },
0178 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD),
0179 .driver_data = SAITEK_RELEASE_MODE_RAT7 },
0180 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7),
0181 .driver_data = SAITEK_RELEASE_MODE_RAT7 },
0182 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_CONTAGION),
0183 .driver_data = SAITEK_RELEASE_MODE_RAT7 },
0184 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT9),
0185 .driver_data = SAITEK_RELEASE_MODE_RAT7 },
0186 { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9),
0187 .driver_data = SAITEK_RELEASE_MODE_RAT7 },
0188 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7),
0189 .driver_data = SAITEK_RELEASE_MODE_MMO7 },
0190 { }
0191 };
0192
0193 MODULE_DEVICE_TABLE(hid, saitek_devices);
0194
0195 static struct hid_driver saitek_driver = {
0196 .name = "saitek",
0197 .id_table = saitek_devices,
0198 .probe = saitek_probe,
0199 .report_fixup = saitek_report_fixup,
0200 .raw_event = saitek_raw_event,
0201 .event = saitek_event,
0202 };
0203 module_hid_driver(saitek_driver);
0204
0205 MODULE_LICENSE("GPL");