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