174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 28d5d45fbSJean Delvare /* 3caaa0f36SShubhrajyoti D * lm75.c - Part of lm_sensors, Linux kernel modules for hardware 4caaa0f36SShubhrajyoti D * monitoring 5caaa0f36SShubhrajyoti D * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> 68d5d45fbSJean Delvare */ 78d5d45fbSJean Delvare 88d5d45fbSJean Delvare #include <linux/module.h> 98d5d45fbSJean Delvare #include <linux/init.h> 108d5d45fbSJean Delvare #include <linux/slab.h> 118d5d45fbSJean Delvare #include <linux/jiffies.h> 128d5d45fbSJean Delvare #include <linux/i2c.h> 13943b0830SMark M. Hoffman #include <linux/hwmon.h> 149ca8e40cSJean Delvare #include <linux/hwmon-sysfs.h> 15943b0830SMark M. Hoffman #include <linux/err.h> 16e97a45f1SJavier Martinez Canillas #include <linux/of_device.h> 1722e73183SEduardo Valentin #include <linux/of.h> 18e65365feSGuenter Roeck #include <linux/regmap.h> 194b5be3c1SIker Perez del Palomar Sustatxa #include <linux/util_macros.h> 208d5d45fbSJean Delvare #include "lm75.h" 218d5d45fbSJean Delvare 2201a52397SDavid Brownell /* 2301a52397SDavid Brownell * This driver handles the LM75 and compatible digital temperature sensors. 2401a52397SDavid Brownell */ 2501a52397SDavid Brownell 269ebd3d82SDavid Brownell enum lm75_type { /* keep sorted in alphabetical order */ 27e96f9d89SMichael Hennerich adt75, 281f86df49SJean Delvare ds1775, 299ebd3d82SDavid Brownell ds75, 303fbc81e3SJean Delvare ds7505, 31c98d6c65SArnaud Ebalard g751, 321f86df49SJean Delvare lm75, 339ebd3d82SDavid Brownell lm75a, 34799fc602SMichael Thalmeier lm75b, 359ebd3d82SDavid Brownell max6625, 369ebd3d82SDavid Brownell max6626, 37a54ca77aSKun Yi max31725, 389ebd3d82SDavid Brownell mcp980x, 39557c7ffaSDaniel Mack pct2075, 409ebd3d82SDavid Brownell stds75, 412e9a41bbSJagan Teki stlm75, 429ebd3d82SDavid Brownell tcn75, 439ebd3d82SDavid Brownell tmp100, 449ebd3d82SDavid Brownell tmp101, 456d034059SShubhrajyoti Datta tmp105, 46c83959f8SFrans Klaver tmp112, 479ebd3d82SDavid Brownell tmp175, 489ebd3d82SDavid Brownell tmp275, 499ebd3d82SDavid Brownell tmp75, 5039abe9d8SIker Perez del Palomar Sustatxa tmp75b, 519c32e815SBen Gardner tmp75c, 529ebd3d82SDavid Brownell }; 539ebd3d82SDavid Brownell 54dcb12653SIker Perez del Palomar Sustatxa /** 55dcb12653SIker Perez del Palomar Sustatxa * struct lm75_params - lm75 configuration parameters. 56dcb12653SIker Perez del Palomar Sustatxa * @set_mask: Bits to set in configuration register when configuring 57dcb12653SIker Perez del Palomar Sustatxa * the chip. 58dcb12653SIker Perez del Palomar Sustatxa * @clr_mask: Bits to clear in configuration register when configuring 59dcb12653SIker Perez del Palomar Sustatxa * the chip. 60dcb12653SIker Perez del Palomar Sustatxa * @default_resolution: Default number of bits to represent the temperature 61dcb12653SIker Perez del Palomar Sustatxa * value. 62dcb12653SIker Perez del Palomar Sustatxa * @resolution_limits: Limit register resolution. Optional. Should be set if 63dcb12653SIker Perez del Palomar Sustatxa * the resolution of limit registers does not match the 64dcb12653SIker Perez del Palomar Sustatxa * resolution of the temperature register. 657f1a300fSIker Perez del Palomar Sustatxa * @resolutions: List of resolutions associated with sample times. 667f1a300fSIker Perez del Palomar Sustatxa * Optional. Should be set if num_sample_times is larger 677f1a300fSIker Perez del Palomar Sustatxa * than 1, and if the resolution changes with sample times. 687f1a300fSIker Perez del Palomar Sustatxa * If set, number of entries must match num_sample_times. 697f1a300fSIker Perez del Palomar Sustatxa * @default_sample_time:Sample time to be set by default. 707f1a300fSIker Perez del Palomar Sustatxa * @num_sample_times: Number of possible sample times to be set. Optional. 717f1a300fSIker Perez del Palomar Sustatxa * Should be set if the number of sample times is larger 727f1a300fSIker Perez del Palomar Sustatxa * than one. 737f1a300fSIker Perez del Palomar Sustatxa * @sample_times: All the possible sample times to be set. Mandatory if 747f1a300fSIker Perez del Palomar Sustatxa * num_sample_times is larger than 1. If set, number of 757f1a300fSIker Perez del Palomar Sustatxa * entries must match num_sample_times. 76dcb12653SIker Perez del Palomar Sustatxa */ 77dcb12653SIker Perez del Palomar Sustatxa 78dcb12653SIker Perez del Palomar Sustatxa struct lm75_params { 79dcb12653SIker Perez del Palomar Sustatxa u8 set_mask; 80dcb12653SIker Perez del Palomar Sustatxa u8 clr_mask; 81dcb12653SIker Perez del Palomar Sustatxa u8 default_resolution; 82dcb12653SIker Perez del Palomar Sustatxa u8 resolution_limits; 837f1a300fSIker Perez del Palomar Sustatxa const u8 *resolutions; 84dcb12653SIker Perez del Palomar Sustatxa unsigned int default_sample_time; 857f1a300fSIker Perez del Palomar Sustatxa u8 num_sample_times; 867f1a300fSIker Perez del Palomar Sustatxa const unsigned int *sample_times; 87dcb12653SIker Perez del Palomar Sustatxa }; 88dcb12653SIker Perez del Palomar Sustatxa 898ff69eebSJean Delvare /* Addresses scanned */ 9025e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 918d5d45fbSJean Delvare 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 928d5d45fbSJean Delvare 938d5d45fbSJean Delvare /* The LM75 registers */ 94e65365feSGuenter Roeck #define LM75_REG_TEMP 0x00 958d5d45fbSJean Delvare #define LM75_REG_CONF 0x01 96e65365feSGuenter Roeck #define LM75_REG_HYST 0x02 97e65365feSGuenter Roeck #define LM75_REG_MAX 0x03 98d7a85cdeSGuenter Roeck #define PCT2075_REG_IDLE 0x04 998d5d45fbSJean Delvare 1008d5d45fbSJean Delvare /* Each client has this additional data */ 1018d5d45fbSJean Delvare struct lm75_data { 102d663ec49SGuenter Roeck struct i2c_client *client; 103e65365feSGuenter Roeck struct regmap *regmap; 1049ebd3d82SDavid Brownell u8 orig_conf; 105dcb12653SIker Perez del Palomar Sustatxa u8 current_conf; 106dcb12653SIker Perez del Palomar Sustatxa u8 resolution; /* In bits, 9 to 16 */ 107e65365feSGuenter Roeck unsigned int sample_time; /* In ms */ 108dcb12653SIker Perez del Palomar Sustatxa enum lm75_type kind; 109dcb12653SIker Perez del Palomar Sustatxa const struct lm75_params *params; 1108d5d45fbSJean Delvare }; 1118d5d45fbSJean Delvare 11201a52397SDavid Brownell /*-----------------------------------------------------------------------*/ 1137db0db3fSGuenter Roeck 1147db0db3fSGuenter Roeck static const u8 lm75_sample_set_masks[] = { 0 << 5, 1 << 5, 2 << 5, 3 << 5 }; 1157db0db3fSGuenter Roeck 1167db0db3fSGuenter Roeck #define LM75_SAMPLE_CLEAR_MASK (3 << 5) 1177db0db3fSGuenter Roeck 118dcb12653SIker Perez del Palomar Sustatxa /* The structure below stores the configuration values of the supported devices. 119dcb12653SIker Perez del Palomar Sustatxa * In case of being supported multiple configurations, the default one must 120dcb12653SIker Perez del Palomar Sustatxa * always be the first element of the array 121dcb12653SIker Perez del Palomar Sustatxa */ 122dcb12653SIker Perez del Palomar Sustatxa static const struct lm75_params device_params[] = { 123dcb12653SIker Perez del Palomar Sustatxa [adt75] = { 124dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 5, /* not one-shot mode */ 125dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 12635cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10, 127dcb12653SIker Perez del Palomar Sustatxa }, 128dcb12653SIker Perez del Palomar Sustatxa [ds1775] = { 129dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 3 << 5, 130dcb12653SIker Perez del Palomar Sustatxa .set_mask = 2 << 5, /* 11-bit mode */ 131dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11, 13235cd1804SIker Perez del Palomar Sustatxa .default_sample_time = 500, 1337db0db3fSGuenter Roeck .num_sample_times = 4, 13435cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 125, 250, 500, 1000 }, 1357db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 136dcb12653SIker Perez del Palomar Sustatxa }, 137dcb12653SIker Perez del Palomar Sustatxa [ds75] = { 138dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 3 << 5, 139dcb12653SIker Perez del Palomar Sustatxa .set_mask = 2 << 5, /* 11-bit mode */ 140dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11, 1417db0db3fSGuenter Roeck .default_sample_time = 600, 1427db0db3fSGuenter Roeck .num_sample_times = 4, 1437db0db3fSGuenter Roeck .sample_times = (unsigned int []){ 150, 300, 600, 1200 }, 1447db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 145dcb12653SIker Perez del Palomar Sustatxa }, 146dcb12653SIker Perez del Palomar Sustatxa [stds75] = { 147dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 3 << 5, 148dcb12653SIker Perez del Palomar Sustatxa .set_mask = 2 << 5, /* 11-bit mode */ 149dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11, 1507db0db3fSGuenter Roeck .default_sample_time = 600, 1517db0db3fSGuenter Roeck .num_sample_times = 4, 1527db0db3fSGuenter Roeck .sample_times = (unsigned int []){ 150, 300, 600, 1200 }, 1537db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 154dcb12653SIker Perez del Palomar Sustatxa }, 155dcb12653SIker Perez del Palomar Sustatxa [stlm75] = { 156dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9, 15735cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 6, 158dcb12653SIker Perez del Palomar Sustatxa }, 159dcb12653SIker Perez del Palomar Sustatxa [ds7505] = { 160dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode*/ 161dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 1627db0db3fSGuenter Roeck .default_sample_time = 200, 1637db0db3fSGuenter Roeck .num_sample_times = 4, 1647db0db3fSGuenter Roeck .sample_times = (unsigned int []){ 25, 50, 100, 200 }, 1657db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 166dcb12653SIker Perez del Palomar Sustatxa }, 167dcb12653SIker Perez del Palomar Sustatxa [g751] = { 168dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9, 16935cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10, 170dcb12653SIker Perez del Palomar Sustatxa }, 171dcb12653SIker Perez del Palomar Sustatxa [lm75] = { 172dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9, 17335cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10, 174dcb12653SIker Perez del Palomar Sustatxa }, 175dcb12653SIker Perez del Palomar Sustatxa [lm75a] = { 176dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9, 17735cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10, 178dcb12653SIker Perez del Palomar Sustatxa }, 179dcb12653SIker Perez del Palomar Sustatxa [lm75b] = { 180dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11, 18135cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10, 182dcb12653SIker Perez del Palomar Sustatxa }, 183dcb12653SIker Perez del Palomar Sustatxa [max6625] = { 184dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9, 18535cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 7, 186dcb12653SIker Perez del Palomar Sustatxa }, 187dcb12653SIker Perez del Palomar Sustatxa [max6626] = { 188dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 18935cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 7, 190dcb12653SIker Perez del Palomar Sustatxa .resolution_limits = 9, 191dcb12653SIker Perez del Palomar Sustatxa }, 192dcb12653SIker Perez del Palomar Sustatxa [max31725] = { 193dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 16, 19435cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 20, 195dcb12653SIker Perez del Palomar Sustatxa }, 196dcb12653SIker Perez del Palomar Sustatxa [tcn75] = { 197dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9, 19835cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 18, 199dcb12653SIker Perez del Palomar Sustatxa }, 200dcb12653SIker Perez del Palomar Sustatxa [pct2075] = { 201dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11, 202dcb12653SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10, 203d7a85cdeSGuenter Roeck .num_sample_times = 31, 204d7a85cdeSGuenter Roeck .sample_times = (unsigned int []){ 100, 200, 300, 400, 500, 600, 205d7a85cdeSGuenter Roeck 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 206d7a85cdeSGuenter Roeck 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 207d7a85cdeSGuenter Roeck 2800, 2900, 3000, 3100 }, 208dcb12653SIker Perez del Palomar Sustatxa }, 209dcb12653SIker Perez del Palomar Sustatxa [mcp980x] = { 210dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */ 211dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode */ 212dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 213dcb12653SIker Perez del Palomar Sustatxa .resolution_limits = 9, 2147db0db3fSGuenter Roeck .default_sample_time = 240, 2157db0db3fSGuenter Roeck .num_sample_times = 4, 21635cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 30, 60, 120, 240 }, 2177db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 218dcb12653SIker Perez del Palomar Sustatxa }, 219dcb12653SIker Perez del Palomar Sustatxa [tmp100] = { 220dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */ 221dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode */ 222dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 2237db0db3fSGuenter Roeck .default_sample_time = 320, 2247db0db3fSGuenter Roeck .num_sample_times = 4, 22535cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 40, 80, 160, 320 }, 2267db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 227dcb12653SIker Perez del Palomar Sustatxa }, 228dcb12653SIker Perez del Palomar Sustatxa [tmp101] = { 229dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */ 230dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode */ 231dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 2327db0db3fSGuenter Roeck .default_sample_time = 320, 2337db0db3fSGuenter Roeck .num_sample_times = 4, 23435cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 40, 80, 160, 320 }, 2357db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 2367db0db3fSGuenter Roeck }, 2377db0db3fSGuenter Roeck [tmp105] = { 2387db0db3fSGuenter Roeck .set_mask = 3 << 5, /* 12-bit mode */ 2397db0db3fSGuenter Roeck .clr_mask = 1 << 7, /* not one-shot mode*/ 2407db0db3fSGuenter Roeck .default_resolution = 12, 2417db0db3fSGuenter Roeck .default_sample_time = 220, 2427db0db3fSGuenter Roeck .num_sample_times = 4, 24335cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 28, 55, 110, 220 }, 2447db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 245dcb12653SIker Perez del Palomar Sustatxa }, 246dcb12653SIker Perez del Palomar Sustatxa [tmp112] = { 24735cd1804SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 8 samples / second */ 248dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* no one-shot mode*/ 249dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 25035cd1804SIker Perez del Palomar Sustatxa .default_sample_time = 125, 251cee04a01SGuenter Roeck .num_sample_times = 4, 252cee04a01SGuenter Roeck .sample_times = (unsigned int []){ 125, 250, 1000, 4000 }, 253dcb12653SIker Perez del Palomar Sustatxa }, 254dcb12653SIker Perez del Palomar Sustatxa [tmp175] = { 255dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */ 256dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode*/ 257dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 2587db0db3fSGuenter Roeck .default_sample_time = 220, 2597db0db3fSGuenter Roeck .num_sample_times = 4, 26035cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 28, 55, 110, 220 }, 2617db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 262dcb12653SIker Perez del Palomar Sustatxa }, 263dcb12653SIker Perez del Palomar Sustatxa [tmp275] = { 264dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */ 265dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode*/ 266dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 2677db0db3fSGuenter Roeck .default_sample_time = 220, 2687db0db3fSGuenter Roeck .num_sample_times = 4, 26935cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 28, 55, 110, 220 }, 2707db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 271dcb12653SIker Perez del Palomar Sustatxa }, 272dcb12653SIker Perez del Palomar Sustatxa [tmp75] = { 273dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */ 274dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode*/ 275dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 2767db0db3fSGuenter Roeck .default_sample_time = 220, 2777db0db3fSGuenter Roeck .num_sample_times = 4, 27835cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 28, 55, 110, 220 }, 2797db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 }, 280dcb12653SIker Perez del Palomar Sustatxa }, 281dcb12653SIker Perez del Palomar Sustatxa [tmp75b] = { /* not one-shot mode, Conversion rate 37Hz */ 282dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7 | 3 << 5, 283dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 284dcb12653SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 37, 2857f1a300fSIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ MSEC_PER_SEC / 37, 2867f1a300fSIker Perez del Palomar Sustatxa MSEC_PER_SEC / 18, 2877f1a300fSIker Perez del Palomar Sustatxa MSEC_PER_SEC / 9, MSEC_PER_SEC / 4 }, 2887f1a300fSIker Perez del Palomar Sustatxa .num_sample_times = 4, 289dcb12653SIker Perez del Palomar Sustatxa }, 290dcb12653SIker Perez del Palomar Sustatxa [tmp75c] = { 291dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 5, /*not one-shot mode*/ 292dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12, 29335cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 12, 294dcb12653SIker Perez del Palomar Sustatxa } 295dcb12653SIker Perez del Palomar Sustatxa }; 29601a52397SDavid Brownell 29722e73183SEduardo Valentin static inline long lm75_reg_to_mc(s16 temp, u8 resolution) 29822e73183SEduardo Valentin { 29922e73183SEduardo Valentin return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); 30022e73183SEduardo Valentin } 30122e73183SEduardo Valentin 30258608cfeSIker Perez del Palomar Sustatxa static int lm75_write_config(struct lm75_data *data, u8 set_mask, 30358608cfeSIker Perez del Palomar Sustatxa u8 clr_mask) 30458608cfeSIker Perez del Palomar Sustatxa { 30558608cfeSIker Perez del Palomar Sustatxa u8 value; 30658608cfeSIker Perez del Palomar Sustatxa 30758608cfeSIker Perez del Palomar Sustatxa clr_mask |= LM75_SHUTDOWN; 30858608cfeSIker Perez del Palomar Sustatxa value = data->current_conf & ~clr_mask; 30958608cfeSIker Perez del Palomar Sustatxa value |= set_mask; 31058608cfeSIker Perez del Palomar Sustatxa 31158608cfeSIker Perez del Palomar Sustatxa if (data->current_conf != value) { 31258608cfeSIker Perez del Palomar Sustatxa s32 err; 31358608cfeSIker Perez del Palomar Sustatxa 31458608cfeSIker Perez del Palomar Sustatxa err = i2c_smbus_write_byte_data(data->client, LM75_REG_CONF, 31558608cfeSIker Perez del Palomar Sustatxa value); 31658608cfeSIker Perez del Palomar Sustatxa if (err) 31758608cfeSIker Perez del Palomar Sustatxa return err; 31858608cfeSIker Perez del Palomar Sustatxa data->current_conf = value; 31958608cfeSIker Perez del Palomar Sustatxa } 32058608cfeSIker Perez del Palomar Sustatxa return 0; 32158608cfeSIker Perez del Palomar Sustatxa } 32258608cfeSIker Perez del Palomar Sustatxa 32308b02433SGuenter Roeck static int lm75_read(struct device *dev, enum hwmon_sensor_types type, 32408b02433SGuenter Roeck u32 attr, int channel, long *val) 32522e73183SEduardo Valentin { 326e65365feSGuenter Roeck struct lm75_data *data = dev_get_drvdata(dev); 32708b02433SGuenter Roeck unsigned int regval; 32808b02433SGuenter Roeck int err, reg; 32922e73183SEduardo Valentin 33008b02433SGuenter Roeck switch (type) { 33108b02433SGuenter Roeck case hwmon_chip: 33208b02433SGuenter Roeck switch (attr) { 33308b02433SGuenter Roeck case hwmon_chip_update_interval: 33408b02433SGuenter Roeck *val = data->sample_time; 335ccffe776SLuis de Bethencourt break; 33608b02433SGuenter Roeck default: 33708b02433SGuenter Roeck return -EINVAL; 33808b02433SGuenter Roeck } 33908b02433SGuenter Roeck break; 34008b02433SGuenter Roeck case hwmon_temp: 34108b02433SGuenter Roeck switch (attr) { 34208b02433SGuenter Roeck case hwmon_temp_input: 34308b02433SGuenter Roeck reg = LM75_REG_TEMP; 34408b02433SGuenter Roeck break; 34508b02433SGuenter Roeck case hwmon_temp_max: 34608b02433SGuenter Roeck reg = LM75_REG_MAX; 34708b02433SGuenter Roeck break; 34808b02433SGuenter Roeck case hwmon_temp_max_hyst: 34908b02433SGuenter Roeck reg = LM75_REG_HYST; 35008b02433SGuenter Roeck break; 35108b02433SGuenter Roeck default: 35208b02433SGuenter Roeck return -EINVAL; 35308b02433SGuenter Roeck } 35408b02433SGuenter Roeck err = regmap_read(data->regmap, reg, ®val); 355e65365feSGuenter Roeck if (err < 0) 356e65365feSGuenter Roeck return err; 35722e73183SEduardo Valentin 35808b02433SGuenter Roeck *val = lm75_reg_to_mc(regval, data->resolution); 35908b02433SGuenter Roeck break; 36008b02433SGuenter Roeck default: 36108b02433SGuenter Roeck return -EINVAL; 36208b02433SGuenter Roeck } 36322e73183SEduardo Valentin return 0; 36422e73183SEduardo Valentin } 36522e73183SEduardo Valentin 3664b5be3c1SIker Perez del Palomar Sustatxa static int lm75_write_temp(struct device *dev, u32 attr, long temp) 3679ca8e40cSJean Delvare { 368e65365feSGuenter Roeck struct lm75_data *data = dev_get_drvdata(dev); 36987d0621aSJean Delvare u8 resolution; 37008b02433SGuenter Roeck int reg; 371e3cd9528SShubhrajyoti D 37208b02433SGuenter Roeck switch (attr) { 37308b02433SGuenter Roeck case hwmon_temp_max: 37408b02433SGuenter Roeck reg = LM75_REG_MAX; 37508b02433SGuenter Roeck break; 37608b02433SGuenter Roeck case hwmon_temp_max_hyst: 37708b02433SGuenter Roeck reg = LM75_REG_HYST; 37808b02433SGuenter Roeck break; 37908b02433SGuenter Roeck default: 38008b02433SGuenter Roeck return -EINVAL; 38108b02433SGuenter Roeck } 3829ca8e40cSJean Delvare 38387d0621aSJean Delvare /* 38487d0621aSJean Delvare * Resolution of limit registers is assumed to be the same as the 38587d0621aSJean Delvare * temperature input register resolution unless given explicitly. 38687d0621aSJean Delvare */ 387dcb12653SIker Perez del Palomar Sustatxa if (data->params->resolution_limits) 388dcb12653SIker Perez del Palomar Sustatxa resolution = data->params->resolution_limits; 38987d0621aSJean Delvare else 39087d0621aSJean Delvare resolution = data->resolution; 39187d0621aSJean Delvare 39287d0621aSJean Delvare temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); 393e65365feSGuenter Roeck temp = DIV_ROUND_CLOSEST(temp << (resolution - 8), 39487d0621aSJean Delvare 1000) << (16 - resolution); 395e65365feSGuenter Roeck 3967d82fcc9SGuenter Roeck return regmap_write(data->regmap, reg, (u16)temp); 3978d5d45fbSJean Delvare } 3988d5d45fbSJean Delvare 399040b106fSGuenter Roeck static int lm75_update_interval(struct device *dev, long val) 4004b5be3c1SIker Perez del Palomar Sustatxa { 4014b5be3c1SIker Perez del Palomar Sustatxa struct lm75_data *data = dev_get_drvdata(dev); 402cee04a01SGuenter Roeck unsigned int reg; 4034b5be3c1SIker Perez del Palomar Sustatxa u8 index; 4044b5be3c1SIker Perez del Palomar Sustatxa s32 err; 4054b5be3c1SIker Perez del Palomar Sustatxa 4064b5be3c1SIker Perez del Palomar Sustatxa index = find_closest(val, data->params->sample_times, 4074b5be3c1SIker Perez del Palomar Sustatxa (int)data->params->num_sample_times); 4084b5be3c1SIker Perez del Palomar Sustatxa 409cee04a01SGuenter Roeck switch (data->kind) { 410cee04a01SGuenter Roeck default: 411040b106fSGuenter Roeck err = lm75_write_config(data, lm75_sample_set_masks[index], 4127db0db3fSGuenter Roeck LM75_SAMPLE_CLEAR_MASK); 4134b5be3c1SIker Perez del Palomar Sustatxa if (err) 4144b5be3c1SIker Perez del Palomar Sustatxa return err; 4154b5be3c1SIker Perez del Palomar Sustatxa 416040b106fSGuenter Roeck data->sample_time = data->params->sample_times[index]; 4174b5be3c1SIker Perez del Palomar Sustatxa if (data->params->resolutions) 4184b5be3c1SIker Perez del Palomar Sustatxa data->resolution = data->params->resolutions[index]; 419cee04a01SGuenter Roeck break; 420cee04a01SGuenter Roeck case tmp112: 421cee04a01SGuenter Roeck err = regmap_read(data->regmap, LM75_REG_CONF, ®); 422cee04a01SGuenter Roeck if (err < 0) 423cee04a01SGuenter Roeck return err; 424cee04a01SGuenter Roeck reg &= ~0x00c0; 425cee04a01SGuenter Roeck reg |= (3 - index) << 6; 426cee04a01SGuenter Roeck err = regmap_write(data->regmap, LM75_REG_CONF, reg); 427cee04a01SGuenter Roeck if (err < 0) 428cee04a01SGuenter Roeck return err; 429cee04a01SGuenter Roeck data->sample_time = data->params->sample_times[index]; 430cee04a01SGuenter Roeck break; 431d7a85cdeSGuenter Roeck case pct2075: 432d7a85cdeSGuenter Roeck err = i2c_smbus_write_byte_data(data->client, PCT2075_REG_IDLE, 433d7a85cdeSGuenter Roeck index + 1); 434d7a85cdeSGuenter Roeck if (err) 435d7a85cdeSGuenter Roeck return err; 436d7a85cdeSGuenter Roeck data->sample_time = data->params->sample_times[index]; 437d7a85cdeSGuenter Roeck break; 438cee04a01SGuenter Roeck } 439040b106fSGuenter Roeck return 0; 440040b106fSGuenter Roeck } 441040b106fSGuenter Roeck 442040b106fSGuenter Roeck static int lm75_write_chip(struct device *dev, u32 attr, long val) 443040b106fSGuenter Roeck { 444040b106fSGuenter Roeck switch (attr) { 445040b106fSGuenter Roeck case hwmon_chip_update_interval: 446040b106fSGuenter Roeck return lm75_update_interval(dev, val); 4474b5be3c1SIker Perez del Palomar Sustatxa default: 4484b5be3c1SIker Perez del Palomar Sustatxa return -EINVAL; 4494b5be3c1SIker Perez del Palomar Sustatxa } 4504b5be3c1SIker Perez del Palomar Sustatxa return 0; 4514b5be3c1SIker Perez del Palomar Sustatxa } 4524b5be3c1SIker Perez del Palomar Sustatxa 4534b5be3c1SIker Perez del Palomar Sustatxa static int lm75_write(struct device *dev, enum hwmon_sensor_types type, 4544b5be3c1SIker Perez del Palomar Sustatxa u32 attr, int channel, long val) 4554b5be3c1SIker Perez del Palomar Sustatxa { 4564b5be3c1SIker Perez del Palomar Sustatxa switch (type) { 4574b5be3c1SIker Perez del Palomar Sustatxa case hwmon_chip: 4584b5be3c1SIker Perez del Palomar Sustatxa return lm75_write_chip(dev, attr, val); 4594b5be3c1SIker Perez del Palomar Sustatxa case hwmon_temp: 4604b5be3c1SIker Perez del Palomar Sustatxa return lm75_write_temp(dev, attr, val); 4614b5be3c1SIker Perez del Palomar Sustatxa default: 4624b5be3c1SIker Perez del Palomar Sustatxa return -EINVAL; 4634b5be3c1SIker Perez del Palomar Sustatxa } 4644b5be3c1SIker Perez del Palomar Sustatxa return 0; 4654b5be3c1SIker Perez del Palomar Sustatxa } 4664b5be3c1SIker Perez del Palomar Sustatxa 46708b02433SGuenter Roeck static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type, 46808b02433SGuenter Roeck u32 attr, int channel) 4695f7e5e29SGuenter Roeck { 4704b5be3c1SIker Perez del Palomar Sustatxa const struct lm75_data *config_data = data; 4714b5be3c1SIker Perez del Palomar Sustatxa 47208b02433SGuenter Roeck switch (type) { 47308b02433SGuenter Roeck case hwmon_chip: 47408b02433SGuenter Roeck switch (attr) { 47508b02433SGuenter Roeck case hwmon_chip_update_interval: 4764b5be3c1SIker Perez del Palomar Sustatxa if (config_data->params->num_sample_times > 1) 4774b5be3c1SIker Perez del Palomar Sustatxa return 0644; 478e6ab6e0eSGuenter Roeck return 0444; 4795f7e5e29SGuenter Roeck } 48008b02433SGuenter Roeck break; 48108b02433SGuenter Roeck case hwmon_temp: 48208b02433SGuenter Roeck switch (attr) { 48308b02433SGuenter Roeck case hwmon_temp_input: 484e6ab6e0eSGuenter Roeck return 0444; 48508b02433SGuenter Roeck case hwmon_temp_max: 48608b02433SGuenter Roeck case hwmon_temp_max_hyst: 487e6ab6e0eSGuenter Roeck return 0644; 48808b02433SGuenter Roeck } 48908b02433SGuenter Roeck break; 49008b02433SGuenter Roeck default: 49108b02433SGuenter Roeck break; 49208b02433SGuenter Roeck } 49308b02433SGuenter Roeck return 0; 49408b02433SGuenter Roeck } 4952251aef6SEduardo Valentin 49608b02433SGuenter Roeck static const struct hwmon_channel_info *lm75_info[] = { 497e4f6fed1SGuenter Roeck HWMON_CHANNEL_INFO(chip, 498e4f6fed1SGuenter Roeck HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL), 499e4f6fed1SGuenter Roeck HWMON_CHANNEL_INFO(temp, 500e4f6fed1SGuenter Roeck HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), 50108b02433SGuenter Roeck NULL 50208b02433SGuenter Roeck }; 50308b02433SGuenter Roeck 50408b02433SGuenter Roeck static const struct hwmon_ops lm75_hwmon_ops = { 50508b02433SGuenter Roeck .is_visible = lm75_is_visible, 50608b02433SGuenter Roeck .read = lm75_read, 50708b02433SGuenter Roeck .write = lm75_write, 50808b02433SGuenter Roeck }; 50908b02433SGuenter Roeck 51008b02433SGuenter Roeck static const struct hwmon_chip_info lm75_chip_info = { 51108b02433SGuenter Roeck .ops = &lm75_hwmon_ops, 51208b02433SGuenter Roeck .info = lm75_info, 51308b02433SGuenter Roeck }; 51408b02433SGuenter Roeck 515e65365feSGuenter Roeck static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg) 516e65365feSGuenter Roeck { 517e65365feSGuenter Roeck return reg != LM75_REG_TEMP; 518e65365feSGuenter Roeck } 519e65365feSGuenter Roeck 520e65365feSGuenter Roeck static bool lm75_is_volatile_reg(struct device *dev, unsigned int reg) 521e65365feSGuenter Roeck { 522cee04a01SGuenter Roeck return reg == LM75_REG_TEMP || reg == LM75_REG_CONF; 523e65365feSGuenter Roeck } 524e65365feSGuenter Roeck 525e65365feSGuenter Roeck static const struct regmap_config lm75_regmap_config = { 526e65365feSGuenter Roeck .reg_bits = 8, 527e65365feSGuenter Roeck .val_bits = 16, 528d7a85cdeSGuenter Roeck .max_register = PCT2075_REG_IDLE, 529e65365feSGuenter Roeck .writeable_reg = lm75_is_writeable_reg, 530e65365feSGuenter Roeck .volatile_reg = lm75_is_volatile_reg, 531e65365feSGuenter Roeck .val_format_endian = REGMAP_ENDIAN_BIG, 532e65365feSGuenter Roeck .cache_type = REGCACHE_RBTREE, 5331c96a2f6SDavid Frey .use_single_read = true, 5341c96a2f6SDavid Frey .use_single_write = true, 535e65365feSGuenter Roeck }; 536e65365feSGuenter Roeck 5379e37d3e2SGuenter Roeck static void lm75_remove(void *data) 5389e37d3e2SGuenter Roeck { 5399e37d3e2SGuenter Roeck struct lm75_data *lm75 = data; 5409e37d3e2SGuenter Roeck struct i2c_client *client = lm75->client; 5419e37d3e2SGuenter Roeck 5429e37d3e2SGuenter Roeck i2c_smbus_write_byte_data(client, LM75_REG_CONF, lm75->orig_conf); 5439e37d3e2SGuenter Roeck } 5449e37d3e2SGuenter Roeck 5459ebd3d82SDavid Brownell static int 5469ebd3d82SDavid Brownell lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) 5479ebd3d82SDavid Brownell { 548d663ec49SGuenter Roeck struct device *dev = &client->dev; 5499e37d3e2SGuenter Roeck struct device *hwmon_dev; 5509ebd3d82SDavid Brownell struct lm75_data *data; 55190e2b545SGuenter Roeck int status, err; 552e97a45f1SJavier Martinez Canillas enum lm75_type kind; 553e97a45f1SJavier Martinez Canillas 554e97a45f1SJavier Martinez Canillas if (client->dev.of_node) 555e97a45f1SJavier Martinez Canillas kind = (enum lm75_type)of_device_get_match_data(&client->dev); 556e97a45f1SJavier Martinez Canillas else 557e97a45f1SJavier Martinez Canillas kind = id->driver_data; 5589ebd3d82SDavid Brownell 5599ebd3d82SDavid Brownell if (!i2c_check_functionality(client->adapter, 5609ebd3d82SDavid Brownell I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) 5619ebd3d82SDavid Brownell return -EIO; 5629ebd3d82SDavid Brownell 563d663ec49SGuenter Roeck data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); 5649ebd3d82SDavid Brownell if (!data) 5659ebd3d82SDavid Brownell return -ENOMEM; 5669ebd3d82SDavid Brownell 567d663ec49SGuenter Roeck data->client = client; 568dcb12653SIker Perez del Palomar Sustatxa data->kind = kind; 569e65365feSGuenter Roeck 570e65365feSGuenter Roeck data->regmap = devm_regmap_init_i2c(client, &lm75_regmap_config); 571e65365feSGuenter Roeck if (IS_ERR(data->regmap)) 572e65365feSGuenter Roeck return PTR_ERR(data->regmap); 5739ebd3d82SDavid Brownell 5749ebd3d82SDavid Brownell /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. 5759ebd3d82SDavid Brownell * Then tweak to be more precise when appropriate. 5769ebd3d82SDavid Brownell */ 5778a5c5cc6SJean Delvare 578dcb12653SIker Perez del Palomar Sustatxa data->params = &device_params[data->kind]; 5799ebd3d82SDavid Brownell 580dcb12653SIker Perez del Palomar Sustatxa /* Save default sample time and resolution*/ 581dcb12653SIker Perez del Palomar Sustatxa data->sample_time = data->params->default_sample_time; 582dcb12653SIker Perez del Palomar Sustatxa data->resolution = data->params->default_resolution; 583dcb12653SIker Perez del Palomar Sustatxa 584dcb12653SIker Perez del Palomar Sustatxa /* Cache original configuration */ 58538aefb41SGuenter Roeck status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); 5869ebd3d82SDavid Brownell if (status < 0) { 587d663ec49SGuenter Roeck dev_dbg(dev, "Can't read config? %d\n", status); 58813ac7a01SGuenter Roeck return status; 5899ebd3d82SDavid Brownell } 5909ebd3d82SDavid Brownell data->orig_conf = status; 59158608cfeSIker Perez del Palomar Sustatxa data->current_conf = status; 59258608cfeSIker Perez del Palomar Sustatxa 59358608cfeSIker Perez del Palomar Sustatxa err = lm75_write_config(data, data->params->set_mask, 59458608cfeSIker Perez del Palomar Sustatxa data->params->clr_mask); 59558608cfeSIker Perez del Palomar Sustatxa if (err) 59658608cfeSIker Perez del Palomar Sustatxa return err; 5979e37d3e2SGuenter Roeck 59890e2b545SGuenter Roeck err = devm_add_action_or_reset(dev, lm75_remove, data); 59990e2b545SGuenter Roeck if (err) 60090e2b545SGuenter Roeck return err; 6019e37d3e2SGuenter Roeck 60208b02433SGuenter Roeck hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 60308b02433SGuenter Roeck data, &lm75_chip_info, 60408b02433SGuenter Roeck NULL); 6059e37d3e2SGuenter Roeck if (IS_ERR(hwmon_dev)) 6069e37d3e2SGuenter Roeck return PTR_ERR(hwmon_dev); 6079ebd3d82SDavid Brownell 6089e37d3e2SGuenter Roeck dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name); 6099ebd3d82SDavid Brownell 6109ebd3d82SDavid Brownell return 0; 6119ebd3d82SDavid Brownell } 6129ebd3d82SDavid Brownell 6139ebd3d82SDavid Brownell static const struct i2c_device_id lm75_ids[] = { 614e96f9d89SMichael Hennerich { "adt75", adt75, }, 6159ebd3d82SDavid Brownell { "ds1775", ds1775, }, 6169ebd3d82SDavid Brownell { "ds75", ds75, }, 6173fbc81e3SJean Delvare { "ds7505", ds7505, }, 618c98d6c65SArnaud Ebalard { "g751", g751, }, 6199ebd3d82SDavid Brownell { "lm75", lm75, }, 6209ebd3d82SDavid Brownell { "lm75a", lm75a, }, 621799fc602SMichael Thalmeier { "lm75b", lm75b, }, 6229ebd3d82SDavid Brownell { "max6625", max6625, }, 6239ebd3d82SDavid Brownell { "max6626", max6626, }, 624a54ca77aSKun Yi { "max31725", max31725, }, 625a54ca77aSKun Yi { "max31726", max31725, }, 6269ebd3d82SDavid Brownell { "mcp980x", mcp980x, }, 627557c7ffaSDaniel Mack { "pct2075", pct2075, }, 6289ebd3d82SDavid Brownell { "stds75", stds75, }, 6292e9a41bbSJagan Teki { "stlm75", stlm75, }, 6309ebd3d82SDavid Brownell { "tcn75", tcn75, }, 6319ebd3d82SDavid Brownell { "tmp100", tmp100, }, 6329ebd3d82SDavid Brownell { "tmp101", tmp101, }, 6336d034059SShubhrajyoti Datta { "tmp105", tmp105, }, 634c83959f8SFrans Klaver { "tmp112", tmp112, }, 6359ebd3d82SDavid Brownell { "tmp175", tmp175, }, 6369ebd3d82SDavid Brownell { "tmp275", tmp275, }, 6379ebd3d82SDavid Brownell { "tmp75", tmp75, }, 63839abe9d8SIker Perez del Palomar Sustatxa { "tmp75b", tmp75b, }, 6399c32e815SBen Gardner { "tmp75c", tmp75c, }, 6409ebd3d82SDavid Brownell { /* LIST END */ } 6419ebd3d82SDavid Brownell }; 6429ebd3d82SDavid Brownell MODULE_DEVICE_TABLE(i2c, lm75_ids); 6439ebd3d82SDavid Brownell 644ffa83e78SGuenter Roeck static const struct of_device_id __maybe_unused lm75_of_match[] = { 645e97a45f1SJavier Martinez Canillas { 646e97a45f1SJavier Martinez Canillas .compatible = "adi,adt75", 647e97a45f1SJavier Martinez Canillas .data = (void *)adt75 648e97a45f1SJavier Martinez Canillas }, 649e97a45f1SJavier Martinez Canillas { 650e97a45f1SJavier Martinez Canillas .compatible = "dallas,ds1775", 651e97a45f1SJavier Martinez Canillas .data = (void *)ds1775 652e97a45f1SJavier Martinez Canillas }, 653e97a45f1SJavier Martinez Canillas { 654e97a45f1SJavier Martinez Canillas .compatible = "dallas,ds75", 655e97a45f1SJavier Martinez Canillas .data = (void *)ds75 656e97a45f1SJavier Martinez Canillas }, 657e97a45f1SJavier Martinez Canillas { 658e97a45f1SJavier Martinez Canillas .compatible = "dallas,ds7505", 659e97a45f1SJavier Martinez Canillas .data = (void *)ds7505 660e97a45f1SJavier Martinez Canillas }, 661e97a45f1SJavier Martinez Canillas { 662e97a45f1SJavier Martinez Canillas .compatible = "gmt,g751", 663e97a45f1SJavier Martinez Canillas .data = (void *)g751 664e97a45f1SJavier Martinez Canillas }, 665e97a45f1SJavier Martinez Canillas { 666e97a45f1SJavier Martinez Canillas .compatible = "national,lm75", 667e97a45f1SJavier Martinez Canillas .data = (void *)lm75 668e97a45f1SJavier Martinez Canillas }, 669e97a45f1SJavier Martinez Canillas { 670e97a45f1SJavier Martinez Canillas .compatible = "national,lm75a", 671e97a45f1SJavier Martinez Canillas .data = (void *)lm75a 672e97a45f1SJavier Martinez Canillas }, 673e97a45f1SJavier Martinez Canillas { 674e97a45f1SJavier Martinez Canillas .compatible = "national,lm75b", 675e97a45f1SJavier Martinez Canillas .data = (void *)lm75b 676e97a45f1SJavier Martinez Canillas }, 677e97a45f1SJavier Martinez Canillas { 678e97a45f1SJavier Martinez Canillas .compatible = "maxim,max6625", 679e97a45f1SJavier Martinez Canillas .data = (void *)max6625 680e97a45f1SJavier Martinez Canillas }, 681e97a45f1SJavier Martinez Canillas { 682e97a45f1SJavier Martinez Canillas .compatible = "maxim,max6626", 683e97a45f1SJavier Martinez Canillas .data = (void *)max6626 684e97a45f1SJavier Martinez Canillas }, 685e97a45f1SJavier Martinez Canillas { 686a54ca77aSKun Yi .compatible = "maxim,max31725", 687a54ca77aSKun Yi .data = (void *)max31725 688a54ca77aSKun Yi }, 689a54ca77aSKun Yi { 690a54ca77aSKun Yi .compatible = "maxim,max31726", 691a54ca77aSKun Yi .data = (void *)max31725 692a54ca77aSKun Yi }, 693a54ca77aSKun Yi { 694e97a45f1SJavier Martinez Canillas .compatible = "maxim,mcp980x", 695e97a45f1SJavier Martinez Canillas .data = (void *)mcp980x 696e97a45f1SJavier Martinez Canillas }, 697e97a45f1SJavier Martinez Canillas { 698557c7ffaSDaniel Mack .compatible = "nxp,pct2075", 699557c7ffaSDaniel Mack .data = (void *)pct2075 700557c7ffaSDaniel Mack }, 701557c7ffaSDaniel Mack { 702e97a45f1SJavier Martinez Canillas .compatible = "st,stds75", 703e97a45f1SJavier Martinez Canillas .data = (void *)stds75 704e97a45f1SJavier Martinez Canillas }, 705e97a45f1SJavier Martinez Canillas { 7062e9a41bbSJagan Teki .compatible = "st,stlm75", 7072e9a41bbSJagan Teki .data = (void *)stlm75 7082e9a41bbSJagan Teki }, 7092e9a41bbSJagan Teki { 710e97a45f1SJavier Martinez Canillas .compatible = "microchip,tcn75", 711e97a45f1SJavier Martinez Canillas .data = (void *)tcn75 712e97a45f1SJavier Martinez Canillas }, 713e97a45f1SJavier Martinez Canillas { 714e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp100", 715e97a45f1SJavier Martinez Canillas .data = (void *)tmp100 716e97a45f1SJavier Martinez Canillas }, 717e97a45f1SJavier Martinez Canillas { 718e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp101", 719e97a45f1SJavier Martinez Canillas .data = (void *)tmp101 720e97a45f1SJavier Martinez Canillas }, 721e97a45f1SJavier Martinez Canillas { 722e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp105", 723e97a45f1SJavier Martinez Canillas .data = (void *)tmp105 724e97a45f1SJavier Martinez Canillas }, 725e97a45f1SJavier Martinez Canillas { 726e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp112", 727e97a45f1SJavier Martinez Canillas .data = (void *)tmp112 728e97a45f1SJavier Martinez Canillas }, 729e97a45f1SJavier Martinez Canillas { 730e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp175", 731e97a45f1SJavier Martinez Canillas .data = (void *)tmp175 732e97a45f1SJavier Martinez Canillas }, 733e97a45f1SJavier Martinez Canillas { 734e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp275", 735e97a45f1SJavier Martinez Canillas .data = (void *)tmp275 736e97a45f1SJavier Martinez Canillas }, 737e97a45f1SJavier Martinez Canillas { 738e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp75", 739e97a45f1SJavier Martinez Canillas .data = (void *)tmp75 740e97a45f1SJavier Martinez Canillas }, 741e97a45f1SJavier Martinez Canillas { 74239abe9d8SIker Perez del Palomar Sustatxa .compatible = "ti,tmp75b", 74339abe9d8SIker Perez del Palomar Sustatxa .data = (void *)tmp75b 74439abe9d8SIker Perez del Palomar Sustatxa }, 74539abe9d8SIker Perez del Palomar Sustatxa { 746e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp75c", 747e97a45f1SJavier Martinez Canillas .data = (void *)tmp75c 748e97a45f1SJavier Martinez Canillas }, 749e97a45f1SJavier Martinez Canillas { }, 750e97a45f1SJavier Martinez Canillas }; 751e97a45f1SJavier Martinez Canillas MODULE_DEVICE_TABLE(of, lm75_of_match); 752e97a45f1SJavier Martinez Canillas 75305e82fe4SLen Sorensen #define LM75A_ID 0xA1 75405e82fe4SLen Sorensen 7558ff69eebSJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */ 756310ec792SJean Delvare static int lm75_detect(struct i2c_client *new_client, 7578ff69eebSJean Delvare struct i2c_board_info *info) 7588d5d45fbSJean Delvare { 7598ff69eebSJean Delvare struct i2c_adapter *adapter = new_client->adapter; 7608d5d45fbSJean Delvare int i; 761e76f67b5SJean Delvare int conf, hyst, os; 76205e82fe4SLen Sorensen bool is_lm75a = 0; 7638d5d45fbSJean Delvare 7648d5d45fbSJean Delvare if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 7658d5d45fbSJean Delvare I2C_FUNC_SMBUS_WORD_DATA)) 7668ff69eebSJean Delvare return -ENODEV; 7678d5d45fbSJean Delvare 768426343efSJean Delvare /* 769426343efSJean Delvare * Now, we do the remaining detection. There is no identification- 770426343efSJean Delvare * dedicated register so we have to rely on several tricks: 771426343efSJean Delvare * unused bits, registers cycling over 8-address boundaries, 772426343efSJean Delvare * addresses 0x04-0x07 returning the last read value. 773426343efSJean Delvare * The cycling+unused addresses combination is not tested, 774426343efSJean Delvare * since it would significantly slow the detection down and would 775426343efSJean Delvare * hardly add any value. 776426343efSJean Delvare * 777426343efSJean Delvare * The National Semiconductor LM75A is different than earlier 778426343efSJean Delvare * LM75s. It has an ID byte of 0xaX (where X is the chip 779426343efSJean Delvare * revision, with 1 being the only revision in existence) in 780426343efSJean Delvare * register 7, and unused registers return 0xff rather than the 781426343efSJean Delvare * last read value. 782426343efSJean Delvare * 783426343efSJean Delvare * Note that this function only detects the original National 784426343efSJean Delvare * Semiconductor LM75 and the LM75A. Clones from other vendors 785426343efSJean Delvare * aren't detected, on purpose, because they are typically never 786426343efSJean Delvare * found on PC hardware. They are found on embedded designs where 787426343efSJean Delvare * they can be instantiated explicitly so detection is not needed. 788426343efSJean Delvare * The absence of identification registers on all these clones 789426343efSJean Delvare * would make their exhaustive detection very difficult and weak, 790426343efSJean Delvare * and odds are that the driver would bind to unsupported devices. 791426343efSJean Delvare */ 79205e82fe4SLen Sorensen 793e76f67b5SJean Delvare /* Unused bits */ 7948d5d45fbSJean Delvare conf = i2c_smbus_read_byte_data(new_client, 1); 795e76f67b5SJean Delvare if (conf & 0xe0) 796e76f67b5SJean Delvare return -ENODEV; 79705e82fe4SLen Sorensen 79805e82fe4SLen Sorensen /* First check for LM75A */ 79905e82fe4SLen Sorensen if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { 8008cbf2172SMichal Orzel /* 8018cbf2172SMichal Orzel * LM75A returns 0xff on unused registers so 8028cbf2172SMichal Orzel * just to be sure we check for that too. 8038cbf2172SMichal Orzel */ 80405e82fe4SLen Sorensen if (i2c_smbus_read_byte_data(new_client, 4) != 0xff 80505e82fe4SLen Sorensen || i2c_smbus_read_byte_data(new_client, 5) != 0xff 80605e82fe4SLen Sorensen || i2c_smbus_read_byte_data(new_client, 6) != 0xff) 80705e82fe4SLen Sorensen return -ENODEV; 80805e82fe4SLen Sorensen is_lm75a = 1; 809e76f67b5SJean Delvare hyst = i2c_smbus_read_byte_data(new_client, 2); 810e76f67b5SJean Delvare os = i2c_smbus_read_byte_data(new_client, 3); 81105e82fe4SLen Sorensen } else { /* Traditional style LM75 detection */ 81205e82fe4SLen Sorensen /* Unused addresses */ 813e76f67b5SJean Delvare hyst = i2c_smbus_read_byte_data(new_client, 2); 814e76f67b5SJean Delvare if (i2c_smbus_read_byte_data(new_client, 4) != hyst 815e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 5) != hyst 816e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 6) != hyst 817e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 7) != hyst) 8188ff69eebSJean Delvare return -ENODEV; 819e76f67b5SJean Delvare os = i2c_smbus_read_byte_data(new_client, 3); 820e76f67b5SJean Delvare if (i2c_smbus_read_byte_data(new_client, 4) != os 821e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 5) != os 822e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 6) != os 823e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 7) != os) 8248ff69eebSJean Delvare return -ENODEV; 82505e82fe4SLen Sorensen } 8264ad40cc5SGuenter Roeck /* 8274ad40cc5SGuenter Roeck * It is very unlikely that this is a LM75 if both 8284ad40cc5SGuenter Roeck * hysteresis and temperature limit registers are 0. 8294ad40cc5SGuenter Roeck */ 8304ad40cc5SGuenter Roeck if (hyst == 0 && os == 0) 8314ad40cc5SGuenter Roeck return -ENODEV; 8328d5d45fbSJean Delvare 8338d5d45fbSJean Delvare /* Addresses cycling */ 834e76f67b5SJean Delvare for (i = 8; i <= 248; i += 40) { 8358d5d45fbSJean Delvare if (i2c_smbus_read_byte_data(new_client, i + 1) != conf 836e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, i + 2) != hyst 837e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, i + 3) != os) 8388ff69eebSJean Delvare return -ENODEV; 83905e82fe4SLen Sorensen if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) 84005e82fe4SLen Sorensen != LM75A_ID) 84105e82fe4SLen Sorensen return -ENODEV; 8428d5d45fbSJean Delvare } 8438d5d45fbSJean Delvare 84405e82fe4SLen Sorensen strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); 8458d5d45fbSJean Delvare 8468d5d45fbSJean Delvare return 0; 8478d5d45fbSJean Delvare } 8488d5d45fbSJean Delvare 8499914518eSShubhrajyoti Datta #ifdef CONFIG_PM 8509914518eSShubhrajyoti Datta static int lm75_suspend(struct device *dev) 8519914518eSShubhrajyoti Datta { 8529914518eSShubhrajyoti Datta int status; 8539914518eSShubhrajyoti Datta struct i2c_client *client = to_i2c_client(dev); 8548cbf2172SMichal Orzel 85538aefb41SGuenter Roeck status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); 8569914518eSShubhrajyoti Datta if (status < 0) { 8579914518eSShubhrajyoti Datta dev_dbg(&client->dev, "Can't read config? %d\n", status); 8589914518eSShubhrajyoti Datta return status; 8599914518eSShubhrajyoti Datta } 8609914518eSShubhrajyoti Datta status = status | LM75_SHUTDOWN; 86138aefb41SGuenter Roeck i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); 8629914518eSShubhrajyoti Datta return 0; 8639914518eSShubhrajyoti Datta } 8649914518eSShubhrajyoti Datta 8659914518eSShubhrajyoti Datta static int lm75_resume(struct device *dev) 8669914518eSShubhrajyoti Datta { 8679914518eSShubhrajyoti Datta int status; 8689914518eSShubhrajyoti Datta struct i2c_client *client = to_i2c_client(dev); 8698cbf2172SMichal Orzel 87038aefb41SGuenter Roeck status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); 8719914518eSShubhrajyoti Datta if (status < 0) { 8729914518eSShubhrajyoti Datta dev_dbg(&client->dev, "Can't read config? %d\n", status); 8739914518eSShubhrajyoti Datta return status; 8749914518eSShubhrajyoti Datta } 8759914518eSShubhrajyoti Datta status = status & ~LM75_SHUTDOWN; 87638aefb41SGuenter Roeck i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); 8779914518eSShubhrajyoti Datta return 0; 8789914518eSShubhrajyoti Datta } 8799914518eSShubhrajyoti Datta 8809914518eSShubhrajyoti Datta static const struct dev_pm_ops lm75_dev_pm_ops = { 8819914518eSShubhrajyoti Datta .suspend = lm75_suspend, 8829914518eSShubhrajyoti Datta .resume = lm75_resume, 8839914518eSShubhrajyoti Datta }; 8849914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) 8859914518eSShubhrajyoti Datta #else 8869914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS NULL 8879914518eSShubhrajyoti Datta #endif /* CONFIG_PM */ 8889914518eSShubhrajyoti Datta 8898ff69eebSJean Delvare static struct i2c_driver lm75_driver = { 8908ff69eebSJean Delvare .class = I2C_CLASS_HWMON, 89101a52397SDavid Brownell .driver = { 8928ff69eebSJean Delvare .name = "lm75", 893e97a45f1SJavier Martinez Canillas .of_match_table = of_match_ptr(lm75_of_match), 8949914518eSShubhrajyoti Datta .pm = LM75_DEV_PM_OPS, 89501a52397SDavid Brownell }, 8968ff69eebSJean Delvare .probe = lm75_probe, 8978ff69eebSJean Delvare .id_table = lm75_ids, 8988ff69eebSJean Delvare .detect = lm75_detect, 899c3813d6aSJean Delvare .address_list = normal_i2c, 90001a52397SDavid Brownell }; 90101a52397SDavid Brownell 902f0967eeaSAxel Lin module_i2c_driver(lm75_driver); 9038d5d45fbSJean Delvare 9048d5d45fbSJean Delvare MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); 9058d5d45fbSJean Delvare MODULE_DESCRIPTION("LM75 driver"); 9068d5d45fbSJean Delvare MODULE_LICENSE("GPL"); 907