/*
 * Copyright (C) 2015, Google, Inc.
 *
 * The LM95071 is a three-pin SPI-enabled temperature sensor.
 * Datasheet can be found here:
 *   http://www.ti.com/lit/gpn/lm95071
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/hwmon.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/hwmon-sysfs.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/sysfs.h>

#define DEVNAME "lm95071"
#define DEVID   0x800f

#define LM95071_CC 0x0000

struct lm95071 {
	struct device *hwmon_dev;
};

static ssize_t lm95071_show_name(struct device *dev,
				 struct device_attribute *devattr, char *buf)
{
	return sprintf(buf, "%s\n", DEVNAME);
}

static DEVICE_ATTR(name, S_IRUGO, lm95071_show_name, NULL);


static ssize_t lm95071_show_temp(struct device *dev,
				 struct device_attribute *devattr, char *buf)
{
	int ret;
	s64 temp;
	u16 sign;
	u8 rx_buf[2];
	u16 raw_temp = 0;
	struct spi_device *spi = to_spi_device(dev);
	ret = spi_write_then_read(spi, NULL, 0, rx_buf, ARRAY_SIZE(rx_buf));
	if (ret < 0) {
		return ret;
	}

	/* Temperature Conversion */
	raw_temp = (rx_buf[0] << 8) | rx_buf[1];
	sign = 0x8000 & raw_temp;
	if (sign) {
		raw_temp = ~raw_temp + 1;
	}

	/*
	 * LM90571 Temp register has two unused bits at the end.  After these are
	 * removed, every number remaining corresponds to 0.03125 C of temperature.
	 * This is increased by three orders of five orders of magnitude to make math
	 * simple, then divided by 100 to convert to millidigrees.
	 *
	 * Official docs here: http://www.ti.com/lit/ds/symlink/lm95071.pdf
	 */
	temp = raw_temp >> 2;
	temp = (temp * 1000) >> 5;
	return sprintf(buf, "%lld\n", sign ? -temp : temp);
}

static DEVICE_ATTR(temp1_input, S_IRUGO, lm95071_show_temp, NULL);

/*
 * Before continuous conversion mode is activated, the sensor will return its
 * ID whenever 16 bits are read.
 */
static int lm95071_detect(struct spi_device *spi)
{
	u16 id;
	u8 rx_buf[2];
	spi_write_then_read(spi, NULL, 0, rx_buf, ARRAY_SIZE(rx_buf));
	id = (rx_buf[0] << 8) | rx_buf[1];
	if (id != DEVID) {
		return -ENODEV;
	}
	return 0;
}

static int lm95071_activate_cc(struct spi_device *spi)
{
	u8 tx_buf[2];
	u8 rx_buf[2];
	tx_buf[0] = (LM95071_CC >> 8) & 0xff;
	tx_buf[1] = LM95071_CC & 0xff;
	return spi_write_then_read(spi, tx_buf, ARRAY_SIZE(tx_buf),
			rx_buf, ARRAY_SIZE(rx_buf));
}

static int lm95071_probe(struct spi_device *spi)
{
	struct lm95071 *lm_dev;
	int err = 0;
	printk(KERN_INFO "lm95071: Probing for device\n");
	if ((err = lm95071_detect(spi)) || (err = lm95071_activate_cc(spi))) {
		goto exit;
	}
	lm_dev = kzalloc(sizeof(*lm_dev), GFP_KERNEL);
	if (!lm_dev) {
		err = -ENOMEM;
		goto exit;
	}
	lm_dev->hwmon_dev = hwmon_device_register(&spi->dev);
	if (IS_ERR(lm_dev->hwmon_dev)) {
		err = PTR_ERR(lm_dev->hwmon_dev);
		goto hwmon_dev_reg_fail;
	}
	spi_set_drvdata(spi, lm_dev);
	if ((err = device_create_file(&spi->dev, &dev_attr_temp1_input)) ||
		(err = device_create_file(&spi->dev, &dev_attr_name))) {
		goto sysfs_create_fail;
	}
	printk(KERN_INFO "lm95071: Found device\n");
	return 0;

sysfs_create_fail:
	device_remove_file(&spi->dev, &dev_attr_temp1_input);
	hwmon_device_unregister(lm_dev->hwmon_dev);
hwmon_dev_reg_fail:
	spi_set_drvdata(spi, NULL);
	kfree(lm_dev);
exit:
	if (err == -ENODEV) {
		printk(KERN_ERR "lm95071: Device not found\n");
	} else {
		printk(KERN_ERR "lm95071: Probe failed (%d)\n", err);
	}
	return err;
}

static int lm95071_remove(struct spi_device *spi)
{
	struct lm95071 *lm_dev = spi_get_drvdata(spi);
	device_remove_file(&spi->dev, &dev_attr_temp1_input);
	device_remove_file(&spi->dev, &dev_attr_name);
	hwmon_device_unregister(lm_dev->hwmon_dev);
	spi_set_drvdata(spi, NULL);
	kfree(lm_dev);
	return 0;
}

/* Driver data. */
static const struct spi_device_id lm95071_id[] = {
	{ DEVNAME, 0 },
	{ },
};

static struct spi_driver lm95071_driver = {
	.driver = {
		.name	= DEVNAME,
		.owner	= THIS_MODULE,
	},
	.id_table = lm95071_id,
	.probe = lm95071_probe,
	.remove = lm95071_remove,
};

module_spi_driver(lm95071_driver);
