Subject: [PATCH] [acpi battery] Add proc interface - Compatible interface w/ legacy driver: - info, status, and alarm files Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/battery/proc.c | 228 +++++++++++++++++++++++++++++++++++ 1 files changed, 227 insertions(+), 1 deletions(-) applies-to: 3fe2d6bd936424c143505cc6ec5c8663576e48ff bb647e18509ed2832d884863fde6b8eab782dc0f diff --git a/drivers/acpi/drivers/battery/proc.c b/drivers/acpi/drivers/battery/proc.c index e92565e..057e879 100644 --- a/drivers/acpi/drivers/battery/proc.c +++ b/drivers/acpi/drivers/battery/proc.c @@ -9,4 +9,230 @@ #include #include "battery.h" -acpi_driver_proc_none(battery); + +#define ACPI_BATTERY_UNITS_WATTS "mW" +#define ACPI_BATTERY_UNITS_AMPS "mA" + + +static int read_info(struct seq_file *seq, void *offset) +{ + struct acpi_dev * ad = seq->private; + struct acpi_battery * ab = dev_get_drvdata(&ad->dev); + const char * units; + + seq_printf(seq, "present: "); + if (ab->b_present) + seq_printf(seq, "yes\n"); + else { + seq_printf(seq, "no\n"); + return 0; + } + + units = ab->b_bif->power_unit ? + ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; + + seq_printf(seq, "design capacity: "); + if (ab->b_bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + seq_printf(seq, "unknown\n"); + else + seq_printf(seq, "%u %sh\n", + (u32) ab->b_bif->design_capacity, units); + + seq_printf(seq, "last full capacity: "); + if (ab->b_bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + seq_printf(seq, "unknown\n"); + else + seq_printf(seq, "%d %sh\n", + (u32) ab->b_bif->last_full_capacity, units); + + seq_printf(seq, "battery technology: "); + switch ((u32) ab->b_bif->battery_technology) { + case 0: + seq_printf(seq, "non-rechargeable\n"); + break; + case 1: + seq_printf(seq, "rechargeable\n"); + break; + default: + seq_printf(seq, "unknown\n"); + break; + } + + seq_printf(seq, "design voltage: "); + if (ab->b_bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) + seq_printf(seq, "unknown\n"); + else + seq_printf(seq, "%d mV\n", + (u32) ab->b_bif->design_voltage); + + seq_printf(seq, "design capacity warning: %d %sh\n", + (u32) ab->b_bif->design_capacity_warning, units); + seq_printf(seq, "design capacity low: %d %sh\n", + (u32) ab->b_bif->design_capacity_low, units); + seq_printf(seq, "capacity granularity 1: %d %sh\n", + (u32) ab->b_bif->battery_capacity_granularity_1, units); + seq_printf(seq, "capacity granularity 2: %d %sh\n", + (u32) ab->b_bif->battery_capacity_granularity_2, units); + seq_printf(seq, "model number: %s\n", ab->b_bif->model_number); + seq_printf(seq, "serial number: %s\n", ab->b_bif->serial_number); + seq_printf(seq, "battery type: %s\n", ab->b_bif->battery_type); + seq_printf(seq, "OEM info: %s\n", ab->b_bif->oem_info); + + return 0; +} + +static int open_info(struct inode *inode, struct file *file) +{ + return single_open(file, read_info, PDE(inode)->data); +} + + + +static int read_status(struct seq_file *seq, void *offset) +{ + struct acpi_dev * ad = seq->private; + struct acpi_battery * ab = dev_get_drvdata(&ad->dev); + struct acpi_bst * bst; + const char * units; + int ret; + + seq_printf(seq, "present: "); + if (ab->b_present) + seq_printf(seq, "yes\n"); + else { + seq_printf(seq, "no\n"); + return 0; + } + + /* Battery Units */ + + units = ab->b_bif->power_unit ? + ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; + + /* Battery Status (_BST) */ + + ret = battery_get_status(ab, &bst); + if (ret) { + seq_printf(seq, "ERROR: Unable to read battery status\n"); + return 0; + } + + seq_printf(seq, "capacity state: "); + if (!(bst->state & 0x04)) + seq_printf(seq, "ok\n"); + else + seq_printf(seq, "critical\n"); + + + seq_printf(seq, "charging state: "); + if ((bst->state & 0x01) && (bst->state & 0x02)) { + seq_printf(seq, "charging/discharging\n"); + dbg("Battery Charging and Discharging?\n"); + } else if (bst->state & 0x01) + seq_printf(seq, "discharging\n"); + else if (bst->state & 0x02) + seq_printf(seq, "charging\n"); + else { + seq_printf(seq, "charged\n"); + } + + seq_printf(seq, "present rate: "); + if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) + seq_printf(seq, "unknown\n"); + else + seq_printf(seq, "%u %s\n", (u32) bst->present_rate, units); + + seq_printf(seq, "remaining capacity: "); + if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + seq_printf(seq, "unknown\n"); + else + seq_printf(seq, "%u %sh\n", + (u32) bst->remaining_capacity, units); + + seq_printf(seq, "present voltage: "); + if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN) + seq_printf(seq, "unknown\n"); + else + seq_printf(seq, "%u mV\n", + (u32) bst->present_voltage); + return ret; +} + +static int open_status(struct inode *inode, struct file *file) +{ + return single_open(file, read_status, PDE(inode)->data); +} + + + +static int read_alarm(struct seq_file *seq, void *offset) +{ + struct acpi_dev * ad = seq->private; + struct acpi_battery * ab = dev_get_drvdata(&ad->dev); + const char * units; + + if (!ab->b_present) { + seq_printf(seq, "present: no\n"); + goto end; + } + + /* Battery Units */ + + units = ab->b_bif->power_unit ? + ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; + + /* Battery Alarm */ + + seq_printf(seq, "alarm: "); + if (ab->b_have_alarm) + seq_printf(seq, "%u %sh\n", ab->b_alarm, units); + else + seq_printf(seq, "unsupported\n"); + +end: + return 0; +} + +static ssize_t write_alarm(struct file *file, const char __user * buffer, + size_t count, loff_t * ppos) +{ + struct seq_file * m = file->private_data; + struct acpi_dev * ad = m->private; + struct acpi_battery * ab = dev_get_drvdata(&ad->dev); + + char alarm_string[12] = ""; + char * end; + u32 alarm; + int ret; + + if (count > sizeof(alarm_string) - 1) + return -EINVAL; + + if (!ab->b_present) + return -ENODEV; + + if (copy_from_user(alarm_string, buffer, count)) + return -EFAULT; + + alarm = simple_strtoul(alarm_string, &end, 0); + if (*end) + return -EINVAL; + + ret = battery_set_alarm(ab, alarm); + + return ret; +} + +static int open_alarm(struct inode *inode, struct file *file) +{ + return single_open(file, read_alarm, PDE(inode)->data); +} + + +static struct acpi_proc_file battery_files[] = { + proc_file_ro(info), + proc_file_ro(status), + proc_file_rw(alarm), +}; + +acpi_driver_proc(battery); --- 0.99.9.GIT