xref: /openbmc/linux/drivers/hwmon/lm75.c (revision 22e73183)
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,
559ebd3d82SDavid Brownell 	tmp175,
569ebd3d82SDavid Brownell 	tmp275,
579ebd3d82SDavid Brownell 	tmp75,
589ebd3d82SDavid Brownell };
599ebd3d82SDavid Brownell 
608ff69eebSJean Delvare /* Addresses scanned */
6125e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
628d5d45fbSJean Delvare 					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
638d5d45fbSJean Delvare 
648d5d45fbSJean Delvare 
658d5d45fbSJean Delvare /* The LM75 registers */
668d5d45fbSJean Delvare #define LM75_REG_CONF		0x01
679ca8e40cSJean Delvare static const u8 LM75_REG_TEMP[3] = {
689ca8e40cSJean Delvare 	0x00,		/* input */
699ca8e40cSJean Delvare 	0x03,		/* max */
709ca8e40cSJean Delvare 	0x02,		/* hyst */
719ca8e40cSJean Delvare };
728d5d45fbSJean Delvare 
738d5d45fbSJean Delvare /* Each client has this additional data */
748d5d45fbSJean Delvare struct lm75_data {
751beeffe4STony Jones 	struct device		*hwmon_dev;
7622e73183SEduardo Valentin 	struct thermal_zone_device	*tz;
779a61bf63SIngo Molnar 	struct mutex		update_lock;
789ebd3d82SDavid Brownell 	u8			orig_conf;
7987d0621aSJean Delvare 	u8			resolution;	/* In bits, between 9 and 12 */
8087d0621aSJean Delvare 	u8			resolution_limits;
8101a52397SDavid Brownell 	char			valid;		/* !=0 if registers are valid */
828d5d45fbSJean Delvare 	unsigned long		last_updated;	/* In jiffies */
8387d0621aSJean Delvare 	unsigned long		sample_time;	/* In jiffies */
8487d0621aSJean Delvare 	s16			temp[3];	/* Register values,
859ca8e40cSJean Delvare 						   0 = input
869ca8e40cSJean Delvare 						   1 = max
879ca8e40cSJean Delvare 						   2 = hyst */
888d5d45fbSJean Delvare };
898d5d45fbSJean Delvare 
908d5d45fbSJean Delvare static int lm75_read_value(struct i2c_client *client, u8 reg);
918d5d45fbSJean Delvare static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
928d5d45fbSJean Delvare static struct lm75_data *lm75_update_device(struct device *dev);
938d5d45fbSJean Delvare 
948d5d45fbSJean Delvare 
9501a52397SDavid Brownell /*-----------------------------------------------------------------------*/
9601a52397SDavid Brownell 
9722e73183SEduardo Valentin static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
9822e73183SEduardo Valentin {
9922e73183SEduardo Valentin 	return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
10022e73183SEduardo Valentin }
10122e73183SEduardo Valentin 
10201a52397SDavid Brownell /* sysfs attributes for hwmon */
1038d5d45fbSJean Delvare 
10422e73183SEduardo Valentin static int lm75_read_temp(void *dev, long *temp)
10522e73183SEduardo Valentin {
10622e73183SEduardo Valentin 	struct lm75_data *data = lm75_update_device(dev);
10722e73183SEduardo Valentin 
10822e73183SEduardo Valentin 	if (IS_ERR(data))
10922e73183SEduardo Valentin 		return PTR_ERR(data);
11022e73183SEduardo Valentin 
11122e73183SEduardo Valentin 	*temp = lm75_reg_to_mc(data->temp[0], data->resolution);
11222e73183SEduardo Valentin 
11322e73183SEduardo Valentin 	return 0;
11422e73183SEduardo Valentin }
11522e73183SEduardo Valentin 
1169ca8e40cSJean Delvare static ssize_t show_temp(struct device *dev, struct device_attribute *da,
1179ca8e40cSJean Delvare 			 char *buf)
1189ca8e40cSJean Delvare {
1199ca8e40cSJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1209ca8e40cSJean Delvare 	struct lm75_data *data = lm75_update_device(dev);
1211f962f36SFrans Meulenbroeks 
1221f962f36SFrans Meulenbroeks 	if (IS_ERR(data))
1231f962f36SFrans Meulenbroeks 		return PTR_ERR(data);
1241f962f36SFrans Meulenbroeks 
12522e73183SEduardo Valentin 	return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index],
12622e73183SEduardo Valentin 						    data->resolution));
1278d5d45fbSJean Delvare }
1288d5d45fbSJean Delvare 
1299ca8e40cSJean Delvare static ssize_t set_temp(struct device *dev, struct device_attribute *da,
1309ca8e40cSJean Delvare 			const char *buf, size_t count)
1319ca8e40cSJean Delvare {
1329ca8e40cSJean Delvare 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1339ca8e40cSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
1349ca8e40cSJean Delvare 	struct lm75_data *data = i2c_get_clientdata(client);
1359ca8e40cSJean Delvare 	int nr = attr->index;
136e3cd9528SShubhrajyoti D 	long temp;
137e3cd9528SShubhrajyoti D 	int error;
13887d0621aSJean Delvare 	u8 resolution;
139e3cd9528SShubhrajyoti D 
14024edc0a7SFrans Meulenbroeks 	error = kstrtol(buf, 10, &temp);
141e3cd9528SShubhrajyoti D 	if (error)
142e3cd9528SShubhrajyoti D 		return error;
1439ca8e40cSJean Delvare 
14487d0621aSJean Delvare 	/*
14587d0621aSJean Delvare 	 * Resolution of limit registers is assumed to be the same as the
14687d0621aSJean Delvare 	 * temperature input register resolution unless given explicitly.
14787d0621aSJean Delvare 	 */
14887d0621aSJean Delvare 	if (attr->index && data->resolution_limits)
14987d0621aSJean Delvare 		resolution = data->resolution_limits;
15087d0621aSJean Delvare 	else
15187d0621aSJean Delvare 		resolution = data->resolution;
15287d0621aSJean Delvare 
1539ca8e40cSJean Delvare 	mutex_lock(&data->update_lock);
15487d0621aSJean Delvare 	temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
15587d0621aSJean Delvare 	data->temp[nr] = DIV_ROUND_CLOSEST(temp  << (resolution - 8),
15687d0621aSJean Delvare 					   1000) << (16 - resolution);
1579ca8e40cSJean Delvare 	lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]);
1589ca8e40cSJean Delvare 	mutex_unlock(&data->update_lock);
1599ca8e40cSJean Delvare 	return count;
1608d5d45fbSJean Delvare }
1618d5d45fbSJean Delvare 
1629ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
1639ca8e40cSJean Delvare 			show_temp, set_temp, 1);
1649ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
1659ca8e40cSJean Delvare 			show_temp, set_temp, 2);
1669ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
1678d5d45fbSJean Delvare 
168c1685f61SMark M. Hoffman static struct attribute *lm75_attributes[] = {
1699ca8e40cSJean Delvare 	&sensor_dev_attr_temp1_input.dev_attr.attr,
1709ca8e40cSJean Delvare 	&sensor_dev_attr_temp1_max.dev_attr.attr,
1719ca8e40cSJean Delvare 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
172c1685f61SMark M. Hoffman 
173c1685f61SMark M. Hoffman 	NULL
174c1685f61SMark M. Hoffman };
175c1685f61SMark M. Hoffman 
176c1685f61SMark M. Hoffman static const struct attribute_group lm75_group = {
177c1685f61SMark M. Hoffman 	.attrs = lm75_attributes,
178c1685f61SMark M. Hoffman };
179c1685f61SMark M. Hoffman 
18001a52397SDavid Brownell /*-----------------------------------------------------------------------*/
18101a52397SDavid Brownell 
1828ff69eebSJean Delvare /* device probe and removal */
1839ebd3d82SDavid Brownell 
1849ebd3d82SDavid Brownell static int
1859ebd3d82SDavid Brownell lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
1869ebd3d82SDavid Brownell {
1879ebd3d82SDavid Brownell 	struct lm75_data *data;
1889ebd3d82SDavid Brownell 	int status;
1899ebd3d82SDavid Brownell 	u8 set_mask, clr_mask;
1909ebd3d82SDavid Brownell 	int new;
1910cd2c72dSJean Delvare 	enum lm75_type kind = id->driver_data;
1929ebd3d82SDavid Brownell 
1939ebd3d82SDavid Brownell 	if (!i2c_check_functionality(client->adapter,
1949ebd3d82SDavid Brownell 			I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
1959ebd3d82SDavid Brownell 		return -EIO;
1969ebd3d82SDavid Brownell 
19713ac7a01SGuenter Roeck 	data = devm_kzalloc(&client->dev, sizeof(struct lm75_data), GFP_KERNEL);
1989ebd3d82SDavid Brownell 	if (!data)
1999ebd3d82SDavid Brownell 		return -ENOMEM;
2009ebd3d82SDavid Brownell 
2019ebd3d82SDavid Brownell 	i2c_set_clientdata(client, data);
2029ebd3d82SDavid Brownell 	mutex_init(&data->update_lock);
2039ebd3d82SDavid Brownell 
2049ebd3d82SDavid Brownell 	/* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
2059ebd3d82SDavid Brownell 	 * Then tweak to be more precise when appropriate.
2069ebd3d82SDavid Brownell 	 */
2079ebd3d82SDavid Brownell 	set_mask = 0;
2088a5c5cc6SJean Delvare 	clr_mask = LM75_SHUTDOWN;		/* continuous conversions */
2098a5c5cc6SJean Delvare 
2100cd2c72dSJean Delvare 	switch (kind) {
2118a5c5cc6SJean Delvare 	case adt75:
2128a5c5cc6SJean Delvare 		clr_mask |= 1 << 5;		/* not one-shot mode */
2130cd2c72dSJean Delvare 		data->resolution = 12;
2140cd2c72dSJean Delvare 		data->sample_time = HZ / 8;
2158a5c5cc6SJean Delvare 		break;
2168a5c5cc6SJean Delvare 	case ds1775:
2178a5c5cc6SJean Delvare 	case ds75:
2188a5c5cc6SJean Delvare 	case stds75:
2190cd2c72dSJean Delvare 		clr_mask |= 3 << 5;
2200cd2c72dSJean Delvare 		set_mask |= 2 << 5;		/* 11-bit mode */
2210cd2c72dSJean Delvare 		data->resolution = 11;
2220cd2c72dSJean Delvare 		data->sample_time = HZ;
2230cd2c72dSJean Delvare 		break;
2243fbc81e3SJean Delvare 	case ds7505:
2253fbc81e3SJean Delvare 		set_mask |= 3 << 5;		/* 12-bit mode */
2263fbc81e3SJean Delvare 		data->resolution = 12;
2273fbc81e3SJean Delvare 		data->sample_time = HZ / 4;
2283fbc81e3SJean Delvare 		break;
229c98d6c65SArnaud Ebalard 	case g751:
2300cd2c72dSJean Delvare 	case lm75:
2310cd2c72dSJean Delvare 	case lm75a:
2320cd2c72dSJean Delvare 		data->resolution = 9;
2330cd2c72dSJean Delvare 		data->sample_time = HZ / 2;
2340cd2c72dSJean Delvare 		break;
2350cd2c72dSJean Delvare 	case max6625:
2360cd2c72dSJean Delvare 		data->resolution = 9;
2370cd2c72dSJean Delvare 		data->sample_time = HZ / 4;
2380cd2c72dSJean Delvare 		break;
2390cd2c72dSJean Delvare 	case max6626:
2400cd2c72dSJean Delvare 		data->resolution = 12;
2410cd2c72dSJean Delvare 		data->resolution_limits = 9;
2420cd2c72dSJean Delvare 		data->sample_time = HZ / 4;
2430cd2c72dSJean Delvare 		break;
2440cd2c72dSJean Delvare 	case tcn75:
2450cd2c72dSJean Delvare 		data->resolution = 9;
2460cd2c72dSJean Delvare 		data->sample_time = HZ / 8;
2478a5c5cc6SJean Delvare 		break;
2488a5c5cc6SJean Delvare 	case mcp980x:
2490cd2c72dSJean Delvare 		data->resolution_limits = 9;
2500cd2c72dSJean Delvare 		/* fall through */
2518a5c5cc6SJean Delvare 	case tmp100:
2528a5c5cc6SJean Delvare 	case tmp101:
2530cd2c72dSJean Delvare 		set_mask |= 3 << 5;		/* 12-bit mode */
2540cd2c72dSJean Delvare 		data->resolution = 12;
2550cd2c72dSJean Delvare 		data->sample_time = HZ;
2560cd2c72dSJean Delvare 		clr_mask |= 1 << 7;		/* not one-shot mode */
2570cd2c72dSJean Delvare 		break;
2588a5c5cc6SJean Delvare 	case tmp105:
2598a5c5cc6SJean Delvare 	case tmp175:
2608a5c5cc6SJean Delvare 	case tmp275:
2618a5c5cc6SJean Delvare 	case tmp75:
2620cd2c72dSJean Delvare 		set_mask |= 3 << 5;		/* 12-bit mode */
2638a5c5cc6SJean Delvare 		clr_mask |= 1 << 7;		/* not one-shot mode */
2640cd2c72dSJean Delvare 		data->resolution = 12;
2650cd2c72dSJean Delvare 		data->sample_time = HZ / 2;
2668a5c5cc6SJean Delvare 		break;
2678a5c5cc6SJean Delvare 	}
2689ebd3d82SDavid Brownell 
2699ebd3d82SDavid Brownell 	/* configure as specified */
2709ebd3d82SDavid Brownell 	status = lm75_read_value(client, LM75_REG_CONF);
2719ebd3d82SDavid Brownell 	if (status < 0) {
2729ebd3d82SDavid Brownell 		dev_dbg(&client->dev, "Can't read config? %d\n", status);
27313ac7a01SGuenter Roeck 		return status;
2749ebd3d82SDavid Brownell 	}
2759ebd3d82SDavid Brownell 	data->orig_conf = status;
2769ebd3d82SDavid Brownell 	new = status & ~clr_mask;
2779ebd3d82SDavid Brownell 	new |= set_mask;
2789ebd3d82SDavid Brownell 	if (status != new)
2799ebd3d82SDavid Brownell 		lm75_write_value(client, LM75_REG_CONF, new);
2809ebd3d82SDavid Brownell 	dev_dbg(&client->dev, "Config %02x\n", new);
2819ebd3d82SDavid Brownell 
2829ebd3d82SDavid Brownell 	/* Register sysfs hooks */
2839ebd3d82SDavid Brownell 	status = sysfs_create_group(&client->dev.kobj, &lm75_group);
2849ebd3d82SDavid Brownell 	if (status)
28513ac7a01SGuenter Roeck 		return status;
2869ebd3d82SDavid Brownell 
2879ebd3d82SDavid Brownell 	data->hwmon_dev = hwmon_device_register(&client->dev);
2889ebd3d82SDavid Brownell 	if (IS_ERR(data->hwmon_dev)) {
2899ebd3d82SDavid Brownell 		status = PTR_ERR(data->hwmon_dev);
2909ebd3d82SDavid Brownell 		goto exit_remove;
2919ebd3d82SDavid Brownell 	}
2929ebd3d82SDavid Brownell 
29322e73183SEduardo Valentin 	data->tz = thermal_zone_of_sensor_register(&client->dev,
29422e73183SEduardo Valentin 						   0,
29522e73183SEduardo Valentin 						   &client->dev,
29622e73183SEduardo Valentin 						   lm75_read_temp, NULL);
29722e73183SEduardo Valentin 	if (IS_ERR(data->tz))
29822e73183SEduardo Valentin 		data->tz = NULL;
29922e73183SEduardo Valentin 
3009ebd3d82SDavid Brownell 	dev_info(&client->dev, "%s: sensor '%s'\n",
301739cf3a2SKay Sievers 		 dev_name(data->hwmon_dev), client->name);
3029ebd3d82SDavid Brownell 
3039ebd3d82SDavid Brownell 	return 0;
3049ebd3d82SDavid Brownell 
3059ebd3d82SDavid Brownell exit_remove:
3069ebd3d82SDavid Brownell 	sysfs_remove_group(&client->dev.kobj, &lm75_group);
3079ebd3d82SDavid Brownell 	return status;
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 
31422e73183SEduardo Valentin 	thermal_zone_of_sensor_unregister(&client->dev, data->tz);
3159ebd3d82SDavid Brownell 	hwmon_device_unregister(data->hwmon_dev);
3169ebd3d82SDavid Brownell 	sysfs_remove_group(&client->dev.kobj, &lm75_group);
3179ebd3d82SDavid Brownell 	lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
3189ebd3d82SDavid Brownell 	return 0;
3199ebd3d82SDavid Brownell }
3209ebd3d82SDavid Brownell 
3219ebd3d82SDavid Brownell static const struct i2c_device_id lm75_ids[] = {
322e96f9d89SMichael Hennerich 	{ "adt75", adt75, },
3239ebd3d82SDavid Brownell 	{ "ds1775", ds1775, },
3249ebd3d82SDavid Brownell 	{ "ds75", ds75, },
3253fbc81e3SJean Delvare 	{ "ds7505", ds7505, },
326c98d6c65SArnaud Ebalard 	{ "g751", g751, },
3279ebd3d82SDavid Brownell 	{ "lm75", lm75, },
3289ebd3d82SDavid Brownell 	{ "lm75a", lm75a, },
3299ebd3d82SDavid Brownell 	{ "max6625", max6625, },
3309ebd3d82SDavid Brownell 	{ "max6626", max6626, },
3319ebd3d82SDavid Brownell 	{ "mcp980x", mcp980x, },
3329ebd3d82SDavid Brownell 	{ "stds75", stds75, },
3339ebd3d82SDavid Brownell 	{ "tcn75", tcn75, },
3349ebd3d82SDavid Brownell 	{ "tmp100", tmp100, },
3359ebd3d82SDavid Brownell 	{ "tmp101", tmp101, },
3366d034059SShubhrajyoti Datta 	{ "tmp105", tmp105, },
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 {
5108d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
5118d5d45fbSJean Delvare 	struct lm75_data *data = i2c_get_clientdata(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