xref: /openbmc/linux/drivers/hwmon/lm75.c (revision 2251aef6)
18d5d45fbSJean Delvare /*
2caaa0f36SShubhrajyoti D  * lm75.c - Part of lm_sensors, Linux kernel modules for hardware
3caaa0f36SShubhrajyoti D  *	 monitoring
4caaa0f36SShubhrajyoti D  * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
5caaa0f36SShubhrajyoti D  *
6caaa0f36SShubhrajyoti D  * This program is free software; you can redistribute it and/or modify
7caaa0f36SShubhrajyoti D  * it under the terms of the GNU General Public License as published by
8caaa0f36SShubhrajyoti D  * the Free Software Foundation; either version 2 of the License, or
9caaa0f36SShubhrajyoti D  * (at your option) any later version.
10caaa0f36SShubhrajyoti D  *
11caaa0f36SShubhrajyoti D  * This program is distributed in the hope that it will be useful,
12caaa0f36SShubhrajyoti D  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13caaa0f36SShubhrajyoti D  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14caaa0f36SShubhrajyoti D  * GNU General Public License for more details.
15caaa0f36SShubhrajyoti D  *
16caaa0f36SShubhrajyoti D  * You should have received a copy of the GNU General Public License
17caaa0f36SShubhrajyoti D  * along with this program; if not, write to the Free Software
18caaa0f36SShubhrajyoti D  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
198d5d45fbSJean Delvare  */
208d5d45fbSJean Delvare 
218d5d45fbSJean Delvare #include <linux/module.h>
228d5d45fbSJean Delvare #include <linux/init.h>
238d5d45fbSJean Delvare #include <linux/slab.h>
248d5d45fbSJean Delvare #include <linux/jiffies.h>
258d5d45fbSJean Delvare #include <linux/i2c.h>
26943b0830SMark M. Hoffman #include <linux/hwmon.h>
279ca8e40cSJean Delvare #include <linux/hwmon-sysfs.h>
28943b0830SMark M. Hoffman #include <linux/err.h>
299a61bf63SIngo Molnar #include <linux/mutex.h>
3022e73183SEduardo Valentin #include <linux/of.h>
3122e73183SEduardo Valentin #include <linux/thermal.h>
328d5d45fbSJean Delvare #include "lm75.h"
338d5d45fbSJean Delvare 
348d5d45fbSJean Delvare 
3501a52397SDavid Brownell /*
3601a52397SDavid Brownell  * This driver handles the LM75 and compatible digital temperature sensors.
3701a52397SDavid Brownell  */
3801a52397SDavid Brownell 
399ebd3d82SDavid Brownell enum lm75_type {		/* keep sorted in alphabetical order */
40e96f9d89SMichael Hennerich 	adt75,
411f86df49SJean Delvare 	ds1775,
429ebd3d82SDavid Brownell 	ds75,
433fbc81e3SJean Delvare 	ds7505,
44c98d6c65SArnaud Ebalard 	g751,
451f86df49SJean Delvare 	lm75,
469ebd3d82SDavid Brownell 	lm75a,
479ebd3d82SDavid Brownell 	max6625,
489ebd3d82SDavid Brownell 	max6626,
499ebd3d82SDavid Brownell 	mcp980x,
509ebd3d82SDavid Brownell 	stds75,
519ebd3d82SDavid Brownell 	tcn75,
529ebd3d82SDavid Brownell 	tmp100,
539ebd3d82SDavid Brownell 	tmp101,
546d034059SShubhrajyoti Datta 	tmp105,
55c83959f8SFrans Klaver 	tmp112,
569ebd3d82SDavid Brownell 	tmp175,
579ebd3d82SDavid Brownell 	tmp275,
589ebd3d82SDavid Brownell 	tmp75,
599ebd3d82SDavid Brownell };
609ebd3d82SDavid Brownell 
618ff69eebSJean Delvare /* Addresses scanned */
6225e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
638d5d45fbSJean Delvare 					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
648d5d45fbSJean Delvare 
658d5d45fbSJean Delvare 
668d5d45fbSJean Delvare /* The LM75 registers */
678d5d45fbSJean Delvare #define LM75_REG_CONF		0x01
689ca8e40cSJean Delvare static const u8 LM75_REG_TEMP[3] = {
699ca8e40cSJean Delvare 	0x00,		/* input */
709ca8e40cSJean Delvare 	0x03,		/* max */
719ca8e40cSJean Delvare 	0x02,		/* hyst */
729ca8e40cSJean Delvare };
738d5d45fbSJean Delvare 
748d5d45fbSJean Delvare /* Each client has this additional data */
758d5d45fbSJean Delvare struct lm75_data {
76d663ec49SGuenter Roeck 	struct i2c_client	*client;
771beeffe4STony Jones 	struct device		*hwmon_dev;
7822e73183SEduardo Valentin 	struct thermal_zone_device	*tz;
799a61bf63SIngo Molnar 	struct mutex		update_lock;
809ebd3d82SDavid Brownell 	u8			orig_conf;
8187d0621aSJean Delvare 	u8			resolution;	/* In bits, between 9 and 12 */
8287d0621aSJean Delvare 	u8			resolution_limits;
8301a52397SDavid Brownell 	char			valid;		/* !=0 if registers are valid */
848d5d45fbSJean Delvare 	unsigned long		last_updated;	/* In jiffies */
8587d0621aSJean Delvare 	unsigned long		sample_time;	/* In jiffies */
8687d0621aSJean Delvare 	s16			temp[3];	/* Register values,
879ca8e40cSJean Delvare 						   0 = input
889ca8e40cSJean Delvare 						   1 = max
899ca8e40cSJean Delvare 						   2 = hyst */
908d5d45fbSJean Delvare };
918d5d45fbSJean Delvare 
928d5d45fbSJean Delvare static int lm75_read_value(struct i2c_client *client, u8 reg);
938d5d45fbSJean Delvare static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
948d5d45fbSJean Delvare static struct lm75_data *lm75_update_device(struct device *dev);
958d5d45fbSJean Delvare 
968d5d45fbSJean Delvare 
9701a52397SDavid Brownell /*-----------------------------------------------------------------------*/
9801a52397SDavid Brownell 
9922e73183SEduardo Valentin static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
10022e73183SEduardo Valentin {
10122e73183SEduardo Valentin 	return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
10222e73183SEduardo Valentin }
10322e73183SEduardo Valentin 
10401a52397SDavid Brownell /* sysfs attributes for hwmon */
1058d5d45fbSJean Delvare 
10622e73183SEduardo Valentin static int lm75_read_temp(void *dev, long *temp)
10722e73183SEduardo Valentin {
10822e73183SEduardo Valentin 	struct lm75_data *data = lm75_update_device(dev);
10922e73183SEduardo Valentin 
11022e73183SEduardo Valentin 	if (IS_ERR(data))
11122e73183SEduardo Valentin 		return PTR_ERR(data);
11222e73183SEduardo Valentin 
11322e73183SEduardo Valentin 	*temp = lm75_reg_to_mc(data->temp[0], data->resolution);
11422e73183SEduardo Valentin 
11522e73183SEduardo Valentin 	return 0;
11622e73183SEduardo Valentin }
11722e73183SEduardo Valentin 
1189ca8e40cSJean Delvare static ssize_t show_temp(struct device *dev, struct device_attribute *da,
1199ca8e40cSJean Delvare 			 char *buf)
1209ca8e40cSJean Delvare {
1219ca8e40cSJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1229ca8e40cSJean Delvare 	struct lm75_data *data = lm75_update_device(dev);
1231f962f36SFrans Meulenbroeks 
1241f962f36SFrans Meulenbroeks 	if (IS_ERR(data))
1251f962f36SFrans Meulenbroeks 		return PTR_ERR(data);
1261f962f36SFrans Meulenbroeks 
12722e73183SEduardo Valentin 	return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index],
12822e73183SEduardo Valentin 						    data->resolution));
1298d5d45fbSJean Delvare }
1308d5d45fbSJean Delvare 
1319ca8e40cSJean Delvare static ssize_t set_temp(struct device *dev, struct device_attribute *da,
1329ca8e40cSJean Delvare 			const char *buf, size_t count)
1339ca8e40cSJean Delvare {
1349ca8e40cSJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
135d663ec49SGuenter Roeck 	struct lm75_data *data = dev_get_drvdata(dev);
136d663ec49SGuenter Roeck 	struct i2c_client *client = data->client;
1379ca8e40cSJean Delvare 	int nr = attr->index;
138e3cd9528SShubhrajyoti D 	long temp;
139e3cd9528SShubhrajyoti D 	int error;
14087d0621aSJean Delvare 	u8 resolution;
141e3cd9528SShubhrajyoti D 
14224edc0a7SFrans Meulenbroeks 	error = kstrtol(buf, 10, &temp);
143e3cd9528SShubhrajyoti D 	if (error)
144e3cd9528SShubhrajyoti D 		return error;
1459ca8e40cSJean Delvare 
14687d0621aSJean Delvare 	/*
14787d0621aSJean Delvare 	 * Resolution of limit registers is assumed to be the same as the
14887d0621aSJean Delvare 	 * temperature input register resolution unless given explicitly.
14987d0621aSJean Delvare 	 */
15087d0621aSJean Delvare 	if (attr->index && data->resolution_limits)
15187d0621aSJean Delvare 		resolution = data->resolution_limits;
15287d0621aSJean Delvare 	else
15387d0621aSJean Delvare 		resolution = data->resolution;
15487d0621aSJean Delvare 
1559ca8e40cSJean Delvare 	mutex_lock(&data->update_lock);
15687d0621aSJean Delvare 	temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
15787d0621aSJean Delvare 	data->temp[nr] = DIV_ROUND_CLOSEST(temp  << (resolution - 8),
15887d0621aSJean Delvare 					   1000) << (16 - resolution);
1599ca8e40cSJean Delvare 	lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]);
1609ca8e40cSJean Delvare 	mutex_unlock(&data->update_lock);
1619ca8e40cSJean Delvare 	return count;
1628d5d45fbSJean Delvare }
1638d5d45fbSJean Delvare 
1649ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
1659ca8e40cSJean Delvare 			show_temp, set_temp, 1);
1669ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
1679ca8e40cSJean Delvare 			show_temp, set_temp, 2);
1689ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
1698d5d45fbSJean Delvare 
170d663ec49SGuenter Roeck static struct attribute *lm75_attrs[] = {
1719ca8e40cSJean Delvare 	&sensor_dev_attr_temp1_input.dev_attr.attr,
1729ca8e40cSJean Delvare 	&sensor_dev_attr_temp1_max.dev_attr.attr,
1739ca8e40cSJean Delvare 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
174c1685f61SMark M. Hoffman 
175c1685f61SMark M. Hoffman 	NULL
176c1685f61SMark M. Hoffman };
177d663ec49SGuenter Roeck ATTRIBUTE_GROUPS(lm75);
178c1685f61SMark M. Hoffman 
1792251aef6SEduardo Valentin static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = {
1802251aef6SEduardo Valentin 	.get_temp = lm75_read_temp,
1812251aef6SEduardo Valentin };
1822251aef6SEduardo Valentin 
18301a52397SDavid Brownell /*-----------------------------------------------------------------------*/
18401a52397SDavid Brownell 
1858ff69eebSJean Delvare /* device probe and removal */
1869ebd3d82SDavid Brownell 
1879ebd3d82SDavid Brownell static int
1889ebd3d82SDavid Brownell lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
1899ebd3d82SDavid Brownell {
190d663ec49SGuenter Roeck 	struct device *dev = &client->dev;
1919ebd3d82SDavid Brownell 	struct lm75_data *data;
1929ebd3d82SDavid Brownell 	int status;
1939ebd3d82SDavid Brownell 	u8 set_mask, clr_mask;
1949ebd3d82SDavid Brownell 	int new;
1950cd2c72dSJean Delvare 	enum lm75_type kind = id->driver_data;
1969ebd3d82SDavid Brownell 
1979ebd3d82SDavid Brownell 	if (!i2c_check_functionality(client->adapter,
1989ebd3d82SDavid Brownell 			I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
1999ebd3d82SDavid Brownell 		return -EIO;
2009ebd3d82SDavid Brownell 
201d663ec49SGuenter Roeck 	data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL);
2029ebd3d82SDavid Brownell 	if (!data)
2039ebd3d82SDavid Brownell 		return -ENOMEM;
2049ebd3d82SDavid Brownell 
205d663ec49SGuenter Roeck 	data->client = client;
2069ebd3d82SDavid Brownell 	i2c_set_clientdata(client, data);
2079ebd3d82SDavid Brownell 	mutex_init(&data->update_lock);
2089ebd3d82SDavid Brownell 
2099ebd3d82SDavid Brownell 	/* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
2109ebd3d82SDavid Brownell 	 * Then tweak to be more precise when appropriate.
2119ebd3d82SDavid Brownell 	 */
2129ebd3d82SDavid Brownell 	set_mask = 0;
2138a5c5cc6SJean Delvare 	clr_mask = LM75_SHUTDOWN;		/* continuous conversions */
2148a5c5cc6SJean Delvare 
2150cd2c72dSJean Delvare 	switch (kind) {
2168a5c5cc6SJean Delvare 	case adt75:
2178a5c5cc6SJean Delvare 		clr_mask |= 1 << 5;		/* not one-shot mode */
2180cd2c72dSJean Delvare 		data->resolution = 12;
2190cd2c72dSJean Delvare 		data->sample_time = HZ / 8;
2208a5c5cc6SJean Delvare 		break;
2218a5c5cc6SJean Delvare 	case ds1775:
2228a5c5cc6SJean Delvare 	case ds75:
2238a5c5cc6SJean Delvare 	case stds75:
2240cd2c72dSJean Delvare 		clr_mask |= 3 << 5;
2250cd2c72dSJean Delvare 		set_mask |= 2 << 5;		/* 11-bit mode */
2260cd2c72dSJean Delvare 		data->resolution = 11;
2270cd2c72dSJean Delvare 		data->sample_time = HZ;
2280cd2c72dSJean Delvare 		break;
2293fbc81e3SJean Delvare 	case ds7505:
2303fbc81e3SJean Delvare 		set_mask |= 3 << 5;		/* 12-bit mode */
2313fbc81e3SJean Delvare 		data->resolution = 12;
2323fbc81e3SJean Delvare 		data->sample_time = HZ / 4;
2333fbc81e3SJean Delvare 		break;
234c98d6c65SArnaud Ebalard 	case g751:
2350cd2c72dSJean Delvare 	case lm75:
2360cd2c72dSJean Delvare 	case lm75a:
2370cd2c72dSJean Delvare 		data->resolution = 9;
2380cd2c72dSJean Delvare 		data->sample_time = HZ / 2;
2390cd2c72dSJean Delvare 		break;
2400cd2c72dSJean Delvare 	case max6625:
2410cd2c72dSJean Delvare 		data->resolution = 9;
2420cd2c72dSJean Delvare 		data->sample_time = HZ / 4;
2430cd2c72dSJean Delvare 		break;
2440cd2c72dSJean Delvare 	case max6626:
2450cd2c72dSJean Delvare 		data->resolution = 12;
2460cd2c72dSJean Delvare 		data->resolution_limits = 9;
2470cd2c72dSJean Delvare 		data->sample_time = HZ / 4;
2480cd2c72dSJean Delvare 		break;
2490cd2c72dSJean Delvare 	case tcn75:
2500cd2c72dSJean Delvare 		data->resolution = 9;
2510cd2c72dSJean Delvare 		data->sample_time = HZ / 8;
2528a5c5cc6SJean Delvare 		break;
2538a5c5cc6SJean Delvare 	case mcp980x:
2540cd2c72dSJean Delvare 		data->resolution_limits = 9;
2550cd2c72dSJean Delvare 		/* fall through */
2568a5c5cc6SJean Delvare 	case tmp100:
2578a5c5cc6SJean Delvare 	case tmp101:
2580cd2c72dSJean Delvare 		set_mask |= 3 << 5;		/* 12-bit mode */
2590cd2c72dSJean Delvare 		data->resolution = 12;
2600cd2c72dSJean Delvare 		data->sample_time = HZ;
2610cd2c72dSJean Delvare 		clr_mask |= 1 << 7;		/* not one-shot mode */
2620cd2c72dSJean Delvare 		break;
263c83959f8SFrans Klaver 	case tmp112:
264c83959f8SFrans Klaver 		set_mask |= 3 << 5;		/* 12-bit mode */
265c83959f8SFrans Klaver 		clr_mask |= 1 << 7;		/* not one-shot mode */
266c83959f8SFrans Klaver 		data->resolution = 12;
267c83959f8SFrans Klaver 		data->sample_time = HZ / 4;
268c83959f8SFrans Klaver 		break;
2698a5c5cc6SJean Delvare 	case tmp105:
2708a5c5cc6SJean Delvare 	case tmp175:
2718a5c5cc6SJean Delvare 	case tmp275:
2728a5c5cc6SJean Delvare 	case tmp75:
2730cd2c72dSJean Delvare 		set_mask |= 3 << 5;		/* 12-bit mode */
2748a5c5cc6SJean Delvare 		clr_mask |= 1 << 7;		/* not one-shot mode */
2750cd2c72dSJean Delvare 		data->resolution = 12;
2760cd2c72dSJean Delvare 		data->sample_time = HZ / 2;
2778a5c5cc6SJean Delvare 		break;
2788a5c5cc6SJean Delvare 	}
2799ebd3d82SDavid Brownell 
2809ebd3d82SDavid Brownell 	/* configure as specified */
2819ebd3d82SDavid Brownell 	status = lm75_read_value(client, LM75_REG_CONF);
2829ebd3d82SDavid Brownell 	if (status < 0) {
283d663ec49SGuenter Roeck 		dev_dbg(dev, "Can't read config? %d\n", status);
28413ac7a01SGuenter Roeck 		return status;
2859ebd3d82SDavid Brownell 	}
2869ebd3d82SDavid Brownell 	data->orig_conf = status;
2879ebd3d82SDavid Brownell 	new = status & ~clr_mask;
2889ebd3d82SDavid Brownell 	new |= set_mask;
2899ebd3d82SDavid Brownell 	if (status != new)
2909ebd3d82SDavid Brownell 		lm75_write_value(client, LM75_REG_CONF, new);
291d663ec49SGuenter Roeck 	dev_dbg(dev, "Config %02x\n", new);
2929ebd3d82SDavid Brownell 
293d663ec49SGuenter Roeck 	data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
294d663ec49SGuenter Roeck 							    data, lm75_groups);
295d663ec49SGuenter Roeck 	if (IS_ERR(data->hwmon_dev))
296d663ec49SGuenter Roeck 		return PTR_ERR(data->hwmon_dev);
2979ebd3d82SDavid Brownell 
2982251aef6SEduardo Valentin 	data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, 0,
299d663ec49SGuenter Roeck 						   data->hwmon_dev,
3002251aef6SEduardo Valentin 						   &lm75_of_thermal_ops);
30122e73183SEduardo Valentin 	if (IS_ERR(data->tz))
30222e73183SEduardo Valentin 		data->tz = NULL;
30322e73183SEduardo Valentin 
304d663ec49SGuenter Roeck 	dev_info(dev, "%s: sensor '%s'\n",
305739cf3a2SKay Sievers 		 dev_name(data->hwmon_dev), client->name);
3069ebd3d82SDavid Brownell 
3079ebd3d82SDavid Brownell 	return 0;
3089ebd3d82SDavid Brownell }
3099ebd3d82SDavid Brownell 
3109ebd3d82SDavid Brownell static int lm75_remove(struct i2c_client *client)
3119ebd3d82SDavid Brownell {
3129ebd3d82SDavid Brownell 	struct lm75_data *data = i2c_get_clientdata(client);
3139ebd3d82SDavid Brownell 
314d663ec49SGuenter Roeck 	thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz);
3159ebd3d82SDavid Brownell 	hwmon_device_unregister(data->hwmon_dev);
3169ebd3d82SDavid Brownell 	lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
3179ebd3d82SDavid Brownell 	return 0;
3189ebd3d82SDavid Brownell }
3199ebd3d82SDavid Brownell 
3209ebd3d82SDavid Brownell static const struct i2c_device_id lm75_ids[] = {
321e96f9d89SMichael Hennerich 	{ "adt75", adt75, },
3229ebd3d82SDavid Brownell 	{ "ds1775", ds1775, },
3239ebd3d82SDavid Brownell 	{ "ds75", ds75, },
3243fbc81e3SJean Delvare 	{ "ds7505", ds7505, },
325c98d6c65SArnaud Ebalard 	{ "g751", g751, },
3269ebd3d82SDavid Brownell 	{ "lm75", lm75, },
3279ebd3d82SDavid Brownell 	{ "lm75a", lm75a, },
3289ebd3d82SDavid Brownell 	{ "max6625", max6625, },
3299ebd3d82SDavid Brownell 	{ "max6626", max6626, },
3309ebd3d82SDavid Brownell 	{ "mcp980x", mcp980x, },
3319ebd3d82SDavid Brownell 	{ "stds75", stds75, },
3329ebd3d82SDavid Brownell 	{ "tcn75", tcn75, },
3339ebd3d82SDavid Brownell 	{ "tmp100", tmp100, },
3349ebd3d82SDavid Brownell 	{ "tmp101", tmp101, },
3356d034059SShubhrajyoti Datta 	{ "tmp105", tmp105, },
336c83959f8SFrans Klaver 	{ "tmp112", tmp112, },
3379ebd3d82SDavid Brownell 	{ "tmp175", tmp175, },
3389ebd3d82SDavid Brownell 	{ "tmp275", tmp275, },
3399ebd3d82SDavid Brownell 	{ "tmp75", tmp75, },
3409ebd3d82SDavid Brownell 	{ /* LIST END */ }
3419ebd3d82SDavid Brownell };
3429ebd3d82SDavid Brownell MODULE_DEVICE_TABLE(i2c, lm75_ids);
3439ebd3d82SDavid Brownell 
34405e82fe4SLen Sorensen #define LM75A_ID 0xA1
34505e82fe4SLen Sorensen 
3468ff69eebSJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */
347310ec792SJean Delvare static int lm75_detect(struct i2c_client *new_client,
3488ff69eebSJean Delvare 		       struct i2c_board_info *info)
3498d5d45fbSJean Delvare {
3508ff69eebSJean Delvare 	struct i2c_adapter *adapter = new_client->adapter;
3518d5d45fbSJean Delvare 	int i;
352e76f67b5SJean Delvare 	int conf, hyst, os;
35305e82fe4SLen Sorensen 	bool is_lm75a = 0;
3548d5d45fbSJean Delvare 
3558d5d45fbSJean Delvare 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
3568d5d45fbSJean Delvare 				     I2C_FUNC_SMBUS_WORD_DATA))
3578ff69eebSJean Delvare 		return -ENODEV;
3588d5d45fbSJean Delvare 
359426343efSJean Delvare 	/*
360426343efSJean Delvare 	 * Now, we do the remaining detection. There is no identification-
361426343efSJean Delvare 	 * dedicated register so we have to rely on several tricks:
362426343efSJean Delvare 	 * unused bits, registers cycling over 8-address boundaries,
363426343efSJean Delvare 	 * addresses 0x04-0x07 returning the last read value.
364426343efSJean Delvare 	 * The cycling+unused addresses combination is not tested,
365426343efSJean Delvare 	 * since it would significantly slow the detection down and would
366426343efSJean Delvare 	 * hardly add any value.
367426343efSJean Delvare 	 *
368426343efSJean Delvare 	 * The National Semiconductor LM75A is different than earlier
369426343efSJean Delvare 	 * LM75s.  It has an ID byte of 0xaX (where X is the chip
370426343efSJean Delvare 	 * revision, with 1 being the only revision in existence) in
371426343efSJean Delvare 	 * register 7, and unused registers return 0xff rather than the
372426343efSJean Delvare 	 * last read value.
373426343efSJean Delvare 	 *
374426343efSJean Delvare 	 * Note that this function only detects the original National
375426343efSJean Delvare 	 * Semiconductor LM75 and the LM75A. Clones from other vendors
376426343efSJean Delvare 	 * aren't detected, on purpose, because they are typically never
377426343efSJean Delvare 	 * found on PC hardware. They are found on embedded designs where
378426343efSJean Delvare 	 * they can be instantiated explicitly so detection is not needed.
379426343efSJean Delvare 	 * The absence of identification registers on all these clones
380426343efSJean Delvare 	 * would make their exhaustive detection very difficult and weak,
381426343efSJean Delvare 	 * and odds are that the driver would bind to unsupported devices.
382426343efSJean Delvare 	 */
38305e82fe4SLen Sorensen 
384e76f67b5SJean Delvare 	/* Unused bits */
3858d5d45fbSJean Delvare 	conf = i2c_smbus_read_byte_data(new_client, 1);
386e76f67b5SJean Delvare 	if (conf & 0xe0)
387e76f67b5SJean Delvare 		return -ENODEV;
38805e82fe4SLen Sorensen 
38905e82fe4SLen Sorensen 	/* First check for LM75A */
39005e82fe4SLen Sorensen 	if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) {
39105e82fe4SLen Sorensen 		/* LM75A returns 0xff on unused registers so
39205e82fe4SLen Sorensen 		   just to be sure we check for that too. */
39305e82fe4SLen Sorensen 		if (i2c_smbus_read_byte_data(new_client, 4) != 0xff
39405e82fe4SLen Sorensen 		 || i2c_smbus_read_byte_data(new_client, 5) != 0xff
39505e82fe4SLen Sorensen 		 || i2c_smbus_read_byte_data(new_client, 6) != 0xff)
39605e82fe4SLen Sorensen 			return -ENODEV;
39705e82fe4SLen Sorensen 		is_lm75a = 1;
398e76f67b5SJean Delvare 		hyst = i2c_smbus_read_byte_data(new_client, 2);
399e76f67b5SJean Delvare 		os = i2c_smbus_read_byte_data(new_client, 3);
40005e82fe4SLen Sorensen 	} else { /* Traditional style LM75 detection */
40105e82fe4SLen Sorensen 		/* Unused addresses */
402e76f67b5SJean Delvare 		hyst = i2c_smbus_read_byte_data(new_client, 2);
403e76f67b5SJean Delvare 		if (i2c_smbus_read_byte_data(new_client, 4) != hyst
404e76f67b5SJean Delvare 		 || i2c_smbus_read_byte_data(new_client, 5) != hyst
405e76f67b5SJean Delvare 		 || i2c_smbus_read_byte_data(new_client, 6) != hyst
406e76f67b5SJean Delvare 		 || i2c_smbus_read_byte_data(new_client, 7) != hyst)
4078ff69eebSJean Delvare 			return -ENODEV;
408e76f67b5SJean Delvare 		os = i2c_smbus_read_byte_data(new_client, 3);
409e76f67b5SJean Delvare 		if (i2c_smbus_read_byte_data(new_client, 4) != os
410e76f67b5SJean Delvare 		 || i2c_smbus_read_byte_data(new_client, 5) != os
411e76f67b5SJean Delvare 		 || i2c_smbus_read_byte_data(new_client, 6) != os
412e76f67b5SJean Delvare 		 || i2c_smbus_read_byte_data(new_client, 7) != os)
4138ff69eebSJean Delvare 			return -ENODEV;
41405e82fe4SLen Sorensen 	}
4158d5d45fbSJean Delvare 
4168d5d45fbSJean Delvare 	/* Addresses cycling */
417e76f67b5SJean Delvare 	for (i = 8; i <= 248; i += 40) {
4188d5d45fbSJean Delvare 		if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
419e76f67b5SJean Delvare 		 || i2c_smbus_read_byte_data(new_client, i + 2) != hyst
420e76f67b5SJean Delvare 		 || i2c_smbus_read_byte_data(new_client, i + 3) != os)
4218ff69eebSJean Delvare 			return -ENODEV;
42205e82fe4SLen Sorensen 		if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7)
42305e82fe4SLen Sorensen 				!= LM75A_ID)
42405e82fe4SLen Sorensen 			return -ENODEV;
4258d5d45fbSJean Delvare 	}
4268d5d45fbSJean Delvare 
42705e82fe4SLen Sorensen 	strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE);
4288d5d45fbSJean Delvare 
4298d5d45fbSJean Delvare 	return 0;
4308d5d45fbSJean Delvare }
4318d5d45fbSJean Delvare 
4329914518eSShubhrajyoti Datta #ifdef CONFIG_PM
4339914518eSShubhrajyoti Datta static int lm75_suspend(struct device *dev)
4349914518eSShubhrajyoti Datta {
4359914518eSShubhrajyoti Datta 	int status;
4369914518eSShubhrajyoti Datta 	struct i2c_client *client = to_i2c_client(dev);
4379914518eSShubhrajyoti Datta 	status = lm75_read_value(client, LM75_REG_CONF);
4389914518eSShubhrajyoti Datta 	if (status < 0) {
4399914518eSShubhrajyoti Datta 		dev_dbg(&client->dev, "Can't read config? %d\n", status);
4409914518eSShubhrajyoti Datta 		return status;
4419914518eSShubhrajyoti Datta 	}
4429914518eSShubhrajyoti Datta 	status = status | LM75_SHUTDOWN;
4439914518eSShubhrajyoti Datta 	lm75_write_value(client, LM75_REG_CONF, status);
4449914518eSShubhrajyoti Datta 	return 0;
4459914518eSShubhrajyoti Datta }
4469914518eSShubhrajyoti Datta 
4479914518eSShubhrajyoti Datta static int lm75_resume(struct device *dev)
4489914518eSShubhrajyoti Datta {
4499914518eSShubhrajyoti Datta 	int status;
4509914518eSShubhrajyoti Datta 	struct i2c_client *client = to_i2c_client(dev);
4519914518eSShubhrajyoti Datta 	status = lm75_read_value(client, LM75_REG_CONF);
4529914518eSShubhrajyoti Datta 	if (status < 0) {
4539914518eSShubhrajyoti Datta 		dev_dbg(&client->dev, "Can't read config? %d\n", status);
4549914518eSShubhrajyoti Datta 		return status;
4559914518eSShubhrajyoti Datta 	}
4569914518eSShubhrajyoti Datta 	status = status & ~LM75_SHUTDOWN;
4579914518eSShubhrajyoti Datta 	lm75_write_value(client, LM75_REG_CONF, status);
4589914518eSShubhrajyoti Datta 	return 0;
4599914518eSShubhrajyoti Datta }
4609914518eSShubhrajyoti Datta 
4619914518eSShubhrajyoti Datta static const struct dev_pm_ops lm75_dev_pm_ops = {
4629914518eSShubhrajyoti Datta 	.suspend	= lm75_suspend,
4639914518eSShubhrajyoti Datta 	.resume		= lm75_resume,
4649914518eSShubhrajyoti Datta };
4659914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS (&lm75_dev_pm_ops)
4669914518eSShubhrajyoti Datta #else
4679914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS NULL
4689914518eSShubhrajyoti Datta #endif /* CONFIG_PM */
4699914518eSShubhrajyoti Datta 
4708ff69eebSJean Delvare static struct i2c_driver lm75_driver = {
4718ff69eebSJean Delvare 	.class		= I2C_CLASS_HWMON,
47201a52397SDavid Brownell 	.driver = {
4738ff69eebSJean Delvare 		.name	= "lm75",
4749914518eSShubhrajyoti Datta 		.pm	= LM75_DEV_PM_OPS,
47501a52397SDavid Brownell 	},
4768ff69eebSJean Delvare 	.probe		= lm75_probe,
4778ff69eebSJean Delvare 	.remove		= lm75_remove,
4788ff69eebSJean Delvare 	.id_table	= lm75_ids,
4798ff69eebSJean Delvare 	.detect		= lm75_detect,
480c3813d6aSJean Delvare 	.address_list	= normal_i2c,
48101a52397SDavid Brownell };
48201a52397SDavid Brownell 
48301a52397SDavid Brownell /*-----------------------------------------------------------------------*/
48401a52397SDavid Brownell 
48501a52397SDavid Brownell /* register access */
48601a52397SDavid Brownell 
487caaa0f36SShubhrajyoti D /*
488caaa0f36SShubhrajyoti D  * All registers are word-sized, except for the configuration register.
489caaa0f36SShubhrajyoti D  * LM75 uses a high-byte first convention, which is exactly opposite to
490caaa0f36SShubhrajyoti D  * the SMBus standard.
491caaa0f36SShubhrajyoti D  */
4928d5d45fbSJean Delvare static int lm75_read_value(struct i2c_client *client, u8 reg)
4938d5d45fbSJean Delvare {
4948d5d45fbSJean Delvare 	if (reg == LM75_REG_CONF)
4958d5d45fbSJean Delvare 		return i2c_smbus_read_byte_data(client, reg);
49690f4102cSJean Delvare 	else
49790f4102cSJean Delvare 		return i2c_smbus_read_word_swapped(client, reg);
4988d5d45fbSJean Delvare }
4998d5d45fbSJean Delvare 
5008d5d45fbSJean Delvare static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
5018d5d45fbSJean Delvare {
5028d5d45fbSJean Delvare 	if (reg == LM75_REG_CONF)
5038d5d45fbSJean Delvare 		return i2c_smbus_write_byte_data(client, reg, value);
5048d5d45fbSJean Delvare 	else
50590f4102cSJean Delvare 		return i2c_smbus_write_word_swapped(client, reg, value);
5068d5d45fbSJean Delvare }
5078d5d45fbSJean Delvare 
5088d5d45fbSJean Delvare static struct lm75_data *lm75_update_device(struct device *dev)
5098d5d45fbSJean Delvare {
510d663ec49SGuenter Roeck 	struct lm75_data *data = dev_get_drvdata(dev);
511d663ec49SGuenter Roeck 	struct i2c_client *client = data->client;
5121f962f36SFrans Meulenbroeks 	struct lm75_data *ret = data;
5138d5d45fbSJean Delvare 
5149a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
5158d5d45fbSJean Delvare 
51687d0621aSJean Delvare 	if (time_after(jiffies, data->last_updated + data->sample_time)
5178d5d45fbSJean Delvare 	    || !data->valid) {
5189ca8e40cSJean Delvare 		int i;
5198d5d45fbSJean Delvare 		dev_dbg(&client->dev, "Starting lm75 update\n");
5208d5d45fbSJean Delvare 
521bcccc3a2SDavid Brownell 		for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
522bcccc3a2SDavid Brownell 			int status;
523bcccc3a2SDavid Brownell 
524bcccc3a2SDavid Brownell 			status = lm75_read_value(client, LM75_REG_TEMP[i]);
5251f962f36SFrans Meulenbroeks 			if (unlikely(status < 0)) {
5261f962f36SFrans Meulenbroeks 				dev_dbg(dev,
5271f962f36SFrans Meulenbroeks 					"LM75: Failed to read value: reg %d, error %d\n",
528bcccc3a2SDavid Brownell 					LM75_REG_TEMP[i], status);
5291f962f36SFrans Meulenbroeks 				ret = ERR_PTR(status);
5301f962f36SFrans Meulenbroeks 				data->valid = 0;
5311f962f36SFrans Meulenbroeks 				goto abort;
5321f962f36SFrans Meulenbroeks 			}
533bcccc3a2SDavid Brownell 			data->temp[i] = status;
534bcccc3a2SDavid Brownell 		}
5358d5d45fbSJean Delvare 		data->last_updated = jiffies;
5368d5d45fbSJean Delvare 		data->valid = 1;
5378d5d45fbSJean Delvare 	}
5388d5d45fbSJean Delvare 
5391f962f36SFrans Meulenbroeks abort:
5409a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
5411f962f36SFrans Meulenbroeks 	return ret;
5428d5d45fbSJean Delvare }
5438d5d45fbSJean Delvare 
544f0967eeaSAxel Lin module_i2c_driver(lm75_driver);
5458d5d45fbSJean Delvare 
5468d5d45fbSJean Delvare MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
5478d5d45fbSJean Delvare MODULE_DESCRIPTION("LM75 driver");
5488d5d45fbSJean Delvare MODULE_LICENSE("GPL");
549