aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Kępień <kernel@kempniu.pl>2016-01-22 09:27:27 -0500
committerDarren Hart <dvhart@linux.intel.com>2016-03-23 13:05:43 -0400
commitcf0d7ea335966744f2a4fc6f882165b7dba54c15 (patch)
treec8be9a3dc71b182dc3f7ed9d616443cf7fa9c6a7
parentb7bca2d7ff1a232466fa5447ec27e62bf02b310f (diff)
dell-led: use dell_smbios_find_token() for finding mic DMI tokens
With the advent of dell_smbios_find_token(), dell-led does not need to perform any DMI walking on its own, but it can rather ask dell-smbios to look up the DMI tokens it needs for changing the state of the microphone LED. Signed-off-by: Michał Kępień <kernel@kempniu.pl> Reviewed-by: Pali Rohár <pali.rohar@gmail.com> Acked-by: Jacek Anaszewski <j.anaszewski@samsung.com> Signed-off-by: Darren Hart <dvhart@linux.intel.com>
-rw-r--r--drivers/leds/Kconfig1
-rw-r--r--drivers/leds/dell-led.c63
2 files changed, 10 insertions, 54 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 7f940c24a16b..4351cbe57221 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -443,6 +443,7 @@ config LEDS_DELL_NETBOOKS
443 tristate "External LED on Dell Business Netbooks" 443 tristate "External LED on Dell Business Netbooks"
444 depends on LEDS_CLASS 444 depends on LEDS_CLASS
445 depends on X86 && ACPI_WMI 445 depends on X86 && ACPI_WMI
446 depends on DELL_SMBIOS
446 help 447 help
447 This adds support for the Latitude 2100 and similar 448 This adds support for the Latitude 2100 and similar
448 notebooks that have an external LED. 449 notebooks that have an external LED.
diff --git a/drivers/leds/dell-led.c b/drivers/leds/dell-led.c
index c36acaf566a6..bfa7511374bd 100644
--- a/drivers/leds/dell-led.c
+++ b/drivers/leds/dell-led.c
@@ -17,6 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/dmi.h> 18#include <linux/dmi.h>
19#include <linux/dell-led.h> 19#include <linux/dell-led.h>
20#include "../platform/x86/dell-smbios.h"
20 21
21MODULE_AUTHOR("Louis Davis/Jim Dailey"); 22MODULE_AUTHOR("Louis Davis/Jim Dailey");
22MODULE_DESCRIPTION("Dell LED Control Driver"); 23MODULE_DESCRIPTION("Dell LED Control Driver");
@@ -59,22 +60,6 @@ struct app_wmi_args {
59#define GLOBAL_MIC_MUTE_ENABLE 0x364 60#define GLOBAL_MIC_MUTE_ENABLE 0x364
60#define GLOBAL_MIC_MUTE_DISABLE 0x365 61#define GLOBAL_MIC_MUTE_DISABLE 0x365
61 62
62struct dell_bios_data_token {
63 u16 tokenid;
64 u16 location;
65 u16 value;
66};
67
68struct __attribute__ ((__packed__)) dell_bios_calling_interface {
69 struct dmi_header header;
70 u16 cmd_io_addr;
71 u8 cmd_io_code;
72 u32 supported_cmds;
73 struct dell_bios_data_token damap[];
74};
75
76static struct dell_bios_data_token dell_mic_tokens[2];
77
78static int dell_wmi_perform_query(struct app_wmi_args *args) 63static int dell_wmi_perform_query(struct app_wmi_args *args)
79{ 64{
80 struct app_wmi_args *bios_return; 65 struct app_wmi_args *bios_return;
@@ -112,43 +97,24 @@ static int dell_wmi_perform_query(struct app_wmi_args *args)
112 return rc; 97 return rc;
113} 98}
114 99
115static void __init find_micmute_tokens(const struct dmi_header *dm, void *dummy)
116{
117 struct dell_bios_calling_interface *calling_interface;
118 struct dell_bios_data_token *token;
119 int token_size = sizeof(struct dell_bios_data_token);
120 int i = 0;
121
122 if (dm->type == 0xda && dm->length > 17) {
123 calling_interface = container_of(dm,
124 struct dell_bios_calling_interface, header);
125
126 token = &calling_interface->damap[i];
127 while (token->tokenid != 0xffff) {
128 if (token->tokenid == GLOBAL_MIC_MUTE_DISABLE)
129 memcpy(&dell_mic_tokens[0], token, token_size);
130 else if (token->tokenid == GLOBAL_MIC_MUTE_ENABLE)
131 memcpy(&dell_mic_tokens[1], token, token_size);
132
133 i++;
134 token = &calling_interface->damap[i];
135 }
136 }
137}
138
139static int dell_micmute_led_set(int state) 100static int dell_micmute_led_set(int state)
140{ 101{
102 struct calling_interface_token *token;
141 struct app_wmi_args args; 103 struct app_wmi_args args;
142 struct dell_bios_data_token *token;
143 104
144 if (!wmi_has_guid(DELL_APP_GUID)) 105 if (!wmi_has_guid(DELL_APP_GUID))
145 return -ENODEV; 106 return -ENODEV;
146 107
147 if (state == 0 || state == 1) 108 if (state == 0)
148 token = &dell_mic_tokens[state]; 109 token = dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE);
110 else if (state == 1)
111 token = dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE);
149 else 112 else
150 return -EINVAL; 113 return -EINVAL;
151 114
115 if (!token)
116 return -ENODEV;
117
152 memset(&args, 0, sizeof(struct app_wmi_args)); 118 memset(&args, 0, sizeof(struct app_wmi_args));
153 119
154 args.class = 1; 120 args.class = 1;
@@ -177,14 +143,6 @@ int dell_app_wmi_led_set(int whichled, int on)
177} 143}
178EXPORT_SYMBOL_GPL(dell_app_wmi_led_set); 144EXPORT_SYMBOL_GPL(dell_app_wmi_led_set);
179 145
180static int __init dell_micmute_led_init(void)
181{
182 memset(dell_mic_tokens, 0, sizeof(struct dell_bios_data_token) * 2);
183 dmi_walk(find_micmute_tokens, NULL);
184
185 return 0;
186}
187
188struct bios_args { 146struct bios_args {
189 unsigned char length; 147 unsigned char length;
190 unsigned char result_code; 148 unsigned char result_code;
@@ -330,9 +288,6 @@ static int __init dell_led_init(void)
330 if (!wmi_has_guid(DELL_LED_BIOS_GUID) && !wmi_has_guid(DELL_APP_GUID)) 288 if (!wmi_has_guid(DELL_LED_BIOS_GUID) && !wmi_has_guid(DELL_APP_GUID))
331 return -ENODEV; 289 return -ENODEV;
332 290
333 if (wmi_has_guid(DELL_APP_GUID))
334 error = dell_micmute_led_init();
335
336 if (wmi_has_guid(DELL_LED_BIOS_GUID)) { 291 if (wmi_has_guid(DELL_LED_BIOS_GUID)) {
337 error = led_off(); 292 error = led_off();
338 if (error != 0) 293 if (error != 0)