/*
 * Battery class driver for Apple PMU
 *
 *	Copyright © 2006  David Woodhouse <dwmw2@infradead.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/power_supply.h>
#include <linux/adb.h>
#include <linux/pmu.h>
#include <linux/slab.h>

static struct pmu_battery_dev {
	struct power_supply bat;
	struct pmu_battery_info *pbi;
	char name[16];
	int propval;
} *pbats[PMU_MAX_BATTERIES];

#define to_pmu_battery_dev(x) container_of(x, struct pmu_battery_dev, bat)

/*********************************************************************
 *		Power
 *********************************************************************/

static int pmu_get_ac_prop(struct power_supply *psy,
			   enum power_supply_property psp,
			   union power_supply_propval *val)
{
	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		val->intval = (!!(pmu_power_flags & PMU_PWR_AC_PRESENT)) ||
			      (pmu_battery_count == 0);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static enum power_supply_property pmu_ac_props[] = {
	POWER_SUPPLY_PROP_ONLINE,
};

static struct power_supply pmu_ac = {
	.name = "pmu-ac",
	.type = POWER_SUPPLY_TYPE_MAINS,
	.properties = pmu_ac_props,
	.num_properties = ARRAY_SIZE(pmu_ac_props),
	.get_property = pmu_get_ac_prop,
};

/*********************************************************************
 *		Battery properties
 *********************************************************************/

static char *pmu_batt_types[] = {
	"Smart", "Comet", "Hooper", "Unknown"
};

static char *pmu_bat_get_model_name(struct pmu_battery_info *pbi)
{
	switch (pbi->flags & PMU_BATT_TYPE_MASK) {
	case PMU_BATT_TYPE_SMART:
		return pmu_batt_types[0];
	case PMU_BATT_TYPE_COMET:
		return pmu_batt_types[1];
	case PMU_BATT_TYPE_HOOPER:
		return pmu_batt_types[2];
	default: break;
	}
	return pmu_batt_types[3];
}

static int pmu_bat_get_property(struct power_supply *psy,
				enum power_supply_property psp,
				union power_supply_propval *val)
{
	struct pmu_battery_dev *pbat = to_pmu_battery_dev(psy);
	struct pmu_battery_info *pbi = pbat->pbi;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		if (pbi->flags & PMU_BATT_CHARGING)
			val->intval = POWER_SUPPLY_STATUS_CHARGING;
		else if (pmu_power_flags & PMU_PWR_AC_PRESENT)
			val->intval = POWER_SUPPLY_STATUS_FULL;
		else
			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
		break;
	case POWER_SUPPLY_PROP_PRESENT:
		val->intval = !!(pbi->flags & PMU_BATT_PRESENT);
		break;
	case POWER_SUPPLY_PROP_MODEL_NAME:
		val->strval = pmu_bat_get_model_name(pbi);
		break;
	case POWER_SUPPLY_PROP_ENERGY_AVG:
		val->intval = pbi->charge     * 1000; /* mWh -> µWh */
		break;
	case POWER_SUPPLY_PROP_ENERGY_FULL:
		val->intval = pbi->max_charge * 1000; /* mWh -> µWh */
		break;
	case POWER_SUPPLY_PROP_CURRENT_AVG:
		val->intval = pbi->amperage   * 1000; /* mA -> µA */
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
		val->intval = pbi->voltage    * 1000; /* mV -> µV */
		break;
	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
		val->intval = pbi->time_remaining;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static enum power_supply_property pmu_bat_props[] = {
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_ENERGY_AVG,
	POWER_SUPPLY_PROP_ENERGY_FULL,
	POWER_SUPPLY_PROP_CURRENT_AVG,
	POWER_SUPPLY_PROP_VOLTAGE_AVG,
	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
};

/*********************************************************************
 *		Initialisation
 *********************************************************************/

static struct platform_device *bat_pdev;

static int __init pmu_bat_init(void)
{
	int ret;
	int i;

	bat_pdev = platform_device_register_simple("pmu-battery",
						   0, NULL, 0);
	if (IS_ERR(bat_pdev)) {
		ret = PTR_ERR(bat_pdev);
		goto pdev_register_failed;
	}

	ret = power_supply_register(&bat_pdev->dev, &pmu_ac);
	if (ret)
		goto ac_register_failed;

	for (i = 0; i < pmu_battery_count; i++) {
		struct pmu_battery_dev *pbat = kzalloc(sizeof(*pbat),
						       GFP_KERNEL);
		if (!pbat)
			break;

		sprintf(pbat->name, "PMU_battery_%d", i);
		pbat->bat.name = pbat->name;
		pbat->bat.properties = pmu_bat_props;
		pbat->bat.num_properties = ARRAY_SIZE(pmu_bat_props);
		pbat->bat.get_property = pmu_bat_get_property;
		pbat->pbi = &pmu_batteries[i];

		ret = power_supply_register(&bat_pdev->dev, &pbat->bat);
		if (ret) {
			kfree(pbat);
			goto battery_register_failed;
		}
		pbats[i] = pbat;
	}

	goto success;

battery_register_failed:
	while (i--) {
		if (!pbats[i])
			continue;
		power_supply_unregister(&pbats[i]->bat);
		kfree(pbats[i]);
	}
	power_supply_unregister(&pmu_ac);
ac_register_failed:
	platform_device_unregister(bat_pdev);
pdev_register_failed:
success:
	return ret;
}

static void __exit pmu_bat_exit(void)
{
	int i;

	for (i = 0; i < PMU_MAX_BATTERIES; i++) {
		if (!pbats[i])
			continue;
		power_supply_unregister(&pbats[i]->bat);
		kfree(pbats[i]);
	}
	power_supply_unregister(&pmu_ac);
	platform_device_unregister(bat_pdev);
}

module_init(pmu_bat_init);
module_exit(pmu_bat_exit);

MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PMU battery driver");
