HID: roccat: move functionality to roccat-common
Reduced code duplication by moving functions from individual drivers to roccat-common module. Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
6a2a6390cf
commit
4728f2dc9f
|
@ -64,6 +64,64 @@ int roccat_common_send(struct usb_device *usb_dev, uint report_id,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_common_send);
|
||||
|
||||
enum roccat_common_control_states {
|
||||
ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD = 0,
|
||||
ROCCAT_COMMON_CONTROL_STATUS_OK = 1,
|
||||
ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2,
|
||||
ROCCAT_COMMON_CONTROL_STATUS_WAIT = 3,
|
||||
};
|
||||
|
||||
static int roccat_common_receive_control_status(struct usb_device *usb_dev)
|
||||
{
|
||||
int retval;
|
||||
struct roccat_common_control control;
|
||||
|
||||
do {
|
||||
msleep(50);
|
||||
retval = roccat_common_receive(usb_dev,
|
||||
ROCCAT_COMMON_COMMAND_CONTROL,
|
||||
&control, sizeof(struct roccat_common_control));
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
switch (control.value) {
|
||||
case ROCCAT_COMMON_CONTROL_STATUS_OK:
|
||||
return 0;
|
||||
case ROCCAT_COMMON_CONTROL_STATUS_WAIT:
|
||||
msleep(500);
|
||||
continue;
|
||||
case ROCCAT_COMMON_CONTROL_STATUS_INVALID:
|
||||
|
||||
case ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD:
|
||||
/* seems to be critical - replug necessary */
|
||||
return -EINVAL;
|
||||
default:
|
||||
dev_err(&usb_dev->dev,
|
||||
"roccat_common_receive_control_status: "
|
||||
"unknown response value 0x%x\n",
|
||||
control.value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
} while (1);
|
||||
}
|
||||
|
||||
int roccat_common_send_with_status(struct usb_device *usb_dev,
|
||||
uint command, void const *buf, uint size)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = roccat_common_send(usb_dev, command, buf, size);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
msleep(100);
|
||||
|
||||
return roccat_common_receive_control_status(usb_dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(roccat_common_send_with_status);
|
||||
|
||||
MODULE_AUTHOR("Stefan Achatz");
|
||||
MODULE_DESCRIPTION("USB Roccat common driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -15,9 +15,21 @@
|
|||
#include <linux/usb.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
enum roccat_common_commands {
|
||||
ROCCAT_COMMON_COMMAND_CONTROL = 0x4,
|
||||
};
|
||||
|
||||
struct roccat_common_control {
|
||||
uint8_t command;
|
||||
uint8_t value;
|
||||
uint8_t request; /* always 0 on requesting write check */
|
||||
} __packed;
|
||||
|
||||
int roccat_common_receive(struct usb_device *usb_dev, uint report_id,
|
||||
void *data, uint size);
|
||||
int roccat_common_send(struct usb_device *usb_dev, uint report_id,
|
||||
void const *data, uint size);
|
||||
int roccat_common_send_with_status(struct usb_device *usb_dev,
|
||||
uint command, void const *buf, uint size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,50 +39,6 @@ static int isku_receive(struct usb_device *usb_dev, uint command,
|
|||
return roccat_common_receive(usb_dev, command, buf, size);
|
||||
}
|
||||
|
||||
static int isku_receive_control_status(struct usb_device *usb_dev)
|
||||
{
|
||||
int retval;
|
||||
struct isku_control control;
|
||||
|
||||
do {
|
||||
msleep(50);
|
||||
retval = isku_receive(usb_dev, ISKU_COMMAND_CONTROL,
|
||||
&control, sizeof(struct isku_control));
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
switch (control.value) {
|
||||
case ISKU_CONTROL_VALUE_STATUS_OK:
|
||||
return 0;
|
||||
case ISKU_CONTROL_VALUE_STATUS_WAIT:
|
||||
continue;
|
||||
case ISKU_CONTROL_VALUE_STATUS_INVALID:
|
||||
/* seems to be critical - replug necessary */
|
||||
case ISKU_CONTROL_VALUE_STATUS_OVERLOAD:
|
||||
return -EINVAL;
|
||||
default:
|
||||
hid_err(usb_dev, "isku_receive_control_status: "
|
||||
"unknown response value 0x%x\n",
|
||||
control.value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static int isku_send(struct usb_device *usb_dev, uint command,
|
||||
void const *buf, uint size)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = roccat_common_send(usb_dev, command, buf, size);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return isku_receive_control_status(usb_dev);
|
||||
}
|
||||
|
||||
static int isku_get_actual_profile(struct usb_device *usb_dev)
|
||||
{
|
||||
struct isku_actual_profile buf;
|
||||
|
@ -100,7 +56,8 @@ static int isku_set_actual_profile(struct usb_device *usb_dev, int new_profile)
|
|||
buf.command = ISKU_COMMAND_ACTUAL_PROFILE;
|
||||
buf.size = sizeof(struct isku_actual_profile);
|
||||
buf.actual_profile = new_profile;
|
||||
return isku_send(usb_dev, ISKU_COMMAND_ACTUAL_PROFILE, &buf,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
ISKU_COMMAND_ACTUAL_PROFILE, &buf,
|
||||
sizeof(struct isku_actual_profile));
|
||||
}
|
||||
|
||||
|
@ -197,7 +154,8 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj,
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&isku->isku_lock);
|
||||
retval = isku_send(usb_dev, command, (void *)buf, real_size);
|
||||
retval = roccat_common_send_with_status(usb_dev, command,
|
||||
(void *)buf, real_size);
|
||||
mutex_unlock(&isku->isku_lock);
|
||||
|
||||
return retval ? retval : real_size;
|
||||
|
|
|
@ -25,13 +25,6 @@ struct isku_control {
|
|||
uint8_t request;
|
||||
} __packed;
|
||||
|
||||
enum isku_control_values {
|
||||
ISKU_CONTROL_VALUE_STATUS_OVERLOAD = 0,
|
||||
ISKU_CONTROL_VALUE_STATUS_OK = 1,
|
||||
ISKU_CONTROL_VALUE_STATUS_INVALID = 2,
|
||||
ISKU_CONTROL_VALUE_STATUS_WAIT = 3,
|
||||
};
|
||||
|
||||
struct isku_actual_profile {
|
||||
uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */
|
||||
uint8_t size; /* always 3 */
|
||||
|
|
|
@ -39,82 +39,20 @@ static void koneplus_profile_activated(struct koneplus_device *koneplus,
|
|||
static int koneplus_send_control(struct usb_device *usb_dev, uint value,
|
||||
enum koneplus_control_requests request)
|
||||
{
|
||||
struct koneplus_control control;
|
||||
struct roccat_common_control control;
|
||||
|
||||
if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
|
||||
request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
|
||||
value > 4)
|
||||
return -EINVAL;
|
||||
|
||||
control.command = KONEPLUS_COMMAND_CONTROL;
|
||||
control.command = ROCCAT_COMMON_COMMAND_CONTROL;
|
||||
control.value = value;
|
||||
control.request = request;
|
||||
|
||||
return roccat_common_send(usb_dev, KONEPLUS_COMMAND_CONTROL,
|
||||
&control, sizeof(struct koneplus_control));
|
||||
}
|
||||
|
||||
static int koneplus_receive_control_status(struct usb_device *usb_dev)
|
||||
{
|
||||
int retval;
|
||||
struct koneplus_control control;
|
||||
|
||||
do {
|
||||
retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_CONTROL,
|
||||
&control, sizeof(struct koneplus_control));
|
||||
|
||||
/* check if we get a completely wrong answer */
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OK)
|
||||
return 0;
|
||||
|
||||
/* indicates that hardware needs some more time to complete action */
|
||||
if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) {
|
||||
msleep(500); /* windows driver uses 1000 */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* seems to be critical - replug necessary */
|
||||
if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
|
||||
return -EINVAL;
|
||||
|
||||
hid_err(usb_dev, "koneplus_receive_control_status: "
|
||||
"unknown response value 0x%x\n", control.value);
|
||||
return -EINVAL;
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static int koneplus_send(struct usb_device *usb_dev, uint command,
|
||||
void const *buf, uint size)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = roccat_common_send(usb_dev, command, buf, size);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return koneplus_receive_control_status(usb_dev);
|
||||
}
|
||||
|
||||
static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
|
||||
enum koneplus_control_requests request)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = koneplus_send_control(usb_dev, number, request);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/* allow time to settle things - windows driver uses 500 */
|
||||
msleep(100);
|
||||
|
||||
retval = koneplus_receive_control_status(usb_dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return 0;
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
ROCCAT_COMMON_COMMAND_CONTROL,
|
||||
&control, sizeof(struct roccat_common_control));
|
||||
}
|
||||
|
||||
static int koneplus_get_info(struct usb_device *usb_dev,
|
||||
|
@ -129,7 +67,7 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev,
|
|||
{
|
||||
int retval;
|
||||
|
||||
retval = koneplus_select_profile(usb_dev, number,
|
||||
retval = koneplus_send_control(usb_dev, number,
|
||||
KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
@ -141,7 +79,8 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev,
|
|||
static int koneplus_set_profile_settings(struct usb_device *usb_dev,
|
||||
struct koneplus_profile_settings const *settings)
|
||||
{
|
||||
return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
KONEPLUS_COMMAND_PROFILE_SETTINGS,
|
||||
settings, sizeof(struct koneplus_profile_settings));
|
||||
}
|
||||
|
||||
|
@ -150,7 +89,7 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
|
|||
{
|
||||
int retval;
|
||||
|
||||
retval = koneplus_select_profile(usb_dev, number,
|
||||
retval = koneplus_send_control(usb_dev, number,
|
||||
KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
@ -162,7 +101,8 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
|
|||
static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
|
||||
struct koneplus_profile_buttons const *buttons)
|
||||
{
|
||||
return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
KONEPLUS_COMMAND_PROFILE_BUTTONS,
|
||||
buttons, sizeof(struct koneplus_profile_buttons));
|
||||
}
|
||||
|
||||
|
@ -187,7 +127,8 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev,
|
|||
buf.size = sizeof(struct koneplus_actual_profile);
|
||||
buf.actual_profile = new_profile;
|
||||
|
||||
return koneplus_send(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
KONEPLUS_COMMAND_ACTUAL_PROFILE,
|
||||
&buf, sizeof(struct koneplus_actual_profile));
|
||||
}
|
||||
|
||||
|
@ -231,7 +172,8 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&koneplus->koneplus_lock);
|
||||
retval = koneplus_send(usb_dev, command, buf, real_size);
|
||||
retval = roccat_common_send_with_status(usb_dev, command,
|
||||
buf, real_size);
|
||||
mutex_unlock(&koneplus->koneplus_lock);
|
||||
|
||||
if (retval)
|
||||
|
|
|
@ -20,32 +20,11 @@ struct koneplus_talk {
|
|||
uint8_t data[14];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* case 1: writes request 80 and reads value 1
|
||||
*
|
||||
*/
|
||||
struct koneplus_control {
|
||||
uint8_t command; /* KONEPLUS_COMMAND_CONTROL */
|
||||
/*
|
||||
* value is profile number in range 0-4 for requesting settings and buttons
|
||||
* 1 if status ok for requesting status
|
||||
*/
|
||||
uint8_t value;
|
||||
uint8_t request;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
enum koneplus_control_requests {
|
||||
KONEPLUS_CONTROL_REQUEST_STATUS = 0x00,
|
||||
KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80,
|
||||
KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90,
|
||||
};
|
||||
|
||||
enum koneplus_control_values {
|
||||
KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0,
|
||||
KONEPLUS_CONTROL_REQUEST_STATUS_OK = 1,
|
||||
KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3,
|
||||
};
|
||||
|
||||
struct koneplus_actual_profile {
|
||||
uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */
|
||||
uint8_t size; /* always 3 */
|
||||
|
@ -137,7 +116,6 @@ struct koneplus_tcu_image {
|
|||
} __attribute__ ((__packed__));
|
||||
|
||||
enum koneplus_commands {
|
||||
KONEPLUS_COMMAND_CONTROL = 0x4,
|
||||
KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
|
||||
KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
|
||||
KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
|
||||
|
|
|
@ -47,69 +47,23 @@ static int kovaplus_send_control(struct usb_device *usb_dev, uint value,
|
|||
enum kovaplus_control_requests request)
|
||||
{
|
||||
int retval;
|
||||
struct kovaplus_control control;
|
||||
struct roccat_common_control control;
|
||||
|
||||
if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
|
||||
request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
|
||||
value > 4)
|
||||
return -EINVAL;
|
||||
|
||||
control.command = KOVAPLUS_COMMAND_CONTROL;
|
||||
control.command = ROCCAT_COMMON_COMMAND_CONTROL;
|
||||
control.value = value;
|
||||
control.request = request;
|
||||
|
||||
retval = roccat_common_send(usb_dev, KOVAPLUS_COMMAND_CONTROL,
|
||||
&control, sizeof(struct kovaplus_control));
|
||||
retval = roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL,
|
||||
&control, sizeof(struct roccat_common_control));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int kovaplus_receive_control_status(struct usb_device *usb_dev)
|
||||
{
|
||||
int retval;
|
||||
struct kovaplus_control control;
|
||||
|
||||
do {
|
||||
retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_CONTROL,
|
||||
&control, sizeof(struct kovaplus_control));
|
||||
|
||||
/* check if we get a completely wrong answer */
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OK)
|
||||
return 0;
|
||||
|
||||
/* indicates that hardware needs some more time to complete action */
|
||||
if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT) {
|
||||
msleep(500); /* windows driver uses 1000 */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* seems to be critical - replug necessary */
|
||||
if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
|
||||
return -EINVAL;
|
||||
|
||||
hid_err(usb_dev, "roccat_common_receive_control_status: "
|
||||
"unknown response value 0x%x\n", control.value);
|
||||
return -EINVAL;
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static int kovaplus_send(struct usb_device *usb_dev, uint command,
|
||||
void const *buf, uint size)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = roccat_common_send(usb_dev, command, buf, size);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
msleep(100);
|
||||
|
||||
return kovaplus_receive_control_status(usb_dev);
|
||||
}
|
||||
|
||||
static int kovaplus_select_profile(struct usb_device *usb_dev, uint number,
|
||||
enum kovaplus_control_requests request)
|
||||
{
|
||||
|
@ -140,7 +94,8 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev,
|
|||
static int kovaplus_set_profile_settings(struct usb_device *usb_dev,
|
||||
struct kovaplus_profile_settings const *settings)
|
||||
{
|
||||
return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
KOVAPLUS_COMMAND_PROFILE_SETTINGS,
|
||||
settings, sizeof(struct kovaplus_profile_settings));
|
||||
}
|
||||
|
||||
|
@ -161,7 +116,8 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev,
|
|||
static int kovaplus_set_profile_buttons(struct usb_device *usb_dev,
|
||||
struct kovaplus_profile_buttons const *buttons)
|
||||
{
|
||||
return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
KOVAPLUS_COMMAND_PROFILE_BUTTONS,
|
||||
buttons, sizeof(struct kovaplus_profile_buttons));
|
||||
}
|
||||
|
||||
|
@ -186,7 +142,8 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev,
|
|||
buf.size = sizeof(struct kovaplus_actual_profile);
|
||||
buf.actual_profile = new_profile;
|
||||
|
||||
return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
KOVAPLUS_COMMAND_ACTUAL_PROFILE,
|
||||
&buf, sizeof(struct kovaplus_actual_profile));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,27 +14,13 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct kovaplus_control {
|
||||
uint8_t command; /* KOVAPLUS_COMMAND_CONTROL */
|
||||
uint8_t value;
|
||||
uint8_t request;
|
||||
} __packed;
|
||||
|
||||
enum kovaplus_control_requests {
|
||||
/* read after write; value = 1 */
|
||||
KOVAPLUS_CONTROL_REQUEST_STATUS = 0x0,
|
||||
/* write; value = profile number range 0-4 */
|
||||
KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
|
||||
/* write; value = profile number range 0-4 */
|
||||
KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20,
|
||||
};
|
||||
|
||||
enum kovaplus_control_values {
|
||||
KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0, /* supposed */
|
||||
KOVAPLUS_CONTROL_REQUEST_STATUS_OK = 1,
|
||||
KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, /* supposed */
|
||||
};
|
||||
|
||||
struct kovaplus_actual_profile {
|
||||
uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */
|
||||
uint8_t size; /* always 3 */
|
||||
|
@ -75,7 +61,6 @@ struct kovaplus_a {
|
|||
} __packed;
|
||||
|
||||
enum kovaplus_commands {
|
||||
KOVAPLUS_COMMAND_CONTROL = 0x4,
|
||||
KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
|
||||
KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
|
||||
KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
|
||||
|
|
|
@ -42,43 +42,19 @@ static void profile_activated(struct pyra_device *pyra,
|
|||
static int pyra_send_control(struct usb_device *usb_dev, int value,
|
||||
enum pyra_control_requests request)
|
||||
{
|
||||
struct pyra_control control;
|
||||
struct roccat_common_control control;
|
||||
|
||||
if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
|
||||
request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
|
||||
(value < 0 || value > 4))
|
||||
return -EINVAL;
|
||||
|
||||
control.command = PYRA_COMMAND_CONTROL;
|
||||
control.command = ROCCAT_COMMON_COMMAND_CONTROL;
|
||||
control.value = value;
|
||||
control.request = request;
|
||||
|
||||
return roccat_common_send(usb_dev, PYRA_COMMAND_CONTROL,
|
||||
&control, sizeof(struct pyra_control));
|
||||
}
|
||||
|
||||
static int pyra_receive_control_status(struct usb_device *usb_dev)
|
||||
{
|
||||
int retval;
|
||||
struct pyra_control control;
|
||||
|
||||
do {
|
||||
msleep(10);
|
||||
retval = roccat_common_receive(usb_dev, PYRA_COMMAND_CONTROL,
|
||||
&control, sizeof(struct pyra_control));
|
||||
|
||||
/* requested too early, try again */
|
||||
} while (retval == -EPROTO);
|
||||
|
||||
if (!retval && control.command == PYRA_COMMAND_CONTROL &&
|
||||
control.request == PYRA_CONTROL_REQUEST_STATUS &&
|
||||
control.value == 1)
|
||||
return 0;
|
||||
else {
|
||||
hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n",
|
||||
control.request, control.value);
|
||||
return retval ? retval : -EINVAL;
|
||||
}
|
||||
return roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL,
|
||||
&control, sizeof(struct roccat_common_control));
|
||||
}
|
||||
|
||||
static int pyra_get_profile_settings(struct usb_device *usb_dev,
|
||||
|
@ -118,34 +94,27 @@ static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
|
|||
buf, sizeof(struct pyra_info));
|
||||
}
|
||||
|
||||
static int pyra_send(struct usb_device *usb_dev, uint command,
|
||||
void const *buf, uint size)
|
||||
{
|
||||
int retval;
|
||||
retval = roccat_common_send(usb_dev, command, buf, size);
|
||||
if (retval)
|
||||
return retval;
|
||||
return pyra_receive_control_status(usb_dev);
|
||||
}
|
||||
|
||||
static int pyra_set_profile_settings(struct usb_device *usb_dev,
|
||||
struct pyra_profile_settings const *settings)
|
||||
{
|
||||
return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, settings,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
PYRA_COMMAND_PROFILE_SETTINGS, settings,
|
||||
sizeof(struct pyra_profile_settings));
|
||||
}
|
||||
|
||||
static int pyra_set_profile_buttons(struct usb_device *usb_dev,
|
||||
struct pyra_profile_buttons const *buttons)
|
||||
{
|
||||
return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, buttons,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
PYRA_COMMAND_PROFILE_BUTTONS, buttons,
|
||||
sizeof(struct pyra_profile_buttons));
|
||||
}
|
||||
|
||||
static int pyra_set_settings(struct usb_device *usb_dev,
|
||||
struct pyra_settings const *settings)
|
||||
{
|
||||
return pyra_send(usb_dev, PYRA_COMMAND_SETTINGS, settings,
|
||||
return roccat_common_send_with_status(usb_dev,
|
||||
PYRA_COMMAND_SETTINGS, settings,
|
||||
sizeof(struct pyra_settings));
|
||||
}
|
||||
|
||||
|
|
|
@ -20,18 +20,7 @@ struct pyra_b {
|
|||
uint8_t unknown; /* 1 */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct pyra_control {
|
||||
uint8_t command; /* PYRA_COMMAND_CONTROL */
|
||||
/*
|
||||
* value is profile number for request_settings and request_buttons
|
||||
* 1 if status ok for request_status
|
||||
*/
|
||||
uint8_t value; /* Range 0-4 */
|
||||
uint8_t request;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
enum pyra_control_requests {
|
||||
PYRA_CONTROL_REQUEST_STATUS = 0x00,
|
||||
PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
|
||||
PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20
|
||||
};
|
||||
|
@ -75,7 +64,6 @@ struct pyra_info {
|
|||
} __attribute__ ((__packed__));
|
||||
|
||||
enum pyra_commands {
|
||||
PYRA_COMMAND_CONTROL = 0x4,
|
||||
PYRA_COMMAND_SETTINGS = 0x5,
|
||||
PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
|
||||
PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
|
||||
|
|
|
@ -27,50 +27,6 @@
|
|||
|
||||
static struct class *savu_class;
|
||||
|
||||
static int savu_receive_control_status(struct usb_device *usb_dev)
|
||||
{
|
||||
int retval;
|
||||
struct savu_control control;
|
||||
|
||||
do {
|
||||
msleep(50);
|
||||
retval = roccat_common_receive(usb_dev, SAVU_COMMAND_CONTROL,
|
||||
&control, sizeof(struct savu_control));
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
switch (control.value) {
|
||||
case SAVU_CONTROL_REQUEST_WRITE_CHECK_OK:
|
||||
return 0;
|
||||
case SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT:
|
||||
continue;
|
||||
case SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID:
|
||||
/* seems to be critical - replug necessary */
|
||||
case SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD:
|
||||
return -EINVAL;
|
||||
default:
|
||||
hid_err(usb_dev, "savu_receive_control_status: "
|
||||
"unknown response value 0x%x\n",
|
||||
control.value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static int savu_send(struct usb_device *usb_dev, uint command,
|
||||
void const *buf, uint size)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = roccat_common_send(usb_dev, command, buf, size);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return savu_receive_control_status(usb_dev);
|
||||
}
|
||||
|
||||
static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj,
|
||||
char *buf, loff_t off, size_t count,
|
||||
size_t real_size, uint command)
|
||||
|
@ -108,7 +64,8 @@ static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj,
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&savu->savu_lock);
|
||||
retval = savu_send(usb_dev, command, (void *)buf, real_size);
|
||||
retval = roccat_common_send_with_status(usb_dev, command,
|
||||
(void *)buf, real_size);
|
||||
mutex_unlock(&savu->savu_lock);
|
||||
|
||||
return retval ? retval : real_size;
|
||||
|
|
|
@ -23,29 +23,11 @@ enum {
|
|||
SAVU_SIZE_INFO = 0x08,
|
||||
};
|
||||
|
||||
struct savu_control {
|
||||
uint8_t command; /* SAVU_COMMAND_CONTROL */
|
||||
/*
|
||||
* value is profile number in range 0-4 for requesting settings and buttons
|
||||
* 1 if status ok for requesting status
|
||||
*/
|
||||
uint8_t value;
|
||||
uint8_t request;
|
||||
} __packed;
|
||||
|
||||
enum savu_control_requests {
|
||||
SAVU_CONTROL_REQUEST_WRITE_CHECK = 0x00,
|
||||
SAVU_CONTROL_REQUEST_GENERAL = 0x80,
|
||||
SAVU_CONTROL_REQUEST_BUTTONS = 0x90,
|
||||
};
|
||||
|
||||
enum savu_control_values {
|
||||
SAVU_CONTROL_REQUEST_WRITE_CHECK_OVERLOAD = 0,
|
||||
SAVU_CONTROL_REQUEST_WRITE_CHECK_OK = 1,
|
||||
SAVU_CONTROL_REQUEST_WRITE_CHECK_INVALID = 2,
|
||||
SAVU_CONTROL_REQUEST_WRITE_CHECK_WAIT = 3,
|
||||
};
|
||||
|
||||
enum savu_commands {
|
||||
SAVU_COMMAND_CONTROL = 0x4,
|
||||
SAVU_COMMAND_PROFILE = 0x5,
|
||||
|
|
Loading…
Reference in New Issue