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

Commit 5772f636 authored by Stefan Achatz's avatar Stefan Achatz Committed by Jiri Kosina
Browse files

HID: roccat: Introduce module hid-roccat-common



Module hid-roccat-common contains functions used by roccat device driver
modules to reduce code duplication.
At the moment it contains just two wrapper methods for usb_control_msg
that ensure that the buffer used for transfer is dma capable which wasn't
the case before.
The kconfig option is not visible to the user but will be selected by the
device specific drivers.

Signed-off-by: default avatarStefan Achatz <erazor_de@users.sourceforge.net>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent a28764ef
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -417,10 +417,14 @@ config HID_ROCCAT
	Say Y here if you have a Roccat mouse or keyboard and want OSD or
	Say Y here if you have a Roccat mouse or keyboard and want OSD or
	macro execution support.
	macro execution support.


config HID_ROCCAT_COMMON
	tristate

config HID_ROCCAT_ARVO
config HID_ROCCAT_ARVO
	tristate "Roccat Arvo keyboard support"
	tristate "Roccat Arvo keyboard support"
	depends on USB_HID
	depends on USB_HID
	select HID_ROCCAT
	select HID_ROCCAT
	select HID_ROCCAT_COMMON
	---help---
	---help---
	Support for Roccat Arvo keyboard.
	Support for Roccat Arvo keyboard.


@@ -428,6 +432,7 @@ config HID_ROCCAT_KONE
	tristate "Roccat Kone Mouse support"
	tristate "Roccat Kone Mouse support"
	depends on USB_HID
	depends on USB_HID
	select HID_ROCCAT
	select HID_ROCCAT
	select HID_ROCCAT_COMMON
	---help---
	---help---
	Support for Roccat Kone mouse.
	Support for Roccat Kone mouse.


@@ -435,6 +440,7 @@ config HID_ROCCAT_KONEPLUS
	tristate "Roccat Kone[+] mouse support"
	tristate "Roccat Kone[+] mouse support"
	depends on USB_HID
	depends on USB_HID
	select HID_ROCCAT
	select HID_ROCCAT
	select HID_ROCCAT_COMMON
	---help---
	---help---
	Support for Roccat Kone[+] mouse.
	Support for Roccat Kone[+] mouse.


@@ -442,6 +448,7 @@ config HID_ROCCAT_PYRA
	tristate "Roccat Pyra mouse support"
	tristate "Roccat Pyra mouse support"
	depends on USB_HID
	depends on USB_HID
	select HID_ROCCAT
	select HID_ROCCAT
	select HID_ROCCAT_COMMON
	---help---
	---help---
	Support for Roccat Pyra mouse.
	Support for Roccat Pyra mouse.


+1 −0
Original line number Original line Diff line number Diff line
@@ -56,6 +56,7 @@ obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
obj-$(CONFIG_HID_PETALYNX)	+= hid-petalynx.o
obj-$(CONFIG_HID_PETALYNX)	+= hid-petalynx.o
obj-$(CONFIG_HID_PICOLCD)	+= hid-picolcd.o
obj-$(CONFIG_HID_PICOLCD)	+= hid-picolcd.o
obj-$(CONFIG_HID_ROCCAT)	+= hid-roccat.o
obj-$(CONFIG_HID_ROCCAT)	+= hid-roccat.o
obj-$(CONFIG_HID_ROCCAT_COMMON)	+= hid-roccat-common.o
obj-$(CONFIG_HID_ROCCAT_ARVO)	+= hid-roccat-arvo.o
obj-$(CONFIG_HID_ROCCAT_ARVO)	+= hid-roccat-arvo.o
obj-$(CONFIG_HID_ROCCAT_KONE)	+= hid-roccat-kone.o
obj-$(CONFIG_HID_ROCCAT_KONE)	+= hid-roccat-kone.o
obj-$(CONFIG_HID_ROCCAT_KONEPLUS)	+= hid-roccat-koneplus.o
obj-$(CONFIG_HID_ROCCAT_KONEPLUS)	+= hid-roccat-koneplus.o
+41 −107
Original line number Original line Diff line number Diff line
@@ -19,41 +19,15 @@
#include <linux/device.h>
#include <linux/device.h>
#include <linux/input.h>
#include <linux/input.h>
#include <linux/hid.h>
#include <linux/hid.h>
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include "hid-ids.h"
#include "hid-ids.h"
#include "hid-roccat.h"
#include "hid-roccat.h"
#include "hid-roccat-common.h"
#include "hid-roccat-arvo.h"
#include "hid-roccat-arvo.h"


