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