18d5d45fbSJean Delvare /* 2caaa0f36SShubhrajyoti D * lm75.c - Part of lm_sensors, Linux kernel modules for hardware 3caaa0f36SShubhrajyoti D * monitoring 4caaa0f36SShubhrajyoti D * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> 5caaa0f36SShubhrajyoti D * 6caaa0f36SShubhrajyoti D * This program is free software; you can redistribute it and/or modify 7caaa0f36SShubhrajyoti D * it under the terms of the GNU General Public License as published by 8caaa0f36SShubhrajyoti D * the Free Software Foundation; either version 2 of the License, or 9caaa0f36SShubhrajyoti D * (at your option) any later version. 10caaa0f36SShubhrajyoti D * 11caaa0f36SShubhrajyoti D * This program is distributed in the hope that it will be useful, 12caaa0f36SShubhrajyoti D * but WITHOUT ANY WARRANTY; without even the implied warranty of 13caaa0f36SShubhrajyoti D * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14caaa0f36SShubhrajyoti D * GNU General Public License for more details. 15caaa0f36SShubhrajyoti D * 16caaa0f36SShubhrajyoti D * You should have received a copy of the GNU General Public License 17caaa0f36SShubhrajyoti D * along with this program; if not, write to the Free Software 18caaa0f36SShubhrajyoti D * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 198d5d45fbSJean Delvare */ 208d5d45fbSJean Delvare 218d5d45fbSJean Delvare #include <linux/module.h> 228d5d45fbSJean Delvare #include <linux/init.h> 238d5d45fbSJean Delvare #include <linux/slab.h> 248d5d45fbSJean Delvare #include <linux/jiffies.h> 258d5d45fbSJean Delvare #include <linux/i2c.h> 26943b0830SMark M. Hoffman #include <linux/hwmon.h> 279ca8e40cSJean Delvare #include <linux/hwmon-sysfs.h> 28943b0830SMark M. Hoffman #include <linux/err.h> 299a61bf63SIngo Molnar #include <linux/mutex.h> 3022e73183SEduardo Valentin #include <linux/of.h> 3122e73183SEduardo Valentin #include <linux/thermal.h> 328d5d45fbSJean Delvare #include "lm75.h" 338d5d45fbSJean Delvare 348d5d45fbSJean Delvare 3501a52397SDavid Brownell /* 3601a52397SDavid Brownell * This driver handles the LM75 and compatible digital temperature sensors. 3701a52397SDavid Brownell */ 3801a52397SDavid Brownell 399ebd3d82SDavid Brownell enum lm75_type { /* keep sorted in alphabetical order */ 40e96f9d89SMichael Hennerich adt75, 411f86df49SJean Delvare ds1775, 429ebd3d82SDavid Brownell ds75, 433fbc81e3SJean Delvare ds7505, 44c98d6c65SArnaud Ebalard g751, 451f86df49SJean Delvare lm75, 469ebd3d82SDavid Brownell lm75a, 479ebd3d82SDavid Brownell max6625, 489ebd3d82SDavid Brownell max6626, 499ebd3d82SDavid Brownell mcp980x, 509ebd3d82SDavid Brownell stds75, 519ebd3d82SDavid Brownell tcn75, 529ebd3d82SDavid Brownell tmp100, 539ebd3d82SDavid Brownell tmp101, 546d034059SShubhrajyoti Datta tmp105, 559ebd3d82SDavid Brownell tmp175, 569ebd3d82SDavid Brownell tmp275, 579ebd3d82SDavid Brownell tmp75, 589ebd3d82SDavid Brownell }; 599ebd3d82SDavid Brownell 608ff69eebSJean Delvare /* Addresses scanned */ 6125e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 628d5d45fbSJean Delvare 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 638d5d45fbSJean Delvare 648d5d45fbSJean Delvare 658d5d45fbSJean Delvare /* The LM75 registers */ 668d5d45fbSJean Delvare #define LM75_REG_CONF 0x01 679ca8e40cSJean Delvare static const u8 LM75_REG_TEMP[3] = { 689ca8e40cSJean Delvare 0x00, /* input */ 699ca8e40cSJean Delvare 0x03, /* max */ 709ca8e40cSJean Delvare 0x02, /* hyst */ 719ca8e40cSJean Delvare }; 728d5d45fbSJean Delvare 738d5d45fbSJean Delvare /* Each client has this additional data */ 748d5d45fbSJean Delvare struct lm75_data { 751beeffe4STony Jones struct device *hwmon_dev; 7622e73183SEduardo Valentin struct thermal_zone_device *tz; 779a61bf63SIngo Molnar struct mutex update_lock; 789ebd3d82SDavid Brownell u8 orig_conf; 7987d0621aSJean Delvare u8 resolution; /* In bits, between 9 and 12 */ 8087d0621aSJean Delvare u8 resolution_limits; 8101a52397SDavid Brownell char valid; /* !=0 if registers are valid */ 828d5d45fbSJean Delvare unsigned long last_updated; /* In jiffies */ 8387d0621aSJean Delvare unsigned long sample_time; /* In jiffies */ 8487d0621aSJean Delvare s16 temp[3]; /* Register values, 859ca8e40cSJean Delvare 0 = input 869ca8e40cSJean Delvare 1 = max 879ca8e40cSJean Delvare 2 = hyst */ 888d5d45fbSJean Delvare }; 898d5d45fbSJean Delvare 908d5d45fbSJean Delvare static int lm75_read_value(struct i2c_client *client, u8 reg); 918d5d45fbSJean Delvare static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); 928d5d45fbSJean Delvare static struct lm75_data *lm75_update_device(struct device *dev); 938d5d45fbSJean Delvare 948d5d45fbSJean Delvare 9501a52397SDavid Brownell /*-----------------------------------------------------------------------*/ 9601a52397SDavid Brownell 9722e73183SEduardo Valentin static inline long lm75_reg_to_mc(s16 temp, u8 resolution) 9822e73183SEduardo Valentin { 9922e73183SEduardo Valentin return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); 10022e73183SEduardo Valentin } 10122e73183SEduardo Valentin 10201a52397SDavid Brownell /* sysfs attributes for hwmon */ 1038d5d45fbSJean Delvare 10422e73183SEduardo Valentin static int lm75_read_temp(void *dev, long *temp) 10522e73183SEduardo Valentin { 10622e73183SEduardo Valentin struct lm75_data *data = lm75_update_device(dev); 10722e73183SEduardo Valentin 10822e73183SEduardo Valentin if (IS_ERR(data)) 10922e73183SEduardo Valentin return PTR_ERR(data); 11022e73183SEduardo Valentin 11122e73183SEduardo Valentin *temp = lm75_reg_to_mc(data->temp[0], data->resolution); 11222e73183SEduardo Valentin 11322e73183SEduardo Valentin return 0; 11422e73183SEduardo Valentin } 11522e73183SEduardo Valentin 1169ca8e40cSJean Delvare static ssize_t show_temp(struct device *dev, struct device_attribute *da, 1179ca8e40cSJean Delvare char *buf) 1189ca8e40cSJean Delvare { 1199ca8e40cSJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 1209ca8e40cSJean Delvare struct lm75_data *data = lm75_update_device(dev); 1211f962f36SFrans Meulenbroeks 1221f962f36SFrans Meulenbroeks if (IS_ERR(data)) 1231f962f36SFrans Meulenbroeks return PTR_ERR(data); 1241f962f36SFrans Meulenbroeks 12522e73183SEduardo Valentin return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index], 12622e73183SEduardo Valentin data->resolution)); 1278d5d45fbSJean Delvare } 1288d5d45fbSJean Delvare 1299ca8e40cSJean Delvare static ssize_t set_temp(struct device *dev, struct device_attribute *da, 1309ca8e40cSJean Delvare const char *buf, size_t count) 1319ca8e40cSJean Delvare { 1329ca8e40cSJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 1339ca8e40cSJean Delvare struct i2c_client *client = to_i2c_client(dev); 1349ca8e40cSJean Delvare struct lm75_data *data = i2c_get_clientdata(client); 1359ca8e40cSJean Delvare int nr = attr->index; 136e3cd9528SShubhrajyoti D long temp; 137e3cd9528SShubhrajyoti D int error; 13887d0621aSJean Delvare u8 resolution; 139e3cd9528SShubhrajyoti D 14024edc0a7SFrans Meulenbroeks error = kstrtol(buf, 10, &temp); 141e3cd9528SShubhrajyoti D if (error) 142e3cd9528SShubhrajyoti D return error; 1439ca8e40cSJean Delvare 14487d0621aSJean Delvare /* 14587d0621aSJean Delvare * Resolution of limit registers is assumed to be the same as the 14687d0621aSJean Delvare * temperature input register resolution unless given explicitly. 14787d0621aSJean Delvare */ 14887d0621aSJean Delvare if (attr->index && data->resolution_limits) 14987d0621aSJean Delvare resolution = data->resolution_limits; 15087d0621aSJean Delvare else 15187d0621aSJean Delvare resolution = data->resolution; 15287d0621aSJean Delvare 1539ca8e40cSJean Delvare mutex_lock(&data->update_lock); 15487d0621aSJean Delvare temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); 15587d0621aSJean Delvare data->temp[nr] = DIV_ROUND_CLOSEST(temp << (resolution - 8), 15687d0621aSJean Delvare 1000) << (16 - resolution); 1579ca8e40cSJean Delvare lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); 1589ca8e40cSJean Delvare mutex_unlock(&data->update_lock); 1599ca8e40cSJean Delvare return count; 1608d5d45fbSJean Delvare } 1618d5d45fbSJean Delvare 1629ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, 1639ca8e40cSJean Delvare show_temp, set_temp, 1); 1649ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, 1659ca8e40cSJean Delvare show_temp, set_temp, 2); 1669ca8e40cSJean Delvare static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 1678d5d45fbSJean Delvare 168c1685f61SMark M. Hoffman static struct attribute *lm75_attributes[] = { 1699ca8e40cSJean Delvare &sensor_dev_attr_temp1_input.dev_attr.attr, 1709ca8e40cSJean Delvare &sensor_dev_attr_temp1_max.dev_attr.attr, 1719ca8e40cSJean Delvare &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, 172c1685f61SMark M. Hoffman 173c1685f61SMark M. Hoffman NULL 174c1685f61SMark M. Hoffman }; 175c1685f61SMark M. Hoffman 176c1685f61SMark M. Hoffman static const struct attribute_group lm75_group = { 177c1685f61SMark M. Hoffman .attrs = lm75_attributes, 178c1685f61SMark M. Hoffman }; 179c1685f61SMark M. Hoffman 18001a52397SDavid Brownell /*-----------------------------------------------------------------------*/ 18101a52397SDavid Brownell 1828ff69eebSJean Delvare /* device probe and removal */ 1839ebd3d82SDavid Brownell 1849ebd3d82SDavid Brownell static int 1859ebd3d82SDavid Brownell lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) 1869ebd3d82SDavid Brownell { 1879ebd3d82SDavid Brownell struct lm75_data *data; 1889ebd3d82SDavid Brownell int status; 1899ebd3d82SDavid Brownell u8 set_mask, clr_mask; 1909ebd3d82SDavid Brownell int new; 1910cd2c72dSJean Delvare enum lm75_type kind = id->driver_data; 1929ebd3d82SDavid Brownell 1939ebd3d82SDavid Brownell if (!i2c_check_functionality(client->adapter, 1949ebd3d82SDavid Brownell I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) 1959ebd3d82SDavid Brownell return -EIO; 1969ebd3d82SDavid Brownell 19713ac7a01SGuenter Roeck data = devm_kzalloc(&client->dev, sizeof(struct lm75_data), GFP_KERNEL); 1989ebd3d82SDavid Brownell if (!data) 1999ebd3d82SDavid Brownell return -ENOMEM; 2009ebd3d82SDavid Brownell 2019ebd3d82SDavid Brownell i2c_set_clientdata(client, data); 2029ebd3d82SDavid Brownell mutex_init(&data->update_lock); 2039ebd3d82SDavid Brownell 2049ebd3d82SDavid Brownell /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. 2059ebd3d82SDavid Brownell * Then tweak to be more precise when appropriate. 2069ebd3d82SDavid Brownell */ 2079ebd3d82SDavid Brownell set_mask = 0; 2088a5c5cc6SJean Delvare clr_mask = LM75_SHUTDOWN; /* continuous conversions */ 2098a5c5cc6SJean Delvare 2100cd2c72dSJean Delvare switch (kind) { 2118a5c5cc6SJean Delvare case adt75: 2128a5c5cc6SJean Delvare clr_mask |= 1 << 5; /* not one-shot mode */ 2130cd2c72dSJean Delvare data->resolution = 12; 2140cd2c72dSJean Delvare data->sample_time = HZ / 8; 2158a5c5cc6SJean Delvare break; 2168a5c5cc6SJean Delvare case ds1775: 2178a5c5cc6SJean Delvare case ds75: 2188a5c5cc6SJean Delvare case stds75: 2190cd2c72dSJean Delvare clr_mask |= 3 << 5; 2200cd2c72dSJean Delvare set_mask |= 2 << 5; /* 11-bit mode */ 2210cd2c72dSJean Delvare data->resolution = 11; 2220cd2c72dSJean Delvare data->sample_time = HZ; 2230cd2c72dSJean Delvare break; 2243fbc81e3SJean Delvare case ds7505: 2253fbc81e3SJean Delvare set_mask |= 3 << 5; /* 12-bit mode */ 2263fbc81e3SJean Delvare data->resolution = 12; 2273fbc81e3SJean Delvare data->sample_time = HZ / 4; 2283fbc81e3SJean Delvare break; 229c98d6c65SArnaud Ebalard case g751: 2300cd2c72dSJean Delvare case lm75: 2310cd2c72dSJean Delvare case lm75a: 2320cd2c72dSJean Delvare data->resolution = 9; 2330cd2c72dSJean Delvare data->sample_time = HZ / 2; 2340cd2c72dSJean Delvare break; 2350cd2c72dSJean Delvare case max6625: 2360cd2c72dSJean Delvare data->resolution = 9; 2370cd2c72dSJean Delvare data->sample_time = HZ / 4; 2380cd2c72dSJean Delvare break; 2390cd2c72dSJean Delvare case max6626: 2400cd2c72dSJean Delvare data->resolution = 12; 2410cd2c72dSJean Delvare data->resolution_limits = 9; 2420cd2c72dSJean Delvare data->sample_time = HZ / 4; 2430cd2c72dSJean Delvare break; 2440cd2c72dSJean Delvare case tcn75: 2450cd2c72dSJean Delvare data->resolution = 9; 2460cd2c72dSJean Delvare data->sample_time = HZ / 8; 2478a5c5cc6SJean Delvare break; 2488a5c5cc6SJean Delvare case mcp980x: 2490cd2c72dSJean Delvare data->resolution_limits = 9; 2500cd2c72dSJean Delvare /* fall through */ 2518a5c5cc6SJean Delvare case tmp100: 2528a5c5cc6SJean Delvare case tmp101: 2530cd2c72dSJean Delvare set_mask |= 3 << 5; /* 12-bit mode */ 2540cd2c72dSJean Delvare data->resolution = 12; 2550cd2c72dSJean Delvare data->sample_time = HZ; 2560cd2c72dSJean Delvare clr_mask |= 1 << 7; /* not one-shot mode */ 2570cd2c72dSJean Delvare break; 2588a5c5cc6SJean Delvare case tmp105: 2598a5c5cc6SJean Delvare case tmp175: 2608a5c5cc6SJean Delvare case tmp275: 2618a5c5cc6SJean Delvare case tmp75: 2620cd2c72dSJean Delvare set_mask |= 3 << 5; /* 12-bit mode */ 2638a5c5cc6SJean Delvare clr_mask |= 1 << 7; /* not one-shot mode */ 2640cd2c72dSJean Delvare data->resolution = 12; 2650cd2c72dSJean Delvare data->sample_time = HZ / 2; 2668a5c5cc6SJean Delvare break; 2678a5c5cc6SJean Delvare } 2689ebd3d82SDavid Brownell 2699ebd3d82SDavid Brownell /* configure as specified */ 2709ebd3d82SDavid Brownell status = lm75_read_value(client, LM75_REG_CONF); 2719ebd3d82SDavid Brownell if (status < 0) { 2729ebd3d82SDavid Brownell dev_dbg(&client->dev, "Can't read config? %d\n", status); 27313ac7a01SGuenter Roeck return status; 2749ebd3d82SDavid Brownell } 2759ebd3d82SDavid Brownell data->orig_conf = status; 2769ebd3d82SDavid Brownell new = status & ~clr_mask; 2779ebd3d82SDavid Brownell new |= set_mask; 2789ebd3d82SDavid Brownell if (status != new) 2799ebd3d82SDavid Brownell lm75_write_value(client, LM75_REG_CONF, new); 2809ebd3d82SDavid Brownell dev_dbg(&client->dev, "Config %02x\n", new); 2819ebd3d82SDavid Brownell 2829ebd3d82SDavid Brownell /* Register sysfs hooks */ 2839ebd3d82SDavid Brownell status = sysfs_create_group(&client->dev.kobj, &lm75_group); 2849ebd3d82SDavid Brownell if (status) 28513ac7a01SGuenter Roeck return status; 2869ebd3d82SDavid Brownell 2879ebd3d82SDavid Brownell data->hwmon_dev = hwmon_device_register(&client->dev); 2889ebd3d82SDavid Brownell if (IS_ERR(data->hwmon_dev)) { 2899ebd3d82SDavid Brownell status = PTR_ERR(data->hwmon_dev); 2909ebd3d82SDavid Brownell goto exit_remove; 2919ebd3d82SDavid Brownell } 2929ebd3d82SDavid Brownell 29322e73183SEduardo Valentin data->tz = thermal_zone_of_sensor_register(&client->dev, 29422e73183SEduardo Valentin 0, 29522e73183SEduardo Valentin &client->dev, 29622e73183SEduardo Valentin lm75_read_temp, NULL); 29722e73183SEduardo Valentin if (IS_ERR(data->tz)) 29822e73183SEduardo Valentin data->tz = NULL; 29922e73183SEduardo Valentin 3009ebd3d82SDavid Brownell dev_info(&client->dev, "%s: sensor '%s'\n", 301739cf3a2SKay Sievers dev_name(data->hwmon_dev), client->name); 3029ebd3d82SDavid Brownell 3039ebd3d82SDavid Brownell return 0; 3049ebd3d82SDavid Brownell 3059ebd3d82SDavid Brownell exit_remove: 3069ebd3d82SDavid Brownell sysfs_remove_group(&client->dev.kobj, &lm75_group); 3079ebd3d82SDavid Brownell return status; 3089ebd3d82SDavid Brownell } 3099ebd3d82SDavid Brownell 3109ebd3d82SDavid Brownell static int lm75_remove(struct i2c_client *client) 3119ebd3d82SDavid Brownell { 3129ebd3d82SDavid Brownell struct lm75_data *data = i2c_get_clientdata(client); 3139ebd3d82SDavid Brownell 31422e73183SEduardo Valentin thermal_zone_of_sensor_unregister(&client->dev, data->tz); 3159ebd3d82SDavid Brownell hwmon_device_unregister(data->hwmon_dev); 3169ebd3d82SDavid Brownell sysfs_remove_group(&client->dev.kobj, &lm75_group); 3179ebd3d82SDavid Brownell lm75_write_value(client, LM75_REG_CONF, data->orig_conf); 3189ebd3d82SDavid Brownell return 0; 3199ebd3d82SDavid Brownell } 3209ebd3d82SDavid Brownell 3219ebd3d82SDavid Brownell static const struct i2c_device_id lm75_ids[] = { 322e96f9d89SMichael Hennerich { "adt75", adt75, }, 3239ebd3d82SDavid Brownell { "ds1775", ds1775, }, 3249ebd3d82SDavid Brownell { "ds75", ds75, }, 3253fbc81e3SJean Delvare { "ds7505", ds7505, }, 326c98d6c65SArnaud Ebalard { "g751", g751, }, 3279ebd3d82SDavid Brownell { "lm75", lm75, }, 3289ebd3d82SDavid Brownell { "lm75a", lm75a, }, 3299ebd3d82SDavid Brownell { "max6625", max6625, }, 3309ebd3d82SDavid Brownell { "max6626", max6626, }, 3319ebd3d82SDavid Brownell { "mcp980x", mcp980x, }, 3329ebd3d82SDavid Brownell { "stds75", stds75, }, 3339ebd3d82SDavid Brownell { "tcn75", tcn75, }, 3349ebd3d82SDavid Brownell { "tmp100", tmp100, }, 3359ebd3d82SDavid Brownell { "tmp101", tmp101, }, 3366d034059SShubhrajyoti Datta { "tmp105", tmp105, }, 3379ebd3d82SDavid Brownell { "tmp175", tmp175, }, 3389ebd3d82SDavid Brownell { "tmp275", tmp275, }, 3399ebd3d82SDavid Brownell { "tmp75", tmp75, }, 3409ebd3d82SDavid Brownell { /* LIST END */ } 3419ebd3d82SDavid Brownell }; 3429ebd3d82SDavid Brownell MODULE_DEVICE_TABLE(i2c, lm75_ids); 3439ebd3d82SDavid Brownell 34405e82fe4SLen Sorensen #define LM75A_ID 0xA1 34505e82fe4SLen Sorensen 3468ff69eebSJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */ 347310ec792SJean Delvare static int lm75_detect(struct i2c_client *new_client, 3488ff69eebSJean Delvare struct i2c_board_info *info) 3498d5d45fbSJean Delvare { 3508ff69eebSJean Delvare struct i2c_adapter *adapter = new_client->adapter; 3518d5d45fbSJean Delvare int i; 352e76f67b5SJean Delvare int conf, hyst, os; 35305e82fe4SLen Sorensen bool is_lm75a = 0; 3548d5d45fbSJean Delvare 3558d5d45fbSJean Delvare if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 3568d5d45fbSJean Delvare I2C_FUNC_SMBUS_WORD_DATA)) 3578ff69eebSJean Delvare return -ENODEV; 3588d5d45fbSJean Delvare 359426343efSJean Delvare /* 360426343efSJean Delvare * Now, we do the remaining detection. There is no identification- 361426343efSJean Delvare * dedicated register so we have to rely on several tricks: 362426343efSJean Delvare * unused bits, registers cycling over 8-address boundaries, 363426343efSJean Delvare * addresses 0x04-0x07 returning the last read value. 364426343efSJean Delvare * The cycling+unused addresses combination is not tested, 365426343efSJean Delvare * since it would significantly slow the detection down and would 366426343efSJean Delvare * hardly add any value. 367426343efSJean Delvare * 368426343efSJean Delvare * The National Semiconductor LM75A is different than earlier 369426343efSJean Delvare * LM75s. It has an ID byte of 0xaX (where X is the chip 370426343efSJean Delvare * revision, with 1 being the only revision in existence) in 371426343efSJean Delvare * register 7, and unused registers return 0xff rather than the 372426343efSJean Delvare * last read value. 373426343efSJean Delvare * 374426343efSJean Delvare * Note that this function only detects the original National 375426343efSJean Delvare * Semiconductor LM75 and the LM75A. Clones from other vendors 376426343efSJean Delvare * aren't detected, on purpose, because they are typically never 377426343efSJean Delvare * found on PC hardware. They are found on embedded designs where 378426343efSJean Delvare * they can be instantiated explicitly so detection is not needed. 379426343efSJean Delvare * The absence of identification registers on all these clones 380426343efSJean Delvare * would make their exhaustive detection very difficult and weak, 381426343efSJean Delvare * and odds are that the driver would bind to unsupported devices. 382426343efSJean Delvare */ 38305e82fe4SLen Sorensen 384e76f67b5SJean Delvare /* Unused bits */ 3858d5d45fbSJean Delvare conf = i2c_smbus_read_byte_data(new_client, 1); 386e76f67b5SJean Delvare if (conf & 0xe0) 387e76f67b5SJean Delvare return -ENODEV; 38805e82fe4SLen Sorensen 38905e82fe4SLen Sorensen /* First check for LM75A */ 39005e82fe4SLen Sorensen if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { 39105e82fe4SLen Sorensen /* LM75A returns 0xff on unused registers so 39205e82fe4SLen Sorensen just to be sure we check for that too. */ 39305e82fe4SLen Sorensen if (i2c_smbus_read_byte_data(new_client, 4) != 0xff 39405e82fe4SLen Sorensen || i2c_smbus_read_byte_data(new_client, 5) != 0xff 39505e82fe4SLen Sorensen || i2c_smbus_read_byte_data(new_client, 6) != 0xff) 39605e82fe4SLen Sorensen return -ENODEV; 39705e82fe4SLen Sorensen is_lm75a = 1; 398e76f67b5SJean Delvare hyst = i2c_smbus_read_byte_data(new_client, 2); 399e76f67b5SJean Delvare os = i2c_smbus_read_byte_data(new_client, 3); 40005e82fe4SLen Sorensen } else { /* Traditional style LM75 detection */ 40105e82fe4SLen Sorensen /* Unused addresses */ 402e76f67b5SJean Delvare hyst = i2c_smbus_read_byte_data(new_client, 2); 403e76f67b5SJean Delvare if (i2c_smbus_read_byte_data(new_client, 4) != hyst 404e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 5) != hyst 405e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 6) != hyst 406e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 7) != hyst) 4078ff69eebSJean Delvare return -ENODEV; 408e76f67b5SJean Delvare os = i2c_smbus_read_byte_data(new_client, 3); 409e76f67b5SJean Delvare if (i2c_smbus_read_byte_data(new_client, 4) != os 410e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 5) != os 411e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 6) != os 412e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 7) != os) 4138ff69eebSJean Delvare return -ENODEV; 41405e82fe4SLen Sorensen } 4158d5d45fbSJean Delvare 4168d5d45fbSJean Delvare /* Addresses cycling */ 417e76f67b5SJean Delvare for (i = 8; i <= 248; i += 40) { 4188d5d45fbSJean Delvare if (i2c_smbus_read_byte_data(new_client, i + 1) != conf 419e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, i + 2) != hyst 420e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, i + 3) != os) 4218ff69eebSJean Delvare return -ENODEV; 42205e82fe4SLen Sorensen if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) 42305e82fe4SLen Sorensen != LM75A_ID) 42405e82fe4SLen Sorensen return -ENODEV; 4258d5d45fbSJean Delvare } 4268d5d45fbSJean Delvare 42705e82fe4SLen Sorensen strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); 4288d5d45fbSJean Delvare 4298d5d45fbSJean Delvare return 0; 4308d5d45fbSJean Delvare } 4318d5d45fbSJean Delvare 4329914518eSShubhrajyoti Datta #ifdef CONFIG_PM 4339914518eSShubhrajyoti Datta static int lm75_suspend(struct device *dev) 4349914518eSShubhrajyoti Datta { 4359914518eSShubhrajyoti Datta int status; 4369914518eSShubhrajyoti Datta struct i2c_client *client = to_i2c_client(dev); 4379914518eSShubhrajyoti Datta status = lm75_read_value(client, LM75_REG_CONF); 4389914518eSShubhrajyoti Datta if (status < 0) { 4399914518eSShubhrajyoti Datta dev_dbg(&client->dev, "Can't read config? %d\n", status); 4409914518eSShubhrajyoti Datta return status; 4419914518eSShubhrajyoti Datta } 4429914518eSShubhrajyoti Datta status = status | LM75_SHUTDOWN; 4439914518eSShubhrajyoti Datta lm75_write_value(client, LM75_REG_CONF, status); 4449914518eSShubhrajyoti Datta return 0; 4459914518eSShubhrajyoti Datta } 4469914518eSShubhrajyoti Datta 4479914518eSShubhrajyoti Datta static int lm75_resume(struct device *dev) 4489914518eSShubhrajyoti Datta { 4499914518eSShubhrajyoti Datta int status; 4509914518eSShubhrajyoti Datta struct i2c_client *client = to_i2c_client(dev); 4519914518eSShubhrajyoti Datta status = lm75_read_value(client, LM75_REG_CONF); 4529914518eSShubhrajyoti Datta if (status < 0) { 4539914518eSShubhrajyoti Datta dev_dbg(&client->dev, "Can't read config? %d\n", status); 4549914518eSShubhrajyoti Datta return status; 4559914518eSShubhrajyoti Datta } 4569914518eSShubhrajyoti Datta status = status & ~LM75_SHUTDOWN; 4579914518eSShubhrajyoti Datta lm75_write_value(client, LM75_REG_CONF, status); 4589914518eSShubhrajyoti Datta return 0; 4599914518eSShubhrajyoti Datta } 4609914518eSShubhrajyoti Datta 4619914518eSShubhrajyoti Datta static const struct dev_pm_ops lm75_dev_pm_ops = { 4629914518eSShubhrajyoti Datta .suspend = lm75_suspend, 4639914518eSShubhrajyoti Datta .resume = lm75_resume, 4649914518eSShubhrajyoti Datta }; 4659914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) 4669914518eSShubhrajyoti Datta #else 4679914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS NULL 4689914518eSShubhrajyoti Datta #endif /* CONFIG_PM */ 4699914518eSShubhrajyoti Datta 4708ff69eebSJean Delvare static struct i2c_driver lm75_driver = { 4718ff69eebSJean Delvare .class = I2C_CLASS_HWMON, 47201a52397SDavid Brownell .driver = { 4738ff69eebSJean Delvare .name = "lm75", 4749914518eSShubhrajyoti Datta .pm = LM75_DEV_PM_OPS, 47501a52397SDavid Brownell }, 4768ff69eebSJean Delvare .probe = lm75_probe, 4778ff69eebSJean Delvare .remove = lm75_remove, 4788ff69eebSJean Delvare .id_table = lm75_ids, 4798ff69eebSJean Delvare .detect = lm75_detect, 480c3813d6aSJean Delvare .address_list = normal_i2c, 48101a52397SDavid Brownell }; 48201a52397SDavid Brownell 48301a52397SDavid Brownell /*-----------------------------------------------------------------------*/ 48401a52397SDavid Brownell 48501a52397SDavid Brownell /* register access */ 48601a52397SDavid Brownell 487caaa0f36SShubhrajyoti D /* 488caaa0f36SShubhrajyoti D * All registers are word-sized, except for the configuration register. 489caaa0f36SShubhrajyoti D * LM75 uses a high-byte first convention, which is exactly opposite to 490caaa0f36SShubhrajyoti D * the SMBus standard. 491caaa0f36SShubhrajyoti D */ 4928d5d45fbSJean Delvare static int lm75_read_value(struct i2c_client *client, u8 reg) 4938d5d45fbSJean Delvare { 4948d5d45fbSJean Delvare if (reg == LM75_REG_CONF) 4958d5d45fbSJean Delvare return i2c_smbus_read_byte_data(client, reg); 49690f4102cSJean Delvare else 49790f4102cSJean Delvare return i2c_smbus_read_word_swapped(client, reg); 4988d5d45fbSJean Delvare } 4998d5d45fbSJean Delvare 5008d5d45fbSJean Delvare static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) 5018d5d45fbSJean Delvare { 5028d5d45fbSJean Delvare if (reg == LM75_REG_CONF) 5038d5d45fbSJean Delvare return i2c_smbus_write_byte_data(client, reg, value); 5048d5d45fbSJean Delvare else 50590f4102cSJean Delvare return i2c_smbus_write_word_swapped(client, reg, value); 5068d5d45fbSJean Delvare } 5078d5d45fbSJean Delvare 5088d5d45fbSJean Delvare static struct lm75_data *lm75_update_device(struct device *dev) 5098d5d45fbSJean Delvare { 5108d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 5118d5d45fbSJean Delvare struct lm75_data *data = i2c_get_clientdata(client); 5121f962f36SFrans Meulenbroeks struct lm75_data *ret = data; 5138d5d45fbSJean Delvare 5149a61bf63SIngo Molnar mutex_lock(&data->update_lock); 5158d5d45fbSJean Delvare 51687d0621aSJean Delvare if (time_after(jiffies, data->last_updated + data->sample_time) 5178d5d45fbSJean Delvare || !data->valid) { 5189ca8e40cSJean Delvare int i; 5198d5d45fbSJean Delvare dev_dbg(&client->dev, "Starting lm75 update\n"); 5208d5d45fbSJean Delvare 521bcccc3a2SDavid Brownell for (i = 0; i < ARRAY_SIZE(data->temp); i++) { 522bcccc3a2SDavid Brownell int status; 523bcccc3a2SDavid Brownell 524bcccc3a2SDavid Brownell status = lm75_read_value(client, LM75_REG_TEMP[i]); 5251f962f36SFrans Meulenbroeks if (unlikely(status < 0)) { 5261f962f36SFrans Meulenbroeks dev_dbg(dev, 5271f962f36SFrans Meulenbroeks "LM75: Failed to read value: reg %d, error %d\n", 528bcccc3a2SDavid Brownell LM75_REG_TEMP[i], status); 5291f962f36SFrans Meulenbroeks ret = ERR_PTR(status); 5301f962f36SFrans Meulenbroeks data->valid = 0; 5311f962f36SFrans Meulenbroeks goto abort; 5321f962f36SFrans Meulenbroeks } 533bcccc3a2SDavid Brownell data->temp[i] = status; 534bcccc3a2SDavid Brownell } 5358d5d45fbSJean Delvare data->last_updated = jiffies; 5368d5d45fbSJean Delvare data->valid = 1; 5378d5d45fbSJean Delvare } 5388d5d45fbSJean Delvare 5391f962f36SFrans Meulenbroeks abort: 5409a61bf63SIngo Molnar mutex_unlock(&data->update_lock); 5411f962f36SFrans Meulenbroeks return ret; 5428d5d45fbSJean Delvare } 5438d5d45fbSJean Delvare 544f0967eeaSAxel Lin module_i2c_driver(lm75_driver); 5458d5d45fbSJean Delvare 5468d5d45fbSJean Delvare MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); 5478d5d45fbSJean Delvare MODULE_DESCRIPTION("LM75 driver"); 5488d5d45fbSJean Delvare MODULE_LICENSE("GPL"); 549