1 /* 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 14 #include <linux/hid.h> 15 #include <linux/slab.h> 16 #include <linux/module.h> 17 #include "hid-roccat-common.h" 18 19 static inline uint16_t roccat_common_feature_report(uint8_t report_id) 20 { 21 return 0x300 | report_id; 22 } 23 24 int roccat_common_receive(struct usb_device *usb_dev, uint report_id, 25 void *data, uint size) 26 { 27 char *buf; 28 int len; 29 30 buf = kmalloc(size, GFP_KERNEL); 31 if (buf == NULL) 32 return -ENOMEM; 33 34 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 35 HID_REQ_GET_REPORT, 36 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 37 roccat_common_feature_report(report_id), 38 0, buf, size, USB_CTRL_SET_TIMEOUT); 39 40 memcpy(data, buf, size); 41 kfree(buf); 42 return ((len < 0) ? len : ((len != size) ? -EIO : 0)); 43 } 44 EXPORT_SYMBOL_GPL(roccat_common_receive); 45 46 int roccat_common_send(struct usb_device *usb_dev, uint report_id, 47 void const *data, uint size) 48 { 49 char *buf; 50 int len; 51 52 buf = kmemdup(data, size, GFP_KERNEL); 53 if (buf == NULL) 54 return -ENOMEM; 55 56 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 57 HID_REQ_SET_REPORT, 58 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 59 roccat_common_feature_report(report_id), 60 0, buf, size, USB_CTRL_SET_TIMEOUT); 61 62 kfree(buf); 63 return ((len < 0) ? len : ((len != size) ? -EIO : 0)); 64 } 65 EXPORT_SYMBOL_GPL(roccat_common_send); 66 67 MODULE_AUTHOR("Stefan Achatz"); 68 MODULE_DESCRIPTION("USB Roccat common driver"); 69 MODULE_LICENSE("GPL v2"); 70