Skip to content

Commit

Permalink
Merge branch 'for-3.15/hid-core-ll-transport-cleanup' into for-3.15/sony
Browse files Browse the repository at this point in the history
  • Loading branch information
Jiri Kosina committed Apr 1, 2014
2 parents 2078b9b + c3d77fa commit b95dd3c
Show file tree
Hide file tree
Showing 21 changed files with 1,288 additions and 200 deletions.
3 changes: 2 additions & 1 deletion Documentation/hid/hid-transport.txt
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,8 @@ The available HID callbacks are:
int reqtype)
Same as ->request() but provides the report as raw buffer. This request shall
be synchronous. A transport driver must not use ->wait() to complete such
requests.
requests. This request is mandatory and hid core will reject the device if
it is missing.

- int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len)
Send raw output report via intr channel. Used by some HID device drivers
Expand Down
9 changes: 9 additions & 0 deletions drivers/hid/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ config HID_PRODIKEYS
multimedia keyboard, but will lack support for the musical keyboard
and some additional multimedia keys.

config HID_CP2112
tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support"
depends on USB_HID && I2C && GPIOLIB
---help---
Support for Silicon Labs CP2112 HID USB to SMBus Master Bridge.
This is a HID device driver which registers as an i2c adapter
and gpiochip to expose these functions of the CP2112. The
customizable USB descriptor fields are exposed as sysfs attributes.

config HID_CYPRESS
tristate "Cypress mouse and barcode readers" if EXPERT
depends on HID
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ obj-$(CONFIG_HID_AUREAL) += hid-aureal.o
obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
obj-$(CONFIG_HID_CP2112) += hid-cp2112.o
obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o
obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o
Expand Down
51 changes: 50 additions & 1 deletion drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,11 @@ void hid_output_report(struct hid_report *report, __u8 *data)
}
EXPORT_SYMBOL_GPL(hid_output_report);

static int hid_report_len(struct hid_report *report)
{
return ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7;
}

/*
* Allocator for buffer that is going to be passed to hid_output_report()
*/
Expand All @@ -1258,7 +1263,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
* of implement() working on 8 byte chunks
*/

int len = ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7;
int len = hid_report_len(report);

return kmalloc(len, flags);
}
Expand Down Expand Up @@ -1314,6 +1319,41 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
return report;
}

/*
* Implement a generic .request() callback, using .raw_request()
* DO NOT USE in hid drivers directly, but through hid_hw_request instead.
*/
void __hid_request(struct hid_device *hid, struct hid_report *report,
int reqtype)
{
char *buf;
int ret;
int len;

buf = hid_alloc_report_buf(report, GFP_KERNEL);
if (!buf)
return;

len = hid_report_len(report);

if (reqtype == HID_REQ_SET_REPORT)
hid_output_report(report, buf);

ret = hid->ll_driver->raw_request(hid, report->id, buf, len,
report->type, reqtype);
if (ret < 0) {
dbg_hid("unable to complete request: %d\n", ret);
goto out;
}

if (reqtype == HID_REQ_GET_REPORT)
hid_input_report(hid, report->type, buf, ret, 0);

out:
kfree(buf);
}
EXPORT_SYMBOL_GPL(__hid_request);

int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
int interrupt)
{
Expand Down Expand Up @@ -1692,6 +1732,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
Expand Down Expand Up @@ -2428,6 +2469,14 @@ int hid_add_device(struct hid_device *hdev)
if (hid_ignore(hdev))
return -ENODEV;

/*
* Check for the mandatory transport channel.
*/
if (!hdev->ll_driver->raw_request) {
hid_err(hdev, "transport driver missing .raw_request()\n");
return -EINVAL;
}

/*
* Read the device report descriptor once and use as template
* for the driver-specific modifications.
Expand Down
Loading

0 comments on commit b95dd3c

Please sign in to comment.