diff options
Diffstat (limited to 'drivers/platform/x86/asus-laptop.c')
| -rw-r--r-- | drivers/platform/x86/asus-laptop.c | 397 |
1 files changed, 257 insertions, 140 deletions
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index b7944f90388..7f4dc6f51f8 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -53,8 +53,7 @@ #include <linux/rfkill.h> #include <linux/slab.h> #include <linux/dmi.h> -#include <acpi/acpi_drivers.h> -#include <acpi/acpi_bus.h> +#include <linux/acpi.h> #define ASUS_LAPTOP_VERSION "0.42" @@ -81,6 +80,19 @@ static uint wapf = 1; module_param(wapf, uint, 0444); MODULE_PARM_DESC(wapf, "WAPF value"); +static char *wled_type = "unknown"; +static char *bled_type = "unknown"; + +module_param(wled_type, charp, 0444); +MODULE_PARM_DESC(wled_type, "Set the wled type on boot " + "(unknown, led or rfkill). " + "default is unknown"); + +module_param(bled_type, charp, 0444); +MODULE_PARM_DESC(bled_type, "Set the bled type on boot " + "(unknown, led or rfkill). " + "default is unknown"); + static int wlan_status = 1; static int bluetooth_status = 1; static int wimax_status = -1; @@ -115,10 +127,12 @@ MODULE_PARM_DESC(als_status, "Set the ALS status on boot " /* * Some events we use, same for all Asus */ -#define ATKD_BR_UP 0x10 /* (event & ~ATKD_BR_UP) = brightness level */ -#define ATKD_BR_DOWN 0x20 /* (event & ~ATKD_BR_DOWN) = britghness level */ -#define ATKD_BR_MIN ATKD_BR_UP -#define ATKD_BR_MAX (ATKD_BR_DOWN | 0xF) /* 0x2f */ +#define ATKD_BRNUP_MIN 0x10 +#define ATKD_BRNUP_MAX 0x1f +#define ATKD_BRNDOWN_MIN 0x20 +#define ATKD_BRNDOWN_MAX 0x2f +#define ATKD_BRNDOWN 0x20 +#define ATKD_BRNUP 0x2f #define ATKD_LCD_ON 0x33 #define ATKD_LCD_OFF 0x34 @@ -137,6 +151,11 @@ MODULE_PARM_DESC(als_status, "Set the ALS status on boot " #define WM_RSTS 0x08 /* internal wimax */ #define WW_RSTS 0x20 /* internal wwan */ +/* WLED and BLED type */ +#define TYPE_UNKNOWN 0 +#define TYPE_LED 1 +#define TYPE_RFKILL 2 + /* LED */ #define METHOD_MLED "MLED" #define METHOD_TLED "TLED" @@ -218,8 +237,9 @@ struct asus_led { /* * Same thing for rfkill */ -struct asus_pega_rfkill { - int control_id; /* type of control. Maps to PEGA_* values */ +struct asus_rfkill { + /* type of control. Maps to PEGA_* values or *_RSTS */ + int control_id; struct rfkill *rfkill; struct asus_laptop *asus; }; @@ -240,6 +260,8 @@ struct asus_laptop { struct key_entry *keymap; struct input_polled_dev *pega_accel_poll; + struct asus_led wled; + struct asus_led bled; struct asus_led mled; struct asus_led tled; struct asus_led rled; @@ -248,6 +270,8 @@ struct asus_laptop { struct asus_led kled; struct workqueue_struct *led_workqueue; + int wled_type; + int bled_type; int wireless_status; bool have_rsts; bool is_pega_lucid; @@ -256,11 +280,11 @@ struct asus_laptop { int pega_acc_y; int pega_acc_z; - struct rfkill *gps_rfkill; - - struct asus_pega_rfkill wlanrfk; - struct asus_pega_rfkill btrfk; - struct asus_pega_rfkill wwanrfk; + struct asus_rfkill wlan; + struct asus_rfkill bluetooth; + struct asus_rfkill wwan; + struct asus_rfkill wimax; + struct asus_rfkill gps; acpi_handle handle; /* the handle of the hotk device */ u32 ledd_status; /* status of the LED display */ @@ -274,41 +298,69 @@ static const struct key_entry asus_keymap[] = { {KE_KEY, 0x02, { KEY_SCREENLOCK } }, {KE_KEY, 0x05, { KEY_WLAN } }, {KE_KEY, 0x08, { KEY_F13 } }, + {KE_KEY, 0x09, { KEY_PROG2 } }, /* Dock */ {KE_KEY, 0x17, { KEY_ZOOM } }, {KE_KEY, 0x1f, { KEY_BATTERY } }, /* End of Lenovo SL Specific keycodes */ + {KE_KEY, ATKD_BRNDOWN, { KEY_BRIGHTNESSDOWN } }, + {KE_KEY, ATKD_BRNUP, { KEY_BRIGHTNESSUP } }, {KE_KEY, 0x30, { KEY_VOLUMEUP } }, {KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, {KE_KEY, 0x32, { KEY_MUTE } }, - {KE_KEY, 0x33, { KEY_SWITCHVIDEOMODE } }, - {KE_KEY, 0x34, { KEY_SWITCHVIDEOMODE } }, + {KE_KEY, 0x33, { KEY_DISPLAYTOGGLE } }, /* LCD on */ + {KE_KEY, 0x34, { KEY_DISPLAY_OFF } }, /* LCD off */ {KE_KEY, 0x40, { KEY_PREVIOUSSONG } }, {KE_KEY, 0x41, { KEY_NEXTSONG } }, - {KE_KEY, 0x43, { KEY_STOPCD } }, + {KE_KEY, 0x43, { KEY_STOPCD } }, /* Stop/Eject */ {KE_KEY, 0x45, { KEY_PLAYPAUSE } }, - {KE_KEY, 0x4c, { KEY_MEDIA } }, + {KE_KEY, 0x4c, { KEY_MEDIA } }, /* WMP Key */ {KE_KEY, 0x50, { KEY_EMAIL } }, {KE_KEY, 0x51, { KEY_WWW } }, {KE_KEY, 0x55, { KEY_CALC } }, + {KE_IGNORE, 0x57, }, /* Battery mode */ + {KE_IGNORE, 0x58, }, /* AC mode */ {KE_KEY, 0x5C, { KEY_SCREENLOCK } }, /* Screenlock */ - {KE_KEY, 0x5D, { KEY_WLAN } }, - {KE_KEY, 0x5E, { KEY_WLAN } }, - {KE_KEY, 0x5F, { KEY_WLAN } }, - {KE_KEY, 0x60, { KEY_SWITCHVIDEOMODE } }, - {KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, - {KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, - {KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, - {KE_KEY, 0x6B, { KEY_F13 } }, /* Lock Touchpad */ - {KE_KEY, 0x7E, { KEY_BLUETOOTH } }, - {KE_KEY, 0x7D, { KEY_BLUETOOTH } }, + {KE_KEY, 0x5D, { KEY_WLAN } }, /* WLAN Toggle */ + {KE_KEY, 0x5E, { KEY_WLAN } }, /* WLAN Enable */ + {KE_KEY, 0x5F, { KEY_WLAN } }, /* WLAN Disable */ + {KE_KEY, 0x60, { KEY_TOUCHPAD_ON } }, + {KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD only */ + {KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT only */ + {KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT */ + {KE_KEY, 0x64, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV */ + {KE_KEY, 0x65, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV */ + {KE_KEY, 0x66, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV */ + {KE_KEY, 0x67, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV */ + {KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, /* Lock Touchpad */ + {KE_KEY, 0x6C, { KEY_SLEEP } }, /* Suspend */ + {KE_KEY, 0x6D, { KEY_SLEEP } }, /* Hibernate */ + {KE_IGNORE, 0x6E, }, /* Low Battery notification */ + {KE_KEY, 0x7D, { KEY_BLUETOOTH } }, /* Bluetooth Enable */ + {KE_KEY, 0x7E, { KEY_BLUETOOTH } }, /* Bluetooth Disable */ {KE_KEY, 0x82, { KEY_CAMERA } }, - {KE_KEY, 0x88, { KEY_WLAN } }, - {KE_KEY, 0x8A, { KEY_PROG1 } }, + {KE_KEY, 0x88, { KEY_RFKILL } }, /* Radio Toggle Key */ + {KE_KEY, 0x8A, { KEY_PROG1 } }, /* Color enhancement mode */ + {KE_KEY, 0x8C, { KEY_SWITCHVIDEOMODE } }, /* SDSP DVI only */ + {KE_KEY, 0x8D, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + DVI */ + {KE_KEY, 0x8E, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + DVI */ + {KE_KEY, 0x8F, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + DVI */ + {KE_KEY, 0x90, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + DVI */ + {KE_KEY, 0x91, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + DVI */ + {KE_KEY, 0x92, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + DVI */ + {KE_KEY, 0x93, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + DVI */ {KE_KEY, 0x95, { KEY_MEDIA } }, {KE_KEY, 0x99, { KEY_PHONE } }, - {KE_KEY, 0xc4, { KEY_KBDILLUMUP } }, - {KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } }, - {KE_KEY, 0xb5, { KEY_CALC } }, + {KE_KEY, 0xA0, { KEY_SWITCHVIDEOMODE } }, /* SDSP HDMI only */ + {KE_KEY, 0xA1, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + HDMI */ + {KE_KEY, 0xA2, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + HDMI */ + {KE_KEY, 0xA3, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + HDMI */ + {KE_KEY, 0xA4, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + HDMI */ + {KE_KEY, 0xA5, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + HDMI */ + {KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */ + {KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */ + {KE_KEY, 0xB5, { KEY_CALC } }, + {KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, + {KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, {KE_END, 0}, }; @@ -601,6 +653,10 @@ static enum led_brightness asus_kled_cdev_get(struct led_classdev *led_cdev) static void asus_led_exit(struct asus_laptop *asus) { + if (!IS_ERR_OR_NULL(asus->wled.led.dev)) + led_classdev_unregister(&asus->wled.led); + if (!IS_ERR_OR_NULL(asus->bled.led.dev)) + led_classdev_unregister(&asus->bled.led); if (!IS_ERR_OR_NULL(asus->mled.led.dev)) led_classdev_unregister(&asus->mled.led); if (!IS_ERR_OR_NULL(asus->tled.led.dev)) @@ -642,7 +698,7 @@ static int asus_led_register(struct asus_laptop *asus, static int asus_led_init(struct asus_laptop *asus) { - int r; + int r = 0; /* * The Pegatron Lucid has no physical leds, but all methods are @@ -661,6 +717,16 @@ static int asus_led_init(struct asus_laptop *asus) if (!asus->led_workqueue) return -ENOMEM; + if (asus->wled_type == TYPE_LED) + r = asus_led_register(asus, &asus->wled, "asus::wlan", + METHOD_WLAN); + if (r) + goto error; + if (asus->bled_type == TYPE_LED) + r = asus_led_register(asus, &asus->bled, "asus::bluetooth", + METHOD_BLUETOOTH); + if (r) + goto error; r = asus_led_register(asus, &asus->mled, "asus::mail", METHOD_MLED); if (r) goto error; @@ -820,12 +886,14 @@ static ssize_t show_infos(struct device *dev, /* * The HWRS method return informations about the hardware. * 0x80 bit is for WLAN, 0x100 for Bluetooth. + * 0x40 for WWAN, 0x10 for WIMAX. * The significance of others is yet to be found. - * If we don't find the method, we assume the device are present. + * We don't currently use this for device detection, and it + * takes several seconds to run on some systems. */ - rv = acpi_evaluate_integer(asus->handle, "HRWS", NULL, &temp); + rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); if (!ACPI_FAILURE(rv)) - len += sprintf(page + len, "HRWS value : %#x\n", + len += sprintf(page + len, "HWRS value : %#x\n", (uint) temp); /* * Another value for userspace: the ASYM method returns 0x02 for @@ -963,7 +1031,7 @@ static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, return sysfs_acpi_set(asus, buf, count, METHOD_WLAN); } -/* +/*e * Bluetooth */ static int asus_bluetooth_set(struct asus_laptop *asus, int status) @@ -1228,7 +1296,7 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr, ret = asus_gps_switch(asus, !!value); if (ret) return ret; - rfkill_set_sw_state(asus->gps_rfkill, !value); + rfkill_set_sw_state(asus->gps.rfkill, !value); return rv; } @@ -1246,90 +1314,139 @@ static const struct rfkill_ops asus_gps_rfkill_ops = { .set_block = asus_gps_rfkill_set, }; +static int asus_rfkill_set(void *data, bool blocked) +{ + struct asus_rfkill *rfk = data; + struct asus_laptop *asus = rfk->asus; + + if (rfk->control_id == WL_RSTS) + return asus_wlan_set(asus, !blocked); + else if (rfk->control_id == BT_RSTS) + return asus_bluetooth_set(asus, !blocked); + else if (rfk->control_id == WM_RSTS) + return asus_wimax_set(asus, !blocked); + else if (rfk->control_id == WW_RSTS) + return asus_wwan_set(asus, !blocked); + + return -EINVAL; +} + +static const struct rfkill_ops asus_rfkill_ops = { + .set_block = asus_rfkill_set, +}; + +static void asus_rfkill_terminate(struct asus_rfkill *rfk) +{ + if (!rfk->rfkill) + return ; + + rfkill_unregister(rfk->rfkill); + rfkill_destroy(rfk->rfkill); + rfk->rfkill = NULL; +} + static void asus_rfkill_exit(struct asus_laptop *asus) { - if (asus->gps_rfkill) { - rfkill_unregister(asus->gps_rfkill); - rfkill_destroy(asus->gps_rfkill); - asus->gps_rfkill = NULL; - } + asus_rfkill_terminate(&asus->wwan); + asus_rfkill_terminate(&asus->bluetooth); + asus_rfkill_terminate(&asus->wlan); + asus_rfkill_terminate(&asus->gps); } -static int asus_rfkill_init(struct asus_laptop *asus) +static int asus_rfkill_setup(struct asus_laptop *asus, struct asus_rfkill *rfk, + const char *name, int control_id, int type, + const struct rfkill_ops *ops) { int result; - if (acpi_check_handle(asus->handle, METHOD_GPS_ON, NULL) || - acpi_check_handle(asus->handle, METHOD_GPS_OFF, NULL) || - acpi_check_handle(asus->handle, METHOD_GPS_STATUS, NULL)) - return 0; - - asus->gps_rfkill = rfkill_alloc("asus-gps", &asus->platform_device->dev, - RFKILL_TYPE_GPS, - &asus_gps_rfkill_ops, asus); - if (!asus->gps_rfkill) + rfk->control_id = control_id; + rfk->asus = asus; + rfk->rfkill = rfkill_alloc(name, &asus->platform_device->dev, + type, ops, rfk); + if (!rfk->rfkill) return -EINVAL; - result = rfkill_register(asus->gps_rfkill); + result = rfkill_register(rfk->rfkill); if (result) { - rfkill_destroy(asus->gps_rfkill); - asus->gps_rfkill = NULL; + rfkill_destroy(rfk->rfkill); + rfk->rfkill = NULL; } return result; } -static int pega_rfkill_set(void *data, bool blocked) +static int asus_rfkill_init(struct asus_laptop *asus) { - struct asus_pega_rfkill *pega_rfk = data; + int result = 0; - int ret = asus_pega_lucid_set(pega_rfk->asus, pega_rfk->control_id, !blocked); - pr_warn("Setting rfkill %d, to %d; returned %d\n", pega_rfk->control_id, !blocked, ret); + if (asus->is_pega_lucid) + return -ENODEV; - return ret; -} + if (!acpi_check_handle(asus->handle, METHOD_GPS_ON, NULL) && + !acpi_check_handle(asus->handle, METHOD_GPS_OFF, NULL) && + !acpi_check_handle(asus->handle, METHOD_GPS_STATUS, NULL)) + result = asus_rfkill_setup(asus, &asus->gps, "asus-gps", + -1, RFKILL_TYPE_GPS, + &asus_gps_rfkill_ops); + if (result) + goto exit; -static const struct rfkill_ops pega_rfkill_ops = { - .set_block = pega_rfkill_set, -}; -static void pega_rfkill_terminate(struct asus_pega_rfkill *pega_rfk) -{ - pr_warn("Terminating %d\n", pega_rfk->control_id); - if (pega_rfk->rfkill) { - rfkill_unregister(pega_rfk->rfkill); - rfkill_destroy(pega_rfk->rfkill); - pega_rfk->rfkill = NULL; - } -} + if (!acpi_check_handle(asus->handle, METHOD_WLAN, NULL) && + asus->wled_type == TYPE_RFKILL) + result = asus_rfkill_setup(asus, &asus->wlan, "asus-wlan", + WL_RSTS, RFKILL_TYPE_WLAN, + &asus_rfkill_ops); + if (result) + goto exit; -static void pega_rfkill_exit(struct asus_laptop *asus) -{ - pega_rfkill_terminate(&asus->wwanrfk); - pega_rfkill_terminate(&asus->btrfk); - pega_rfkill_terminate(&asus->wlanrfk); + if (!acpi_check_handle(asus->handle, METHOD_BLUETOOTH, NULL) && + asus->bled_type == TYPE_RFKILL) + result = asus_rfkill_setup(asus, &asus->bluetooth, + "asus-bluetooth", BT_RSTS, + RFKILL_TYPE_BLUETOOTH, + &asus_rfkill_ops); + if (result) + goto exit; + + if (!acpi_check_handle(asus->handle, METHOD_WWAN, NULL)) + result = asus_rfkill_setup(asus, &asus->wwan, "asus-wwan", + WW_RSTS, RFKILL_TYPE_WWAN, + &asus_rfkill_ops); + if (result) + goto exit; + + if (!acpi_check_handle(asus->handle, METHOD_WIMAX, NULL)) + result = asus_rfkill_setup(asus, &asus->wimax, "asus-wimax", + WM_RSTS, RFKILL_TYPE_WIMAX, + &asus_rfkill_ops); + if (result) + goto exit; + +exit: + if (result) + asus_rfkill_exit(asus); + + return result; } -static int pega_rfkill_setup(struct asus_laptop *asus, struct asus_pega_rfkill *pega_rfk, - const char *name, int controlid, int rfkill_type) +static int pega_rfkill_set(void *data, bool blocked) { - int result; + struct asus_rfkill *rfk = data; - pr_warn("Setting up rfk %s, control %d, type %d\n", name, controlid, rfkill_type); - pega_rfk->control_id = controlid; - pega_rfk->asus = asus; - pega_rfk->rfkill = rfkill_alloc(name, &asus->platform_device->dev, - rfkill_type, &pega_rfkill_ops, pega_rfk); - if (!pega_rfk->rfkill) - return -EINVAL; + int ret = asus_pega_lucid_set(rfk->asus, rfk->control_id, !blocked); + return ret; +} - result = rfkill_register(pega_rfk->rfkill); - if (result) { - rfkill_destroy(pega_rfk->rfkill); - pega_rfk->rfkill = NULL; - } +static const struct rfkill_ops pega_rfkill_ops = { + .set_block = pega_rfkill_set, +}; - return result; +static int pega_rfkill_setup(struct asus_laptop *asus, struct asus_rfkill *rfk, + const char *name, int controlid, int rfkill_type) +{ + return asus_rfkill_setup(asus, rfk, name, controlid, rfkill_type, + &pega_rfkill_ops); } static int pega_rfkill_init(struct asus_laptop *asus) @@ -1339,22 +1456,22 @@ static int pega_rfkill_init(struct asus_laptop *asus) if(!asus->is_pega_lucid) return -ENODEV; - ret = pega_rfkill_setup(asus, &asus->wlanrfk, "pega-wlan", PEGA_WLAN, RFKILL_TYPE_WLAN); + ret = pega_rfkill_setup(asus, &asus->wlan, "pega-wlan", + PEGA_WLAN, RFKILL_TYPE_WLAN); if(ret) - return ret; - ret = pega_rfkill_setup(asus, &asus->btrfk, "pega-bt", PEGA_BLUETOOTH, RFKILL_TYPE_BLUETOOTH); - if(ret) - goto err_btrfk; - ret = pega_rfkill_setup(asus, &asus->wwanrfk, "pega-wwan", PEGA_WWAN, RFKILL_TYPE_WWAN); + goto exit; + + ret = pega_rfkill_setup(asus, &asus->bluetooth, "pega-bt", + PEGA_BLUETOOTH, RFKILL_TYPE_BLUETOOTH); if(ret) - goto err_wwanrfk; + goto exit; - pr_warn("Pega rfkill init succeeded\n"); - return 0; -err_wwanrfk: - pega_rfkill_terminate(&asus->btrfk); -err_btrfk: - pega_rfkill_terminate(&asus->wlanrfk); + ret = pega_rfkill_setup(asus, &asus->wwan, "pega-wwan", + PEGA_WWAN, RFKILL_TYPE_WWAN); + +exit: + if (ret) + asus_rfkill_exit(asus); return ret; } @@ -1364,8 +1481,10 @@ err_btrfk: */ static void asus_input_notify(struct asus_laptop *asus, int event) { - if (asus->inputdev) - sparse_keymap_report_event(asus->inputdev, event, 1, true); + if (!asus->inputdev) + return ; + if (!sparse_keymap_report_event(asus->inputdev, event, 1, true)) + pr_info("Unknown key %x pressed\n", event); } static int asus_input_init(struct asus_laptop *asus) @@ -1374,10 +1493,9 @@ static int asus_input_init(struct asus_laptop *asus) int error; input = input_allocate_device(); - if (!input) { - pr_info("Unable to allocate input device\n"); + if (!input) return -ENOMEM; - } + input->name = "Asus Laptop extra buttons"; input->phys = ASUS_LAPTOP_FILE "/input0"; input->id.bustype = BUS_HOST; @@ -1390,7 +1508,7 @@ static int asus_input_init(struct asus_laptop *asus) } error = input_register_device(input); if (error) { - pr_info("Unable to register input device\n"); + pr_warn("Unable to register input device\n"); goto err_free_keymap; } @@ -1423,20 +1541,23 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event) /* TODO Find a better way to handle events count. */ count = asus->event_count[event % 128]++; - acpi_bus_generate_proc_event(asus->device, event, count); acpi_bus_generate_netlink_event(asus->device->pnp.device_class, dev_name(&asus->device->dev), event, count); - /* Brightness events are special */ - if (event >= ATKD_BR_MIN && event <= ATKD_BR_MAX) { + if (event >= ATKD_BRNUP_MIN && event <= ATKD_BRNUP_MAX) + event = ATKD_BRNUP; + else if (event >= ATKD_BRNDOWN_MIN && + event <= ATKD_BRNDOWN_MAX) + event = ATKD_BRNDOWN; - /* Ignore them completely if the acpi video driver is used */ + /* Brightness events are special */ + if (event == ATKD_BRNDOWN || event == ATKD_BRNUP) { if (asus->backlight_device != NULL) { /* Update the backlight device. */ asus_backlight_notify(asus); + return ; } - return ; } /* Accelerometer "coarse orientation change" event */ @@ -1591,7 +1712,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *model = NULL; - unsigned long long bsts_result, hwrs_result; + unsigned long long bsts_result; char *string = NULL; acpi_status status; @@ -1650,20 +1771,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus) return -ENOMEM; } - if (*string) + if (string) pr_notice(" %s model detected\n", string); - /* - * The HWRS method return informations about the hardware. - * 0x80 bit is for WLAN, 0x100 for Bluetooth, - * 0x40 for WWAN, 0x10 for WIMAX. - * The significance of others is yet to be found. - */ - status = - acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result); - if (!ACPI_FAILURE(status)) - pr_notice(" HRWS returned %x", (int)hwrs_result); - if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) asus->have_rsts = true; @@ -1672,7 +1782,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) return AE_OK; } -static int __devinit asus_acpi_init(struct asus_laptop *asus) +static int asus_acpi_init(struct asus_laptop *asus) { int result = 0; @@ -1688,7 +1798,16 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus) if (result) return result; - /* WLED and BLED are on by default */ + if (!strcmp(bled_type, "led")) + asus->bled_type = TYPE_LED; + else if (!strcmp(bled_type, "rfkill")) + asus->bled_type = TYPE_RFKILL; + + if (!strcmp(wled_type, "led")) + asus->wled_type = TYPE_LED; + else if (!strcmp(wled_type, "rfkill")) + asus->wled_type = TYPE_RFKILL; + if (bluetooth_status >= 0) asus_bluetooth_set(asus, !!bluetooth_status); @@ -1723,7 +1842,7 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus) return result; } -static void __devinit asus_dmi_check(void) +static void asus_dmi_check(void) { const char *model; @@ -1739,7 +1858,7 @@ static void __devinit asus_dmi_check(void) static bool asus_device_present; -static int __devinit asus_acpi_add(struct acpi_device *device) +static int asus_acpi_add(struct acpi_device *device) { struct asus_laptop *asus; int result; @@ -1786,7 +1905,7 @@ static int __devinit asus_acpi_add(struct acpi_device *device) goto fail_led; result = asus_rfkill_init(asus); - if (result) + if (result && result != -ENODEV) goto fail_rfkill; result = pega_accel_init(asus); @@ -1813,13 +1932,12 @@ fail_input: fail_backlight: asus_platform_exit(asus); fail_platform: - kfree(asus->name); kfree(asus); return result; } -static int asus_acpi_remove(struct acpi_device *device, int type) +static int asus_acpi_remove(struct acpi_device *device) { struct asus_laptop *asus = acpi_driver_data(device); @@ -1828,7 +1946,6 @@ static int asus_acpi_remove(struct acpi_device *device, int type) asus_led_exit(asus); asus_input_exit(asus); pega_accel_exit(asus); - pega_rfkill_exit(asus); asus_platform_exit(asus); kfree(asus->name); |
