/*
 * 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 <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/system.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(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 struct wf_sensor_ops smu_cputemp_ops = {
	.get_value	= smu_cputemp_get,
	.release	= smu_ads_release,
	.owner		= THIS_MODULE,
};
static struct wf_sensor_ops smu_cpuamp_ops = {
	.get_value	= smu_cpuamp_get,
	.release	= smu_ads_release,
	.owner		= THIS_MODULE,
};
static struct wf_sensor_ops smu_cpuvolt_ops = {
	.get_value	= smu_cpuvolt_get,
	.release	= smu_ads_release,
	.owner		= THIS_MODULE,
};
static 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;
	char *c, *l;
	u32 *v;

	ads = kmalloc(sizeof(struct smu_ad_sensor), GFP_KERNEL);
	if (ads == NULL)
		return NULL;
	c = (char *)get_property(node, "device_type", NULL);
	l = (char *)get_property(node, "location", NULL);
	if (c == NULL || 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 (!strcmp(c, "temp-sensor") &&
	    !strcmp(l, "CPU T-Diode")) {
		ads->sens.ops = &smu_cputemp_ops;
		ads->sens.name = "cpu-temp";
	} else if (!strcmp(c, "current-sensor") &&
		   !strcmp(l, "CPU Current")) {
		ads->sens.ops = &smu_cpuamp_ops;
		ads->sens.name = "cpu-current";
	} else if (!strcmp(c, "voltage-sensor") &&
		   !strcmp(l, "CPU Voltage")) {
		ads->sens.ops = &smu_cpuvolt_ops;
		ads->sens.name = "cpu-voltage";
	} else if (!strcmp(c, "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 = (u32 *)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 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 ((machine_is_compatible("PowerMac8,1") ||
	     machine_is_compatible("PowerMac8,2") ||
	     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 int smu_fetch_param_partitions(void)
{
	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) {
		DBG("wf: cpuvcp partition (%02x) not found\n",
		    SMU_SDB_CPUVCP_ID);
		return -ENODEV;
	}
	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) {
		DBG("wf: cpudiode partition (%02x) not found\n",
		    SMU_SDB_CPUDIODE_ID);
		return -ENODEV;
	}
	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];

	return 0;
}

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

	if (!smu_present())
		return -ENODEV;

	/* Get parameters partitions */
	rc = smu_fetch_param_partitions();
	if (rc)
		return rc;

	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 (!strcmp(sensors->name, "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");

