// SPDX-License-Identifier: GPL-2.0-or-later
/* tmp401.c
 *
 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
 * Preliminary tmp411 support by:
 * Gabriel Konat, Sander Leget, Wouter Willems
 * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de>
 *
 * Cleanup and support for TMP431 and TMP432 by Guenter Roeck
 * Copyright (c) 2013 Guenter Roeck <linux@roeck-us.net>
 */

/*
 * Driver for the Texas Instruments TMP401 SMBUS temperature sensor IC.
 *
 * Note this IC is in some aspect similar to the LM90, but it has quite a
 * few differences too, for example the local temp has a higher resolution
 * and thus has 16 bits registers for its value and limit instead of 8 bits.
 */

#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/slab.h>

/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d,
	0x4e, 0x4f, I2C_CLIENT_END };

enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 };

/*
 * The TMP401 registers, note some registers have different addresses for
 * reading and writing
 */
#define TMP401_STATUS				0x02
#define TMP401_CONFIG				0x03
#define TMP401_CONVERSION_RATE			0x04
#define TMP4XX_N_FACTOR_REG			0x18
#define TMP43X_BETA_RANGE			0x25
#define TMP401_TEMP_CRIT_HYST			0x21
#define TMP401_MANUFACTURER_ID_REG		0xFE
#define TMP401_DEVICE_ID_REG			0xFF

static const u8 TMP401_TEMP_MSB[7][3] = {
	{ 0x00, 0x01, 0x23 },	/* temp */
	{ 0x06, 0x08, 0x16 },	/* low limit */
	{ 0x05, 0x07, 0x15 },	/* high limit */
	{ 0x20, 0x19, 0x1a },	/* therm (crit) limit */
	{ 0x30, 0x34, 0x00 },	/* lowest */
	{ 0x32, 0xf6, 0x00 },	/* highest */
};

/* [0] = fault, [1] = low, [2] = high, [3] = therm/crit */
static const u8 TMP432_STATUS_REG[] = {
	0x1b, 0x36, 0x35, 0x37 };

/* Flags */
#define TMP401_CONFIG_RANGE			BIT(2)
#define TMP401_CONFIG_SHUTDOWN			BIT(6)
#define TMP401_STATUS_LOCAL_CRIT		BIT(0)
#define TMP401_STATUS_REMOTE_CRIT		BIT(1)
#define TMP401_STATUS_REMOTE_OPEN		BIT(2)
#define TMP401_STATUS_REMOTE_LOW		BIT(3)
#define TMP401_STATUS_REMOTE_HIGH		BIT(4)
#define TMP401_STATUS_LOCAL_LOW			BIT(5)
#define TMP401_STATUS_LOCAL_HIGH		BIT(6)

/* On TMP432, each status has its own register */
#define TMP432_STATUS_LOCAL			BIT(0)
#define TMP432_STATUS_REMOTE1			BIT(1)
#define TMP432_STATUS_REMOTE2			BIT(2)

/* Manufacturer / Device ID's */
#define TMP401_MANUFACTURER_ID			0x55
#define TMP401_DEVICE_ID			0x11
#define TMP411A_DEVICE_ID			0x12
#define TMP411B_DEVICE_ID			0x13
#define TMP411C_DEVICE_ID			0x10
#define TMP431_DEVICE_ID			0x31
#define TMP432_DEVICE_ID			0x32
#define TMP435_DEVICE_ID			0x35

/*
 * Driver data (common to all clients)
 */

