static int pega_int_read(struct asus_laptop *asus, int arg, int *result) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; int err = write_acpi_int_ret(asus->handle, METHOD_PEGA_READ, arg, &buffer); if (!err) { union acpi_object *obj = buffer.pointer; if (obj && obj->type == ACPI_TYPE_INTEGER) *result = obj->integer.value; else err = -EIO; } return err; }
static int write_acpi_int(acpi_handle handle, const char *method, int val) { return write_acpi_int_ret(handle, method, val, NULL); }
/* * 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 * struct */ 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; char *string = NULL; acpi_status status; /* * Get DSDT headers early enough to allow for differentiating between * models, but late enough to allow acpi_bus_register_driver() to fail * before doing anything ACPI-specific. Should we encounter a machine, * which needs special handling (i.e. its hotkey device has a different * HID), this bit will be moved. */ status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus->dsdt_info); if (ACPI_FAILURE(status)) pr_warning("Couldn't get the DSDT table header\n"); /* We have to write 0 on init this far for all ASUS models */ if (write_acpi_int_ret(asus->handle, "INIT", 0, &buffer)) { pr_err("Hotkey initialization failed\n"); return -ENODEV; } /* This needs to be called for some laptops to init properly */ status = acpi_evaluate_integer(asus->handle, "BSTS", NULL, &bsts_result); if (ACPI_FAILURE(status)) pr_warning("Error calling BSTS\n"); else if (bsts_result) pr_notice("BSTS called, 0x%02x returned\n", (uint) bsts_result); /* This too ... */ if (write_acpi_int(asus->handle, "CWAP", wapf)) pr_err("Error calling CWAP(%d)\n", wapf); /* * Try to match the object returned by INIT to the specific model. * Handle every possible object (or the lack of thereof) the DSDT * writers might throw at us. When in trouble, we pass NULL to * asus_model_match() and try something completely different. */ if (buffer.pointer) { model = buffer.pointer; switch (model->type) { case ACPI_TYPE_STRING: string = model->string.pointer; break; case ACPI_TYPE_BUFFER: string = model->buffer.pointer; break; default: string = ""; break; } } asus->name = kstrdup(string, GFP_KERNEL); if (!asus->name) { kfree(buffer.pointer); return -ENOMEM; } 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. * 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; /* Scheduled for removal */ ASUS_HANDLE_INIT(lcd_switch); ASUS_HANDLE_INIT(display_get); kfree(model); return AE_OK; }
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; char *string = NULL; acpi_status status; status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus->dsdt_info); if (ACPI_FAILURE(status)) pr_warn("Couldn't get the DSDT table header\n"); if (write_acpi_int_ret(asus->handle, "INIT", 0, &buffer)) { pr_err("Hotkey initialization failed\n"); return -ENODEV; } status = acpi_evaluate_integer(asus->handle, "BSTS", NULL, &bsts_result); if (ACPI_FAILURE(status)) pr_warn("Error calling BSTS\n"); else if (bsts_result) pr_notice("BSTS called, 0x%02x returned\n", (uint) bsts_result); if (write_acpi_int(asus->handle, "CWAP", wapf)) pr_err("Error calling CWAP(%d)\n", wapf); if (buffer.pointer) { model = buffer.pointer; switch (model->type) { case ACPI_TYPE_STRING: string = model->string.pointer; break; case ACPI_TYPE_BUFFER: string = model->buffer.pointer; break; default: string = ""; break; } } asus->name = kstrdup(string, GFP_KERNEL); if (!asus->name) { kfree(buffer.pointer); return -ENOMEM; } if (*string) pr_notice(" %s model detected\n", string); status = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); if (!ACPI_FAILURE(status)) pr_notice(" HWRS returned %x", (int)hwrs_result); if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) asus->have_rsts = true; kfree(model); return AE_OK; }