Further modularize drivers incl. probe/remove

This commit is contained in:
Christoffer Sandberg 2020-05-28 18:35:46 +02:00
parent bc9a14328c
commit 955c683971
No known key found for this signature in database
GPG key ID: BF563F71B6C7A96D
3 changed files with 142 additions and 115 deletions

View file

@ -70,7 +70,7 @@
#define WMI_KEYEVENT_CODE_RFKILL1 0x85 #define WMI_KEYEVENT_CODE_RFKILL1 0x85
#define WMI_KEYEVENT_CODE_RFKILL2 0x86 #define WMI_KEYEVENT_CODE_RFKILL2 0x86
static const struct key_entry clevo_wmi_keymap[] = { static struct key_entry clevo_wmi_keymap[] = {
// Keyboard backlight (RGB versions) // Keyboard backlight (RGB versions)
{ KE_KEY, WMI_KEYEVENT_CODE_DECREASE_BACKLIGHT, { KEY_KBDILLUMDOWN } }, { KE_KEY, WMI_KEYEVENT_CODE_DECREASE_BACKLIGHT, { KEY_KBDILLUMDOWN } },
{ KE_KEY, WMI_KEYEVENT_CODE_INCREASE_BACKLIGHT, { KEY_KBDILLUMUP } }, { KE_KEY, WMI_KEYEVENT_CODE_INCREASE_BACKLIGHT, { KEY_KBDILLUMUP } },
@ -615,12 +615,33 @@ static void tuxedo_wmi_notify(u32 value, void *context)
} }
} }
// Sysfs attribute file permissions and method linking
static DEVICE_ATTR(state, 0644, show_state_fs, set_state_fs);
static DEVICE_ATTR(color_left, 0644, show_color_left_fs, set_color_left_fs);
static DEVICE_ATTR(color_center, 0644, show_color_center_fs,
set_color_center_fs);
static DEVICE_ATTR(color_right, 0644, show_color_right_fs, set_color_right_fs);
static DEVICE_ATTR(color_extra, 0644, show_color_extra_fs, set_color_extra_fs);
static DEVICE_ATTR(brightness, 0644, show_brightness_fs, set_brightness_fs);
static DEVICE_ATTR(mode, 0644, show_blinking_patterns_fs, set_blinking_pattern_fs);
static DEVICE_ATTR(extra, 0444, show_hasextra_fs, NULL);
static int tuxedo_wmi_probe(struct platform_device *dev) static int tuxedo_wmi_probe(struct platform_device *dev)
{ {
int status = wmi_install_notify_handler(CLEVO_EVENT_GUID, int status, err;
tuxedo_wmi_notify, NULL);
TUXEDO_DEBUG("tuxedo_wmi_probe status: (%0#6x)", status); if (!wmi_has_guid(CLEVO_EVENT_GUID)) {
TUXEDO_ERROR("No known WMI event notification GUID found\n");
return -ENODEV;
}
if (!wmi_has_guid(CLEVO_GET_GUID)) {
TUXEDO_ERROR("No known WMI control method GUID found\n");
return -ENODEV;
}
status = wmi_install_notify_handler(CLEVO_EVENT_GUID, tuxedo_wmi_notify,
NULL);
if (unlikely(ACPI_FAILURE(status))) { if (unlikely(ACPI_FAILURE(status))) {
TUXEDO_ERROR("Could not register WMI notify handler (%0#6x)\n", TUXEDO_ERROR("Could not register WMI notify handler (%0#6x)\n",
@ -628,14 +649,98 @@ static int tuxedo_wmi_probe(struct platform_device *dev)
return -EIO; return -EIO;
} }
// Enable WMI events
evaluate_wmi_method_clevo(WMI_SUBMETHOD_ID_GET_AP, 0, NULL); evaluate_wmi_method_clevo(WMI_SUBMETHOD_ID_GET_AP, 0, NULL);
// Setup sysfs
if (device_create_file(&dev->dev, &dev_attr_state) != 0) {
TUXEDO_ERROR("Sysfs attribute file creation failed for state\n");
}
if (device_create_file
(&dev->dev, &dev_attr_color_left) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for color left\n");
}
if (device_create_file
(&dev->dev, &dev_attr_color_center) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for color center\n");
}
if (device_create_file
(&dev->dev, &dev_attr_color_right) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for color right\n");
}
if (set_color(REGION_EXTRA, KB_COLOR_DEFAULT) != 0) {
TUXEDO_DEBUG("Keyboard does not support EXTRA Color");
kbd_led_state.has_extra = 0;
} else {
kbd_led_state.has_extra = 1;
if (device_create_file
(&dev->dev,
&dev_attr_color_extra) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for color extra\n");
}
set_color(REGION_EXTRA, param_color_extra);
}
if (device_create_file(&dev->dev, &dev_attr_extra) !=
0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for extra information flag\n");
}
if (device_create_file(&dev->dev, &dev_attr_mode) !=
0) {
TUXEDO_ERROR("Sysfs attribute file creation failed for blinking pattern\n");
}
if (device_create_file
(&dev->dev, &dev_attr_brightness) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for brightness\n");
}
// Set state variables
kbd_led_state.color.left = param_color_left;
kbd_led_state.color.center = param_color_center;
kbd_led_state.color.right = param_color_right;
kbd_led_state.color.extra = param_color_extra;
// Write state
set_color(REGION_LEFT, param_color_left);
set_color(REGION_CENTER, param_color_center);
set_color(REGION_RIGHT, param_color_right);
set_blinking_pattern(param_blinking_pattern);
set_brightness(param_brightness);
set_enabled(param_state);
return 0; return 0;
} }
static int tuxedo_wmi_remove(struct platform_device *dev) static int tuxedo_wmi_remove(struct platform_device *dev)
{ {
wmi_remove_notify_handler(CLEVO_EVENT_GUID); wmi_remove_notify_handler(CLEVO_EVENT_GUID);
device_remove_file(&dev->dev, &dev_attr_state);
device_remove_file(&dev->dev, &dev_attr_color_left);
device_remove_file(&dev->dev, &dev_attr_color_center);
device_remove_file(&dev->dev, &dev_attr_color_right);
device_remove_file(&dev->dev, &dev_attr_extra);
device_remove_file(&dev->dev, &dev_attr_mode);
device_remove_file(&dev->dev, &dev_attr_brightness);
if (kbd_led_state.has_extra == 1) {
device_remove_file(&dev->dev, &dev_attr_color_extra);
}
return 0; return 0;
} }
@ -673,13 +778,8 @@ static struct platform_driver platform_driver_clevo = {
}, },
}; };
// Sysfs attribute file permissions and method linking struct tuxedo_keyboard_driver clevo_keyboard_driver = {
static DEVICE_ATTR(state, 0644, show_state_fs, set_state_fs); .platform_driver = &platform_driver_clevo,
static DEVICE_ATTR(color_left, 0644, show_color_left_fs, set_color_left_fs); .probe = tuxedo_wmi_probe,
static DEVICE_ATTR(color_center, 0644, show_color_center_fs, .key_map = clevo_wmi_keymap,
set_color_center_fs); };
static DEVICE_ATTR(color_right, 0644, show_color_right_fs, set_color_right_fs);
static DEVICE_ATTR(color_extra, 0644, show_color_extra_fs, set_color_extra_fs);
static DEVICE_ATTR(brightness, 0644, show_brightness_fs, set_brightness_fs);
static DEVICE_ATTR(mode, 0644, show_blinking_patterns_fs, set_blinking_pattern_fs);
static DEVICE_ATTR(extra, 0444, show_hasextra_fs, NULL);

