linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pavel Machek <pavel@ucw.cz>
To: Pekka Paalanen <pekka.paalanen@haloniitty.fi>
Cc: Werner Sembach <wse@tuxedocomputers.com>,
	Hans de Goede <hdegoede@redhat.com>, Lee Jones <lee@kernel.org>,
	jikos@kernel.org, linux-kernel@vger.kernel.org,
	Jelle van der Waa <jelle@vdwaa.nl>,
	Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>,
	linux-input@vger.kernel.org, ojeda@kernel.org,
	linux-leds@vger.kernel.org
Subject: Keybaords with arrays of RGB LEDs was Re: Future handling of complex RGB devices on Linux v2
Date: Tue, 23 Jul 2024 22:40:22 +0200	[thread overview]
Message-ID: <ZqAVNmyFOEmR0Ilr@duo.ucw.cz> (raw)
In-Reply-To: <20240223105328.38d3f8da@eldfell>

[-- Attachment #1: Type: text/plain, Size: 9684 bytes --]

Hi!

So... I got two gaming keyboards. One is totally unusable (and it
looks LEDs are not controllable from the host), and the second one is
.. HyperX Elite RGB. Needs 2 USB connections, very buggy, probably
needs repair, and I'd not recomend it to anyone. But that one seems to
be usable for RGB keyboard development.

(Unusable one is
https://www.trust.com/en/product/23651-gxt-835-azor-illuminated-gaming-keyboard
Usable one is
0951:16be Kingston Technology HyperX Alloy Elite RGB
)

First step is to create some kind of driver, I believe. And I did
that, userland version works quite good, and I started hacking kernel
one. Version is below, and help would be welcome. Especially if
someone knows how to do the probing right (it binds 3 times, log
below). What is worse, loading this driver kills keyboard
functionality -- input is no longer possible. Is there simple way to
keep that functionality?

Best regards,
								Pavel

[ 9880.950973] input: HyperX Alloy Elite RGB HyperX Alloy Elite RGB System Control as /devices/p
ci0000:00/0000:00:1d.0/usb1/1-1/1-1:1.2/0003:0951:16BE.0045/input/input216
[ 9881.009994] input: HyperX Alloy Elite RGB HyperX Alloy Elite RGB Consumer Control as /devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1:1.2/0003:0951:16BE.0045/input/input217
[ 9881.013758] input: HyperX Alloy Elite RGB HyperX Alloy Elite RGB Keyboard as /devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1:1.2/0003:0951:16BE.0045/input/input219
[ 9881.014528] hid-generic 0003:0951:16BE.0045: input,hiddev96,hidraw2: USB HID v1.11 Mouse [HyperX Alloy Elite RGB HyperX Alloy Elite RGB] on usb-0000:00:1d.0-1/input2
[ 9886.017646] input: HyperX Alloy Elite RGB HyperX Alloy Elite RGB as /devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1:1.0/0003:0951:16BE.0043/input/input221
[ 9886.218066] hx 0003:0951:16BE.0043: input,hidraw0: USB HID v1.11 Keyboard [HyperX Alloy Elite RGB HyperX Alloy Elite RGB] on usb-0000:00:1d.0-1/input0
[ 9886.218088] Have device.
...
[ 9899.399088] input: HyperX Alloy Elite RGB HyperX Alloy Elite RGB as /devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1:1.1/0003:0951:16BE.0044/input/input222
[ 9899.537173] hx 0003:0951:16BE.0044: input,hidraw1: USB HID v1.11 Keyboard [HyperX Alloy Elite RGB HyperX Alloy Elite RGB] on usb-0000:00:1d.0-1/input1
[ 9899.537194] Have device.
...
[ 9912.691800] input: HyperX Alloy Elite RGB HyperX Alloy Elite RGB as /devices/pci0000:00/0000:
00:1d.0/usb1/1-1/1-1:1.2/0003:0951:16BE.0045/input/input223
[ 9912.751478] hx 0003:0951:16BE.0045: input,hiddev96,hidraw2: USB HID v1.11 Mouse [HyperX Alloy
 Elite RGB HyperX Alloy Elite RGB] on usb-0000:00:1d.0-1/input2
[ 9912.751502] Have device.


// SPDX-License-Identifier: GPL-2.0-or-later
/*
 */

#include <linux/device.h>
#include <linux/input.h>
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/hid-roccat.h>
#include <linux/usb.h>

struct hx_device {};

static unsigned char keys[] = {
	0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
	0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x21, 0x22,
	0x23, 0x24, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
	0x31, 0x32, 0x33, 0x34, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x41,
	0x44, 0x45, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x51, 0x54, 0x55,
	0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x61, 0x64, 0x65, 0x68, 0x69, 0x6A,
	0x6B, 0x6C, 0x6E, 0x6F, 0x74, 0x75, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
	0x7F, 0x81, 0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91,
	0x94, 0x95 };

struct hid_device *one_hdev;

static int set_direct_color(struct hid_device *hdev, int color, int val)
{
	const int s = 264;
	unsigned char *buf = kmalloc(s, GFP_KERNEL);
	int i, ret;

	/* Zero out buffer */
	memset(buf, 0x00, s);

	/* Set up Direct packet */
	for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
		buf[keys[i]] = val;
	}

	buf[0x00] = 0x07;
	buf[0x01] = 0x16; // HYPERX_ALLOY_ELITE_PACKET_ID_DIRECT
	buf[0x02] = color; // HYPERX_ALLOY_ELITE_COLOR_CHANNEL_GREEN
	buf[0x03] = 0xA0;

	ret = hid_hw_power(hdev, PM_HINT_FULLON);
	if (ret) {
		hid_err(hdev, "Failed to power on HID device\n");
		return ret;
	}

	// ioctl(3, HIDIOCSFEATURE(264), 0xbfce5974) = 264
	// -> hidraw_send_report(file, user_arg, len, HID_FEATURE_REPORT);
	//
	printk(KERN_INFO "Set feature report -- direct\n");
	i = hid_hw_raw_request(hdev, buf[0], buf, s, HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
	printk("raw: %d, einval %d, eagain %d\n", i, -EINVAL, -EAGAIN);
	msleep(100);
	return 0;
}

#define SIZE 128
const int real_size = SIZE;

static ssize_t hx_sysfs_read(struct file *fp, struct kobject *kobj,
			       struct bin_attribute * b,
			      char *buf, loff_t off, size_t count)
{
	struct device *dev = kobj_to_dev(kobj);
	struct hx_device *hx = hid_get_drvdata(dev_get_drvdata(dev));
	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
	int retval;

	if (off >= real_size)
		return 0;

	if (off != 0 || count != real_size)
		return -EINVAL;
	
	printk("read\n");
	set_direct_color(one_hdev, 2, 0xff);

	return retval ? retval : real_size;
}

static ssize_t hx_sysfs_write(struct file *fp, struct kobject *kobj,
			       struct bin_attribute * b,
		void const *buf, loff_t off, size_t count)
{
	struct device *dev = kobj_to_dev(kobj);
	struct hx_device *hx = hid_get_drvdata(dev_get_drvdata(dev));
	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
	int retval;

	if (off != 0 || count != real_size)
		return -EINVAL;

	printk("Write\n");

	return retval ? retval : real_size;
}

static struct bin_attribute hx_control_attr = { \
  .attr = { .name = "thingy", .mode = 0660 },		\
	.size = SIZE, \
	.read = hx_sysfs_read, \
};

static int hx_create_sysfs_attributes(struct usb_interface *intf)
{
  return sysfs_create_bin_file(&intf->dev.kobj, &hx_control_attr);
}

static void hx_remove_sysfs_attributes(struct usb_interface *intf)
{
  sysfs_remove_bin_file(&intf->dev.kobj, &hx_control_attr);
}

static int hx_init_hx_device_struct(struct usb_device *usb_dev,
		struct hx_device *hx)
{
	//mutex_init(&hx->hx_lock);
	return 0;
}

static int hx_init_specials(struct hid_device *hdev)
{
	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
	struct usb_device *usb_dev = interface_to_usbdev(intf);
	struct hx_device *hx;
	int retval;

	hx = kzalloc(sizeof(*hx), GFP_KERNEL);
	if (!hx) {
		hid_err(hdev, "can't alloc device descriptor\n");
		return -ENOMEM;
	}
	hid_set_drvdata(hdev, hx);

	retval = hx_create_sysfs_attributes(intf);
	if (retval) {
		hid_err(hdev, "cannot create sysfs files\n");
		goto exit;
	}

	return 0;
exit:
	kfree(hx);
	return retval;
}

static void hx_remove_specials(struct hid_device *hdev)
{
	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
	struct hx_device *hx;

	hx_remove_sysfs_attributes(intf);

	hx = hid_get_drvdata(hdev);
	kfree(hx);
}

static int num;

static int hx_probe(struct hid_device *hdev,
		const struct hid_device_id *id)
{
	int retval;

	if (!hid_is_usb(hdev))
		return -EINVAL;

	if (++num != 2)
		return -EINVAL;

	retval = hid_parse(hdev);
	if (retval) {
		hid_err(hdev, "parse failed\n");
		goto exit;
	}

	retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (retval) {
		hid_err(hdev, "hw start failed\n");
		goto exit;
	}

	printk("Have device.\n");

	if (!hid_is_usb(hdev)) {
		printk("Not an usb?\n");
	}

	{
		struct usb_interface *interface = to_usb_interface(hdev->dev.parent);
		struct usb_device *dev = interface_to_usbdev(interface);
		struct usb_host_interface *iface_desc;
		struct usb_endpoint_descriptor *endpoint;
		char manufacturer[128];
		char product[128];

		// Retrieve manufacturer string
		retval = usb_string(dev, dev->descriptor.iManufacturer, manufacturer, sizeof(manufacturer));
		if (retval > 0)
			printk(KERN_INFO "Manufacturer: %s\n", manufacturer);
		else
			printk(KERN_ERR "Failed to get manufacturer string\n");

		// Retrieve product string
		retval = usb_string(dev, dev->descriptor.iProduct, product, sizeof(product));
		if (retval > 0)
			printk(KERN_INFO "Product: %s\n", product);
		else
			printk(KERN_ERR "Failed to get product string\n");

	}

	retval = hx_init_specials(hdev);
	if (retval) {
		hid_err(hdev, "couldn't install mouse\n");
		goto exit_stop;
	}

	// Example call to set_direct_color function
	for (int i=0; i<20; i++) {
		set_direct_color(hdev, 0x01, 0); // Example values
		set_direct_color(hdev, 0x02, 0); // Example values
		set_direct_color(hdev, 0x03, 0); // Example values
		set_direct_color(hdev, 0x01, 0xFF); // Example values
		set_direct_color(hdev, 0x02, 0xFF); // Example values
		set_direct_color(hdev, 0x03, 0xFF); // Example values
	}
	one_hdev = hdev;
	return 0;

exit_stop:
	hid_hw_stop(hdev);
exit:
	return retval;
}

static void hx_remove(struct hid_device *hdev)
{
	hx_remove_specials(hdev);
	hid_hw_stop(hdev);
}

static const struct hid_device_id hx_devices[] = {
	{ HID_USB_DEVICE(0x0951, 0x16be) },
	{ }
};

MODULE_DEVICE_TABLE(hid, hx_devices);

static struct hid_driver hx_driver = {
	.name = "hx",
	.id_table = hx_devices,
	.probe = hx_probe,
	.remove = hx_remove
};
module_hid_driver(hx_driver);

MODULE_AUTHOR("Pavel Machek");
MODULE_DESCRIPTION("USB HyperX elite backlight driver");
MODULE_LICENSE("GPL v2");


-- 
People of Russia, stop Putin before his war on Ukraine escalates.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

  reply	other threads:[~2024-07-23 20:40 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20231011190017.1230898-1-wse@tuxedocomputers.com>
     [not found] ` <ZSe1GYLplZo5fsAe@duo.ucw.cz>
     [not found]   ` <0440ed38-c53b-4aa1-8899-969e5193cfef@tuxedocomputers.com>
     [not found]     ` <ZSf9QneKO/8IzWhd@duo.ucw.cz>
     [not found]       ` <a244a00d-6be4-44bc-9d41-6f9df14de8ee@tuxedocomputers.com>
     [not found]         ` <ZSk16iTBmZ2fLHZ0@duo.ucw.cz>
2023-10-13 14:54           ` Implement per-key keyboard backlight as auxdisplay? Werner Sembach
2023-10-13 19:56             ` Pavel Machek
2023-10-13 20:03               ` Pavel Machek
2023-10-16 10:57               ` Miguel Ojeda
2023-10-23 11:40                 ` Jani Nikula
2023-10-23 11:44                   ` Miguel Ojeda
2023-11-20 20:53                     ` Pavel Machek
2023-11-20 20:52                   ` Pavel Machek
2023-11-21 11:33                     ` Werner Sembach
2023-11-21 12:20                       ` Hans de Goede
2023-11-21 13:29                         ` Werner Sembach
2023-11-22 18:34                           ` Hans de Goede
2023-11-27 10:59                             ` Werner Sembach
2023-12-29 19:13                               ` Werner Sembach
2024-01-17 15:26                               ` Hans de Goede
2024-01-17 16:50                               ` Userspace API for per key backlight for non HID (no hidraw) keyboards Hans de Goede
2024-01-17 19:03                                 ` Armin Wolf
2024-01-18  0:58                                   ` Werner Sembach
2024-01-18 17:45                               ` Implement per-key keyboard backlight as auxdisplay? Pavel Machek
2024-01-18 22:32                                 ` Werner Sembach
2024-01-19  8:44                                 ` Hans de Goede
2024-01-19 10:51                                   ` Jani Nikula
2024-01-19 16:06                                     ` Werner Sembach
2024-01-19 18:33                                     ` Dmitry Torokhov
2024-01-19 22:14                                       ` Pavel Machek
2024-01-23 16:51                                         ` Werner Sembach
2024-01-19 16:04                                   ` Werner Sembach
2024-01-29 13:24                                     ` Hans de Goede
2024-01-30 11:12                                       ` Werner Sembach
2024-01-30 17:10                                         ` Hans de Goede
2024-01-30 18:09                                           ` Werner Sembach
2024-01-30 18:35                                             ` Hans de Goede
2024-01-30 19:08                                               ` Werner Sembach
2024-01-30 19:46                                                 ` Hans de Goede
2024-01-31 11:41                                                   ` Future handling of complex RGB devices on Linux Werner Sembach
2024-01-31 15:52                                                     ` Roderick Colenbrander
2024-02-21 11:12                                                     ` Future handling of complex RGB devices on Linux v2 Werner Sembach
2024-02-21 22:17                                                       ` Pavel Machek
2024-02-22  9:04                                                         ` Pekka Paalanen
2024-02-22 17:38                                                           ` Pavel Machek
2024-02-23  8:53                                                             ` Pekka Paalanen
2024-07-23 20:40                                                               ` Pavel Machek [this message]
2024-02-23  9:21                                                             ` Thomas Zimmermann
2024-02-22 10:46                                                         ` Hans de Goede
2024-02-22 11:38                                                           ` Gregor Riepl
2024-02-22 12:39                                                             ` Hans de Goede
2024-02-22 13:14                                                               ` Future handling of complex RGB devices on Linux v3 Werner Sembach
2024-03-18 11:11                                                                 ` Hans de Goede
2024-03-19 15:18                                                                   ` Werner Sembach
2024-03-25 14:18                                                                     ` Hans de Goede
2024-03-25 17:01                                                                       ` Werner Sembach
2024-03-20 11:16                                                                 ` Werner Sembach
2024-03-20 11:33                                                                   ` Werner Sembach
2024-03-20 18:45                                                                     ` Werner Sembach
2024-03-25 14:25                                                                   ` In kernel virtual HID devices (was Future handling of complex RGB devices on Linux v3) Hans de Goede
2024-03-25 15:56                                                                     ` Benjamin Tissoires
2024-03-25 16:48                                                                       ` Werner Sembach
2024-03-25 18:30                                                                         ` Hans de Goede
2024-03-26  7:57                                                                           ` Werner Sembach
2024-03-26 15:39                                                                             ` Benjamin Tissoires
2024-03-26 16:57                                                                               ` Werner Sembach
2024-03-27 11:03                                                                                 ` Benjamin Tissoires
2024-03-28 23:52                                                                                   ` Werner Sembach
2024-03-27 11:01                                                                               ` Hans de Goede
2024-07-24 17:36                                                                         ` Pavel Machek
2024-07-24 21:08                                                                           ` Werner Sembach
2024-03-25 18:38                                                                     ` Miguel Ojeda
2024-04-09 13:33                                                                       ` Andy Shevchenko
2024-02-22 17:42                                                               ` Future handling of complex RGB devices on Linux v2 Pavel Machek
2024-02-22 17:52                                                               ` Pavel Machek
2024-02-22 17:23                                                           ` Pavel Machek
2024-02-23  8:33                                                         ` Werner Sembach
2024-01-19 20:15                                   ` Implement per-key keyboard backlight as auxdisplay? Pavel Machek
2024-01-19 20:22                                     ` Werner Sembach
2024-01-19 20:32                                       ` Pavel Machek
2024-01-29 13:24                                     ` Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZqAVNmyFOEmR0Ilr@duo.ucw.cz \
    --to=pavel@ucw.cz \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hdegoede@redhat.com \
    --cc=jelle@vdwaa.nl \
    --cc=jikos@kernel.org \
    --cc=lee@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=miguel.ojeda.sandonis@gmail.com \
    --cc=ojeda@kernel.org \
    --cc=pekka.paalanen@haloniitty.fi \
    --cc=wse@tuxedocomputers.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).