/*
 * Windfarm PowerMac thermal control. FCU fan control
 *
 * Copyright 2012 Benjamin Herrenschmidt, IBM Corp.
 *
 * Released under the term of the GNU GPL v2.
 */
#undef DEBUG

#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/i2c.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/sections.h>

#include "windfarm.h"
#include "windfarm_mpu.h"

#define VERSION "1.0"

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

/*
 * This option is "weird" :) Basically, if you define this to 1
 * the control loop for the RPMs fans (not PWMs) will apply the
 * correction factor obtained from the PID to the actual RPM
 * speed read from the FCU.
 *
 * If you define the below constant to 0, then it will be
 * applied to the setpoint RPM speed, that is basically the
 * speed we proviously "asked" for.
 *
 * I'm using 0 for now which is what therm_pm72 used to do and
 * what Darwin -apparently- does based on observed behaviour.
 */
#define RPM_PID_USE_ACTUAL_SPEED	0

/* Default min/max for pumps */
#define CPU_PUMP_OUTPUT_MAX		3200
#define CPU_PUMP_OUTPUT_MIN		1250

#define FCU_FAN_RPM		0
#define FCU_FAN_PWM		1

struct wf_fcu_priv {
	struct kref		ref;
	struct i2c_client	*i2c;
	struct mutex		lock;
	struct list_head	fan_list;
	int			rpm_shift;
};

struct wf_fcu_fan {
	struct list_head	link;
	int			id;
	s32			min, max, target;
	struct wf_fcu_priv	*fcu_priv;
	struct wf_control	ctrl;
};

static void wf_fcu_release(struct kref *ref)
{
	struct wf_fcu_priv *pv = container_of(ref, struct wf_fcu_priv, ref);

	kfree(pv);
}

static void wf_fcu_fan_release(struct wf_control *ct)
{
	struct wf_fcu_fan *fan = ct->priv;

	kref_put(&fan->fcu_priv->ref, wf_fcu_release);
	kfree(fan);
}

static int wf_fcu_read_reg(struct wf_fcu_priv *pv, int reg,
			   unsigned char *buf, int nb)
{
	int tries, nr, nw;

	mutex_lock(&pv->lock);

	buf[0] = reg;
	tries = 0;
	for (;;) {
		nw = i2c_master_send(pv->i2c, buf, 1);
		if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100)
			break;
		msleep(10);
		++tries;
	}
	if (nw <= 0) {
		pr_err("Failure writing address to FCU: %d", nw);
		nr = nw;
		goto bail;
	}
	tries = 0;
	for (;;) {
		nr = i2c_master_recv(pv->i2c, buf, nb);
		if (nr > 0 || (nr < 0 && nr != -ENODEV) || tries >= 100)
			break;
		msleep(10);
		++tries;
	}
	if (nr <= 0)
		pr_err("wf_fcu: Failure reading data from FCU: %d", nw);
 bail:
	mutex_unlock(&pv->lock);
	return nr;
}

static int wf_fcu_write_reg(struct wf_fcu_priv *pv, int reg,
			    const unsigned char *ptr, int nb)
{
	int tries, nw;
	unsigned char buf[16];

	buf[0] = reg;
	memcpy(buf+1, ptr, nb);
	++nb;
	tries = 0;
	for (;;) {
		nw = i2c_master_send(pv->i2c, buf, nb);
		if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100)
			break;
		msleep(10);
		++tries;
	}
	if (nw < 0)
		pr_err("wf_fcu: Failure writing to FCU: %d", nw);
	return nw;
}

static int wf_fcu_fan_set_rpm(struct wf_control *ct, s32 value)
{
	struct wf_fcu_fan *fan = ct->priv;
	struct wf_fcu_priv *pv = fan->fcu_priv;
	int rc, shift = pv->rpm_shift;
	unsigned char buf[2];

	if (value < fan->min)
		value = fan->min;
	if (value > fan->max)
		value = fan->max;

	fan->target = value;

	buf[0] = value >> (8 - shift);
	buf[1] = value << shift;
	rc = wf_fcu_write_reg(pv, 0x10 + (fan->id * 2), buf, 2);
	if (rc < 0)
		return -EIO;
	return 0;
}