static struct class *arvo_class;
static struct class *arvo_class;


static int arvo_receive(struct usb_device *usb_dev, uint usb_command,
		void *buf, uint size)
{
	int len;

	len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
			USB_REQ_CLEAR_FEATURE,
			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
			usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);

	return (len != size) ? -EIO : 0;
}

static int arvo_send(struct usb_device *usb_dev, uint usb_command,
		void const *buf, uint size)
{
	int len;

	len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
			USB_REQ_SET_CONFIGURATION,
			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
			usb_command, 0, (void *)buf, size, USB_CTRL_SET_TIMEOUT);

	return (len != size) ? -EIO : 0;
}

static ssize_t arvo_sysfs_show_mode_key(struct device *dev,
static ssize_t arvo_sysfs_show_mode_key(struct device *dev,
		struct device_attribute *attr, char *buf)
		struct device_attribute *attr, char *buf)
{
{
@@ -61,24 +35,17 @@ static ssize_t arvo_sysfs_show_mode_key(struct device *dev,
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
	struct usb_device *usb_dev =
	struct usb_device *usb_dev =
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
	struct arvo_mode_key *temp_buf;
	struct arvo_mode_key temp_buf;
	int retval;
	int retval;


	temp_buf = kmalloc(sizeof(struct arvo_mode_key), GFP_KERNEL);
	if (!temp_buf)
		return -ENOMEM;

	mutex_lock(&arvo->arvo_lock);
	mutex_lock(&arvo->arvo_lock);
	retval = arvo_receive(usb_dev, ARVO_USB_COMMAND_MODE_KEY,
	retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_MODE_KEY,
			temp_buf, sizeof(struct arvo_mode_key));
			&temp_buf, sizeof(struct arvo_mode_key));
	mutex_unlock(&arvo->arvo_lock);
	mutex_unlock(&arvo->arvo_lock);
	if (retval)
	if (retval)
		goto out;

	retval = snprintf(buf, PAGE_SIZE, "%d\n", temp_buf->state);
out:
	kfree(temp_buf);
		return retval;
		return retval;

	return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.state);
}
}


static ssize_t arvo_sysfs_set_mode_key(struct device *dev,
static ssize_t arvo_sysfs_set_mode_key(struct device *dev,
@@ -88,32 +55,25 @@ static ssize_t arvo_sysfs_set_mode_key(struct device *dev,
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
	struct usb_device *usb_dev =
	struct usb_device *usb_dev =
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
	struct arvo_mode_key *temp_buf;
	struct arvo_mode_key temp_buf;
	unsigned long state;
	unsigned long state;
	int retval;
	int retval;


	temp_buf = kmalloc(sizeof(struct arvo_mode_key), GFP_KERNEL);
	if (!temp_buf)
		return -ENOMEM;

	retval = strict_strtoul(buf, 10, &state);
	retval = strict_strtoul(buf, 10, &state);
	if (retval)
	if (retval)
		goto out;
		return retval;


	temp_buf->command = ARVO_COMMAND_MODE_KEY;
	temp_buf.command = ARVO_COMMAND_MODE_KEY;
	temp_buf->state = state;
	temp_buf.state = state;


	mutex_lock(&arvo->arvo_lock);
	mutex_lock(&arvo->arvo_lock);
	retval = arvo_send(usb_dev, ARVO_USB_COMMAND_MODE_KEY,
	retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_MODE_KEY,
			temp_buf, sizeof(struct arvo_mode_key));
			&temp_buf, sizeof(struct arvo_mode_key));
	mutex_unlock(&arvo->arvo_lock);
	mutex_unlock(&arvo->arvo_lock);
	if (retval)
	if (retval)
		goto out;

	retval = size;
out:
	kfree(temp_buf);
		return retval;
		return retval;

	return size;
}
}


