From patchwork Wed May 23 13:44:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Hung X-Patchwork-Id: 160928 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 32EBAB6FBB for ; Wed, 23 May 2012 23:44:42 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SXBrk-00044e-V3 for incoming@patchwork.ozlabs.org; Wed, 23 May 2012 13:44:41 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SXBri-00042E-Ih for fwts-devel@lists.ubuntu.com; Wed, 23 May 2012 13:44:38 +0000 Received: from [175.182.118.154] (helo=canonical.com) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1SXBrh-0000CB-4c; Wed, 23 May 2012 13:44:38 +0000 From: Alex Hung To: fwts-devel@lists.ubuntu.com Subject: [PATCH] acpi: battery: add trip point tests for acpi batteries Date: Wed, 23 May 2012 21:44:32 +0800 Message-Id: <1337780672-28893-1-git-send-email-alex.hung@canonical.com> X-Mailer: git-send-email 1.7.9.5 X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: fwts-devel-bounces@lists.ubuntu.com Errors-To: fwts-devel-bounces@lists.ubuntu.com Signed-off-by: Alex Hung Acked-by: Colin Ian King Acked-by: Ivan Hu --- src/acpi/battery/battery.c | 41 ++++++++ src/lib/include/fwts_battery.h | 3 + src/lib/src/fwts_battery.c | 207 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) diff --git a/src/acpi/battery/battery.c b/src/acpi/battery/battery.c index d9e4d5e..47771b0 100644 --- a/src/acpi/battery/battery.c +++ b/src/acpi/battery/battery.c @@ -188,6 +188,46 @@ static void check_battery_cycle_count(fwts_framework *fw, int index, char *name) } +static void check_battery_trip_point(fwts_framework *fw, int index, char *name) +{ + int trip_point; + int trip_point_org; + + fwts_printf(fw, "==== Checking trip point of battery '%s' ====\n", name); + + if (!fwts_battery_check_trip_point_support(fw, index)) { + fwts_printf(fw, "==== Not supported - skip test ====\n"); + return; + } + + if (fwts_battery_get_trip_point(fw, index, &trip_point) == FWTS_OK) + trip_point_org = trip_point; + else + trip_point_org = 0; + + fwts_log_info(fw, "Test battery '%s' downward trip point.", name); + fwts_printf(fw, "==== Please now UNPLUG the AC power of the machine ====\n"); + fwts_press_enter(fw); + sleep(1); + trip_point = get_full(fw, index) - 5; + fwts_battery_set_trip_point(fw, index, trip_point); + fwts_cpu_consume_start(); + wait_for_acpi_event(fw, name); + fwts_cpu_consume_complete(); + + fwts_log_info(fw, "Test battery '%s' upwards trip point.", name); + fwts_printf(fw, "==== Please PLUG IN the AC power of the machine ====\n"); + fwts_press_enter(fw); + sleep(1); + trip_point = get_full(fw, index) + 3; + fwts_battery_set_trip_point(fw, index, trip_point); + wait_for_acpi_event(fw, name); + + if (trip_point_org != 0) + fwts_battery_set_trip_point(fw, index, trip_point_org); + +} + static void do_battery_test(fwts_framework *fw, int index) { char name[PATH_MAX]; @@ -211,6 +251,7 @@ static void do_battery_test(fwts_framework *fw, int index) wait_for_acpi_event(fw, name); check_charging(fw, index, name); check_battery_cycle_count(fw, index, name); + check_battery_trip_point(fw, index, name); } static int battery_test1(fwts_framework *fw) diff --git a/src/lib/include/fwts_battery.h b/src/lib/include/fwts_battery.h index 83d381b..8fbd838 100644 --- a/src/lib/include/fwts_battery.h +++ b/src/lib/include/fwts_battery.h @@ -27,6 +27,9 @@ int fwts_battery_get_count(fwts_framework *fw, int *count); int fwts_battery_get_cycle_count(fwts_framework *fw, int index, int *cycle_count); +bool fwts_battery_check_trip_point_support(fwts_framework *fw, int index); +int fwts_battery_set_trip_point(fwts_framework *fw, int index, int trip_point); +int fwts_battery_get_trip_point(fwts_framework *fw, int index, int *trip_point); int fwts_battery_get_capacity(fwts_framework *fw, int type, int index, uint32_t *capacity_mAh, uint32_t *capacity_mWh); int fwts_battery_get_name(fwts_framework *fw, int index, char *name); diff --git a/src/lib/src/fwts_battery.c b/src/lib/src/fwts_battery.c index 468c616..423b525 100644 --- a/src/lib/src/fwts_battery.c +++ b/src/lib/src/fwts_battery.c @@ -360,6 +360,213 @@ static int fwts_battery_get_cycle_count_proc_fs(fwts_framework *fw, DIR *dir, in return FWTS_OK; } +static int fwts_battery_set_trip_point_sys_fs(fwts_framework *fw, DIR *dir, int index, int trip_point) +{ + struct dirent *entry; + int i = 0; + + do { + entry = readdir(dir); + if (entry && strlen(entry->d_name) > 2) { + char path[PATH_MAX]; + char *data; + FILE *fp; + bool match; + + /* Check that type field matches the expected type */ + snprintf(path, sizeof(path), "%s/%s/type", FWTS_SYS_CLASS_POWER_SUPPLY, entry->d_name); + if ((data = fwts_get(path)) != NULL) { + bool mismatch = (strstr(data, "Battery") == NULL); + free(data); + if (mismatch) + continue; /* type don't match, skip this entry */ + } else + continue; /* can't check type, skip this entry */ + match = ((index == FWTS_BATTERY_ALL) || (index == i)); + i++; + if (!match) + continue; + + snprintf(path, sizeof(path), "%s/%s/alarm", FWTS_SYS_CLASS_POWER_SUPPLY, entry->d_name); + if ((fp = fopen(path, "rw+")) == NULL) { + fwts_log_info(fw, "Battery %s present but undersupported - no state present.", entry->d_name); + } else { + char buffer[512]; + sprintf(buffer, "%d", trip_point * 1000); + fputs(buffer, fp); + fclose(fp); + } + } + } while (entry); + + return FWTS_OK; +} + +static int fwts_battery_get_trip_point_sys_fs(fwts_framework *fw, DIR *dir, int index, int *trip_point) +{ + struct dirent *entry; + int i = 0; + + *trip_point = 0; + do { + entry = readdir(dir); + if (entry && strlen(entry->d_name) > 2) { + char path[PATH_MAX]; + char *data; + int val; + FILE *fp; + bool match; + + /* Check that type field matches the expected type */ + snprintf(path, sizeof(path), "%s/%s/type", FWTS_SYS_CLASS_POWER_SUPPLY, entry->d_name); + if ((data = fwts_get(path)) != NULL) { + bool mismatch = (strstr(data, "Battery") == NULL); + free(data); + if (mismatch) + continue; /* type don't match, skip this entry */ + } else + continue; /* can't check type, skip this entry */ + match = ((index == FWTS_BATTERY_ALL) || (index == i)); + i++; + if (!match) + continue; + + snprintf(path, sizeof(path), "%s/%s/alarm", FWTS_SYS_CLASS_POWER_SUPPLY, entry->d_name); + if ((fp = fopen(path, "r")) == NULL) { + fwts_log_info(fw, "Battery %s present but undersupported - no state present.", entry->d_name); + } else { + char buffer[4096]; + while (fgets(buffer, sizeof(buffer)-1, fp) != NULL) { + sscanf(buffer, "%d", &val); + *trip_point = val / 1000; + } + fclose(fp); + } + } + } while (entry); + + return FWTS_OK; +} + +static int fwts_battery_set_trip_point_proc_fs(fwts_framework *fw, DIR *dir, int index, int trip_point) +{ + struct dirent *entry; + int i = 0; + + do { + entry = readdir(dir); + if (entry && strlen(entry->d_name) > 2) { + char path[PATH_MAX]; + FILE *fp; + bool match = ((index == FWTS_BATTERY_ALL) || (index == i)); + + i++; + if (!match) + continue; + + snprintf(path, sizeof(path), "%s/%s/alarm", FWTS_PROC_ACPI_BATTERY, entry->d_name); + if ((fp = fopen(path, "rw+")) == NULL) { + fwts_log_info(fw, "Battery %s present but undersupported - no state present.", entry->d_name); + } else { + char buffer[512]; + sprintf(buffer, "%d", trip_point); + fputs(buffer, fp); + fclose(fp); + } + } + } while (entry); + + return FWTS_OK; +} + +static int fwts_battery_get_trip_point_proc_fs(fwts_framework *fw, DIR *dir, int index, int *trip_point) +{ + struct dirent *entry; + int i = 0; + + *trip_point = 0; + do { + entry = readdir(dir); + if (entry && strlen(entry->d_name) > 2) { + char path[PATH_MAX]; + int val; + FILE *fp; + bool match = ((index == FWTS_BATTERY_ALL) || (index == i)); + + i++; + if (!match) + continue; + + snprintf(path, sizeof(path), "%s/%s/alarm", FWTS_PROC_ACPI_BATTERY, entry->d_name); + if ((fp = fopen(path, "r")) == NULL) { + fwts_log_info(fw, "Battery %s present but undersupported - no state present.", entry->d_name); + } else { + char buffer[4096]; + while (fgets(buffer, sizeof(buffer)-1, fp) != NULL) { + if (strstr(buffer, "alarm:") && + strlen(buffer) > 25) { + sscanf(buffer + 25, "%d", &val); + *trip_point = val; + break; + } + } + fclose(fp); + } + } + } while (entry); + + return FWTS_OK; +} + +int fwts_battery_set_trip_point(fwts_framework *fw, int index, int trip_point) +{ + int ret; + DIR *dir; + + if ((dir = opendir(FWTS_SYS_CLASS_POWER_SUPPLY)) != NULL) { + ret = fwts_battery_set_trip_point_sys_fs(fw, dir, index, trip_point); + closedir(dir); + } else if ((dir = opendir(FWTS_PROC_ACPI_BATTERY)) != NULL) { + ret = fwts_battery_set_trip_point_proc_fs(fw, dir, index, trip_point); + closedir(dir); + } else { + return FWTS_ERROR; + } + + return ret; +} + +int fwts_battery_get_trip_point(fwts_framework *fw, int index, int *trip_point) +{ + int ret; + DIR *dir; + + if ((dir = opendir(FWTS_SYS_CLASS_POWER_SUPPLY)) != NULL) { + ret = fwts_battery_get_trip_point_sys_fs(fw, dir, index, trip_point); + closedir(dir); + } else if ((dir = opendir(FWTS_PROC_ACPI_BATTERY)) != NULL) { + ret = fwts_battery_get_trip_point_proc_fs(fw, dir, index, trip_point); + closedir(dir); + } else { + return FWTS_ERROR; + } + + return ret; +} + +bool fwts_battery_check_trip_point_support(fwts_framework *fw, int index) +{ + int trip_point; + + if (!(fwts_battery_get_trip_point(fw, index, &trip_point) == FWTS_OK)) + return false; + + if (trip_point == 0) + return false; + + return true; +} + int fwts_battery_get_cycle_count(fwts_framework *fw, int index, int *cycle_count) { int ret;