/*
 * Windfarm PowerMac thermal control. SMU based sensors
 *
 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
 *                    <benh@kernel.crashing.org>
 *
 * Released under the term of the GNU GPL v2.
 */

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/completion.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/sections.h>
#include <asm/smu.h>

#include "windfarm.h"

#define VERSION "0.2"

#undef DEBUG

#ifdef DEBUG
#define DBG(args...)	printk(args)
#else
#define DBG(args...)	do { } while(0)
#endif

/*
 * Various SMU "partitions" calibration objects for which we
 * keep pointers here for use by bits & pieces of the driver
 */
static struct smu_sdbp_cpuvcp *cpuvcp;
static int  cpuvcp_version;
static struct smu_sdbp_cpudiode *cpudiode;
static struct smu_sdbp_slotspow *slotspow;
static u8 *debugswitches;

/*
 * SMU basic sensors objects
 */

static LIST_HEAD(smu_ads);

struct smu_ad_sensor {
	struct list_head	link;
	u32			reg;		/* index in SMU */
	struct wf_sensor	sens;
};
#define to_smu_ads(c) container_of(c, struct smu_ad_sensor, sens)

static void smu_ads_release(struct wf_sensor *sr)
{
	struct smu_ad_sensor *ads = to_smu_ads(sr);

	kfree(ads);
}

static int smu_read_adc(u8 id, s32 *value)
{
	struct smu_simple_cmd	cmd;
	DECLARE_COMPLETION_ONSTACK(comp);
	int rc;

	rc = smu_queue_simple(&cmd, SMU_CMD_READ_ADC, 1,
			      smu_done_complete, &comp, id);
	if (rc)
		return rc;
	wait_for_completion(&comp);
	if (cmd.cmd.status != 0)
		return cmd.cmd.status;
	if (cmd.cmd.reply_len != 2) {
		printk(KERN_ERR "winfarm: read ADC 0x%x returned %d bytes !\n",
		       id, cmd.cmd.reply_len);
		return -EIO;
	}
	*value = *((u16 *)cmd.buffer);
	return 0;
}

static int smu_cputemp_get(struct wf_sensor *sr, s32 *value)
{
	struct smu_ad_sensor *ads = to_smu_ads(sr);
	int rc;
	s32 val;
	s64 scaled;

	rc = smu_read_adc(ads->reg, &val);
	if (rc) {
		printk(KERN_ERR "windfarm: read CPU temp failed, err %d\n",
		       rc);
		return rc;
	}

	/* Ok, we have to scale & adjust, taking units into account */
	scaled = (s64)(((u64)val) * (u64)cpudiode->m_value);
	scaled >>= 3;
	scaled += ((s64)cpudiode->b_value) << 9;
	*value = (s32)(scaled << 1);

	return 0;
}

static int smu_cpuamp_get(struct wf_sensor *sr, s32 *value)
{
	struct smu_ad_sensor *ads = to_smu_ads(sr);
	s32 val, scaled;
	int rc;

	rc = smu_read_adc(ads->reg, &val);
	if (rc) {
		printk(KERN_ERR "windfarm: read CPU current failed, err %d\n",
		       rc);
		return rc;
	}

	/* Ok, we have to scale & adjust, taking units into account */
	scaled = (s32)(val * (u32)cpuvcp->curr_scale);
	scaled += (s32)cpuvcp->curr_offset;
	*value = scaled << 4;

	return 0;
}

static int smu_cpuvolt_get(struct wf_sensor *sr, s32 *value)
{
	struct smu_ad_sensor *ads = to_smu_ads(sr);
	s32 val, scaled;
	int rc;

	rc = smu_read_adc(ads->reg, &val);
	if (rc) {
		printk(KERN_ERR "windfarm: read CPU voltage failed, err %d\n",
		       rc);
		return rc;
	}

	/* Ok, we have to scale & adjust, taking units into account */
	scaled = (s32)(val * (u32)cpuvcp->volt_scale);
	scaled += (s32)cpuvcp->volt_offset;
	*value = scaled << 4;

	return 0;
}

static int smu_slotspow_get(struct wf_sensor *sr, s32 *value)
{
	struct smu_ad_sensor *ads = to_smu_ads(sr);
	s32 val, scaled;
	int rc;

	rc = smu_read_adc(ads->reg, &val);
	if (rc) {
		printk(KERN_ERR "windfarm: read slots power failed, err %d\n",
		       rc);
		return rc;
	}

	/* Ok, we have to scale & adjust, taking units into account */
	scaled = (s32)(val * (u32)slotspow->pow_scale);
	scaled += (s32)slotspow->pow_offset;
	*value = scaled << 4;

	return 0;
}


