1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * eeepc-laptop.c - Asus Eee PC extras
4 *
5 * Based on asus_acpi.c as patched for the Eee PC by Asus:
6 * ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
7 * Based on eee.c from eeepc-linux
8 */
9
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/types.h>
16 #include <linux/platform_device.h>
17 #include <linux/backlight.h>
18 #include <linux/hwmon.h>
19 #include <linux/hwmon-sysfs.h>
20 #include <linux/slab.h>
21 #include <linux/acpi.h>
22 #include <linux/uaccess.h>
23 #include <linux/input.h>
24 #include <linux/input/sparse-keymap.h>
25 #include <linux/rfkill.h>
26 #include <linux/pci.h>
27 #include <linux/pci_hotplug.h>
28 #include <linux/sysfs.h>
29 #include <linux/leds.h>
30 #include <linux/dmi.h>
31 #include <acpi/video.h>
32
33 #define EEEPC_LAPTOP_VERSION "0.1"
34 #define EEEPC_LAPTOP_NAME "Eee PC Hotkey Driver"
35 #define EEEPC_LAPTOP_FILE "eeepc"
36
37 #define EEEPC_ACPI_HID "ASUS010"
38
39 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
40 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
41 MODULE_LICENSE("GPL");
42
43 static bool hotplug_disabled;
44
45 module_param(hotplug_disabled, bool, 0444);
46 MODULE_PARM_DESC(hotplug_disabled,
47 "Disable hotplug for wireless device. "
48 "If your laptop need that, please report to "
49 "acpi4asus-user@lists.sourceforge.net.");
50
51 /*
52 * Definitions for Asus EeePC
53 */
54 #define NOTIFY_BRN_MIN 0x20
55 #define NOTIFY_BRN_MAX 0x2f
56
57 enum {
58 DISABLE_ASL_WLAN = 0x0001,
59 DISABLE_ASL_BLUETOOTH = 0x0002,
60 DISABLE_ASL_IRDA = 0x0004,
61 DISABLE_ASL_CAMERA = 0x0008,
62 DISABLE_ASL_TV = 0x0010,
63 DISABLE_ASL_GPS = 0x0020,
64 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
65 DISABLE_ASL_MODEM = 0x0080,
66 DISABLE_ASL_CARDREADER = 0x0100,
67 DISABLE_ASL_3G = 0x0200,
68 DISABLE_ASL_WIMAX = 0x0400,
69 DISABLE_ASL_HWCF = 0x0800
70 };
71
72 enum {
73 CM_ASL_WLAN = 0,
74 CM_ASL_BLUETOOTH,
75 CM_ASL_IRDA,
76 CM_ASL_1394,
77 CM_ASL_CAMERA,
78 CM_ASL_TV,
79 CM_ASL_GPS,
80 CM_ASL_DVDROM,
81 CM_ASL_DISPLAYSWITCH,
82 CM_ASL_PANELBRIGHT,
83 CM_ASL_BIOSFLASH,
84 CM_ASL_ACPIFLASH,
85 CM_ASL_CPUFV,
86 CM_ASL_CPUTEMPERATURE,
87 CM_ASL_FANCPU,
88 CM_ASL_FANCHASSIS,
89 CM_ASL_USBPORT1,
90 CM_ASL_USBPORT2,
91 CM_ASL_USBPORT3,
92 CM_ASL_MODEM,
93 CM_ASL_CARDREADER,
94 CM_ASL_3G,
95 CM_ASL_WIMAX,
96 CM_ASL_HWCF,
97 CM_ASL_LID,
98 CM_ASL_TYPE,
99 CM_ASL_PANELPOWER, /*P901*/
100 CM_ASL_TPD
101 };
102
103 static const char *cm_getv[] = {
104 "WLDG", "BTHG", NULL, NULL,
105 "CAMG", NULL, NULL, NULL,
106 NULL, "PBLG", NULL, NULL,
107 "CFVG", NULL, NULL, NULL,
108 "USBG", NULL, NULL, "MODG",
109 "CRDG", "M3GG", "WIMG", "HWCF",
110 "LIDG", "TYPE", "PBPG", "TPDG"
111 };
112
113 static const char *cm_setv[] = {
114 "WLDS", "BTHS", NULL, NULL,
115 "CAMS", NULL, NULL, NULL,
116 "SDSP", "PBLS", "HDPS", NULL,
117 "CFVS", NULL, NULL, NULL,
118 "USBG", NULL, NULL, "MODS",
119 "CRDS", "M3GS", "WIMS", NULL,
120 NULL, NULL, "PBPS", "TPDS"
121 };
122
123 static const struct key_entry eeepc_keymap[] = {
124 { KE_KEY, 0x10, { KEY_WLAN } },
125 { KE_KEY, 0x11, { KEY_WLAN } },
126 { KE_KEY, 0x12, { KEY_PROG1 } },
127 { KE_KEY, 0x13, { KEY_MUTE } },
128 { KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
129 { KE_KEY, 0x15, { KEY_VOLUMEUP } },
130 { KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
131 { KE_KEY, 0x1a, { KEY_COFFEE } },
132 { KE_KEY, 0x1b, { KEY_ZOOM } },
133 { KE_KEY, 0x1c, { KEY_PROG2 } },
134 { KE_KEY, 0x1d, { KEY_PROG3 } },
135 { KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
136 { KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
137 { KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
138 { KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
139 { KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
140 { KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
141 { KE_KEY, 0x38, { KEY_F14 } },
142 { KE_IGNORE, 0x50, { KEY_RESERVED } }, /* AC plugged */
143 { KE_IGNORE, 0x51, { KEY_RESERVED } }, /* AC unplugged */
144 { KE_END, 0 },
145 };
146
147 /*
148 * This is the main structure, we can use it to store useful information
149 */
150 struct eeepc_laptop {
151 acpi_handle handle; /* the handle of the acpi device */
152 u32 cm_supported; /* the control methods supported
153 by this BIOS */
154 bool cpufv_disabled;
155 bool hotplug_disabled;
156 u16 event_count[128]; /* count for each event */
157
158 struct platform_device *platform_device;
159 struct acpi_device *device; /* the device we are in */
160 struct backlight_device *backlight_device;
161
162 struct input_dev *inputdev;
163
164 struct rfkill *wlan_rfkill;
165 struct rfkill *bluetooth_rfkill;
166 struct rfkill *wwan3g_rfkill;
167 struct rfkill *wimax_rfkill;
168
169 struct hotplug_slot hotplug_slot;
170 struct mutex hotplug_lock;
171
172 struct led_classdev tpd_led;
173 int tpd_led_wk;
174 struct workqueue_struct *led_workqueue;
175 struct work_struct tpd_led_work;
176 };
177
178 /*
179 * ACPI Helpers
180 */
write_acpi_int(acpi_handle handle,const char * method,int val)181 static int write_acpi_int(acpi_handle handle, const char *method, int val)
182 {
183 acpi_status status;
184
185 status = acpi_execute_simple_method(handle, (char *)method, val);
186
187 return (status == AE_OK ? 0 : -1);
188 }
189
read_acpi_int(acpi_handle handle,const char * method,int * val)190 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
191 {
192 acpi_status status;
193 unsigned long long result;
194
195 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
196 if (ACPI_FAILURE(status)) {
197 *val = -1;
198 return -1;
199 } else {
200 *val = result;
201 return 0;
202 }
203 }
204
set_acpi(struct eeepc_laptop * eeepc,int cm,int value)205 static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
206 {
207 const char *method = cm_setv[cm];
208
209 if (method == NULL)
210 return -ENODEV;
211 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
212 return -ENODEV;
213
214 if (write_acpi_int(eeepc->handle, method, value))
215 pr_warn("Error writing %s\n", method);
216 return 0;
217 }
218
get_acpi(struct eeepc_laptop * eeepc,int cm)219 static int get_acpi(struct eeepc_laptop *eeepc, int cm)
220 {
221 const char *method = cm_getv[cm];
222 int value;
223
224 if (method == NULL)
225 return -ENODEV;
226 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
227 return -ENODEV;
228
229 if (read_acpi_int(eeepc->handle, method, &value))
230 pr_warn("Error reading %s\n", method);
231 return value;
232 }
233
acpi_setter_handle(struct eeepc_laptop * eeepc,int cm,acpi_handle * handle)234 static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
235 acpi_handle *handle)
236 {
237 const char *method = cm_setv[cm];
238 acpi_status status;
239
240 if (method == NULL)
241 return -ENODEV;
242 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
243 return -ENODEV;
244
245 status = acpi_get_handle(eeepc->handle, (char *)method,
246 handle);
247 if (status != AE_OK) {
248 pr_warn("Error finding %s\n", method);
249 return -ENODEV;
250 }
251 return 0;
252 }
253
254
255 /*
256 * Sys helpers
257 */
parse_arg(const char * buf,int * val)258 static int parse_arg(const char *buf, int *val)
259 {
260 if (sscanf(buf, "%i", val) != 1)
261 return -EINVAL;
262 return 0;
263 }
264
store_sys_acpi(struct device * dev,int cm,const char * buf,size_t count)265 static ssize_t store_sys_acpi(struct device *dev, int cm,
266 const char *buf, size_t count)
267 {
268 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
269 int rv, value;
270
271 rv = parse_arg(buf, &value);
272 if (rv < 0)
273 return rv;
274 rv = set_acpi(eeepc, cm, value);
275 if (rv < 0)
276 return -EIO;
277 return count;
278 }
279
show_sys_acpi(struct device * dev,int cm,char * buf)280 static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
281 {
282 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
283 int value = get_acpi(eeepc, cm);
284
285 if (value < 0)
286 return -EIO;
287 return sysfs_emit(buf, "%d\n", value);
288 }
289
290 #define EEEPC_ACPI_SHOW_FUNC(_name, _cm) \
291 static ssize_t _name##_show(struct device *dev, \
292 struct device_attribute *attr, \
293 char *buf) \
294 { \
295 return show_sys_acpi(dev, _cm, buf); \
296 }
297
298 #define EEEPC_ACPI_STORE_FUNC(_name, _cm) \
299 static ssize_t _name##_store(struct device *dev, \
300 struct device_attribute *attr, \
301 const char *buf, size_t count) \
302 { \
303 return store_sys_acpi(dev, _cm, buf, count); \
304 }
305
306 #define EEEPC_CREATE_DEVICE_ATTR_RW(_name, _cm) \
307 EEEPC_ACPI_SHOW_FUNC(_name, _cm) \
308 EEEPC_ACPI_STORE_FUNC(_name, _cm) \
309 static DEVICE_ATTR_RW(_name)
310
311 #define EEEPC_CREATE_DEVICE_ATTR_WO(_name, _cm) \
312 EEEPC_ACPI_STORE_FUNC(_name, _cm) \
313 static DEVICE_ATTR_WO(_name)
314
315 EEEPC_CREATE_DEVICE_ATTR_RW(camera, CM_ASL_CAMERA);
316 EEEPC_CREATE_DEVICE_ATTR_RW(cardr, CM_ASL_CARDREADER);
317 EEEPC_CREATE_DEVICE_ATTR_WO(disp, CM_ASL_DISPLAYSWITCH);
318
319 struct eeepc_cpufv {
320 int num;
321 int cur;
322 };
323
get_cpufv(struct eeepc_laptop * eeepc,struct eeepc_cpufv * c)324 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
325 {
326 c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
327 if (c->cur < 0)
328 return -ENODEV;
329
330 c->num = (c->cur >> 8) & 0xff;
331 c->cur &= 0xff;
332 if (c->num == 0 || c->num > 12)
333 return -ENODEV;
334 return 0;
335 }
336
available_cpufv_show(struct device * dev,struct device_attribute * attr,char * buf)337 static ssize_t available_cpufv_show(struct device *dev,
338 struct device_attribute *attr,
339 char *buf)
340 {
341 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
342 struct eeepc_cpufv c;
343 int i;
344 ssize_t len = 0;
345
346 if (get_cpufv(eeepc, &c))
347 return -ENODEV;
348 for (i = 0; i < c.num; i++)
349 len += sprintf(buf + len, "%d ", i);
350 len += sprintf(buf + len, "\n");
351 return len;
352 }
353
cpufv_show(struct device * dev,struct device_attribute * attr,char * buf)354 static ssize_t cpufv_show(struct device *dev,
355 struct device_attribute *attr,
356 char *buf)
357 {
358 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
359 struct eeepc_cpufv c;
360
361 if (get_cpufv(eeepc, &c))
362 return -ENODEV;
363 return sysfs_emit(buf, "%#x\n", (c.num << 8) | c.cur);
364 }
365
cpufv_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)366 static ssize_t cpufv_store(struct device *dev,
367 struct device_attribute *attr,
368 const char *buf, size_t count)
369 {
370 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
371 struct eeepc_cpufv c;
372 int rv, value;
373
374 if (eeepc->cpufv_disabled)
375 return -EPERM;
376 if (get_cpufv(eeepc, &c))
377 return -ENODEV;
378 rv = parse_arg(buf, &value);
379 if (rv < 0)
380 return rv;
381 if (value < 0 || value >= c.num)
382 return -EINVAL;
383 rv = set_acpi(eeepc, CM_ASL_CPUFV, value);
384 if (rv)
385 return rv;
386 return count;
387 }
388
cpufv_disabled_show(struct device * dev,struct device_attribute * attr,char * buf)389 static ssize_t cpufv_disabled_show(struct device *dev,
390 struct device_attribute *attr,
391 char *buf)
392 {
393 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
394
395 return sysfs_emit(buf, "%d\n", eeepc->cpufv_disabled);
396 }
397
cpufv_disabled_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)398 static ssize_t cpufv_disabled_store(struct device *dev,
399 struct device_attribute *attr,
400 const char *buf, size_t count)
401 {
402 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
403 int rv, value;
404
405 rv = parse_arg(buf, &value);
406 if (rv < 0)
407 return rv;
408
409 switch (value) {
410 case 0:
411 if (eeepc->cpufv_disabled)
412 pr_warn("cpufv enabled (not officially supported on this model)\n");
413 eeepc->cpufv_disabled = false;
414 return count;
415 case 1:
416 return -EPERM;
417 default:
418 return -EINVAL;
419 }
420 }
421
422
423 static DEVICE_ATTR_RW(cpufv);
424 static DEVICE_ATTR_RO(available_cpufv);
425 static DEVICE_ATTR_RW(cpufv_disabled);
426
427 static struct attribute *platform_attributes[] = {
428 &dev_attr_camera.attr,
429 &dev_attr_cardr.attr,
430 &dev_attr_disp.attr,
431 &dev_attr_cpufv.attr,
432 &dev_attr_available_cpufv.attr,
433 &dev_attr_cpufv_disabled.attr,
434 NULL
435 };
436
437 static const struct attribute_group platform_attribute_group = {
438 .attrs = platform_attributes
439 };
440
eeepc_platform_init(struct eeepc_laptop * eeepc)441 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
442 {
443 int result;
444
445 eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, PLATFORM_DEVID_NONE);
446 if (!eeepc->platform_device)
447 return -ENOMEM;
448 platform_set_drvdata(eeepc->platform_device, eeepc);
449
450 result = platform_device_add(eeepc->platform_device);
451 if (result)
452 goto fail_platform_device;
453
454 result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
455 &platform_attribute_group);
456 if (result)
457 goto fail_sysfs;
458 return 0;
459
460 fail_sysfs:
461 platform_device_del(eeepc->platform_device);
462 fail_platform_device:
463 platform_device_put(eeepc->platform_device);
464 return result;
465 }
466
eeepc_platform_exit(struct eeepc_laptop * eeepc)467 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
468 {
469 sysfs_remove_group(&eeepc->platform_device->dev.kobj,
470 &platform_attribute_group);
471 platform_device_unregister(eeepc->platform_device);
472 }
473
474 /*
475 * LEDs
476 */
477 /*
478 * These functions actually update the LED's, and are called from a
479 * workqueue. By doing this as separate work rather than when the LED
480 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
481 * potentially bad time, such as a timer interrupt.
482 */
tpd_led_update(struct work_struct * work)483 static void tpd_led_update(struct work_struct *work)
484 {
485 struct eeepc_laptop *eeepc;
486
487 eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
488
489 set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
490 }
491
tpd_led_set(struct led_classdev * led_cdev,enum led_brightness value)492 static void tpd_led_set(struct led_classdev *led_cdev,
493 enum led_brightness value)
494 {
495 struct eeepc_laptop *eeepc;
496
497 eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
498
499 eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
500 queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
501 }
502
tpd_led_get(struct led_classdev * led_cdev)503 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
504 {
505 struct eeepc_laptop *eeepc;
506
507 eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
508
509 return get_acpi(eeepc, CM_ASL_TPD);
510 }
511
eeepc_led_init(struct eeepc_laptop * eeepc)512 static int eeepc_led_init(struct eeepc_laptop *eeepc)
513 {
514 int rv;
515
516 if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
517 return 0;
518
519 eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
520 if (!eeepc->led_workqueue)
521 return -ENOMEM;
522 INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
523
524 eeepc->tpd_led.name = "eeepc::touchpad";
525 eeepc->tpd_led.brightness_set = tpd_led_set;
526 if (get_acpi(eeepc, CM_ASL_TPD) >= 0) /* if method is available */
527 eeepc->tpd_led.brightness_get = tpd_led_get;
528 eeepc->tpd_led.max_brightness = 1;
529
530 rv = led_classdev_register(&eeepc->platform_device->dev,
531 &eeepc->tpd_led);
532 if (rv) {
533 destroy_workqueue(eeepc->led_workqueue);
534 return rv;
535 }
536
537 return 0;
538 }
539
eeepc_led_exit(struct eeepc_laptop * eeepc)540 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
541 {
542 led_classdev_unregister(&eeepc->tpd_led);
543 if (eeepc->led_workqueue)
544 destroy_workqueue(eeepc->led_workqueue);
545 }
546
547 /*
548 * PCI hotplug (for wlan rfkill)
549 */
eeepc_wlan_rfkill_blocked(struct eeepc_laptop * eeepc)550 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
551 {
552 if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
553 return false;
554 return true;
555 }
556
eeepc_rfkill_hotplug(struct eeepc_laptop * eeepc,acpi_handle handle)557 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
558 {
559 struct pci_dev *port;
560 struct pci_dev *dev;
561 struct pci_bus *bus;
562 bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
563 bool absent;
564 u32 l;
565
566 if (eeepc->wlan_rfkill)
567 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
568
569 mutex_lock(&eeepc->hotplug_lock);
570 pci_lock_rescan_remove();
571
572 if (!eeepc->hotplug_slot.ops)
573 goto out_unlock;
574
575 port = acpi_get_pci_dev(handle);
576 if (!port) {
577 pr_warn("Unable to find port\n");
578 goto out_unlock;
579 }
580
581 bus = port->subordinate;
582
583 if (!bus) {
584 pr_warn("Unable to find PCI bus 1?\n");
585 goto out_put_dev;
586 }
587
588 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
589 pr_err("Unable to read PCI config space?\n");
590 goto out_put_dev;
591 }
592
593 absent = (l == 0xffffffff);
594
595 if (blocked != absent) {
596 pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n",
597 blocked ? "blocked" : "unblocked",
598 absent ? "absent" : "present");
599 pr_warn("skipped wireless hotplug as probably inappropriate for this model\n");
600 goto out_put_dev;
601 }
602
603 if (!blocked) {
604 dev = pci_get_slot(bus, 0);
605 if (dev) {
606 /* Device already present */
607 pci_dev_put(dev);
608 goto out_put_dev;
609 }
610 dev = pci_scan_single_device(bus, 0);
611 if (dev) {
612 pci_bus_assign_resources(bus);
613 pci_bus_add_device(dev);
614 }
615 } else {
616 dev = pci_get_slot(bus, 0);
617 if (dev) {
618 pci_stop_and_remove_bus_device(dev);
619 pci_dev_put(dev);
620 }
621 }
622 out_put_dev:
623 pci_dev_put(port);
624
625 out_unlock:
626 pci_unlock_rescan_remove();
627 mutex_unlock(&eeepc->hotplug_lock);
628 }
629
eeepc_rfkill_hotplug_update(struct eeepc_laptop * eeepc,char * node)630 static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
631 {
632 acpi_status status = AE_OK;
633 acpi_handle handle;
634
635 status = acpi_get_handle(NULL, node, &handle);
636
637 if (ACPI_SUCCESS(status))
638 eeepc_rfkill_hotplug(eeepc, handle);
639 }
640
eeepc_rfkill_notify(acpi_handle handle,u32 event,void * data)641 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
642 {
643 struct eeepc_laptop *eeepc = data;
644
645 if (event != ACPI_NOTIFY_BUS_CHECK)
646 return;
647
648 eeepc_rfkill_hotplug(eeepc, handle);
649 }
650
eeepc_register_rfkill_notifier(struct eeepc_laptop * eeepc,char * node)651 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
652 char *node)
653 {
654 acpi_status status;
655 acpi_handle handle;
656
657 status = acpi_get_handle(NULL, node, &handle);
658
659 if (ACPI_FAILURE(status))
660 return -ENODEV;
661
662 status = acpi_install_notify_handler(handle,
663 ACPI_SYSTEM_NOTIFY,
664 eeepc_rfkill_notify,
665 eeepc);
666 if (ACPI_FAILURE(status))
667 pr_warn("Failed to register notify on %s\n", node);
668
669 /*
670 * Refresh pci hotplug in case the rfkill state was
671 * changed during setup.
672 */
673 eeepc_rfkill_hotplug(eeepc, handle);
674 return 0;
675 }
676
eeepc_unregister_rfkill_notifier(struct eeepc_laptop * eeepc,char * node)677 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
678 char *node)
679 {
680 acpi_status status = AE_OK;
681 acpi_handle handle;
682
683 status = acpi_get_handle(NULL, node, &handle);
684
685 if (ACPI_FAILURE(status))
686 return;
687
688 status = acpi_remove_notify_handler(handle,
689 ACPI_SYSTEM_NOTIFY,
690 eeepc_rfkill_notify);
691 if (ACPI_FAILURE(status))
692 pr_err("Error removing rfkill notify handler %s\n",
693 node);
694 /*
695 * Refresh pci hotplug in case the rfkill
696 * state was changed after
697 * eeepc_unregister_rfkill_notifier()
698 */
699 eeepc_rfkill_hotplug(eeepc, handle);
700 }
701
eeepc_get_adapter_status(struct hotplug_slot * hotplug_slot,u8 * value)702 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
703 u8 *value)
704 {
705 struct eeepc_laptop *eeepc;
706 int val;
707
708 eeepc = container_of(hotplug_slot, struct eeepc_laptop, hotplug_slot);
709 val = get_acpi(eeepc, CM_ASL_WLAN);
710
711 if (val == 1 || val == 0)
712 *value = val;
713 else
714 return -EINVAL;
715
716 return 0;
717 }
718
719 static const struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
720 .get_adapter_status = eeepc_get_adapter_status,
721 .get_power_status = eeepc_get_adapter_status,
722 };
723
eeepc_setup_pci_hotplug(struct eeepc_laptop * eeepc)724 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
725 {
726 int ret = -ENOMEM;
727 struct pci_bus *bus = pci_find_bus(0, 1);
728
729 if (!bus) {
730 pr_err("Unable to find wifi PCI bus\n");
731 return -ENODEV;
732 }
733
734 eeepc->hotplug_slot.ops = &eeepc_hotplug_slot_ops;
735
736 ret = pci_hp_register(&eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
737 if (ret) {
738 pr_err("Unable to register hotplug slot - %d\n", ret);
739 goto error_register;
740 }
741
742 return 0;
743
744 error_register:
745 eeepc->hotplug_slot.ops = NULL;
746 return ret;
747 }
748
749 /*
750 * Rfkill devices
751 */
eeepc_rfkill_set(void * data,bool blocked)752 static int eeepc_rfkill_set(void *data, bool blocked)
753 {
754 acpi_handle handle = data;
755
756 return write_acpi_int(handle, NULL, !blocked);
757 }
758
759 static const struct rfkill_ops eeepc_rfkill_ops = {
760 .set_block = eeepc_rfkill_set,
761 };
762
eeepc_new_rfkill(struct eeepc_laptop * eeepc,struct rfkill ** rfkill,const char * name,enum rfkill_type type,int cm)763 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
764 struct rfkill **rfkill,
765 const char *name,
766 enum rfkill_type type, int cm)
767 {
768 acpi_handle handle;
769 int result;
770
771 result = acpi_setter_handle(eeepc, cm, &handle);
772 if (result < 0)
773 return result;
774
775 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
776 &eeepc_rfkill_ops, handle);
777
778 if (!*rfkill)
779 return -EINVAL;
780
781 rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
782 result = rfkill_register(*rfkill);
783 if (result) {
784 rfkill_destroy(*rfkill);
785 *rfkill = NULL;
786 return result;
787 }
788 return 0;
789 }
790
791 static char EEEPC_RFKILL_NODE_1[] = "\\_SB.PCI0.P0P5";
792 static char EEEPC_RFKILL_NODE_2[] = "\\_SB.PCI0.P0P6";
793 static char EEEPC_RFKILL_NODE_3[] = "\\_SB.PCI0.P0P7";
794
eeepc_rfkill_exit(struct eeepc_laptop * eeepc)795 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
796 {
797 eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
798 eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
799 eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
800 if (eeepc->wlan_rfkill) {
801 rfkill_unregister(eeepc->wlan_rfkill);
802 rfkill_destroy(eeepc->wlan_rfkill);
803 eeepc->wlan_rfkill = NULL;
804 }
805
806 if (eeepc->hotplug_slot.ops)
807 pci_hp_deregister(&eeepc->hotplug_slot);
808
809 if (eeepc->bluetooth_rfkill) {
810 rfkill_unregister(eeepc->bluetooth_rfkill);
811 rfkill_destroy(eeepc->bluetooth_rfkill);
812 eeepc->bluetooth_rfkill = NULL;
813 }
814 if (eeepc->wwan3g_rfkill) {
815 rfkill_unregister(eeepc->wwan3g_rfkill);
816 rfkill_destroy(eeepc->wwan3g_rfkill);
817 eeepc->wwan3g_rfkill = NULL;
818 }
819 if (eeepc->wimax_rfkill) {
820 rfkill_unregister(eeepc->wimax_rfkill);
821 rfkill_destroy(eeepc->wimax_rfkill);
822 eeepc->wimax_rfkill = NULL;
823 }
824 }
825
eeepc_rfkill_init(struct eeepc_laptop * eeepc)826 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
827 {
828 int result = 0;
829
830 mutex_init(&eeepc->hotplug_lock);
831
832 result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
833 "eeepc-wlan", RFKILL_TYPE_WLAN,
834 CM_ASL_WLAN);
835
836 if (result && result != -ENODEV)
837 goto exit;
838
839 result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
840 "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
841 CM_ASL_BLUETOOTH);
842
843 if (result && result != -ENODEV)
844 goto exit;
845
846 result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
847 "eeepc-wwan3g", RFKILL_TYPE_WWAN,
848 CM_ASL_3G);
849
850 if (result && result != -ENODEV)
851 goto exit;
852
853 result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
854 "eeepc-wimax", RFKILL_TYPE_WIMAX,
855 CM_ASL_WIMAX);
856
857 if (result && result != -ENODEV)
858 goto exit;
859
860 if (eeepc->hotplug_disabled)
861 return 0;
862
863 result = eeepc_setup_pci_hotplug(eeepc);
864 /*
865 * If we get -EBUSY then something else is handling the PCI hotplug -
866 * don't fail in this case
867 */
868 if (result == -EBUSY)
869 result = 0;
870
871 eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
872 eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
873 eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
874
875 exit:
876 if (result && result != -ENODEV)
877 eeepc_rfkill_exit(eeepc);
878 return result;
879 }
880
881 /*
882 * Platform driver - hibernate/resume callbacks
883 */
eeepc_hotk_thaw(struct device * device)884 static int eeepc_hotk_thaw(struct device *device)
885 {
886 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
887
888 if (eeepc->wlan_rfkill) {
889 int wlan;
890
891 /*
892 * Work around bios bug - acpi _PTS turns off the wireless led
893 * during suspend. Normally it restores it on resume, but
894 * we should kick it ourselves in case hibernation is aborted.
895 */
896 wlan = get_acpi(eeepc, CM_ASL_WLAN);
897 if (wlan >= 0)
898 set_acpi(eeepc, CM_ASL_WLAN, wlan);
899 }
900
901 return 0;
902 }
903
eeepc_hotk_restore(struct device * device)904 static int eeepc_hotk_restore(struct device *device)
905 {
906 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
907
908 /* Refresh both wlan rfkill state and pci hotplug */
909 if (eeepc->wlan_rfkill) {
910 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_1);
911 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_2);
912 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_3);
913 }
914
915 if (eeepc->bluetooth_rfkill)
916 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
917 get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
918 if (eeepc->wwan3g_rfkill)
919 rfkill_set_sw_state(eeepc->wwan3g_rfkill,
920 get_acpi(eeepc, CM_ASL_3G) != 1);
921 if (eeepc->wimax_rfkill)
922 rfkill_set_sw_state(eeepc->wimax_rfkill,
923 get_acpi(eeepc, CM_ASL_WIMAX) != 1);
924
925 return 0;
926 }
927
928 static const struct dev_pm_ops eeepc_pm_ops = {
929 .thaw = eeepc_hotk_thaw,
930 .restore = eeepc_hotk_restore,
931 };
932
933 static struct platform_driver platform_driver = {
934 .driver = {
935 .name = EEEPC_LAPTOP_FILE,
936 .pm = &eeepc_pm_ops,
937 }
938 };
939
940 /*
941 * Hwmon device
942 */
943
944 #define EEEPC_EC_SC00 0x61
945 #define EEEPC_EC_FAN_PWM (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
946 #define EEEPC_EC_FAN_HRPM (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
947 #define EEEPC_EC_FAN_LRPM (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
948
949 #define EEEPC_EC_SFB0 0xD0
950 #define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */
951
eeepc_pwm_to_lmsensors(int value)952 static inline int eeepc_pwm_to_lmsensors(int value)
953 {
954 return value * 255 / 100;
955 }
956
eeepc_lmsensors_to_pwm(int value)957 static inline int eeepc_lmsensors_to_pwm(int value)
958 {
959 value = clamp_val(value, 0, 255);
960 return value * 100 / 255;
961 }
962
eeepc_get_fan_pwm(void)963 static int eeepc_get_fan_pwm(void)
964 {
965 u8 value = 0;
966
967 ec_read(EEEPC_EC_FAN_PWM, &value);
968 return eeepc_pwm_to_lmsensors(value);
969 }
970
eeepc_set_fan_pwm(int value)971 static void eeepc_set_fan_pwm(int value)
972 {
973 value = eeepc_lmsensors_to_pwm(value);
974 ec_write(EEEPC_EC_FAN_PWM, value);
975 }
976
eeepc_get_fan_rpm(void)977 static int eeepc_get_fan_rpm(void)
978 {
979 u8 high = 0;
980 u8 low = 0;
981
982 ec_read(EEEPC_EC_FAN_HRPM, &high);
983 ec_read(EEEPC_EC_FAN_LRPM, &low);
984 return high << 8 | low;
985 }
986
987 #define EEEPC_EC_FAN_CTRL_BIT 0x02
988 #define EEEPC_FAN_CTRL_MANUAL 1
989 #define EEEPC_FAN_CTRL_AUTO 2
990
eeepc_get_fan_ctrl(void)991 static int eeepc_get_fan_ctrl(void)
992 {
993 u8 value = 0;
994
995 ec_read(EEEPC_EC_FAN_CTRL, &value);
996 if (value & EEEPC_EC_FAN_CTRL_BIT)
997 return EEEPC_FAN_CTRL_MANUAL;
998 else
999 return EEEPC_FAN_CTRL_AUTO;
1000 }
1001
eeepc_set_fan_ctrl(int manual)1002 static void eeepc_set_fan_ctrl(int manual)
1003 {
1004 u8 value = 0;
1005
1006 ec_read(EEEPC_EC_FAN_CTRL, &value);
1007 if (manual == EEEPC_FAN_CTRL_MANUAL)
1008 value |= EEEPC_EC_FAN_CTRL_BIT;
1009 else
1010 value &= ~EEEPC_EC_FAN_CTRL_BIT;
1011 ec_write(EEEPC_EC_FAN_CTRL, value);
1012 }
1013
store_sys_hwmon(void (* set)(int),const char * buf,size_t count)1014 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1015 {
1016 int rv, value;
1017
1018 rv = parse_arg(buf, &value);
1019 if (rv < 0)
1020 return rv;
1021 set(value);
1022 return count;
1023 }
1024
show_sys_hwmon(int (* get)(void),char * buf)1025 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1026 {
1027 return sysfs_emit(buf, "%d\n", get());
1028 }
1029
1030 #define EEEPC_SENSOR_SHOW_FUNC(_name, _get) \
1031 static ssize_t _name##_show(struct device *dev, \
1032 struct device_attribute *attr, \
1033 char *buf) \
1034 { \
1035 return show_sys_hwmon(_get, buf); \
1036 }
1037
1038 #define EEEPC_SENSOR_STORE_FUNC(_name, _set) \
1039 static ssize_t _name##_store(struct device *dev, \
1040 struct device_attribute *attr, \
1041 const char *buf, size_t count) \
1042 { \
1043 return store_sys_hwmon(_set, buf, count); \
1044 }
1045
1046 #define EEEPC_CREATE_SENSOR_ATTR_RW(_name, _get, _set) \
1047 EEEPC_SENSOR_SHOW_FUNC(_name, _get) \
1048 EEEPC_SENSOR_STORE_FUNC(_name, _set) \
1049 static DEVICE_ATTR_RW(_name)
1050
1051 #define EEEPC_CREATE_SENSOR_ATTR_RO(_name, _get) \
1052 EEEPC_SENSOR_SHOW_FUNC(_name, _get) \
1053 static DEVICE_ATTR_RO(_name)
1054
1055 EEEPC_CREATE_SENSOR_ATTR_RO(fan1_input, eeepc_get_fan_rpm);
1056 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1, eeepc_get_fan_pwm,
1057 eeepc_set_fan_pwm);
1058 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1_enable, eeepc_get_fan_ctrl,
1059 eeepc_set_fan_ctrl);
1060
1061 static struct attribute *hwmon_attrs[] = {
1062 &dev_attr_pwm1.attr,
1063 &dev_attr_fan1_input.attr,
1064 &dev_attr_pwm1_enable.attr,
1065 NULL
1066 };
1067 ATTRIBUTE_GROUPS(hwmon);
1068
eeepc_hwmon_init(struct eeepc_laptop * eeepc)1069 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1070 {
1071 struct device *dev = &eeepc->platform_device->dev;
1072 struct device *hwmon;
1073
1074 hwmon = devm_hwmon_device_register_with_groups(dev, "eeepc", NULL,
1075 hwmon_groups);
1076 if (IS_ERR(hwmon)) {
1077 pr_err("Could not register eeepc hwmon device\n");
1078 return PTR_ERR(hwmon);
1079 }
1080 return 0;
1081 }
1082
1083 /*
1084 * Backlight device
1085 */
read_brightness(struct backlight_device * bd)1086 static int read_brightness(struct backlight_device *bd)
1087 {
1088 struct eeepc_laptop *eeepc = bl_get_data(bd);
1089
1090 return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1091 }
1092
set_brightness(struct backlight_device * bd,int value)1093 static int set_brightness(struct backlight_device *bd, int value)
1094 {
1095 struct eeepc_laptop *eeepc = bl_get_data(bd);
1096
1097 return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1098 }
1099
update_bl_status(struct backlight_device * bd)1100 static int update_bl_status(struct backlight_device *bd)
1101 {
1102 return set_brightness(bd, bd->props.brightness);
1103 }
1104
1105 static const struct backlight_ops eeepcbl_ops = {
1106 .get_brightness = read_brightness,
1107 .update_status = update_bl_status,
1108 };
1109
eeepc_backlight_notify(struct eeepc_laptop * eeepc)1110 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1111 {
1112 struct backlight_device *bd = eeepc->backlight_device;
1113 int old = bd->props.brightness;
1114
1115 backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1116
1117 return old;
1118 }
1119
eeepc_backlight_init(struct eeepc_laptop * eeepc)1120 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1121 {
1122 struct backlight_properties props;
1123 struct backlight_device *bd;
1124
1125 memset(&props, 0, sizeof(struct backlight_properties));
1126 props.type = BACKLIGHT_PLATFORM;
1127 props.max_brightness = 15;
1128 bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1129 &eeepc->platform_device->dev, eeepc,
1130 &eeepcbl_ops, &props);
1131 if (IS_ERR(bd)) {
1132 pr_err("Could not register eeepc backlight device\n");
1133 eeepc->backlight_device = NULL;
1134 return PTR_ERR(bd);
1135 }
1136 eeepc->backlight_device = bd;
1137 bd->props.brightness = read_brightness(bd);
1138 bd->props.power = BACKLIGHT_POWER_ON;
1139 backlight_update_status(bd);
1140 return 0;
1141 }
1142
eeepc_backlight_exit(struct eeepc_laptop * eeepc)1143 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1144 {
1145 backlight_device_unregister(eeepc->backlight_device);
1146 eeepc->backlight_device = NULL;
1147 }
1148
1149
1150 /*
1151 * Input device (i.e. hotkeys)
1152 */
eeepc_input_init(struct eeepc_laptop * eeepc)1153 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1154 {
1155 struct input_dev *input;
1156 int error;
1157
1158 input = input_allocate_device();
1159 if (!input)
1160 return -ENOMEM;
1161
1162 input->name = "Asus EeePC extra buttons";
1163 input->phys = EEEPC_LAPTOP_FILE "/input0";
1164 input->id.bustype = BUS_HOST;
1165 input->dev.parent = &eeepc->platform_device->dev;
1166
1167 error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1168 if (error) {
1169 pr_err("Unable to setup input device keymap\n");
1170 goto err_free_dev;
1171 }
1172
1173 error = input_register_device(input);
1174 if (error) {
1175 pr_err("Unable to register input device\n");
1176 goto err_free_dev;
1177 }
1178
1179 eeepc->inputdev = input;
1180 return 0;
1181
1182 err_free_dev:
1183 input_free_device(input);
1184 return error;
1185 }
1186
eeepc_input_exit(struct eeepc_laptop * eeepc)1187 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1188 {
1189 if (eeepc->inputdev)
1190 input_unregister_device(eeepc->inputdev);
1191 eeepc->inputdev = NULL;
1192 }
1193
1194 /*
1195 * ACPI driver
1196 */
eeepc_input_notify(struct eeepc_laptop * eeepc,int event)1197 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1198 {
1199 if (!eeepc->inputdev)
1200 return;
1201 if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
1202 pr_info("Unknown key %x pressed\n", event);
1203 }
1204
eeepc_acpi_notify(acpi_handle handle,u32 event,void * data)1205 static void eeepc_acpi_notify(acpi_handle handle, u32 event, void *data)
1206 {
1207 struct eeepc_laptop *eeepc = data;
1208 struct acpi_device *device = eeepc->device;
1209 int old_brightness, new_brightness;
1210 u16 count;
1211
1212 if (event > ACPI_MAX_SYS_NOTIFY)
1213 return;
1214 count = eeepc->event_count[event % 128]++;
1215 acpi_bus_generate_netlink_event("hotkey", dev_name(&device->dev), event,
1216 count);
1217
1218 /* Brightness events are special */
1219 if (event < NOTIFY_BRN_MIN || event > NOTIFY_BRN_MAX) {
1220 eeepc_input_notify(eeepc, event);
1221 return;
1222 }
1223
1224 /* Ignore them completely if the acpi video driver is used */
1225 if (!eeepc->backlight_device)
1226 return;
1227
1228 /* Update the backlight device. */
1229 old_brightness = eeepc_backlight_notify(eeepc);
1230
1231 /* Convert event to keypress (obsolescent hack) */
1232 new_brightness = event - NOTIFY_BRN_MIN;
1233
1234 if (new_brightness < old_brightness) {
1235 event = NOTIFY_BRN_MIN; /* brightness down */
1236 } else if (new_brightness > old_brightness) {
1237 event = NOTIFY_BRN_MAX; /* brightness up */
1238 } else {
1239 /*
1240 * no change in brightness - already at min/max,
1241 * event will be desired value (or else ignored)
1242 */
1243 }
1244 eeepc_input_notify(eeepc, event);
1245 }
1246
eeepc_dmi_check(struct eeepc_laptop * eeepc)1247 static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1248 {
1249 const char *model;
1250
1251 model = dmi_get_system_info(DMI_PRODUCT_NAME);
1252 if (!model)
1253 return;
1254
1255 /*
1256 * Blacklist for setting cpufv (cpu speed).
1257 *
1258 * EeePC 4G ("701") implements CFVS, but it is not supported
1259 * by the pre-installed OS, and the original option to change it
1260 * in the BIOS setup screen was removed in later versions.
1261 *
1262 * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1263 * this applies to all "701" models (4G/4G Surf/2G Surf).
1264 *
1265 * So Asus made a deliberate decision not to support it on this model.
1266 * We have several reports that using it can cause the system to hang
1267 *
1268 * The hang has also been reported on a "702" (Model name "8G"?).
1269 *
1270 * We avoid dmi_check_system() / dmi_match(), because they use
1271 * substring matching. We don't want to affect the "701SD"
1272 * and "701SDX" models, because they do support S.H.E.
1273 */
1274 if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1275 eeepc->cpufv_disabled = true;
1276 pr_info("model %s does not officially support setting cpu speed\n",
1277 model);
1278 pr_info("cpufv disabled to avoid instability\n");
1279 }
1280
1281 /*
1282 * Blacklist for wlan hotplug
1283 *
1284 * Eeepc 1005HA doesn't work like others models and don't need the
1285 * hotplug code. In fact, current hotplug code seems to unplug another
1286 * device...
1287 */
1288 if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
1289 strcmp(model, "1005PE") == 0) {
1290 eeepc->hotplug_disabled = true;
1291 pr_info("wlan hotplug disabled\n");
1292 }
1293 }
1294
cmsg_quirk(struct eeepc_laptop * eeepc,int cm,const char * name)1295 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1296 {
1297 int dummy;
1298
1299 /* Some BIOSes do not report cm although it is available.
1300 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1301 if (!(eeepc->cm_supported & (1 << cm))
1302 && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1303 pr_info("%s (%x) not reported by BIOS, enabling anyway\n",
1304 name, 1 << cm);
1305 eeepc->cm_supported |= 1 << cm;
1306 }
1307 }
1308
cmsg_quirks(struct eeepc_laptop * eeepc)1309 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1310 {
1311 cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1312 cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1313 cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1314 cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1315 }
1316
eeepc_acpi_init(struct eeepc_laptop * eeepc)1317 static int eeepc_acpi_init(struct eeepc_laptop *eeepc)
1318 {
1319 unsigned int init_flags;
1320 int result;
1321
1322 result = acpi_bus_get_status(eeepc->device);
1323 if (result)
1324 return result;
1325 if (!eeepc->device->status.present) {
1326 pr_err("Hotkey device not present, aborting\n");
1327 return -ENODEV;
1328 }
1329
1330 init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1331 pr_notice("Hotkey init flags 0x%x\n", init_flags);
1332
1333 if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1334 pr_err("Hotkey initialization failed\n");
1335 return -ENODEV;
1336 }
1337
1338 /* get control methods supported */
1339 if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1340 pr_err("Get control methods supported failed\n");
1341 return -ENODEV;
1342 }
1343 cmsg_quirks(eeepc);
1344 pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1345
1346 return 0;
1347 }
1348
eeepc_enable_camera(struct eeepc_laptop * eeepc)1349 static void eeepc_enable_camera(struct eeepc_laptop *eeepc)
1350 {
1351 /*
1352 * If the following call to set_acpi() fails, it's because there's no
1353 * camera so we can ignore the error.
1354 */
1355 if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1356 set_acpi(eeepc, CM_ASL_CAMERA, 1);
1357 }
1358
1359 static bool eeepc_device_present;
1360
eeepc_acpi_probe(struct platform_device * pdev)1361 static int eeepc_acpi_probe(struct platform_device *pdev)
1362 {
1363 struct acpi_device *device;
1364 struct eeepc_laptop *eeepc;
1365 int result;
1366
1367 device = ACPI_COMPANION(&pdev->dev);
1368 if (!device)
1369 return -ENODEV;
1370
1371 pr_notice(EEEPC_LAPTOP_NAME "\n");
1372 eeepc = kzalloc_obj(struct eeepc_laptop);
1373 if (!eeepc)
1374 return -ENOMEM;
1375 eeepc->handle = device->handle;
1376 eeepc->device = device;
1377
1378 platform_set_drvdata(pdev, eeepc);
1379
1380 eeepc->hotplug_disabled = hotplug_disabled;
1381
1382 eeepc_dmi_check(eeepc);
1383
1384 result = eeepc_acpi_init(eeepc);
1385 if (result)
1386 goto fail_platform;
1387 eeepc_enable_camera(eeepc);
1388
1389 /*
1390 * Register the platform device first. It is used as a parent for the
1391 * sub-devices below.
1392 *
1393 * Note that if there are multiple instances of this ACPI device it
1394 * will bail out, because the platform device is registered with a
1395 * fixed name. Of course it doesn't make sense to have more than one,
1396 * and machine-specific scripts find the fixed name convenient. But
1397 * It's also good for us to exclude multiple instances because both
1398 * our hwmon and our wlan rfkill subdevice use global ACPI objects
1399 * (the EC and the PCI wlan slot respectively).
1400 */
1401 result = eeepc_platform_init(eeepc);
1402 if (result)
1403 goto fail_platform;
1404
1405 if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
1406 result = eeepc_backlight_init(eeepc);
1407 if (result)
1408 goto fail_backlight;
1409 }
1410
1411 result = eeepc_input_init(eeepc);
1412 if (result)
1413 goto fail_input;
1414
1415 result = eeepc_hwmon_init(eeepc);
1416 if (result)
1417 goto fail_hwmon;
1418
1419 result = eeepc_led_init(eeepc);
1420 if (result)
1421 goto fail_led;
1422
1423 result = eeepc_rfkill_init(eeepc);
1424 if (result)
1425 goto fail_rfkill;
1426
1427 result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
1428 eeepc_acpi_notify, eeepc);
1429 if (result)
1430 goto fail_acpi_notifier;
1431
1432 eeepc_device_present = true;
1433 return 0;
1434
1435 fail_acpi_notifier:
1436 eeepc_rfkill_exit(eeepc);
1437 fail_rfkill:
1438 eeepc_led_exit(eeepc);
1439 fail_led:
1440 fail_hwmon:
1441 eeepc_input_exit(eeepc);
1442 fail_input:
1443 eeepc_backlight_exit(eeepc);
1444 fail_backlight:
1445 eeepc_platform_exit(eeepc);
1446 fail_platform:
1447 kfree(eeepc);
1448
1449 return result;
1450 }
1451
eeepc_acpi_remove(struct platform_device * pdev)1452 static void eeepc_acpi_remove(struct platform_device *pdev)
1453 {
1454 struct eeepc_laptop *eeepc = platform_get_drvdata(pdev);
1455
1456 acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
1457 ACPI_ALL_NOTIFY, eeepc_acpi_notify);
1458 eeepc_backlight_exit(eeepc);
1459 eeepc_rfkill_exit(eeepc);
1460 eeepc_input_exit(eeepc);
1461 eeepc_led_exit(eeepc);
1462 eeepc_platform_exit(eeepc);
1463
1464 kfree(eeepc);
1465 }
1466
1467
1468 static const struct acpi_device_id eeepc_device_ids[] = {
1469 {EEEPC_ACPI_HID, 0},
1470 {"", 0},
1471 };
1472 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1473
1474 static struct platform_driver eeepc_acpi_driver = {
1475 .probe = eeepc_acpi_probe,
1476 .remove = eeepc_acpi_remove,
1477 .driver = {
1478 .name = EEEPC_LAPTOP_NAME,
1479 .acpi_match_table = eeepc_device_ids,
1480 },
1481 };
1482
1483
eeepc_laptop_init(void)1484 static int __init eeepc_laptop_init(void)
1485 {
1486 int result;
1487
1488 result = platform_driver_register(&platform_driver);
1489 if (result < 0)
1490 return result;
1491
1492 result = platform_driver_register(&eeepc_acpi_driver);
1493 if (result < 0)
1494 goto fail_acpi_driver;
1495
1496 if (!eeepc_device_present) {
1497 result = -ENODEV;
1498 goto fail_no_device;
1499 }
1500
1501 return 0;
1502
1503 fail_no_device:
1504 platform_driver_unregister(&eeepc_acpi_driver);
1505 fail_acpi_driver:
1506 platform_driver_unregister(&platform_driver);
1507 return result;
1508 }
1509
eeepc_laptop_exit(void)1510 static void __exit eeepc_laptop_exit(void)
1511 {
1512 platform_driver_unregister(&eeepc_acpi_driver);
1513 platform_driver_unregister(&platform_driver);
1514 }
1515
1516 module_init(eeepc_laptop_init);
1517 module_exit(eeepc_laptop_exit);
1518