brintos

brintos / linux-shallow public Read only

0
0
Text · 18.3 KiB · 0f629c6 Raw
704 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2 3/* Driver for the Texas Instruments TMP464 SMBus temperature sensor IC.4 * Supported models: TMP464, TMP4685 6 * Copyright (C) 2022 Agathe Porte <agathe.porte@nokia.com>7 * Preliminary support by:8 * Lionel Pouliquen <lionel.lp.pouliquen@nokia.com>9 */10 11#include <linux/err.h>12#include <linux/hwmon.h>13#include <linux/i2c.h>14#include <linux/init.h>15#include <linux/module.h>16#include <linux/mutex.h>17#include <linux/of.h>18#include <linux/regmap.h>19#include <linux/slab.h>20 21/* Addresses to scan */22static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END };23 24#define TMP464_NUM_CHANNELS		5	/* chan 0 is internal, 1-4 are remote */25#define TMP468_NUM_CHANNELS		9	/* chan 0 is internal, 1-8 are remote */26 27#define MAX_CHANNELS			928 29#define TMP464_TEMP_REG(channel)	(channel)30#define TMP464_TEMP_OFFSET_REG(channel)	(0x40 + ((channel) - 1) * 8)31#define TMP464_N_FACTOR_REG(channel)	(0x41 + ((channel) - 1) * 8)32 33static const u8 TMP464_THERM_LIMIT[MAX_CHANNELS] = {34	0x39, 0x42, 0x4A, 0x52, 0x5A, 0x62, 0x6a, 0x72, 0x7a };35static const u8 TMP464_THERM2_LIMIT[MAX_CHANNELS] = {36	0x3A, 0x43, 0x4B, 0x53, 0x5B, 0x63, 0x6b, 0x73, 0x7b };37 38#define TMP464_THERM_STATUS_REG			0x2139#define TMP464_THERM2_STATUS_REG		0x2240#define TMP464_REMOTE_OPEN_REG			0x2341#define TMP464_CONFIG_REG			0x3042#define TMP464_TEMP_HYST_REG			0x3843#define TMP464_LOCK_REG				0xc444 45/* Identification */46#define TMP464_MANUFACTURER_ID_REG		0xFE47#define TMP464_DEVICE_ID_REG			0xFF48 49/* Flags */50#define TMP464_CONFIG_SHUTDOWN			BIT(5)51#define TMP464_CONFIG_RANGE			0x0452#define TMP464_CONFIG_REG_REN(x)		(BIT(7 + (x)))53#define TMP464_CONFIG_REG_REN_MASK		GENMASK(15, 7)54#define TMP464_CONFIG_CONVERSION_RATE_B0	255#define TMP464_CONFIG_CONVERSION_RATE_B2	456#define TMP464_CONFIG_CONVERSION_RATE_MASK      GENMASK(TMP464_CONFIG_CONVERSION_RATE_B2, \57							TMP464_CONFIG_CONVERSION_RATE_B0)58 59#define TMP464_UNLOCK_VAL			0xeb1960#define TMP464_LOCK_VAL				0x5ca661#define TMP464_LOCKED				0x800062 63/* Manufacturer / Device ID's */64#define TMP464_MANUFACTURER_ID			0x544965#define TMP464_DEVICE_ID			0x146866#define TMP468_DEVICE_ID			0x046867 68static const struct i2c_device_id tmp464_id[] = {69	{ "tmp464", TMP464_NUM_CHANNELS },70	{ "tmp468", TMP468_NUM_CHANNELS },71	{ }72};73MODULE_DEVICE_TABLE(i2c, tmp464_id);74 75static const struct of_device_id __maybe_unused tmp464_of_match[] = {76	{77		.compatible = "ti,tmp464",78		.data = (void *)TMP464_NUM_CHANNELS79	},80	{81		.compatible = "ti,tmp468",82		.data = (void *)TMP468_NUM_CHANNELS83	},84	{},85};86MODULE_DEVICE_TABLE(of, tmp464_of_match);87 88struct tmp464_channel {89	const char *label;90	bool enabled;91};92 93struct tmp464_data {94	struct regmap *regmap;95	struct mutex update_lock;96	int channels;97	s16 config_orig;98	u16 open_reg;99	unsigned long last_updated;100	bool valid;101	int update_interval;102	struct tmp464_channel channel[MAX_CHANNELS];103};104 105static int temp_from_reg(s16 reg)106{107	return DIV_ROUND_CLOSEST((reg >> 3) * 625, 10);108}109 110static s16 temp_to_limit_reg(long temp)111{112	return DIV_ROUND_CLOSEST(temp, 500) << 6;113}114 115static s16 temp_to_offset_reg(long temp)116{117	return DIV_ROUND_CLOSEST(temp * 10, 625) << 3;118}119 120static int tmp464_enable_channels(struct tmp464_data *data)121{122	struct regmap *regmap = data->regmap;123	u16 enable = 0;124	int i;125 126	for (i = 0; i < data->channels; i++)127		if (data->channel[i].enabled)128			enable |= TMP464_CONFIG_REG_REN(i);129 130	return regmap_update_bits(regmap, TMP464_CONFIG_REG, TMP464_CONFIG_REG_REN_MASK, enable);131}132 133static int tmp464_chip_read(struct device *dev, u32 attr, int channel, long *val)134{135	struct tmp464_data *data = dev_get_drvdata(dev);136 137	switch (attr) {138	case hwmon_chip_update_interval:139		*val = data->update_interval;140		return 0;141	default:142		return -EOPNOTSUPP;143	}144}145 146static int tmp464_temp_read(struct device *dev, u32 attr, int channel, long *val)147{148	struct tmp464_data *data = dev_get_drvdata(dev);149	struct regmap *regmap = data->regmap;150	unsigned int regs[2];151	unsigned int regval;152	u16 regvals[2];153	int err = 0;154 155	switch (attr) {156	case hwmon_temp_max_alarm:157		err = regmap_read(regmap, TMP464_THERM_STATUS_REG, &regval);158		if (err < 0)159			break;160		*val = !!(regval & BIT(channel + 7));161		break;162	case hwmon_temp_crit_alarm:163		err = regmap_read(regmap, TMP464_THERM2_STATUS_REG, &regval);164		if (err < 0)165			break;166		*val = !!(regval & BIT(channel + 7));167		break;168	case hwmon_temp_fault:169		/*170		 * The chip clears TMP464_REMOTE_OPEN_REG after it is read171		 * and only updates it after the next measurement cycle is172		 * complete. That means we have to cache the value internally173		 * for one measurement cycle and report the cached value.174		 */175		mutex_lock(&data->update_lock);176		if (!data->valid || time_after(jiffies, data->last_updated +177					       msecs_to_jiffies(data->update_interval))) {178			err = regmap_read(regmap, TMP464_REMOTE_OPEN_REG, &regval);179			if (err < 0)180				goto unlock;181			data->open_reg = regval;182			data->last_updated = jiffies;183			data->valid = true;184		}185		*val = !!(data->open_reg & BIT(channel + 7));186unlock:187		mutex_unlock(&data->update_lock);188		break;189	case hwmon_temp_max_hyst:190		regs[0] = TMP464_THERM_LIMIT[channel];191		regs[1] = TMP464_TEMP_HYST_REG;192		err = regmap_multi_reg_read(regmap, regs, regvals, 2);193		if (err < 0)194			break;195		*val = temp_from_reg(regvals[0] - regvals[1]);196		break;197	case hwmon_temp_max:198		err = regmap_read(regmap, TMP464_THERM_LIMIT[channel], &regval);199		if (err < 0)200			break;201		*val = temp_from_reg(regval);202		break;203	case hwmon_temp_crit_hyst:204		regs[0] = TMP464_THERM2_LIMIT[channel];205		regs[1] = TMP464_TEMP_HYST_REG;206		err = regmap_multi_reg_read(regmap, regs, regvals, 2);207		if (err < 0)208			break;209		*val = temp_from_reg(regvals[0] - regvals[1]);210		break;211	case hwmon_temp_crit:212		err = regmap_read(regmap, TMP464_THERM2_LIMIT[channel], &regval);213		if (err < 0)214			break;215		*val = temp_from_reg(regval);216		break;217	case hwmon_temp_offset:218		err = regmap_read(regmap, TMP464_TEMP_OFFSET_REG(channel), &regval);219		if (err < 0)220			break;221		*val = temp_from_reg(regval);222		break;223	case hwmon_temp_input:224		if (!data->channel[channel].enabled) {225			err = -ENODATA;226			break;227		}228		err = regmap_read(regmap, TMP464_TEMP_REG(channel), &regval);229		if (err < 0)230			break;231		*val = temp_from_reg(regval);232		break;233	case hwmon_temp_enable:234		*val = data->channel[channel].enabled;235		break;236	default:237		err = -EOPNOTSUPP;238		break;239	}240 241	return err;242}243 244static int tmp464_read(struct device *dev, enum hwmon_sensor_types type,245		       u32 attr, int channel, long *val)246{247	switch (type) {248	case hwmon_chip:249		return tmp464_chip_read(dev, attr, channel, val);250	case hwmon_temp:251		return tmp464_temp_read(dev, attr, channel, val);252	default:253		return -EOPNOTSUPP;254	}255}256 257static int tmp464_read_string(struct device *dev, enum hwmon_sensor_types type,258			      u32 attr, int channel, const char **str)259{260	struct tmp464_data *data = dev_get_drvdata(dev);261 262	*str = data->channel[channel].label;263 264	return 0;265}266 267static int tmp464_set_convrate(struct tmp464_data *data, long interval)268{269	int rate;270 271	/*272	 * For valid rates, interval in milli-seconds can be calculated as273	 *      interval = 125 << (7 - rate);274	 * or275	 *      interval = (1 << (7 - rate)) * 125;276	 * The rate is therefore277	 *      rate = 7 - __fls(interval / 125);278	 * and the rounded rate is279	 *      rate = 7 - __fls(interval * 4 / (125 * 3));280	 * Use clamp_val() to avoid overflows, and to ensure valid input281	 * for __fls.282	 */283	interval = clamp_val(interval, 125, 16000);284	rate = 7 - __fls(interval * 4 / (125 * 3));285	data->update_interval = 125 << (7 - rate);286 287	return regmap_update_bits(data->regmap, TMP464_CONFIG_REG,288				  TMP464_CONFIG_CONVERSION_RATE_MASK,289				  rate << TMP464_CONFIG_CONVERSION_RATE_B0);290}291 292static int tmp464_chip_write(struct tmp464_data *data, u32 attr, int channel, long val)293{294	switch (attr) {295	case hwmon_chip_update_interval:296		return tmp464_set_convrate(data, val);297	default:298		return -EOPNOTSUPP;299	}300}301 302static int tmp464_temp_write(struct tmp464_data *data, u32 attr, int channel, long val)303{304	struct regmap *regmap = data->regmap;305	unsigned int regval;306	int err = 0;307 308	switch (attr) {309	case hwmon_temp_max_hyst:310		err = regmap_read(regmap, TMP464_THERM_LIMIT[0], &regval);311		if (err < 0)312			break;313		val = clamp_val(val, -256000, 256000);	/* prevent overflow/underflow */314		val = clamp_val(temp_from_reg(regval) - val, 0, 255000);315		err = regmap_write(regmap, TMP464_TEMP_HYST_REG,316				   DIV_ROUND_CLOSEST(val, 1000) << 7);317		break;318	case hwmon_temp_max:319		val = temp_to_limit_reg(clamp_val(val, -255000, 255500));320		err = regmap_write(regmap, TMP464_THERM_LIMIT[channel], val);321		break;322	case hwmon_temp_crit:323		val = temp_to_limit_reg(clamp_val(val, -255000, 255500));324		err = regmap_write(regmap, TMP464_THERM2_LIMIT[channel], val);325		break;326	case hwmon_temp_offset:327		val = temp_to_offset_reg(clamp_val(val, -128000, 127937));328		err = regmap_write(regmap, TMP464_TEMP_OFFSET_REG(channel), val);329		break;330	case hwmon_temp_enable:331		data->channel[channel].enabled = !!val;332		err = tmp464_enable_channels(data);333		break;334	default:335		err = -EOPNOTSUPP;336		break;337	}338 339	return err;340}341 342static int tmp464_write(struct device *dev, enum hwmon_sensor_types type,343			u32 attr, int channel, long val)344{345	struct tmp464_data *data = dev_get_drvdata(dev);346	int err;347 348	mutex_lock(&data->update_lock);349 350	switch (type) {351	case hwmon_chip:352		err = tmp464_chip_write(data, attr, channel, val);353		break;354	case hwmon_temp:355		err = tmp464_temp_write(data, attr, channel, val);356		break;357	default:358		err = -EOPNOTSUPP;359		break;360	}361 362	mutex_unlock(&data->update_lock);363 364	return err;365}366 367static umode_t tmp464_is_visible(const void *_data, enum hwmon_sensor_types type,368				 u32 attr, int channel)369{370	const struct tmp464_data *data = _data;371 372	if (channel >= data->channels)373		return 0;374 375	if (type == hwmon_chip) {376		if (attr == hwmon_chip_update_interval)377			return 0644;378		return 0;379	}380 381	switch (attr) {382	case hwmon_temp_input:383	case hwmon_temp_max_alarm:384	case hwmon_temp_crit_alarm:385	case hwmon_temp_crit_hyst:386		return 0444;387	case hwmon_temp_enable:388	case hwmon_temp_max:389	case hwmon_temp_crit:390		return 0644;391	case hwmon_temp_max_hyst:392		if (!channel)393			return 0644;394		return 0444;395	case hwmon_temp_label:396		if (data->channel[channel].label)397			return 0444;398		return 0;399	case hwmon_temp_fault:400		if (channel)401			return 0444;402		return 0;403	case hwmon_temp_offset:404		if (channel)405			return 0644;406		return 0;407	default:408		return 0;409	}410}411 412static void tmp464_restore_lock(void *regmap)413{414	regmap_write(regmap, TMP464_LOCK_REG, TMP464_LOCK_VAL);415}416 417static void tmp464_restore_config(void *_data)418{419	struct tmp464_data *data = _data;420 421	regmap_write(data->regmap, TMP464_CONFIG_REG, data->config_orig);422}423 424static int tmp464_init_client(struct device *dev, struct tmp464_data *data)425{426	struct regmap *regmap = data->regmap;427	unsigned int regval;428	int err;429 430	err = regmap_read(regmap, TMP464_LOCK_REG, &regval);431	if (err)432		return err;433	if (regval == TMP464_LOCKED) {434		/* Explicitly unlock chip if it is locked */435		err = regmap_write(regmap, TMP464_LOCK_REG, TMP464_UNLOCK_VAL);436		if (err)437			return err;438		/* and lock it again when unloading the driver */439		err = devm_add_action_or_reset(dev, tmp464_restore_lock, regmap);440		if (err)441			return err;442	}443 444	err = regmap_read(regmap, TMP464_CONFIG_REG, &regval);445	if (err)446		return err;447	data->config_orig = regval;448	err = devm_add_action_or_reset(dev, tmp464_restore_config, data);449	if (err)450		return err;451 452	/* Default to 500 ms update interval */453	err = regmap_update_bits(regmap, TMP464_CONFIG_REG,454				 TMP464_CONFIG_CONVERSION_RATE_MASK | TMP464_CONFIG_SHUTDOWN,455				 BIT(TMP464_CONFIG_CONVERSION_RATE_B0) |456				 BIT(TMP464_CONFIG_CONVERSION_RATE_B2));457	if (err)458		return err;459 460	data->update_interval = 500;461 462	return tmp464_enable_channels(data);463}464 465static int tmp464_detect(struct i2c_client *client,466			 struct i2c_board_info *info)467{468	struct i2c_adapter *adapter = client->adapter;469	char *name, *chip;470	int reg;471 472	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))473		return -ENODEV;474 475	reg = i2c_smbus_read_word_swapped(client, TMP464_MANUFACTURER_ID_REG);476	if (reg < 0)477		return reg;478	if (reg != TMP464_MANUFACTURER_ID)479		return -ENODEV;480 481	/* Check for "always return zero" bits */482	reg = i2c_smbus_read_word_swapped(client, TMP464_THERM_STATUS_REG);483	if (reg < 0)484		return reg;485	if (reg & 0x1f)486		return -ENODEV;487	reg = i2c_smbus_read_word_swapped(client, TMP464_THERM2_STATUS_REG);488	if (reg < 0)489		return reg;490	if (reg & 0x1f)491		return -ENODEV;492 493	reg = i2c_smbus_read_word_swapped(client, TMP464_DEVICE_ID_REG);494	if (reg < 0)495		return reg;496	switch (reg) {497	case TMP464_DEVICE_ID:498		name = "tmp464";499		chip = "TMP464";500		break;501	case TMP468_DEVICE_ID:502		name = "tmp468";503		chip = "TMP468";504		break;505	default:506		return -ENODEV;507	}508 509	strscpy(info->type, name, I2C_NAME_SIZE);510	dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n", chip, client->addr);511 512	return 0;513}514 515static int tmp464_probe_child_from_dt(struct device *dev,516				      struct device_node *child,517				      struct tmp464_data *data)518 519{520	struct regmap *regmap = data->regmap;521	u32 channel;522	s32 nfactor;523	int err;524 525	err = of_property_read_u32(child, "reg", &channel);526	if (err) {527		dev_err(dev, "missing reg property of %pOFn\n", child);528		return err;529	}530 531	if (channel >= data->channels) {532		dev_err(dev, "invalid reg %d of %pOFn\n", channel, child);533		return -EINVAL;534	}535 536	of_property_read_string(child, "label", &data->channel[channel].label);537 538	data->channel[channel].enabled = of_device_is_available(child);539 540	err = of_property_read_s32(child, "ti,n-factor", &nfactor);541	if (err && err != -EINVAL)542		return err;543	if (!err) {544		if (channel == 0) {545			dev_err(dev, "n-factor can't be set for internal channel\n");546			return -EINVAL;547		}548		if (nfactor > 127 || nfactor < -128) {549			dev_err(dev, "n-factor for channel %d invalid (%d)\n",550				channel, nfactor);551			return -EINVAL;552		}553		err = regmap_write(regmap, TMP464_N_FACTOR_REG(channel),554				   (nfactor << 8) & 0xff00);555		if (err)556			return err;557	}558 559	return 0;560}561 562static int tmp464_probe_from_dt(struct device *dev, struct tmp464_data *data)563{564	const struct device_node *np = dev->of_node;565	int err;566 567	for_each_child_of_node_scoped(np, child) {568		if (strcmp(child->name, "channel"))569			continue;570 571		err = tmp464_probe_child_from_dt(dev, child, data);572		if (err)573			return err;574	}575 576	return 0;577}578 579static const struct hwmon_ops tmp464_ops = {580	.is_visible = tmp464_is_visible,581	.read = tmp464_read,582	.read_string = tmp464_read_string,583	.write = tmp464_write,584};585 586static const struct hwmon_channel_info * const tmp464_info[] = {587	HWMON_CHANNEL_INFO(chip,588			   HWMON_C_UPDATE_INTERVAL),589	HWMON_CHANNEL_INFO(temp,590			   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | HWMON_T_CRIT |591			   HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |592			   HWMON_T_LABEL | HWMON_T_ENABLE,593			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |594			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |595			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,596			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |597			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |598			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,599			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |600			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |601			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,602			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |603			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |604			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,605			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |606			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |607			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,608			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |609			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |610			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,611			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |612			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |613			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE,614			   HWMON_T_INPUT | HWMON_T_OFFSET | HWMON_T_MAX | HWMON_T_MAX_HYST |615			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MAX_ALARM |616			   HWMON_T_CRIT_ALARM | HWMON_T_FAULT | HWMON_T_LABEL | HWMON_T_ENABLE),617	NULL618};619 620static const struct hwmon_chip_info tmp464_chip_info = {621	.ops = &tmp464_ops,622	.info = tmp464_info,623};624 625/* regmap */626 627static bool tmp464_is_volatile_reg(struct device *dev, unsigned int reg)628{629	return (reg < TMP464_TEMP_REG(TMP468_NUM_CHANNELS) ||630		reg == TMP464_THERM_STATUS_REG ||631		reg == TMP464_THERM2_STATUS_REG ||632		reg == TMP464_REMOTE_OPEN_REG);633}634 635static const struct regmap_config tmp464_regmap_config = {636	.reg_bits = 8,637	.val_bits = 16,638	.max_register = TMP464_DEVICE_ID_REG,639	.volatile_reg = tmp464_is_volatile_reg,640	.val_format_endian = REGMAP_ENDIAN_BIG,641	.cache_type = REGCACHE_MAPLE,642	.use_single_read = true,643	.use_single_write = true,644};645 646static int tmp464_probe(struct i2c_client *client)647{648	struct device *dev = &client->dev;649	struct device *hwmon_dev;650	struct tmp464_data *data;651	int i, err;652 653	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {654		dev_err(&client->dev, "i2c functionality check failed\n");655		return -ENODEV;656	}657	data = devm_kzalloc(dev, sizeof(struct tmp464_data), GFP_KERNEL);658	if (!data)659		return -ENOMEM;660 661	mutex_init(&data->update_lock);662 663	data->channels = (int)(unsigned long)i2c_get_match_data(client);664 665	data->regmap = devm_regmap_init_i2c(client, &tmp464_regmap_config);666	if (IS_ERR(data->regmap))667		return PTR_ERR(data->regmap);668 669	for (i = 0; i < data->channels; i++)670		data->channel[i].enabled = true;671 672	err = tmp464_init_client(dev, data);673	if (err)674		return err;675 676	if (dev->of_node) {677		err = tmp464_probe_from_dt(dev, data);678		if (err)679			return err;680	}681 682	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,683							 data, &tmp464_chip_info, NULL);684	return PTR_ERR_OR_ZERO(hwmon_dev);685}686 687static struct i2c_driver tmp464_driver = {688	.class = I2C_CLASS_HWMON,689	.driver = {690		.name	= "tmp464",691		.of_match_table = of_match_ptr(tmp464_of_match),692	},693	.probe = tmp464_probe,694	.id_table = tmp464_id,695	.detect = tmp464_detect,696	.address_list = normal_i2c,697};698 699module_i2c_driver(tmp464_driver);700 701MODULE_AUTHOR("Agathe Porte <agathe.porte@nokia.com>");702MODULE_DESCRIPTION("Texas Instruments TMP464 temperature sensor driver");703MODULE_LICENSE("GPL");704