static int wf_fcu_fan_get_rpm(struct wf_control *ct, s32 *value)
{
	struct wf_fcu_fan *fan = ct->priv;
	struct wf_fcu_priv *pv = fan->fcu_priv;
	int rc, reg_base, shift = pv->rpm_shift;
	unsigned char failure;
	unsigned char active;
	unsigned char buf[2];

	rc = wf_fcu_read_reg(pv, 0xb, &failure, 1);
	if (rc != 1)
		return -EIO;
	if ((failure & (1 << fan->id)) != 0)
		return -EFAULT;
	rc = wf_fcu_read_reg(pv, 0xd, &active, 1);
	if (rc != 1)
		return -EIO;
	if ((active & (1 << fan->id)) == 0)
		return -ENXIO;

	/* Programmed value or real current speed */
#if RPM_PID_USE_ACTUAL_SPEED
	reg_base = 0x11;
#else
	reg_base = 0x10;
#endif
	rc = wf_fcu_read_reg(pv, reg_base + (fan->id * 2), buf, 2);
	if (rc != 2)
		return -EIO;

	*value = (buf[0] << (8 - shift)) | buf[1] >> shift;

	return 0;
}

static int wf_fcu_fan_set_pwm(struct wf_control *ct, s32 value)
{
	struct wf_fcu_fan *fan = ct->priv;
	struct wf_fcu_priv *pv = fan->fcu_priv;
	unsigned char buf[2];
	int rc;

	if (value < fan->min)
		value = fan->min;
	if (value > fan->max)
		value = fan->max;

	fan->target = value;

	value = (value * 2559) / 1000;
	buf[0] = value;
	rc = wf_fcu_write_reg(pv, 0x30 + (fan->id * 2), buf, 1);
	if (rc < 0)
		return -EIO;
	return 0;
}

static int wf_fcu_fan_get_pwm(struct wf_control *ct, s32 *value)
{
	struct wf_fcu_fan *fan = ct->priv;
	struct wf_fcu_priv *pv = fan->fcu_priv;
	unsigned char failure;
	unsigned char active;
	unsigned char buf[2];
	int rc;

	rc = wf_fcu_read_reg(pv, 0x2b, &failure, 1);
	if (rc != 1)
		return -EIO;
	if ((failure & (1 << fan->id)) != 0)
		return -EFAULT;
	rc = wf_fcu_read_reg(pv, 0x2d, &active, 1);
	if (rc != 1)
		return -EIO;
	if ((active & (1 << fan->id)) == 0)
		return -ENXIO;

	rc = wf_fcu_read_reg(pv, 0x30 + (fan->id * 2), buf, 1);
	if (rc != 1)
		return -EIO;

	*value = (((s32)buf[0]) * 1000) / 2559;

	return 0;
}

static s32 wf_fcu_fan_min(struct wf_control *ct)
{
	struct wf_fcu_fan *fan = ct->priv;

	return fan->min;
}

static s32 wf_fcu_fan_max(struct wf_control *ct)
{
	struct wf_fcu_fan *fan = ct->priv;

	return fan->max;
}

static const struct wf_control_ops wf_fcu_fan_rpm_ops = {
	.set_value	= wf_fcu_fan_set_rpm,
	.get_value	= wf_fcu_fan_get_rpm,
	.get_min	= wf_fcu_fan_min,
	.get_max	= wf_fcu_fan_max,
	.release	= wf_fcu_fan_release,
	.owner		= THIS_MODULE,
};

static const struct wf_control_ops wf_fcu_fan_pwm_ops = {
	.set_value	= wf_fcu_fan_set_pwm,
	.get_value	= wf_fcu_fan_get_pwm,
	.get_min	= wf_fcu_fan_min,
	.get_max	= wf_fcu_fan_max,
	.release	= wf_fcu_fan_release,
	.owner		= THIS_MODULE,
};

