11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * lm75.c - Part of lm_sensors, Linux kernel modules for hardware
3caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D *	 monitoring
4caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
5caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D *
6caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * This program is free software; you can redistribute it and/or modify
7caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * it under the terms of the GNU General Public License as published by
8caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * the Free Software Foundation; either version 2 of the License, or
9caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * (at your option) any later version.
10caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D *
11caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * This program is distributed in the hope that it will be useful,
12caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * but WITHOUT ANY WARRANTY; without even the implied warranty of
13caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * GNU General Public License for more details.
15caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D *
16caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * You should have received a copy of the GNU General Public License
17caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * along with this program; if not, write to the Free Software
18caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D */
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h>
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/jiffies.h>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c.h>
26943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/hwmon.h>
279ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare#include <linux/hwmon-sysfs.h>
28943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/err.h>
299a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar#include <linux/mutex.h>
3022e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin#include <linux/of.h>
3122e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin#include <linux/thermal.h>
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "lm75.h"
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3501a52397e95a8532c59506691759dba9262d6be7David Brownell/*
3601a52397e95a8532c59506691759dba9262d6be7David Brownell * This driver handles the LM75 and compatible digital temperature sensors.
3701a52397e95a8532c59506691759dba9262d6be7David Brownell */
3801a52397e95a8532c59506691759dba9262d6be7David Brownell
399ebd3d822efeca2e73565516a80373c76ce3fa12David Brownellenum lm75_type {		/* keep sorted in alphabetical order */
40e96f9d89e6213c7630a3323cd0c754e7f2619564Michael Hennerich	adt75,
411f86df49ddfd0067cce941187d57b2fd2f749a9eJean Delvare	ds1775,
429ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	ds75,
433fbc81e3c0257c756c0955bcb291374d74c11f61Jean Delvare	ds7505,
44c98d6c65e6e6bd24a12174fff6ca4990d346de5dArnaud Ebalard	g751,
451f86df49ddfd0067cce941187d57b2fd2f749a9eJean Delvare	lm75,
469ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	lm75a,
479ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	max6625,
489ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	max6626,
499ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	mcp980x,
509ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	stds75,
519ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	tcn75,
529ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	tmp100,
539ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	tmp101,
546d034059eef080a0cdda92b45baa18cb00a19835Shubhrajyoti Datta	tmp105,
55c83959f89f1cbe2e712c11e4a77d89f4d34d09ffFrans Klaver	tmp112,
569ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	tmp175,
579ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	tmp275,
589ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	tmp75,
599ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell};
609ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
618ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare/* Addresses scanned */
6225e9c86d5a6d82ea45eb680fc66bf73ac5e50dffMark M. Hoffmanstatic const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The LM75 registers */
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM75_REG_CONF		0x01
689ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvarestatic const u8 LM75_REG_TEMP[3] = {
699ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	0x00,		/* input */
709ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	0x03,		/* max */
719ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	0x02,		/* hyst */
729ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare};
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Each client has this additional data */
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct lm75_data {
76d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	struct i2c_client	*client;
7701a52397e95a8532c59506691759dba9262d6be7David Brownell	struct device		*hwmon_dev;
7822e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin	struct thermal_zone_device	*tz;
799a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	struct mutex		update_lock;
809ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	u8			orig_conf;
8187d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	u8			resolution;	/* In bits, between 9 and 12 */
8287d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	u8			resolution_limits;
8301a52397e95a8532c59506691759dba9262d6be7David Brownell	char			valid;		/* !=0 if registers are valid */
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long		last_updated;	/* In jiffies */
8587d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	unsigned long		sample_time;	/* In jiffies */
8687d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	s16			temp[3];	/* Register values,
879ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare						   0 = input
889ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare						   1 = max
899ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare						   2 = hyst */
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int lm75_read_value(struct i2c_client *client, u8 reg);
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct lm75_data *lm75_update_device(struct device *dev);
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9701a52397e95a8532c59506691759dba9262d6be7David Brownell/*-----------------------------------------------------------------------*/
9801a52397e95a8532c59506691759dba9262d6be7David Brownell
9922e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentinstatic inline long lm75_reg_to_mc(s16 temp, u8 resolution)
10022e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin{
10122e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin	return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
10222e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin}
10322e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin
10401a52397e95a8532c59506691759dba9262d6be7David Brownell/* sysfs attributes for hwmon */
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10622e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentinstatic int lm75_read_temp(void *dev, long *temp)
10722e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin{
10822e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin	struct lm75_data *data = lm75_update_device(dev);
10922e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin
11022e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin	if (IS_ERR(data))
11122e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin		return PTR_ERR(data);
11222e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin
11322e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin	*temp = lm75_reg_to_mc(data->temp[0], data->resolution);
11422e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin
11522e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin	return 0;
11622e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin}
11722e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin
1189ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvarestatic ssize_t show_temp(struct device *dev, struct device_attribute *da,
1199ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare			 char *buf)
1209ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare{
1219ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
1229ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	struct lm75_data *data = lm75_update_device(dev);
1231f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks
1241f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks	if (IS_ERR(data))
1251f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks		return PTR_ERR(data);
1261f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks
12722e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin	return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index],
12822e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin						    data->resolution));
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1309ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare
1319ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvarestatic ssize_t set_temp(struct device *dev, struct device_attribute *da,
1329ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare			const char *buf, size_t count)
1339ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare{
1349ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
135d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	struct lm75_data *data = dev_get_drvdata(dev);
136d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	struct i2c_client *client = data->client;
1379ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	int nr = attr->index;
138e3cd9528af4d1fd404eefe16e52ae421f99a7817Shubhrajyoti D	long temp;
139e3cd9528af4d1fd404eefe16e52ae421f99a7817Shubhrajyoti D	int error;
14087d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	u8 resolution;
141e3cd9528af4d1fd404eefe16e52ae421f99a7817Shubhrajyoti D
14224edc0a71badc13a9574b060e6a22e78339ac7a4Frans Meulenbroeks	error = kstrtol(buf, 10, &temp);
143e3cd9528af4d1fd404eefe16e52ae421f99a7817Shubhrajyoti D	if (error)
144e3cd9528af4d1fd404eefe16e52ae421f99a7817Shubhrajyoti D		return error;
1459ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare
14687d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	/*
14787d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	 * Resolution of limit registers is assumed to be the same as the
14887d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	 * temperature input register resolution unless given explicitly.
14987d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	 */
15087d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	if (attr->index && data->resolution_limits)
15187d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare		resolution = data->resolution_limits;
15287d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	else
15387d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare		resolution = data->resolution;
15487d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare
1559ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	mutex_lock(&data->update_lock);
15687d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
15787d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	data->temp[nr] = DIV_ROUND_CLOSEST(temp  << (resolution - 8),
15887d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare					   1000) << (16 - resolution);
1599ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]);
1609ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	mutex_unlock(&data->update_lock);
1619ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	return count;
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1649ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
1659ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare			show_temp, set_temp, 1);
1669ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
1679ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare			show_temp, set_temp, 2);
1689ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
170d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeckstatic struct attribute *lm75_attrs[] = {
1719ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	&sensor_dev_attr_temp1_input.dev_attr.attr,
1729ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	&sensor_dev_attr_temp1_max.dev_attr.attr,
1739ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
174c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman
175c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman	NULL
176c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman};
177d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter RoeckATTRIBUTE_GROUPS(lm75);
178c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman
17901a52397e95a8532c59506691759dba9262d6be7David Brownell/*-----------------------------------------------------------------------*/
18001a52397e95a8532c59506691759dba9262d6be7David Brownell
1818ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare/* device probe and removal */
1829ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
1839ebd3d822efeca2e73565516a80373c76ce3fa12David Brownellstatic int
1849ebd3d822efeca2e73565516a80373c76ce3fa12David Brownelllm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
1859ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell{
186d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	struct device *dev = &client->dev;
1879ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	struct lm75_data *data;
1889ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	int status;
1899ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	u8 set_mask, clr_mask;
1909ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	int new;
1910cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare	enum lm75_type kind = id->driver_data;
1929ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
1939ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	if (!i2c_check_functionality(client->adapter,
1949ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell			I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
1959ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell		return -EIO;
1969ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
197d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL);
1989ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	if (!data)
1999ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell		return -ENOMEM;
2009ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
201d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	data->client = client;
2029ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	i2c_set_clientdata(client, data);
2039ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	mutex_init(&data->update_lock);
2049ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
2059ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	/* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
2069ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	 * Then tweak to be more precise when appropriate.
2079ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	 */
2089ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	set_mask = 0;
2098a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	clr_mask = LM75_SHUTDOWN;		/* continuous conversions */
2108a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare
2110cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare	switch (kind) {
2128a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case adt75:
2138a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare		clr_mask |= 1 << 5;		/* not one-shot mode */
2140cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution = 12;
2150cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->sample_time = HZ / 8;
2168a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare		break;
2178a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case ds1775:
2188a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case ds75:
2198a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case stds75:
2200cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		clr_mask |= 3 << 5;
2210cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		set_mask |= 2 << 5;		/* 11-bit mode */
2220cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution = 11;
2230cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->sample_time = HZ;
2240cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		break;
2253fbc81e3c0257c756c0955bcb291374d74c11f61Jean Delvare	case ds7505:
2263fbc81e3c0257c756c0955bcb291374d74c11f61Jean Delvare		set_mask |= 3 << 5;		/* 12-bit mode */
2273fbc81e3c0257c756c0955bcb291374d74c11f61Jean Delvare		data->resolution = 12;
2283fbc81e3c0257c756c0955bcb291374d74c11f61Jean Delvare		data->sample_time = HZ / 4;
2293fbc81e3c0257c756c0955bcb291374d74c11f61Jean Delvare		break;
230c98d6c65e6e6bd24a12174fff6ca4990d346de5dArnaud Ebalard	case g751:
2310cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare	case lm75:
2320cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare	case lm75a:
2330cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution = 9;
2340cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->sample_time = HZ / 2;
2350cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		break;
2360cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare	case max6625:
2370cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution = 9;
2380cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->sample_time = HZ / 4;
2390cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		break;
2400cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare	case max6626:
2410cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution = 12;
2420cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution_limits = 9;
2430cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->sample_time = HZ / 4;
2440cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		break;
2450cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare	case tcn75:
2460cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution = 9;
2470cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->sample_time = HZ / 8;
2488a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare		break;
2498a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case mcp980x:
2500cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution_limits = 9;
2510cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		/* fall through */
2528a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case tmp100:
2538a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case tmp101:
2540cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		set_mask |= 3 << 5;		/* 12-bit mode */
2550cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution = 12;
2560cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->sample_time = HZ;
2570cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		clr_mask |= 1 << 7;		/* not one-shot mode */
2580cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		break;
259c83959f89f1cbe2e712c11e4a77d89f4d34d09ffFrans Klaver	case tmp112:
260c83959f89f1cbe2e712c11e4a77d89f4d34d09ffFrans Klaver		set_mask |= 3 << 5;		/* 12-bit mode */
261c83959f89f1cbe2e712c11e4a77d89f4d34d09ffFrans Klaver		clr_mask |= 1 << 7;		/* not one-shot mode */
262c83959f89f1cbe2e712c11e4a77d89f4d34d09ffFrans Klaver		data->resolution = 12;
263c83959f89f1cbe2e712c11e4a77d89f4d34d09ffFrans Klaver		data->sample_time = HZ / 4;
264c83959f89f1cbe2e712c11e4a77d89f4d34d09ffFrans Klaver		break;
2658a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case tmp105:
2668a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case tmp175:
2678a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case tmp275:
2688a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	case tmp75:
2690cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		set_mask |= 3 << 5;		/* 12-bit mode */
2708a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare		clr_mask |= 1 << 7;		/* not one-shot mode */
2710cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->resolution = 12;
2720cd2c72d765191f24d7be14366c0413bf139f3e3Jean Delvare		data->sample_time = HZ / 2;
2738a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare		break;
2748a5c5cc61748642a1276ef94611e21a60f0796abJean Delvare	}
2759ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
2769ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	/* configure as specified */
2779ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	status = lm75_read_value(client, LM75_REG_CONF);
2789ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	if (status < 0) {
279d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck		dev_dbg(dev, "Can't read config? %d\n", status);
28013ac7a017678d9d7ee4dcc93a10947df0d3b5b12Guenter Roeck		return status;
2819ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	}
2829ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	data->orig_conf = status;
2839ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	new = status & ~clr_mask;
2849ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	new |= set_mask;
2859ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	if (status != new)
2869ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell		lm75_write_value(client, LM75_REG_CONF, new);
287d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	dev_dbg(dev, "Config %02x\n", new);
2889ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
289d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
290d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck							    data, lm75_groups);
291d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	if (IS_ERR(data->hwmon_dev))
292d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck		return PTR_ERR(data->hwmon_dev);
2939ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
294d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	data->tz = thermal_zone_of_sensor_register(data->hwmon_dev,
29522e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin						   0,
296d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck						   data->hwmon_dev,
29722e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin						   lm75_read_temp, NULL);
29822e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin	if (IS_ERR(data->tz))
29922e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin		data->tz = NULL;
30022e731838b0e337fed5f16c67aa0b954028dfe93Eduardo Valentin
301d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	dev_info(dev, "%s: sensor '%s'\n",
302739cf3a2691951a2d68baa275201a7e931fd50e9Kay Sievers		 dev_name(data->hwmon_dev), client->name);
3039ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
3049ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	return 0;
3059ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell}
3069ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
3079ebd3d822efeca2e73565516a80373c76ce3fa12David Brownellstatic int lm75_remove(struct i2c_client *client)
3089ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell{
3099ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	struct lm75_data *data = i2c_get_clientdata(client);
3109ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
311d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz);
3129ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	hwmon_device_unregister(data->hwmon_dev);
3139ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
3149ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	return 0;
3159ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell}
3169ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
3179ebd3d822efeca2e73565516a80373c76ce3fa12David Brownellstatic const struct i2c_device_id lm75_ids[] = {
318e96f9d89e6213c7630a3323cd0c754e7f2619564Michael Hennerich	{ "adt75", adt75, },
3199ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "ds1775", ds1775, },
3209ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "ds75", ds75, },
3213fbc81e3c0257c756c0955bcb291374d74c11f61Jean Delvare	{ "ds7505", ds7505, },
322c98d6c65e6e6bd24a12174fff6ca4990d346de5dArnaud Ebalard	{ "g751", g751, },
3239ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "lm75", lm75, },
3249ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "lm75a", lm75a, },
3259ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "max6625", max6625, },
3269ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "max6626", max6626, },
3279ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "mcp980x", mcp980x, },
3289ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "stds75", stds75, },
3299ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "tcn75", tcn75, },
3309ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "tmp100", tmp100, },
3319ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "tmp101", tmp101, },
3326d034059eef080a0cdda92b45baa18cb00a19835Shubhrajyoti Datta	{ "tmp105", tmp105, },
333c83959f89f1cbe2e712c11e4a77d89f4d34d09ffFrans Klaver	{ "tmp112", tmp112, },
3349ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "tmp175", tmp175, },
3359ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "tmp275", tmp275, },
3369ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ "tmp75", tmp75, },
3379ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell	{ /* LIST END */ }
3389ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell};
3399ebd3d822efeca2e73565516a80373c76ce3fa12David BrownellMODULE_DEVICE_TABLE(i2c, lm75_ids);
3409ebd3d822efeca2e73565516a80373c76ce3fa12David Brownell
34105e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen#define LM75A_ID 0xA1
34205e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen
3438ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare/* Return 0 if detection is successful, -ENODEV otherwise */
344310ec79210d754afe51e2e4a983e846b60179abdJean Delvarestatic int lm75_detect(struct i2c_client *new_client,
3458ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare		       struct i2c_board_info *info)
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3478ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare	struct i2c_adapter *adapter = new_client->adapter;
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
349e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare	int conf, hyst, os;
35005e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen	bool is_lm75a = 0;
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     I2C_FUNC_SMBUS_WORD_DATA))
3548ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare		return -ENODEV;
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
356426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	/*
357426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * Now, we do the remaining detection. There is no identification-
358426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * dedicated register so we have to rely on several tricks:
359426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * unused bits, registers cycling over 8-address boundaries,
360426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * addresses 0x04-0x07 returning the last read value.
361426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * The cycling+unused addresses combination is not tested,
362426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * since it would significantly slow the detection down and would
363426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * hardly add any value.
364426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 *
365426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * The National Semiconductor LM75A is different than earlier
366426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * LM75s.  It has an ID byte of 0xaX (where X is the chip
367426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * revision, with 1 being the only revision in existence) in
368426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * register 7, and unused registers return 0xff rather than the
369426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * last read value.
370426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 *
371426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * Note that this function only detects the original National
372426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * Semiconductor LM75 and the LM75A. Clones from other vendors
373426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * aren't detected, on purpose, because they are typically never
374426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * found on PC hardware. They are found on embedded designs where
375426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * they can be instantiated explicitly so detection is not needed.
376426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * The absence of identification registers on all these clones
377426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * would make their exhaustive detection very difficult and weak,
378426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 * and odds are that the driver would bind to unsupported devices.
379426343ef34fac426e619176c84cb2e263b9ed23dJean Delvare	 */
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare	/* Unused bits */
38252df6440a29123eed912183fe785bbe174ef14b9Jean Delvare	conf = i2c_smbus_read_byte_data(new_client, 1);
383e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare	if (conf & 0xe0)
384e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		return -ENODEV;
38505e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen
38605e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen	/* First check for LM75A */
38705e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen	if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) {
38805e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen		/* LM75A returns 0xff on unused registers so
38905e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen		   just to be sure we check for that too. */
39005e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen		if (i2c_smbus_read_byte_data(new_client, 4) != 0xff
39105e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen		 || i2c_smbus_read_byte_data(new_client, 5) != 0xff
39205e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen		 || i2c_smbus_read_byte_data(new_client, 6) != 0xff)
39305e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen			return -ENODEV;
39405e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen		is_lm75a = 1;
395e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		hyst = i2c_smbus_read_byte_data(new_client, 2);
396e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		os = i2c_smbus_read_byte_data(new_client, 3);
39705e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen	} else { /* Traditional style LM75 detection */
39805e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen		/* Unused addresses */
399e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		hyst = i2c_smbus_read_byte_data(new_client, 2);
400e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		if (i2c_smbus_read_byte_data(new_client, 4) != hyst
401e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		 || i2c_smbus_read_byte_data(new_client, 5) != hyst
402e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		 || i2c_smbus_read_byte_data(new_client, 6) != hyst
403e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		 || i2c_smbus_read_byte_data(new_client, 7) != hyst)
40405e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen			return -ENODEV;
405e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		os = i2c_smbus_read_byte_data(new_client, 3);
406e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		if (i2c_smbus_read_byte_data(new_client, 4) != os
407e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		 || i2c_smbus_read_byte_data(new_client, 5) != os
408e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		 || i2c_smbus_read_byte_data(new_client, 6) != os
409e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		 || i2c_smbus_read_byte_data(new_client, 7) != os)
41005e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen			return -ENODEV;
41105e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen	}
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41352df6440a29123eed912183fe785bbe174ef14b9Jean Delvare	/* Addresses cycling */
414e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare	for (i = 8; i <= 248; i += 40) {
41552df6440a29123eed912183fe785bbe174ef14b9Jean Delvare		if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
416e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		 || i2c_smbus_read_byte_data(new_client, i + 2) != hyst
417e76f67b5babc65cd620d395a1fd231409808df90Jean Delvare		 || i2c_smbus_read_byte_data(new_client, i + 3) != os)
41852df6440a29123eed912183fe785bbe174ef14b9Jean Delvare			return -ENODEV;
41905e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen		if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7)
42005e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen				!= LM75A_ID)
42105e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen			return -ENODEV;
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
42405e82fe40faee8499b4e3ba12fddaaf013d84203Len Sorensen	strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE);
425c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
42701a52397e95a8532c59506691759dba9262d6be7David Brownell}
42801a52397e95a8532c59506691759dba9262d6be7David Brownell
4299914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta#ifdef CONFIG_PM
4309914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Dattastatic int lm75_suspend(struct device *dev)
4319914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta{
4329914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	int status;
4339914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	struct i2c_client *client = to_i2c_client(dev);
4349914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	status = lm75_read_value(client, LM75_REG_CONF);
4359914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	if (status < 0) {
4369914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta		dev_dbg(&client->dev, "Can't read config? %d\n", status);
4379914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta		return status;
4389914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	}
4399914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	status = status | LM75_SHUTDOWN;
4409914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	lm75_write_value(client, LM75_REG_CONF, status);
4419914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	return 0;
4429914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta}
4439914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta
4449914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Dattastatic int lm75_resume(struct device *dev)
4459914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta{
4469914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	int status;
4479914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	struct i2c_client *client = to_i2c_client(dev);
4489914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	status = lm75_read_value(client, LM75_REG_CONF);
4499914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	if (status < 0) {
4509914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta		dev_dbg(&client->dev, "Can't read config? %d\n", status);
4519914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta		return status;
4529914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	}
4539914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	status = status & ~LM75_SHUTDOWN;
4549914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	lm75_write_value(client, LM75_REG_CONF, status);
4559914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	return 0;
4569914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta}
4579914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta
4589914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Dattastatic const struct dev_pm_ops lm75_dev_pm_ops = {
4599914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	.suspend	= lm75_suspend,
4609914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta	.resume		= lm75_resume,
4619914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta};
4629914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops)
4639914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta#else
4649914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta#define LM75_DEV_PM_OPS NULL
4659914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta#endif /* CONFIG_PM */
4669914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta
4678ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvarestatic struct i2c_driver lm75_driver = {
4688ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare	.class		= I2C_CLASS_HWMON,
46901a52397e95a8532c59506691759dba9262d6be7David Brownell	.driver = {
4708ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare		.name	= "lm75",
4719914518e79800c977e20eda1335d43a4df813e3dShubhrajyoti Datta		.pm	= LM75_DEV_PM_OPS,
47201a52397e95a8532c59506691759dba9262d6be7David Brownell	},
4738ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare	.probe		= lm75_probe,
4748ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare	.remove		= lm75_remove,
4758ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare	.id_table	= lm75_ids,
4768ff69eebf5bf8a123a117b78412d5efb85765d8bJean Delvare	.detect		= lm75_detect,
477c3813d6af177fab19e322f3114b1f64fbcf08d71Jean Delvare	.address_list	= normal_i2c,
47801a52397e95a8532c59506691759dba9262d6be7David Brownell};
47901a52397e95a8532c59506691759dba9262d6be7David Brownell
48001a52397e95a8532c59506691759dba9262d6be7David Brownell/*-----------------------------------------------------------------------*/
48101a52397e95a8532c59506691759dba9262d6be7David Brownell
48201a52397e95a8532c59506691759dba9262d6be7David Brownell/* register access */
48301a52397e95a8532c59506691759dba9262d6be7David Brownell
484caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D/*
485caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * All registers are word-sized, except for the configuration register.
486caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * LM75 uses a high-byte first convention, which is exactly opposite to
487caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D * the SMBus standard.
488caaa0f36c378c6fec6fd5260a63566e002ac4a84Shubhrajyoti D */
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int lm75_read_value(struct i2c_client *client, u8 reg)
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (reg == LM75_REG_CONF)
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return i2c_smbus_read_byte_data(client, reg);
49390f4102ce59226954edbe960b2434d8b3da5f086Jean Delvare	else
49490f4102ce59226954edbe960b2434d8b3da5f086Jean Delvare		return i2c_smbus_read_word_swapped(client, reg);
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (reg == LM75_REG_CONF)
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return i2c_smbus_write_byte_data(client, reg, value);
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
50290f4102ce59226954edbe960b2434d8b3da5f086Jean Delvare		return i2c_smbus_write_word_swapped(client, reg, value);
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct lm75_data *lm75_update_device(struct device *dev)
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
507d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	struct lm75_data *data = dev_get_drvdata(dev);
508d663ec496d4a808b02ae10f85a55799b3c91fe7aGuenter Roeck	struct i2c_client *client = data->client;
5091f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks	struct lm75_data *ret = data;
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5119a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51387d0621ae2bdf2e2c60aadbbcb8b6c680777c1bfJean Delvare	if (time_after(jiffies, data->last_updated + data->sample_time)
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    || !data->valid) {
5159ca8e40c8414d25e880b587cbd4d130750c49588Jean Delvare		int i;
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dev_dbg(&client->dev, "Starting lm75 update\n");
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
518bcccc3a28e9cbb44549cde326852c26203a53a56David Brownell		for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
519bcccc3a28e9cbb44549cde326852c26203a53a56David Brownell			int status;
520bcccc3a28e9cbb44549cde326852c26203a53a56David Brownell
521bcccc3a28e9cbb44549cde326852c26203a53a56David Brownell			status = lm75_read_value(client, LM75_REG_TEMP[i]);
5221f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks			if (unlikely(status < 0)) {
5231f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks				dev_dbg(dev,
5241f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks					"LM75: Failed to read value: reg %d, error %d\n",
5251f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks					LM75_REG_TEMP[i], status);
5261f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks				ret = ERR_PTR(status);
5271f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks				data->valid = 0;
5281f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks				goto abort;
5291f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks			}
5301f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks			data->temp[i] = status;
531bcccc3a28e9cbb44549cde326852c26203a53a56David Brownell		}
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data->last_updated = jiffies;
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data->valid = 1;
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5361f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeksabort:
5379a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
5381f962f363b762887d8f9057598b6acacf9e80234Frans Meulenbroeks	return ret;
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
541f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7Axel Linmodule_i2c_driver(lm75_driver);
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("LM75 driver");
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
546