[PATCH 1/2] platform/x86: bitland-mifs-wmi: Add sysfs controls for device status
Rsplwe <[email protected]>
| Newsgroups | org.kernel.vger.platform-driver-x86,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Add sysfs interfaces for controlling device status: Ambient Light, Fn Key Lock, TouchPad Lock. Add missing ambient light command/event definitions and updated documentation. Signed-off-by: Rsplwe <[email protected]> --- .../wmi/devices/bitland-mifs-wmi.rst | 4 + drivers/platform/x86/bitland-mifs-wmi.c | 166 +++++++++++++++++- 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/Documentation/wmi/devices/bitland-mifs-wmi.rst b/Documentation/wmi/devices/bitland-mifs-wmi.rst index 9e86ecc2993c..57c5e6e18132 100644 --- a/Documentation/wmi/devices/bitland-mifs-wmi.rst +++ b/Documentation/wmi/devices/bitland-mifs-wmi.rst @@ -109,6 +109,8 @@ The following Command IDs are used in the third byte of the buffer: | | | Bytes 6-7: GPU Fan RPM (Little Endian) | | | | Bytes 10-11: SYS Fan RPM (Little Endian) | +----------+-----------------------+------------------------------------------+ +| 15 | Ambient Light | 0: Off, 1: On | ++----------+-----------------------+------------------------------------------+ | 16 | RGBKeyboardMode | 0: Off, 1: Auto Cyclic, 2: Fixed, | | | | 3: Custom | +----------+-----------------------+------------------------------------------+ @@ -168,6 +170,8 @@ Note: reserved event ids are not listed there +----------+------------------------------------------------------------------+ | 9 | CapsLock state change | +----------+------------------------------------------------------------------+ +| 10 | Ambient Light state change | ++----------+------------------------------------------------------------------+ | 13 | NumLock state change | +----------+------------------------------------------------------------------+ | 14 | ScrollLock state change | diff --git a/drivers/platform/x86/bitland-mifs-wmi.c b/drivers/platform/x86/bitland-mifs-wmi.c index 3a373184519d..e2652d1a1bf7 100644 --- a/drivers/platform/x86/bitland-mifs-wmi.c +++ b/drivers/platform/x86/bitland-mifs-wmi.c @@ -50,6 +50,7 @@ enum bitland_mifs_function { WMI_FN_FN_LOCK = 11, WMI_FN_TP_LOCK = 12, WMI_FN_FAN_SPEEDS = 13, + WMI_FN_AMBIENT_LIGHT = 15, WMI_FN_RGB_KB_MODE = 16, WMI_FN_RGB_KB_COLOR = 17, WMI_FN_RGB_KB_BRIGHTNESS = 18, @@ -83,6 +84,7 @@ enum bitland_mifs_event_id { WMI_EVENT_FNLOCK_STATE = 7, WMI_EVENT_KBD_MODE = 8, WMI_EVENT_CAPSLOCK_STATE = 9, + WMI_EVENT_AMBIENTLIGHT_STATE = 10, WMI_EVENT_CALCULATOR_START = 11, WMI_EVENT_BROWSER_START = 12, WMI_EVENT_NUMLOCK_STATE = 13, @@ -143,6 +145,7 @@ enum bitland_notifier_actions { BITLAND_NOTIFY_KBD_BRIGHTNESS, BITLAND_NOTIFY_PLATFORM_PROFILE, BITLAND_NOTIFY_HWMON, + BITLAND_NOTIFY_SYSFS_STATE, }; struct bitland_fan_notify_data { @@ -568,6 +571,139 @@ static ssize_t kb_mode_store(struct device *dev, struct device_attribute *attr, return count; } +static int bitland_state_get(struct bitland_mifs_wmi_data *data, u8 function) +{ + struct bitland_mifs_input input = { + .reserved1 = 0, + .operation = WMI_METHOD_GET, + .reserved2 = 0, + }; + struct bitland_mifs_output res; + int ret; + + input.function = function; + + ret = bitland_mifs_wmi_call(data, &input, &res); + if (ret) + return ret; + + return res.data[0]; +} + +/* Switch states: 0:OFF, 1:ON */ +static ssize_t ambient_light_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct bitland_mifs_wmi_data *data = dev_get_drvdata(dev); + int state; + + state = bitland_state_get(data, WMI_FN_AMBIENT_LIGHT); + if (state < 0) + return state; + + return sysfs_emit(buf, "%d\n", state); +} + +static ssize_t ambient_light_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct bitland_mifs_wmi_data *data = dev_get_drvdata(dev); + struct bitland_mifs_input input = { + .reserved1 = 0, + .operation = WMI_METHOD_SET, + .reserved2 = 0, + .function = WMI_FN_AMBIENT_LIGHT, + }; + bool val; + int ret; + + if (kstrtobool(buf, &val)) + return -EINVAL; + + input.payload[0] = val; + + ret = bitland_mifs_wmi_call(data, &input, NULL); + if (ret) + return ret; + + return count; +} + +static ssize_t fn_lock_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct bitland_mifs_wmi_data *data = dev_get_drvdata(dev); + int state; + + state = bitland_state_get(data, WMI_FN_FN_LOCK); + if (state < 0) + return state; + + return sysfs_emit(buf, "%d\n", state); +} + +static ssize_t fn_lock_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct bitland_mifs_wmi_data *data = dev_get_drvdata(dev); + struct bitland_mifs_input input = { + .reserved1 = 0, + .operation = WMI_METHOD_SET, + .reserved2 = 0, + .function = WMI_FN_FN_LOCK, + }; + bool val; + int ret; + + if (kstrtobool(buf, &val)) + return -EINVAL; + + input.payload[0] = val; + + ret = bitland_mifs_wmi_call(data, &input, NULL); + if (ret) + return ret; + + return count; +} + +static ssize_t tp_lock_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct bitland_mifs_wmi_data *data = dev_get_drvdata(dev); + int state; + + state = bitland_state_get(data, WMI_FN_TP_LOCK); + if (state < 0) + return state; + + return sysfs_emit(buf, "%d\n", state); +} + +static ssize_t tp_lock_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct bitland_mifs_wmi_data *data = dev_get_drvdata(dev); + struct bitland_mifs_input input = { + .reserved1 = 0, + .operation = WMI_METHOD_SET, + .reserved2 = 0, + .function = WMI_FN_TP_LOCK, + }; + bool val; + int ret; + + if (kstrtobool(buf, &val)) + return -EINVAL; + + input.payload[0] = val; + + ret = bitland_mifs_wmi_call(data, &input, NULL); + if (ret) + return ret; + return count; +} + /* Fan Boost: 0:Normal, 1:Max Speed */ static ssize_t fan_boost_store(struct device *dev, struct device_attribute *attr, const char *buf, @@ -599,11 +735,17 @@ static ssize_t fan_boost_store(struct device *dev, static const DEVICE_ATTR_RW(gpu_mode); static const DEVICE_ATTR_RW(kb_mode); static const DEVICE_ATTR_WO(fan_boost); +static const DEVICE_ATTR_RW(ambient_light); +static const DEVICE_ATTR_RW(fn_lock); +static const DEVICE_ATTR_RW(tp_lock); static const struct attribute *const laptop_attrs[] = { &dev_attr_gpu_mode.attr, &dev_attr_kb_mode.attr, &dev_attr_fan_boost.attr, + &dev_attr_ambient_light.attr, + &dev_attr_fn_lock.attr, + &dev_attr_tp_lock.attr, NULL, }; ATTRIBUTE_GROUPS(laptop); @@ -653,6 +795,11 @@ static int bitland_notifier_callback(struct notifier_block *nb, hwmon_notify_event(data_ctx->hwmon_dev, hwmon_fan, hwmon_fan_input, fan_info->channel); break; + case BITLAND_NOTIFY_SYSFS_STATE: + const char *attr = data; + + sysfs_notify(&data_ctx->wdev->dev.kobj, NULL, attr); + break; } return NOTIFY_OK; @@ -798,8 +945,6 @@ static void bitland_mifs_wmi_notify(struct wmi_device *wdev, break; case WMI_EVENT_AIRPLANE_MODE: - case WMI_EVENT_TOUCHPAD_STATE: - case WMI_EVENT_FNLOCK_STATE: case WMI_EVENT_KBD_MODE: case WMI_EVENT_CAPSLOCK_STATE: case WMI_EVENT_NUMLOCK_STATE: @@ -810,6 +955,23 @@ static void bitland_mifs_wmi_notify(struct wmi_device *wdev, dev_dbg(&wdev->dev, "State change event: id=%d value=%d\n", event->event_id, event->value_low); break; + case WMI_EVENT_AMBIENTLIGHT_STATE: + blocking_notifier_call_chain(&bitland_notifier_list, + BITLAND_NOTIFY_SYSFS_STATE, + "ambient_light"); + break; + + case WMI_EVENT_TOUCHPAD_STATE: + blocking_notifier_call_chain(&bitland_notifier_list, + BITLAND_NOTIFY_SYSFS_STATE, + "tp_lock"); + break; + + case WMI_EVENT_FNLOCK_STATE: + blocking_notifier_call_chain(&bitland_notifier_list, + BITLAND_NOTIFY_SYSFS_STATE, + "fn_lock"); + break; default: dev_dbg(&wdev->dev, "Unknown event: id=0x%02x value=0x%02x\n", -- 2.55.0