static void wf_fcu_get_pump_minmax(struct wf_fcu_fan *fan)
{
	const struct mpu_data *mpu = wf_get_mpu(0);
	u16 pump_min = 0, pump_max = 0xffff;
	u16 tmp[4];

	/* Try to fetch pumps min/max infos from eeprom */
	if (mpu) {
		memcpy(&tmp, mpu->processor_part_num, 8);
		if (tmp[0] != 0xffff && tmp[1] != 0xffff) {
			pump_min = max(pump_min, tmp[0]);
			pump_max = min(pump_max, tmp[1]);
		}
		if (tmp[2] != 0xffff && tmp[3] != 0xffff) {
			pump_min = max(pump_min, tmp[2]);
			pump_max = min(pump_max, tmp[3]);
		}
	}

	/* Double check the values, this _IS_ needed as the EEPROM on
	 * some dual 2.5Ghz G5s seem, at least, to have both min & max
	 * same to the same value ... (grrrr)
	 */
	if (pump_min == pump_max || pump_min == 0 || pump_max == 0xffff) {
		pump_min = CPU_PUMP_OUTPUT_MIN;
		pump_max = CPU_PUMP_OUTPUT_MAX;
	}

	fan->min = pump_min;
	fan->max = pump_max;

	DBG("wf_fcu: pump min/max for %s set to: [%d..%d] RPM\n",
	    fan->ctrl.name, pump_min, pump_max);
}

static void wf_fcu_get_rpmfan_minmax(struct wf_fcu_fan *fan)
{
	struct wf_fcu_priv *pv = fan->fcu_priv;
	const struct mpu_data *mpu0 = wf_get_mpu(0);
	const struct mpu_data *mpu1 = wf_get_mpu(1);

	/* Default */
	fan->min = 2400 >> pv->rpm_shift;
	fan->max = 56000 >> pv->rpm_shift;

	/* CPU fans have min/max in MPU */
	if (mpu0 && !strcmp(fan->ctrl.name, "cpu-front-fan-0")) {
		fan->min = max(fan->min, (s32)mpu0->rminn_intake_fan);
		fan->max = min(fan->max, (s32)mpu0->rmaxn_intake_fan);
		goto bail;
	}
	if (mpu1 && !strcmp(fan->ctrl.name, "cpu-front-fan-1")) {
		fan->min = max(fan->min, (s32)mpu1->rminn_intake_fan);
		fan->max = min(fan->max, (s32)mpu1->rmaxn_intake_fan);
		goto bail;
	}
	if (mpu0 && !strcmp(fan->ctrl.name, "cpu-rear-fan-0")) {
		fan->min = max(fan->min, (s32)mpu0->rminn_exhaust_fan);
		fan->max = min(fan->max, (s32)mpu0->rmaxn_exhaust_fan);
		goto bail;
	}
	if (mpu1 && !strcmp(fan->ctrl.name, "cpu-rear-fan-1")) {
		fan->min = max(fan->min, (s32)mpu1->rminn_exhaust_fan);
		fan->max = min(fan->max, (s32)mpu1->rmaxn_exhaust_fan);
		goto bail;
	}
	/* Rackmac variants, we just use mpu0 intake */
	if (!strncmp(fan->ctrl.name, "cpu-fan", 7)) {
		fan->min = max(fan->min, (s32)mpu0->rminn_intake_fan);
		fan->max = min(fan->max, (s32)mpu0->rmaxn_intake_fan);
		goto bail;
	}
 bail:
	DBG("wf_fcu: fan min/max for %s set to: [%d..%d] RPM\n",
	    fan->ctrl.name, fan->min, fan->max);
}