static const struct i2c_device_id tmp401_id[] = {
	{ "tmp401", tmp401 },
	{ "tmp411", tmp411 },
	{ "tmp431", tmp431 },
	{ "tmp432", tmp432 },
	{ "tmp435", tmp435 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, tmp401_id);

/*
 * Client data (each client gets its own)
 */

struct tmp401_data {
	struct i2c_client *client;
	struct regmap *regmap;
	enum chips kind;

	bool extended_range;

	/* hwmon API configuration data */
	u32 chip_channel_config[4];
	struct hwmon_channel_info chip_info;
	u32 temp_channel_config[4];
	struct hwmon_channel_info temp_info;
	const struct hwmon_channel_info *info[3];
	struct hwmon_chip_info chip;
};

/* regmap */

static bool tmp401_regmap_is_volatile(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case 0:			/* local temp msb */
	case 1:			/* remote temp msb */
	case 2:			/* status */
	case 0x10:		/* remote temp lsb */
	case 0x15:		/* local temp lsb */
	case 0x1b:		/* status (tmp432) */
	case 0x23 ... 0x24:	/* remote temp 2 msb / lsb */
	case 0x30 ... 0x37:	/* lowest/highest temp; status (tmp432) */
		return true;
	default:
		return false;
	}
}

static int tmp401_reg_read(void *context, unsigned int reg, unsigned int *val)
{
	struct tmp401_data *data = context;
	struct i2c_client *client = data->client;
	int regval;

	switch (reg) {
	case 0:			/* local temp msb */
	case 1:			/* remote temp msb */
	case 5:			/* local temp high limit msb */
	case 6:			/* local temp low limit msb */
	case 7:			/* remote temp ligh limit msb */
	case 8:			/* remote temp low limit msb */
	case 0x15:		/* remote temp 2 high limit msb */
	case 0x16:		/* remote temp 2 low limit msb */
	case 0x23:		/* remote temp 2 msb */
	case 0x30:		/* local temp minimum, tmp411 */
	case 0x32:		/* local temp maximum, tmp411 */
	case 0x34:		/* remote temp minimum, tmp411 */
	case 0xf6:		/* remote temp maximum, tmp411 (really 0x36) */
		/* work around register overlap between TMP411 and TMP432 */
		if (reg == 0xf6)
			reg = 0x36;
		regval = i2c_smbus_read_word_swapped(client, reg);
		if (regval < 0)
			return regval;
		*val = regval;
		break;
	case 0x19:		/* critical limits, 8-bit registers */
	case 0x1a:
	case 0x20:
		regval = i2c_smbus_read_byte_data(client, reg);
		if (regval < 0)
			return regval;
		*val = regval << 8;
		break;
	case 0x1b:
	case 0x35 ... 0x37:
		if (data->kind == tmp432) {
			regval = i2c_smbus_read_byte_data(client, reg);
			if (regval < 0)
				return regval;
			*val = regval;
			break;
		}
		/* simulate TMP432 status registers */
		regval = i2c_smbus_read_byte_data(client, TMP401_STATUS);
		if (regval < 0)
			return regval;
		*val = 0;
		switch (reg) {
		case 0x1b:	/* open / fault */
			if (regval & TMP401_STATUS_REMOTE_OPEN)
				*val |= BIT(1);
			break;
		case 0x35:	/* high limit */
			if (regval & TMP401_STATUS_LOCAL_HIGH)
				*val |= BIT(0);
			if (regval & TMP401_STATUS_REMOTE_HIGH)
				*val |= BIT(1);
			break;
		case 0x36:	/* low limit */
			if (regval & TMP401_STATUS_LOCAL_LOW)
				*val |= BIT(0);
			if (regval & TMP401_STATUS_REMOTE_LOW)
				*val |= BIT(1);
			break;
		case 0x37:	/* therm / crit limit */
			if (regval & TMP401_STATUS_LOCAL_CRIT)
				*val |= BIT(0);
			if (regval & TMP401_STATUS_REMOTE_CRIT)
				*val |= BIT(1);
			break;
		}
		break;
	default:
		regval = i2c_smbus_read_byte_data(client, reg);
		if (regval < 0)
			return regval;
		*val = regval;
		break;
	}
	return 0;
}

