11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * lm90.c - Part of lm_sensors, Linux kernel modules for hardware 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * monitoring 495238364167edaf93ce2890e5f55326b63194851Jean Delvare * Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Based on the lm83 driver. The LM90 is a sensor chip made by National 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Semiconductor. It reports up to two temperatures (its own plus up to 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * one external one) with a 0.125 deg resolution (1 deg for local 9a874a10cf0b7105ae5eeb98b4860eae0fc78fcddJean Delvare * temperature) and a 3-4 deg accuracy. 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This driver also supports the LM89 and LM99, two other sensor chips 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * made by National Semiconductor. Both have an increased remote 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * temperature measurement accuracy (1 degree), and the LM99 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * additionally shifts remote temperatures (measured and limits) by 16 1597ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare * degrees, which allows for higher temperatures measurement. 1644bbe87e9017efa050bb1b506c6822f1f3bb94d7Steven Cole * Note that there is no way to differentiate between both chips. 1797ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare * When device is auto-detected, the driver will assume an LM99. 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This driver also supports the LM86, another sensor chip made by 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * National Semiconductor. It is exactly similar to the LM90 except it 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * has a higher accuracy. 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This driver also supports the ADM1032, a sensor chip made by Analog 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Devices. That chip is similar to the LM90, with a few differences 25a874a10cf0b7105ae5eeb98b4860eae0fc78fcddJean Delvare * that are not handled by this driver. Among others, it has a higher 26a874a10cf0b7105ae5eeb98b4860eae0fc78fcddJean Delvare * accuracy than the LM90, much like the LM86 does. 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This driver also supports the MAX6657, MAX6658 and MAX6659 sensor 29a874a10cf0b7105ae5eeb98b4860eae0fc78fcddJean Delvare * chips made by Maxim. These chips are similar to the LM86. 3044bbe87e9017efa050bb1b506c6822f1f3bb94d7Steven Cole * Note that there is no easy way to differentiate between the three 316948708dd07573c578aa99f80915cd1867334abeGuenter Roeck * variants. We use the device address to detect MAX6659, which will result 326948708dd07573c578aa99f80915cd1867334abeGuenter Roeck * in a detection as max6657 if it is on address 0x4c. The extra address 336948708dd07573c578aa99f80915cd1867334abeGuenter Roeck * and features of the MAX6659 are only supported if the chip is configured 346948708dd07573c578aa99f80915cd1867334abeGuenter Roeck * explicitly as max6659, or if its address is not 0x4c. 356948708dd07573c578aa99f80915cd1867334abeGuenter Roeck * These chips lack the remote temperature offset feature. 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 371a51e068c900eb6ea23ce597361ebf3b19a57b23Darrick J. Wong * This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and 381a51e068c900eb6ea23ce597361ebf3b19a57b23Darrick J. Wong * MAX6692 chips made by Maxim. These are again similar to the LM86, 391a51e068c900eb6ea23ce597361ebf3b19a57b23Darrick J. Wong * but they use unsigned temperature values and can report temperatures 401a51e068c900eb6ea23ce597361ebf3b19a57b23Darrick J. Wong * from 0 to 145 degrees. 41271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings * 4232c82a934759b2c9939c9e25865c2d7d1204b9e8Rainer Birkenmaier * This driver also supports the MAX6680 and MAX6681, two other sensor 4332c82a934759b2c9939c9e25865c2d7d1204b9e8Rainer Birkenmaier * chips made by Maxim. These are quite similar to the other Maxim 44a874a10cf0b7105ae5eeb98b4860eae0fc78fcddJean Delvare * chips. The MAX6680 and MAX6681 only differ in the pinout so they can 45a874a10cf0b7105ae5eeb98b4860eae0fc78fcddJean Delvare * be treated identically. 4632c82a934759b2c9939c9e25865c2d7d1204b9e8Rainer Birkenmaier * 4706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * This driver also supports the MAX6695 and MAX6696, two other sensor 4806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * chips made by Maxim. These are also quite similar to other Maxim 4906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * chips, but support three temperature sensors instead of two. MAX6695 5006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * and MAX6696 only differ in the pinout so they can be treated identically. 5106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * 525a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck * This driver also supports ADT7461 and ADT7461A from Analog Devices as well as 535a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck * NCT1008 from ON Semiconductor. The chips are supported in both compatibility 545a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck * and extended mode. They are mostly compatible with LM90 except for a data 555a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck * format difference for the temperature value registers. 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 572ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt * This driver also supports the SA56004 from Philips. This device is 582ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt * pin-compatible with the LM86, the ED/EDP parts are also address-compatible. 592ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt * 60ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck * This driver also supports the G781 from GMT. This device is compatible 61ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck * with the ADM1032. 62ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck * 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Since the LM90 was the first chipset supported by this driver, most 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * comments will refer to this chipset, but are actually general and 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * concern all supported chipsets, unless mentioned otherwise. 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (at your option) any later version. 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details. 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/jiffies.h> 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c.h> 8710c08f8100ee2c4d27b862635574cdf4ef439e67Jean Delvare#include <linux/hwmon-sysfs.h> 88943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/hwmon.h> 89943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/err.h> 909a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar#include <linux/mutex.h> 910e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare#include <linux/sysfs.h> 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Addresses to scan 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Address is fully defined internally and cannot be changed except for 9632c82a934759b2c9939c9e25865c2d7d1204b9e8Rainer Birkenmaier * MAX6659, MAX6680 and MAX6681. 975a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, ADT7461A, MAX6649, 985a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck * MAX6657, MAX6658, NCT1008 and W83L771 have address 0x4c. 995a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck * ADM1032-2, ADT7461-2, ADT7461A-2, LM89-1, LM99-1, MAX6646, and NCT1008D 1005a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck * have address 0x4d. 101271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings * MAX6647 has address 0x4e. 10213c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck * MAX6659 can have address 0x4c, 0x4d or 0x4e. 10332c82a934759b2c9939c9e25865c2d7d1204b9e8Rainer Birkenmaier * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 10432c82a934759b2c9939c9e25865c2d7d1204b9e8Rainer Birkenmaier * 0x4c, 0x4d or 0x4e. 1052ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt * SA56004 can have address 0x48 through 0x4F. 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10825e9c86d5a6d82ea45eb680fc66bf73ac5e50dffMark M. Hoffmanstatic const unsigned short normal_i2c[] = { 1092ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 1102ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11213c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeckenum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, 113ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck max6646, w83l771, max6696, sa56004, g781 }; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The LM90 registers 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_MAN_ID 0xFE 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_CHIP_ID 0xFF 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_CONFIG1 0x03 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_CONFIG1 0x09 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_CONFIG2 0xBF 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_CONFIG2 0xBF 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_CONVRATE 0x04 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_CONVRATE 0x0A 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_STATUS 0x02 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_LOCAL_TEMP 0x00 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_LOCAL_HIGH 0x05 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_LOCAL_HIGH 0x0B 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_LOCAL_LOW 0x06 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_LOCAL_LOW 0x0C 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_LOCAL_CRIT 0x20 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_LOCAL_CRIT 0x20 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_REMOTE_TEMPH 0x01 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_REMOTE_TEMPL 0x10 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_REMOTE_OFFSH 0x11 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_REMOTE_OFFSH 0x11 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_REMOTE_OFFSL 0x12 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_REMOTE_OFFSL 0x12 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_REMOTE_HIGHH 0x07 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_REMOTE_HIGHH 0x0D 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_REMOTE_HIGHL 0x13 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_REMOTE_HIGHL 0x13 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_REMOTE_LOWH 0x08 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_REMOTE_LOWH 0x0E 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_REMOTE_LOWL 0x14 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_REMOTE_LOWL 0x14 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_REMOTE_CRIT 0x19 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_REMOTE_CRIT 0x19 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_R_TCRIT_HYST 0x21 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM90_REG_W_TCRIT_HYST 0x21 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck/* MAX6646/6647/6649/6657/6658/6659/6695/6696 registers */ 155f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvare 156f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvare#define MAX6657_REG_R_LOCAL_TEMPL 0x11 15706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck#define MAX6696_REG_R_STATUS2 0x12 1586948708dd07573c578aa99f80915cd1867334abeGuenter Roeck#define MAX6659_REG_R_REMOTE_EMERG 0x16 1596948708dd07573c578aa99f80915cd1867334abeGuenter Roeck#define MAX6659_REG_W_REMOTE_EMERG 0x16 1606948708dd07573c578aa99f80915cd1867334abeGuenter Roeck#define MAX6659_REG_R_LOCAL_EMERG 0x17 1616948708dd07573c578aa99f80915cd1867334abeGuenter Roeck#define MAX6659_REG_W_LOCAL_EMERG 0x17 162f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvare 1632ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt/* SA56004 registers */ 1642ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt 1652ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt#define SA56004_REG_R_LOCAL_TEMPL 0x22 1662ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt 1670c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck#define LM90_DEF_CONVRATE_RVAL 6 /* Def conversion rate register value */ 1680c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck#define LM90_MAX_CONVRATE_MS 16000 /* Maximum conversion rate in ms */ 1690c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 17123b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case * Device flags 17223b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case */ 17388073bb1ba969d4e3c41dc5f35c902c6b7dab0a7Guenter Roeck#define LM90_FLAG_ADT7461_EXT (1 << 0) /* ADT7461 extended mode */ 17488073bb1ba969d4e3c41dc5f35c902c6b7dab0a7Guenter Roeck/* Device features */ 17588073bb1ba969d4e3c41dc5f35c902c6b7dab0a7Guenter Roeck#define LM90_HAVE_OFFSET (1 << 1) /* temperature offset register */ 17688073bb1ba969d4e3c41dc5f35c902c6b7dab0a7Guenter Roeck#define LM90_HAVE_REM_LIMIT_EXT (1 << 3) /* extended remote limit */ 1776948708dd07573c578aa99f80915cd1867334abeGuenter Roeck#define LM90_HAVE_EMERGENCY (1 << 4) /* 3rd upper (emergency) limit */ 17806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck#define LM90_HAVE_EMERGENCY_ALARM (1 << 5)/* emergency alarm */ 17906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck#define LM90_HAVE_TEMP3 (1 << 6) /* 3rd temperature sensor */ 1801179324c411edcefb28a5293f8cc6a5bd9567448Guenter Roeck#define LM90_HAVE_BROKEN_ALERT (1 << 7) /* Broken alert */ 18123b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case 18223b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case/* 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Driver data (common to all clients) 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1869b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvarestatic const struct i2c_device_id lm90_id[] = { 1879b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare { "adm1032", adm1032 }, 1889b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare { "adt7461", adt7461 }, 1895a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck { "adt7461a", adt7461 }, 190ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck { "g781", g781 }, 1919b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare { "lm90", lm90 }, 1929b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare { "lm86", lm86 }, 19397ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare { "lm89", lm86 }, 19497ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare { "lm99", lm99 }, 195271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings { "max6646", max6646 }, 196271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings { "max6647", max6646 }, 197271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings { "max6649", max6646 }, 1989b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare { "max6657", max6657 }, 1999b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare { "max6658", max6657 }, 20013c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck { "max6659", max6659 }, 2019b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare { "max6680", max6680 }, 2029b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare { "max6681", max6680 }, 20306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck { "max6695", max6696 }, 20406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck { "max6696", max6696 }, 2055a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck { "nct1008", adt7461 }, 2066771ea1fff988651593f78c122bc02e80f5100a0Jean Delvare { "w83l771", w83l771 }, 2072ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt { "sa56004", sa56004 }, 2089b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare { } 2099b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare}; 2109b0e85269275159a1f9c3e4a5d254caf5211950bJean DelvareMODULE_DEVICE_TABLE(i2c, lm90_id); 2119b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2134667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck * chip type specific parameters 2144667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck */ 2154667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeckstruct lm90_params { 2164667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck u32 flags; /* Capabilities */ 2174667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck u16 alert_alarms; /* Which alarm bits trigger ALERT# */ 2184667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck /* Upper 8 bits for max6695/96 */ 2190c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck u8 max_convrate; /* Maximum conversion rate register value */ 220a095f687f1e19c54147bd51f735717508a49e225Jean Delvare u8 reg_local_ext; /* Extended local temp register (optional) */ 2214667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck}; 2224667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck 2234667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeckstatic const struct lm90_params lm90_params[] = { 2244667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [adm1032] = { 2251179324c411edcefb28a5293f8cc6a5bd9567448Guenter Roeck .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT 2261179324c411edcefb28a5293f8cc6a5bd9567448Guenter Roeck | LM90_HAVE_BROKEN_ALERT, 2274667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7c, 2280c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 10, 2294667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2304667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [adt7461] = { 2311179324c411edcefb28a5293f8cc6a5bd9567448Guenter Roeck .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT 2321179324c411edcefb28a5293f8cc6a5bd9567448Guenter Roeck | LM90_HAVE_BROKEN_ALERT, 2334667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7c, 2340c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 10, 2354667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 236ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck [g781] = { 237ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT 238ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck | LM90_HAVE_BROKEN_ALERT, 239ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck .alert_alarms = 0x7c, 240ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck .max_convrate = 8, 241ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck }, 2424667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [lm86] = { 2434667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, 2444667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7b, 2450c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 9, 2464667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2474667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [lm90] = { 2484667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, 2494667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7b, 2500c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 9, 2514667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2524667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [lm99] = { 2534667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, 2544667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7b, 2550c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 9, 2564667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2574667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [max6646] = { 2584667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7c, 2590c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 6, 2602ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, 2614667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2624667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [max6657] = { 2634667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7c, 2640c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 8, 2652ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, 2664667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2674667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [max6659] = { 268a095f687f1e19c54147bd51f735717508a49e225Jean Delvare .flags = LM90_HAVE_EMERGENCY, 2694667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7c, 2700c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 8, 2712ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, 2724667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2734667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [max6680] = { 2744667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .flags = LM90_HAVE_OFFSET, 2754667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7c, 2760c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 7, 2774667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2784667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [max6696] = { 279a095f687f1e19c54147bd51f735717508a49e225Jean Delvare .flags = LM90_HAVE_EMERGENCY 2804667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck | LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3, 2814667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x187c, 2820c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 6, 2832ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, 2844667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2854667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck [w83l771] = { 2864667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, 2874667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck .alert_alarms = 0x7c, 2880c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck .max_convrate = 8, 2894667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck }, 2902ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt [sa56004] = { 291a095f687f1e19c54147bd51f735717508a49e225Jean Delvare .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, 2922ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt .alert_alarms = 0x7b, 2932ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt .max_convrate = 9, 2942ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt .reg_local_ext = SA56004_REG_R_LOCAL_TEMPL, 2952ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt }, 2964667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck}; 2974667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck 2984667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck/* 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Client data (each client gets its own) 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct lm90_data { 3031beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones struct device *hwmon_dev; 3049a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar struct mutex update_lock; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char valid; /* zero until following fields are valid */ 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long last_updated; /* in jiffies */ 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int kind; 3084667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck u32 flags; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3100c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck int update_interval; /* in milliseconds */ 3110c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 31295238364167edaf93ce2890e5f55326b63194851Jean Delvare u8 config_orig; /* Original configuration register value */ 3130c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck u8 convrate_orig; /* Original conversion rate register value */ 31406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck u16 alert_alarms; /* Which alarm bits trigger ALERT# */ 31506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck /* Upper 8 bits for max6695/96 */ 3160c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck u8 max_convrate; /* Maximum conversion rate */ 3172ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt u8 reg_local_ext; /* local extension register offset */ 31895238364167edaf93ce2890e5f55326b63194851Jean Delvare 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* registers values */ 32006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck s8 temp8[8]; /* 0: local low limit 321f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 1: local high limit 322f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 2: local critical limit 323f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 3: remote critical limit 324f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 4: local emergency limit (max6659 and max6695/96) 325f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 5: remote emergency limit (max6659 and max6695/96) 326f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 6: remote 2 critical limit (max6695/96 only) 327f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 7: remote 2 emergency limit (max6695/96 only) 328f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck */ 32906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck s16 temp11[8]; /* 0: remote input 330f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 1: remote low limit 331f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 2: remote high limit 332f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 3: remote offset (except max6646, max6657/58/59, 333f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * and max6695/96) 334f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 4: local input 335f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 5: remote 2 input (max6695/96 only) 336f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 6: remote 2 low limit (max6695/96 only) 337f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * 7: remote 2 high limit (max6695/96 only) 338f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck */ 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 temp_hyst; 34006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck u16 alarms; /* bitvector (upper 8 bits for max6695/96) */ 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 34415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * Support functions 34515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck */ 34615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 34715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck/* 34815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * The ADM1032 supports PEC but not on write byte transactions, so we need 34915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * to explicitly ask for a transaction without PEC. 35015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck */ 35115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeckstatic inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) 35215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck{ 35315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck return i2c_smbus_xfer(client->adapter, client->addr, 35415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck client->flags & ~I2C_CLIENT_PEC, 35515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); 35615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck} 35715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 35815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck/* 35915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * It is assumed that client->update_lock is held (unless we are in 36015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * detection or initialization steps). This matters when PEC is enabled, 36115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * because we don't want the address pointer to change between the write 36215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * byte and the read byte transactions. 36315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck */ 36415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeckstatic int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value) 36515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck{ 36615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck int err; 36715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 36815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (client->flags & I2C_CLIENT_PEC) { 36915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck err = adm1032_write_byte(client, reg); 37015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (err >= 0) 37115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck err = i2c_smbus_read_byte(client); 37215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } else 37315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck err = i2c_smbus_read_byte_data(client, reg); 37415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 37515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (err < 0) { 37615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck dev_warn(&client->dev, "Register %#02x read failed (%d)\n", 37715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck reg, err); 37815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck return err; 37915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 38015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck *value = err; 38115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 38215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck return 0; 38315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck} 38415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 38515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeckstatic int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) 38615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck{ 38715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck int err; 38815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck u8 oldh, newh, l; 38915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 39015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck /* 39115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * There is a trick here. We have to read two registers to have the 39215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * sensor temperature, but we have to beware a conversion could occur 39325985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * between the readings. The datasheet says we should either use 39415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * the one-shot conversion register, which we don't want to do 39515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * (disables hardware monitoring) or monitor the busy bit, which is 39615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * impossible (we can't read the values and monitor that bit at the 39715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * exact same time). So the solution used here is to read the high 39815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * byte once, then the low byte, then the high byte again. If the new 39915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * high byte matches the old one, then we have a valid reading. Else 40015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * we have to read the low byte again, and now we believe we have a 40115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * correct reading. 40215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck */ 40315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if ((err = lm90_read_reg(client, regh, &oldh)) 40415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck || (err = lm90_read_reg(client, regl, &l)) 40515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck || (err = lm90_read_reg(client, regh, &newh))) 40615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck return err; 40715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (oldh != newh) { 40815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck err = lm90_read_reg(client, regl, &l); 40915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (err) 41015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck return err; 41115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 41215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck *value = (newh << 8) | l; 41315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 41415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck return 0; 41515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck} 41615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 41715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck/* 41815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * client->update_lock must be held when calling this function (unless we are 41915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * in detection or initialization steps), and while a remote channel other 42015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * than channel 0 is selected. Also, calling code must make sure to re-select 42115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * external channel 0 before releasing the lock. This is necessary because 42215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * various registers have different meanings as a result of selecting a 42315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * non-default remote channel. 42415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck */ 42515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeckstatic inline void lm90_select_remote_channel(struct i2c_client *client, 42615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck struct lm90_data *data, 42715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck int channel) 42815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck{ 42915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck u8 config; 43015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 43115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (data->kind == max6696) { 43215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); 43315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck config &= ~0x08; 43415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (channel) 43515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck config |= 0x08; 43615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, 43715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck config); 43815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 43915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck} 44015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 4410c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck/* 4420c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck * Set conversion rate. 4430c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck * client->update_lock must be held when calling this function (unless we are 4440c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck * in detection or initialization steps). 4450c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck */ 4460c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeckstatic void lm90_set_convrate(struct i2c_client *client, struct lm90_data *data, 4470c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck unsigned int interval) 4480c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck{ 4490c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck int i; 4500c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck unsigned int update_interval; 4510c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 4520c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck /* Shift calculations to avoid rounding errors */ 4530c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck interval <<= 6; 4540c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 4550c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck /* find the nearest update rate */ 4560c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck for (i = 0, update_interval = LM90_MAX_CONVRATE_MS << 6; 4570c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck i < data->max_convrate; i++, update_interval >>= 1) 4580c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck if (interval >= update_interval * 3 / 4) 4590c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck break; 4600c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 4610c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, i); 4620c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck data->update_interval = DIV_ROUND_CLOSEST(update_interval, 64); 4630c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck} 4640c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 46515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeckstatic struct lm90_data *lm90_update_device(struct device *dev) 46615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck{ 46715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck struct i2c_client *client = to_i2c_client(dev); 46815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck struct lm90_data *data = i2c_get_clientdata(client); 4690c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck unsigned long next_update; 47015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 47115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck mutex_lock(&data->update_lock); 47215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 4730c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck next_update = data->last_updated 4740c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck + msecs_to_jiffies(data->update_interval) + 1; 4750c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck if (time_after(jiffies, next_update) || !data->valid) { 47615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck u8 h, l; 47715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck u8 alarms; 47815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 47915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck dev_dbg(&client->dev, "Updating lm90 data.\n"); 48015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]); 48115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]); 48215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]); 48315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]); 48415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); 48515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 486a095f687f1e19c54147bd51f735717508a49e225Jean Delvare if (data->reg_local_ext) { 48715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read16(client, LM90_REG_R_LOCAL_TEMP, 4882ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt data->reg_local_ext, 48915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &data->temp11[4]); 49015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } else { 49115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, 49215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &h) == 0) 49315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->temp11[4] = h << 8; 49415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 49515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, 49615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]); 49715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 49815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) { 49915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->temp11[1] = h << 8; 50015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) 50115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, 50215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &l) == 0) 50315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->temp11[1] |= l; 50415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 50515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) { 50615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->temp11[2] = h << 8; 50715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) 50815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, 50915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &l) == 0) 51015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->temp11[2] |= l; 51115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 51215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 51315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (data->flags & LM90_HAVE_OFFSET) { 51415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, 51515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &h) == 0 51615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, 51715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &l) == 0) 51815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->temp11[3] = (h << 8) | l; 51915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 52015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (data->flags & LM90_HAVE_EMERGENCY) { 52115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG, 52215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &data->temp8[4]); 52315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, 52415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &data->temp8[5]); 52515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 52615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, LM90_REG_R_STATUS, &alarms); 52715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->alarms = alarms; /* save as 16 bit value */ 52815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 52915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (data->kind == max6696) { 53015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_select_remote_channel(client, data, 1); 53115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, 53215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &data->temp8[6]); 53315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, 53415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &data->temp8[7]); 53515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, 53615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck LM90_REG_R_REMOTE_TEMPL, &data->temp11[5]); 53715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (!lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h)) 53815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->temp11[6] = h << 8; 53915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (!lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h)) 54015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->temp11[7] = h << 8; 54115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_select_remote_channel(client, data, 0); 54215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 54315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (!lm90_read_reg(client, MAX6696_REG_R_STATUS2, 54415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck &alarms)) 54515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->alarms |= alarms << 8; 54615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 54715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 548f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck /* 549f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * Re-enable ALERT# output if it was originally enabled and 550f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * relevant alarms are all clear 551f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck */ 55215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if ((data->config_orig & 0x80) == 0 55315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck && (data->alarms & data->alert_alarms) == 0) { 55415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck u8 config; 55515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 55615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); 55715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (config & 0x80) { 55815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck dev_dbg(&client->dev, "Re-enabling ALERT#\n"); 55915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck i2c_smbus_write_byte_data(client, 56015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck LM90_REG_W_CONFIG1, 56115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck config & ~0x80); 56215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 56315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 56415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 56515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->last_updated = jiffies; 56615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->valid = 1; 56715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 56815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 56915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck mutex_unlock(&data->update_lock); 57015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 57115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck return data; 57215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck} 57315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 57415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck/* 575cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case * Conversions 576cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case * For local temperatures and limits, critical limits and the hysteresis 577cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius. 578cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case * For remote temperatures and limits, it uses signed 11-bit values with 579271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. Some 580271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings * Maxim chips use unsigned values. 581cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case */ 582cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case 5839d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchingsstatic inline int temp_from_s8(s8 val) 584cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case{ 585cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return val * 1000; 586cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case} 587cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case 588271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchingsstatic inline int temp_from_u8(u8 val) 589271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings{ 590271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings return val * 1000; 591271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings} 592271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings 5939d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchingsstatic inline int temp_from_s16(s16 val) 594cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case{ 595cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return val / 32 * 125; 596cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case} 597cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case 598271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchingsstatic inline int temp_from_u16(u16 val) 599271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings{ 600271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings return val / 32 * 125; 601271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings} 602271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings 6039d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchingsstatic s8 temp_to_s8(long val) 604cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case{ 605cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case if (val <= -128000) 606cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return -128; 607cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case if (val >= 127000) 608cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return 127; 609cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case if (val < 0) 610cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return (val - 500) / 1000; 611cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return (val + 500) / 1000; 612cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case} 613cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case 614271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchingsstatic u8 temp_to_u8(long val) 615271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings{ 616271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings if (val <= 0) 617271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings return 0; 618271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings if (val >= 255000) 619271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings return 255; 620271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings return (val + 500) / 1000; 621271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings} 622271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings 6239d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchingsstatic s16 temp_to_s16(long val) 624cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case{ 625cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case if (val <= -128000) 626cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return 0x8000; 627cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case if (val >= 127875) 628cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return 0x7FE0; 629cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case if (val < 0) 630cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return (val - 62) / 125 * 32; 631cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return (val + 62) / 125 * 32; 632cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case} 633cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case 634cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Casestatic u8 hyst_to_reg(long val) 635cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case{ 636cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case if (val <= 0) 637cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return 0; 638cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case if (val >= 30500) 639cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return 31; 640cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case return (val + 500) / 1000; 641cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case} 642cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case 643cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case/* 64423b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case * ADT7461 in compatibility mode is almost identical to LM90 except that 64523b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case * attempts to write values that are outside the range 0 < temp < 127 are 64623b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case * treated as the boundary value. 64723b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case * 64823b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case * ADT7461 in "extended mode" operation uses unsigned integers offset by 64923b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case * 64 (e.g., 0 -> -64 degC). The range is restricted to -64..191 degC. 650cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case */ 6519d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchingsstatic inline int temp_from_u8_adt7461(struct lm90_data *data, u8 val) 652cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case{ 65323b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (data->flags & LM90_FLAG_ADT7461_EXT) 65423b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return (val - 64) * 1000; 65523b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case else 6569d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings return temp_from_s8(val); 657cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case} 658cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case 6599d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchingsstatic inline int temp_from_u16_adt7461(struct lm90_data *data, u16 val) 660cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case{ 66123b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (data->flags & LM90_FLAG_ADT7461_EXT) 66223b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return (val - 0x4000) / 64 * 250; 66323b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case else 6649d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings return temp_from_s16(val); 66523b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case} 66623b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case 6679d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchingsstatic u8 temp_to_u8_adt7461(struct lm90_data *data, long val) 66823b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case{ 66923b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (data->flags & LM90_FLAG_ADT7461_EXT) { 67023b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (val <= -64000) 67123b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return 0; 67223b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (val >= 191000) 67323b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return 0xFF; 67423b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return (val + 500 + 64000) / 1000; 67523b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case } else { 67623b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (val <= 0) 67723b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return 0; 67823b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (val >= 127000) 67923b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return 127; 68023b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return (val + 500) / 1000; 68123b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case } 68223b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case} 68323b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case 6849d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchingsstatic u16 temp_to_u16_adt7461(struct lm90_data *data, long val) 68523b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case{ 68623b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (data->flags & LM90_FLAG_ADT7461_EXT) { 68723b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (val <= -64000) 68823b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return 0; 68923b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (val >= 191750) 69023b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return 0xFFC0; 69123b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return (val + 64000 + 125) / 250 * 64; 69223b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case } else { 69323b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (val <= 0) 69423b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return 0; 69523b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (val >= 127750) 69623b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return 0x7FC0; 69723b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return (val + 125) / 250 * 64; 69823b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case } 699cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case} 700cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case 701cea50fe2fdea36174aa24b58c69c4eb9770e7c49Nate Case/* 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sysfs stuff 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 70530d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic ssize_t show_temp8(struct device *dev, struct device_attribute *devattr, 70630d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare char *buf) 70730d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare{ 70830d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 70930d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct lm90_data *data = lm90_update_device(dev); 71023b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case int temp; 71123b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case 71223b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (data->kind == adt7461) 7139d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); 714271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings else if (data->kind == max6646) 715271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings temp = temp_from_u8(data->temp8[attr->index]); 71623b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case else 7179d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings temp = temp_from_s8(data->temp8[attr->index]); 71823b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case 71997ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare /* +16 degrees offset for temp2 for the LM99 */ 72097ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare if (data->kind == lm99 && attr->index == 3) 72197ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare temp += 16000; 72297ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare 72323b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return sprintf(buf, "%d\n", temp); 72430d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare} 72530d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare 72630d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, 72730d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare const char *buf, size_t count) 72830d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare{ 72906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck static const u8 reg[8] = { 73030d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare LM90_REG_W_LOCAL_LOW, 73130d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare LM90_REG_W_LOCAL_HIGH, 73230d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare LM90_REG_W_LOCAL_CRIT, 73330d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare LM90_REG_W_REMOTE_CRIT, 7346948708dd07573c578aa99f80915cd1867334abeGuenter Roeck MAX6659_REG_W_LOCAL_EMERG, 7356948708dd07573c578aa99f80915cd1867334abeGuenter Roeck MAX6659_REG_W_REMOTE_EMERG, 73606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck LM90_REG_W_REMOTE_CRIT, 73706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck MAX6659_REG_W_REMOTE_EMERG, 73830d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare }; 73930d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare 74030d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 74130d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct i2c_client *client = to_i2c_client(dev); 74230d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct lm90_data *data = i2c_get_clientdata(client); 74330d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare int nr = attr->index; 74411e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck long val; 74511e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck int err; 74611e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck 747179c4fdb565dd2157e5dfe89318b74868e3b523dFrans Meulenbroeks err = kstrtol(buf, 10, &val); 74811e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck if (err < 0) 74911e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck return err; 75030d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare 75197ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare /* +16 degrees offset for temp2 for the LM99 */ 75297ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare if (data->kind == lm99 && attr->index == 3) 75397ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare val -= 16000; 75497ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare 7559a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 75630d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare if (data->kind == adt7461) 7579d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings data->temp8[nr] = temp_to_u8_adt7461(data, val); 758271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings else if (data->kind == max6646) 759271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings data->temp8[nr] = temp_to_u8(val); 76030d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare else 7619d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings data->temp8[nr] = temp_to_s8(val); 76206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 76306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck lm90_select_remote_channel(client, data, nr >= 6); 764f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvare i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]); 76506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck lm90_select_remote_channel(client, data, 0); 76606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 7679a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 76830d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare return count; 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 77030d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare 77130d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, 77230d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare char *buf) 77330d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare{ 77496512861c3733609ac3d558602574674fa95ebf4Guenter Roeck struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 77530d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct lm90_data *data = lm90_update_device(dev); 77623b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case int temp; 77723b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case 77823b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (data->kind == adt7461) 7799d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings temp = temp_from_u16_adt7461(data, data->temp11[attr->index]); 780271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings else if (data->kind == max6646) 781271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings temp = temp_from_u16(data->temp11[attr->index]); 78223b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case else 7839d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings temp = temp_from_s16(data->temp11[attr->index]); 78423b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case 78597ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare /* +16 degrees offset for temp2 for the LM99 */ 78697ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare if (data->kind == lm99 && attr->index <= 2) 78797ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare temp += 16000; 78897ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare 78923b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case return sprintf(buf, "%d\n", temp); 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 79130d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare 79230d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, 79330d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare const char *buf, size_t count) 79430d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare{ 79596512861c3733609ac3d558602574674fa95ebf4Guenter Roeck struct { 79696512861c3733609ac3d558602574674fa95ebf4Guenter Roeck u8 high; 79796512861c3733609ac3d558602574674fa95ebf4Guenter Roeck u8 low; 79806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck int channel; 79906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck } reg[5] = { 80006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL, 0 }, 80106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL, 0 }, 80206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck { LM90_REG_W_REMOTE_OFFSH, LM90_REG_W_REMOTE_OFFSL, 0 }, 80306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck { LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL, 1 }, 80406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck { LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL, 1 } 80530d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare }; 80630d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare 80796512861c3733609ac3d558602574674fa95ebf4Guenter Roeck struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 80830d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct i2c_client *client = to_i2c_client(dev); 80930d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct lm90_data *data = i2c_get_clientdata(client); 81096512861c3733609ac3d558602574674fa95ebf4Guenter Roeck int nr = attr->nr; 81196512861c3733609ac3d558602574674fa95ebf4Guenter Roeck int index = attr->index; 81211e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck long val; 81311e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck int err; 81411e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck 815179c4fdb565dd2157e5dfe89318b74868e3b523dFrans Meulenbroeks err = kstrtol(buf, 10, &val); 81611e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck if (err < 0) 81711e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck return err; 81830d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare 81997ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare /* +16 degrees offset for temp2 for the LM99 */ 82096512861c3733609ac3d558602574674fa95ebf4Guenter Roeck if (data->kind == lm99 && index <= 2) 82197ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare val -= 16000; 82297ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare 8239a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 82430d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare if (data->kind == adt7461) 82596512861c3733609ac3d558602574674fa95ebf4Guenter Roeck data->temp11[index] = temp_to_u16_adt7461(data, val); 826271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings else if (data->kind == max6646) 82796512861c3733609ac3d558602574674fa95ebf4Guenter Roeck data->temp11[index] = temp_to_u8(val) << 8; 82888073bb1ba969d4e3c41dc5f35c902c6b7dab0a7Guenter Roeck else if (data->flags & LM90_HAVE_REM_LIMIT_EXT) 82996512861c3733609ac3d558602574674fa95ebf4Guenter Roeck data->temp11[index] = temp_to_s16(val); 83088073bb1ba969d4e3c41dc5f35c902c6b7dab0a7Guenter Roeck else 83196512861c3733609ac3d558602574674fa95ebf4Guenter Roeck data->temp11[index] = temp_to_s8(val) << 8; 8325f502a834a6471dc3cc456ccef66292e9e3a152eJean Delvare 83306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck lm90_select_remote_channel(client, data, reg[nr].channel); 83496512861c3733609ac3d558602574674fa95ebf4Guenter Roeck i2c_smbus_write_byte_data(client, reg[nr].high, 83596512861c3733609ac3d558602574674fa95ebf4Guenter Roeck data->temp11[index] >> 8); 83688073bb1ba969d4e3c41dc5f35c902c6b7dab0a7Guenter Roeck if (data->flags & LM90_HAVE_REM_LIMIT_EXT) 83796512861c3733609ac3d558602574674fa95ebf4Guenter Roeck i2c_smbus_write_byte_data(client, reg[nr].low, 83896512861c3733609ac3d558602574674fa95ebf4Guenter Roeck data->temp11[index] & 0xff); 83906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck lm90_select_remote_channel(client, data, 0); 84006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 8419a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 84230d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare return count; 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 84430d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare 84511e578129af74c4866cf559e62e981c6415fffd9Guenter Roeckstatic ssize_t show_temphyst(struct device *dev, 84611e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck struct device_attribute *devattr, 84730d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare char *buf) 84830d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare{ 84930d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 85030d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare struct lm90_data *data = lm90_update_device(dev); 85123b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case int temp; 85223b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case 85323b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case if (data->kind == adt7461) 8549d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings temp = temp_from_u8_adt7461(data, data->temp8[attr->index]); 855ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare else if (data->kind == max6646) 856ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare temp = temp_from_u8(data->temp8[attr->index]); 85723b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case else 8589d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings temp = temp_from_s8(data->temp8[attr->index]); 85923b2d4778ad33ee6bfe60439fb73c16580f204f2Nate Case 86097ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare /* +16 degrees offset for temp2 for the LM99 */ 86197ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare if (data->kind == lm99 && attr->index == 3) 86297ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare temp += 16000; 86397ae60bb38279e1941c738b1037a57e6b14efeafJean Delvare 8649d4d3834229e9949c066c2d0f73ed5d4b4965761Ben Hutchings return sprintf(buf, "%d\n", temp - temp_from_s8(data->temp_hyst)); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 86730d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy, 86830d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare const char *buf, size_t count) 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_client *client = to_i2c_client(dev); 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm90_data *data = i2c_get_clientdata(client); 87211e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck long val; 87311e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck int err; 874ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare int temp; 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 876179c4fdb565dd2157e5dfe89318b74868e3b523dFrans Meulenbroeks err = kstrtol(buf, 10, &val); 87711e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck if (err < 0) 87811e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck return err; 87911e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck 8809a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 881ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare if (data->kind == adt7461) 882ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare temp = temp_from_u8_adt7461(data, data->temp8[2]); 883ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare else if (data->kind == max6646) 884ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare temp = temp_from_u8(data->temp8[2]); 885ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare else 886ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare temp = temp_from_s8(data->temp8[2]); 887ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare 888ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare data->temp_hyst = hyst_to_reg(temp - val); 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, 890ec38fa2b35f13e7fa1d676a5bc997d0df1b02574Jean Delvare data->temp_hyst); 8919a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 89530d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, 89630d7394b1a3df0e7cc145a543846109babd4d53bJean Delvare char *buf) 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm90_data *data = lm90_update_device(dev); 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%d\n", data->alarms); 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9022d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvarestatic ssize_t show_alarm(struct device *dev, struct device_attribute 9032d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare *devattr, char *buf) 9042d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare{ 9052d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 9062d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare struct lm90_data *data = lm90_update_device(dev); 9072d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare int bitnr = attr->index; 9082d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare 9092d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); 9102d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare} 9112d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare 9120c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeckstatic ssize_t show_update_interval(struct device *dev, 9130c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck struct device_attribute *attr, char *buf) 9140c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck{ 9150c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck struct lm90_data *data = dev_get_drvdata(dev); 9160c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 9170c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck return sprintf(buf, "%u\n", data->update_interval); 9180c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck} 9190c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 9200c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeckstatic ssize_t set_update_interval(struct device *dev, 9210c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck struct device_attribute *attr, 9220c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck const char *buf, size_t count) 9230c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck{ 9240c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck struct i2c_client *client = to_i2c_client(dev); 9250c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck struct lm90_data *data = i2c_get_clientdata(client); 9260c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck unsigned long val; 9270c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck int err; 9280c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 929179c4fdb565dd2157e5dfe89318b74868e3b523dFrans Meulenbroeks err = kstrtoul(buf, 10, &val); 9300c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck if (err) 9310c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck return err; 9320c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 9330c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck mutex_lock(&data->update_lock); 9346b101116ae445311031f3e9f91d3010d444b9845Guenter Roeck lm90_set_convrate(client, data, SENSORS_LIMIT(val, 0, 100000)); 9350c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck mutex_unlock(&data->update_lock); 9360c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 9370c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck return count; 9380c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck} 9390c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 94096512861c3733609ac3d558602574674fa95ebf4Guenter Roeckstatic SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp11, NULL, 0, 4); 94196512861c3733609ac3d558602574674fa95ebf4Guenter Roeckstatic SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp11, NULL, 0, 0); 94230d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, 943f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvare set_temp8, 0); 94496512861c3733609ac3d558602574674fa95ebf4Guenter Roeckstatic SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp11, 94596512861c3733609ac3d558602574674fa95ebf4Guenter Roeck set_temp11, 0, 1); 94630d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8, 947f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvare set_temp8, 1); 94896512861c3733609ac3d558602574674fa95ebf4Guenter Roeckstatic SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp11, 94996512861c3733609ac3d558602574674fa95ebf4Guenter Roeck set_temp11, 1, 2); 95030d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8, 951f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvare set_temp8, 2); 95230d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, 953f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvare set_temp8, 3); 95430d7394b1a3df0e7cc145a543846109babd4d53bJean Delvarestatic SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, 955f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvare set_temphyst, 2); 956f65e17086fc141bee1592bbf6e709e9c7a43541bJean Delvarestatic SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 3); 95796512861c3733609ac3d558602574674fa95ebf4Guenter Roeckstatic SENSOR_DEVICE_ATTR_2(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, 95896512861c3733609ac3d558602574674fa95ebf4Guenter Roeck set_temp11, 2, 3); 9592d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare 9602d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare/* Individual alarm files */ 9612d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); 9622d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvarestatic SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); 9637817a39e65f04abe136d94a65fa26b7fe3334a1fJean Delvarestatic SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); 9642d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvarestatic SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); 9652d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvarestatic SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); 9662d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); 9672d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); 9682d45771e6ea79f56a7d85e448f702f60ef86c228Jean Delvare/* Raw alarm file for compatibility */ 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9710c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeckstatic DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, 9720c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck set_update_interval); 9730c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 9740e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvarestatic struct attribute *lm90_attributes[] = { 9750e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp1_input.dev_attr.attr, 9760e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp2_input.dev_attr.attr, 9770e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp1_min.dev_attr.attr, 9780e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp2_min.dev_attr.attr, 9790e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp1_max.dev_attr.attr, 9800e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp2_max.dev_attr.attr, 9810e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp1_crit.dev_attr.attr, 9820e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp2_crit.dev_attr.attr, 9830e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, 9840e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, 9850e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare 9860e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, 9870e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, 9887817a39e65f04abe136d94a65fa26b7fe3334a1fJean Delvare &sensor_dev_attr_temp2_fault.dev_attr.attr, 9890e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, 9900e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, 9910e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, 9920e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 9930e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare &dev_attr_alarms.attr, 9940c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck &dev_attr_update_interval.attr, 9950e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare NULL 9960e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare}; 9970e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare 9980e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvarestatic const struct attribute_group lm90_group = { 9990e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare .attrs = lm90_attributes, 10000e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare}; 10010e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare 10026948708dd07573c578aa99f80915cd1867334abeGuenter Roeck/* 10036948708dd07573c578aa99f80915cd1867334abeGuenter Roeck * Additional attributes for devices with emergency sensors 10046948708dd07573c578aa99f80915cd1867334abeGuenter Roeck */ 10056948708dd07573c578aa99f80915cd1867334abeGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_emergency, S_IWUSR | S_IRUGO, show_temp8, 10066948708dd07573c578aa99f80915cd1867334abeGuenter Roeck set_temp8, 4); 10076948708dd07573c578aa99f80915cd1867334abeGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp2_emergency, S_IWUSR | S_IRUGO, show_temp8, 10086948708dd07573c578aa99f80915cd1867334abeGuenter Roeck set_temp8, 5); 10096948708dd07573c578aa99f80915cd1867334abeGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_emergency_hyst, S_IRUGO, show_temphyst, 10106948708dd07573c578aa99f80915cd1867334abeGuenter Roeck NULL, 4); 10116948708dd07573c578aa99f80915cd1867334abeGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp2_emergency_hyst, S_IRUGO, show_temphyst, 10126948708dd07573c578aa99f80915cd1867334abeGuenter Roeck NULL, 5); 10136948708dd07573c578aa99f80915cd1867334abeGuenter Roeck 10146948708dd07573c578aa99f80915cd1867334abeGuenter Roeckstatic struct attribute *lm90_emergency_attributes[] = { 10156948708dd07573c578aa99f80915cd1867334abeGuenter Roeck &sensor_dev_attr_temp1_emergency.dev_attr.attr, 10166948708dd07573c578aa99f80915cd1867334abeGuenter Roeck &sensor_dev_attr_temp2_emergency.dev_attr.attr, 10176948708dd07573c578aa99f80915cd1867334abeGuenter Roeck &sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr, 10186948708dd07573c578aa99f80915cd1867334abeGuenter Roeck &sensor_dev_attr_temp2_emergency_hyst.dev_attr.attr, 10196948708dd07573c578aa99f80915cd1867334abeGuenter Roeck NULL 10206948708dd07573c578aa99f80915cd1867334abeGuenter Roeck}; 10216948708dd07573c578aa99f80915cd1867334abeGuenter Roeck 10226948708dd07573c578aa99f80915cd1867334abeGuenter Roeckstatic const struct attribute_group lm90_emergency_group = { 10236948708dd07573c578aa99f80915cd1867334abeGuenter Roeck .attrs = lm90_emergency_attributes, 10246948708dd07573c578aa99f80915cd1867334abeGuenter Roeck}; 10256948708dd07573c578aa99f80915cd1867334abeGuenter Roeck 102606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_emergency_alarm, S_IRUGO, show_alarm, NULL, 15); 102706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp2_emergency_alarm, S_IRUGO, show_alarm, NULL, 13); 102806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 102906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic struct attribute *lm90_emergency_alarm_attributes[] = { 103006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp1_emergency_alarm.dev_attr.attr, 103106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp2_emergency_alarm.dev_attr.attr, 103206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck NULL 103306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck}; 103406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 103506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic const struct attribute_group lm90_emergency_alarm_group = { 103606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck .attrs = lm90_emergency_alarm_attributes, 103706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck}; 103806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 103906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck/* 104006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * Additional attributes for devices with 3 temperature sensors 104106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck */ 104206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp11, NULL, 0, 5); 104306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR_2(temp3_min, S_IWUSR | S_IRUGO, show_temp11, 104406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck set_temp11, 3, 6); 104506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR_2(temp3_max, S_IWUSR | S_IRUGO, show_temp11, 104606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck set_temp11, 4, 7); 104706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp8, 104806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck set_temp8, 6); 104906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_temphyst, NULL, 6); 105006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_emergency, S_IWUSR | S_IRUGO, show_temp8, 105106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck set_temp8, 7); 105206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_emergency_hyst, S_IRUGO, show_temphyst, 105306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck NULL, 7); 105406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 105506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 9); 105606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 10); 105706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_alarm, NULL, 11); 105806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 12); 105906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_emergency_alarm, S_IRUGO, show_alarm, NULL, 14); 106006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 106106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic struct attribute *lm90_temp3_attributes[] = { 106206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_input.dev_attr.attr, 106306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_min.dev_attr.attr, 106406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_max.dev_attr.attr, 106506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_crit.dev_attr.attr, 106606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, 106706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_emergency.dev_attr.attr, 106806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_emergency_hyst.dev_attr.attr, 106906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 107006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_fault.dev_attr.attr, 107106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, 107206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, 107306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, 107406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &sensor_dev_attr_temp3_emergency_alarm.dev_attr.attr, 107506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck NULL 107606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck}; 107706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 107806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeckstatic const struct attribute_group lm90_temp3_group = { 107906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck .attrs = lm90_temp3_attributes, 108006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck}; 108106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 1082c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare/* pec used for ADM1032 only */ 1083c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvarestatic ssize_t show_pec(struct device *dev, struct device_attribute *dummy, 1084c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare char *buf) 1085c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare{ 1086c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare struct i2c_client *client = to_i2c_client(dev); 1087c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); 1088c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare} 1089c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare 1090c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvarestatic ssize_t set_pec(struct device *dev, struct device_attribute *dummy, 1091c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare const char *buf, size_t count) 1092c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare{ 1093c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare struct i2c_client *client = to_i2c_client(dev); 109411e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck long val; 109511e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck int err; 109611e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck 1097179c4fdb565dd2157e5dfe89318b74868e3b523dFrans Meulenbroeks err = kstrtol(buf, 10, &val); 109811e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck if (err < 0) 109911e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck return err; 1100c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare 1101c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare switch (val) { 1102c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare case 0: 1103c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare client->flags &= ~I2C_CLIENT_PEC; 1104c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare break; 1105c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare case 1: 1106c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare client->flags |= I2C_CLIENT_PEC; 1107c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare break; 1108c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare default: 1109c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare return -EINVAL; 1110c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare } 1111c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare 1112c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare return count; 1113c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare} 1114c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare 1115c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvarestatic DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); 1116c3df5806cdae6fac678c662b527cb974bef4b60cJean Delvare 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Real code 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 112115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck/* Return 0 if detection is successful, -ENODEV otherwise */ 1122b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvarestatic int lm90_detect(struct i2c_client *client, 112315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck struct i2c_board_info *info) 11248256fe0f40f1cd72f80f2c46fe0ab1638f03a98dJean Delvare{ 1125b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare struct i2c_adapter *adapter = client->adapter; 1126b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare int address = client->addr; 112715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck const char *name = NULL; 1128b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare int man_id, chip_id, config1, config2, convrate; 11298256fe0f40f1cd72f80f2c46fe0ab1638f03a98dJean Delvare 113015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 113115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck return -ENODEV; 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11338f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare /* detection and identification */ 1134b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare man_id = i2c_smbus_read_byte_data(client, LM90_REG_R_MAN_ID); 1135b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare chip_id = i2c_smbus_read_byte_data(client, LM90_REG_R_CHIP_ID); 1136b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare config1 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1); 1137b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare convrate = i2c_smbus_read_byte_data(client, LM90_REG_R_CONVRATE); 1138b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0) 11398f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare return -ENODEV; 11408f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare 1141f90be42fb383f39aa814b8e14de138da8973e5c1Jean Delvare if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) { 1142b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2); 1143b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare if (config2 < 0) 11449b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare return -ENODEV; 1145f90be42fb383f39aa814b8e14de138da8973e5c1Jean Delvare } else 1146b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare config2 = 0; /* Make compiler happy */ 11478f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare 1148f90be42fb383f39aa814b8e14de138da8973e5c1Jean Delvare if ((address == 0x4C || address == 0x4D) 1149f90be42fb383f39aa814b8e14de138da8973e5c1Jean Delvare && man_id == 0x01) { /* National Semiconductor */ 1150b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare if ((config1 & 0x2A) == 0x00 1151b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config2 & 0xF8) == 0x00 1152b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x09) { 11538f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if (address == 0x4C 11548f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare && (chip_id & 0xF0) == 0x20) { /* LM90 */ 11558f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare name = "lm90"; 115632c82a934759b2c9939c9e25865c2d7d1204b9e8Rainer Birkenmaier } else 11578f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */ 11588f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare name = "lm99"; 11598f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare dev_info(&adapter->dev, 11608f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare "Assuming LM99 chip at 0x%02x\n", 11618f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare address); 11628f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare dev_info(&adapter->dev, 11638f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare "If it is an LM89, instantiate it " 11648f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare "with the new_device sysfs " 11658f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare "interface\n"); 1166271dabf5bbf6ae6e2792cd5cf6f0434230e5c18cBen Hutchings } else 11678f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if (address == 0x4C 11688f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare && (chip_id & 0xF0) == 0x10) { /* LM86 */ 11698f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare name = "lm86"; 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11728f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare } else 11738f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if ((address == 0x4C || address == 0x4D) 11748f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare && man_id == 0x41) { /* Analog Devices */ 11758f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ 1176b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config1 & 0x3F) == 0x00 1177b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x0A) { 11788f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare name = "adm1032"; 1179f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck /* 1180f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * The ADM1032 supports PEC, but only if combined 1181f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * transactions are not used. 1182f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck */ 11838f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if (i2c_check_functionality(adapter, 11848f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare I2C_FUNC_SMBUS_BYTE)) 11858f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare info->flags |= I2C_CLIENT_PEC; 11868f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare } else 11878f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if (chip_id == 0x51 /* ADT7461 */ 1188b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config1 & 0x1B) == 0x00 1189b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x0A) { 11908f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare name = "adt7461"; 11915a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck } else 11925a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck if (chip_id == 0x57 /* ADT7461A, NCT1008 */ 1193b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config1 & 0x1B) == 0x00 1194b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x0A) { 11955a4e5e6a701bea7d3cbeed19fa9ea45802e8fabbGuenter Roeck name = "adt7461a"; 11968f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare } 11978f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare } else 11988f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if (man_id == 0x4D) { /* Maxim */ 1199b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare int emerg, emerg2, status2; 120006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 120106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck /* 120206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * We read MAX6659_REG_R_REMOTE_EMERG twice, and re-read 120306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * LM90_REG_R_MAN_ID in between. If MAX6659_REG_R_REMOTE_EMERG 120406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * exists, both readings will reflect the same value. Otherwise, 120506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * the readings will be different. 120606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck */ 1207b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare emerg = i2c_smbus_read_byte_data(client, 1208b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare MAX6659_REG_R_REMOTE_EMERG); 1209b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare man_id = i2c_smbus_read_byte_data(client, 12108dc089d68b125179b1c97e75d29623472d99c68bJean Delvare LM90_REG_R_MAN_ID); 1211b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare emerg2 = i2c_smbus_read_byte_data(client, 12128dc089d68b125179b1c97e75d29623472d99c68bJean Delvare MAX6659_REG_R_REMOTE_EMERG); 1213b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare status2 = i2c_smbus_read_byte_data(client, 1214b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare MAX6696_REG_R_STATUS2); 1215b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare if (emerg < 0 || man_id < 0 || emerg2 < 0 || status2 < 0) 121606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck return -ENODEV; 121706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 12188f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare /* 12198f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * The MAX6657, MAX6658 and MAX6659 do NOT have a chip_id 12208f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * register. Reading from that address will return the last 12218f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * read value, which in our case is those of the man_id 12228f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * register. Likewise, the config1 register seems to lack a 12238f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * low nibble, so the value will be those of the previous 12248f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * read, so in our case those of the man_id register. 122513c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck * MAX6659 has a third set of upper temperature limit registers. 122613c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck * Those registers also return values on MAX6657 and MAX6658, 122713c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck * thus the only way to detect MAX6659 is by its address. 122813c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck * For this reason it will be mis-detected as MAX6657 if its 122913c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck * address is 0x4C. 12308f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare */ 12318f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if (chip_id == man_id 123213c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck && (address == 0x4C || address == 0x4D || address == 0x4E) 1233b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config1 & 0x1F) == (man_id & 0x0F) 1234b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x09) { 123513c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck if (address == 0x4C) 123613c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck name = "max6657"; 123713c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck else 123813c84951a3d75ba820adf47eb2a3b1c5ab1fa635Guenter Roeck name = "max6659"; 12398f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare } else 12408f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare /* 124106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * Even though MAX6695 and MAX6696 do not have a chip ID 124206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * register, reading it returns 0x01. Bit 4 of the config1 124306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * register is unused and should return zero when read. Bit 0 of 124406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * the status2 register is unused and should return zero when 124506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * read. 124606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * 124706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * MAX6695 and MAX6696 have an additional set of temperature 124806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * limit registers. We can detect those chips by checking if 124906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck * one of those registers exists. 125006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck */ 125106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if (chip_id == 0x01 1252b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config1 & 0x10) == 0x00 1253b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (status2 & 0x01) == 0x00 1254b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && emerg == emerg2 1255b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x07) { 125606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck name = "max6696"; 125706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck } else 125806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck /* 12598f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * The chip_id register of the MAX6680 and MAX6681 holds the 12608f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * revision of the chip. The lowest bit of the config1 register 12618f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * is unused and should return zero when read, so should the 12628f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * second to last bit of config1 (software reset). 12638f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare */ 12648f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if (chip_id == 0x01 1265b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config1 & 0x03) == 0x00 1266b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x07) { 12678f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare name = "max6680"; 12688f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare } else 12698f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare /* 12708f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * The chip_id register of the MAX6646/6647/6649 holds the 12718f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * revision of the chip. The lowest 6 bits of the config1 12728f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare * register are unused and should return zero when read. 12738f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare */ 12748f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if (chip_id == 0x59 1275b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config1 & 0x3f) == 0x00 1276b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x07) { 12778f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare name = "max6646"; 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12796771ea1fff988651593f78c122bc02e80f5100a0Jean Delvare } else 12806771ea1fff988651593f78c122bc02e80f5100a0Jean Delvare if (address == 0x4C 12816771ea1fff988651593f78c122bc02e80f5100a0Jean Delvare && man_id == 0x5C) { /* Winbond/Nuvoton */ 1282b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare if ((config1 & 0x2A) == 0x00 1283b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config2 & 0xF8) == 0x00) { 1284c4f99a2b8fb4c564865f0037a2b7be690d4409f3Jean Delvare if (chip_id == 0x01 /* W83L771W/G */ 1285b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x09) { 1286c4f99a2b8fb4c564865f0037a2b7be690d4409f3Jean Delvare name = "w83l771"; 1287c4f99a2b8fb4c564865f0037a2b7be690d4409f3Jean Delvare } else 1288c4f99a2b8fb4c564865f0037a2b7be690d4409f3Jean Delvare if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */ 1289b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x08) { 1290c4f99a2b8fb4c564865f0037a2b7be690d4409f3Jean Delvare name = "w83l771"; 1291c4f99a2b8fb4c564865f0037a2b7be690d4409f3Jean Delvare } 12926771ea1fff988651593f78c122bc02e80f5100a0Jean Delvare } 12932ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt } else 12946d101c588f0fe08ef00f16c1a93762dd5d563df7Jean Delvare if (address >= 0x48 && address <= 0x4F 12956d101c588f0fe08ef00f16c1a93762dd5d563df7Jean Delvare && man_id == 0xA1) { /* NXP Semiconductor/Philips */ 12966d101c588f0fe08ef00f16c1a93762dd5d563df7Jean Delvare if (chip_id == 0x00 1297b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config1 & 0x2A) == 0x00 1298b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && (config2 & 0xFE) == 0x00 1299b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare && convrate <= 0x09) { 13002ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt name = "sa56004"; 13012ef017935d698b1c7c7421a7ebe20579d8f904ddStijn Devriendt } 1302ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck } else 1303ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck if ((address == 0x4C || address == 0x4D) 1304ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck && man_id == 0x47) { /* GMT */ 1305ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck if (chip_id == 0x01 /* G781 */ 1306ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck && (config1 & 0x3F) == 0x00 1307ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck && convrate <= 0x08) 1308ae544f64cc7b0850471f62e6808068ef77b90763Guenter Roeck name = "g781"; 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13118f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare if (!name) { /* identification failed */ 13128f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare dev_dbg(&adapter->dev, 13138f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare "Unsupported chip at 0x%02x (man_id=0x%02X, " 13148f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare "chip_id=0x%02X)\n", address, man_id, chip_id); 13158f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare return -ENODEV; 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13178f2fa77c53ba8c10696143c21b4111d449c85fb2Jean Delvare 13189b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare strlcpy(info->type, name, I2C_NAME_SIZE); 13199b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare 13209b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare return 0; 13219b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare} 13229b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare 1323b6fc1bacc7eae99d276d096fe0c702b1e13e4499Guenter Roeckstatic void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) 1324b6fc1bacc7eae99d276d096fe0c702b1e13e4499Guenter Roeck{ 1325b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare struct device *dev = &client->dev; 1326b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare 132706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if (data->flags & LM90_HAVE_TEMP3) 1328b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare sysfs_remove_group(&dev->kobj, &lm90_temp3_group); 132906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if (data->flags & LM90_HAVE_EMERGENCY_ALARM) 1330b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare sysfs_remove_group(&dev->kobj, &lm90_emergency_alarm_group); 13316948708dd07573c578aa99f80915cd1867334abeGuenter Roeck if (data->flags & LM90_HAVE_EMERGENCY) 1332b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare sysfs_remove_group(&dev->kobj, &lm90_emergency_group); 1333b6fc1bacc7eae99d276d096fe0c702b1e13e4499Guenter Roeck if (data->flags & LM90_HAVE_OFFSET) 1334b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare device_remove_file(dev, &sensor_dev_attr_temp2_offset.dev_attr); 1335b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare device_remove_file(dev, &dev_attr_pec); 1336b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare sysfs_remove_group(&dev->kobj, &lm90_group); 1337b6fc1bacc7eae99d276d096fe0c702b1e13e4499Guenter Roeck} 1338b6fc1bacc7eae99d276d096fe0c702b1e13e4499Guenter Roeck 1339f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeckstatic void lm90_restore_conf(struct i2c_client *client, struct lm90_data *data) 1340f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck{ 1341f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck /* Restore initial configuration */ 1342f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, 1343f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck data->convrate_orig); 1344f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, 1345f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck data->config_orig); 1346f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck} 1347f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck 134815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeckstatic void lm90_init_client(struct i2c_client *client) 134915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck{ 13500c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck u8 config, convrate; 135115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck struct lm90_data *data = i2c_get_clientdata(client); 135215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 13530c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck if (lm90_read_reg(client, LM90_REG_R_CONVRATE, &convrate) < 0) { 13540c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck dev_warn(&client->dev, "Failed to read convrate register!\n"); 13550c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck convrate = LM90_DEF_CONVRATE_RVAL; 13560c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck } 13570c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck data->convrate_orig = convrate; 13580c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 135915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck /* 136015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * Start the conversions. 136115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck */ 13620c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck lm90_set_convrate(client, data, 500); /* 500ms; 2Hz conversion rate */ 136315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) { 136415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck dev_warn(&client->dev, "Initialization failed!\n"); 136515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck return; 136615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 136715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->config_orig = config; 136815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 136915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck /* Check Temperature Range Select */ 137015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (data->kind == adt7461) { 137115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (config & 0x04) 137215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck data->flags |= LM90_FLAG_ADT7461_EXT; 137315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck } 137415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 137515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck /* 137615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * Put MAX6680/MAX8881 into extended resolution (bit 0x10, 137715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * 0.125 degree resolution) and range (0x08, extend range 137815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * to -64 degree) mode for the remote temperature sensor. 137915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck */ 138015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (data->kind == max6680) 138115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck config |= 0x18; 138215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 138315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck /* 138415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck * Select external channel 0 for max6695/96 138515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck */ 138615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (data->kind == max6696) 138715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck config &= ~0x08; 138815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 138915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck config &= 0xBF; /* run */ 139015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck if (config != data->config_orig) /* Only write if changed */ 139115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); 139215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck} 139315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck 1394b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvarestatic int lm90_probe(struct i2c_client *client, 13959b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare const struct i2c_device_id *id) 13969b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare{ 1397b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare struct device *dev = &client->dev; 1398b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare struct i2c_adapter *adapter = to_i2c_adapter(dev->parent); 13999b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare struct lm90_data *data; 14009b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare int err; 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14029b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL); 14039b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare if (!data) { 14049b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare err = -ENOMEM; 14059b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare goto exit; 14069b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare } 1407b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare i2c_set_clientdata(client, data); 14089a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_init(&data->update_lock); 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14109b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare /* Set the device type */ 14119b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare data->kind = id->driver_data; 14129b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare if (data->kind == adm1032) { 14139b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) 1414b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare client->flags &= ~I2C_CLIENT_PEC; 14159b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvare } 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1417f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck /* 1418f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * Different devices have different alarm bits triggering the 1419f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * ALERT# output 1420f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck */ 14214667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck data->alert_alarms = lm90_params[data->kind].alert_alarms; 142253de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare 142388073bb1ba969d4e3c41dc5f35c902c6b7dab0a7Guenter Roeck /* Set chip capabilities */ 14244667bcb8d8fc081a804a798df70dc91241946e0aGuenter Roeck data->flags = lm90_params[data->kind].flags; 1425a095f687f1e19c54147bd51f735717508a49e225Jean Delvare data->reg_local_ext = lm90_params[data->kind].reg_local_ext; 142606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 14270c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck /* Set maximum conversion rate */ 14280c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck data->max_convrate = lm90_params[data->kind].max_convrate; 14290c01b644f77a3df892a48a59901997469aeab0a7Guenter Roeck 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize the LM90 chip */ 1431b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare lm90_init_client(client); 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Register sysfs hooks */ 1434b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare err = sysfs_create_group(&dev->kobj, &lm90_group); 143511e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck if (err) 1436f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck goto exit_restore; 1437b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare if (client->flags & I2C_CLIENT_PEC) { 1438b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare err = device_create_file(dev, &dev_attr_pec); 143911e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck if (err) 14400e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare goto exit_remove_files; 14410e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare } 144288073bb1ba969d4e3c41dc5f35c902c6b7dab0a7Guenter Roeck if (data->flags & LM90_HAVE_OFFSET) { 1443b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare err = device_create_file(dev, 144411e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck &sensor_dev_attr_temp2_offset.dev_attr); 144511e578129af74c4866cf559e62e981c6415fffd9Guenter Roeck if (err) 144669f2f96d9c189070ed5e40ec186b755ef697288dJean Delvare goto exit_remove_files; 144769f2f96d9c189070ed5e40ec186b755ef697288dJean Delvare } 14486948708dd07573c578aa99f80915cd1867334abeGuenter Roeck if (data->flags & LM90_HAVE_EMERGENCY) { 1449b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare err = sysfs_create_group(&dev->kobj, &lm90_emergency_group); 14506948708dd07573c578aa99f80915cd1867334abeGuenter Roeck if (err) 14516948708dd07573c578aa99f80915cd1867334abeGuenter Roeck goto exit_remove_files; 14526948708dd07573c578aa99f80915cd1867334abeGuenter Roeck } 145306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if (data->flags & LM90_HAVE_EMERGENCY_ALARM) { 1454b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare err = sysfs_create_group(&dev->kobj, 145506e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck &lm90_emergency_alarm_group); 145606e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if (err) 145706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck goto exit_remove_files; 145806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck } 145906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if (data->flags & LM90_HAVE_TEMP3) { 1460b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare err = sysfs_create_group(&dev->kobj, &lm90_temp3_group); 146106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if (err) 146206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck goto exit_remove_files; 146306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck } 14640e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare 1465b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare data->hwmon_dev = hwmon_device_register(dev); 14661beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones if (IS_ERR(data->hwmon_dev)) { 14671beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones err = PTR_ERR(data->hwmon_dev); 14680e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvare goto exit_remove_files; 1469943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman } 1470943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14730e39e01c908fdc498fff0d788fd7b955ab75ebb6Jean Delvareexit_remove_files: 1474b2589ab02b46ea4a80b30a90fc2fe8eed957e86aJean Delvare lm90_remove_files(client, data); 1475f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeckexit_restore: 1476f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck lm90_restore_conf(client, data); 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(data); 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit: 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14829b0e85269275159a1f9c3e4a5d254caf5211950bJean Delvarestatic int lm90_remove(struct i2c_client *client) 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1484943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman struct lm90_data *data = i2c_get_clientdata(client); 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14861beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones hwmon_device_unregister(data->hwmon_dev); 1487b6fc1bacc7eae99d276d096fe0c702b1e13e4499Guenter Roeck lm90_remove_files(client, data); 1488f7001bb063ec06e7fff8782146a7bed49dfe6507Guenter Roeck lm90_restore_conf(client, data); 148995238364167edaf93ce2890e5f55326b63194851Jean Delvare 1490943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman kfree(data); 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 149453de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvarestatic void lm90_alert(struct i2c_client *client, unsigned int flag) 149553de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare{ 149653de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare struct lm90_data *data = i2c_get_clientdata(client); 149706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck u8 config, alarms, alarms2 = 0; 149853de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare 149953de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare lm90_read_reg(client, LM90_REG_R_STATUS, &alarms); 150006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 150106e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if (data->kind == max6696) 150206e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck lm90_read_reg(client, MAX6696_REG_R_STATUS2, &alarms2); 150306e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 150406e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if ((alarms & 0x7f) == 0 && (alarms2 & 0xfe) == 0) { 150553de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare dev_info(&client->dev, "Everything OK\n"); 150653de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare } else { 150753de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare if (alarms & 0x61) 150853de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare dev_warn(&client->dev, 150953de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare "temp%d out of range, please check!\n", 1); 151053de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare if (alarms & 0x1a) 151153de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare dev_warn(&client->dev, 151253de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare "temp%d out of range, please check!\n", 2); 151353de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare if (alarms & 0x04) 151453de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare dev_warn(&client->dev, 151553de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare "temp%d diode open, please check!\n", 2); 151653de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare 151706e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck if (alarms2 & 0x18) 151806e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck dev_warn(&client->dev, 151906e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck "temp%d out of range, please check!\n", 3); 152006e1c0a2167d48442d0bd06373390886670aa6e5Guenter Roeck 1521f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck /* 1522f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * Disable ALERT# output, because these chips don't implement 1523f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * SMBus alert correctly; they should only hold the alert line 1524f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck * low briefly. 1525f36ffeab0a1d0a0a56edd39be7a97a07486305e8Guenter Roeck */ 15261179324c411edcefb28a5293f8cc6a5bd9567448Guenter Roeck if ((data->flags & LM90_HAVE_BROKEN_ALERT) 152753de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare && (alarms & data->alert_alarms)) { 152853de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare dev_dbg(&client->dev, "Disabling ALERT#\n"); 152953de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); 153053de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, 153153de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare config | 0x80); 153253de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare } 153353de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare } 153453de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare} 153553de33427fa3d7dd62cc5ec75ce0d4e6c6d602ddJean Delvare 153615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeckstatic struct i2c_driver lm90_driver = { 153715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck .class = I2C_CLASS_HWMON, 153815b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck .driver = { 153915b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck .name = "lm90", 154015b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck }, 154115b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck .probe = lm90_probe, 154215b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck .remove = lm90_remove, 154315b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck .alert = lm90_alert, 154415b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck .id_table = lm90_id, 154515b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck .detect = lm90_detect, 154615b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck .address_list = normal_i2c, 154715b66ab69051c014d0ba9f46f7081a8a7e6ad1c3Guenter Roeck}; 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1549f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7Axel Linmodule_i2c_driver(lm90_driver); 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("LM90/ADM1032 driver"); 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 1554