static void wf_fcu_add_fan(struct wf_fcu_priv *pv, const char *name,
			   int type, int id)
{
	struct wf_fcu_fan *fan;

	fan = kzalloc(sizeof(*fan), GFP_KERNEL);
	if (!fan)
		return;
	fan->fcu_priv = pv;
	fan->id = id;
	fan->ctrl.name = name;
	fan->ctrl.priv = fan;

	/* min/max is oddball but the code comes from
	 * therm_pm72 which seems to work so ...
	 */
	if (type == FCU_FAN_RPM) {
		if (!strncmp(name, "cpu-pump", strlen("cpu-pump")))
			wf_fcu_get_pump_minmax(fan);
		else
			wf_fcu_get_rpmfan_minmax(fan);
		fan->ctrl.type = WF_CONTROL_RPM_FAN;
		fan->ctrl.ops = &wf_fcu_fan_rpm_ops;
	} else {
		fan->min = 10;
		fan->max = 100;
		fan->ctrl.type = WF_CONTROL_PWM_FAN;
		fan->ctrl.ops = &wf_fcu_fan_pwm_ops;
	}

	if (wf_register_control(&fan->ctrl)) {
		pr_err("wf_fcu: Failed to register fan %s\n", name);
		kfree(fan);
		return;
	}
	list_add(&fan->link, &pv->fan_list);
	kref_get(&pv->ref);
}

static void wf_fcu_lookup_fans(struct wf_fcu_priv *pv)
{
	/* Translation of device-tree location properties to
	 * windfarm fan names
	 */
	static const struct {
		const char *dt_name;	/* Device-tree name */
		const char *ct_name;	/* Control name */
	} loc_trans[] = {
		{ "BACKSIDE",		"backside-fan",		},
		{ "SYS CTRLR FAN",	"backside-fan",		},
		{ "DRIVE BAY",		"drive-bay-fan",	},
		{ "SLOT",		"slots-fan",		},
		{ "PCI FAN",		"slots-fan",		},
		{ "CPU A INTAKE",	"cpu-front-fan-0",	},
		{ "CPU A EXHAUST",	"cpu-rear-fan-0",	},
		{ "CPU B INTAKE",	"cpu-front-fan-1",	},
		{ "CPU B EXHAUST",	"cpu-rear-fan-1",	},
		{ "CPU A PUMP",		"cpu-pump-0",		},
		{ "CPU B PUMP",		"cpu-pump-1",		},
		{ "CPU A 1",		"cpu-fan-a-0",		},
		{ "CPU A 2",		"cpu-fan-b-0",		},
		{ "CPU A 3",		"cpu-fan-c-0",		},
		{ "CPU B 1",		"cpu-fan-a-1",		},
		{ "CPU B 2",		"cpu-fan-b-1",		},
		{ "CPU B 3",		"cpu-fan-c-1",		},
	};
	struct device_node *np = NULL, *fcu = pv->i2c->dev.of_node;
	int i;

	DBG("Looking up FCU controls in device-tree...\n");

	while ((np = of_get_next_child(fcu, np)) != NULL) {
		int id, type = -1;
		const char *loc;
		const char *name;
		const u32 *reg;

		DBG(" control: %s, type: %s\n", np->name, np->type);

		/* Detect control type */
		if (!strcmp(np->type, "fan-rpm-control") ||
		    !strcmp(np->type, "fan-rpm"))
			type = FCU_FAN_RPM;
		if (!strcmp(np->type, "fan-pwm-control") ||
		    !strcmp(np->type, "fan-pwm"))
			type = FCU_FAN_PWM;
		/* Only care about fans for now */
		if (type == -1)
			continue;

		/* Lookup for a matching location */
		loc = of_get_property(np, "location", NULL);
		reg = of_get_property(np, "reg", NULL);
		if (loc == NULL || reg == NULL)
			continue;
		DBG(" matching location: %s, reg: 0x%08x\n", loc, *reg);

		for (i = 0; i < ARRAY_SIZE(loc_trans); i++) {
			if (strncmp(loc, loc_trans[i].dt_name,
				    strlen(loc_trans[i].dt_name)))
				continue;
			name = loc_trans[i].ct_name;

			DBG(" location match, name: %s\n", name);

			if (type == FCU_FAN_RPM)
				id = ((*reg) - 0x10) / 2;
			else
				id = ((*reg) - 0x30) / 2;
			if (id > 7) {
				pr_warning("wf_fcu: Can't parse "
				       "fan ID in device-tree for %s\n",
					   np->full_name);
				break;
			}
			wf_fcu_add_fan(pv, name, type, id);
			break;
		}
	}
}