static const struct wf_sensor_ops smu_cputemp_ops = {
	.get_value	= smu_cputemp_get,
	.release	= smu_ads_release,
	.owner		= THIS_MODULE,
};
static const struct wf_sensor_ops smu_cpuamp_ops = {
	.get_value	= smu_cpuamp_get,
	.release	= smu_ads_release,
	.owner		= THIS_MODULE,
};
static const struct wf_sensor_ops smu_cpuvolt_ops = {
	.get_value	= smu_cpuvolt_get,
	.release	= smu_ads_release,
	.owner		= THIS_MODULE,
};
static const struct wf_sensor_ops smu_slotspow_ops = {
	.get_value	= smu_slotspow_get,
	.release	= smu_ads_release,
	.owner		= THIS_MODULE,
};


static struct smu_ad_sensor *smu_ads_create(struct device_node *node)
{
	struct smu_ad_sensor *ads;
	const char *l;
	const u32 *v;

	ads = kmalloc(sizeof(struct smu_ad_sensor), GFP_KERNEL);
	if (ads == NULL)
		return NULL;
	l = of_get_property(node, "location", NULL);
	if (l == NULL)
		goto fail;

	/* We currently pick the sensors based on the OF name and location
	 * properties, while Darwin uses the sensor-id's.
	 * The problem with the IDs is that they are model specific while it
	 * looks like apple has been doing a reasonably good job at keeping
	 * the names and locations consistents so I'll stick with the names
	 * and locations for now.
	 */
	if (of_node_is_type(node, "temp-sensor") &&
	    !strcmp(l, "CPU T-Diode")) {
		ads->sens.ops = &smu_cputemp_ops;
		ads->sens.name = "cpu-temp";
		if (cpudiode == NULL) {
			DBG("wf: cpudiode partition (%02x) not found\n",
			    SMU_SDB_CPUDIODE_ID);
			goto fail;
		}
	} else if (of_node_is_type(node, "current-sensor") &&
		   !strcmp(l, "CPU Current")) {
		ads->sens.ops = &smu_cpuamp_ops;
		ads->sens.name = "cpu-current";
		if (cpuvcp == NULL) {
			DBG("wf: cpuvcp partition (%02x) not found\n",
			    SMU_SDB_CPUVCP_ID);
			goto fail;
		}
	} else if (of_node_is_type(node, "voltage-sensor") &&
		   !strcmp(l, "CPU Voltage")) {
		ads->sens.ops = &smu_cpuvolt_ops;
		ads->sens.name = "cpu-voltage";
		if (cpuvcp == NULL) {
			DBG("wf: cpuvcp partition (%02x) not found\n",
			    SMU_SDB_CPUVCP_ID);
			goto fail;
		}
	} else if (of_node_is_type(node, "power-sensor") &&
		   !strcmp(l, "Slots Power")) {
		ads->sens.ops = &smu_slotspow_ops;
		ads->sens.name = "slots-power";
		if (slotspow == NULL) {
			DBG("wf: slotspow partition (%02x) not found\n",
			    SMU_SDB_SLOTSPOW_ID);
			goto fail;
		}
	} else
		goto fail;

	v = of_get_property(node, "reg", NULL);
	if (v == NULL)
		goto fail;
	ads->reg = *v;

	if (wf_register_sensor(&ads->sens))
		goto fail;
	return ads;
 fail:
	kfree(ads);
	return NULL;
}

/*
 * SMU Power combo sensor object
 */

struct smu_cpu_power_sensor {
	struct list_head	link;
	struct wf_sensor	*volts;
	struct wf_sensor	*amps;
	int			fake_volts : 1;
	int			quadratic : 1;
	struct wf_sensor	sens;
};
#define to_smu_cpu_power(c) container_of(c, struct smu_cpu_power_sensor, sens)

static struct smu_cpu_power_sensor *smu_cpu_power;

static void smu_cpu_power_release(struct wf_sensor *sr)
{
	struct smu_cpu_power_sensor *pow = to_smu_cpu_power(sr);

	if (pow->volts)
		wf_put_sensor(pow->volts);
	if (pow->amps)
		wf_put_sensor(pow->amps);
	kfree(pow);
}

static int smu_cpu_power_get(struct wf_sensor *sr, s32 *value)
{
	struct smu_cpu_power_sensor *pow = to_smu_cpu_power(sr);
	s32 volts, amps, power;
	u64 tmps, tmpa, tmpb;
	int rc;

	rc = pow->amps->ops->get_value(pow->amps, &amps);
	if (rc)
		return rc;

	if (pow->fake_volts) {
		*value = amps * 12 - 0x30000;
		return 0;
	}

	rc = pow->volts->ops->get_value(pow->volts, &volts);
	if (rc)
		return rc;

	power = (s32)((((u64)volts) * ((u64)amps)) >> 16);
	if (!pow->quadratic) {
		*value = power;
		return 0;
	}
	tmps = (((u64)power) * ((u64)power)) >> 16;
	tmpa = ((u64)cpuvcp->power_quads[0]) * tmps;
	tmpb = ((u64)cpuvcp->power_quads[1]) * ((u64)power);
	*value = (tmpa >> 28) + (tmpb >> 28) + (cpuvcp->power_quads[2] >> 12);

	return 0;
}