static int tmp401_reg_write(void *context, unsigned int reg, unsigned int val)
{
	struct tmp401_data *data = context;
	struct i2c_client *client = data->client;

	switch (reg) {
	case 0x05:		/* local temp high limit msb */
	case 0x06:		/* local temp low limit msb */
	case 0x07:		/* remote temp ligh limit msb */
	case 0x08:		/* remote temp low limit msb */
		reg += 6;	/* adjust for register write address */
		fallthrough;
	case 0x15:		/* remote temp 2 high limit msb */
	case 0x16:		/* remote temp 2 low limit msb */
		return i2c_smbus_write_word_swapped(client, reg, val);
	case 0x19:		/* critical limits, 8-bit registers */
	case 0x1a:
	case 0x20:
		return i2c_smbus_write_byte_data(client, reg, val >> 8);
	case TMP401_CONVERSION_RATE:
	case TMP401_CONFIG:
		reg += 6;	/* adjust for register write address */
		fallthrough;
	default:
		return i2c_smbus_write_byte_data(client, reg, val);
	}
}

static const struct regmap_config tmp401_regmap_config = {
	.reg_bits = 8,
	.val_bits = 16,
	.cache_type = REGCACHE_MAPLE,
	.volatile_reg = tmp401_regmap_is_volatile,
	.reg_read = tmp401_reg_read,
	.reg_write = tmp401_reg_write,
};

/* temperature conversion */

static int tmp401_register_to_temp(u16 reg, bool extended)
{
	int temp = reg;

	if (extended)
		temp -= 64 * 256;

	return DIV_ROUND_CLOSEST(temp * 125, 32);
}

static u16 tmp401_temp_to_register(long temp, bool extended, int zbits)
{
	if (extended) {
		temp = clamp_val(temp, -64000, 191000);
		temp += 64000;
	} else {
		temp = clamp_val(temp, 0, 127000);
	}

	return DIV_ROUND_CLOSEST(temp * (1 << (8 - zbits)), 1000) << zbits;
}

/* hwmon API functions */

static const u8 tmp401_temp_reg_index[] = {
	[hwmon_temp_input] = 0,
	[hwmon_temp_min] = 1,
	[hwmon_temp_max] = 2,
	[hwmon_temp_crit] = 3,
	[hwmon_temp_lowest] = 4,
	[hwmon_temp_highest] = 5,
};

static const u8 tmp401_status_reg_index[] = {
	[hwmon_temp_fault] = 0,
	[hwmon_temp_min_alarm] = 1,
	[hwmon_temp_max_alarm] = 2,
	[hwmon_temp_crit_alarm] = 3,
};

static int tmp401_temp_read(struct device *dev, u32 attr, int channel, long *val)
{
	struct tmp401_data *data = dev_get_drvdata(dev);
	struct regmap *regmap = data->regmap;
	unsigned int regs[2] = { TMP401_TEMP_MSB[3][channel], TMP401_TEMP_CRIT_HYST };
	unsigned int regval;
	u16 regvals[2];
	int reg, ret;

	switch (attr) {
	case hwmon_temp_input:
	case hwmon_temp_min:
	case hwmon_temp_max:
	case hwmon_temp_crit:
	case hwmon_temp_lowest:
	case hwmon_temp_highest:
		reg = TMP401_TEMP_MSB[tmp401_temp_reg_index[attr]][channel];
		ret = regmap_read(regmap, reg, &regval);
		if (ret < 0)
			return ret;
		*val = tmp401_register_to_temp(regval, data->extended_range);
		break;
	case hwmon_temp_crit_hyst:
		ret = regmap_multi_reg_read(regmap, regs, regvals, 2);
		if (ret < 0)
			return ret;
		*val = tmp401_register_to_temp(regvals[0], data->extended_range) -
							(regvals[1] * 1000);
		break;
	case hwmon_temp_fault:
	case hwmon_temp_min_alarm:
	case hwmon_temp_max_alarm:
	case hwmon_temp_crit_alarm:
		reg = TMP432_STATUS_REG[tmp401_status_reg_index[attr]];
		ret = regmap_read(regmap, reg, &regval);
		if (ret < 0)
			return ret;
		*val = !!(regval & BIT(channel));
		break;
	default:
		return -EOPNOTSUPP;
	}
	return 0;
}

