// SPDX-License-Identifier: GPL-2.0-only
/*
 * Windfarm PowerMac thermal control. LM87 sensor
 *
 * Copyright 2012 Benjamin Herrenschmidt, IBM Corp.
 */

#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 <asm/pmac_low_i2c.h>

#include "windfarm.h"

#define VERSION "1.0"

#undef DEBUG

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

struct wf_lm87_sensor {
	struct i2c_client	*i2c;
	struct wf_sensor	sens;
};
#define wf_to_lm87(c) container_of(c, struct wf_lm87_sensor, sens)


static int wf_lm87_read_reg(struct i2c_client *chip, int reg)
{
	int rc, tries = 0;
	u8 buf;

	for (;;) {
		/* Set address */
		buf = (u8)reg;
		rc = i2c_master_send(chip, &buf, 1);
		if (rc <= 0)
			goto error;
		rc = i2c_master_recv(chip, &buf, 1);
		if (rc <= 0)
			goto error;
		return (int)buf;
	error:
		DBG("wf_lm87: Error reading LM87, retrying...\n");
		if (++tries > 10) {
			printk(KERN_ERR "wf_lm87: Error reading LM87 !\n");
			return -EIO;
		}
		msleep(10);
	}
}

static int wf_lm87_get(struct wf_sensor *sr, s32 *value)
{
	struct wf_lm87_sensor *lm = sr->priv;
	s32 temp;

	if (lm->i2c == NULL)
		return -ENODEV;

#define LM87_INT_TEMP		0x27

	/* Read temperature register */
	temp = wf_lm87_read_reg(lm->i2c, LM87_INT_TEMP);
	if (temp < 0)
		return temp;
	*value = temp << 16;

	return 0;
}

static void wf_lm87_release(struct wf_sensor *sr)
{
	struct wf_lm87_sensor *lm = wf_to_lm87(sr);

	kfree(lm);
}

static const struct wf_sensor_ops wf_lm87_ops = {
	.get_value	= wf_lm87_get,
	.release	= wf_lm87_release,
	.owner		= THIS_MODULE,
};

static int wf_lm87_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{	
	struct wf_lm87_sensor *lm;
	const char *name = NULL, *loc;
	struct device_node *np = NULL;
	int rc;

	/*
	 * The lm87 contains a whole pile of sensors, additionally,
	 * the Xserve G5 has several lm87's. However, for now we only
	 * care about the internal temperature sensor
	 */
	for_each_child_of_node(client->dev.of_node, np) {
		if (!of_node_name_eq(np, "int-temp"))
			continue;
		loc = of_get_property(np, "location", NULL);
		if (!loc)
			continue;
		if (strstr(loc, "DIMM"))
			name = "dimms-temp";
		else if (strstr(loc, "Processors"))
			name = "between-cpus-temp";
		if (name) {
			of_node_put(np);
			break;
		}
	}
	if (!name) {
		pr_warning("wf_lm87: Unsupported sensor %pOF\n",
			   client->dev.of_node);
		return -ENODEV;
	}

	lm = kzalloc(sizeof(struct wf_lm87_sensor), GFP_KERNEL);
	if (lm == NULL)
		return -ENODEV;

	lm->i2c = client;
	lm->sens.name = name;
	lm->sens.ops = &wf_lm87_ops;
	lm->sens.priv = lm;
	i2c_set_clientdata(client, lm);

	rc = wf_register_sensor(&lm->sens);
	if (rc)
		kfree(lm);
	return rc;
}

static int wf_lm87_remove(struct i2c_client *client)
{
	struct wf_lm87_sensor *lm = i2c_get_clientdata(client);

	DBG("wf_lm87: i2c detatch called for %s\n", lm->sens.name);

	/* Mark client detached */
	lm->i2c = NULL;

	/* release sensor */
	wf_unregister_sensor(&lm->sens);

	return 0;
}

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

static struct i2c_driver wf_lm87_driver = {
	.driver = {
		.name	= "wf_lm87",
	},
	.probe		= wf_lm87_probe,
	.remove		= wf_lm87_remove,
	.id_table	= wf_lm87_id,
};

static int __init wf_lm87_sensor_init(void)
{
	/* We only support this on the Xserve */
	if (!of_machine_is_compatible("RackMac3,1"))
		return -ENODEV;

	return i2c_add_driver(&wf_lm87_driver);
}

static void __exit wf_lm87_sensor_exit(void)
{
	i2c_del_driver(&wf_lm87_driver);
}


module_init(wf_lm87_sensor_init);
module_exit(wf_lm87_sensor_exit);

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