static void wf_fcu_default_fans(struct wf_fcu_priv *pv)
{
	/* We only support the default fans for PowerMac7,2 */
	if (!of_machine_is_compatible("PowerMac7,2"))
		return;

	wf_fcu_add_fan(pv, "backside-fan",	FCU_FAN_PWM, 1);
	wf_fcu_add_fan(pv, "drive-bay-fan",	FCU_FAN_RPM, 2);
	wf_fcu_add_fan(pv, "slots-fan",		FCU_FAN_PWM, 2);
	wf_fcu_add_fan(pv, "cpu-front-fan-0",	FCU_FAN_RPM, 3);
	wf_fcu_add_fan(pv, "cpu-rear-fan-0",	FCU_FAN_RPM, 4);
	wf_fcu_add_fan(pv, "cpu-front-fan-1",	FCU_FAN_RPM, 5);
	wf_fcu_add_fan(pv, "cpu-rear-fan-1",	FCU_FAN_RPM, 6);
}

static int wf_fcu_init_chip(struct wf_fcu_priv *pv)
{
	unsigned char buf = 0xff;
	int rc;

	rc = wf_fcu_write_reg(pv, 0xe, &buf, 1);
	if (rc < 0)
		return -EIO;
	rc = wf_fcu_write_reg(pv, 0x2e, &buf, 1);
	if (rc < 0)
		return -EIO;
	rc = wf_fcu_read_reg(pv, 0, &buf, 1);
	if (rc < 0)
		return -EIO;
	pv->rpm_shift = (buf == 1) ? 2 : 3;

	pr_debug("wf_fcu: FCU Initialized, RPM fan shift is %d\n",
		 pv->rpm_shift);

	return 0;
}

static int wf_fcu_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct wf_fcu_priv *pv;

	pv = kzalloc(sizeof(*pv), GFP_KERNEL);
	if (!pv)
		return -ENOMEM;

	kref_init(&pv->ref);
	mutex_init(&pv->lock);
	INIT_LIST_HEAD(&pv->fan_list);
	pv->i2c = client;

	/*
	 * First we must start the FCU which will query the
	 * shift value to apply to RPMs
	 */
	if (wf_fcu_init_chip(pv)) {
		pr_err("wf_fcu: Initialization failed !\n");
		kfree(pv);
		return -ENXIO;
	}

	/* First lookup fans in the device-tree */
	wf_fcu_lookup_fans(pv);

	/*
	 * Older machines don't have the device-tree entries
	 * we are looking for, just hard code the list
	 */
	if (list_empty(&pv->fan_list))
		wf_fcu_default_fans(pv);

	/* Still no fans ? FAIL */
	if (list_empty(&pv->fan_list)) {
		pr_err("wf_fcu: Failed to find fans for your machine\n");
		kfree(pv);
		return -ENODEV;
	}

	dev_set_drvdata(&client->dev, pv);

	return 0;
}

static int wf_fcu_remove(struct i2c_client *client)
{
	struct wf_fcu_priv *pv = dev_get_drvdata(&client->dev);
	struct wf_fcu_fan *fan;

	while (!list_empty(&pv->fan_list)) {
		fan = list_first_entry(&pv->fan_list, struct wf_fcu_fan, link);
		list_del(&fan->link);
		wf_unregister_control(&fan->ctrl);
	}
	kref_put(&pv->ref, wf_fcu_release);
	return 0;
}

static const struct i2c_device_id wf_fcu_id[] = {
	{ "MAC,fcu", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, wf_fcu_id);

static struct i2c_driver wf_fcu_driver = {
	.driver = {
		.name	= "wf_fcu",
	},
	.probe		= wf_fcu_probe,
	.remove		= wf_fcu_remove,
	.id_table	= wf_fcu_id,
};

module_i2c_driver(wf_fcu_driver);

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

