acpiconf.c revision 148493
165283Siwasaki/*- 265283Siwasaki * Copyright (c) 1999 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 365283Siwasaki * All rights reserved. 465283Siwasaki * 565283Siwasaki * Redistribution and use in source and binary forms, with or without 665283Siwasaki * modification, are permitted provided that the following conditions 765283Siwasaki * are met: 865283Siwasaki * 1. Redistributions of source code must retain the above copyright 965283Siwasaki * notice, this list of conditions and the following disclaimer. 1065283Siwasaki * 2. Redistributions in binary form must reproduce the above copyright 1165283Siwasaki * notice, this list of conditions and the following disclaimer in the 1265283Siwasaki * documentation and/or other materials provided with the distribution. 1365283Siwasaki * 1465283Siwasaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1565283Siwasaki * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1665283Siwasaki * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1765283Siwasaki * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1865283Siwasaki * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1965283Siwasaki * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2065283Siwasaki * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2165283Siwasaki * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2265283Siwasaki * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2365283Siwasaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2465283Siwasaki * SUCH DAMAGE. 2565283Siwasaki * 2665283Siwasaki * $Id: acpiconf.c,v 1.5 2000/08/08 14:12:19 iwasaki Exp $ 2765283Siwasaki * $FreeBSD: head/usr.sbin/acpi/acpiconf/acpiconf.c 148493 2005-07-28 19:41:52Z njl $ 2865283Siwasaki */ 2965283Siwasaki 3065283Siwasaki#include <sys/param.h> 3165283Siwasaki 3265283Siwasaki#include <err.h> 3365283Siwasaki#include <fcntl.h> 3465283Siwasaki#include <stdio.h> 3566490Smsmith#include <sys/ioctl.h> 3687121Scjc#include <sysexits.h> 3765283Siwasaki#include <unistd.h> 3865283Siwasaki 3968475Siwasaki#include <dev/acpica/acpiio.h> 40114246Snjl#include <contrib/dev/acpica/acpi.h> 4168475Siwasaki 42124001Snjl#define ACPIDEV "/dev/acpi" 43124001Snjl#define RC_SUSPEND_PATH "/etc/rc.suspend" 44124001Snjl#define RC_RESUME_PATH "/etc/rc.resume" 4565283Siwasaki 46120036Snjlstatic int acpifd; 47126625Stakawata 48137666Sphilipstatic void 49137638Sphilipacpi_init(void) 50120036Snjl{ 51120036Snjl acpifd = open(ACPIDEV, O_RDWR); 52137763Simp if (acpifd == -1) 53126609Stakawata acpifd = open(ACPIDEV, O_RDONLY); 54137763Simp if (acpifd == -1) 55120036Snjl err(EX_OSFILE, ACPIDEV); 56120036Snjl} 57120036Snjl 58120036Snjlstatic int 5965283Siwasakiacpi_sleep(int sleep_type) 6065283Siwasaki{ 61124001Snjl char cmd[64]; 62124001Snjl int ret; 63124001Snjl 64124001Snjl /* Run the suspend rc script, if available. */ 65124001Snjl if (access(RC_SUSPEND_PATH, X_OK) == 0) { 66124001Snjl snprintf(cmd, sizeof(cmd), "%s acpi %d", RC_SUSPEND_PATH, 67124001Snjl sleep_type); 68124001Snjl system(cmd); 69124001Snjl } 70124001Snjl 71124001Snjl ret = ioctl(acpifd, ACPIIO_SETSLPSTATE, &sleep_type); 72124001Snjl 73124001Snjl /* Run the resume rc script, if available. */ 74124001Snjl if (access(RC_RESUME_PATH, X_OK) == 0) { 75124001Snjl snprintf(cmd, sizeof(cmd), "%s acpi %d", RC_RESUME_PATH, 76124001Snjl sleep_type); 77124001Snjl system(cmd); 78124001Snjl } 79124001Snjl 80124001Snjl if (ret != 0) 8187121Scjc err(EX_IOERR, "sleep type (%d) failed", sleep_type); 8265283Siwasaki 8365283Siwasaki return (0); 8465283Siwasaki} 8565283Siwasaki 86138049Simp/* should be a acpi define, but doesn't appear to be */ 87138049Simp#define UNKNOWN_CAP 0xffffffff 88148491Snjl#define UNKNOWN_VOLTAGE 0xffffffff 89138049Simp 90120036Snjlstatic int 91120036Snjlacpi_battinfo(int num) 92120036Snjl{ 93120036Snjl union acpi_battery_ioctl_arg battio; 94120036Snjl const char *pwr_units; 95148491Snjl int hours, min; 96120036Snjl 97120036Snjl if (num < 0 || num > 64) 98120036Snjl err(EX_USAGE, "invalid battery %d", num); 99120036Snjl 100148491Snjl /* Print battery design information. */ 101120036Snjl battio.unit = num; 102148310Snjl if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) == -1) 103120036Snjl err(EX_IOERR, "get battery info (%d) failed", num); 104120036Snjl if (battio.bif.units == 0) 105148491Snjl pwr_units = "mW"; 106120036Snjl else 107148491Snjl pwr_units = "mA"; 108120036Snjl 109138049Simp if (battio.bif.dcap == UNKNOWN_CAP) 110148491Snjl printf("Design capacity:\tunknown\n"); 111138049Simp else 112148491Snjl printf("Design capacity:\t%d %sh\n", battio.bif.dcap, 113148491Snjl pwr_units); 114138049Simp if (battio.bif.lfcap == UNKNOWN_CAP) 115148491Snjl printf("Last full capacity:\tunknown\n"); 116138049Simp else 117148491Snjl printf("Last full capacity:\t%d %sh\n", battio.bif.lfcap, 118138049Simp pwr_units); 119120036Snjl printf("Technology:\t\t%s\n", battio.bif.btech == 0 ? 120120036Snjl "primary (non-rechargeable)" : "secondary (rechargeable)"); 121138049Simp if (battio.bif.dvol == UNKNOWN_CAP) 122148491Snjl printf("Design voltage:\t\tunknown\n"); 123138049Simp else 124138049Simp printf("Design voltage:\t\t%d mV\n", battio.bif.dvol); 125148491Snjl printf("Capacity (warn):\t%d %sh\n", battio.bif.wcap, pwr_units); 126148491Snjl printf("Capacity (low):\t\t%d %sh\n", battio.bif.lcap, pwr_units); 127148491Snjl printf("Low/warn granularity:\t%d %sh\n", battio.bif.gra1, pwr_units); 128148491Snjl printf("Warn/full granularity:\t%d %sh\n", battio.bif.gra2, pwr_units); 129120036Snjl printf("Model number:\t\t%s\n", battio.bif.model); 130120036Snjl printf("Serial number:\t\t%s\n", battio.bif.serial); 131120036Snjl printf("Type:\t\t\t%s\n", battio.bif.type); 132120036Snjl printf("OEM info:\t\t%s\n", battio.bif.oeminfo); 133120036Snjl 134148491Snjl /* Print current battery state information. */ 135138044Sphk battio.unit = num; 136148491Snjl if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) == -1) 137148491Snjl err(EX_IOERR, "get battery user info (%d) failed", num); 138148491Snjl if (battio.battinfo.state != ACPI_BATT_STAT_NOT_PRESENT) { 139138049Simp printf("State:\t\t\t"); 140148491Snjl if (battio.battinfo.state == 0) 141148491Snjl printf("high "); 142148491Snjl if (battio.battinfo.state & ACPI_BATT_STAT_CRITICAL) 143148491Snjl printf("critical "); 144148491Snjl if (battio.battinfo.state & ACPI_BATT_STAT_DISCHARG) 145148491Snjl printf("discharging "); 146148491Snjl if (battio.battinfo.state & ACPI_BATT_STAT_CHARGING) 147148491Snjl printf("charging "); 148138049Simp printf("\n"); 149148491Snjl if (battio.battinfo.cap == -1) 150148491Snjl printf("Remaining capacity:\tunknown\n"); 151138049Simp else 152148491Snjl printf("Remaining capacity:\t%d%%\n", 153148491Snjl battio.battinfo.cap); 154148491Snjl if (battio.battinfo.min == -1) 155148493Snjl printf("Remaining time:\t\tunknown\n"); 156148491Snjl else { 157148491Snjl hours = battio.battinfo.min / 60; 158148491Snjl min = battio.battinfo.min % 60; 159148491Snjl printf("Remaining time:\t\t%d:%02d\n", hours, min); 160148491Snjl } 161148491Snjl if (battio.battinfo.rate == -1) 162148491Snjl printf("Present rate:\t\tunknown\n"); 163138049Simp else 164148491Snjl printf("Present rate:\t\t%d %s\n", 165148491Snjl battio.battinfo.rate, pwr_units); 166148491Snjl } else 167148491Snjl printf("State:\t\t\tnot present\n"); 168148491Snjl 169148491Snjl /* Print battery voltage information. */ 170148491Snjl battio.unit = num; 171148491Snjl if (ioctl(acpifd, ACPIIO_BATT_GET_BST, &battio) == -1) 172148491Snjl err(EX_IOERR, "get battery status (%d) failed", num); 173148491Snjl if (battio.bst.state != ACPI_BATT_STAT_NOT_PRESENT) { 174148491Snjl if (battio.bst.volt == UNKNOWN_VOLTAGE) 175148491Snjl printf("Voltage:\t\tunknown\n"); 176138049Simp else 177148491Snjl printf("Voltage:\t\t%d mV\n", battio.bst.volt); 178138047Simp } 179148491Snjl 180120036Snjl return (0); 181120036Snjl} 182120036Snjl 18368475Siwasakistatic void 18468475Siwasakiusage(const char* prog) 18568475Siwasaki{ 186133933Snjl printf("usage: %s [-h] [-i batt] [-s 1-5]\n", prog); 18768475Siwasaki exit(0); 18868475Siwasaki} 18968475Siwasaki 19065283Siwasakiint 19165283Siwasakimain(int argc, char *argv[]) 19265283Siwasaki{ 19368475Siwasaki char c, *prog; 19465283Siwasaki int sleep_type; 19565283Siwasaki 19668475Siwasaki prog = argv[0]; 197120036Snjl if (argc < 2) 198120036Snjl usage(prog); 199120036Snjl /* NOTREACHED */ 200120036Snjl 20165283Siwasaki sleep_type = -1; 202120036Snjl acpi_init(); 203133933Snjl while ((c = getopt(argc, argv, "hi:s:")) != -1) { 20465283Siwasaki switch (c) { 205120036Snjl case 'i': 206120036Snjl acpi_battinfo(atoi(optarg)); 207120036Snjl break; 20865283Siwasaki case 's': 209118127Snjl if (optarg[0] == 'S') 210118127Snjl sleep_type = optarg[1] - '0'; 211118127Snjl else 212118127Snjl sleep_type = optarg[0] - '0'; 21387121Scjc if (sleep_type < 0 || sleep_type > 5) 21487121Scjc errx(EX_USAGE, "invalid sleep type (%d)", 215120036Snjl sleep_type); 21665283Siwasaki break; 217120036Snjl case 'h': 21865283Siwasaki default: 219120036Snjl usage(prog); 220120036Snjl /* NOTREACHED */ 22165283Siwasaki } 22265283Siwasaki } 223120036Snjl argc -= optind; 224120036Snjl argv += optind; 22565283Siwasaki 22665283Siwasaki if (sleep_type != -1) { 22765283Siwasaki sleep(1); /* wait 1 sec. for key-release event */ 22865283Siwasaki acpi_sleep(sleep_type); 22965283Siwasaki } 230120036Snjl 231120036Snjl close(acpifd); 232120036Snjl exit (0); 23365283Siwasaki} 234