Skip to content

Commit

Permalink
HID: roccat: move functionality to roccat-common
Browse files Browse the repository at this point in the history
Reduced code duplication by moving functions from individual drivers
to roccat-common module.

Signed-off-by: Stefan Achatz <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
  • Loading branch information
Stefan Achatz authored and Jiri Kosina committed Jun 28, 2012
1 parent 6a2a639 commit 4728f2d
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 332 deletions.
58 changes: 58 additions & 0 deletions drivers/hid/hid-roccat-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
12 changes: 12 additions & 0 deletions drivers/hid/hid-roccat-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
50 changes: 4 additions & 46 deletions drivers/hid/hid-roccat-isku.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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));
}

Expand Down Expand Up @@ -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;
Expand Down
7 changes: 0 additions & 7 deletions drivers/hid/hid-roccat-isku.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
88 changes: 15 additions & 73 deletions drivers/hid/hid-roccat-koneplus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -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));
}

Expand All @@ -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;
Expand All @@ -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));
}

Expand All @@ -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));
}

Expand Down Expand Up @@ -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)
Expand Down
22 changes: 0 additions & 22 deletions drivers/hid/hid-roccat-koneplus.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 4728f2d

Please sign in to comment.