static ssize_t arvo_sysfs_show_key_mask(struct device *dev,
static ssize_t arvo_sysfs_show_key_mask(struct device *dev,
@@ -123,24 +83,17 @@ static ssize_t arvo_sysfs_show_key_mask(struct device *dev,
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
	struct usb_device *usb_dev =
	struct usb_device *usb_dev =
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
	struct arvo_key_mask *temp_buf;
	struct arvo_key_mask temp_buf;
	int retval;
	int retval;


	temp_buf = kmalloc(sizeof(struct arvo_key_mask), GFP_KERNEL);
	if (!temp_buf)
		return -ENOMEM;

	mutex_lock(&arvo->arvo_lock);
	mutex_lock(&arvo->arvo_lock);
	retval = arvo_receive(usb_dev, ARVO_USB_COMMAND_KEY_MASK,
	retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_KEY_MASK,
			temp_buf, sizeof(struct arvo_key_mask));
			&temp_buf, sizeof(struct arvo_key_mask));
	mutex_unlock(&arvo->arvo_lock);
	mutex_unlock(&arvo->arvo_lock);
	if (retval)
	if (retval)
		goto out;

	retval = snprintf(buf, PAGE_SIZE, "%d\n", temp_buf->key_mask);
out:
	kfree(temp_buf);
		return retval;
		return retval;

	return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.key_mask);
}
}


static ssize_t arvo_sysfs_set_key_mask(struct device *dev,
static ssize_t arvo_sysfs_set_key_mask(struct device *dev,
@@ -150,52 +103,40 @@ static ssize_t arvo_sysfs_set_key_mask(struct device *dev,
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
	struct usb_device *usb_dev =
	struct usb_device *usb_dev =
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
	struct arvo_key_mask *temp_buf;
	struct arvo_key_mask temp_buf;
	unsigned long key_mask;
	unsigned long key_mask;
	int retval;
	int retval;


	temp_buf = kmalloc(sizeof(struct arvo_key_mask), GFP_KERNEL);
	if (!temp_buf)
		return -ENOMEM;

	retval = strict_strtoul(buf, 10, &key_mask);
	retval = strict_strtoul(buf, 10, &key_mask);
	if (retval)
	if (retval)
		goto out;
		return retval;


	temp_buf->command = ARVO_COMMAND_KEY_MASK;
	temp_buf.command = ARVO_COMMAND_KEY_MASK;
	temp_buf->key_mask = key_mask;
	temp_buf.key_mask = key_mask;


	mutex_lock(&arvo->arvo_lock);
	mutex_lock(&arvo->arvo_lock);
	retval = arvo_send(usb_dev, ARVO_USB_COMMAND_KEY_MASK,
	retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_KEY_MASK,
			temp_buf, sizeof(struct arvo_key_mask));
			&temp_buf, sizeof(struct arvo_key_mask));
	mutex_unlock(&arvo->arvo_lock);
	mutex_unlock(&arvo->arvo_lock);
	if (retval)
	if (retval)
		goto out;

	retval = size;
out:
	kfree(temp_buf);
		return retval;
		return retval;

	return size;
}
}


/* retval is 1-5 on success, < 0 on error */
/* retval is 1-5 on success, < 0 on error */
static int arvo_get_actual_profile(struct usb_device *usb_dev)
static int arvo_get_actual_profile(struct usb_device *usb_dev)
{
{
	struct arvo_actual_profile *temp_buf;
	struct arvo_actual_profile temp_buf;
	int retval;
	int retval;


	temp_buf = kmalloc(sizeof(struct arvo_actual_profile), GFP_KERNEL);
	retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE,
	if (!temp_buf)
			&temp_buf, sizeof(struct arvo_actual_profile));
		return -ENOMEM;

	retval = arvo_receive(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE,
			temp_buf, sizeof(struct arvo_actual_profile));

	if (!retval)
		retval = temp_buf->actual_profile;


	kfree(temp_buf);
	if (retval)
		return retval;
		return retval;

	return temp_buf.actual_profile;
}
}


