blob: f933221ba525bd3c918c2c1ac0b1c4a6e8e58a87 [file] [log] [blame]
Stefan Achatz5772f632011-01-30 13:38:23 +01001/*
2 * Roccat common functions for device specific drivers
3 *
4 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
Stefan Achatz1edd5b42011-06-01 15:54:17 +020014#include <linux/hid.h>
Stefan Achatz5772f632011-01-30 13:38:23 +010015#include <linux/slab.h>
16#include "hid-roccat-common.h"
17
Stefan Achatz1edd5b42011-06-01 15:54:17 +020018static inline uint16_t roccat_common_feature_report(uint8_t report_id)
19{
20 return 0x300 | report_id;
21}
22
23int roccat_common_receive(struct usb_device *usb_dev, uint report_id,
Stefan Achatz5772f632011-01-30 13:38:23 +010024 void *data, uint size)
25{
26 char *buf;
27 int len;
28
29 buf = kmalloc(size, GFP_KERNEL);
30 if (buf == NULL)
31 return -ENOMEM;
32
33 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
Stefan Achatz1edd5b42011-06-01 15:54:17 +020034 HID_REQ_GET_REPORT,
Stefan Achatz5772f632011-01-30 13:38:23 +010035 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
Stefan Achatz1edd5b42011-06-01 15:54:17 +020036 roccat_common_feature_report(report_id),
37 0, buf, size, USB_CTRL_SET_TIMEOUT);
Stefan Achatz5772f632011-01-30 13:38:23 +010038
39 memcpy(data, buf, size);
40 kfree(buf);
41 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
42}
43EXPORT_SYMBOL_GPL(roccat_common_receive);
44
Stefan Achatz1edd5b42011-06-01 15:54:17 +020045int roccat_common_send(struct usb_device *usb_dev, uint report_id,
Stefan Achatz5772f632011-01-30 13:38:23 +010046 void const *data, uint size)
47{
48 char *buf;
49 int len;
50
Thomas Meyer4c33a882011-11-17 23:43:40 +010051 buf = kmemdup(data, size, GFP_KERNEL);
Stefan Achatz5772f632011-01-30 13:38:23 +010052 if (buf == NULL)
53 return -ENOMEM;
54
Stefan Achatz5772f632011-01-30 13:38:23 +010055 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
Stefan Achatz1edd5b42011-06-01 15:54:17 +020056 HID_REQ_SET_REPORT,
Stefan Achatz5772f632011-01-30 13:38:23 +010057 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
Stefan Achatz1edd5b42011-06-01 15:54:17 +020058 roccat_common_feature_report(report_id),
59 0, buf, size, USB_CTRL_SET_TIMEOUT);
Stefan Achatz5772f632011-01-30 13:38:23 +010060
61 kfree(buf);
62 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
63}
64EXPORT_SYMBOL_GPL(roccat_common_send);
65
66MODULE_AUTHOR("Stefan Achatz");
67MODULE_DESCRIPTION("USB Roccat common driver");
68MODULE_LICENSE("GPL v2");