File Index
Files and directories
Sign in
FILE

tmp464.c

File preview with syntax highlighting.

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