cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hid-roccat-kone.c (24159B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Roccat Kone driver for Linux
      4 *
      5 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
      6 */
      7
      8/*
      9 */
     10
     11/*
     12 * Roccat Kone is a gamer mouse which consists of a mouse part and a keyboard
     13 * part. The keyboard part enables the mouse to execute stored macros with mixed
     14 * key- and button-events.
     15 *
     16 * TODO implement on-the-fly polling-rate change
     17 *      The windows driver has the ability to change the polling rate of the
     18 *      device on the press of a mousebutton.
     19 *      Is it possible to remove and reinstall the urb in raw-event- or any
     20 *      other handler, or to defer this action to be executed somewhere else?
     21 *
     22 * TODO is it possible to overwrite group for sysfs attributes via udev?
     23 */
     24
     25#include <linux/device.h>
     26#include <linux/input.h>
     27#include <linux/hid.h>
     28#include <linux/module.h>
     29#include <linux/slab.h>
     30#include <linux/hid-roccat.h>
     31#include "hid-ids.h"
     32#include "hid-roccat-common.h"
     33#include "hid-roccat-kone.h"
     34
     35static uint profile_numbers[5] = {0, 1, 2, 3, 4};
     36
     37static void kone_profile_activated(struct kone_device *kone, uint new_profile)
     38{
     39	kone->actual_profile = new_profile;
     40	kone->actual_dpi = kone->profiles[new_profile - 1].startup_dpi;
     41}
     42
     43static void kone_profile_report(struct kone_device *kone, uint new_profile)
     44{
     45	struct kone_roccat_report roccat_report;
     46
     47	roccat_report.event = kone_mouse_event_switch_profile;
     48	roccat_report.value = new_profile;
     49	roccat_report.key = 0;
     50	roccat_report_event(kone->chrdev_minor, (uint8_t *)&roccat_report);
     51}
     52
     53static int kone_receive(struct usb_device *usb_dev, uint usb_command,
     54		void *data, uint size)
     55{
     56	char *buf;
     57	int len;
     58
     59	buf = kmalloc(size, GFP_KERNEL);
     60	if (buf == NULL)
     61		return -ENOMEM;
     62
     63	len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
     64			HID_REQ_GET_REPORT,
     65			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
     66			usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
     67
     68	memcpy(data, buf, size);
     69	kfree(buf);
     70	return ((len < 0) ? len : ((len != size) ? -EIO : 0));
     71}
     72
     73static int kone_send(struct usb_device *usb_dev, uint usb_command,
     74		void const *data, uint size)
     75{
     76	char *buf;
     77	int len;
     78
     79	buf = kmemdup(data, size, GFP_KERNEL);
     80	if (buf == NULL)
     81		return -ENOMEM;
     82
     83	len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
     84			HID_REQ_SET_REPORT,
     85			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
     86			usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
     87
     88	kfree(buf);
     89	return ((len < 0) ? len : ((len != size) ? -EIO : 0));
     90}
     91
     92/* kone_class is used for creating sysfs attributes via roccat char device */
     93static struct class *kone_class;
     94
     95static void kone_set_settings_checksum(struct kone_settings *settings)
     96{
     97	uint16_t checksum = 0;
     98	unsigned char *address = (unsigned char *)settings;
     99	int i;
    100
    101	for (i = 0; i < sizeof(struct kone_settings) - 2; ++i, ++address)
    102		checksum += *address;
    103	settings->checksum = cpu_to_le16(checksum);
    104}
    105
    106/*
    107 * Checks success after writing data to mouse
    108 * On success returns 0
    109 * On failure returns errno
    110 */
    111static int kone_check_write(struct usb_device *usb_dev)
    112{
    113	int retval;
    114	uint8_t data;
    115
    116	do {
    117		/*
    118		 * Mouse needs 50 msecs until it says ok, but there are
    119		 * 30 more msecs needed for next write to work.
    120		 */
    121		msleep(80);
    122
    123		retval = kone_receive(usb_dev,
    124				kone_command_confirm_write, &data, 1);
    125		if (retval)
    126			return retval;
    127
    128		/*
    129		 * value of 3 seems to mean something like
    130		 * "not finished yet, but it looks good"
    131		 * So check again after a moment.
    132		 */
    133	} while (data == 3);
    134
    135	if (data == 1) /* everything alright */
    136		return 0;
    137
    138	/* unknown answer */
    139	dev_err(&usb_dev->dev, "got retval %d when checking write\n", data);
    140	return -EIO;
    141}
    142
    143/*
    144 * Reads settings from mouse and stores it in @buf
    145 * On success returns 0
    146 * On failure returns errno
    147 */
    148static int kone_get_settings(struct usb_device *usb_dev,
    149		struct kone_settings *buf)
    150{
    151	return kone_receive(usb_dev, kone_command_settings, buf,
    152			sizeof(struct kone_settings));
    153}
    154
    155/*
    156 * Writes settings from @buf to mouse
    157 * On success returns 0
    158 * On failure returns errno
    159 */
    160static int kone_set_settings(struct usb_device *usb_dev,
    161		struct kone_settings const *settings)
    162{
    163	int retval;
    164
    165	retval = kone_send(usb_dev, kone_command_settings,
    166			settings, sizeof(struct kone_settings));
    167	if (retval)
    168		return retval;
    169	return kone_check_write(usb_dev);
    170}
    171
    172/*
    173 * Reads profile data from mouse and stores it in @buf
    174 * @number: profile number to read
    175 * On success returns 0
    176 * On failure returns errno
    177 */
    178static int kone_get_profile(struct usb_device *usb_dev,
    179		struct kone_profile *buf, int number)
    180{
    181	int len;
    182
    183	if (number < 1 || number > 5)
    184		return -EINVAL;
    185
    186	len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
    187			USB_REQ_CLEAR_FEATURE,
    188			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
    189			kone_command_profile, number, buf,
    190			sizeof(struct kone_profile), USB_CTRL_SET_TIMEOUT);
    191
    192	if (len != sizeof(struct kone_profile))
    193		return -EIO;
    194
    195	return 0;
    196}
    197
    198/*
    199 * Writes profile data to mouse.
    200 * @number: profile number to write
    201 * On success returns 0
    202 * On failure returns errno
    203 */
    204static int kone_set_profile(struct usb_device *usb_dev,
    205		struct kone_profile const *profile, int number)
    206{
    207	int len;
    208
    209	if (number < 1 || number > 5)
    210		return -EINVAL;
    211
    212	len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
    213			USB_REQ_SET_CONFIGURATION,
    214			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
    215			kone_command_profile, number, (void *)profile,
    216			sizeof(struct kone_profile),
    217			USB_CTRL_SET_TIMEOUT);
    218
    219	if (len != sizeof(struct kone_profile))
    220		return len;
    221
    222	if (kone_check_write(usb_dev))
    223		return -EIO;
    224
    225	return 0;
    226}
    227
    228/*
    229 * Reads value of "fast-clip-weight" and stores it in @result
    230 * On success returns 0
    231 * On failure returns errno
    232 */
    233static int kone_get_weight(struct usb_device *usb_dev, int *result)
    234{
    235	int retval;
    236	uint8_t data;
    237
    238	retval = kone_receive(usb_dev, kone_command_weight, &data, 1);
    239
    240	if (retval)
    241		return retval;
    242
    243	*result = (int)data;
    244	return 0;
    245}
    246
    247/*
    248 * Reads firmware_version of mouse and stores it in @result
    249 * On success returns 0
    250 * On failure returns errno
    251 */
    252static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
    253{
    254	int retval;
    255	uint16_t data;
    256
    257	retval = kone_receive(usb_dev, kone_command_firmware_version,
    258			&data, 2);
    259	if (retval)
    260		return retval;
    261
    262	*result = le16_to_cpu(data);
    263	return 0;
    264}
    265
    266static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
    267		struct bin_attribute *attr, char *buf,
    268		loff_t off, size_t count) {
    269	struct device *dev = kobj_to_dev(kobj)->parent->parent;
    270	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
    271
    272	if (off >= sizeof(struct kone_settings))
    273		return 0;
    274
    275	if (off + count > sizeof(struct kone_settings))
    276		count = sizeof(struct kone_settings) - off;
    277
    278	mutex_lock(&kone->kone_lock);
    279	memcpy(buf, ((char const *)&kone->settings) + off, count);
    280	mutex_unlock(&kone->kone_lock);
    281
    282	return count;
    283}
    284
    285/*
    286 * Writing settings automatically activates startup_profile.
    287 * This function keeps values in kone_device up to date and assumes that in
    288 * case of error the old data is still valid
    289 */
    290static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
    291		struct bin_attribute *attr, char *buf,
    292		loff_t off, size_t count) {
    293	struct device *dev = kobj_to_dev(kobj)->parent->parent;
    294	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
    295	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
    296	int retval = 0, difference, old_profile;
    297	struct kone_settings *settings = (struct kone_settings *)buf;
    298
    299	/* I need to get my data in one piece */
    300	if (off != 0 || count != sizeof(struct kone_settings))
    301		return -EINVAL;
    302
    303	mutex_lock(&kone->kone_lock);
    304	difference = memcmp(settings, &kone->settings,
    305			    sizeof(struct kone_settings));
    306	if (difference) {
    307		if (settings->startup_profile < 1 ||
    308		    settings->startup_profile > 5) {
    309			retval = -EINVAL;
    310			goto unlock;
    311		}
    312
    313		retval = kone_set_settings(usb_dev, settings);
    314		if (retval)
    315			goto unlock;
    316
    317		old_profile = kone->settings.startup_profile;
    318		memcpy(&kone->settings, settings, sizeof(struct kone_settings));
    319
    320		kone_profile_activated(kone, kone->settings.startup_profile);
    321
    322		if (kone->settings.startup_profile != old_profile)
    323			kone_profile_report(kone, kone->settings.startup_profile);
    324	}
    325unlock:
    326	mutex_unlock(&kone->kone_lock);
    327
    328	if (retval)
    329		return retval;
    330
    331	return sizeof(struct kone_settings);
    332}
    333static BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
    334		kone_sysfs_write_settings, sizeof(struct kone_settings));
    335
    336static ssize_t kone_sysfs_read_profilex(struct file *fp,
    337		struct kobject *kobj, struct bin_attribute *attr,
    338		char *buf, loff_t off, size_t count) {
    339	struct device *dev = kobj_to_dev(kobj)->parent->parent;
    340	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
    341
    342	if (off >= sizeof(struct kone_profile))
    343		return 0;
    344
    345	if (off + count > sizeof(struct kone_profile))
    346		count = sizeof(struct kone_profile) - off;
    347
    348	mutex_lock(&kone->kone_lock);
    349	memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count);
    350	mutex_unlock(&kone->kone_lock);
    351
    352	return count;
    353}
    354
    355/* Writes data only if different to stored data */
    356static ssize_t kone_sysfs_write_profilex(struct file *fp,
    357		struct kobject *kobj, struct bin_attribute *attr,
    358		char *buf, loff_t off, size_t count) {
    359	struct device *dev = kobj_to_dev(kobj)->parent->parent;
    360	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
    361	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
    362	struct kone_profile *profile;
    363	int retval = 0, difference;
    364
    365	/* I need to get my data in one piece */
    366	if (off != 0 || count != sizeof(struct kone_profile))
    367		return -EINVAL;
    368
    369	profile = &kone->profiles[*(uint *)(attr->private)];
    370
    371	mutex_lock(&kone->kone_lock);
    372	difference = memcmp(buf, profile, sizeof(struct kone_profile));
    373	if (difference) {
    374		retval = kone_set_profile(usb_dev,
    375				(struct kone_profile const *)buf,
    376				*(uint *)(attr->private) + 1);
    377		if (!retval)
    378			memcpy(profile, buf, sizeof(struct kone_profile));
    379	}
    380	mutex_unlock(&kone->kone_lock);
    381
    382	if (retval)
    383		return retval;
    384
    385	return sizeof(struct kone_profile);
    386}
    387#define PROFILE_ATTR(number)					\
    388static struct bin_attribute bin_attr_profile##number = {	\
    389	.attr = { .name = "profile" #number, .mode = 0660 },	\
    390	.size = sizeof(struct kone_profile),			\
    391	.read = kone_sysfs_read_profilex,			\
    392	.write = kone_sysfs_write_profilex,			\
    393	.private = &profile_numbers[number-1],			\
    394}
    395PROFILE_ATTR(1);
    396PROFILE_ATTR(2);
    397PROFILE_ATTR(3);
    398PROFILE_ATTR(4);
    399PROFILE_ATTR(5);
    400
    401static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
    402		struct device_attribute *attr, char *buf)
    403{
    404	struct kone_device *kone =
    405			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
    406	return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile);
    407}
    408static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL);
    409
    410static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
    411		struct device_attribute *attr, char *buf)
    412{
    413	struct kone_device *kone =
    414			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
    415	return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi);
    416}
    417static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL);
    418
    419/* weight is read each time, since we don't get informed when it's changed */
    420static ssize_t kone_sysfs_show_weight(struct device *dev,
    421		struct device_attribute *attr, char *buf)
    422{
    423	struct kone_device *kone;
    424	struct usb_device *usb_dev;
    425	int weight = 0;
    426	int retval;
    427
    428	dev = dev->parent->parent;
    429	kone = hid_get_drvdata(dev_get_drvdata(dev));
    430	usb_dev = interface_to_usbdev(to_usb_interface(dev));
    431
    432	mutex_lock(&kone->kone_lock);
    433	retval = kone_get_weight(usb_dev, &weight);
    434	mutex_unlock(&kone->kone_lock);
    435
    436	if (retval)
    437		return retval;
    438	return snprintf(buf, PAGE_SIZE, "%d\n", weight);
    439}
    440static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL);
    441
    442static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
    443		struct device_attribute *attr, char *buf)
    444{
    445	struct kone_device *kone =
    446			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
    447	return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version);
    448}
    449static DEVICE_ATTR(firmware_version, 0440, kone_sysfs_show_firmware_version,
    450		   NULL);
    451
    452static ssize_t kone_sysfs_show_tcu(struct device *dev,
    453		struct device_attribute *attr, char *buf)
    454{
    455	struct kone_device *kone =
    456			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
    457	return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu);
    458}
    459
    460static int kone_tcu_command(struct usb_device *usb_dev, int number)
    461{
    462	unsigned char value;
    463
    464	value = number;
    465	return kone_send(usb_dev, kone_command_calibrate, &value, 1);
    466}
    467
    468/*
    469 * Calibrating the tcu is the only action that changes settings data inside the
    470 * mouse, so this data needs to be reread
    471 */
    472static ssize_t kone_sysfs_set_tcu(struct device *dev,
    473		struct device_attribute *attr, char const *buf, size_t size)
    474{
    475	struct kone_device *kone;
    476	struct usb_device *usb_dev;
    477	int retval;
    478	unsigned long state;
    479
    480	dev = dev->parent->parent;
    481	kone = hid_get_drvdata(dev_get_drvdata(dev));
    482	usb_dev = interface_to_usbdev(to_usb_interface(dev));
    483
    484	retval = kstrtoul(buf, 10, &state);
    485	if (retval)
    486		return retval;
    487
    488	if (state != 0 && state != 1)
    489		return -EINVAL;
    490
    491	mutex_lock(&kone->kone_lock);
    492
    493	if (state == 1) { /* state activate */
    494		retval = kone_tcu_command(usb_dev, 1);
    495		if (retval)
    496			goto exit_unlock;
    497		retval = kone_tcu_command(usb_dev, 2);
    498		if (retval)
    499			goto exit_unlock;
    500		ssleep(5); /* tcu needs this time for calibration */
    501		retval = kone_tcu_command(usb_dev, 3);
    502		if (retval)
    503			goto exit_unlock;
    504		retval = kone_tcu_command(usb_dev, 0);
    505		if (retval)
    506			goto exit_unlock;
    507		retval = kone_tcu_command(usb_dev, 4);
    508		if (retval)
    509			goto exit_unlock;
    510		/*
    511		 * Kone needs this time to settle things.
    512		 * Reading settings too early will result in invalid data.
    513		 * Roccat's driver waits 1 sec, maybe this time could be
    514		 * shortened.
    515		 */
    516		ssleep(1);
    517	}
    518
    519	/* calibration changes values in settings, so reread */
    520	retval = kone_get_settings(usb_dev, &kone->settings);
    521	if (retval)
    522		goto exit_no_settings;
    523
    524	/* only write settings back if activation state is different */
    525	if (kone->settings.tcu != state) {
    526		kone->settings.tcu = state;
    527		kone_set_settings_checksum(&kone->settings);
    528
    529		retval = kone_set_settings(usb_dev, &kone->settings);
    530		if (retval) {
    531			dev_err(&usb_dev->dev, "couldn't set tcu state\n");
    532			/*
    533			 * try to reread valid settings into buffer overwriting
    534			 * first error code
    535			 */
    536			retval = kone_get_settings(usb_dev, &kone->settings);
    537			if (retval)
    538				goto exit_no_settings;
    539			goto exit_unlock;
    540		}
    541		/* calibration resets profile */
    542		kone_profile_activated(kone, kone->settings.startup_profile);
    543	}
    544
    545	retval = size;
    546exit_no_settings:
    547	dev_err(&usb_dev->dev, "couldn't read settings\n");
    548exit_unlock:
    549	mutex_unlock(&kone->kone_lock);
    550	return retval;
    551}
    552static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu);
    553
    554static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
    555		struct device_attribute *attr, char *buf)
    556{
    557	struct kone_device *kone =
    558			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
    559	return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile);
    560}
    561
    562static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
    563		struct device_attribute *attr, char const *buf, size_t size)
    564{
    565	struct kone_device *kone;
    566	struct usb_device *usb_dev;
    567	int retval;
    568	unsigned long new_startup_profile;
    569
    570	dev = dev->parent->parent;
    571	kone = hid_get_drvdata(dev_get_drvdata(dev));
    572	usb_dev = interface_to_usbdev(to_usb_interface(dev));
    573
    574	retval = kstrtoul(buf, 10, &new_startup_profile);
    575	if (retval)
    576		return retval;
    577
    578	if (new_startup_profile  < 1 || new_startup_profile > 5)
    579		return -EINVAL;
    580
    581	mutex_lock(&kone->kone_lock);
    582
    583	kone->settings.startup_profile = new_startup_profile;
    584	kone_set_settings_checksum(&kone->settings);
    585
    586	retval = kone_set_settings(usb_dev, &kone->settings);
    587	if (retval) {
    588		mutex_unlock(&kone->kone_lock);
    589		return retval;
    590	}
    591
    592	/* changing the startup profile immediately activates this profile */
    593	kone_profile_activated(kone, new_startup_profile);
    594	kone_profile_report(kone, new_startup_profile);
    595
    596	mutex_unlock(&kone->kone_lock);
    597	return size;
    598}
    599static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile,
    600		   kone_sysfs_set_startup_profile);
    601
    602static struct attribute *kone_attrs[] = {
    603	/*
    604	 * Read actual dpi settings.
    605	 * Returns raw value for further processing. Refer to enum
    606	 * kone_polling_rates to get real value.
    607	 */
    608	&dev_attr_actual_dpi.attr,
    609	&dev_attr_actual_profile.attr,
    610
    611	/*
    612	 * The mouse can be equipped with one of four supplied weights from 5
    613	 * to 20 grams which are recognized and its value can be read out.
    614	 * This returns the raw value reported by the mouse for easy evaluation
    615	 * by software. Refer to enum kone_weights to get corresponding real
    616	 * weight.
    617	 */
    618	&dev_attr_weight.attr,
    619
    620	/*
    621	 * Prints firmware version stored in mouse as integer.
    622	 * The raw value reported by the mouse is returned for easy evaluation,
    623	 * to get the real version number the decimal point has to be shifted 2
    624	 * positions to the left. E.g. a value of 138 means 1.38.
    625	 */
    626	&dev_attr_firmware_version.attr,
    627
    628	/*
    629	 * Prints state of Tracking Control Unit as number where 0 = off and
    630	 * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
    631	 * activates the tcu
    632	 */
    633	&dev_attr_tcu.attr,
    634
    635	/* Prints and takes the number of the profile the mouse starts with */
    636	&dev_attr_startup_profile.attr,
    637	NULL,
    638};
    639
    640static struct bin_attribute *kone_bin_attributes[] = {
    641	&bin_attr_settings,
    642	&bin_attr_profile1,
    643	&bin_attr_profile2,
    644	&bin_attr_profile3,
    645	&bin_attr_profile4,
    646	&bin_attr_profile5,
    647	NULL,
    648};
    649
    650static const struct attribute_group kone_group = {
    651	.attrs = kone_attrs,
    652	.bin_attrs = kone_bin_attributes,
    653};
    654
    655static const struct attribute_group *kone_groups[] = {
    656	&kone_group,
    657	NULL,
    658};
    659
    660static int kone_init_kone_device_struct(struct usb_device *usb_dev,
    661		struct kone_device *kone)
    662{
    663	uint i;
    664	int retval;
    665
    666	mutex_init(&kone->kone_lock);
    667
    668	for (i = 0; i < 5; ++i) {
    669		retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1);
    670		if (retval)
    671			return retval;
    672	}
    673
    674	retval = kone_get_settings(usb_dev, &kone->settings);
    675	if (retval)
    676		return retval;
    677
    678	retval = kone_get_firmware_version(usb_dev, &kone->firmware_version);
    679	if (retval)
    680		return retval;
    681
    682	kone_profile_activated(kone, kone->settings.startup_profile);
    683
    684	return 0;
    685}
    686
    687/*
    688 * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to
    689 * mousepart if usb_hid is compiled into the kernel and kone is compiled as
    690 * module.
    691 * Secial behaviour is bound only to mousepart since only mouseevents contain
    692 * additional notifications.
    693 */
    694static int kone_init_specials(struct hid_device *hdev)
    695{
    696	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
    697	struct usb_device *usb_dev = interface_to_usbdev(intf);
    698	struct kone_device *kone;
    699	int retval;
    700
    701	if (intf->cur_altsetting->desc.bInterfaceProtocol
    702			== USB_INTERFACE_PROTOCOL_MOUSE) {
    703
    704		kone = kzalloc(sizeof(*kone), GFP_KERNEL);
    705		if (!kone)
    706			return -ENOMEM;
    707		hid_set_drvdata(hdev, kone);
    708
    709		retval = kone_init_kone_device_struct(usb_dev, kone);
    710		if (retval) {
    711			hid_err(hdev, "couldn't init struct kone_device\n");
    712			goto exit_free;
    713		}
    714
    715		retval = roccat_connect(kone_class, hdev,
    716				sizeof(struct kone_roccat_report));
    717		if (retval < 0) {
    718			hid_err(hdev, "couldn't init char dev\n");
    719			/* be tolerant about not getting chrdev */
    720		} else {
    721			kone->roccat_claimed = 1;
    722			kone->chrdev_minor = retval;
    723		}
    724	} else {
    725		hid_set_drvdata(hdev, NULL);
    726	}
    727
    728	return 0;
    729exit_free:
    730	kfree(kone);
    731	return retval;
    732}
    733
    734static void kone_remove_specials(struct hid_device *hdev)
    735{
    736	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
    737	struct kone_device *kone;
    738
    739	if (intf->cur_altsetting->desc.bInterfaceProtocol
    740			== USB_INTERFACE_PROTOCOL_MOUSE) {
    741		kone = hid_get_drvdata(hdev);
    742		if (kone->roccat_claimed)
    743			roccat_disconnect(kone->chrdev_minor);
    744		kfree(hid_get_drvdata(hdev));
    745	}
    746}
    747
    748static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
    749{
    750	int retval;
    751
    752	if (!hid_is_usb(hdev))
    753		return -EINVAL;
    754
    755	retval = hid_parse(hdev);
    756	if (retval) {
    757		hid_err(hdev, "parse failed\n");
    758		goto exit;
    759	}
    760
    761	retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
    762	if (retval) {
    763		hid_err(hdev, "hw start failed\n");
    764		goto exit;
    765	}
    766
    767	retval = kone_init_specials(hdev);
    768	if (retval) {
    769		hid_err(hdev, "couldn't install mouse\n");
    770		goto exit_stop;
    771	}
    772
    773	return 0;
    774
    775exit_stop:
    776	hid_hw_stop(hdev);
    777exit:
    778	return retval;
    779}
    780
    781static void kone_remove(struct hid_device *hdev)
    782{
    783	kone_remove_specials(hdev);
    784	hid_hw_stop(hdev);
    785}
    786
    787/* handle special events and keep actual profile and dpi values up to date */
    788static void kone_keep_values_up_to_date(struct kone_device *kone,
    789		struct kone_mouse_event const *event)
    790{
    791	switch (event->event) {
    792	case kone_mouse_event_switch_profile:
    793		kone->actual_dpi = kone->profiles[event->value - 1].
    794				startup_dpi;
    795		fallthrough;
    796	case kone_mouse_event_osd_profile:
    797		kone->actual_profile = event->value;
    798		break;
    799	case kone_mouse_event_switch_dpi:
    800	case kone_mouse_event_osd_dpi:
    801		kone->actual_dpi = event->value;
    802		break;
    803	}
    804}
    805
    806static void kone_report_to_chrdev(struct kone_device const *kone,
    807		struct kone_mouse_event const *event)
    808{
    809	struct kone_roccat_report roccat_report;
    810
    811	switch (event->event) {
    812	case kone_mouse_event_switch_profile:
    813	case kone_mouse_event_switch_dpi:
    814	case kone_mouse_event_osd_profile:
    815	case kone_mouse_event_osd_dpi:
    816		roccat_report.event = event->event;
    817		roccat_report.value = event->value;
    818		roccat_report.key = 0;
    819		roccat_report_event(kone->chrdev_minor,
    820				(uint8_t *)&roccat_report);
    821		break;
    822	case kone_mouse_event_call_overlong_macro:
    823	case kone_mouse_event_multimedia:
    824		if (event->value == kone_keystroke_action_press) {
    825			roccat_report.event = event->event;
    826			roccat_report.value = kone->actual_profile;
    827			roccat_report.key = event->macro_key;
    828			roccat_report_event(kone->chrdev_minor,
    829					(uint8_t *)&roccat_report);
    830		}
    831		break;
    832	}
    833
    834}
    835
    836/*
    837 * Is called for keyboard- and mousepart.
    838 * Only mousepart gets informations about special events in its extended event
    839 * structure.
    840 */
    841static int kone_raw_event(struct hid_device *hdev, struct hid_report *report,
    842		u8 *data, int size)
    843{
    844	struct kone_device *kone = hid_get_drvdata(hdev);
    845	struct kone_mouse_event *event = (struct kone_mouse_event *)data;
    846
    847	/* keyboard events are always processed by default handler */
    848	if (size != sizeof(struct kone_mouse_event))
    849		return 0;
    850
    851	if (kone == NULL)
    852		return 0;
    853
    854	/*
    855	 * Firmware 1.38 introduced new behaviour for tilt and special buttons.
    856	 * Pressed button is reported in each movement event.
    857	 * Workaround sends only one event per press.
    858	 */
    859	if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5))
    860		memcpy(&kone->last_mouse_event, event,
    861				sizeof(struct kone_mouse_event));
    862	else
    863		memset(&event->wipe, 0, sizeof(event->wipe));
    864
    865	kone_keep_values_up_to_date(kone, event);
    866
    867	if (kone->roccat_claimed)
    868		kone_report_to_chrdev(kone, event);
    869
    870	return 0; /* always do further processing */
    871}
    872
    873static const struct hid_device_id kone_devices[] = {
    874	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
    875	{ }
    876};
    877
    878MODULE_DEVICE_TABLE(hid, kone_devices);
    879
    880static struct hid_driver kone_driver = {
    881		.name = "kone",
    882		.id_table = kone_devices,
    883		.probe = kone_probe,
    884		.remove = kone_remove,
    885		.raw_event = kone_raw_event
    886};
    887
    888static int __init kone_init(void)
    889{
    890	int retval;
    891
    892	/* class name has to be same as driver name */
    893	kone_class = class_create(THIS_MODULE, "kone");
    894	if (IS_ERR(kone_class))
    895		return PTR_ERR(kone_class);
    896	kone_class->dev_groups = kone_groups;
    897
    898	retval = hid_register_driver(&kone_driver);
    899	if (retval)
    900		class_destroy(kone_class);
    901	return retval;
    902}
    903
    904static void __exit kone_exit(void)
    905{
    906	hid_unregister_driver(&kone_driver);
    907	class_destroy(kone_class);
    908}
    909
    910module_init(kone_init);
    911module_exit(kone_exit);
    912
    913MODULE_AUTHOR("Stefan Achatz");
    914MODULE_DESCRIPTION("USB Roccat Kone driver");
    915MODULE_LICENSE("GPL v2");