drivers/hid/hid-appletb-kbd.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hid/hid-appletb-kbd.c
Extension
.c
Size
14368 bytes
Lines
533
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 appletb_kbd {
	struct hid_field *mode_field;
	struct input_handler inp_handler;
	struct input_handle kbd_handle;
	struct input_handle tpd_handle;
	struct backlight_device *backlight_dev;
	struct delayed_work inactivity_work;
	struct work_struct restore_brightness_work;
	bool has_dimmed;
	bool has_turned_off;
	u8 saved_mode;
	u8 current_mode;
};

static const struct key_entry appletb_kbd_keymap[] = {
	{ KE_KEY, KEY_ESC, { KEY_ESC } },
	{ KE_KEY, KEY_F1,  { KEY_BRIGHTNESSDOWN } },
	{ KE_KEY, KEY_F2,  { KEY_BRIGHTNESSUP } },
	{ KE_KEY, KEY_F3,  { KEY_RESERVED } },
	{ KE_KEY, KEY_F4,  { KEY_RESERVED } },
	{ KE_KEY, KEY_F5,  { KEY_KBDILLUMDOWN } },
	{ KE_KEY, KEY_F6,  { KEY_KBDILLUMUP } },
	{ KE_KEY, KEY_F7,  { KEY_PREVIOUSSONG } },
	{ KE_KEY, KEY_F8,  { KEY_PLAYPAUSE } },
	{ KE_KEY, KEY_F9,  { KEY_NEXTSONG } },
	{ KE_KEY, KEY_F10, { KEY_MUTE } },
	{ KE_KEY, KEY_F11, { KEY_VOLUMEDOWN } },
	{ KE_KEY, KEY_F12, { KEY_VOLUMEUP } },
	{ KE_END, 0 }
};

static int appletb_kbd_set_mode(struct appletb_kbd *kbd, u8 mode)
{
	struct hid_report *report = kbd->mode_field->report;
	struct hid_device *hdev = report->device;
	int ret;

	ret = hid_hw_power(hdev, PM_HINT_FULLON);
	if (ret) {
		hid_err(hdev, "Device didn't resume (%pe)\n", ERR_PTR(ret));
		return ret;
	}

	ret = hid_set_field(kbd->mode_field, 0, mode);
	if (ret) {
		hid_err(hdev, "Failed to set mode field to %u (%pe)\n", mode, ERR_PTR(ret));
		goto power_normal;
	}

	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);

	kbd->current_mode = mode;

power_normal:
	hid_hw_power(hdev, PM_HINT_NORMAL);

	return ret;
}

static ssize_t mode_show(struct device *dev,
			 struct device_attribute *attr, char *buf)
{
	struct appletb_kbd *kbd = dev_get_drvdata(dev);

	return sysfs_emit(buf, "%d\n", kbd->current_mode);
}

static ssize_t mode_store(struct device *dev,
			  struct device_attribute *attr,
			  const char *buf, size_t size)
{
	struct appletb_kbd *kbd = dev_get_drvdata(dev);
	u8 mode;
	int ret;

	ret = kstrtou8(buf, 0, &mode);
	if (ret)
		return ret;

	if (mode > APPLETB_KBD_MODE_MAX)
		return -EINVAL;

	ret = appletb_kbd_set_mode(kbd, mode);

	return ret < 0 ? ret : size;
}
static DEVICE_ATTR_RW(mode);

static struct attribute *appletb_kbd_attrs[] = {
	&dev_attr_mode.attr,

Annotation

Implementation Notes