Blame view
drivers/hid/hid-zpff.c
3.9 KB
bb3caf7f4 Input: add force ... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* * Force feedback support for Zeroplus based devices * * Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com> */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
987fbc1f7 HID: move zeroplu... |
22 |
#include <linux/hid.h> |
bb3caf7f4 Input: add force ... |
23 24 |
#include <linux/input.h> #include <linux/usb.h> |
987fbc1f7 HID: move zeroplu... |
25 26 27 28 |
#include "hid-ids.h" #include "usbhid/usbhid.h" |
bb3caf7f4 Input: add force ... |
29 30 31 32 |
struct zpff_device { struct hid_report *report; }; |
987fbc1f7 HID: move zeroplu... |
33 |
static int zpff_play(struct input_dev *dev, void *data, |
bb3caf7f4 Input: add force ... |
34 35 |
struct ff_effect *effect) { |
e07129858 HID: switch to us... |
36 |
struct hid_device *hid = input_get_drvdata(dev); |
bb3caf7f4 Input: add force ... |
37 38 39 40 41 42 43 44 45 46 47 |
struct zpff_device *zpff = data; int left, right; /* * The following is specified the other way around in the Zeroplus * datasheet but the order below is correct for the XFX Executioner; * however it is possible that the XFX Executioner is an exception */ left = effect->u.rumble.strong_magnitude; right = effect->u.rumble.weak_magnitude; |
58037eb96 HID: make debuggi... |
48 49 |
dbg_hid("called with 0x%04x 0x%04x ", left, right); |
bb3caf7f4 Input: add force ... |
50 51 52 53 54 55 |
left = left * 0x7f / 0xffff; right = right * 0x7f / 0xffff; zpff->report->field[2]->value[0] = left; zpff->report->field[3]->value[0] = right; |
58037eb96 HID: make debuggi... |
56 57 |
dbg_hid("running with 0x%02x 0x%02x ", left, right); |
4916b3a57 [PATCH] Generic H... |
58 |
usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); |
bb3caf7f4 Input: add force ... |
59 60 61 |
return 0; } |
987fbc1f7 HID: move zeroplu... |
62 |
static int zpff_init(struct hid_device *hid) |
bb3caf7f4 Input: add force ... |
63 64 65 66 67 68 69 70 71 72 73 |
{ struct zpff_device *zpff; struct hid_report *report; struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; struct input_dev *dev = hidinput->input; int error; if (list_empty(report_list)) { |
795750197 HID: convert to d... |
74 75 |
dev_err(&hid->dev, "no output report found "); |
bb3caf7f4 Input: add force ... |
76 77 78 79 80 81 |
return -ENODEV; } report = list_entry(report_list->next, struct hid_report, list); if (report->maxfield < 4) { |
795750197 HID: convert to d... |
82 83 |
dev_err(&hid->dev, "not enough fields in report "); |
bb3caf7f4 Input: add force ... |
84 85 86 87 88 89 90 91 |
return -ENODEV; } zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); if (!zpff) return -ENOMEM; set_bit(FF_RUMBLE, dev->ffbit); |
987fbc1f7 HID: move zeroplu... |
92 |
error = input_ff_create_memless(dev, zpff, zpff_play); |
bb3caf7f4 Input: add force ... |
93 94 95 96 97 98 99 100 101 102 |
if (error) { kfree(zpff); return error; } zpff->report = report; zpff->report->field[0]->value[0] = 0x00; zpff->report->field[1]->value[0] = 0x02; zpff->report->field[2]->value[0] = 0x00; zpff->report->field[3]->value[0] = 0x00; |
4916b3a57 [PATCH] Generic H... |
103 |
usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); |
bb3caf7f4 Input: add force ... |
104 |
|
795750197 HID: convert to d... |
105 |
dev_info(&hid->dev, "force feedback for Zeroplus based devices by " |
bb3caf7f4 Input: add force ... |
106 107 108 109 110 |
"Anssi Hannula <anssi.hannula@gmail.com> "); return 0; } |
987fbc1f7 HID: move zeroplu... |
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "parse failed "); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { dev_err(&hdev->dev, "hw start failed "); goto err; } zpff_init(hdev); return 0; err: return ret; } static const struct hid_device_id zp_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, { } }; MODULE_DEVICE_TABLE(hid, zp_devices); static struct hid_driver zp_driver = { .name = "zeroplus", .id_table = zp_devices, .probe = zp_probe, }; static int zp_init(void) { return hid_register_driver(&zp_driver); } static void zp_exit(void) { hid_unregister_driver(&zp_driver); } module_init(zp_init); module_exit(zp_exit); MODULE_LICENSE("GPL"); HID_COMPAT_LOAD_DRIVER(zeroplus); |