Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+58 −0
Original line number Original line Diff line number Diff line
@@ -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");
+12 −0
Original line number Original line Diff line number Diff line
@@ -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
+4 −46
Original line number Original line Diff line number Diff line
@@ -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)
	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,
		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;
+0 −7
Original line number Original line Diff line number Diff line
@@ -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 */
+15 −73
Original line number Original line Diff line number Diff line
@@ -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,
{
{
	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,
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,
{
{
	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,
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,
	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,
		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)
Loading