aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c2
-rw-r--r--drivers/platform/x86/asus-wmi.c33
-rw-r--r--drivers/platform/x86/asus-wmi.h10
-rw-r--r--drivers/platform/x86/eeepc-wmi.c85
4 files changed, 97 insertions, 33 deletions
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 350112736023..1aea6b8019be 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -101,7 +101,7 @@ static struct asus_wmi_driver asus_nb_wmi_driver = {
101 .keymap = asus_nb_wmi_keymap, 101 .keymap = asus_nb_wmi_keymap,
102 .input_name = "Asus WMI hotkeys", 102 .input_name = "Asus WMI hotkeys",
103 .input_phys = ASUS_NB_WMI_FILE "/input0", 103 .input_phys = ASUS_NB_WMI_FILE "/input0",
104 .quirks = asus_nb_wmi_quirks, 104 .detect_quirks = asus_nb_wmi_quirks,
105}; 105};
106 106
107 107
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 2b883470a9d0..eb114f8d39e7 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -784,7 +784,8 @@ static int asus_new_rfkill(struct asus_wmi *asus,
784 arfkill->dev_id = dev_id; 784 arfkill->dev_id = dev_id;
785 arfkill->asus = asus; 785 arfkill->asus = asus;
786 786
787 if (dev_id == ASUS_WMI_DEVID_WLAN && asus->driver->hotplug_wireless) 787 if (dev_id == ASUS_WMI_DEVID_WLAN &&
788 asus->driver->quirks->hotplug_wireless)
788 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type, 789 *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
789 &asus_rfkill_wlan_ops, arfkill); 790 &asus_rfkill_wlan_ops, arfkill);
790 else 791 else
@@ -895,7 +896,7 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus)
895 if (result && result != -ENODEV) 896 if (result && result != -ENODEV)
896 goto exit; 897 goto exit;
897 898
898 if (!asus->driver->hotplug_wireless) 899 if (!asus->driver->quirks->hotplug_wireless)
899 goto exit; 900 goto exit;
900 901
901 result = asus_setup_pci_hotplug(asus); 902 result = asus_setup_pci_hotplug(asus);
@@ -1116,13 +1117,33 @@ static int read_brightness(struct backlight_device *bd)
1116 return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK; 1117 return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
1117} 1118}
1118 1119
1120static u32 get_scalar_command(struct backlight_device *bd)
1121{
1122 struct asus_wmi *asus = bl_get_data(bd);
1123 u32 ctrl_param = 0;
1124
1125 if ((asus->driver->brightness < bd->props.brightness) ||
1126 bd->props.brightness == bd->props.max_brightness)
1127 ctrl_param = 0x00008001;
1128 else if ((asus->driver->brightness > bd->props.brightness) ||
1129 bd->props.brightness == 0)
1130 ctrl_param = 0x00008000;
1131
1132 asus->driver->brightness = bd->props.brightness;
1133
1134 return ctrl_param;
1135}
1136
1119static int update_bl_status(struct backlight_device *bd) 1137static int update_bl_status(struct backlight_device *bd)
1120{ 1138{
1121 struct asus_wmi *asus = bl_get_data(bd); 1139 struct asus_wmi *asus = bl_get_data(bd);
1122 u32 ctrl_param; 1140 u32 ctrl_param;
1123 int power, err; 1141 int power, err;
1124 1142
1125 ctrl_param = bd->props.brightness; 1143 if (asus->driver->quirks->scalar_panel_brightness)
1144 ctrl_param = get_scalar_command(bd);
1145 else
1146 ctrl_param = bd->props.brightness;
1126 1147
1127 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS, 1148 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
1128 ctrl_param, NULL); 1149 ctrl_param, NULL);
@@ -1200,6 +1221,8 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus)
1200 bd->props.power = power; 1221 bd->props.power = power;
1201 backlight_update_status(bd); 1222 backlight_update_status(bd);
1202 1223
1224 asus->driver->brightness = bd->props.brightness;
1225
1203 return 0; 1226 return 0;
1204} 1227}
1205 1228
@@ -1622,8 +1645,8 @@ static int asus_wmi_add(struct platform_device *pdev)
1622 wdrv->platform_device = pdev; 1645 wdrv->platform_device = pdev;
1623 platform_set_drvdata(asus->platform_device, asus); 1646 platform_set_drvdata(asus->platform_device, asus);
1624 1647
1625 if (wdrv->quirks) 1648 if (wdrv->detect_quirks)
1626 wdrv->quirks(asus->driver); 1649 wdrv->detect_quirks(asus->driver);
1627 1650
1628 err = asus_wmi_platform_init(asus); 1651 err = asus_wmi_platform_init(asus);
1629 if (err) 1652 if (err)
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
index 8147c10161cc..ac7dd4eaebd0 100644
--- a/drivers/platform/x86/asus-wmi.h
+++ b/drivers/platform/x86/asus-wmi.h
@@ -35,9 +35,14 @@ struct module;
35struct key_entry; 35struct key_entry;
36struct asus_wmi; 36struct asus_wmi;
37 37
38struct quirk_entry {
39 bool hotplug_wireless;
40 bool scalar_panel_brightness;
41};
42
38struct asus_wmi_driver { 43struct asus_wmi_driver {
39 bool hotplug_wireless;
40 int wapf; 44 int wapf;
45 int brightness;
41 46
42 const char *name; 47 const char *name;
43 struct module *owner; 48 struct module *owner;
@@ -47,13 +52,14 @@ struct asus_wmi_driver {
47 const struct key_entry *keymap; 52 const struct key_entry *keymap;
48 const char *input_name; 53 const char *input_name;
49 const char *input_phys; 54 const char *input_phys;
55 struct quirk_entry *quirks;
50 /* Returns new code, value, and autorelease values in arguments. 56 /* Returns new code, value, and autorelease values in arguments.
51 * Return ASUS_WMI_KEY_IGNORE in code if event should be ignored. */ 57 * Return ASUS_WMI_KEY_IGNORE in code if event should be ignored. */
52 void (*key_filter) (struct asus_wmi_driver *driver, int *code, 58 void (*key_filter) (struct asus_wmi_driver *driver, int *code,
53 unsigned int *value, bool *autorelease); 59 unsigned int *value, bool *autorelease);
54 60
55 int (*probe) (struct platform_device *device); 61 int (*probe) (struct platform_device *device);
56 void (*quirks) (struct asus_wmi_driver *driver); 62 void (*detect_quirks) (struct asus_wmi_driver *driver);
57 63
58 struct platform_driver platform_driver; 64 struct platform_driver platform_driver;
59 struct platform_device *platform_device; 65 struct platform_device *platform_device;
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 1d91eb2ace0a..67186e6ca28d 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -48,6 +48,7 @@ MODULE_LICENSE("GPL");
48 48
49MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID); 49MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
50 50
51static struct quirk_entry *quirks;
51static bool hotplug_wireless; 52static bool hotplug_wireless;
52 53
53module_param(hotplug_wireless, bool, 0444); 54module_param(hotplug_wireless, bool, 0444);
@@ -90,6 +91,60 @@ static const struct key_entry eeepc_wmi_keymap[] = {
90 { KE_END, 0}, 91 { KE_END, 0},
91}; 92};
92 93
94static struct quirk_entry quirk_asus_unknown = {
95};
96
97static struct quirk_entry quirk_asus_1000h = {
98 .hotplug_wireless = true,
99};
100
101static struct quirk_entry quirk_asus_et2012_type3 = {
102 .scalar_panel_brightness = true,
103};
104
105static int dmi_matched(const struct dmi_system_id *dmi)
106{
107 char *model;
108 quirks = dmi->driver_data;
109
110 model = (char *)dmi->matches[1].substr;
111 if (unlikely(strncmp(model, "ET2012", 6) == 0)) {
112 const struct dmi_device *dev = NULL;
113 char oemstring[30];
114 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL,
115 dev))) {
116 if (sscanf(dev->name, "AEMS%24c", oemstring) == 1) {
117 if (oemstring[18] == '3')
118 quirks = &quirk_asus_et2012_type3;
119 break;
120 }
121 }
122 }
123 return 1;
124}
125
126static struct dmi_system_id asus_quirks[] = {
127 {
128 .callback = dmi_matched,
129 .ident = "ASUSTeK Computer INC. 1000H",
130 .matches = {
131 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
132 DMI_MATCH(DMI_PRODUCT_NAME, "1000H"),
133 },
134 .driver_data = &quirk_asus_1000h,
135 },
136 {
137 .callback = dmi_matched,
138 .ident = "ASUSTeK Computer INC. ET2012E/I",
139 .matches = {
140 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
141 DMI_MATCH(DMI_PRODUCT_NAME, "ET2012"),
142 },
143 .driver_data = &quirk_asus_unknown,
144 },
145 {},
146};
147
93static void eeepc_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code, 148static void eeepc_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code,
94 unsigned int *value, bool *autorelease) 149 unsigned int *value, bool *autorelease)
95{ 150{
@@ -144,33 +199,13 @@ static int eeepc_wmi_probe(struct platform_device *pdev)
144 return 0; 199 return 0;
145} 200}
146 201
147static void eeepc_dmi_check(struct asus_wmi_driver *driver)
148{
149 const char *model;
150
151 model = dmi_get_system_info(DMI_PRODUCT_NAME);
152 if (!model)
153 return;
154
155 /*
156 * Whitelist for wlan hotplug
157 *
158 * Asus 1000H needs the current hotplug code to handle
159 * Fn+F2 correctly. We may add other Asus here later, but
160 * it seems that most of the laptops supported by asus-wmi
161 * don't need to be on this list
162 */
163 if (strcmp(model, "1000H") == 0) {
164 driver->hotplug_wireless = true;
165 pr_info("wlan hotplug enabled\n");
166 }
167}
168
169static void eeepc_wmi_quirks(struct asus_wmi_driver *driver) 202static void eeepc_wmi_quirks(struct asus_wmi_driver *driver)
170{ 203{
171 driver->hotplug_wireless = hotplug_wireless;
172 driver->wapf = -1; 204 driver->wapf = -1;
173 eeepc_dmi_check(driver); 205 driver->quirks = &quirk_asus_unknown;
206 driver->quirks->hotplug_wireless = hotplug_wireless;
207 dmi_check_system(asus_quirks);
208 driver->quirks = quirks;
174} 209}
175 210
176static struct asus_wmi_driver asus_wmi_driver = { 211static struct asus_wmi_driver asus_wmi_driver = {
@@ -182,7 +217,7 @@ static struct asus_wmi_driver asus_wmi_driver = {
182 .input_phys = EEEPC_WMI_FILE "/input0", 217 .input_phys = EEEPC_WMI_FILE "/input0",
183 .key_filter = eeepc_wmi_key_filter, 218 .key_filter = eeepc_wmi_key_filter,
184 .probe = eeepc_wmi_probe, 219 .probe = eeepc_wmi_probe,
185 .quirks = eeepc_wmi_quirks, 220 .detect_quirks = eeepc_wmi_quirks,
186}; 221};
187 222
188 223