Commit 4728f2dc authored by Stefan Achatz's avatar Stefan Achatz Committed by Jiri Kosina

HID: roccat: move functionality to roccat-common

Reduced code duplication by moving functions from individual drivers
to roccat-common module.
Signed-off-by: default avatarStefan Achatz <erazor_de@users.sourceforge.net>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 6a2a6390
...@@ -64,6 +64,64 @@ int roccat_common_send(struct usb_device *usb_dev, uint report_id, ...@@ -64,6 +64,64 @@ int roccat_common_send(struct usb_device *usb_dev, uint report_id,
} }
EXPORT_SYMBOL_GPL(roccat_common_send); 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_AUTHOR("Stefan Achatz");
MODULE_DESCRIPTION("USB Roccat common driver"); MODULE_DESCRIPTION("USB Roccat common driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -15,9 +15,21 @@ ...@@ -15,9 +15,21 @@
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/types.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, int roccat_common_receive(struct usb_device *usb_dev, uint report_id,
void *data, uint size); void *data, uint size);
int roccat_common_send(struct usb_device *usb_dev, uint report_id, int roccat_common_send(struct usb_device *usb_dev, uint report_id,
void const *data, uint size); void const *data, uint size);
int roccat_common_send_with_status(struct usb_device *usb_dev,
uint command, void const *buf, uint size);
#endif #endif
...@@ -39,50 +39,6 @@ static int isku_receive(struct usb_device *usb_dev, uint command, ...@@ -39,50 +39,6 @@ static int isku_receive(struct usb_device *usb_dev, uint command,
return roccat_common_receive(usb_dev, command, buf, size); 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) static int isku_get_actual_profile(struct usb_device *usb_dev)
{ {
struct isku_actual_profile buf; struct isku_actual_profile buf;
...@@ -100,7 +56,8 @@ static int isku_set_actual_profile(struct usb_device *usb_dev, int new_profile) ...@@ -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.command = ISKU_COMMAND_ACTUAL_PROFILE;
buf.size = sizeof(struct isku_actual_profile); buf.size = sizeof(struct isku_actual_profile);
buf.actual_profile = new_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)); sizeof(struct isku_actual_profile));
} }
...@@ -197,7 +154,8 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, ...@@ -197,7 +154,8 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj,
return -EINVAL; return -EINVAL;
mutex_lock(&isku->isku_lock); 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); mutex_unlock(&isku->isku_lock);
return retval ? retval : real_size; return retval ? retval : real_size;
......
...@@ -25,13 +25,6 @@ struct isku_control { ...@@ -25,13 +25,6 @@ struct isku_control {
uint8_t request; uint8_t request;
} __packed; } __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 { struct isku_actual_profile {
uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */ uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */
uint8_t size; /* always 3 */ uint8_t size; /* always 3 */
......
...@@ -39,82 +39,20 @@ static void koneplus_profile_activated(struct koneplus_device *koneplus, ...@@ -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, static int koneplus_send_control(struct usb_device *usb_dev, uint value,
enum koneplus_control_requests request) enum koneplus_control_requests request)
{ {
struct koneplus_control control; struct roccat_common_control control;
if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
value > 4) value > 4)
return -EINVAL; return -EINVAL;
control.command = KONEPLUS_COMMAND_CONTROL; control.command = ROCCAT_COMMON_COMMAND_CONTROL;
control.value = value; control.value = value;
control.request = request; control.request = request;
return roccat_common_send(usb_dev, KONEPLUS_COMMAND_CONTROL, return roccat_common_send_with_status(usb_dev,
&control, sizeof(struct koneplus_control)); ROCCAT_COMMON_COMMAND_CONTROL,
} &control, sizeof(struct roccat_common_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;
} }
static int koneplus_get_info(struct usb_device *usb_dev, 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, ...@@ -129,7 +67,7 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev,
{ {
int retval; int retval;
retval = koneplus_select_profile(usb_dev, number, retval = koneplus_send_control(usb_dev, number,
KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
if (retval) if (retval)
return retval; return retval;
...@@ -141,7 +79,8 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev, ...@@ -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, static int koneplus_set_profile_settings(struct usb_device *usb_dev,
struct koneplus_profile_settings const *settings) 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)); settings, sizeof(struct koneplus_profile_settings));
} }
...@@ -150,7 +89,7 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev, ...@@ -150,7 +89,7 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
{ {
int retval; int retval;
retval = koneplus_select_profile(usb_dev, number, retval = koneplus_send_control(usb_dev, number,
KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
if (retval) if (retval)
return retval; return retval;
...@@ -162,7 +101,8 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev, ...@@ -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, static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
struct koneplus_profile_buttons const *buttons) 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)); buttons, sizeof(struct koneplus_profile_buttons));
} }
...@@ -187,7 +127,8 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev, ...@@ -187,7 +127,8 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev,
buf.size = sizeof(struct koneplus_actual_profile); buf.size = sizeof(struct koneplus_actual_profile);
buf.actual_profile = new_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)); &buf, sizeof(struct koneplus_actual_profile));
} }
...@@ -231,7 +172,8 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, ...@@ -231,7 +172,8 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
return -EINVAL; return -EINVAL;
mutex_lock(&koneplus->koneplus_lock); 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); mutex_unlock(&koneplus->koneplus_lock);
if (retval) if (retval)
......
...@@ -20,32 +20,11 @@ struct koneplus_talk { ...@@ -20,32 +20,11 @@ struct koneplus_talk {
uint8_t data[14]; uint8_t data[14];
} __packed; } __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 { enum koneplus_control_requests {
KONEPLUS_CONTROL_REQUEST_STATUS = 0x00,
KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80,
KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90, 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 { struct koneplus_actual_profile {
uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */ uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */
uint8_t size; /* always 3 */ uint8_t size; /* always 3 */
...@@ -137,7 +116,6 @@ struct koneplus_tcu_image { ...@@ -137,7 +116,6 @@ struct koneplus_tcu_image {
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
enum koneplus_commands { enum koneplus_commands {
KONEPLUS_COMMAND_CONTROL = 0x4,
KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
......
...@@ -47,69 +47,23 @@ static int kovaplus_send_control(struct usb_device *usb_dev, uint value, ...@@ -47,69 +47,23 @@ static int kovaplus_send_control(struct usb_device *usb_dev, uint value,
enum kovaplus_control_requests request) enum kovaplus_control_requests request)
{ {
int retval; int retval;
struct kovaplus_control control; struct roccat_common_control control;
if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
value > 4) value > 4)
return -EINVAL; return -EINVAL;
control.command = KOVAPLUS_COMMAND_CONTROL; control.command = ROCCAT_COMMON_COMMAND_CONTROL;
control.value = value; control.value = value;
control.request = request; control.request = request;
retval = roccat_common_send(usb_dev, KOVAPLUS_COMMAND_CONTROL, retval = roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL,
&control, sizeof(struct kovaplus_control)); &control, sizeof(struct roccat_common_control));
return retval; 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, static int kovaplus_select_profile(struct usb_device *usb_dev, uint number,
enum kovaplus_control_requests request) enum kovaplus_control_requests request)
{ {
...@@ -140,7 +94,8 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev, ...@@ -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, static int kovaplus_set_profile_settings(struct usb_device *usb_dev,
struct kovaplus_profile_settings const *settings) 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)); settings, sizeof(struct kovaplus_profile_settings));
} }
...@@ -161,7 +116,8 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, ...@@ -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, static int kovaplus_set_profile_buttons(struct usb_device *usb_dev,
struct kovaplus_profile_buttons const *buttons) 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)); buttons, sizeof(struct kovaplus_profile_buttons));
} }
...@@ -186,7 +142,8 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev, ...@@ -186,7 +142,8 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev,
buf.size = sizeof(struct kovaplus_actual_profile); buf.size = sizeof(struct kovaplus_actual_profile);
buf.actual_profile = new_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)); &buf, sizeof(struct kovaplus_actual_profile));
} }
......
...@@ -14,27 +14,13 @@ ...@@ -14,27 +14,13 @@
#include <linux/types.h> #include <linux/types.h>
struct kovaplus_control {
uint8_t command; /* KOVAPLUS_COMMAND_CONTROL */
uint8_t value;
uint8_t request;
} __packed;
enum kovaplus_control_requests { enum kovaplus_control_requests {
/* read after write; value = 1 */
KOVAPLUS_CONTROL_REQUEST_STATUS = 0x0,
/* write; value = profile number range 0-4 */ /* write; value = profile number range 0-4 */
KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
/* write; value = profile number range 0-4 */ /* write; value = profile number range 0-4 */
KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20, 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 { struct kovaplus_actual_profile {
uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */ uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */
uint8_t size; /* always 3 */ uint8_t size; /* always 3 */
...@@ -75,7 +61,6 @@ struct kovaplus_a { ...@@ -75,7 +61,6 @@ struct kovaplus_a {
} __packed; } __packed;
enum kovaplus_commands { enum kovaplus_commands {
KOVAPLUS_COMMAND_CONTROL = 0x4,
KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7, KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
......
...@@ -42,43 +42,19 @@ static void profile_activated(struct pyra_device *pyra, ...@@ -42,43 +42,19 @@ static void profile_activated(struct pyra_device *pyra,
static int pyra_send_control(struct usb_device *usb_dev, int value, static int pyra_send_control(struct usb_device *usb_dev, int value,
enum pyra_control_requests request) enum pyra_control_requests request)
{ {
struct pyra_control control; struct roccat_common_control control;
if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
(value < 0 || value > 4)) (value < 0 || value > 4))
return -EINVAL; return -EINVAL;
control.command = PYRA_COMMAND_CONTROL; control.command = ROCCAT_COMMON_COMMAND_CONTROL;
control.value = value; control.value = value;
control.request = request; control.request = request;
return roccat_common_send(usb_dev, PYRA_COMMAND_CONTROL, return roccat_common_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL,
&control, sizeof(struct pyra_control)); &control, sizeof(struct roccat_common_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;
}
} }
static int pyra_get_profile_settings(struct usb_device *usb_dev, 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) ...@@ -118,34 +94,27 @@ static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
buf, sizeof(struct pyra_info)); 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, static int pyra_set_profile_settings(struct usb_device *usb_dev,
struct pyra_profile_settings const *settings) 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)); sizeof(struct pyra_profile_settings));
} }
static int pyra_set_profile_buttons(struct usb_device *usb_dev, static int pyra_set_profile_buttons(struct usb_device *usb_dev,
struct pyra_profile_buttons const *buttons) 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)); sizeof(struct pyra_profile_buttons));
} }
static int pyra_set_settings(struct usb_device *usb_dev, static int pyra_set_settings(struct usb_device *usb_dev,
struct pyra_settings const *settings) 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)); sizeof(struct pyra_settings));
} }
......
...@@ -20,18 +20,7 @@ struct pyra_b { ...@@ -20,18 +20,7 @@ struct pyra_b {
uint8_t unknown; /* 1 */ uint8_t unknown; /* 1 */
} __attribute__ ((__packed__)); } __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 { enum pyra_control_requests {
PYRA_CONTROL_REQUEST_STATUS = 0x00,
PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20
}; };
...@@ -75,7 +64,6 @@ struct pyra_info { ...@@ -75,7 +64,6 @@ struct pyra_info {
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
enum pyra_commands { enum pyra_commands {
PYRA_COMMAND_CONTROL = 0x4,
PYRA_COMMAND_SETTINGS = 0x5, PYRA_COMMAND_SETTINGS = 0x5,
PYRA_COMMAND_PROFILE_SETTINGS = 0x6, PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
PYRA_COMMAND_PROFILE_BUTTONS = 0x7, PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
......
...@@ -27,50 +27,6 @@ ...@@ -27,50 +27,6 @@
static struct class *savu_class; 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, static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj,
char *buf, loff_t off, size_t count, char *buf, loff_t off, size_t count,
size_t real_size, uint command) size_t real_size, uint command)
...@@ -108,7 +64,8 @@ static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj, ...@@ -108,7 +64,8 @@ static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj,
return -EINVAL; return -EINVAL;
mutex_lock(&savu->savu_lock); 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); mutex_unlock(&savu->savu_lock);
return retval ? retval : real_size; return retval ? retval : real_size;
......
...@@ -23,29 +23,11 @@ enum { ...@@ -23,29 +23,11 @@ enum {
SAVU_SIZE_INFO = 0x08, 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 { enum savu_control_requests {
SAVU_CONTROL_REQUEST_WRITE_CHECK = 0x00,
SAVU_CONTROL_REQUEST_GENERAL = 0x80, SAVU_CONTROL_REQUEST_GENERAL = 0x80,
SAVU_CONTROL_REQUEST_BUTTONS = 0x90, 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 { enum savu_commands {
SAVU_COMMAND_CONTROL = 0x4, SAVU_COMMAND_CONTROL = 0x4,
SAVU_COMMAND_PROFILE = 0x5, SAVU_COMMAND_PROFILE = 0x5,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment