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> 308d5d45fbSJean Delvare #include "lm75.h" 318d5d45fbSJean Delvare 328d5d45fbSJean Delvare 3301a52397SDavid Brownell /* 3401a52397SDavid Brownell * This driver handles the LM75 and compatible digital temperature sensors. 3501a52397SDavid Brownell */ 3601a52397SDavid Brownell 379ebd3d82SDavid Brownell enum lm75_type { /* keep sorted in alphabetical order */ 38e96f9d89SMichael Hennerich adt75, 391f86df49SJean Delvare ds1775, 409ebd3d82SDavid Brownell ds75, 411f86df49SJean Delvare lm75, 429ebd3d82SDavid Brownell lm75a, 439ebd3d82SDavid Brownell max6625, 449ebd3d82SDavid Brownell max6626, 459ebd3d82SDavid Brownell mcp980x, 469ebd3d82SDavid Brownell stds75, 479ebd3d82SDavid Brownell tcn75, 489ebd3d82SDavid Brownell tmp100, 499ebd3d82SDavid Brownell tmp101, 506d034059SShubhrajyoti Datta tmp105, 519ebd3d82SDavid Brownell tmp175, 529ebd3d82SDavid Brownell tmp275, 539ebd3d82SDavid Brownell tmp75, 549ebd3d82SDavid Brownell }; 559ebd3d82SDavid Brownell 568ff69eebSJean Delvare /* Addresses scanned */ 5725e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 588d5d45fbSJean Delvare 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 598d5d45fbSJean Delvare 608d5d45fbSJean Delvare 618d5d45fbSJean Delvare /* The LM75 registers */ 628d5d45fbSJean Delvare #define LM75_REG_CONF 0x01 639ca8e40cSJean Delvare static const u8 LM75_REG_TEMP[3] = { 649ca8e40cSJean Delvare 0x00, /* input */ 659ca8e40cSJean Delvare 0x03, /* max */ 669ca8e40cSJean Delvare 0x02, /* hyst */ 679ca8e40cSJean Delvare }; 688d5d45fbSJean Delvare 698d5d45fbSJean Delvare /* Each client has this additional data */ 708d5d45fbSJean Delvare struct lm75_data { 711beeffe4STony Jones struct device *hwmon_dev; 729a61bf63SIngo Molnar struct mutex update_lock; 739ebd3d82SDavid Brownell u8 orig_conf; 7401a52397SDavid Brownell char valid; /* !=0 if registers are valid */ 758d5d45fbSJean Delvare unsigned long last_updated; /* In jiffies */ 769ca8e40cSJean Delvare u16 temp[3]; /* Register values, 779ca8e40cSJean Delvare 0 = input 789ca8e40cSJean Delvare 1 = max 799ca8e40cSJean Delvare 2 = hyst */ 808d5d45fbSJean Delvare }; 818d5d45fbSJean Delvare 828d5d45fbSJean Delvare static int lm75_read_value(struct i2c_client *client, u8 reg); 838d5d45fbSJean Delvare static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); 848d5d45fbSJean Delvare static struct lm75_data *lm75_update_device(struct device *dev); 858d5d45fbSJean Delvare 868d5d45fbSJean Delvare 8701a52397SDavid Brownell /*-----------------------------------------------------------------------*/ 8801a52397SDavid Brownell 8901a52397SDavid Brownell /* sysfs attributes for hwmon */ 908d5d45fbSJean Delvare 919ca8e40cSJean Delvare static ssize_t show_temp(struct device *dev, struct device_attribute *da, 929ca8e40cSJean Delvare char *buf) 939ca8e40cSJean Delvare { 949ca8e40cSJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 959ca8e40cSJean Delvare struct lm75_data *data = lm75_update_device(dev); 969ca8e40cSJean Delvare return sprintf(buf, "%d\n", 979ca8e40cSJean Delvare LM75_TEMP_FROM_REG(data->temp[attr->index])); 988d5d45fbSJean Delvare } 998d5d45fbSJean Delvare 1009ca8e40cSJean Delvare static ssize_t set_temp(struct device *dev, struct device_attribute *da, 1019ca8e40cSJean Delvare const char *buf, size_t count) 1029ca8e40cSJean Delvare { 1039ca8e40cSJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 1049ca8e40cSJean Delvare struct i2c_client *client = to_i2c_client(dev); 1059ca8e40cSJean Delvare struct lm75_data *data = i2c_get_clientdata(client); 1069ca8e40cSJean Delvare int nr = attr->index; 107e3cd9528SShubhrajyoti D long temp; 108e3cd9528SShubhrajyoti D int error; 109e3cd9528SShubhrajyoti D 110e3cd9528SShubhrajyoti D error = strict_strtol(buf, 10, &temp); 111e3cd9528SShubhrajyoti D if (error) 112e3cd9528SShubhrajyoti D return error; 1139ca8e40cSJean Delvare 1149ca8e40cSJean Delvare mutex_lock(&data->update_lock); 1159ca8e40cSJean Delvare data->temp[nr] = LM75_TEMP_TO_REG(temp); 1169ca8e40cSJean Delvare lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); 1179ca8e40cSJean Delvare mutex_unlock(&data->update_lock); 1189ca8e40cSJean Delvare return count; 1198d5d45fbSJean Delvare } 1208d5d45fbSJean Delvare 1219ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, 1229ca8e40cSJean Delvare show_temp, set_temp, 1); 1239ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, 1249ca8e40cSJean Delvare show_temp, set_temp, 2); 1259ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 1268d5d45fbSJean Delvare 127c1685f61SMark M. Hoffman static struct attribute *lm75_attributes[] = { 1289ca8e40cSJean Delvare &sensor_dev_attr_temp1_input.dev_attr.attr, 1299ca8e40cSJean Delvare &sensor_dev_attr_temp1_max.dev_attr.attr, 1309ca8e40cSJean Delvare &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, 131c1685f61SMark M. Hoffman 132c1685f61SMark M. Hoffman NULL 133c1685f61SMark M. Hoffman }; 134c1685f61SMark M. Hoffman 135c1685f61SMark M. Hoffman static const struct attribute_group lm75_group = { 136c1685f61SMark M. Hoffman .attrs = lm75_attributes, 137c1685f61SMark M. Hoffman }; 138c1685f61SMark M. Hoffman 13901a52397SDavid Brownell /*-----------------------------------------------------------------------*/ 14001a52397SDavid Brownell 1418ff69eebSJean Delvare /* device probe and removal */ 1429ebd3d82SDavid Brownell 1439ebd3d82SDavid Brownell static int 1449ebd3d82SDavid Brownell lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) 1459ebd3d82SDavid Brownell { 1469ebd3d82SDavid Brownell struct lm75_data *data; 1479ebd3d82SDavid Brownell int status; 1489ebd3d82SDavid Brownell u8 set_mask, clr_mask; 1499ebd3d82SDavid Brownell int new; 1509ebd3d82SDavid Brownell 1519ebd3d82SDavid Brownell if (!i2c_check_functionality(client->adapter, 1529ebd3d82SDavid Brownell I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) 1539ebd3d82SDavid Brownell return -EIO; 1549ebd3d82SDavid Brownell 1559ebd3d82SDavid Brownell data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL); 1569ebd3d82SDavid Brownell if (!data) 1579ebd3d82SDavid Brownell return -ENOMEM; 1589ebd3d82SDavid Brownell 1599ebd3d82SDavid Brownell i2c_set_clientdata(client, data); 1609ebd3d82SDavid Brownell mutex_init(&data->update_lock); 1619ebd3d82SDavid Brownell 1629ebd3d82SDavid Brownell /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. 1639ebd3d82SDavid Brownell * Then tweak to be more precise when appropriate. 1649ebd3d82SDavid Brownell */ 1659ebd3d82SDavid Brownell set_mask = 0; 1669ebd3d82SDavid Brownell clr_mask = (1 << 0) /* continuous conversions */ 1679ebd3d82SDavid Brownell | (1 << 6) | (1 << 5); /* 9-bit mode */ 1689ebd3d82SDavid Brownell 1699ebd3d82SDavid Brownell /* configure as specified */ 1709ebd3d82SDavid Brownell status = lm75_read_value(client, LM75_REG_CONF); 1719ebd3d82SDavid Brownell if (status < 0) { 1729ebd3d82SDavid Brownell dev_dbg(&client->dev, "Can't read config? %d\n", status); 1739ebd3d82SDavid Brownell goto exit_free; 1749ebd3d82SDavid Brownell } 1759ebd3d82SDavid Brownell data->orig_conf = status; 1769ebd3d82SDavid Brownell new = status & ~clr_mask; 1779ebd3d82SDavid Brownell new |= set_mask; 1789ebd3d82SDavid Brownell if (status != new) 1799ebd3d82SDavid Brownell lm75_write_value(client, LM75_REG_CONF, new); 1809ebd3d82SDavid Brownell dev_dbg(&client->dev, "Config %02x\n", new); 1819ebd3d82SDavid Brownell 1829ebd3d82SDavid Brownell /* Register sysfs hooks */ 1839ebd3d82SDavid Brownell status = sysfs_create_group(&client->dev.kobj, &lm75_group); 1849ebd3d82SDavid Brownell if (status) 1859ebd3d82SDavid Brownell goto exit_free; 1869ebd3d82SDavid Brownell 1879ebd3d82SDavid Brownell data->hwmon_dev = hwmon_device_register(&client->dev); 1889ebd3d82SDavid Brownell if (IS_ERR(data->hwmon_dev)) { 1899ebd3d82SDavid Brownell status = PTR_ERR(data->hwmon_dev); 1909ebd3d82SDavid Brownell goto exit_remove; 1919ebd3d82SDavid Brownell } 1929ebd3d82SDavid Brownell 1939ebd3d82SDavid Brownell dev_info(&client->dev, "%s: sensor '%s'\n", 194739cf3a2SKay Sievers dev_name(data->hwmon_dev), client->name); 1959ebd3d82SDavid Brownell 1969ebd3d82SDavid Brownell return 0; 1979ebd3d82SDavid Brownell 1989ebd3d82SDavid Brownell exit_remove: 1999ebd3d82SDavid Brownell sysfs_remove_group(&client->dev.kobj, &lm75_group); 2009ebd3d82SDavid Brownell exit_free: 2019ebd3d82SDavid Brownell kfree(data); 2029ebd3d82SDavid Brownell return status; 2039ebd3d82SDavid Brownell } 2049ebd3d82SDavid Brownell 2059ebd3d82SDavid Brownell static int lm75_remove(struct i2c_client *client) 2069ebd3d82SDavid Brownell { 2079ebd3d82SDavid Brownell struct lm75_data *data = i2c_get_clientdata(client); 2089ebd3d82SDavid Brownell 2099ebd3d82SDavid Brownell hwmon_device_unregister(data->hwmon_dev); 2109ebd3d82SDavid Brownell sysfs_remove_group(&client->dev.kobj, &lm75_group); 2119ebd3d82SDavid Brownell lm75_write_value(client, LM75_REG_CONF, data->orig_conf); 2129ebd3d82SDavid Brownell kfree(data); 2139ebd3d82SDavid Brownell return 0; 2149ebd3d82SDavid Brownell } 2159ebd3d82SDavid Brownell 2169ebd3d82SDavid Brownell static const struct i2c_device_id lm75_ids[] = { 217e96f9d89SMichael Hennerich { "adt75", adt75, }, 2189ebd3d82SDavid Brownell { "ds1775", ds1775, }, 2199ebd3d82SDavid Brownell { "ds75", ds75, }, 2209ebd3d82SDavid Brownell { "lm75", lm75, }, 2219ebd3d82SDavid Brownell { "lm75a", lm75a, }, 2229ebd3d82SDavid Brownell { "max6625", max6625, }, 2239ebd3d82SDavid Brownell { "max6626", max6626, }, 2249ebd3d82SDavid Brownell { "mcp980x", mcp980x, }, 2259ebd3d82SDavid Brownell { "stds75", stds75, }, 2269ebd3d82SDavid Brownell { "tcn75", tcn75, }, 2279ebd3d82SDavid Brownell { "tmp100", tmp100, }, 2289ebd3d82SDavid Brownell { "tmp101", tmp101, }, 2296d034059SShubhrajyoti Datta { "tmp105", tmp105, }, 2309ebd3d82SDavid Brownell { "tmp175", tmp175, }, 2319ebd3d82SDavid Brownell { "tmp275", tmp275, }, 2329ebd3d82SDavid Brownell { "tmp75", tmp75, }, 2339ebd3d82SDavid Brownell { /* LIST END */ } 2349ebd3d82SDavid Brownell }; 2359ebd3d82SDavid Brownell MODULE_DEVICE_TABLE(i2c, lm75_ids); 2369ebd3d82SDavid Brownell 23705e82fe4SLen Sorensen #define LM75A_ID 0xA1 23805e82fe4SLen Sorensen 2398ff69eebSJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */ 240310ec792SJean Delvare static int lm75_detect(struct i2c_client *new_client, 2418ff69eebSJean Delvare struct i2c_board_info *info) 2428d5d45fbSJean Delvare { 2438ff69eebSJean Delvare struct i2c_adapter *adapter = new_client->adapter; 2448d5d45fbSJean Delvare int i; 245e76f67b5SJean Delvare int conf, hyst, os; 24605e82fe4SLen Sorensen bool is_lm75a = 0; 2478d5d45fbSJean Delvare 2488d5d45fbSJean Delvare if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 2498d5d45fbSJean Delvare I2C_FUNC_SMBUS_WORD_DATA)) 2508ff69eebSJean Delvare return -ENODEV; 2518d5d45fbSJean Delvare 252426343efSJean Delvare /* 253426343efSJean Delvare * Now, we do the remaining detection. There is no identification- 254426343efSJean Delvare * dedicated register so we have to rely on several tricks: 255426343efSJean Delvare * unused bits, registers cycling over 8-address boundaries, 256426343efSJean Delvare * addresses 0x04-0x07 returning the last read value. 257426343efSJean Delvare * The cycling+unused addresses combination is not tested, 258426343efSJean Delvare * since it would significantly slow the detection down and would 259426343efSJean Delvare * hardly add any value. 260426343efSJean Delvare * 261426343efSJean Delvare * The National Semiconductor LM75A is different than earlier 262426343efSJean Delvare * LM75s. It has an ID byte of 0xaX (where X is the chip 263426343efSJean Delvare * revision, with 1 being the only revision in existence) in 264426343efSJean Delvare * register 7, and unused registers return 0xff rather than the 265426343efSJean Delvare * last read value. 266426343efSJean Delvare * 267426343efSJean Delvare * Note that this function only detects the original National 268426343efSJean Delvare * Semiconductor LM75 and the LM75A. Clones from other vendors 269426343efSJean Delvare * aren't detected, on purpose, because they are typically never 270426343efSJean Delvare * found on PC hardware. They are found on embedded designs where 271426343efSJean Delvare * they can be instantiated explicitly so detection is not needed. 272426343efSJean Delvare * The absence of identification registers on all these clones 273426343efSJean Delvare * would make their exhaustive detection very difficult and weak, 274426343efSJean Delvare * and odds are that the driver would bind to unsupported devices. 275426343efSJean Delvare */ 27605e82fe4SLen Sorensen 277e76f67b5SJean Delvare /* Unused bits */ 2788d5d45fbSJean Delvare conf = i2c_smbus_read_byte_data(new_client, 1); 279e76f67b5SJean Delvare if (conf & 0xe0) 280e76f67b5SJean Delvare return -ENODEV; 28105e82fe4SLen Sorensen 28205e82fe4SLen Sorensen /* First check for LM75A */ 28305e82fe4SLen Sorensen if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { 28405e82fe4SLen Sorensen /* LM75A returns 0xff on unused registers so 28505e82fe4SLen Sorensen just to be sure we check for that too. */ 28605e82fe4SLen Sorensen if (i2c_smbus_read_byte_data(new_client, 4) != 0xff 28705e82fe4SLen Sorensen || i2c_smbus_read_byte_data(new_client, 5) != 0xff 28805e82fe4SLen Sorensen || i2c_smbus_read_byte_data(new_client, 6) != 0xff) 28905e82fe4SLen Sorensen return -ENODEV; 29005e82fe4SLen Sorensen is_lm75a = 1; 291e76f67b5SJean Delvare hyst = i2c_smbus_read_byte_data(new_client, 2); 292e76f67b5SJean Delvare os = i2c_smbus_read_byte_data(new_client, 3); 29305e82fe4SLen Sorensen } else { /* Traditional style LM75 detection */ 29405e82fe4SLen Sorensen /* Unused addresses */ 295e76f67b5SJean Delvare hyst = i2c_smbus_read_byte_data(new_client, 2); 296e76f67b5SJean Delvare if (i2c_smbus_read_byte_data(new_client, 4) != hyst 297e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 5) != hyst 298e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 6) != hyst 299e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 7) != hyst) 3008ff69eebSJean Delvare return -ENODEV; 301e76f67b5SJean Delvare os = i2c_smbus_read_byte_data(new_client, 3); 302e76f67b5SJean Delvare if (i2c_smbus_read_byte_data(new_client, 4) != os 303e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 5) != os 304e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 6) != os 305e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 7) != os) 3068ff69eebSJean Delvare return -ENODEV; 30705e82fe4SLen Sorensen } 3088d5d45fbSJean Delvare 3098d5d45fbSJean Delvare /* Addresses cycling */ 310e76f67b5SJean Delvare for (i = 8; i <= 248; i += 40) { 3118d5d45fbSJean Delvare if (i2c_smbus_read_byte_data(new_client, i + 1) != conf 312e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, i + 2) != hyst 313e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, i + 3) != os) 3148ff69eebSJean Delvare return -ENODEV; 31505e82fe4SLen Sorensen if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) 31605e82fe4SLen Sorensen != LM75A_ID) 31705e82fe4SLen Sorensen return -ENODEV; 3188d5d45fbSJean Delvare } 3198d5d45fbSJean Delvare 32005e82fe4SLen Sorensen strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); 3218d5d45fbSJean Delvare 3228d5d45fbSJean Delvare return 0; 3238d5d45fbSJean Delvare } 3248d5d45fbSJean Delvare 3259914518eSShubhrajyoti Datta #ifdef CONFIG_PM 3269914518eSShubhrajyoti Datta static int lm75_suspend(struct device *dev) 3279914518eSShubhrajyoti Datta { 3289914518eSShubhrajyoti Datta int status; 3299914518eSShubhrajyoti Datta struct i2c_client *client = to_i2c_client(dev); 3309914518eSShubhrajyoti Datta status = lm75_read_value(client, LM75_REG_CONF); 3319914518eSShubhrajyoti Datta if (status < 0) { 3329914518eSShubhrajyoti Datta dev_dbg(&client->dev, "Can't read config? %d\n", status); 3339914518eSShubhrajyoti Datta return status; 3349914518eSShubhrajyoti Datta } 3359914518eSShubhrajyoti Datta status = status | LM75_SHUTDOWN; 3369914518eSShubhrajyoti Datta lm75_write_value(client, LM75_REG_CONF, status); 3379914518eSShubhrajyoti Datta return 0; 3389914518eSShubhrajyoti Datta } 3399914518eSShubhrajyoti Datta 3409914518eSShubhrajyoti Datta static int lm75_resume(struct device *dev) 3419914518eSShubhrajyoti Datta { 3429914518eSShubhrajyoti Datta int status; 3439914518eSShubhrajyoti Datta struct i2c_client *client = to_i2c_client(dev); 3449914518eSShubhrajyoti Datta status = lm75_read_value(client, LM75_REG_CONF); 3459914518eSShubhrajyoti Datta if (status < 0) { 3469914518eSShubhrajyoti Datta dev_dbg(&client->dev, "Can't read config? %d\n", status); 3479914518eSShubhrajyoti Datta return status; 3489914518eSShubhrajyoti Datta } 3499914518eSShubhrajyoti Datta status = status & ~LM75_SHUTDOWN; 3509914518eSShubhrajyoti Datta lm75_write_value(client, LM75_REG_CONF, status); 3519914518eSShubhrajyoti Datta return 0; 3529914518eSShubhrajyoti Datta } 3539914518eSShubhrajyoti Datta 3549914518eSShubhrajyoti Datta static const struct dev_pm_ops lm75_dev_pm_ops = { 3559914518eSShubhrajyoti Datta .suspend = lm75_suspend, 3569914518eSShubhrajyoti Datta .resume = lm75_resume, 3579914518eSShubhrajyoti Datta }; 3589914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) 3599914518eSShubhrajyoti Datta #else 3609914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS NULL 3619914518eSShubhrajyoti Datta #endif /* CONFIG_PM */ 3629914518eSShubhrajyoti Datta 3638ff69eebSJean Delvare static struct i2c_driver lm75_driver = { 3648ff69eebSJean Delvare .class = I2C_CLASS_HWMON, 36501a52397SDavid Brownell .driver = { 3668ff69eebSJean Delvare .name = "lm75", 3679914518eSShubhrajyoti Datta .pm = LM75_DEV_PM_OPS, 36801a52397SDavid Brownell }, 3698ff69eebSJean Delvare .probe = lm75_probe, 3708ff69eebSJean Delvare .remove = lm75_remove, 3718ff69eebSJean Delvare .id_table = lm75_ids, 3728ff69eebSJean Delvare .detect = lm75_detect, 373c3813d6aSJean Delvare .address_list = normal_i2c, 37401a52397SDavid Brownell }; 37501a52397SDavid Brownell 37601a52397SDavid Brownell /*-----------------------------------------------------------------------*/ 37701a52397SDavid Brownell 37801a52397SDavid Brownell /* register access */ 37901a52397SDavid Brownell 380caaa0f36SShubhrajyoti D /* 381caaa0f36SShubhrajyoti D * All registers are word-sized, except for the configuration register. 382caaa0f36SShubhrajyoti D * LM75 uses a high-byte first convention, which is exactly opposite to 383caaa0f36SShubhrajyoti D * the SMBus standard. 384caaa0f36SShubhrajyoti D */ 3858d5d45fbSJean Delvare static int lm75_read_value(struct i2c_client *client, u8 reg) 3868d5d45fbSJean Delvare { 3878d5d45fbSJean Delvare if (reg == LM75_REG_CONF) 3888d5d45fbSJean Delvare return i2c_smbus_read_byte_data(client, reg); 38990f4102cSJean Delvare else 39090f4102cSJean Delvare return i2c_smbus_read_word_swapped(client, reg); 3918d5d45fbSJean Delvare } 3928d5d45fbSJean Delvare 3938d5d45fbSJean Delvare static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) 3948d5d45fbSJean Delvare { 3958d5d45fbSJean Delvare if (reg == LM75_REG_CONF) 3968d5d45fbSJean Delvare return i2c_smbus_write_byte_data(client, reg, value); 3978d5d45fbSJean Delvare else 39890f4102cSJean Delvare return i2c_smbus_write_word_swapped(client, reg, value); 3998d5d45fbSJean Delvare } 4008d5d45fbSJean Delvare 4018d5d45fbSJean Delvare static struct lm75_data *lm75_update_device(struct device *dev) 4028d5d45fbSJean Delvare { 4038d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 4048d5d45fbSJean Delvare struct lm75_data *data = i2c_get_clientdata(client); 4058d5d45fbSJean Delvare 4069a61bf63SIngo Molnar mutex_lock(&data->update_lock); 4078d5d45fbSJean Delvare 4088d5d45fbSJean Delvare if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 4098d5d45fbSJean Delvare || !data->valid) { 4109ca8e40cSJean Delvare int i; 4118d5d45fbSJean Delvare dev_dbg(&client->dev, "Starting lm75 update\n"); 4128d5d45fbSJean Delvare 413bcccc3a2SDavid Brownell for (i = 0; i < ARRAY_SIZE(data->temp); i++) { 414bcccc3a2SDavid Brownell int status; 415bcccc3a2SDavid Brownell 416bcccc3a2SDavid Brownell status = lm75_read_value(client, LM75_REG_TEMP[i]); 417bcccc3a2SDavid Brownell if (status < 0) 418bcccc3a2SDavid Brownell dev_dbg(&client->dev, "reg %d, err %d\n", 419bcccc3a2SDavid Brownell LM75_REG_TEMP[i], status); 420bcccc3a2SDavid Brownell else 421bcccc3a2SDavid Brownell data->temp[i] = status; 422bcccc3a2SDavid Brownell } 4238d5d45fbSJean Delvare data->last_updated = jiffies; 4248d5d45fbSJean Delvare data->valid = 1; 4258d5d45fbSJean Delvare } 4268d5d45fbSJean Delvare 4279a61bf63SIngo Molnar mutex_unlock(&data->update_lock); 4288d5d45fbSJean Delvare 4298d5d45fbSJean Delvare return data; 4308d5d45fbSJean Delvare } 4318d5d45fbSJean Delvare 43201a52397SDavid Brownell /*-----------------------------------------------------------------------*/ 43301a52397SDavid Brownell 43401a52397SDavid Brownell /* module glue */ 43501a52397SDavid Brownell 4368d5d45fbSJean Delvare static int __init sensors_lm75_init(void) 4378d5d45fbSJean Delvare { 4388ff69eebSJean Delvare return i2c_add_driver(&lm75_driver); 4398d5d45fbSJean Delvare } 4408d5d45fbSJean Delvare 4418d5d45fbSJean Delvare static void __exit sensors_lm75_exit(void) 4428d5d45fbSJean Delvare { 4438d5d45fbSJean Delvare i2c_del_driver(&lm75_driver); 4448d5d45fbSJean Delvare } 4458d5d45fbSJean Delvare 4468d5d45fbSJean Delvare MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); 4478d5d45fbSJean Delvare MODULE_DESCRIPTION("LM75 driver"); 4488d5d45fbSJean Delvare MODULE_LICENSE("GPL"); 4498d5d45fbSJean Delvare 4508d5d45fbSJean Delvare module_init(sensors_lm75_init); 4518d5d45fbSJean Delvare module_exit(sensors_lm75_exit); 452