Subject: [PATCH] [acpi device] Add basic LCD init - Add lcd_init() to initialize LCD devices - Add is_lcd() helper - Add get_package() and get_int_array() helpers Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/video/dev-device.c | 96 +++++++++++++++++++++++++++++++ 1 files changed, 96 insertions(+), 0 deletions(-) applies-to: c813dcafa341261cb59c78ee6d06fd2fd18f15af f074c37ebee05a0acbdeb6c8df5d8395785c7555 diff --git a/drivers/acpi/drivers/video/dev-device.c b/drivers/acpi/drivers/video/dev-device.c index 6988efb..4e47d72 100644 --- a/drivers/acpi/drivers/video/dev-device.c +++ b/drivers/acpi/drivers/video/dev-device.c @@ -24,6 +24,70 @@ static int get_int(struct acpi_dev * ad, } +static int get_package(struct acpi_dev * ad, char * method, + union acpi_object ** package) +{ + struct acpi_buffer buffer = { + .length = ACPI_ALLOCATE_BUFFER, + }; + union acpi_object * obj; + acpi_status status; + + status = acpi_evaluate_object(ad->acpi_device->handle, + method, NULL, &buffer); + if (ACPI_FAILURE(status)) { + err("Evaluating %s", method); + return -ENODEV; + } + + obj = buffer.pointer; + if (!(obj && obj->type == ACPI_TYPE_PACKAGE)) { + err("Invalid %s data", method); + kfree(buffer.pointer); + return -EFAULT; + } + *package = obj; + return 0; +} + +static int get_int_array(struct acpi_dev * ad, char * method, + u32 * values, u32 * num) +{ + union acpi_object * package; + int ret; + int i; + + /* + * Get the package from the namespace + */ + ret = get_package(ad, method, &package); + if (ret) + return ret; + + /* + * Modify the count, based on passed limits + */ + if (package->package.count <= *num) + *num = package->package.count; + else + err("Ignoring elements from %s: Have room for %d, need %d", + method, *num, package->package.count); + + /* + * Fill the array with the package contents + */ + for (i = 0; i < *num; i++) { + union acpi_object * o = &package->package.elements[i]; + + if (o->type != ACPI_TYPE_INTEGER) { + err("Invalid %s data at [%d]", method, i); + } + values[i] = o->integer.value; + } + kfree(package); + return 0; +} + /** * video_dev_test - Determine whether this is a video device * @ad: The ACPI device that we're testing @@ -44,6 +108,34 @@ int video_dev_test(struct acpi_dev * ad) } +static int is_lcd(struct acpi_video_dev * vd) +{ + return ((vd->v_id & VIDEO_DEV_TYPE_MASK) == VIDEO_DEV_LCD); +} + +static int lcd_init(struct acpi_video_dev * vd) +{ + u32 values[VIDEO_LCD_MAX + 2]; + u32 num = VIDEO_LCD_MAX + 2; + int ret = 0; + int i; + + if (is_lcd(vd)) { + ret = get_int_array(vd->v_ad, "_BCL", values, &num); + if (ret) + return ret; + + vd->v_br_ac = values[0]; + vd->v_br_batt = values[1]; + + for (i = 0; (i + 2) < num; i++) + vd->v_br_levels[i] = values[i + 2]; + + } + return ret; +} + + /** * video_dev_init - Initialize a video device * @vd: The ACPI video device @@ -57,5 +149,9 @@ int video_dev_init(struct acpi_video_dev ret = get_int(vd->v_ad, "_ADR", &vd->v_id); if (ret) return ret; + + ret = lcd_init(vd); + if (ret) + return ret; return 0; } --- 0.99.9.GIT