aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86
diff options
context:
space:
mode:
authorAceLan Kao <acelan.kao@canonical.com>2012-03-20 04:53:08 -0400
committerMatthew Garrett <mjg@redhat.com>2012-03-26 15:05:41 -0400
commitc87992d1fa51a6a3d8f0e980ca4d2bdec7e78a17 (patch)
treec702643e69183fcc5cb5f5b8b4f1e429ff1366fb /drivers/platform/x86
parentbde9e5098c121cfca6d9c7e3a26e6ae44a3c9632 (diff)
asus-wmi: add scalar board brightness adj. support
Some ASUS ET2012E/I All-in-One machines that use a scalar board to control the brightness, and they only accept brightness up and down command. So, I introduced a get_scalar_command() function to pass the command to the scalar board through WMI. Besides, we have to store the brightness value locally, for we need the old value to know the brightness value is increasing or decreasing. BTW, since there is no way to retrieve the actual brightness(it would be a fixed value), and the max brightness value would be fixed to 1, so we have to keep passing the brightness up/down command when we reached the max brightness value or 0. Signed-off-by: AceLan Kao <acelan.kao@canonical.com> Signed-off-by: Corentin Chary <corentin.chary@gmail.com> Signed-off-by: Matthew Garrett <mjg@redhat.com>
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