mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-09 01:28:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
180
drivers/hid/hid-roccat-common.c
Normal file
180
drivers/hid/hid-roccat-common.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Roccat common functions for device specific drivers
|
||||
*
|
||||
* Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/hid.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include "hid-roccat-common.h"
|
||||
|
||||
static inline uint16_t roccat_common2_feature_report(uint8_t report_id)
|
||||
{
|
||||
return 0x300 | report_id;
|
||||
}
|
||||
|
||||
int roccat_common2_receive(struct usb_device *usb_dev, uint report_id,
|
||||
void *data, uint size)
|
||||
{
|
||||
char *buf;
|
||||
int len;
|
||||
|
||||
buf = kmalloc(size, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
|
||||
HID_REQ_GET_REPORT,
|
||||
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
|
||||
roccat_common2_feature_report(report_id),
|
||||
0, buf, size, USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
memcpy(data, buf, size);
|
||||
kfree(buf);
|
||||
return ((len < 0) ? len : ((len != size) ? -EIO : 0));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_common2_receive);
|
||||
|
||||
int roccat_common2_send(struct usb_device *usb_dev, uint report_id,
|
||||
void const *data, uint size)
|
||||
{
|
||||
char *buf;
|
||||
int len;
|
||||
|
||||
buf = kmemdup(data, size, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
|
||||
HID_REQ_SET_REPORT,
|
||||
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
|
||||
roccat_common2_feature_report(report_id),
|
||||
0, buf, size, USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
kfree(buf);
|
||||
return ((len < 0) ? len : ((len != size) ? -EIO : 0));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_common2_send);
|
||||
|
||||
enum roccat_common2_control_states {
|
||||
ROCCAT_COMMON_CONTROL_STATUS_CRITICAL = 0,
|
||||
ROCCAT_COMMON_CONTROL_STATUS_OK = 1,
|
||||
ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2,
|
||||
ROCCAT_COMMON_CONTROL_STATUS_BUSY = 3,
|
||||
ROCCAT_COMMON_CONTROL_STATUS_CRITICAL_NEW = 4,
|
||||
};
|
||||
|
||||
static int roccat_common2_receive_control_status(struct usb_device *usb_dev)
|
||||
{
|
||||
int retval;
|
||||
struct roccat_common2_control control;
|
||||
|
||||
do {
|
||||
msleep(50);
|
||||
retval = roccat_common2_receive(usb_dev,
|
||||
ROCCAT_COMMON_COMMAND_CONTROL,
|
||||
&control, sizeof(struct roccat_common2_control));
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
switch (control.value) {
|
||||
case ROCCAT_COMMON_CONTROL_STATUS_OK:
|
||||
return 0;
|
||||
case ROCCAT_COMMON_CONTROL_STATUS_BUSY:
|
||||
msleep(500);
|
||||
continue;
|
||||
case ROCCAT_COMMON_CONTROL_STATUS_INVALID:
|
||||
case ROCCAT_COMMON_CONTROL_STATUS_CRITICAL:
|
||||
case ROCCAT_COMMON_CONTROL_STATUS_CRITICAL_NEW:
|
||||
return -EINVAL;
|
||||
default:
|
||||
dev_err(&usb_dev->dev,
|
||||
"roccat_common2_receive_control_status: "
|
||||
"unknown response value 0x%x\n",
|
||||
control.value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
} while (1);
|
||||
}
|
||||
|
||||
int roccat_common2_send_with_status(struct usb_device *usb_dev,
|
||||
uint command, void const *buf, uint size)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = roccat_common2_send(usb_dev, command, buf, size);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
msleep(100);
|
||||
|
||||
return roccat_common2_receive_control_status(usb_dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_common2_send_with_status);
|
||||
|
||||
int roccat_common2_device_init_struct(struct usb_device *usb_dev,
|
||||
struct roccat_common2_device *dev)
|
||||
{
|
||||
mutex_init(&dev->lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_common2_device_init_struct);
|
||||
|
||||
ssize_t roccat_common2_sysfs_read(struct file *fp, struct kobject *kobj,
|
||||
char *buf, loff_t off, size_t count,
|
||||
size_t real_size, uint command)
|
||||
{
|
||||
struct device *dev =
|
||||
container_of(kobj, struct device, kobj)->parent->parent;
|
||||
struct roccat_common2_device *roccat_dev = hid_get_drvdata(dev_get_drvdata(dev));
|
||||
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
|
||||
int retval;
|
||||
|
||||
if (off >= real_size)
|
||||
return 0;
|
||||
|
||||
if (off != 0 || count != real_size)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&roccat_dev->lock);
|
||||
retval = roccat_common2_receive(usb_dev, command, buf, real_size);
|
||||
mutex_unlock(&roccat_dev->lock);
|
||||
|
||||
return retval ? retval : real_size;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_common2_sysfs_read);
|
||||
|
||||
ssize_t roccat_common2_sysfs_write(struct file *fp, struct kobject *kobj,
|
||||
void const *buf, loff_t off, size_t count,
|
||||
size_t real_size, uint command)
|
||||
{
|
||||
struct device *dev =
|
||||
container_of(kobj, struct device, kobj)->parent->parent;
|
||||
struct roccat_common2_device *roccat_dev = hid_get_drvdata(dev_get_drvdata(dev));
|
||||
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
|
||||
int retval;
|
||||
|
||||
if (off != 0 || count != real_size)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&roccat_dev->lock);
|
||||
retval = roccat_common2_send_with_status(usb_dev, command, buf, real_size);
|
||||
mutex_unlock(&roccat_dev->lock);
|
||||
|
||||
return retval ? retval : real_size;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_common2_sysfs_write);
|
||||
|
||||
MODULE_AUTHOR("Stefan Achatz");
|
||||
MODULE_DESCRIPTION("USB Roccat common driver");
|
||||
MODULE_LICENSE("GPL v2");
|
Loading…
Add table
Add a link
Reference in a new issue