Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  eeepc-laptop.c - Asus Eee PC extras
0004  *
0005  *  Based on asus_acpi.c as patched for the Eee PC by Asus:
0006  *  ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
0007  *  Based on eee.c from eeepc-linux
0008  */
0009 
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/init.h>
0015 #include <linux/types.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/backlight.h>
0018 #include <linux/fb.h>
0019 #include <linux/hwmon.h>
0020 #include <linux/hwmon-sysfs.h>
0021 #include <linux/slab.h>
0022 #include <linux/acpi.h>
0023 #include <linux/uaccess.h>
0024 #include <linux/input.h>
0025 #include <linux/input/sparse-keymap.h>
0026 #include <linux/rfkill.h>
0027 #include <linux/pci.h>
0028 #include <linux/pci_hotplug.h>
0029 #include <linux/leds.h>
0030 #include <linux/dmi.h>
0031 #include <acpi/video.h>
0032 
0033 #define EEEPC_LAPTOP_VERSION    "0.1"
0034 #define EEEPC_LAPTOP_NAME   "Eee PC Hotkey Driver"
0035 #define EEEPC_LAPTOP_FILE   "eeepc"
0036 
0037 #define EEEPC_ACPI_CLASS    "hotkey"
0038 #define EEEPC_ACPI_DEVICE_NAME  "Hotkey"
0039 #define EEEPC_ACPI_HID      "ASUS010"
0040 
0041 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
0042 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
0043 MODULE_LICENSE("GPL");
0044 
0045 static bool hotplug_disabled;
0046 
0047 module_param(hotplug_disabled, bool, 0444);
0048 MODULE_PARM_DESC(hotplug_disabled,
0049          "Disable hotplug for wireless device. "
0050          "If your laptop need that, please report to "
0051          "acpi4asus-user@lists.sourceforge.net.");
0052 
0053 /*
0054  * Definitions for Asus EeePC
0055  */
0056 #define NOTIFY_BRN_MIN  0x20
0057 #define NOTIFY_BRN_MAX  0x2f
0058 
0059 enum {
0060     DISABLE_ASL_WLAN = 0x0001,
0061     DISABLE_ASL_BLUETOOTH = 0x0002,
0062     DISABLE_ASL_IRDA = 0x0004,
0063     DISABLE_ASL_CAMERA = 0x0008,
0064     DISABLE_ASL_TV = 0x0010,
0065     DISABLE_ASL_GPS = 0x0020,
0066     DISABLE_ASL_DISPLAYSWITCH = 0x0040,
0067     DISABLE_ASL_MODEM = 0x0080,
0068     DISABLE_ASL_CARDREADER = 0x0100,
0069     DISABLE_ASL_3G = 0x0200,
0070     DISABLE_ASL_WIMAX = 0x0400,
0071     DISABLE_ASL_HWCF = 0x0800
0072 };
0073 
0074 enum {
0075     CM_ASL_WLAN = 0,
0076     CM_ASL_BLUETOOTH,
0077     CM_ASL_IRDA,
0078     CM_ASL_1394,
0079     CM_ASL_CAMERA,
0080     CM_ASL_TV,
0081     CM_ASL_GPS,
0082     CM_ASL_DVDROM,
0083     CM_ASL_DISPLAYSWITCH,
0084     CM_ASL_PANELBRIGHT,
0085     CM_ASL_BIOSFLASH,
0086     CM_ASL_ACPIFLASH,
0087     CM_ASL_CPUFV,
0088     CM_ASL_CPUTEMPERATURE,
0089     CM_ASL_FANCPU,
0090     CM_ASL_FANCHASSIS,
0091     CM_ASL_USBPORT1,
0092     CM_ASL_USBPORT2,
0093     CM_ASL_USBPORT3,
0094     CM_ASL_MODEM,
0095     CM_ASL_CARDREADER,
0096     CM_ASL_3G,
0097     CM_ASL_WIMAX,
0098     CM_ASL_HWCF,
0099     CM_ASL_LID,
0100     CM_ASL_TYPE,
0101     CM_ASL_PANELPOWER,  /*P901*/
0102     CM_ASL_TPD
0103 };
0104 
0105 static const char *cm_getv[] = {
0106     "WLDG", "BTHG", NULL, NULL,
0107     "CAMG", NULL, NULL, NULL,
0108     NULL, "PBLG", NULL, NULL,
0109     "CFVG", NULL, NULL, NULL,
0110     "USBG", NULL, NULL, "MODG",
0111     "CRDG", "M3GG", "WIMG", "HWCF",
0112     "LIDG", "TYPE", "PBPG", "TPDG"
0113 };
0114 
0115 static const char *cm_setv[] = {
0116     "WLDS", "BTHS", NULL, NULL,
0117     "CAMS", NULL, NULL, NULL,
0118     "SDSP", "PBLS", "HDPS", NULL,
0119     "CFVS", NULL, NULL, NULL,
0120     "USBG", NULL, NULL, "MODS",
0121     "CRDS", "M3GS", "WIMS", NULL,
0122     NULL, NULL, "PBPS", "TPDS"
0123 };
0124 
0125 static const struct key_entry eeepc_keymap[] = {
0126     { KE_KEY, 0x10, { KEY_WLAN } },
0127     { KE_KEY, 0x11, { KEY_WLAN } },
0128     { KE_KEY, 0x12, { KEY_PROG1 } },
0129     { KE_KEY, 0x13, { KEY_MUTE } },
0130     { KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
0131     { KE_KEY, 0x15, { KEY_VOLUMEUP } },
0132     { KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
0133     { KE_KEY, 0x1a, { KEY_COFFEE } },
0134     { KE_KEY, 0x1b, { KEY_ZOOM } },
0135     { KE_KEY, 0x1c, { KEY_PROG2 } },
0136     { KE_KEY, 0x1d, { KEY_PROG3 } },
0137     { KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
0138     { KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
0139     { KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
0140     { KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
0141     { KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
0142     { KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
0143     { KE_KEY, 0x38, { KEY_F14 } },
0144     { KE_IGNORE, 0x50, { KEY_RESERVED } }, /* AC plugged */
0145     { KE_IGNORE, 0x51, { KEY_RESERVED } }, /* AC unplugged */
0146     { KE_END, 0 },
0147 };
0148 
0149 /*
0150  * This is the main structure, we can use it to store useful information
0151  */
0152 struct eeepc_laptop {
0153     acpi_handle handle;     /* the handle of the acpi device */
0154     u32 cm_supported;       /* the control methods supported
0155                        by this BIOS */
0156     bool cpufv_disabled;
0157     bool hotplug_disabled;
0158     u16 event_count[128];       /* count for each event */
0159 
0160     struct platform_device *platform_device;
0161     struct acpi_device *device;     /* the device we are in */
0162     struct backlight_device *backlight_device;
0163 
0164     struct input_dev *inputdev;
0165 
0166     struct rfkill *wlan_rfkill;
0167     struct rfkill *bluetooth_rfkill;
0168     struct rfkill *wwan3g_rfkill;
0169     struct rfkill *wimax_rfkill;
0170 
0171     struct hotplug_slot hotplug_slot;
0172     struct mutex hotplug_lock;
0173 
0174     struct led_classdev tpd_led;
0175     int tpd_led_wk;
0176     struct workqueue_struct *led_workqueue;
0177     struct work_struct tpd_led_work;
0178 };
0179 
0180 /*
0181  * ACPI Helpers
0182  */
0183 static int write_acpi_int(acpi_handle handle, const char *method, int val)
0184 {
0185     acpi_status status;
0186 
0187     status = acpi_execute_simple_method(handle, (char *)method, val);
0188 
0189     return (status == AE_OK ? 0 : -1);
0190 }
0191 
0192 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
0193 {
0194     acpi_status status;
0195     unsigned long long result;
0196 
0197     status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
0198     if (ACPI_FAILURE(status)) {
0199         *val = -1;
0200         return -1;
0201     } else {
0202         *val = result;
0203         return 0;
0204     }
0205 }
0206 
0207 static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
0208 {
0209     const char *method = cm_setv[cm];
0210 
0211     if (method == NULL)
0212         return -ENODEV;
0213     if ((eeepc->cm_supported & (0x1 << cm)) == 0)
0214         return -ENODEV;
0215 
0216     if (write_acpi_int(eeepc->handle, method, value))
0217         pr_warn("Error writing %s\n", method);
0218     return 0;
0219 }
0220 
0221 static int get_acpi(struct eeepc_laptop *eeepc, int cm)
0222 {
0223     const char *method = cm_getv[cm];
0224     int value;
0225 
0226     if (method == NULL)
0227         return -ENODEV;
0228     if ((eeepc->cm_supported & (0x1 << cm)) == 0)
0229         return -ENODEV;
0230 
0231     if (read_acpi_int(eeepc->handle, method, &value))
0232         pr_warn("Error reading %s\n", method);
0233     return value;
0234 }
0235 
0236 static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
0237                   acpi_handle *handle)
0238 {
0239     const char *method = cm_setv[cm];
0240     acpi_status status;
0241 
0242     if (method == NULL)
0243         return -ENODEV;
0244     if ((eeepc->cm_supported & (0x1 << cm)) == 0)
0245         return -ENODEV;
0246 
0247     status = acpi_get_handle(eeepc->handle, (char *)method,
0248                  handle);
0249     if (status != AE_OK) {
0250         pr_warn("Error finding %s\n", method);
0251         return -ENODEV;
0252     }
0253     return 0;
0254 }
0255 
0256 
0257 /*
0258  * Sys helpers
0259  */
0260 static int parse_arg(const char *buf, int *val)
0261 {
0262     if (sscanf(buf, "%i", val) != 1)
0263         return -EINVAL;
0264     return 0;
0265 }
0266 
0267 static ssize_t store_sys_acpi(struct device *dev, int cm,
0268                   const char *buf, size_t count)
0269 {
0270     struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
0271     int rv, value;
0272 
0273     rv = parse_arg(buf, &value);
0274     if (rv < 0)
0275         return rv;
0276     rv = set_acpi(eeepc, cm, value);
0277     if (rv < 0)
0278         return -EIO;
0279     return count;
0280 }
0281 
0282 static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
0283 {
0284     struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
0285     int value = get_acpi(eeepc, cm);
0286 
0287     if (value < 0)
0288         return -EIO;
0289     return sprintf(buf, "%d\n", value);
0290 }
0291 
0292 #define EEEPC_ACPI_SHOW_FUNC(_name, _cm)                \
0293     static ssize_t _name##_show(struct device *dev,         \
0294                     struct device_attribute *attr,  \
0295                     char *buf)              \
0296     {                               \
0297         return show_sys_acpi(dev, _cm, buf);            \
0298     }
0299 
0300 #define EEEPC_ACPI_STORE_FUNC(_name, _cm)               \
0301     static ssize_t _name##_store(struct device *dev,        \
0302                      struct device_attribute *attr, \
0303                      const char *buf, size_t count) \
0304     {                               \
0305         return store_sys_acpi(dev, _cm, buf, count);        \
0306     }
0307 
0308 #define EEEPC_CREATE_DEVICE_ATTR_RW(_name, _cm)             \
0309     EEEPC_ACPI_SHOW_FUNC(_name, _cm)                \
0310     EEEPC_ACPI_STORE_FUNC(_name, _cm)               \
0311     static DEVICE_ATTR_RW(_name)
0312 
0313 #define EEEPC_CREATE_DEVICE_ATTR_WO(_name, _cm)             \
0314     EEEPC_ACPI_STORE_FUNC(_name, _cm)               \
0315     static DEVICE_ATTR_WO(_name)
0316 
0317 EEEPC_CREATE_DEVICE_ATTR_RW(camera, CM_ASL_CAMERA);
0318 EEEPC_CREATE_DEVICE_ATTR_RW(cardr, CM_ASL_CARDREADER);
0319 EEEPC_CREATE_DEVICE_ATTR_WO(disp, CM_ASL_DISPLAYSWITCH);
0320 
0321 struct eeepc_cpufv {
0322     int num;
0323     int cur;
0324 };
0325 
0326 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
0327 {
0328     c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
0329     if (c->cur < 0)
0330         return -ENODEV;
0331 
0332     c->num = (c->cur >> 8) & 0xff;
0333     c->cur &= 0xff;
0334     if (c->num == 0 || c->num > 12)
0335         return -ENODEV;
0336     return 0;
0337 }
0338 
0339 static ssize_t available_cpufv_show(struct device *dev,
0340                     struct device_attribute *attr,
0341                     char *buf)
0342 {
0343     struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
0344     struct eeepc_cpufv c;
0345     int i;
0346     ssize_t len = 0;
0347 
0348     if (get_cpufv(eeepc, &c))
0349         return -ENODEV;
0350     for (i = 0; i < c.num; i++)
0351         len += sprintf(buf + len, "%d ", i);
0352     len += sprintf(buf + len, "\n");
0353     return len;
0354 }
0355 
0356 static ssize_t cpufv_show(struct device *dev,
0357               struct device_attribute *attr,
0358               char *buf)
0359 {
0360     struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
0361     struct eeepc_cpufv c;
0362 
0363     if (get_cpufv(eeepc, &c))
0364         return -ENODEV;
0365     return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
0366 }
0367 
0368 static ssize_t cpufv_store(struct device *dev,
0369                struct device_attribute *attr,
0370                const char *buf, size_t count)
0371 {
0372     struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
0373     struct eeepc_cpufv c;
0374     int rv, value;
0375 
0376     if (eeepc->cpufv_disabled)
0377         return -EPERM;
0378     if (get_cpufv(eeepc, &c))
0379         return -ENODEV;
0380     rv = parse_arg(buf, &value);
0381     if (rv < 0)
0382         return rv;
0383     if (value < 0 || value >= c.num)
0384         return -EINVAL;
0385     rv = set_acpi(eeepc, CM_ASL_CPUFV, value);
0386     if (rv)
0387         return rv;
0388     return count;
0389 }
0390 
0391 static ssize_t cpufv_disabled_show(struct device *dev,
0392               struct device_attribute *attr,
0393               char *buf)
0394 {
0395     struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
0396 
0397     return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
0398 }
0399 
0400 static ssize_t cpufv_disabled_store(struct device *dev,
0401                struct device_attribute *attr,
0402                const char *buf, size_t count)
0403 {
0404     struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
0405     int rv, value;
0406 
0407     rv = parse_arg(buf, &value);
0408     if (rv < 0)
0409         return rv;
0410 
0411     switch (value) {
0412     case 0:
0413         if (eeepc->cpufv_disabled)
0414             pr_warn("cpufv enabled (not officially supported on this model)\n");
0415         eeepc->cpufv_disabled = false;
0416         return count;
0417     case 1:
0418         return -EPERM;
0419     default:
0420         return -EINVAL;
0421     }
0422 }
0423 
0424 
0425 static DEVICE_ATTR_RW(cpufv);
0426 static DEVICE_ATTR_RO(available_cpufv);
0427 static DEVICE_ATTR_RW(cpufv_disabled);
0428 
0429 static struct attribute *platform_attributes[] = {
0430     &dev_attr_camera.attr,
0431     &dev_attr_cardr.attr,
0432     &dev_attr_disp.attr,
0433     &dev_attr_cpufv.attr,
0434     &dev_attr_available_cpufv.attr,
0435     &dev_attr_cpufv_disabled.attr,
0436     NULL
0437 };
0438 
0439 static const struct attribute_group platform_attribute_group = {
0440     .attrs = platform_attributes
0441 };
0442 
0443 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
0444 {
0445     int result;
0446 
0447     eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
0448     if (!eeepc->platform_device)
0449         return -ENOMEM;
0450     platform_set_drvdata(eeepc->platform_device, eeepc);
0451 
0452     result = platform_device_add(eeepc->platform_device);
0453     if (result)
0454         goto fail_platform_device;
0455 
0456     result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
0457                     &platform_attribute_group);
0458     if (result)
0459         goto fail_sysfs;
0460     return 0;
0461 
0462 fail_sysfs:
0463     platform_device_del(eeepc->platform_device);
0464 fail_platform_device:
0465     platform_device_put(eeepc->platform_device);
0466     return result;
0467 }
0468 
0469 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
0470 {
0471     sysfs_remove_group(&eeepc->platform_device->dev.kobj,
0472                &platform_attribute_group);
0473     platform_device_unregister(eeepc->platform_device);
0474 }
0475 
0476 /*
0477  * LEDs
0478  */
0479 /*
0480  * These functions actually update the LED's, and are called from a
0481  * workqueue. By doing this as separate work rather than when the LED
0482  * subsystem asks, we avoid messing with the Asus ACPI stuff during a
0483  * potentially bad time, such as a timer interrupt.
0484  */
0485 static void tpd_led_update(struct work_struct *work)
0486 {
0487     struct eeepc_laptop *eeepc;
0488 
0489     eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
0490 
0491     set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
0492 }
0493 
0494 static void tpd_led_set(struct led_classdev *led_cdev,
0495             enum led_brightness value)
0496 {
0497     struct eeepc_laptop *eeepc;
0498 
0499     eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
0500 
0501     eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
0502     queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
0503 }
0504 
0505 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
0506 {
0507     struct eeepc_laptop *eeepc;
0508 
0509     eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
0510 
0511     return get_acpi(eeepc, CM_ASL_TPD);
0512 }
0513 
0514 static int eeepc_led_init(struct eeepc_laptop *eeepc)
0515 {
0516     int rv;
0517 
0518     if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
0519         return 0;
0520 
0521     eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
0522     if (!eeepc->led_workqueue)
0523         return -ENOMEM;
0524     INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
0525 
0526     eeepc->tpd_led.name = "eeepc::touchpad";
0527     eeepc->tpd_led.brightness_set = tpd_led_set;
0528     if (get_acpi(eeepc, CM_ASL_TPD) >= 0) /* if method is available */
0529         eeepc->tpd_led.brightness_get = tpd_led_get;
0530     eeepc->tpd_led.max_brightness = 1;
0531 
0532     rv = led_classdev_register(&eeepc->platform_device->dev,
0533                    &eeepc->tpd_led);
0534     if (rv) {
0535         destroy_workqueue(eeepc->led_workqueue);
0536         return rv;
0537     }
0538 
0539     return 0;
0540 }
0541 
0542 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
0543 {
0544     led_classdev_unregister(&eeepc->tpd_led);
0545     if (eeepc->led_workqueue)
0546         destroy_workqueue(eeepc->led_workqueue);
0547 }
0548 
0549 /*
0550  * PCI hotplug (for wlan rfkill)
0551  */
0552 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
0553 {
0554     if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
0555         return false;
0556     return true;
0557 }
0558 
0559 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
0560 {
0561     struct pci_dev *port;
0562     struct pci_dev *dev;
0563     struct pci_bus *bus;
0564     bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
0565     bool absent;
0566     u32 l;
0567 
0568     if (eeepc->wlan_rfkill)
0569         rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
0570 
0571     mutex_lock(&eeepc->hotplug_lock);
0572     pci_lock_rescan_remove();
0573 
0574     if (!eeepc->hotplug_slot.ops)
0575         goto out_unlock;
0576 
0577     port = acpi_get_pci_dev(handle);
0578     if (!port) {
0579         pr_warn("Unable to find port\n");
0580         goto out_unlock;
0581     }
0582 
0583     bus = port->subordinate;
0584 
0585     if (!bus) {
0586         pr_warn("Unable to find PCI bus 1?\n");
0587         goto out_put_dev;
0588     }
0589 
0590     if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
0591         pr_err("Unable to read PCI config space?\n");
0592         goto out_put_dev;
0593     }
0594 
0595     absent = (l == 0xffffffff);
0596 
0597     if (blocked != absent) {
0598         pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n",
0599             blocked ? "blocked" : "unblocked",
0600             absent ? "absent" : "present");
0601         pr_warn("skipped wireless hotplug as probably inappropriate for this model\n");
0602         goto out_put_dev;
0603     }
0604 
0605     if (!blocked) {
0606         dev = pci_get_slot(bus, 0);
0607         if (dev) {
0608             /* Device already present */
0609             pci_dev_put(dev);
0610             goto out_put_dev;
0611         }
0612         dev = pci_scan_single_device(bus, 0);
0613         if (dev) {
0614             pci_bus_assign_resources(bus);
0615             pci_bus_add_device(dev);
0616         }
0617     } else {
0618         dev = pci_get_slot(bus, 0);
0619         if (dev) {
0620             pci_stop_and_remove_bus_device(dev);
0621             pci_dev_put(dev);
0622         }
0623     }
0624 out_put_dev:
0625     pci_dev_put(port);
0626 
0627 out_unlock:
0628     pci_unlock_rescan_remove();
0629     mutex_unlock(&eeepc->hotplug_lock);
0630 }
0631 
0632 static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
0633 {
0634     acpi_status status = AE_OK;
0635     acpi_handle handle;
0636 
0637     status = acpi_get_handle(NULL, node, &handle);
0638 
0639     if (ACPI_SUCCESS(status))
0640         eeepc_rfkill_hotplug(eeepc, handle);
0641 }
0642 
0643 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
0644 {
0645     struct eeepc_laptop *eeepc = data;
0646 
0647     if (event != ACPI_NOTIFY_BUS_CHECK)
0648         return;
0649 
0650     eeepc_rfkill_hotplug(eeepc, handle);
0651 }
0652 
0653 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
0654                       char *node)
0655 {
0656     acpi_status status;
0657     acpi_handle handle;
0658 
0659     status = acpi_get_handle(NULL, node, &handle);
0660 
0661     if (ACPI_FAILURE(status))
0662         return -ENODEV;
0663 
0664     status = acpi_install_notify_handler(handle,
0665                          ACPI_SYSTEM_NOTIFY,
0666                          eeepc_rfkill_notify,
0667                          eeepc);
0668     if (ACPI_FAILURE(status))
0669         pr_warn("Failed to register notify on %s\n", node);
0670 
0671     /*
0672      * Refresh pci hotplug in case the rfkill state was
0673      * changed during setup.
0674      */
0675     eeepc_rfkill_hotplug(eeepc, handle);
0676     return 0;
0677 }
0678 
0679 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
0680                          char *node)
0681 {
0682     acpi_status status = AE_OK;
0683     acpi_handle handle;
0684 
0685     status = acpi_get_handle(NULL, node, &handle);
0686 
0687     if (ACPI_FAILURE(status))
0688         return;
0689 
0690     status = acpi_remove_notify_handler(handle,
0691                          ACPI_SYSTEM_NOTIFY,
0692                          eeepc_rfkill_notify);
0693     if (ACPI_FAILURE(status))
0694         pr_err("Error removing rfkill notify handler %s\n",
0695             node);
0696         /*
0697          * Refresh pci hotplug in case the rfkill
0698          * state was changed after
0699          * eeepc_unregister_rfkill_notifier()
0700          */
0701     eeepc_rfkill_hotplug(eeepc, handle);
0702 }
0703 
0704 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
0705                     u8 *value)
0706 {
0707     struct eeepc_laptop *eeepc;
0708     int val;
0709 
0710     eeepc = container_of(hotplug_slot, struct eeepc_laptop, hotplug_slot);
0711     val = get_acpi(eeepc, CM_ASL_WLAN);
0712 
0713     if (val == 1 || val == 0)
0714         *value = val;
0715     else
0716         return -EINVAL;
0717 
0718     return 0;
0719 }
0720 
0721 static const struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
0722     .get_adapter_status = eeepc_get_adapter_status,
0723     .get_power_status = eeepc_get_adapter_status,
0724 };
0725 
0726 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
0727 {
0728     int ret = -ENOMEM;
0729     struct pci_bus *bus = pci_find_bus(0, 1);
0730 
0731     if (!bus) {
0732         pr_err("Unable to find wifi PCI bus\n");
0733         return -ENODEV;
0734     }
0735 
0736     eeepc->hotplug_slot.ops = &eeepc_hotplug_slot_ops;
0737 
0738     ret = pci_hp_register(&eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
0739     if (ret) {
0740         pr_err("Unable to register hotplug slot - %d\n", ret);
0741         goto error_register;
0742     }
0743 
0744     return 0;
0745 
0746 error_register:
0747     eeepc->hotplug_slot.ops = NULL;
0748     return ret;
0749 }
0750 
0751 /*
0752  * Rfkill devices
0753  */
0754 static int eeepc_rfkill_set(void *data, bool blocked)
0755 {
0756     acpi_handle handle = data;
0757 
0758     return write_acpi_int(handle, NULL, !blocked);
0759 }
0760 
0761 static const struct rfkill_ops eeepc_rfkill_ops = {
0762     .set_block = eeepc_rfkill_set,
0763 };
0764 
0765 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
0766                 struct rfkill **rfkill,
0767                 const char *name,
0768                 enum rfkill_type type, int cm)
0769 {
0770     acpi_handle handle;
0771     int result;
0772 
0773     result = acpi_setter_handle(eeepc, cm, &handle);
0774     if (result < 0)
0775         return result;
0776 
0777     *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
0778                    &eeepc_rfkill_ops, handle);
0779 
0780     if (!*rfkill)
0781         return -EINVAL;
0782 
0783     rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
0784     result = rfkill_register(*rfkill);
0785     if (result) {
0786         rfkill_destroy(*rfkill);
0787         *rfkill = NULL;
0788         return result;
0789     }
0790     return 0;
0791 }
0792 
0793 static char EEEPC_RFKILL_NODE_1[] = "\\_SB.PCI0.P0P5";
0794 static char EEEPC_RFKILL_NODE_2[] = "\\_SB.PCI0.P0P6";
0795 static char EEEPC_RFKILL_NODE_3[] = "\\_SB.PCI0.P0P7";
0796 
0797 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
0798 {
0799     eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
0800     eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
0801     eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
0802     if (eeepc->wlan_rfkill) {
0803         rfkill_unregister(eeepc->wlan_rfkill);
0804         rfkill_destroy(eeepc->wlan_rfkill);
0805         eeepc->wlan_rfkill = NULL;
0806     }
0807 
0808     if (eeepc->hotplug_slot.ops)
0809         pci_hp_deregister(&eeepc->hotplug_slot);
0810 
0811     if (eeepc->bluetooth_rfkill) {
0812         rfkill_unregister(eeepc->bluetooth_rfkill);
0813         rfkill_destroy(eeepc->bluetooth_rfkill);
0814         eeepc->bluetooth_rfkill = NULL;
0815     }
0816     if (eeepc->wwan3g_rfkill) {
0817         rfkill_unregister(eeepc->wwan3g_rfkill);
0818         rfkill_destroy(eeepc->wwan3g_rfkill);
0819         eeepc->wwan3g_rfkill = NULL;
0820     }
0821     if (eeepc->wimax_rfkill) {
0822         rfkill_unregister(eeepc->wimax_rfkill);
0823         rfkill_destroy(eeepc->wimax_rfkill);
0824         eeepc->wimax_rfkill = NULL;
0825     }
0826 }
0827 
0828 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
0829 {
0830     int result = 0;
0831 
0832     mutex_init(&eeepc->hotplug_lock);
0833 
0834     result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
0835                   "eeepc-wlan", RFKILL_TYPE_WLAN,
0836                   CM_ASL_WLAN);
0837 
0838     if (result && result != -ENODEV)
0839         goto exit;
0840 
0841     result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
0842                   "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
0843                   CM_ASL_BLUETOOTH);
0844 
0845     if (result && result != -ENODEV)
0846         goto exit;
0847 
0848     result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
0849                   "eeepc-wwan3g", RFKILL_TYPE_WWAN,
0850                   CM_ASL_3G);
0851 
0852     if (result && result != -ENODEV)
0853         goto exit;
0854 
0855     result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
0856                   "eeepc-wimax", RFKILL_TYPE_WIMAX,
0857                   CM_ASL_WIMAX);
0858 
0859     if (result && result != -ENODEV)
0860         goto exit;
0861 
0862     if (eeepc->hotplug_disabled)
0863         return 0;
0864 
0865     result = eeepc_setup_pci_hotplug(eeepc);
0866     /*
0867      * If we get -EBUSY then something else is handling the PCI hotplug -
0868      * don't fail in this case
0869      */
0870     if (result == -EBUSY)
0871         result = 0;
0872 
0873     eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
0874     eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
0875     eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
0876 
0877 exit:
0878     if (result && result != -ENODEV)
0879         eeepc_rfkill_exit(eeepc);
0880     return result;
0881 }
0882 
0883 /*
0884  * Platform driver - hibernate/resume callbacks
0885  */
0886 static int eeepc_hotk_thaw(struct device *device)
0887 {
0888     struct eeepc_laptop *eeepc = dev_get_drvdata(device);
0889 
0890     if (eeepc->wlan_rfkill) {
0891         int wlan;
0892 
0893         /*
0894          * Work around bios bug - acpi _PTS turns off the wireless led
0895          * during suspend.  Normally it restores it on resume, but
0896          * we should kick it ourselves in case hibernation is aborted.
0897          */
0898         wlan = get_acpi(eeepc, CM_ASL_WLAN);
0899         if (wlan >= 0)
0900             set_acpi(eeepc, CM_ASL_WLAN, wlan);
0901     }
0902 
0903     return 0;
0904 }
0905 
0906 static int eeepc_hotk_restore(struct device *device)
0907 {
0908     struct eeepc_laptop *eeepc = dev_get_drvdata(device);
0909 
0910     /* Refresh both wlan rfkill state and pci hotplug */
0911     if (eeepc->wlan_rfkill) {
0912         eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_1);
0913         eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_2);
0914         eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_3);
0915     }
0916 
0917     if (eeepc->bluetooth_rfkill)
0918         rfkill_set_sw_state(eeepc->bluetooth_rfkill,
0919                     get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
0920     if (eeepc->wwan3g_rfkill)
0921         rfkill_set_sw_state(eeepc->wwan3g_rfkill,
0922                     get_acpi(eeepc, CM_ASL_3G) != 1);
0923     if (eeepc->wimax_rfkill)
0924         rfkill_set_sw_state(eeepc->wimax_rfkill,
0925                     get_acpi(eeepc, CM_ASL_WIMAX) != 1);
0926 
0927     return 0;
0928 }
0929 
0930 static const struct dev_pm_ops eeepc_pm_ops = {
0931     .thaw = eeepc_hotk_thaw,
0932     .restore = eeepc_hotk_restore,
0933 };
0934 
0935 static struct platform_driver platform_driver = {
0936     .driver = {
0937         .name = EEEPC_LAPTOP_FILE,
0938         .pm = &eeepc_pm_ops,
0939     }
0940 };
0941 
0942 /*
0943  * Hwmon device
0944  */
0945 
0946 #define EEEPC_EC_SC00      0x61
0947 #define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
0948 #define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
0949 #define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
0950 
0951 #define EEEPC_EC_SFB0      0xD0
0952 #define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
0953 
0954 static inline int eeepc_pwm_to_lmsensors(int value)
0955 {
0956     return value * 255 / 100;
0957 }
0958 
0959 static inline int eeepc_lmsensors_to_pwm(int value)
0960 {
0961     value = clamp_val(value, 0, 255);
0962     return value * 100 / 255;
0963 }
0964 
0965 static int eeepc_get_fan_pwm(void)
0966 {
0967     u8 value = 0;
0968 
0969     ec_read(EEEPC_EC_FAN_PWM, &value);
0970     return eeepc_pwm_to_lmsensors(value);
0971 }
0972 
0973 static void eeepc_set_fan_pwm(int value)
0974 {
0975     value = eeepc_lmsensors_to_pwm(value);
0976     ec_write(EEEPC_EC_FAN_PWM, value);
0977 }
0978 
0979 static int eeepc_get_fan_rpm(void)
0980 {
0981     u8 high = 0;
0982     u8 low = 0;
0983 
0984     ec_read(EEEPC_EC_FAN_HRPM, &high);
0985     ec_read(EEEPC_EC_FAN_LRPM, &low);
0986     return high << 8 | low;
0987 }
0988 
0989 #define EEEPC_EC_FAN_CTRL_BIT   0x02
0990 #define EEEPC_FAN_CTRL_MANUAL   1
0991 #define EEEPC_FAN_CTRL_AUTO 2
0992 
0993 static int eeepc_get_fan_ctrl(void)
0994 {
0995     u8 value = 0;
0996 
0997     ec_read(EEEPC_EC_FAN_CTRL, &value);
0998     if (value & EEEPC_EC_FAN_CTRL_BIT)
0999         return EEEPC_FAN_CTRL_MANUAL;
1000     else
1001         return EEEPC_FAN_CTRL_AUTO;
1002 }
1003 
1004 static void eeepc_set_fan_ctrl(int manual)
1005 {
1006     u8 value = 0;
1007 
1008     ec_read(EEEPC_EC_FAN_CTRL, &value);
1009     if (manual == EEEPC_FAN_CTRL_MANUAL)
1010         value |= EEEPC_EC_FAN_CTRL_BIT;
1011     else
1012         value &= ~EEEPC_EC_FAN_CTRL_BIT;
1013     ec_write(EEEPC_EC_FAN_CTRL, value);
1014 }
1015 
1016 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1017 {
1018     int rv, value;
1019 
1020     rv = parse_arg(buf, &value);
1021     if (rv < 0)
1022         return rv;
1023     set(value);
1024     return count;
1025 }
1026 
1027 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1028 {
1029     return sprintf(buf, "%d\n", get());
1030 }
1031 
1032 #define EEEPC_SENSOR_SHOW_FUNC(_name, _get)             \
1033     static ssize_t _name##_show(struct device *dev,         \
1034                     struct device_attribute *attr,  \
1035                     char *buf)              \
1036     {                               \
1037         return show_sys_hwmon(_get, buf);           \
1038     }
1039 
1040 #define EEEPC_SENSOR_STORE_FUNC(_name, _set)                \
1041     static ssize_t _name##_store(struct device *dev,        \
1042                      struct device_attribute *attr, \
1043                      const char *buf, size_t count) \
1044     {                               \
1045         return store_sys_hwmon(_set, buf, count);       \
1046     }
1047 
1048 #define EEEPC_CREATE_SENSOR_ATTR_RW(_name, _get, _set)          \
1049     EEEPC_SENSOR_SHOW_FUNC(_name, _get)             \
1050     EEEPC_SENSOR_STORE_FUNC(_name, _set)                \
1051     static DEVICE_ATTR_RW(_name)
1052 
1053 #define EEEPC_CREATE_SENSOR_ATTR_RO(_name, _get)            \
1054     EEEPC_SENSOR_SHOW_FUNC(_name, _get)             \
1055     static DEVICE_ATTR_RO(_name)
1056 
1057 EEEPC_CREATE_SENSOR_ATTR_RO(fan1_input, eeepc_get_fan_rpm);
1058 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1, eeepc_get_fan_pwm,
1059                 eeepc_set_fan_pwm);
1060 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1_enable, eeepc_get_fan_ctrl,
1061                 eeepc_set_fan_ctrl);
1062 
1063 static struct attribute *hwmon_attrs[] = {
1064     &dev_attr_pwm1.attr,
1065     &dev_attr_fan1_input.attr,
1066     &dev_attr_pwm1_enable.attr,
1067     NULL
1068 };
1069 ATTRIBUTE_GROUPS(hwmon);
1070 
1071 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1072 {
1073     struct device *dev = &eeepc->platform_device->dev;
1074     struct device *hwmon;
1075 
1076     hwmon = devm_hwmon_device_register_with_groups(dev, "eeepc", NULL,
1077                                hwmon_groups);
1078     if (IS_ERR(hwmon)) {
1079         pr_err("Could not register eeepc hwmon device\n");
1080         return PTR_ERR(hwmon);
1081     }
1082     return 0;
1083 }
1084 
1085 /*
1086  * Backlight device
1087  */
1088 static int read_brightness(struct backlight_device *bd)
1089 {
1090     struct eeepc_laptop *eeepc = bl_get_data(bd);
1091 
1092     return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1093 }
1094 
1095 static int set_brightness(struct backlight_device *bd, int value)
1096 {
1097     struct eeepc_laptop *eeepc = bl_get_data(bd);
1098 
1099     return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1100 }
1101 
1102 static int update_bl_status(struct backlight_device *bd)
1103 {
1104     return set_brightness(bd, bd->props.brightness);
1105 }
1106 
1107 static const struct backlight_ops eeepcbl_ops = {
1108     .get_brightness = read_brightness,
1109     .update_status = update_bl_status,
1110 };
1111 
1112 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1113 {
1114     struct backlight_device *bd = eeepc->backlight_device;
1115     int old = bd->props.brightness;
1116 
1117     backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1118 
1119     return old;
1120 }
1121 
1122 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1123 {
1124     struct backlight_properties props;
1125     struct backlight_device *bd;
1126 
1127     memset(&props, 0, sizeof(struct backlight_properties));
1128     props.type = BACKLIGHT_PLATFORM;
1129     props.max_brightness = 15;
1130     bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1131                        &eeepc->platform_device->dev, eeepc,
1132                        &eeepcbl_ops, &props);
1133     if (IS_ERR(bd)) {
1134         pr_err("Could not register eeepc backlight device\n");
1135         eeepc->backlight_device = NULL;
1136         return PTR_ERR(bd);
1137     }
1138     eeepc->backlight_device = bd;
1139     bd->props.brightness = read_brightness(bd);
1140     bd->props.power = FB_BLANK_UNBLANK;
1141     backlight_update_status(bd);
1142     return 0;
1143 }
1144 
1145 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1146 {
1147     backlight_device_unregister(eeepc->backlight_device);
1148     eeepc->backlight_device = NULL;
1149 }
1150 
1151 
1152 /*
1153  * Input device (i.e. hotkeys)
1154  */
1155 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1156 {
1157     struct input_dev *input;
1158     int error;
1159 
1160     input = input_allocate_device();
1161     if (!input)
1162         return -ENOMEM;
1163 
1164     input->name = "Asus EeePC extra buttons";
1165     input->phys = EEEPC_LAPTOP_FILE "/input0";
1166     input->id.bustype = BUS_HOST;
1167     input->dev.parent = &eeepc->platform_device->dev;
1168 
1169     error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1170     if (error) {
1171         pr_err("Unable to setup input device keymap\n");
1172         goto err_free_dev;
1173     }
1174 
1175     error = input_register_device(input);
1176     if (error) {
1177         pr_err("Unable to register input device\n");
1178         goto err_free_dev;
1179     }
1180 
1181     eeepc->inputdev = input;
1182     return 0;
1183 
1184 err_free_dev:
1185     input_free_device(input);
1186     return error;
1187 }
1188 
1189 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1190 {
1191     if (eeepc->inputdev)
1192         input_unregister_device(eeepc->inputdev);
1193     eeepc->inputdev = NULL;
1194 }
1195 
1196 /*
1197  * ACPI driver
1198  */
1199 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1200 {
1201     if (!eeepc->inputdev)
1202         return;
1203     if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
1204         pr_info("Unknown key %x pressed\n", event);
1205 }
1206 
1207 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1208 {
1209     struct eeepc_laptop *eeepc = acpi_driver_data(device);
1210     int old_brightness, new_brightness;
1211     u16 count;
1212 
1213     if (event > ACPI_MAX_SYS_NOTIFY)
1214         return;
1215     count = eeepc->event_count[event % 128]++;
1216     acpi_bus_generate_netlink_event(device->pnp.device_class,
1217                     dev_name(&device->dev), event,
1218                     count);
1219 
1220     /* Brightness events are special */
1221     if (event < NOTIFY_BRN_MIN || event > NOTIFY_BRN_MAX) {
1222         eeepc_input_notify(eeepc, event);
1223         return;
1224     }
1225 
1226     /* Ignore them completely if the acpi video driver is used */
1227     if (!eeepc->backlight_device)
1228         return;
1229 
1230     /* Update the backlight device. */
1231     old_brightness = eeepc_backlight_notify(eeepc);
1232 
1233     /* Convert event to keypress (obsolescent hack) */
1234     new_brightness = event - NOTIFY_BRN_MIN;
1235 
1236     if (new_brightness < old_brightness) {
1237         event = NOTIFY_BRN_MIN; /* brightness down */
1238     } else if (new_brightness > old_brightness) {
1239         event = NOTIFY_BRN_MAX; /* brightness up */
1240     } else {
1241         /*
1242          * no change in brightness - already at min/max,
1243          * event will be desired value (or else ignored)
1244          */
1245     }
1246     eeepc_input_notify(eeepc, event);
1247 }
1248 
1249 static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1250 {
1251     const char *model;
1252 
1253     model = dmi_get_system_info(DMI_PRODUCT_NAME);
1254     if (!model)
1255         return;
1256 
1257     /*
1258      * Blacklist for setting cpufv (cpu speed).
1259      *
1260      * EeePC 4G ("701") implements CFVS, but it is not supported
1261      * by the pre-installed OS, and the original option to change it
1262      * in the BIOS setup screen was removed in later versions.
1263      *
1264      * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1265      * this applies to all "701" models (4G/4G Surf/2G Surf).
1266      *
1267      * So Asus made a deliberate decision not to support it on this model.
1268      * We have several reports that using it can cause the system to hang
1269      *
1270      * The hang has also been reported on a "702" (Model name "8G"?).
1271      *
1272      * We avoid dmi_check_system() / dmi_match(), because they use
1273      * substring matching.  We don't want to affect the "701SD"
1274      * and "701SDX" models, because they do support S.H.E.
1275      */
1276     if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1277         eeepc->cpufv_disabled = true;
1278         pr_info("model %s does not officially support setting cpu speed\n",
1279             model);
1280         pr_info("cpufv disabled to avoid instability\n");
1281     }
1282 
1283     /*
1284      * Blacklist for wlan hotplug
1285      *
1286      * Eeepc 1005HA doesn't work like others models and don't need the
1287      * hotplug code. In fact, current hotplug code seems to unplug another
1288      * device...
1289      */
1290     if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
1291         strcmp(model, "1005PE") == 0) {
1292         eeepc->hotplug_disabled = true;
1293         pr_info("wlan hotplug disabled\n");
1294     }
1295 }
1296 
1297 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1298 {
1299     int dummy;
1300 
1301     /* Some BIOSes do not report cm although it is available.
1302        Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1303     if (!(eeepc->cm_supported & (1 << cm))
1304         && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1305         pr_info("%s (%x) not reported by BIOS, enabling anyway\n",
1306             name, 1 << cm);
1307         eeepc->cm_supported |= 1 << cm;
1308     }
1309 }
1310 
1311 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1312 {
1313     cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1314     cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1315     cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1316     cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1317 }
1318 
1319 static int eeepc_acpi_init(struct eeepc_laptop *eeepc)
1320 {
1321     unsigned int init_flags;
1322     int result;
1323 
1324     result = acpi_bus_get_status(eeepc->device);
1325     if (result)
1326         return result;
1327     if (!eeepc->device->status.present) {
1328         pr_err("Hotkey device not present, aborting\n");
1329         return -ENODEV;
1330     }
1331 
1332     init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1333     pr_notice("Hotkey init flags 0x%x\n", init_flags);
1334 
1335     if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1336         pr_err("Hotkey initialization failed\n");
1337         return -ENODEV;
1338     }
1339 
1340     /* get control methods supported */
1341     if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1342         pr_err("Get control methods supported failed\n");
1343         return -ENODEV;
1344     }
1345     cmsg_quirks(eeepc);
1346     pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1347 
1348     return 0;
1349 }
1350 
1351 static void eeepc_enable_camera(struct eeepc_laptop *eeepc)
1352 {
1353     /*
1354      * If the following call to set_acpi() fails, it's because there's no
1355      * camera so we can ignore the error.
1356      */
1357     if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1358         set_acpi(eeepc, CM_ASL_CAMERA, 1);
1359 }
1360 
1361 static bool eeepc_device_present;
1362 
1363 static int eeepc_acpi_add(struct acpi_device *device)
1364 {
1365     struct eeepc_laptop *eeepc;
1366     int result;
1367 
1368     pr_notice(EEEPC_LAPTOP_NAME "\n");
1369     eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1370     if (!eeepc)
1371         return -ENOMEM;
1372     eeepc->handle = device->handle;
1373     strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1374     strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1375     device->driver_data = eeepc;
1376     eeepc->device = device;
1377 
1378     eeepc->hotplug_disabled = hotplug_disabled;
1379 
1380     eeepc_dmi_check(eeepc);
1381 
1382     result = eeepc_acpi_init(eeepc);
1383     if (result)
1384         goto fail_platform;
1385     eeepc_enable_camera(eeepc);
1386 
1387     /*
1388      * Register the platform device first.  It is used as a parent for the
1389      * sub-devices below.
1390      *
1391      * Note that if there are multiple instances of this ACPI device it
1392      * will bail out, because the platform device is registered with a
1393      * fixed name.  Of course it doesn't make sense to have more than one,
1394      * and machine-specific scripts find the fixed name convenient.  But
1395      * It's also good for us to exclude multiple instances because both
1396      * our hwmon and our wlan rfkill subdevice use global ACPI objects
1397      * (the EC and the wlan PCI slot respectively).
1398      */
1399     result = eeepc_platform_init(eeepc);
1400     if (result)
1401         goto fail_platform;
1402 
1403     if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
1404         result = eeepc_backlight_init(eeepc);
1405         if (result)
1406             goto fail_backlight;
1407     }
1408 
1409     result = eeepc_input_init(eeepc);
1410     if (result)
1411         goto fail_input;
1412 
1413     result = eeepc_hwmon_init(eeepc);
1414     if (result)
1415         goto fail_hwmon;
1416 
1417     result = eeepc_led_init(eeepc);
1418     if (result)
1419         goto fail_led;
1420 
1421     result = eeepc_rfkill_init(eeepc);
1422     if (result)
1423         goto fail_rfkill;
1424 
1425     eeepc_device_present = true;
1426     return 0;
1427 
1428 fail_rfkill:
1429     eeepc_led_exit(eeepc);
1430 fail_led:
1431 fail_hwmon:
1432     eeepc_input_exit(eeepc);
1433 fail_input:
1434     eeepc_backlight_exit(eeepc);
1435 fail_backlight:
1436     eeepc_platform_exit(eeepc);
1437 fail_platform:
1438     kfree(eeepc);
1439 
1440     return result;
1441 }
1442 
1443 static int eeepc_acpi_remove(struct acpi_device *device)
1444 {
1445     struct eeepc_laptop *eeepc = acpi_driver_data(device);
1446 
1447     eeepc_backlight_exit(eeepc);
1448     eeepc_rfkill_exit(eeepc);
1449     eeepc_input_exit(eeepc);
1450     eeepc_led_exit(eeepc);
1451     eeepc_platform_exit(eeepc);
1452 
1453     kfree(eeepc);
1454     return 0;
1455 }
1456 
1457 
1458 static const struct acpi_device_id eeepc_device_ids[] = {
1459     {EEEPC_ACPI_HID, 0},
1460     {"", 0},
1461 };
1462 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1463 
1464 static struct acpi_driver eeepc_acpi_driver = {
1465     .name = EEEPC_LAPTOP_NAME,
1466     .class = EEEPC_ACPI_CLASS,
1467     .owner = THIS_MODULE,
1468     .ids = eeepc_device_ids,
1469     .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1470     .ops = {
1471         .add = eeepc_acpi_add,
1472         .remove = eeepc_acpi_remove,
1473         .notify = eeepc_acpi_notify,
1474     },
1475 };
1476 
1477 
1478 static int __init eeepc_laptop_init(void)
1479 {
1480     int result;
1481 
1482     result = platform_driver_register(&platform_driver);
1483     if (result < 0)
1484         return result;
1485 
1486     result = acpi_bus_register_driver(&eeepc_acpi_driver);
1487     if (result < 0)
1488         goto fail_acpi_driver;
1489 
1490     if (!eeepc_device_present) {
1491         result = -ENODEV;
1492         goto fail_no_device;
1493     }
1494 
1495     return 0;
1496 
1497 fail_no_device:
1498     acpi_bus_unregister_driver(&eeepc_acpi_driver);
1499 fail_acpi_driver:
1500     platform_driver_unregister(&platform_driver);
1501     return result;
1502 }
1503 
1504 static void __exit eeepc_laptop_exit(void)
1505 {
1506     acpi_bus_unregister_driver(&eeepc_acpi_driver);
1507     platform_driver_unregister(&platform_driver);
1508 }
1509 
1510 module_init(eeepc_laptop_init);
1511 module_exit(eeepc_laptop_exit);