static ssize_t arvo_sysfs_show_actual_profile(struct device *dev,
static ssize_t arvo_sysfs_show_actual_profile(struct device *dev,
@@ -214,32 +155,25 @@ static ssize_t arvo_sysfs_set_actual_profile(struct device *dev,
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
	struct usb_device *usb_dev =
	struct usb_device *usb_dev =
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
			interface_to_usbdev(to_usb_interface(dev->parent->parent));
	struct arvo_actual_profile *temp_buf;
	struct arvo_actual_profile temp_buf;
	unsigned long profile;
	unsigned long profile;
	int retval;
	int retval;


	temp_buf = kmalloc(sizeof(struct arvo_actual_profile), GFP_KERNEL);
	if (!temp_buf)
		return -ENOMEM;

	retval = strict_strtoul(buf, 10, &profile);
	retval = strict_strtoul(buf, 10, &profile);
	if (retval)
	if (retval)
		goto out;
		return retval;


	temp_buf->command = ARVO_COMMAND_ACTUAL_PROFILE;
	temp_buf.command = ARVO_COMMAND_ACTUAL_PROFILE;
	temp_buf->actual_profile = profile;
	temp_buf.actual_profile = profile;


	mutex_lock(&arvo->arvo_lock);
	mutex_lock(&arvo->arvo_lock);
	retval = arvo_send(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE,
	retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE,
			temp_buf, sizeof(struct arvo_actual_profile));
			&temp_buf, sizeof(struct arvo_actual_profile));
	if (!retval) {
	if (!retval) {
		arvo->actual_profile = profile;
		arvo->actual_profile = profile;
		retval = size;
		retval = size;
	}
	}
	mutex_unlock(&arvo->arvo_lock);
	mutex_unlock(&arvo->arvo_lock);

out:
	kfree(temp_buf);
	return retval;
	return retval;
}
}


@@ -257,7 +191,7 @@ static ssize_t arvo_sysfs_write(struct file *fp,
		return -EINVAL;
		return -EINVAL;


	mutex_lock(&arvo->arvo_lock);
	mutex_lock(&arvo->arvo_lock);
	retval = arvo_send(usb_dev, command, buf, real_size);
	retval = roccat_common_send(usb_dev, command, buf, real_size);
	mutex_unlock(&arvo->arvo_lock);
	mutex_unlock(&arvo->arvo_lock);


	return (retval ? retval : real_size);
	return (retval ? retval : real_size);
@@ -280,7 +214,7 @@ static ssize_t arvo_sysfs_read(struct file *fp,
		return -EINVAL;
		return -EINVAL;


	mutex_lock(&arvo->arvo_lock);
	mutex_lock(&arvo->arvo_lock);
	retval = arvo_receive(usb_dev, command, buf, real_size);
	retval = roccat_common_receive(usb_dev, command, buf, real_size);
	mutex_unlock(&arvo->arvo_lock);
	mutex_unlock(&arvo->arvo_lock);


	return (retval ? retval : real_size);
	return (retval ? retval : real_size);
+62 −0
Original line number Original line Diff line number Diff line
/*
 * 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/slab.h>
#include "hid-roccat-common.h"

int roccat_common_receive(struct usb_device *usb_dev, uint usb_command,
		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),
			USB_REQ_CLEAR_FEATURE,
			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
			usb_command, 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_common_receive);

int roccat_common_send(struct usb_device *usb_dev, uint usb_command,
		void const *data, uint size)
{
	char *buf;
	int len;

	buf = kmalloc(size, GFP_KERNEL);
	if (buf == NULL)
		return -ENOMEM;

	memcpy(buf, data, size);

	len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
			USB_REQ_SET_CONFIGURATION,
			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
			usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);

	kfree(buf);
	return ((len < 0) ? len : ((len != size) ? -EIO : 0));
}
EXPORT_SYMBOL_GPL(roccat_common_send);

MODULE_AUTHOR("Stefan Achatz");
MODULE_DESCRIPTION("USB Roccat common driver");
MODULE_LICENSE("GPL v2");
+23 −0
Original line number Original line Diff line number Diff line
#ifndef __HID_ROCCAT_COMMON_H
#define __HID_ROCCAT_COMMON_H

/*
 * 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/usb.h>
#include <linux/types.h>

int roccat_common_receive(struct usb_device *usb_dev, uint usb_command,
		void *data, uint size);
int roccat_common_send(struct usb_device *usb_dev, uint usb_command,
		void const *data, uint size);

#endif
Loading