drivers/hid/hid-gt683r.c

Source file repositories/reference/linux-study-clean/drivers/hid/hid-gt683r.c

File Facts

System
Linux kernel
Corpus path
drivers/hid/hid-gt683r.c
Extension
.c
Size
6428 bytes
Lines
311
Domain
Driver Families
Bucket
drivers/hid
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct gt683r_led {
	struct hid_device *hdev;
	struct led_classdev led_devs[GT683R_LED_COUNT];
	struct mutex lock;
	struct work_struct work;
	enum led_brightness brightnesses[GT683R_LED_COUNT];
	enum gt683r_led_mode mode;
};

static const struct hid_device_id gt683r_led_id[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
	{ }
};
MODULE_DEVICE_TABLE(hid, gt683r_led_id);

static void gt683r_brightness_set(struct led_classdev *led_cdev,
				enum led_brightness brightness)
{
	int i;
	struct device *dev = led_cdev->dev->parent;
	struct hid_device *hdev = to_hid_device(dev);
	struct gt683r_led *led = hid_get_drvdata(hdev);

	for (i = 0; i < GT683R_LED_COUNT; i++) {
		if (led_cdev == &led->led_devs[i])
			break;
	}

	if (i < GT683R_LED_COUNT) {
		led->brightnesses[i] = brightness;
		schedule_work(&led->work);
	}
}

static ssize_t mode_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	u8 sysfs_mode;
	struct hid_device *hdev = to_hid_device(dev->parent);
	struct gt683r_led *led = hid_get_drvdata(hdev);

	if (led->mode == GT683R_LED_NORMAL)
		sysfs_mode = 0;
	else if (led->mode == GT683R_LED_AUDIO)
		sysfs_mode = 1;
	else
		sysfs_mode = 2;

	return scnprintf(buf, PAGE_SIZE, "%u\n", sysfs_mode);
}

static ssize_t mode_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	u8 sysfs_mode;
	struct hid_device *hdev = to_hid_device(dev->parent);
	struct gt683r_led *led = hid_get_drvdata(hdev);


	if (kstrtou8(buf, 10, &sysfs_mode) || sysfs_mode > 2)
		return -EINVAL;

	mutex_lock(&led->lock);

	if (sysfs_mode == 0)
		led->mode = GT683R_LED_NORMAL;
	else if (sysfs_mode == 1)
		led->mode = GT683R_LED_AUDIO;
	else
		led->mode = GT683R_LED_BREATHING;

	mutex_unlock(&led->lock);
	schedule_work(&led->work);

	return count;
}

static int gt683r_led_snd_msg(struct gt683r_led *led, u8 *msg)
{
	int ret;

	ret = hid_hw_raw_request(led->hdev, msg[0], msg, GT683R_BUFFER_SIZE,
				HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
	if (ret != GT683R_BUFFER_SIZE) {
		hid_err(led->hdev,
			"failed to send set report request: %i\n", ret);
		if (ret < 0)
			return ret;

Annotation

Implementation Notes