diff options
Diffstat (limited to 'drivers/platform/x86/asus-laptop.c')
-rw-r--r-- | drivers/platform/x86/asus-laptop.c | 183 |
1 files changed, 22 insertions, 161 deletions
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index f3aa6a7fdab..c53b3ff7978 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -29,7 +29,7 @@ * John Belmonte - ACPI code for Toshiba laptop was a good starting point. * Eric Burghard - LED display support for W1N * Josh Green - Light Sens support - * Thomas Tuttle - His first patch for led support was very helpfull + * Thomas Tuttle - His first patch for led support was very helpful * Sam Lin - GPS support */ @@ -50,6 +50,7 @@ #include <linux/input/sparse-keymap.h> #include <linux/rfkill.h> #include <linux/slab.h> +#include <linux/dmi.h> #include <acpi/acpi_drivers.h> #include <acpi/acpi_bus.h> @@ -157,46 +158,9 @@ MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot " #define METHOD_BRIGHTNESS_SET "SPLV" #define METHOD_BRIGHTNESS_GET "GPLV" -/* Backlight */ -static acpi_handle lcd_switch_handle; -static char *lcd_switch_paths[] = { - "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ - "\\_SB.PCI0.ISA.EC0._Q10", /* A1x */ - "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */ - "\\_SB.PCI0.PX40.EC0.Q10", /* M1A */ - "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */ - "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */ - "\\_SB.PCI0.PX40.Q10", /* S1x */ - "\\Q10"}; /* A2x, L2D, L3D, M2E */ - /* Display */ #define METHOD_SWITCH_DISPLAY "SDSP" -static acpi_handle display_get_handle; -static char *display_get_paths[] = { - /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */ - "\\_SB.PCI0.P0P1.VGA.GETD", - /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V S5A M5A z33A W1Jc W2V G1 */ - "\\_SB.PCI0.P0P2.VGA.GETD", - /* A6V A6Q */ - "\\_SB.PCI0.P0P3.VGA.GETD", - /* A6T, A6M */ - "\\_SB.PCI0.P0PA.VGA.GETD", - /* L3C */ - "\\_SB.PCI0.PCI1.VGAC.NMAP", - /* Z96F */ - "\\_SB.PCI0.VGA.GETD", - /* A2D */ - "\\ACTD", - /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */ - "\\ADVG", - /* P30 */ - "\\DNXT", - /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */ - "\\INFB", - /* A3F A6F A3N A3L M6N W3N W6A */ - "\\SSTE"}; - #define METHOD_ALS_CONTROL "ALSC" /* Z71A Z71V */ #define METHOD_ALS_LEVEL "ALSL" /* Z71A Z71V */ @@ -246,7 +210,6 @@ struct asus_laptop { int wireless_status; bool have_rsts; - int lcd_state; struct rfkill *gps_rfkill; @@ -559,48 +522,6 @@ error: /* * Backlight device */ -static int asus_lcd_status(struct asus_laptop *asus) -{ - return asus->lcd_state; -} - -static int asus_lcd_set(struct asus_laptop *asus, int value) -{ - int lcd = 0; - acpi_status status = 0; - - lcd = !!value; - - if (lcd == asus_lcd_status(asus)) - return 0; - - if (!lcd_switch_handle) - return -ENODEV; - - status = acpi_evaluate_object(lcd_switch_handle, - NULL, NULL, NULL); - - if (ACPI_FAILURE(status)) { - pr_warning("Error switching LCD\n"); - return -ENODEV; - } - - asus->lcd_state = lcd; - return 0; -} - -static void lcd_blank(struct asus_laptop *asus, int blank) -{ - struct backlight_device *bd = asus->backlight_device; - - asus->lcd_state = (blank == FB_BLANK_UNBLANK); - - if (bd) { - bd->props.power = blank; - backlight_update_status(bd); - } -} - static int asus_read_brightness(struct backlight_device *bd) { struct asus_laptop *asus = bl_get_data(bd); @@ -628,16 +549,9 @@ static int asus_set_brightness(struct backlight_device *bd, int value) static int update_bl_status(struct backlight_device *bd) { - struct asus_laptop *asus = bl_get_data(bd); - int rv; int value = bd->props.brightness; - rv = asus_set_brightness(bd, value); - if (rv) - return rv; - - value = (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0; - return asus_lcd_set(asus, value); + return asus_set_brightness(bd, value); } static const struct backlight_ops asusbl_ops = { @@ -661,12 +575,12 @@ static int asus_backlight_init(struct asus_laptop *asus) struct backlight_properties props; if (acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) || - acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) || - !lcd_switch_handle) + acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL)) return 0; memset(&props, 0, sizeof(struct backlight_properties)); props.max_brightness = 15; + props.type = BACKLIGHT_PLATFORM; bd = backlight_device_register(ASUS_LAPTOP_FILE, &asus->platform_device->dev, asus, @@ -970,41 +884,6 @@ static void asus_set_display(struct asus_laptop *asus, int value) return; } -static int read_display(struct asus_laptop *asus) -{ - unsigned long long value = 0; - acpi_status rv = AE_OK; - - /* - * In most of the case, we know how to set the display, but sometime - * we can't read it - */ - if (display_get_handle) { - rv = acpi_evaluate_integer(display_get_handle, NULL, - NULL, &value); - if (ACPI_FAILURE(rv)) - pr_warning("Error reading display status\n"); - } - - value &= 0x0F; /* needed for some models, shouldn't hurt others */ - - return value; -} - -/* - * Now, *this* one could be more user-friendly, but so far, no-one has - * complained. The significance of bits is the same as in store_disp() - */ -static ssize_t show_disp(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct asus_laptop *asus = dev_get_drvdata(dev); - - if (!display_get_handle) - return -ENODEV; - return sprintf(buf, "%d\n", read_display(asus)); -} - /* * Experimental support for display switching. As of now: 1 should activate * the LCD output, 2 should do for CRT, 4 for TV-Out and 8 for DVI. @@ -1246,15 +1125,6 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event) struct asus_laptop *asus = acpi_driver_data(device); u16 count; - /* - * We need to tell the backlight device when the backlight power is - * switched - */ - if (event == ATKD_LCD_ON) - lcd_blank(asus, FB_BLANK_UNBLANK); - else if (event == ATKD_LCD_OFF) - lcd_blank(asus, FB_BLANK_POWERDOWN); - /* TODO Find a better way to handle events count. */ count = asus->event_count[event % 128]++; acpi_bus_generate_proc_event(asus->device, event, count); @@ -1281,7 +1151,7 @@ static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, show_bluetooth, store_bluetooth); static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax); static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan); -static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp); +static DEVICE_ATTR(display, S_IWUSR, NULL, store_disp); static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw); @@ -1392,26 +1262,6 @@ static struct platform_driver platform_driver = { } }; -static int asus_handle_init(char *name, acpi_handle * handle, - char **paths, int num_paths) -{ - int i; - acpi_status status; - - for (i = 0; i < num_paths; i++) { - status = acpi_get_handle(NULL, paths[i], handle); - if (ACPI_SUCCESS(status)) - return 0; - } - - *handle = NULL; - return -ENODEV; -} - -#define ASUS_HANDLE_INIT(object) \ - asus_handle_init(#object, &object##_handle, object##_paths, \ - ARRAY_SIZE(object##_paths)) - /* * This function is used to initialize the context with right values. In this * method, we can make all the detection we want, and modify the asus_laptop @@ -1497,10 +1347,6 @@ static int asus_laptop_get_info(struct asus_laptop *asus) if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) asus->have_rsts = true; - /* Scheduled for removal */ - ASUS_HANDLE_INIT(lcd_switch); - ASUS_HANDLE_INIT(display_get); - kfree(model); return AE_OK; @@ -1552,10 +1398,23 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus) asus_als_level(asus, asus->light_level); } - asus->lcd_state = 1; /* LCD should be on when the module load */ return result; } +static void __devinit asus_dmi_check(void) +{ + const char *model; + + model = dmi_get_system_info(DMI_PRODUCT_NAME); + if (!model) + return; + + /* On L1400B WLED control the sound card, don't mess with it ... */ + if (strncmp(model, "L1400B", 6) == 0) { + wlan_status = -1; + } +} + static bool asus_device_present; static int __devinit asus_acpi_add(struct acpi_device *device) @@ -1574,6 +1433,8 @@ static int __devinit asus_acpi_add(struct acpi_device *device) device->driver_data = asus; asus->device = device; + asus_dmi_check(); + result = asus_acpi_init(asus); if (result) goto fail_platform; |