diff options
| author | Alexey Starikovskiy <astarikovskiy@suse.de> | 2009-10-15 14:31:44 +0400 | 
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2010-01-15 17:03:33 -0500 | 
| commit | c67fcd670b55e89e0c129fbf7fae854bd1f8bfa6 (patch) | |
| tree | 3546d921cf8abc3a35bf5e771b22644fb91bf81f | |
| parent | 16698857fba1b10af4890055272975adf5686e83 (diff) | |
| download | talos-op-linux-c67fcd670b55e89e0c129fbf7fae854bd1f8bfa6.tar.gz talos-op-linux-c67fcd670b55e89e0c129fbf7fae854bd1f8bfa6.zip  | |
ACPI: Battery: Add support for _BIX extended info method
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | drivers/acpi/battery.c | 68 | 
1 files changed, 58 insertions, 10 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b2b48f8545c7..1ca0ea77115b 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -54,6 +54,7 @@  #define ACPI_BATTERY_DEVICE_NAME	"Battery"  #define ACPI_BATTERY_NOTIFY_STATUS	0x80  #define ACPI_BATTERY_NOTIFY_INFO	0x81 +#define ACPI_BATTERY_NOTIFY_THRESHOLD   0x82  #define _COMPONENT		ACPI_BATTERY_COMPONENT @@ -90,9 +91,11 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids);  enum {  	ACPI_BATTERY_ALARM_PRESENT, -	/* For buggy DSDTs that report negative 16-bit values for either charging -	* or discharging current and/or report 0 as 65536 due to bad math. -	*/ +	ACPI_BATTERY_XINFO_PRESENT, +	/* For buggy DSDTs that report negative 16-bit values for either +	 * charging or discharging current and/or report 0 as 65536 +	 * due to bad math. +	 */  	ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,  }; @@ -112,6 +115,12 @@ struct acpi_battery {  	int design_voltage;  	int design_capacity_warning;  	int design_capacity_low; +	int cycle_count; +	int measurement_accuracy; +	int max_sampling_time; +	int min_sampling_time; +	int max_averaging_interval; +	int min_averaging_interval;  	int capacity_granularity_1;  	int capacity_granularity_2;  	int alarm; @@ -200,6 +209,9 @@ static int acpi_battery_get_property(struct power_supply *psy,  	case POWER_SUPPLY_PROP_TECHNOLOGY:  		val->intval = acpi_battery_technology(battery);  		break; +	case POWER_SUPPLY_PROP_CYCLE_COUNT: +		val->intval = battery->cycle_count; +		break;  	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:  		val->intval = battery->design_voltage * 1000;  		break; @@ -241,6 +253,7 @@ static enum power_supply_property charge_battery_props[] = {  	POWER_SUPPLY_PROP_STATUS,  	POWER_SUPPLY_PROP_PRESENT,  	POWER_SUPPLY_PROP_TECHNOLOGY, +	POWER_SUPPLY_PROP_CYCLE_COUNT,  	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,  	POWER_SUPPLY_PROP_VOLTAGE_NOW,  	POWER_SUPPLY_PROP_CURRENT_NOW, @@ -256,6 +269,7 @@ static enum power_supply_property energy_battery_props[] = {  	POWER_SUPPLY_PROP_STATUS,  	POWER_SUPPLY_PROP_PRESENT,  	POWER_SUPPLY_PROP_TECHNOLOGY, +	POWER_SUPPLY_PROP_CYCLE_COUNT,  	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,  	POWER_SUPPLY_PROP_VOLTAGE_NOW,  	POWER_SUPPLY_PROP_CURRENT_NOW, @@ -307,6 +321,28 @@ static struct acpi_offsets info_offsets[] = {  	{offsetof(struct acpi_battery, oem_info), 1},  }; +static struct acpi_offsets extended_info_offsets[] = { +	{offsetof(struct acpi_battery, power_unit), 0}, +	{offsetof(struct acpi_battery, design_capacity), 0}, +	{offsetof(struct acpi_battery, full_charge_capacity), 0}, +	{offsetof(struct acpi_battery, technology), 0}, +	{offsetof(struct acpi_battery, design_voltage), 0}, +	{offsetof(struct acpi_battery, design_capacity_warning), 0}, +	{offsetof(struct acpi_battery, design_capacity_low), 0}, +	{offsetof(struct acpi_battery, cycle_count), 0}, +	{offsetof(struct acpi_battery, measurement_accuracy), 0}, +	{offsetof(struct acpi_battery, max_sampling_time), 0}, +	{offsetof(struct acpi_battery, min_sampling_time), 0}, +	{offsetof(struct acpi_battery, max_averaging_interval), 0}, +	{offsetof(struct acpi_battery, min_averaging_interval), 0}, +	{offsetof(struct acpi_battery, capacity_granularity_1), 0}, +	{offsetof(struct acpi_battery, capacity_granularity_2), 0}, +	{offsetof(struct acpi_battery, model_number), 1}, +	{offsetof(struct acpi_battery, serial_number), 1}, +	{offsetof(struct acpi_battery, type), 1}, +	{offsetof(struct acpi_battery, oem_info), 1}, +}; +  static int extract_package(struct acpi_battery *battery,  			   union acpi_object *package,  			   struct acpi_offsets *offsets, int num) @@ -352,22 +388,29 @@ static int acpi_battery_get_info(struct acpi_battery *battery)  {  	int result = -EFAULT;  	acpi_status status = 0; +	char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)? +			"_BIX" : "_BIF"; +  	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };  	if (!acpi_battery_present(battery))  		return 0;  	mutex_lock(&battery->lock); -	status = acpi_evaluate_object(battery->device->handle, "_BIF", -				      NULL, &buffer); +	status = acpi_evaluate_object(battery->device->handle, name, +						NULL, &buffer);  	mutex_unlock(&battery->lock);  	if (ACPI_FAILURE(status)) { -		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); +		ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));  		return -ENODEV;  	} - -	result = extract_package(battery, buffer.pointer, -				 info_offsets, ARRAY_SIZE(info_offsets)); +	if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)) +		result = extract_package(battery, buffer.pointer, +				extended_info_offsets, +				ARRAY_SIZE(extended_info_offsets)); +	else +		result = extract_package(battery, buffer.pointer, +				info_offsets, ARRAY_SIZE(info_offsets));  	kfree(buffer.pointer);  	return result;  } @@ -414,7 +457,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)  	union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };  	struct acpi_object_list arg_list = { 1, &arg0 }; -	if (!acpi_battery_present(battery)|| +	if (!acpi_battery_present(battery) ||  	    !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))  		return -ENODEV; @@ -592,6 +635,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)  	seq_printf(seq, "design capacity low:     %d %sh\n",  		   battery->design_capacity_low,  		   acpi_battery_units(battery)); +	seq_printf(seq, "cycle count:		  %i\n", battery->cycle_count);  	seq_printf(seq, "capacity granularity 1:  %d %sh\n",  		   battery->capacity_granularity_1,  		   acpi_battery_units(battery)); @@ -843,6 +887,7 @@ static int acpi_battery_add(struct acpi_device *device)  {  	int result = 0;  	struct acpi_battery *battery = NULL; +	acpi_handle handle;  	if (!device)  		return -EINVAL;  	battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); @@ -853,6 +898,9 @@ static int acpi_battery_add(struct acpi_device *device)  	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);  	device->driver_data = battery;  	mutex_init(&battery->lock); +	if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, +			"_BIX", &handle))) +		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);  	acpi_battery_update(battery);  #ifdef CONFIG_ACPI_PROCFS_POWER  	result = acpi_battery_add_fs(device);  | 