View file

@ -39,7 +39,7 @@ MODULE_VERSION("2.0.4");
MODULE_ALIAS("wmi:" CLEVO_EVENT_GUID); MODULE_ALIAS("wmi:" CLEVO_EVENT_GUID);
MODULE_ALIAS("wmi:" CLEVO_GET_GUID); MODULE_ALIAS("wmi:" CLEVO_GET_GUID);
static int __init tuxedo_input_init(const struct key_entry key_map[]) static int tuxedo_input_init(const struct key_entry key_map[])
{ {
int err; int err;
@ -92,100 +92,31 @@ static int __init tuxdeo_keyboard_init(void)
{ {
int err; int err;
if (!wmi_has_guid(CLEVO_EVENT_GUID)) {
TUXEDO_ERROR("No known WMI event notification GUID found\n");
return -ENODEV;
}
if (!wmi_has_guid(CLEVO_GET_GUID)) {
TUXEDO_ERROR("No known WMI control method GUID found\n");
return -ENODEV;
}
TUXEDO_INFO("Model '%s' found\n", TUXEDO_INFO("Model '%s' found\n",
dmi_get_system_info(DMI_PRODUCT_NAME)); dmi_get_system_info(DMI_PRODUCT_NAME));
// Attempt to load each available driver
// Associated probe decides if it fits
// Driver from first successful probe is used
tuxedo_platform_device = tuxedo_platform_device =
platform_create_bundle(&platform_driver_clevo, tuxedo_wmi_probe, platform_create_bundle(clevo_keyboard_driver.platform_driver,
NULL, 0, NULL, 0); clevo_keyboard_driver.probe, NULL, 0,
NULL, 0);
if (unlikely(IS_ERR(tuxedo_platform_device))) { if (IS_ERR(tuxedo_platform_device)) {
TUXEDO_ERROR("Can not init Platform driver"); TUXEDO_ERROR("No matching hardware found\n");
return PTR_ERR(tuxedo_platform_device); return -ENODEV;
} else {
current_driver = &clevo_keyboard_driver;
} }
err = tuxedo_input_init(clevo_wmi_keymap); if (current_driver->key_map != NULL) {
err = tuxedo_input_init(current_driver->key_map);
if (unlikely(err)) { if (unlikely(err)) {
TUXEDO_ERROR("Could not register input device\n"); TUXEDO_ERROR("Could not register input device\n");
} }
if (device_create_file(&tuxedo_platform_device->dev, &dev_attr_state) != 0) {
TUXEDO_ERROR("Sysfs attribute file creation failed for state\n");
} }
if (device_create_file
(&tuxedo_platform_device->dev, &dev_attr_color_left) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for color left\n");
}
if (device_create_file
(&tuxedo_platform_device->dev, &dev_attr_color_center) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for color center\n");
}
if (device_create_file
(&tuxedo_platform_device->dev, &dev_attr_color_right) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for color right\n");
}
if (set_color(REGION_EXTRA, KB_COLOR_DEFAULT) != 0) {
TUXEDO_DEBUG("Keyboard does not support EXTRA Color");
kbd_led_state.has_extra = 0;
} else {
kbd_led_state.has_extra = 1;
if (device_create_file
(&tuxedo_platform_device->dev,
&dev_attr_color_extra) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for color extra\n");
}
set_color(REGION_EXTRA, param_color_extra);
}
if (device_create_file(&tuxedo_platform_device->dev, &dev_attr_extra) !=
0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for extra information flag\n");
}
if (device_create_file(&tuxedo_platform_device->dev, &dev_attr_mode) !=
0) {
TUXEDO_ERROR("Sysfs attribute file creation failed for blinking pattern\n");
}
if (device_create_file
(&tuxedo_platform_device->dev, &dev_attr_brightness) != 0) {
TUXEDO_ERROR
("Sysfs attribute file creation failed for brightness\n");
}
kbd_led_state.color.left = param_color_left;
kbd_led_state.color.center = param_color_center;
kbd_led_state.color.right = param_color_right;
kbd_led_state.color.extra = param_color_extra;
set_color(REGION_LEFT, param_color_left);
set_color(REGION_CENTER, param_color_center);
set_color(REGION_RIGHT, param_color_right);
set_blinking_pattern(param_blinking_pattern);
set_brightness(param_brightness);
set_enabled(param_state);
return 0; return 0;
} }
@ -193,23 +124,9 @@ static void __exit tuxdeo_keyboard_exit(void)
{ {
tuxedo_input_exit(); tuxedo_input_exit();
device_remove_file(&tuxedo_platform_device->dev, &dev_attr_state);
device_remove_file(&tuxedo_platform_device->dev, &dev_attr_color_left);
device_remove_file(&tuxedo_platform_device->dev,
&dev_attr_color_center);
device_remove_file(&tuxedo_platform_device->dev, &dev_attr_color_right);
device_remove_file(&tuxedo_platform_device->dev, &dev_attr_extra);
device_remove_file(&tuxedo_platform_device->dev, &dev_attr_mode);
device_remove_file(&tuxedo_platform_device->dev, &dev_attr_brightness);
if (kbd_led_state.has_extra == 1) {
device_remove_file(&tuxedo_platform_device->dev,
&dev_attr_color_extra);
}
platform_device_unregister(tuxedo_platform_device); platform_device_unregister(tuxedo_platform_device);
platform_driver_unregister(&platform_driver_clevo); platform_driver_unregister(current_driver->platform_driver);
TUXEDO_DEBUG("exit"); TUXEDO_DEBUG("exit");
} }

View file

@ -28,9 +28,19 @@
#define TUXEDO_ERROR(fmt, ...) __TUXEDO_PR(err, fmt, ##__VA_ARGS__) #define TUXEDO_ERROR(fmt, ...) __TUXEDO_PR(err, fmt, ##__VA_ARGS__)
#define TUXEDO_DEBUG(fmt, ...) __TUXEDO_PR(debug, "[%s:%u] " fmt, __func__, __LINE__, ##__VA_ARGS__) #define TUXEDO_DEBUG(fmt, ...) __TUXEDO_PR(debug, "[%s:%u] " fmt, __func__, __LINE__, ##__VA_ARGS__)
struct tuxedo_keyboard_driver {
struct platform_driver *platform_driver;
int (*probe)(struct platform_device *);
struct key_entry *key_map;
};
// Global module devices
static struct platform_device *tuxedo_platform_device; static struct platform_device *tuxedo_platform_device;
static struct input_dev *tuxedo_input_device; static struct input_dev *tuxedo_input_device;
// Currently chosen driver
static struct tuxedo_keyboard_driver *current_driver;
/** /**
* Basically a copy of the existing report event but doesn't report unknown events * Basically a copy of the existing report event but doesn't report unknown events
*/ */