static int tmp401_temp_write(struct device *dev, u32 attr, int channel,
			     long val)
{
	struct tmp401_data *data = dev_get_drvdata(dev);
	struct regmap *regmap = data->regmap;
	unsigned int regval;
	int reg, ret, temp;

	switch (attr) {
	case hwmon_temp_min:
	case hwmon_temp_max:
	case hwmon_temp_crit:
		reg = TMP401_TEMP_MSB[tmp401_temp_reg_index[attr]][channel];
		regval = tmp401_temp_to_register(val, data->extended_range,
						 attr == hwmon_temp_crit ? 8 : 4);
		ret = regmap_write(regmap, reg, regval);
		break;
	case hwmon_temp_crit_hyst:
		if (data->extended_range)
			val = clamp_val(val, -64000, 191000);
		else
			val = clamp_val(val, 0, 127000);

		reg = TMP401_TEMP_MSB[3][channel];
		ret = regmap_read(regmap, reg, &regval);
		if (ret < 0)
			break;
		temp = tmp401_register_to_temp(regval, data->extended_range);
		val = clamp_val(val, temp - 255000, temp);
		regval = ((temp - val) + 500) / 1000;
		ret = regmap_write(regmap, TMP401_TEMP_CRIT_HYST, regval);
		break;
	default:
		ret = -EOPNOTSUPP;
		break;
	}
	return ret;
}

