320 lines
12 KiB
Diff
320 lines
12 KiB
Diff
commit 711909b33d6fdee149b5cb58bd888e7c10407acb
|
|
Author: Bastien Nocera <hadess@hadess.net>
|
|
Date: Wed Apr 21 15:24:56 2010 +0100
|
|
|
|
Add support for the Wacom Intuos 4 wireless
|
|
|
|
And to the HID blacklist.
|
|
|
|
Same command set as the Graphire Bluetooth tablet.
|
|
|
|
Signed-off-by: Bastien Nocera <hadess@hadess.net>
|
|
|
|
commit 1e03f3dc79ae5a9456545702f6dcac1023b06666
|
|
Author: Antonio Ospite <ospite@studenti.unina.it>
|
|
Date: Thu Apr 29 23:59:34 2010 +0200
|
|
|
|
hid/hid-sony: fix sony_set_operational_bt
|
|
|
|
Don't send the report type as part of the data, this prevents the
|
|
controller from going into the operational state at all.
|
|
|
|
This is completely equivalent to what the code originally meant to accomplish:
|
|
as per in net/bluetooth/hidp/core.c::hidp_output_raw_report(), by using
|
|
HID_FEATURE_REPORT here, what will be actually sent is
|
|
(HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE) which is exactly 0x53.
|
|
|
|
Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
|
|
|
|
commit ea42416024fb33c970dbc10a6c69c0831126d75e
|
|
Author: Jiri Kosina <jkosina@suse.cz>
|
|
Date: Wed Feb 3 15:52:31 2010 +0100
|
|
|
|
HID: make Wacom modesetting failures non-fatal
|
|
|
|
With Wacom tablet mode-setting moved from userspace into kernel,
|
|
we don't have to consider failures of device queries through the
|
|
_raw callback as hard failure, as the driver can safely continue
|
|
anyway.
|
|
|
|
This is consistent with the current USB driver in wacom_sys.c
|
|
|
|
Reported-by: Ping Cheng <pinglinux@gmail.com>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
commit a37234f5fcd6ad44ada8c477c2ab531f3ed9fbe5
|
|
Author: Bastien Nocera <hadess@hadess.net>
|
|
Date: Wed Jan 20 12:01:53 2010 +0000
|
|
|
|
HID: Enable Sixaxis controller over Bluetooth
|
|
|
|
Now that hid_output_raw_report works, port the PS3 Sixaxis
|
|
Bluetooth quirk from user-space, into kernel-space.
|
|
|
|
Signed-off-by: Bastien Nocera <hadess@hadess.net>
|
|
Acked-by: Marcel Holtmann <marcel@holtmann.org>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
commit 6bc702ac6551532774171d593a805c3565befb4e
|
|
Author: Bastien Nocera <hadess@hadess.net>
|
|
Date: Wed Jan 20 12:00:53 2010 +0000
|
|
|
|
HID: Implement Wacom quirk in the kernel
|
|
|
|
The hid-wacom driver required user-space to poke at the tablet
|
|
to make it send data about the cursor location.
|
|
|
|
This patch makes it do the same thing but in the kernel.
|
|
|
|
Signed-off-by: Bastien Nocera <hadess@hadess.net>
|
|
Acked-by: Marcel Holtmann <marcel@holtmann.org>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
commit 6fd920bdba1752fdd6411a55b3c17e0fda67b8d2
|
|
Author: Jiri Kosina <jkosina@suse.cz>
|
|
Date: Fri Jan 29 15:03:36 2010 +0100
|
|
|
|
HID: make raw reports possible for both feature and output reports
|
|
|
|
In commit 2da31939a42 ("Bluetooth: Implement raw output support for HIDP
|
|
layer"), support for Bluetooth hid_output_raw_report was added, but it
|
|
pushes the data to the intr socket instead of the ctrl one. This has been
|
|
fixed by 6bf8268f9a91f1 ("Bluetooth: Use the control channel for raw HID reports")
|
|
|
|
Still, it is necessary to distinguish whether the report in question should be
|
|
either FEATURE or OUTPUT. For this, we have to extend the generic HID API,
|
|
so that hid_output_raw_report() callback provides means to specify this
|
|
value so that it can be passed down to lower level hardware drivers (currently
|
|
Bluetooth and USB).
|
|
|
|
Based on original patch by Bastien Nocera <hadess@hadess.net>
|
|
Acked-by: Marcel Holtmann <marcel@holtmann.org>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
|
|
index 8455f3d..112568e 100644
|
|
--- a/drivers/hid/hid-core.c
|
|
+++ b/drivers/hid/hid-core.c
|
|
@@ -1340,6 +1340,7 @@ static const struct hid_device_id hid_blacklist[] = {
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
|
|
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
|
|
@@ -1352,6 +1353,7 @@ static const struct hid_device_id hid_blacklist[] = {
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
|
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
|
|
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
|
|
|
|
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
|
|
index 793691f..4ccd60b 100644
|
|
--- a/drivers/hid/hid-ids.h
|
|
+++ b/drivers/hid/hid-ids.h
|
|
@@ -428,6 +428,7 @@
|
|
|
|
#define USB_VENDOR_ID_WACOM 0x056a
|
|
#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
|
|
+#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0xbd
|
|
|
|
#define USB_VENDOR_ID_WISEGROUP 0x0925
|
|
#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005
|
|
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
|
|
index 4e84502..e71da89 100644
|
|
--- a/drivers/hid/hid-sony.c
|
|
+++ b/drivers/hid/hid-sony.c
|
|
@@ -48,7 +48,7 @@ static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|
* to "operational". Without this, the ps3 controller will not report any
|
|
* events.
|
|
*/
|
|
-static int sony_set_operational(struct hid_device *hdev)
|
|
+static int sony_set_operational_usb(struct hid_device *hdev)
|
|
{
|
|
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
|
struct usb_device *dev = interface_to_usbdev(intf);
|
|
@@ -73,6 +73,12 @@ static int sony_set_operational(struct hid_device *hdev)
|
|
return ret;
|
|
}
|
|
|
|
+static int sony_set_operational_bt(struct hid_device *hdev)
|
|
+{
|
|
+ unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
|
|
+ return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
|
|
+}
|
|
+
|
|
static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|
{
|
|
int ret;
|
|
@@ -101,7 +107,17 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|
goto err_free;
|
|
}
|
|
|
|
- ret = sony_set_operational(hdev);
|
|
+ switch (hdev->bus) {
|
|
+ case BUS_USB:
|
|
+ ret = sony_set_operational_usb(hdev);
|
|
+ break;
|
|
+ case BUS_BLUETOOTH:
|
|
+ ret = sony_set_operational_bt(hdev);
|
|
+ break;
|
|
+ default:
|
|
+ ret = 0;
|
|
+ }
|
|
+
|
|
if (ret < 0)
|
|
goto err_stop;
|
|
|
|
@@ -121,6 +137,7 @@ static void sony_remove(struct hid_device *hdev)
|
|
|
|
static const struct hid_device_id sony_devices[] = {
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
|
|
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
|
|
.driver_data = VAIO_RDESC_CONSTANT },
|
|
{ }
|
|
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
|
|
index 12dcda5..91dbae3 100644
|
|
--- a/drivers/hid/hid-wacom.c
|
|
+++ b/drivers/hid/hid-wacom.c
|
|
@@ -156,7 +156,9 @@ static int wacom_probe(struct hid_device *hdev,
|
|
struct hid_input *hidinput;
|
|
struct input_dev *input;
|
|
struct wacom_data *wdata;
|
|
+ char rep_data[2];
|
|
int ret;
|
|
+ int limit;
|
|
|
|
wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
|
|
if (wdata == NULL) {
|
|
@@ -166,6 +168,7 @@ static int wacom_probe(struct hid_device *hdev,
|
|
|
|
hid_set_drvdata(hdev, wdata);
|
|
|
|
+ /* Parse the HID report now */
|
|
ret = hid_parse(hdev);
|
|
if (ret) {
|
|
dev_err(&hdev->dev, "parse failed\n");
|
|
@@ -178,6 +181,31 @@ static int wacom_probe(struct hid_device *hdev,
|
|
goto err_free;
|
|
}
|
|
|
|
+ /*
|
|
+ * Note that if the raw queries fail, it's not a hard failure and it
|
|
+ * is safe to continue
|
|
+ */
|
|
+
|
|
+ /* Set Wacom mode2 */
|
|
+ rep_data[0] = 0x03; rep_data[1] = 0x00;
|
|
+ limit = 3;
|
|
+ do {
|
|
+ ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
|
|
+ HID_FEATURE_REPORT);
|
|
+ } while (ret < 0 && limit-- > 0);
|
|
+ if (ret < 0)
|
|
+ dev_warn(&hdev->dev, "failed to poke device #1, %d\n", ret);
|
|
+
|
|
+ /* 0x06 - high reporting speed, 0x05 - low speed */
|
|
+ rep_data[0] = 0x06; rep_data[1] = 0x00;
|
|
+ limit = 3;
|
|
+ do {
|
|
+ ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
|
|
+ HID_FEATURE_REPORT);
|
|
+ } while (ret < 0 && limit-- > 0);
|
|
+ if (ret < 0)
|
|
+ dev_warn(&hdev->dev, "failed to poke device #2, %d\n", ret);
|
|
+
|
|
hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
|
|
input = hidinput->input;
|
|
|
|
@@ -228,7 +256,7 @@ static void wacom_remove(struct hid_device *hdev)
|
|
|
|
static const struct hid_device_id wacom_devices[] = {
|
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
|
|
-
|
|
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
|
|
{ }
|
|
};
|
|
MODULE_DEVICE_TABLE(hid, wacom_devices);
|
|
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
|
|
index cdd1369..d044767 100644
|
|
--- a/drivers/hid/hidraw.c
|
|
+++ b/drivers/hid/hidraw.c
|
|
@@ -134,7 +134,7 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
|
|
goto out;
|
|
}
|
|
|
|
- ret = dev->hid_output_raw_report(dev, buf, count);
|
|
+ ret = dev->hid_output_raw_report(dev, buf, count, HID_OUTPUT_REPORT);
|
|
out:
|
|
kfree(buf);
|
|
return ret;
|
|
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
|
|
index 2f84237..83c9f94 100644
|
|
--- a/drivers/hid/usbhid/hid-core.c
|
|
+++ b/drivers/hid/usbhid/hid-core.c
|
|
@@ -798,7 +798,8 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
|
|
return 0;
|
|
}
|
|
|
|
-static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count)
|
|
+static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count,
|
|
+ unsigned char report_type)
|
|
{
|
|
struct usbhid_device *usbhid = hid->driver_data;
|
|
struct usb_device *dev = hid_to_usb_dev(hid);
|
|
@@ -809,7 +810,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
|
|
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
|
HID_REQ_SET_REPORT,
|
|
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
|
- ((HID_OUTPUT_REPORT + 1) << 8) | *buf,
|
|
+ ((report_type + 1) << 8) | *buf,
|
|
interface->desc.bInterfaceNumber, buf + 1, count - 1,
|
|
USB_CTRL_SET_TIMEOUT);
|
|
|
|
diff --git a/include/linux/hid.h b/include/linux/hid.h
|
|
index 8709365..3661a62 100644
|
|
--- a/include/linux/hid.h
|
|
+++ b/include/linux/hid.h
|
|
@@ -501,7 +501,7 @@ struct hid_device { /* device report descriptor */
|
|
void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
|
|
|
|
/* handler for raw output data, used by hidraw */
|
|
- int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
|
|
+ int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char);
|
|
|
|
/* debugging support via debugfs */
|
|
unsigned short debug;
|
|
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
|
|
index fc6ec1e..280529a 100644
|
|
--- a/net/bluetooth/hidp/core.c
|
|
+++ b/net/bluetooth/hidp/core.c
|
|
@@ -313,10 +313,21 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
|
|
return hidp_queue_report(session, buf, rsize);
|
|
}
|
|
|
|
-static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count)
|
|
+static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
|
|
+ unsigned char report_type)
|
|
{
|
|
- if (hidp_send_ctrl_message(hid->driver_data,
|
|
- HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE,
|
|
+ switch (report_type) {
|
|
+ case HID_FEATURE_REPORT:
|
|
+ report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
|
|
+ break;
|
|
+ case HID_OUTPUT_REPORT:
|
|
+ report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if (hidp_send_ctrl_message(hid->driver_data, report_type,
|
|
data, count))
|
|
return -ENOMEM;
|
|
return count;
|