| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for Dell laptop extras |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) Red Hat <mjg@redhat.com> |
|---|
| 5 | 6 | * Copyright (c) 2014 Gabriele Mazzotta <gabriele.mzt@gmail.com> |
|---|
| 6 | | - * Copyright (c) 2014 Pali Rohár <pali.rohar@gmail.com> |
|---|
| 7 | + * Copyright (c) 2014 Pali Rohár <pali@kernel.org> |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * Based on documentation in the libsmbios package: |
|---|
| 9 | 10 | * Copyright (C) 2005-2014 Dell Inc. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 12 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 13 | | - * published by the Free Software Foundation. |
|---|
| 14 | 11 | */ |
|---|
| 15 | 12 | |
|---|
| 16 | 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 29 | 26 | #include <linux/mm.h> |
|---|
| 30 | 27 | #include <linux/i8042.h> |
|---|
| 31 | 28 | #include <linux/debugfs.h> |
|---|
| 32 | | -#include <linux/dell-led.h> |
|---|
| 33 | 29 | #include <linux/seq_file.h> |
|---|
| 34 | 30 | #include <acpi/video.h> |
|---|
| 35 | 31 | #include "dell-rbtn.h" |
|---|
| .. | .. |
|---|
| 1591 | 1587 | switch (unit) { |
|---|
| 1592 | 1588 | case KBD_TIMEOUT_DAYS: |
|---|
| 1593 | 1589 | value *= 24; |
|---|
| 1590 | + fallthrough; |
|---|
| 1594 | 1591 | case KBD_TIMEOUT_HOURS: |
|---|
| 1595 | 1592 | value *= 60; |
|---|
| 1593 | + fallthrough; |
|---|
| 1596 | 1594 | case KBD_TIMEOUT_MINUTES: |
|---|
| 1597 | 1595 | value *= 60; |
|---|
| 1598 | 1596 | unit = KBD_TIMEOUT_SECONDS; |
|---|
| .. | .. |
|---|
| 2135 | 2133 | .notifier_call = dell_laptop_notifier_call, |
|---|
| 2136 | 2134 | }; |
|---|
| 2137 | 2135 | |
|---|
| 2138 | | -int dell_micmute_led_set(int state) |
|---|
| 2136 | +static int micmute_led_set(struct led_classdev *led_cdev, |
|---|
| 2137 | + enum led_brightness brightness) |
|---|
| 2139 | 2138 | { |
|---|
| 2140 | 2139 | struct calling_interface_buffer buffer; |
|---|
| 2141 | 2140 | struct calling_interface_token *token; |
|---|
| 2141 | + int state = brightness != LED_OFF; |
|---|
| 2142 | 2142 | |
|---|
| 2143 | 2143 | if (state == 0) |
|---|
| 2144 | 2144 | token = dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE); |
|---|
| 2145 | | - else if (state == 1) |
|---|
| 2146 | | - token = dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE); |
|---|
| 2147 | 2145 | else |
|---|
| 2148 | | - return -EINVAL; |
|---|
| 2146 | + token = dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE); |
|---|
| 2149 | 2147 | |
|---|
| 2150 | 2148 | if (!token) |
|---|
| 2151 | 2149 | return -ENODEV; |
|---|
| .. | .. |
|---|
| 2153 | 2151 | dell_fill_request(&buffer, token->location, token->value, 0, 0); |
|---|
| 2154 | 2152 | dell_send_request(&buffer, CLASS_TOKEN_WRITE, SELECT_TOKEN_STD); |
|---|
| 2155 | 2153 | |
|---|
| 2156 | | - return state; |
|---|
| 2154 | + return 0; |
|---|
| 2157 | 2155 | } |
|---|
| 2158 | | -EXPORT_SYMBOL_GPL(dell_micmute_led_set); |
|---|
| 2156 | + |
|---|
| 2157 | +static struct led_classdev micmute_led_cdev = { |
|---|
| 2158 | + .name = "platform::micmute", |
|---|
| 2159 | + .max_brightness = 1, |
|---|
| 2160 | + .brightness_set_blocking = micmute_led_set, |
|---|
| 2161 | + .default_trigger = "audio-micmute", |
|---|
| 2162 | +}; |
|---|
| 2159 | 2163 | |
|---|
| 2160 | 2164 | static int __init dell_init(void) |
|---|
| 2161 | 2165 | { |
|---|
| .. | .. |
|---|
| 2195 | 2199 | kbd_led_init(&platform_device->dev); |
|---|
| 2196 | 2200 | |
|---|
| 2197 | 2201 | dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); |
|---|
| 2198 | | - if (dell_laptop_dir != NULL) |
|---|
| 2199 | | - debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, |
|---|
| 2200 | | - &dell_debugfs_fops); |
|---|
| 2202 | + debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, |
|---|
| 2203 | + &dell_debugfs_fops); |
|---|
| 2201 | 2204 | |
|---|
| 2202 | 2205 | dell_laptop_register_notifier(&dell_laptop_notifier); |
|---|
| 2206 | + |
|---|
| 2207 | + if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) && |
|---|
| 2208 | + dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) { |
|---|
| 2209 | + micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); |
|---|
| 2210 | + ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev); |
|---|
| 2211 | + if (ret < 0) |
|---|
| 2212 | + goto fail_led; |
|---|
| 2213 | + } |
|---|
| 2203 | 2214 | |
|---|
| 2204 | 2215 | if (acpi_video_get_backlight_type() != acpi_backlight_vendor) |
|---|
| 2205 | 2216 | return 0; |
|---|
| .. | .. |
|---|
| 2246 | 2257 | fail_get_brightness: |
|---|
| 2247 | 2258 | backlight_device_unregister(dell_backlight_device); |
|---|
| 2248 | 2259 | fail_backlight: |
|---|
| 2260 | + led_classdev_unregister(&micmute_led_cdev); |
|---|
| 2261 | +fail_led: |
|---|
| 2249 | 2262 | dell_cleanup_rfkill(); |
|---|
| 2250 | 2263 | fail_rfkill: |
|---|
| 2251 | 2264 | platform_device_del(platform_device); |
|---|
| .. | .. |
|---|
| 2265 | 2278 | touchpad_led_exit(); |
|---|
| 2266 | 2279 | kbd_led_exit(); |
|---|
| 2267 | 2280 | backlight_device_unregister(dell_backlight_device); |
|---|
| 2281 | + led_classdev_unregister(&micmute_led_cdev); |
|---|
| 2268 | 2282 | dell_cleanup_rfkill(); |
|---|
| 2269 | 2283 | if (platform_device) { |
|---|
| 2270 | 2284 | platform_device_unregister(platform_device); |
|---|
| .. | .. |
|---|
| 2284 | 2298 | |
|---|
| 2285 | 2299 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); |
|---|
| 2286 | 2300 | MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>"); |
|---|
| 2287 | | -MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); |
|---|
| 2301 | +MODULE_AUTHOR("Pali Rohár <pali@kernel.org>"); |
|---|
| 2288 | 2302 | MODULE_DESCRIPTION("Dell laptop driver"); |
|---|
| 2289 | 2303 | MODULE_LICENSE("GPL"); |
|---|