0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/hid.h>
0013 #include <linux/input.h>
0014 #include <linux/slab.h>
0015 #include <linux/module.h>
0016
0017 #include "hid-ids.h"
0018
0019 #ifdef CONFIG_ZEROPLUS_FF
0020
0021 struct zpff_device {
0022 struct hid_report *report;
0023 };
0024
0025 static int zpff_play(struct input_dev *dev, void *data,
0026 struct ff_effect *effect)
0027 {
0028 struct hid_device *hid = input_get_drvdata(dev);
0029 struct zpff_device *zpff = data;
0030 int left, right;
0031
0032
0033
0034
0035
0036
0037
0038 left = effect->u.rumble.strong_magnitude;
0039 right = effect->u.rumble.weak_magnitude;
0040 dbg_hid("called with 0x%04x 0x%04x\n", left, right);
0041
0042 left = left * 0x7f / 0xffff;
0043 right = right * 0x7f / 0xffff;
0044
0045 zpff->report->field[2]->value[0] = left;
0046 zpff->report->field[3]->value[0] = right;
0047 dbg_hid("running with 0x%02x 0x%02x\n", left, right);
0048 hid_hw_request(hid, zpff->report, HID_REQ_SET_REPORT);
0049
0050 return 0;
0051 }
0052
0053 static int zpff_init(struct hid_device *hid)
0054 {
0055 struct zpff_device *zpff;
0056 struct hid_report *report;
0057 struct hid_input *hidinput;
0058 struct input_dev *dev;
0059 int i, error;
0060
0061 if (list_empty(&hid->inputs)) {
0062 hid_err(hid, "no inputs found\n");
0063 return -ENODEV;
0064 }
0065 hidinput = list_entry(hid->inputs.next, struct hid_input, list);
0066 dev = hidinput->input;
0067
0068 for (i = 0; i < 4; i++) {
0069 report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1);
0070 if (!report)
0071 return -ENODEV;
0072 }
0073
0074 zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
0075 if (!zpff)
0076 return -ENOMEM;
0077
0078 set_bit(FF_RUMBLE, dev->ffbit);
0079
0080 error = input_ff_create_memless(dev, zpff, zpff_play);
0081 if (error) {
0082 kfree(zpff);
0083 return error;
0084 }
0085
0086 zpff->report = report;
0087 zpff->report->field[0]->value[0] = 0x00;
0088 zpff->report->field[1]->value[0] = 0x02;
0089 zpff->report->field[2]->value[0] = 0x00;
0090 zpff->report->field[3]->value[0] = 0x00;
0091 hid_hw_request(hid, zpff->report, HID_REQ_SET_REPORT);
0092
0093 hid_info(hid, "force feedback for Zeroplus based devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
0094
0095 return 0;
0096 }
0097 #else
0098 static inline int zpff_init(struct hid_device *hid)
0099 {
0100 return 0;
0101 }
0102 #endif
0103
0104 static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id)
0105 {
0106 int ret;
0107
0108 ret = hid_parse(hdev);
0109 if (ret) {
0110 hid_err(hdev, "parse failed\n");
0111 goto err;
0112 }
0113
0114 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
0115 if (ret) {
0116 hid_err(hdev, "hw start failed\n");
0117 goto err;
0118 }
0119
0120 zpff_init(hdev);
0121
0122 return 0;
0123 err:
0124 return ret;
0125 }
0126
0127 static const struct hid_device_id zp_devices[] = {
0128 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
0129 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
0130 { }
0131 };
0132 MODULE_DEVICE_TABLE(hid, zp_devices);
0133
0134 static struct hid_driver zp_driver = {
0135 .name = "zeroplus",
0136 .id_table = zp_devices,
0137 .probe = zp_probe,
0138 };
0139 module_hid_driver(zp_driver);
0140
0141 MODULE_LICENSE("GPL");