static int tmp401_chip_read(struct device *dev, u32 attr, int channel, long *val)
{
	struct tmp401_data *data = dev_get_drvdata(dev);
	u32 regval;
	int ret;

	switch (attr) {
	case hwmon_chip_update_interval:
		ret = regmap_read(data->regmap, TMP401_CONVERSION_RATE, &regval);
		if (ret < 0)
			return ret;
		*val = (1 << (7 - min(regval, 7))) * 125;
		break;
	case hwmon_chip_temp_reset_history:
		*val = 0;
		break;
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

static int tmp401_set_convrate(struct regmap *regmap, long val)
{
	int rate;

	/*
	 * For valid rates, interval can be calculated as
	 *	interval = (1 << (7 - rate)) * 125;
	 * Rounded rate is therefore
	 *	rate = 7 - __fls(interval * 4 / (125 * 3));
	 * Use clamp_val() to avoid overflows, and to ensure valid input
	 * for __fls.
	 */
	val = clamp_val(val, 125, 16000);
	rate = 7 - __fls(val * 4 / (125 * 3));
	return regmap_write(regmap, TMP401_CONVERSION_RATE, rate);
}

static int tmp401_chip_write(struct device *dev, u32 attr, int channel, long val)
{
	struct tmp401_data *data = dev_get_drvdata(dev);
	struct regmap *regmap = data->regmap;
	int err;

	switch (attr) {
	case hwmon_chip_update_interval:
		err = tmp401_set_convrate(regmap, val);
		break;
	case hwmon_chip_temp_reset_history:
		if (val != 1) {
			err = -EINVAL;
			break;
		}
		/*
		 * Reset history by writing any value to any of the
		 * minimum/maximum registers (0x30-0x37).
		 */
		err = regmap_write(regmap, 0x30, 0);
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}
	return err;
}

static int tmp401_read(struct device *dev, enum hwmon_sensor_types type,
		       u32 attr, int channel, long *val)
{
	switch (type) {
	case hwmon_chip:
		return tmp401_chip_read(dev, attr, channel, val);
	case hwmon_temp:
		return tmp401_temp_read(dev, attr, channel, val);
	default:
		return -EOPNOTSUPP;
	}
}

static int tmp401_write(struct device *dev, enum hwmon_sensor_types type,
			u32 attr, int channel, long val)
{
	switch (type) {
	case hwmon_chip:
		return tmp401_chip_write(dev, attr, channel, val);
	case hwmon_temp:
		return tmp401_temp_write(dev, attr, channel, val);
	default:
		return -EOPNOTSUPP;
	}
}

static umode_t tmp401_is_visible(const void *data, enum hwmon_sensor_types type,
				 u32 attr, int channel)
{
	switch (type) {
	case hwmon_chip:
		switch (attr) {
		case hwmon_chip_update_interval:
		case hwmon_chip_temp_reset_history:
			return 0644;
		default:
			break;
		}
		break;
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_input:
		case hwmon_temp_min_alarm:
		case hwmon_temp_max_alarm:
		case hwmon_temp_crit_alarm:
		case hwmon_temp_fault:
		case hwmon_temp_lowest:
		case hwmon_temp_highest:
			return 0444;
		case hwmon_temp_min:
		case hwmon_temp_max:
		case hwmon_temp_crit:
		case hwmon_temp_crit_hyst:
			return 0644;
		default:
			break;
		}
		break;
	default:
		break;
	}
	return 0;
}

static const struct hwmon_ops tmp401_ops = {
	.is_visible = tmp401_is_visible,
	.read = tmp401_read,
	.write = tmp401_write,
};

/* chip initialization, detect, probe */

static int tmp401_init_client(struct tmp401_data *data)
{
	struct regmap *regmap = data->regmap;
	u32 config, config_orig;
	int ret;
	u32 val = 0;
	s32 nfactor = 0;

	/* Set conversion rate to 2 Hz */
	ret = regmap_write(regmap, TMP401_CONVERSION_RATE, 5);
	if (ret < 0)
		return ret;

	/* Start conversions (disable shutdown if necessary) */
	ret = regmap_read(regmap, TMP401_CONFIG, &config);
	if (ret < 0)
		return ret;

	config_orig = config;
	config &= ~TMP401_CONFIG_SHUTDOWN;

	if (of_property_read_bool(data->client->dev.of_node, "ti,extended-range-enable")) {
		/* Enable measurement over extended temperature range */
		config |= TMP401_CONFIG_RANGE;
	}

	data->extended_range = !!(config & TMP401_CONFIG_RANGE);

	if (config != config_orig) {
		ret = regmap_write(regmap, TMP401_CONFIG, config);
		if (ret < 0)
			return ret;
	}

	ret = of_property_read_u32(data->client->dev.of_node, "ti,n-factor", &nfactor);
	if (!ret) {
		if (data->kind == tmp401) {
			dev_err(&data->client->dev, "ti,tmp401 does not support n-factor correction\n");
			return -EINVAL;
		}
		if (nfactor < -128 || nfactor > 127) {
			dev_err(&data->client->dev, "n-factor is invalid (%d)\n", nfactor);
			return -EINVAL;
		}
		ret = regmap_write(regmap, TMP4XX_N_FACTOR_REG, (unsigned int)nfactor);
		if (ret < 0)
			return ret;
	}

	ret = of_property_read_u32(data->client->dev.of_node, "ti,beta-compensation", &val);
	if (!ret) {
		if (data->kind == tmp401 || data->kind == tmp411) {
			dev_err(&data->client->dev, "ti,tmp401 or ti,tmp411 does not support beta compensation\n");
			return -EINVAL;
		}
		if (val > 15) {
			dev_err(&data->client->dev, "beta-compensation is invalid (%u)\n", val);
			return -EINVAL;
		}
		ret = regmap_write(regmap, TMP43X_BETA_RANGE, val);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int tmp401_detect(struct i2c_client *client,
			 struct i2c_board_info *info)
{
	enum chips kind;
	struct i2c_adapter *adapter = client->adapter;
	u8 reg;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -ENODEV;

	/* Detect and identify the chip */
	reg = i2c_smbus_read_byte_data(client, TMP401_MANUFACTURER_ID_REG);
	if (reg != TMP401_MANUFACTURER_ID)
		return -ENODEV;

	reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);

	switch (reg) {
	case TMP401_DEVICE_ID:
		if (client->addr != 0x4c)
			return -ENODEV;
		kind = tmp401;
		break;
	case TMP411A_DEVICE_ID:
		if (client->addr != 0x4c)
			return -ENODEV;
		kind = tmp411;
		break;
	case TMP411B_DEVICE_ID:
		if (client->addr != 0x4d)
			return -ENODEV;
		kind = tmp411;
		break;
	case TMP411C_DEVICE_ID:
		if (client->addr != 0x4e)
			return -ENODEV;
		kind = tmp411;
		break;
	case TMP431_DEVICE_ID:
		if (client->addr != 0x4c && client->addr != 0x4d)
			return -ENODEV;
		kind = tmp431;
		break;
	case TMP432_DEVICE_ID:
		if (client->addr != 0x4c && client->addr != 0x4d)
			return -ENODEV;
		kind = tmp432;
		break;
	case TMP435_DEVICE_ID:
		kind = tmp435;
		break;
	default:
		return -ENODEV;
	}

	reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG);
	if (reg & 0x1b)
		return -ENODEV;

	reg = i2c_smbus_read_byte_data(client, TMP401_CONVERSION_RATE);
	/* Datasheet says: 0x1-0x6 */
	if (reg > 15)
		return -ENODEV;

	strscpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE);

	return 0;
}