static const struct wf_sensor_ops smu_cpu_power_ops = {
	.get_value	= smu_cpu_power_get,
	.release	= smu_cpu_power_release,
	.owner		= THIS_MODULE,
};


static struct smu_cpu_power_sensor *
smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps)
{
	struct smu_cpu_power_sensor *pow;

	pow = kmalloc(sizeof(struct smu_cpu_power_sensor), GFP_KERNEL);
	if (pow == NULL)
		return NULL;
	pow->sens.ops = &smu_cpu_power_ops;
	pow->sens.name = "cpu-power";

	wf_get_sensor(volts);
	pow->volts = volts;
	wf_get_sensor(amps);
	pow->amps = amps;

	/* Some early machines need a faked voltage */
	if (debugswitches && ((*debugswitches) & 0x80)) {
		printk(KERN_INFO "windfarm: CPU Power sensor using faked"
		       " voltage !\n");
		pow->fake_volts = 1;
	} else
		pow->fake_volts = 0;

	/* Try to use quadratic transforms on PowerMac8,1 and 9,1 for now,
	 * I yet have to figure out what's up with 8,2 and will have to
	 * adjust for later, unless we can 100% trust the SDB partition...
	 */
	if ((of_machine_is_compatible("PowerMac8,1") ||
	     of_machine_is_compatible("PowerMac8,2") ||
	     of_machine_is_compatible("PowerMac9,1")) &&
	    cpuvcp_version >= 2) {
		pow->quadratic = 1;
		DBG("windfarm: CPU Power using quadratic transform\n");
	} else
		pow->quadratic = 0;

	if (wf_register_sensor(&pow->sens))
		goto fail;
	return pow;
 fail:
	kfree(pow);
	return NULL;
}

static void smu_fetch_param_partitions(void)
{
	const struct smu_sdbp_header *hdr;

	/* Get CPU voltage/current/power calibration data */
	hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL);
	if (hdr != NULL) {
		cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1];
		/* Keep version around */
		cpuvcp_version = hdr->version;
	}

	/* Get CPU diode calibration data */
	hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL);
	if (hdr != NULL)
		cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1];

	/* Get slots power calibration data if any */
	hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL);
	if (hdr != NULL)
		slotspow = (struct smu_sdbp_slotspow *)&hdr[1];

	/* Get debug switches if any */
	hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL);
	if (hdr != NULL)
		debugswitches = (u8 *)&hdr[1];
}

static int __init smu_sensors_init(void)
{
	struct device_node *smu, *sensors, *s;
	struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL;

	if (!smu_present())
		return -ENODEV;

	/* Get parameters partitions */
	smu_fetch_param_partitions();

	smu = of_find_node_by_type(NULL, "smu");
	if (smu == NULL)
		return -ENODEV;

	/* Look for sensors subdir */
	for (sensors = NULL;
	     (sensors = of_get_next_child(smu, sensors)) != NULL;)
		if (of_node_name_eq(sensors, "sensors"))
			break;

	of_node_put(smu);

	/* Create basic sensors */
	for (s = NULL;
	     sensors && (s = of_get_next_child(sensors, s)) != NULL;) {
		struct smu_ad_sensor *ads;

		ads = smu_ads_create(s);
		if (ads == NULL)
			continue;
		list_add(&ads->link, &smu_ads);
		/* keep track of cpu voltage & current */
		if (!strcmp(ads->sens.name, "cpu-voltage"))
			volt_sensor = ads;
		else if (!strcmp(ads->sens.name, "cpu-current"))
			curr_sensor = ads;
	}

	of_node_put(sensors);

	/* Create CPU power sensor if possible */
	if (volt_sensor && curr_sensor)
		smu_cpu_power = smu_cpu_power_create(&volt_sensor->sens,
						     &curr_sensor->sens);

	return 0;
}

static void __exit smu_sensors_exit(void)
{
	struct smu_ad_sensor *ads;

	/* dispose of power sensor */
	if (smu_cpu_power)
		wf_unregister_sensor(&smu_cpu_power->sens);

	/* dispose of basic sensors */
	while (!list_empty(&smu_ads)) {
		ads = list_entry(smu_ads.next, struct smu_ad_sensor, link);
		list_del(&ads->link);
		wf_unregister_sensor(&ads->sens);
	}
}


module_init(smu_sensors_init);
module_exit(smu_sensors_exit);

MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("SMU sensor objects for PowerMacs thermal control");
MODULE_LICENSE("GPL");

