diff options
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r-- | drivers/platform/x86/asus-nb-wmi.c | 2 | ||||
-rw-r--r-- | drivers/platform/x86/asus-wmi.c | 33 | ||||
-rw-r--r-- | drivers/platform/x86/asus-wmi.h | 10 | ||||
-rw-r--r-- | drivers/platform/x86/eeepc-wmi.c | 85 |
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 | ||
1120 | static 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 | |||
1119 | static int update_bl_status(struct backlight_device *bd) | 1137 | static 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; | |||
35 | struct key_entry; | 35 | struct key_entry; |
36 | struct asus_wmi; | 36 | struct asus_wmi; |
37 | 37 | ||
38 | struct quirk_entry { | ||
39 | bool hotplug_wireless; | ||
40 | bool scalar_panel_brightness; | ||
41 | }; | ||
42 | |||
38 | struct asus_wmi_driver { | 43 | struct 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 | ||
49 | MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID); | 49 | MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID); |
50 | 50 | ||
51 | static struct quirk_entry *quirks; | ||
51 | static bool hotplug_wireless; | 52 | static bool hotplug_wireless; |
52 | 53 | ||
53 | module_param(hotplug_wireless, bool, 0444); | 54 | module_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 | ||
94 | static struct quirk_entry quirk_asus_unknown = { | ||
95 | }; | ||
96 | |||
97 | static struct quirk_entry quirk_asus_1000h = { | ||
98 | .hotplug_wireless = true, | ||
99 | }; | ||
100 | |||
101 | static struct quirk_entry quirk_asus_et2012_type3 = { | ||
102 | .scalar_panel_brightness = true, | ||
103 | }; | ||
104 | |||
105 | static 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 | |||
126 | static 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 | |||
93 | static void eeepc_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code, | 148 | static 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 | ||
147 | static 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 | |||
169 | static void eeepc_wmi_quirks(struct asus_wmi_driver *driver) | 202 | static 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 | ||
176 | static struct asus_wmi_driver asus_wmi_driver = { | 211 | static 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 | ||