static int tmp401_probe(struct i2c_client *client)
{
	static const char * const names[] = {
		"TMP401", "TMP411", "TMP431", "TMP432", "TMP435"
	};
	struct device *dev = &client->dev;
	struct hwmon_channel_info *info;
	struct device *hwmon_dev;
	struct tmp401_data *data;
	int status;

	data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->client = client;
	data->kind = (uintptr_t)i2c_get_match_data(client);

	data->regmap = devm_regmap_init(dev, NULL, data, &tmp401_regmap_config);
	if (IS_ERR(data->regmap))
		return PTR_ERR(data->regmap);

	/* initialize configuration data */
	data->chip.ops = &tmp401_ops;
	data->chip.info = data->info;

	data->info[0] = &data->chip_info;
	data->info[1] = &data->temp_info;

	info = &data->chip_info;
	info->type = hwmon_chip;
	info->config = data->chip_channel_config;

	data->chip_channel_config[0] = HWMON_C_UPDATE_INTERVAL;

	info = &data->temp_info;
	info->type = hwmon_temp;
	info->config = data->temp_channel_config;

	data->temp_channel_config[0] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
		HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
		HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM;
	data->temp_channel_config[1] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
		HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
		HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT;

	if (data->kind == tmp411) {
		data->temp_channel_config[0] |= HWMON_T_HIGHEST | HWMON_T_LOWEST;
		data->temp_channel_config[1] |= HWMON_T_HIGHEST | HWMON_T_LOWEST;
		data->chip_channel_config[0] |= HWMON_C_TEMP_RESET_HISTORY;
	}

	if (data->kind == tmp432) {
		data->temp_channel_config[2] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
			HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
			HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT;
	}

	/* Initialize the TMP401 chip */
	status = tmp401_init_client(data);
	if (status < 0)
		return status;

	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
							 &data->chip, NULL);
	if (IS_ERR(hwmon_dev))
		return PTR_ERR(hwmon_dev);

	dev_info(dev, "Detected TI %s chip\n", names[data->kind]);

	return 0;
}

static const struct of_device_id __maybe_unused tmp4xx_of_match[] = {
	{ .compatible = "ti,tmp401", },
	{ .compatible = "ti,tmp411", },
	{ .compatible = "ti,tmp431", },
	{ .compatible = "ti,tmp432", },
	{ .compatible = "ti,tmp435", },
	{ },
};
MODULE_DEVICE_TABLE(of, tmp4xx_of_match);

static struct i2c_driver tmp401_driver = {
	.class		= I2C_CLASS_HWMON,
	.driver = {
		.name	= "tmp401",
		.of_match_table = of_match_ptr(tmp4xx_of_match),
	},
	.probe		= tmp401_probe,
	.id_table	= tmp401_id,
	.detect		= tmp401_detect,
	.address_list	= normal_i2c,
};

module_i2c_driver(tmp401_driver);

MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver");
MODULE_LICENSE("GPL");
