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>
1622e73183SEduardo Valentin #include <linux/of.h>
17e65365feSGuenter Roeck #include <linux/regmap.h>
184b5be3c1SIker Perez del Palomar Sustatxa #include <linux/util_macros.h>
19707d151bSAlban Bedel #include <linux/regulator/consumer.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,
28c851b715SPeter Rosin at30ts74,
291f86df49SJean Delvare ds1775,
309ebd3d82SDavid Brownell ds75,
313fbc81e3SJean Delvare ds7505,
32c98d6c65SArnaud Ebalard g751,
331f86df49SJean Delvare lm75,
349ebd3d82SDavid Brownell lm75a,
35799fc602SMichael Thalmeier lm75b,
369ebd3d82SDavid Brownell max6625,
379ebd3d82SDavid Brownell max6626,
38a54ca77aSKun Yi max31725,
399ebd3d82SDavid Brownell mcp980x,
40557c7ffaSDaniel Mack pct2075,
419ebd3d82SDavid Brownell stds75,
422e9a41bbSJagan Teki stlm75,
439ebd3d82SDavid Brownell tcn75,
449ebd3d82SDavid Brownell tmp100,
459ebd3d82SDavid Brownell tmp101,
466d034059SShubhrajyoti Datta tmp105,
47c83959f8SFrans Klaver tmp112,
489ebd3d82SDavid Brownell tmp175,
499ebd3d82SDavid Brownell tmp275,
509ebd3d82SDavid Brownell tmp75,
5139abe9d8SIker Perez del Palomar Sustatxa tmp75b,
529c32e815SBen Gardner tmp75c,
53ec081f91SRobert Marko tmp1075,
549ebd3d82SDavid Brownell };
559ebd3d82SDavid Brownell
56dcb12653SIker Perez del Palomar Sustatxa /**
57dcb12653SIker Perez del Palomar Sustatxa * struct lm75_params - lm75 configuration parameters.
58dcb12653SIker Perez del Palomar Sustatxa * @set_mask: Bits to set in configuration register when configuring
59dcb12653SIker Perez del Palomar Sustatxa * the chip.
60dcb12653SIker Perez del Palomar Sustatxa * @clr_mask: Bits to clear in configuration register when configuring
61dcb12653SIker Perez del Palomar Sustatxa * the chip.
62dcb12653SIker Perez del Palomar Sustatxa * @default_resolution: Default number of bits to represent the temperature
63dcb12653SIker Perez del Palomar Sustatxa * value.
64dcb12653SIker Perez del Palomar Sustatxa * @resolution_limits: Limit register resolution. Optional. Should be set if
65dcb12653SIker Perez del Palomar Sustatxa * the resolution of limit registers does not match the
66dcb12653SIker Perez del Palomar Sustatxa * resolution of the temperature register.
677f1a300fSIker Perez del Palomar Sustatxa * @resolutions: List of resolutions associated with sample times.
687f1a300fSIker Perez del Palomar Sustatxa * Optional. Should be set if num_sample_times is larger
697f1a300fSIker Perez del Palomar Sustatxa * than 1, and if the resolution changes with sample times.
707f1a300fSIker Perez del Palomar Sustatxa * If set, number of entries must match num_sample_times.
717f1a300fSIker Perez del Palomar Sustatxa * @default_sample_time:Sample time to be set by default.
727f1a300fSIker Perez del Palomar Sustatxa * @num_sample_times: Number of possible sample times to be set. Optional.
737f1a300fSIker Perez del Palomar Sustatxa * Should be set if the number of sample times is larger
747f1a300fSIker Perez del Palomar Sustatxa * than one.
757f1a300fSIker Perez del Palomar Sustatxa * @sample_times: All the possible sample times to be set. Mandatory if
767f1a300fSIker Perez del Palomar Sustatxa * num_sample_times is larger than 1. If set, number of
777f1a300fSIker Perez del Palomar Sustatxa * entries must match num_sample_times.
78dcb12653SIker Perez del Palomar Sustatxa */
79dcb12653SIker Perez del Palomar Sustatxa
80dcb12653SIker Perez del Palomar Sustatxa struct lm75_params {
81dcb12653SIker Perez del Palomar Sustatxa u8 set_mask;
82dcb12653SIker Perez del Palomar Sustatxa u8 clr_mask;
83dcb12653SIker Perez del Palomar Sustatxa u8 default_resolution;
84dcb12653SIker Perez del Palomar Sustatxa u8 resolution_limits;
857f1a300fSIker Perez del Palomar Sustatxa const u8 *resolutions;
86dcb12653SIker Perez del Palomar Sustatxa unsigned int default_sample_time;
877f1a300fSIker Perez del Palomar Sustatxa u8 num_sample_times;
887f1a300fSIker Perez del Palomar Sustatxa const unsigned int *sample_times;
89dcb12653SIker Perez del Palomar Sustatxa };
90dcb12653SIker Perez del Palomar Sustatxa
918ff69eebSJean Delvare /* Addresses scanned */
9225e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
938d5d45fbSJean Delvare 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
948d5d45fbSJean Delvare
958d5d45fbSJean Delvare /* The LM75 registers */
96e65365feSGuenter Roeck #define LM75_REG_TEMP 0x00
978d5d45fbSJean Delvare #define LM75_REG_CONF 0x01
98e65365feSGuenter Roeck #define LM75_REG_HYST 0x02
99e65365feSGuenter Roeck #define LM75_REG_MAX 0x03
100d7a85cdeSGuenter Roeck #define PCT2075_REG_IDLE 0x04
1018d5d45fbSJean Delvare
1028d5d45fbSJean Delvare /* Each client has this additional data */
1038d5d45fbSJean Delvare struct lm75_data {
104d663ec49SGuenter Roeck struct i2c_client *client;
105e65365feSGuenter Roeck struct regmap *regmap;
106707d151bSAlban Bedel struct regulator *vs;
1079ebd3d82SDavid Brownell u8 orig_conf;
108dcb12653SIker Perez del Palomar Sustatxa u8 current_conf;
109dcb12653SIker Perez del Palomar Sustatxa u8 resolution; /* In bits, 9 to 16 */
110e65365feSGuenter Roeck unsigned int sample_time; /* In ms */
111dcb12653SIker Perez del Palomar Sustatxa enum lm75_type kind;
112dcb12653SIker Perez del Palomar Sustatxa const struct lm75_params *params;
1138d5d45fbSJean Delvare };
1148d5d45fbSJean Delvare
11501a52397SDavid Brownell /*-----------------------------------------------------------------------*/
1167db0db3fSGuenter Roeck
1177db0db3fSGuenter Roeck static const u8 lm75_sample_set_masks[] = { 0 << 5, 1 << 5, 2 << 5, 3 << 5 };
1187db0db3fSGuenter Roeck
1197db0db3fSGuenter Roeck #define LM75_SAMPLE_CLEAR_MASK (3 << 5)
1207db0db3fSGuenter Roeck
121dcb12653SIker Perez del Palomar Sustatxa /* The structure below stores the configuration values of the supported devices.
122dcb12653SIker Perez del Palomar Sustatxa * In case of being supported multiple configurations, the default one must
123dcb12653SIker Perez del Palomar Sustatxa * always be the first element of the array
124dcb12653SIker Perez del Palomar Sustatxa */
125dcb12653SIker Perez del Palomar Sustatxa static const struct lm75_params device_params[] = {
126dcb12653SIker Perez del Palomar Sustatxa [adt75] = {
127dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 5, /* not one-shot mode */
128dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
12935cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10,
130dcb12653SIker Perez del Palomar Sustatxa },
131c851b715SPeter Rosin [at30ts74] = {
132c851b715SPeter Rosin .set_mask = 3 << 5, /* 12-bit mode*/
133c851b715SPeter Rosin .default_resolution = 12,
134c851b715SPeter Rosin .default_sample_time = 200,
135c851b715SPeter Rosin .num_sample_times = 4,
136c851b715SPeter Rosin .sample_times = (unsigned int []){ 25, 50, 100, 200 },
137c851b715SPeter Rosin .resolutions = (u8 []) {9, 10, 11, 12 },
138c851b715SPeter Rosin },
139dcb12653SIker Perez del Palomar Sustatxa [ds1775] = {
140dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 3 << 5,
141dcb12653SIker Perez del Palomar Sustatxa .set_mask = 2 << 5, /* 11-bit mode */
142dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11,
14335cd1804SIker Perez del Palomar Sustatxa .default_sample_time = 500,
1447db0db3fSGuenter Roeck .num_sample_times = 4,
14535cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 125, 250, 500, 1000 },
1467db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
147dcb12653SIker Perez del Palomar Sustatxa },
148dcb12653SIker Perez del Palomar Sustatxa [ds75] = {
149dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 3 << 5,
150dcb12653SIker Perez del Palomar Sustatxa .set_mask = 2 << 5, /* 11-bit mode */
151dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11,
1527db0db3fSGuenter Roeck .default_sample_time = 600,
1537db0db3fSGuenter Roeck .num_sample_times = 4,
1547db0db3fSGuenter Roeck .sample_times = (unsigned int []){ 150, 300, 600, 1200 },
1557db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
156dcb12653SIker Perez del Palomar Sustatxa },
157dcb12653SIker Perez del Palomar Sustatxa [stds75] = {
158dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 3 << 5,
159dcb12653SIker Perez del Palomar Sustatxa .set_mask = 2 << 5, /* 11-bit mode */
160dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11,
1617db0db3fSGuenter Roeck .default_sample_time = 600,
1627db0db3fSGuenter Roeck .num_sample_times = 4,
1637db0db3fSGuenter Roeck .sample_times = (unsigned int []){ 150, 300, 600, 1200 },
1647db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
165dcb12653SIker Perez del Palomar Sustatxa },
166dcb12653SIker Perez del Palomar Sustatxa [stlm75] = {
167dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9,
16835cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 6,
169dcb12653SIker Perez del Palomar Sustatxa },
170dcb12653SIker Perez del Palomar Sustatxa [ds7505] = {
171dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode*/
172dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
1737db0db3fSGuenter Roeck .default_sample_time = 200,
1747db0db3fSGuenter Roeck .num_sample_times = 4,
1757db0db3fSGuenter Roeck .sample_times = (unsigned int []){ 25, 50, 100, 200 },
1767db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
177dcb12653SIker Perez del Palomar Sustatxa },
178dcb12653SIker Perez del Palomar Sustatxa [g751] = {
179dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9,
18035cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10,
181dcb12653SIker Perez del Palomar Sustatxa },
182dcb12653SIker Perez del Palomar Sustatxa [lm75] = {
183dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9,
18435cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10,
185dcb12653SIker Perez del Palomar Sustatxa },
186dcb12653SIker Perez del Palomar Sustatxa [lm75a] = {
187dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9,
18835cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10,
189dcb12653SIker Perez del Palomar Sustatxa },
190dcb12653SIker Perez del Palomar Sustatxa [lm75b] = {
191dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11,
19235cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10,
193dcb12653SIker Perez del Palomar Sustatxa },
194dcb12653SIker Perez del Palomar Sustatxa [max6625] = {
195dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9,
19635cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 7,
197dcb12653SIker Perez del Palomar Sustatxa },
198dcb12653SIker Perez del Palomar Sustatxa [max6626] = {
199dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
20035cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 7,
201dcb12653SIker Perez del Palomar Sustatxa .resolution_limits = 9,
202dcb12653SIker Perez del Palomar Sustatxa },
203dcb12653SIker Perez del Palomar Sustatxa [max31725] = {
204dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 16,
20535cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 20,
206dcb12653SIker Perez del Palomar Sustatxa },
207dcb12653SIker Perez del Palomar Sustatxa [tcn75] = {
208dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 9,
20935cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 18,
210dcb12653SIker Perez del Palomar Sustatxa },
211dcb12653SIker Perez del Palomar Sustatxa [pct2075] = {
212dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 11,
213dcb12653SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 10,
214d7a85cdeSGuenter Roeck .num_sample_times = 31,
215d7a85cdeSGuenter Roeck .sample_times = (unsigned int []){ 100, 200, 300, 400, 500, 600,
216d7a85cdeSGuenter Roeck 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700,
217d7a85cdeSGuenter Roeck 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700,
218d7a85cdeSGuenter Roeck 2800, 2900, 3000, 3100 },
219dcb12653SIker Perez del Palomar Sustatxa },
220dcb12653SIker Perez del Palomar Sustatxa [mcp980x] = {
221dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */
222dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode */
223dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
224dcb12653SIker Perez del Palomar Sustatxa .resolution_limits = 9,
2257db0db3fSGuenter Roeck .default_sample_time = 240,
2267db0db3fSGuenter Roeck .num_sample_times = 4,
22735cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 30, 60, 120, 240 },
2287db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
229dcb12653SIker Perez del Palomar Sustatxa },
230dcb12653SIker Perez del Palomar Sustatxa [tmp100] = {
231dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */
232dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode */
233dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
2347db0db3fSGuenter Roeck .default_sample_time = 320,
2357db0db3fSGuenter Roeck .num_sample_times = 4,
23635cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 40, 80, 160, 320 },
2377db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
238dcb12653SIker Perez del Palomar Sustatxa },
239dcb12653SIker Perez del Palomar Sustatxa [tmp101] = {
240dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */
241dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode */
242dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
2437db0db3fSGuenter Roeck .default_sample_time = 320,
2447db0db3fSGuenter Roeck .num_sample_times = 4,
24535cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 40, 80, 160, 320 },
2467db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
2477db0db3fSGuenter Roeck },
2487db0db3fSGuenter Roeck [tmp105] = {
2497db0db3fSGuenter Roeck .set_mask = 3 << 5, /* 12-bit mode */
2507db0db3fSGuenter Roeck .clr_mask = 1 << 7, /* not one-shot mode*/
2517db0db3fSGuenter Roeck .default_resolution = 12,
2527db0db3fSGuenter Roeck .default_sample_time = 220,
2537db0db3fSGuenter Roeck .num_sample_times = 4,
25435cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 28, 55, 110, 220 },
2557db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
256dcb12653SIker Perez del Palomar Sustatxa },
257dcb12653SIker Perez del Palomar Sustatxa [tmp112] = {
25835cd1804SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 8 samples / second */
259dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* no one-shot mode*/
260dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
26135cd1804SIker Perez del Palomar Sustatxa .default_sample_time = 125,
262cee04a01SGuenter Roeck .num_sample_times = 4,
263cee04a01SGuenter Roeck .sample_times = (unsigned int []){ 125, 250, 1000, 4000 },
264dcb12653SIker Perez del Palomar Sustatxa },
265dcb12653SIker Perez del Palomar Sustatxa [tmp175] = {
266dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */
267dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode*/
268dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
2697db0db3fSGuenter Roeck .default_sample_time = 220,
2707db0db3fSGuenter Roeck .num_sample_times = 4,
27135cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 28, 55, 110, 220 },
2727db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
273dcb12653SIker Perez del Palomar Sustatxa },
274dcb12653SIker Perez del Palomar Sustatxa [tmp275] = {
275dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */
276dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode*/
277dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
2787db0db3fSGuenter Roeck .default_sample_time = 220,
2797db0db3fSGuenter Roeck .num_sample_times = 4,
28035cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 28, 55, 110, 220 },
2817db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
282dcb12653SIker Perez del Palomar Sustatxa },
283dcb12653SIker Perez del Palomar Sustatxa [tmp75] = {
284dcb12653SIker Perez del Palomar Sustatxa .set_mask = 3 << 5, /* 12-bit mode */
285dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7, /* not one-shot mode*/
286dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
2877db0db3fSGuenter Roeck .default_sample_time = 220,
2887db0db3fSGuenter Roeck .num_sample_times = 4,
28935cd1804SIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ 28, 55, 110, 220 },
2907db0db3fSGuenter Roeck .resolutions = (u8 []) {9, 10, 11, 12 },
291dcb12653SIker Perez del Palomar Sustatxa },
292dcb12653SIker Perez del Palomar Sustatxa [tmp75b] = { /* not one-shot mode, Conversion rate 37Hz */
293dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 7 | 3 << 5,
294dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
295dcb12653SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 37,
2967f1a300fSIker Perez del Palomar Sustatxa .sample_times = (unsigned int []){ MSEC_PER_SEC / 37,
2977f1a300fSIker Perez del Palomar Sustatxa MSEC_PER_SEC / 18,
2987f1a300fSIker Perez del Palomar Sustatxa MSEC_PER_SEC / 9, MSEC_PER_SEC / 4 },
2997f1a300fSIker Perez del Palomar Sustatxa .num_sample_times = 4,
300dcb12653SIker Perez del Palomar Sustatxa },
301dcb12653SIker Perez del Palomar Sustatxa [tmp75c] = {
302dcb12653SIker Perez del Palomar Sustatxa .clr_mask = 1 << 5, /*not one-shot mode*/
303dcb12653SIker Perez del Palomar Sustatxa .default_resolution = 12,
30435cd1804SIker Perez del Palomar Sustatxa .default_sample_time = MSEC_PER_SEC / 12,
305ec081f91SRobert Marko },
306ec081f91SRobert Marko [tmp1075] = { /* not one-shot mode, 27.5 ms sample rate */
307ec081f91SRobert Marko .clr_mask = 1 << 5 | 1 << 6 | 1 << 7,
308ec081f91SRobert Marko .default_resolution = 12,
309ec081f91SRobert Marko .default_sample_time = 28,
310ec081f91SRobert Marko .num_sample_times = 4,
311ec081f91SRobert Marko .sample_times = (unsigned int []){ 28, 55, 110, 220 },
312dcb12653SIker Perez del Palomar Sustatxa }
313dcb12653SIker Perez del Palomar Sustatxa };
31401a52397SDavid Brownell
lm75_reg_to_mc(s16 temp,u8 resolution)31522e73183SEduardo Valentin static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
31622e73183SEduardo Valentin {
31722e73183SEduardo Valentin return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
31822e73183SEduardo Valentin }
31922e73183SEduardo Valentin
lm75_write_config(struct lm75_data * data,u8 set_mask,u8 clr_mask)32058608cfeSIker Perez del Palomar Sustatxa static int lm75_write_config(struct lm75_data *data, u8 set_mask,
32158608cfeSIker Perez del Palomar Sustatxa u8 clr_mask)
32258608cfeSIker Perez del Palomar Sustatxa {
32358608cfeSIker Perez del Palomar Sustatxa u8 value;
32458608cfeSIker Perez del Palomar Sustatxa
32558608cfeSIker Perez del Palomar Sustatxa clr_mask |= LM75_SHUTDOWN;
32658608cfeSIker Perez del Palomar Sustatxa value = data->current_conf & ~clr_mask;
32758608cfeSIker Perez del Palomar Sustatxa value |= set_mask;
32858608cfeSIker Perez del Palomar Sustatxa
32958608cfeSIker Perez del Palomar Sustatxa if (data->current_conf != value) {
33058608cfeSIker Perez del Palomar Sustatxa s32 err;
33158608cfeSIker Perez del Palomar Sustatxa
33258608cfeSIker Perez del Palomar Sustatxa err = i2c_smbus_write_byte_data(data->client, LM75_REG_CONF,
33358608cfeSIker Perez del Palomar Sustatxa value);
33458608cfeSIker Perez del Palomar Sustatxa if (err)
33558608cfeSIker Perez del Palomar Sustatxa return err;
33658608cfeSIker Perez del Palomar Sustatxa data->current_conf = value;
33758608cfeSIker Perez del Palomar Sustatxa }
33858608cfeSIker Perez del Palomar Sustatxa return 0;
33958608cfeSIker Perez del Palomar Sustatxa }
34058608cfeSIker Perez del Palomar Sustatxa
lm75_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)34108b02433SGuenter Roeck static int lm75_read(struct device *dev, enum hwmon_sensor_types type,
34208b02433SGuenter Roeck u32 attr, int channel, long *val)
34322e73183SEduardo Valentin {
344e65365feSGuenter Roeck struct lm75_data *data = dev_get_drvdata(dev);
34508b02433SGuenter Roeck unsigned int regval;
34608b02433SGuenter Roeck int err, reg;
34722e73183SEduardo Valentin
34808b02433SGuenter Roeck switch (type) {
34908b02433SGuenter Roeck case hwmon_chip:
35008b02433SGuenter Roeck switch (attr) {
35108b02433SGuenter Roeck case hwmon_chip_update_interval:
35208b02433SGuenter Roeck *val = data->sample_time;
353ccffe776SLuis de Bethencourt break;
35408b02433SGuenter Roeck default:
35508b02433SGuenter Roeck return -EINVAL;
35608b02433SGuenter Roeck }
35708b02433SGuenter Roeck break;
35808b02433SGuenter Roeck case hwmon_temp:
35908b02433SGuenter Roeck switch (attr) {
36008b02433SGuenter Roeck case hwmon_temp_input:
36108b02433SGuenter Roeck reg = LM75_REG_TEMP;
36208b02433SGuenter Roeck break;
36308b02433SGuenter Roeck case hwmon_temp_max:
36408b02433SGuenter Roeck reg = LM75_REG_MAX;
36508b02433SGuenter Roeck break;
36608b02433SGuenter Roeck case hwmon_temp_max_hyst:
36708b02433SGuenter Roeck reg = LM75_REG_HYST;
36808b02433SGuenter Roeck break;
36908b02433SGuenter Roeck default:
37008b02433SGuenter Roeck return -EINVAL;
37108b02433SGuenter Roeck }
37208b02433SGuenter Roeck err = regmap_read(data->regmap, reg, ®val);
373e65365feSGuenter Roeck if (err < 0)
374e65365feSGuenter Roeck return err;
37522e73183SEduardo Valentin
37608b02433SGuenter Roeck *val = lm75_reg_to_mc(regval, data->resolution);
37708b02433SGuenter Roeck break;
37808b02433SGuenter Roeck default:
37908b02433SGuenter Roeck return -EINVAL;
38008b02433SGuenter Roeck }
38122e73183SEduardo Valentin return 0;
38222e73183SEduardo Valentin }
38322e73183SEduardo Valentin
lm75_write_temp(struct device * dev,u32 attr,long temp)3844b5be3c1SIker Perez del Palomar Sustatxa static int lm75_write_temp(struct device *dev, u32 attr, long temp)
3859ca8e40cSJean Delvare {
386e65365feSGuenter Roeck struct lm75_data *data = dev_get_drvdata(dev);
38787d0621aSJean Delvare u8 resolution;
38808b02433SGuenter Roeck int reg;
389e3cd9528SShubhrajyoti D
39008b02433SGuenter Roeck switch (attr) {
39108b02433SGuenter Roeck case hwmon_temp_max:
39208b02433SGuenter Roeck reg = LM75_REG_MAX;
39308b02433SGuenter Roeck break;
39408b02433SGuenter Roeck case hwmon_temp_max_hyst:
39508b02433SGuenter Roeck reg = LM75_REG_HYST;
39608b02433SGuenter Roeck break;
39708b02433SGuenter Roeck default:
39808b02433SGuenter Roeck return -EINVAL;
39908b02433SGuenter Roeck }
4009ca8e40cSJean Delvare
40187d0621aSJean Delvare /*
40287d0621aSJean Delvare * Resolution of limit registers is assumed to be the same as the
40387d0621aSJean Delvare * temperature input register resolution unless given explicitly.
40487d0621aSJean Delvare */
405dcb12653SIker Perez del Palomar Sustatxa if (data->params->resolution_limits)
406dcb12653SIker Perez del Palomar Sustatxa resolution = data->params->resolution_limits;
40787d0621aSJean Delvare else
40887d0621aSJean Delvare resolution = data->resolution;
40987d0621aSJean Delvare
41087d0621aSJean Delvare temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
411e65365feSGuenter Roeck temp = DIV_ROUND_CLOSEST(temp << (resolution - 8),
41287d0621aSJean Delvare 1000) << (16 - resolution);
413e65365feSGuenter Roeck
4147d82fcc9SGuenter Roeck return regmap_write(data->regmap, reg, (u16)temp);
4158d5d45fbSJean Delvare }
4168d5d45fbSJean Delvare
lm75_update_interval(struct device * dev,long val)417040b106fSGuenter Roeck static int lm75_update_interval(struct device *dev, long val)
4184b5be3c1SIker Perez del Palomar Sustatxa {
4194b5be3c1SIker Perez del Palomar Sustatxa struct lm75_data *data = dev_get_drvdata(dev);
420cee04a01SGuenter Roeck unsigned int reg;
4214b5be3c1SIker Perez del Palomar Sustatxa u8 index;
4224b5be3c1SIker Perez del Palomar Sustatxa s32 err;
4234b5be3c1SIker Perez del Palomar Sustatxa
4244b5be3c1SIker Perez del Palomar Sustatxa index = find_closest(val, data->params->sample_times,
4254b5be3c1SIker Perez del Palomar Sustatxa (int)data->params->num_sample_times);
4264b5be3c1SIker Perez del Palomar Sustatxa
427cee04a01SGuenter Roeck switch (data->kind) {
428cee04a01SGuenter Roeck default:
429040b106fSGuenter Roeck err = lm75_write_config(data, lm75_sample_set_masks[index],
4307db0db3fSGuenter Roeck LM75_SAMPLE_CLEAR_MASK);
4314b5be3c1SIker Perez del Palomar Sustatxa if (err)
4324b5be3c1SIker Perez del Palomar Sustatxa return err;
4334b5be3c1SIker Perez del Palomar Sustatxa
434040b106fSGuenter Roeck data->sample_time = data->params->sample_times[index];
4354b5be3c1SIker Perez del Palomar Sustatxa if (data->params->resolutions)
4364b5be3c1SIker Perez del Palomar Sustatxa data->resolution = data->params->resolutions[index];
437cee04a01SGuenter Roeck break;
438cee04a01SGuenter Roeck case tmp112:
439cee04a01SGuenter Roeck err = regmap_read(data->regmap, LM75_REG_CONF, ®);
440cee04a01SGuenter Roeck if (err < 0)
441cee04a01SGuenter Roeck return err;
442cee04a01SGuenter Roeck reg &= ~0x00c0;
443cee04a01SGuenter Roeck reg |= (3 - index) << 6;
444cee04a01SGuenter Roeck err = regmap_write(data->regmap, LM75_REG_CONF, reg);
445cee04a01SGuenter Roeck if (err < 0)
446cee04a01SGuenter Roeck return err;
447cee04a01SGuenter Roeck data->sample_time = data->params->sample_times[index];
448cee04a01SGuenter Roeck break;
449d7a85cdeSGuenter Roeck case pct2075:
450d7a85cdeSGuenter Roeck err = i2c_smbus_write_byte_data(data->client, PCT2075_REG_IDLE,
451d7a85cdeSGuenter Roeck index + 1);
452d7a85cdeSGuenter Roeck if (err)
453d7a85cdeSGuenter Roeck return err;
454d7a85cdeSGuenter Roeck data->sample_time = data->params->sample_times[index];
455d7a85cdeSGuenter Roeck break;
456cee04a01SGuenter Roeck }
457040b106fSGuenter Roeck return 0;
458040b106fSGuenter Roeck }
459040b106fSGuenter Roeck
lm75_write_chip(struct device * dev,u32 attr,long val)460040b106fSGuenter Roeck static int lm75_write_chip(struct device *dev, u32 attr, long val)
461040b106fSGuenter Roeck {
462040b106fSGuenter Roeck switch (attr) {
463040b106fSGuenter Roeck case hwmon_chip_update_interval:
464040b106fSGuenter Roeck return lm75_update_interval(dev, val);
4654b5be3c1SIker Perez del Palomar Sustatxa default:
4664b5be3c1SIker Perez del Palomar Sustatxa return -EINVAL;
4674b5be3c1SIker Perez del Palomar Sustatxa }
4684b5be3c1SIker Perez del Palomar Sustatxa return 0;
4694b5be3c1SIker Perez del Palomar Sustatxa }
4704b5be3c1SIker Perez del Palomar Sustatxa
lm75_write(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long val)4714b5be3c1SIker Perez del Palomar Sustatxa static int lm75_write(struct device *dev, enum hwmon_sensor_types type,
4724b5be3c1SIker Perez del Palomar Sustatxa u32 attr, int channel, long val)
4734b5be3c1SIker Perez del Palomar Sustatxa {
4744b5be3c1SIker Perez del Palomar Sustatxa switch (type) {
4754b5be3c1SIker Perez del Palomar Sustatxa case hwmon_chip:
4764b5be3c1SIker Perez del Palomar Sustatxa return lm75_write_chip(dev, attr, val);
4774b5be3c1SIker Perez del Palomar Sustatxa case hwmon_temp:
4784b5be3c1SIker Perez del Palomar Sustatxa return lm75_write_temp(dev, attr, val);
4794b5be3c1SIker Perez del Palomar Sustatxa default:
4804b5be3c1SIker Perez del Palomar Sustatxa return -EINVAL;
4814b5be3c1SIker Perez del Palomar Sustatxa }
4824b5be3c1SIker Perez del Palomar Sustatxa return 0;
4834b5be3c1SIker Perez del Palomar Sustatxa }
4844b5be3c1SIker Perez del Palomar Sustatxa
lm75_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)48508b02433SGuenter Roeck static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type,
48608b02433SGuenter Roeck u32 attr, int channel)
4875f7e5e29SGuenter Roeck {
4884b5be3c1SIker Perez del Palomar Sustatxa const struct lm75_data *config_data = data;
4894b5be3c1SIker Perez del Palomar Sustatxa
49008b02433SGuenter Roeck switch (type) {
49108b02433SGuenter Roeck case hwmon_chip:
49208b02433SGuenter Roeck switch (attr) {
49308b02433SGuenter Roeck case hwmon_chip_update_interval:
4944b5be3c1SIker Perez del Palomar Sustatxa if (config_data->params->num_sample_times > 1)
4954b5be3c1SIker Perez del Palomar Sustatxa return 0644;
496e6ab6e0eSGuenter Roeck return 0444;
4975f7e5e29SGuenter Roeck }
49808b02433SGuenter Roeck break;
49908b02433SGuenter Roeck case hwmon_temp:
50008b02433SGuenter Roeck switch (attr) {
50108b02433SGuenter Roeck case hwmon_temp_input:
502e6ab6e0eSGuenter Roeck return 0444;
50308b02433SGuenter Roeck case hwmon_temp_max:
50408b02433SGuenter Roeck case hwmon_temp_max_hyst:
505e6ab6e0eSGuenter Roeck return 0644;
50608b02433SGuenter Roeck }
50708b02433SGuenter Roeck break;
50808b02433SGuenter Roeck default:
50908b02433SGuenter Roeck break;
51008b02433SGuenter Roeck }
51108b02433SGuenter Roeck return 0;
51208b02433SGuenter Roeck }
5132251aef6SEduardo Valentin
5143ee2cecaSKrzysztof Kozlowski static const struct hwmon_channel_info * const lm75_info[] = {
515e4f6fed1SGuenter Roeck HWMON_CHANNEL_INFO(chip,
516e4f6fed1SGuenter Roeck HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL),
517e4f6fed1SGuenter Roeck HWMON_CHANNEL_INFO(temp,
518e4f6fed1SGuenter Roeck HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST),
51908b02433SGuenter Roeck NULL
52008b02433SGuenter Roeck };
52108b02433SGuenter Roeck
52208b02433SGuenter Roeck static const struct hwmon_ops lm75_hwmon_ops = {
52308b02433SGuenter Roeck .is_visible = lm75_is_visible,
52408b02433SGuenter Roeck .read = lm75_read,
52508b02433SGuenter Roeck .write = lm75_write,
52608b02433SGuenter Roeck };
52708b02433SGuenter Roeck
52808b02433SGuenter Roeck static const struct hwmon_chip_info lm75_chip_info = {
52908b02433SGuenter Roeck .ops = &lm75_hwmon_ops,
53008b02433SGuenter Roeck .info = lm75_info,
53108b02433SGuenter Roeck };
53208b02433SGuenter Roeck
lm75_is_writeable_reg(struct device * dev,unsigned int reg)533e65365feSGuenter Roeck static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg)
534e65365feSGuenter Roeck {
535e65365feSGuenter Roeck return reg != LM75_REG_TEMP;
536e65365feSGuenter Roeck }
537e65365feSGuenter Roeck
lm75_is_volatile_reg(struct device * dev,unsigned int reg)538e65365feSGuenter Roeck static bool lm75_is_volatile_reg(struct device *dev, unsigned int reg)
539e65365feSGuenter Roeck {
540cee04a01SGuenter Roeck return reg == LM75_REG_TEMP || reg == LM75_REG_CONF;
541e65365feSGuenter Roeck }
542e65365feSGuenter Roeck
543e65365feSGuenter Roeck static const struct regmap_config lm75_regmap_config = {
544e65365feSGuenter Roeck .reg_bits = 8,
545e65365feSGuenter Roeck .val_bits = 16,
546d7a85cdeSGuenter Roeck .max_register = PCT2075_REG_IDLE,
547e65365feSGuenter Roeck .writeable_reg = lm75_is_writeable_reg,
548e65365feSGuenter Roeck .volatile_reg = lm75_is_volatile_reg,
549e65365feSGuenter Roeck .val_format_endian = REGMAP_ENDIAN_BIG,
55030841ce3SMark Brown .cache_type = REGCACHE_MAPLE,
5511c96a2f6SDavid Frey .use_single_read = true,
5521c96a2f6SDavid Frey .use_single_write = true,
553e65365feSGuenter Roeck };
554e65365feSGuenter Roeck
lm75_disable_regulator(void * data)555707d151bSAlban Bedel static void lm75_disable_regulator(void *data)
556707d151bSAlban Bedel {
557707d151bSAlban Bedel struct lm75_data *lm75 = data;
558707d151bSAlban Bedel
559707d151bSAlban Bedel regulator_disable(lm75->vs);
560707d151bSAlban Bedel }
561707d151bSAlban Bedel
lm75_remove(void * data)5629e37d3e2SGuenter Roeck static void lm75_remove(void *data)
5639e37d3e2SGuenter Roeck {
5649e37d3e2SGuenter Roeck struct lm75_data *lm75 = data;
5659e37d3e2SGuenter Roeck struct i2c_client *client = lm75->client;
5669e37d3e2SGuenter Roeck
5679e37d3e2SGuenter Roeck i2c_smbus_write_byte_data(client, LM75_REG_CONF, lm75->orig_conf);
5689e37d3e2SGuenter Roeck }
5699e37d3e2SGuenter Roeck
57067487038SStephen Kitt static const struct i2c_device_id lm75_ids[];
57167487038SStephen Kitt
lm75_probe(struct i2c_client * client)57267487038SStephen Kitt static int lm75_probe(struct i2c_client *client)
5739ebd3d82SDavid Brownell {
574d663ec49SGuenter Roeck struct device *dev = &client->dev;
5759e37d3e2SGuenter Roeck struct device *hwmon_dev;
5769ebd3d82SDavid Brownell struct lm75_data *data;
57790e2b545SGuenter Roeck int status, err;
578e97a45f1SJavier Martinez Canillas enum lm75_type kind;
579e97a45f1SJavier Martinez Canillas
580e97a45f1SJavier Martinez Canillas if (client->dev.of_node)
581*c7e07faaSKrzysztof Kozlowski kind = (uintptr_t)of_device_get_match_data(&client->dev);
582e97a45f1SJavier Martinez Canillas else
58367487038SStephen Kitt kind = i2c_match_id(lm75_ids, client)->driver_data;
5849ebd3d82SDavid Brownell
5859ebd3d82SDavid Brownell if (!i2c_check_functionality(client->adapter,
5869ebd3d82SDavid Brownell I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
5879ebd3d82SDavid Brownell return -EIO;
5889ebd3d82SDavid Brownell
589d663ec49SGuenter Roeck data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL);
5909ebd3d82SDavid Brownell if (!data)
5919ebd3d82SDavid Brownell return -ENOMEM;
5929ebd3d82SDavid Brownell
593d663ec49SGuenter Roeck data->client = client;
594dcb12653SIker Perez del Palomar Sustatxa data->kind = kind;
595e65365feSGuenter Roeck
596707d151bSAlban Bedel data->vs = devm_regulator_get(dev, "vs");
597707d151bSAlban Bedel if (IS_ERR(data->vs))
598707d151bSAlban Bedel return PTR_ERR(data->vs);
599707d151bSAlban Bedel
600e65365feSGuenter Roeck data->regmap = devm_regmap_init_i2c(client, &lm75_regmap_config);
601e65365feSGuenter Roeck if (IS_ERR(data->regmap))
602e65365feSGuenter Roeck return PTR_ERR(data->regmap);
6039ebd3d82SDavid Brownell
6049ebd3d82SDavid Brownell /* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
6059ebd3d82SDavid Brownell * Then tweak to be more precise when appropriate.
6069ebd3d82SDavid Brownell */
6078a5c5cc6SJean Delvare
608dcb12653SIker Perez del Palomar Sustatxa data->params = &device_params[data->kind];
6099ebd3d82SDavid Brownell
610dcb12653SIker Perez del Palomar Sustatxa /* Save default sample time and resolution*/
611dcb12653SIker Perez del Palomar Sustatxa data->sample_time = data->params->default_sample_time;
612dcb12653SIker Perez del Palomar Sustatxa data->resolution = data->params->default_resolution;
613dcb12653SIker Perez del Palomar Sustatxa
614707d151bSAlban Bedel /* Enable the power */
615707d151bSAlban Bedel err = regulator_enable(data->vs);
616707d151bSAlban Bedel if (err) {
617707d151bSAlban Bedel dev_err(dev, "failed to enable regulator: %d\n", err);
618707d151bSAlban Bedel return err;
619707d151bSAlban Bedel }
620707d151bSAlban Bedel
621707d151bSAlban Bedel err = devm_add_action_or_reset(dev, lm75_disable_regulator, data);
622707d151bSAlban Bedel if (err)
623707d151bSAlban Bedel return err;
624707d151bSAlban Bedel
625dcb12653SIker Perez del Palomar Sustatxa /* Cache original configuration */
62638aefb41SGuenter Roeck status = i2c_smbus_read_byte_data(client, LM75_REG_CONF);
6279ebd3d82SDavid Brownell if (status < 0) {
628d663ec49SGuenter Roeck dev_dbg(dev, "Can't read config? %d\n", status);
62913ac7a01SGuenter Roeck return status;
6309ebd3d82SDavid Brownell }
6319ebd3d82SDavid Brownell data->orig_conf = status;
63258608cfeSIker Perez del Palomar Sustatxa data->current_conf = status;
63358608cfeSIker Perez del Palomar Sustatxa
63458608cfeSIker Perez del Palomar Sustatxa err = lm75_write_config(data, data->params->set_mask,
63558608cfeSIker Perez del Palomar Sustatxa data->params->clr_mask);
63658608cfeSIker Perez del Palomar Sustatxa if (err)
63758608cfeSIker Perez del Palomar Sustatxa return err;
6389e37d3e2SGuenter Roeck
63990e2b545SGuenter Roeck err = devm_add_action_or_reset(dev, lm75_remove, data);
64090e2b545SGuenter Roeck if (err)
64190e2b545SGuenter Roeck return err;
6429e37d3e2SGuenter Roeck
64308b02433SGuenter Roeck hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
64408b02433SGuenter Roeck data, &lm75_chip_info,
64508b02433SGuenter Roeck NULL);
6469e37d3e2SGuenter Roeck if (IS_ERR(hwmon_dev))
6479e37d3e2SGuenter Roeck return PTR_ERR(hwmon_dev);
6489ebd3d82SDavid Brownell
6499e37d3e2SGuenter Roeck dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name);
6509ebd3d82SDavid Brownell
6519ebd3d82SDavid Brownell return 0;
6529ebd3d82SDavid Brownell }
6539ebd3d82SDavid Brownell
6549ebd3d82SDavid Brownell static const struct i2c_device_id lm75_ids[] = {
655e96f9d89SMichael Hennerich { "adt75", adt75, },
656c851b715SPeter Rosin { "at30ts74", at30ts74, },
6579ebd3d82SDavid Brownell { "ds1775", ds1775, },
6589ebd3d82SDavid Brownell { "ds75", ds75, },
6593fbc81e3SJean Delvare { "ds7505", ds7505, },
660c98d6c65SArnaud Ebalard { "g751", g751, },
6619ebd3d82SDavid Brownell { "lm75", lm75, },
6629ebd3d82SDavid Brownell { "lm75a", lm75a, },
663799fc602SMichael Thalmeier { "lm75b", lm75b, },
6649ebd3d82SDavid Brownell { "max6625", max6625, },
6659ebd3d82SDavid Brownell { "max6626", max6626, },
666a54ca77aSKun Yi { "max31725", max31725, },
667a54ca77aSKun Yi { "max31726", max31725, },
6689ebd3d82SDavid Brownell { "mcp980x", mcp980x, },
669557c7ffaSDaniel Mack { "pct2075", pct2075, },
6709ebd3d82SDavid Brownell { "stds75", stds75, },
6712e9a41bbSJagan Teki { "stlm75", stlm75, },
6729ebd3d82SDavid Brownell { "tcn75", tcn75, },
6739ebd3d82SDavid Brownell { "tmp100", tmp100, },
6749ebd3d82SDavid Brownell { "tmp101", tmp101, },
6756d034059SShubhrajyoti Datta { "tmp105", tmp105, },
676c83959f8SFrans Klaver { "tmp112", tmp112, },
6779ebd3d82SDavid Brownell { "tmp175", tmp175, },
6789ebd3d82SDavid Brownell { "tmp275", tmp275, },
6799ebd3d82SDavid Brownell { "tmp75", tmp75, },
68039abe9d8SIker Perez del Palomar Sustatxa { "tmp75b", tmp75b, },
6819c32e815SBen Gardner { "tmp75c", tmp75c, },
682ec081f91SRobert Marko { "tmp1075", tmp1075, },
6839ebd3d82SDavid Brownell { /* LIST END */ }
6849ebd3d82SDavid Brownell };
6859ebd3d82SDavid Brownell MODULE_DEVICE_TABLE(i2c, lm75_ids);
6869ebd3d82SDavid Brownell
687ffa83e78SGuenter Roeck static const struct of_device_id __maybe_unused lm75_of_match[] = {
688e97a45f1SJavier Martinez Canillas {
689e97a45f1SJavier Martinez Canillas .compatible = "adi,adt75",
690e97a45f1SJavier Martinez Canillas .data = (void *)adt75
691e97a45f1SJavier Martinez Canillas },
692e97a45f1SJavier Martinez Canillas {
693c851b715SPeter Rosin .compatible = "atmel,at30ts74",
694c851b715SPeter Rosin .data = (void *)at30ts74
695c851b715SPeter Rosin },
696c851b715SPeter Rosin {
697e97a45f1SJavier Martinez Canillas .compatible = "dallas,ds1775",
698e97a45f1SJavier Martinez Canillas .data = (void *)ds1775
699e97a45f1SJavier Martinez Canillas },
700e97a45f1SJavier Martinez Canillas {
701e97a45f1SJavier Martinez Canillas .compatible = "dallas,ds75",
702e97a45f1SJavier Martinez Canillas .data = (void *)ds75
703e97a45f1SJavier Martinez Canillas },
704e97a45f1SJavier Martinez Canillas {
705e97a45f1SJavier Martinez Canillas .compatible = "dallas,ds7505",
706e97a45f1SJavier Martinez Canillas .data = (void *)ds7505
707e97a45f1SJavier Martinez Canillas },
708e97a45f1SJavier Martinez Canillas {
709e97a45f1SJavier Martinez Canillas .compatible = "gmt,g751",
710e97a45f1SJavier Martinez Canillas .data = (void *)g751
711e97a45f1SJavier Martinez Canillas },
712e97a45f1SJavier Martinez Canillas {
713e97a45f1SJavier Martinez Canillas .compatible = "national,lm75",
714e97a45f1SJavier Martinez Canillas .data = (void *)lm75
715e97a45f1SJavier Martinez Canillas },
716e97a45f1SJavier Martinez Canillas {
717e97a45f1SJavier Martinez Canillas .compatible = "national,lm75a",
718e97a45f1SJavier Martinez Canillas .data = (void *)lm75a
719e97a45f1SJavier Martinez Canillas },
720e97a45f1SJavier Martinez Canillas {
721e97a45f1SJavier Martinez Canillas .compatible = "national,lm75b",
722e97a45f1SJavier Martinez Canillas .data = (void *)lm75b
723e97a45f1SJavier Martinez Canillas },
724e97a45f1SJavier Martinez Canillas {
725e97a45f1SJavier Martinez Canillas .compatible = "maxim,max6625",
726e97a45f1SJavier Martinez Canillas .data = (void *)max6625
727e97a45f1SJavier Martinez Canillas },
728e97a45f1SJavier Martinez Canillas {
729e97a45f1SJavier Martinez Canillas .compatible = "maxim,max6626",
730e97a45f1SJavier Martinez Canillas .data = (void *)max6626
731e97a45f1SJavier Martinez Canillas },
732e97a45f1SJavier Martinez Canillas {
733a54ca77aSKun Yi .compatible = "maxim,max31725",
734a54ca77aSKun Yi .data = (void *)max31725
735a54ca77aSKun Yi },
736a54ca77aSKun Yi {
737a54ca77aSKun Yi .compatible = "maxim,max31726",
738a54ca77aSKun Yi .data = (void *)max31725
739a54ca77aSKun Yi },
740a54ca77aSKun Yi {
741e97a45f1SJavier Martinez Canillas .compatible = "maxim,mcp980x",
742e97a45f1SJavier Martinez Canillas .data = (void *)mcp980x
743e97a45f1SJavier Martinez Canillas },
744e97a45f1SJavier Martinez Canillas {
745557c7ffaSDaniel Mack .compatible = "nxp,pct2075",
746557c7ffaSDaniel Mack .data = (void *)pct2075
747557c7ffaSDaniel Mack },
748557c7ffaSDaniel Mack {
749e97a45f1SJavier Martinez Canillas .compatible = "st,stds75",
750e97a45f1SJavier Martinez Canillas .data = (void *)stds75
751e97a45f1SJavier Martinez Canillas },
752e97a45f1SJavier Martinez Canillas {
7532e9a41bbSJagan Teki .compatible = "st,stlm75",
7542e9a41bbSJagan Teki .data = (void *)stlm75
7552e9a41bbSJagan Teki },
7562e9a41bbSJagan Teki {
757e97a45f1SJavier Martinez Canillas .compatible = "microchip,tcn75",
758e97a45f1SJavier Martinez Canillas .data = (void *)tcn75
759e97a45f1SJavier Martinez Canillas },
760e97a45f1SJavier Martinez Canillas {
761e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp100",
762e97a45f1SJavier Martinez Canillas .data = (void *)tmp100
763e97a45f1SJavier Martinez Canillas },
764e97a45f1SJavier Martinez Canillas {
765e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp101",
766e97a45f1SJavier Martinez Canillas .data = (void *)tmp101
767e97a45f1SJavier Martinez Canillas },
768e97a45f1SJavier Martinez Canillas {
769e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp105",
770e97a45f1SJavier Martinez Canillas .data = (void *)tmp105
771e97a45f1SJavier Martinez Canillas },
772e97a45f1SJavier Martinez Canillas {
773e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp112",
774e97a45f1SJavier Martinez Canillas .data = (void *)tmp112
775e97a45f1SJavier Martinez Canillas },
776e97a45f1SJavier Martinez Canillas {
777e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp175",
778e97a45f1SJavier Martinez Canillas .data = (void *)tmp175
779e97a45f1SJavier Martinez Canillas },
780e97a45f1SJavier Martinez Canillas {
781e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp275",
782e97a45f1SJavier Martinez Canillas .data = (void *)tmp275
783e97a45f1SJavier Martinez Canillas },
784e97a45f1SJavier Martinez Canillas {
785e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp75",
786e97a45f1SJavier Martinez Canillas .data = (void *)tmp75
787e97a45f1SJavier Martinez Canillas },
788e97a45f1SJavier Martinez Canillas {
78939abe9d8SIker Perez del Palomar Sustatxa .compatible = "ti,tmp75b",
79039abe9d8SIker Perez del Palomar Sustatxa .data = (void *)tmp75b
79139abe9d8SIker Perez del Palomar Sustatxa },
79239abe9d8SIker Perez del Palomar Sustatxa {
793e97a45f1SJavier Martinez Canillas .compatible = "ti,tmp75c",
794e97a45f1SJavier Martinez Canillas .data = (void *)tmp75c
795e97a45f1SJavier Martinez Canillas },
796ec081f91SRobert Marko {
797ec081f91SRobert Marko .compatible = "ti,tmp1075",
798ec081f91SRobert Marko .data = (void *)tmp1075
799ec081f91SRobert Marko },
800e97a45f1SJavier Martinez Canillas { },
801e97a45f1SJavier Martinez Canillas };
802e97a45f1SJavier Martinez Canillas MODULE_DEVICE_TABLE(of, lm75_of_match);
803e97a45f1SJavier Martinez Canillas
80405e82fe4SLen Sorensen #define LM75A_ID 0xA1
80505e82fe4SLen Sorensen
8068ff69eebSJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */
lm75_detect(struct i2c_client * new_client,struct i2c_board_info * info)807310ec792SJean Delvare static int lm75_detect(struct i2c_client *new_client,
8088ff69eebSJean Delvare struct i2c_board_info *info)
8098d5d45fbSJean Delvare {
8108ff69eebSJean Delvare struct i2c_adapter *adapter = new_client->adapter;
8118d5d45fbSJean Delvare int i;
812e76f67b5SJean Delvare int conf, hyst, os;
81305e82fe4SLen Sorensen bool is_lm75a = 0;
8148d5d45fbSJean Delvare
8158d5d45fbSJean Delvare if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
8168d5d45fbSJean Delvare I2C_FUNC_SMBUS_WORD_DATA))
8178ff69eebSJean Delvare return -ENODEV;
8188d5d45fbSJean Delvare
819426343efSJean Delvare /*
820426343efSJean Delvare * Now, we do the remaining detection. There is no identification-
821426343efSJean Delvare * dedicated register so we have to rely on several tricks:
822426343efSJean Delvare * unused bits, registers cycling over 8-address boundaries,
823426343efSJean Delvare * addresses 0x04-0x07 returning the last read value.
824426343efSJean Delvare * The cycling+unused addresses combination is not tested,
825426343efSJean Delvare * since it would significantly slow the detection down and would
826426343efSJean Delvare * hardly add any value.
827426343efSJean Delvare *
828426343efSJean Delvare * The National Semiconductor LM75A is different than earlier
829426343efSJean Delvare * LM75s. It has an ID byte of 0xaX (where X is the chip
830426343efSJean Delvare * revision, with 1 being the only revision in existence) in
831426343efSJean Delvare * register 7, and unused registers return 0xff rather than the
832426343efSJean Delvare * last read value.
833426343efSJean Delvare *
834426343efSJean Delvare * Note that this function only detects the original National
835426343efSJean Delvare * Semiconductor LM75 and the LM75A. Clones from other vendors
836426343efSJean Delvare * aren't detected, on purpose, because they are typically never
837426343efSJean Delvare * found on PC hardware. They are found on embedded designs where
838426343efSJean Delvare * they can be instantiated explicitly so detection is not needed.
839426343efSJean Delvare * The absence of identification registers on all these clones
840426343efSJean Delvare * would make their exhaustive detection very difficult and weak,
841426343efSJean Delvare * and odds are that the driver would bind to unsupported devices.
842426343efSJean Delvare */
84305e82fe4SLen Sorensen
844e76f67b5SJean Delvare /* Unused bits */
8458d5d45fbSJean Delvare conf = i2c_smbus_read_byte_data(new_client, 1);
846e76f67b5SJean Delvare if (conf & 0xe0)
847e76f67b5SJean Delvare return -ENODEV;
84805e82fe4SLen Sorensen
84905e82fe4SLen Sorensen /* First check for LM75A */
85005e82fe4SLen Sorensen if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) {
8518cbf2172SMichal Orzel /*
8528cbf2172SMichal Orzel * LM75A returns 0xff on unused registers so
8538cbf2172SMichal Orzel * just to be sure we check for that too.
8548cbf2172SMichal Orzel */
85505e82fe4SLen Sorensen if (i2c_smbus_read_byte_data(new_client, 4) != 0xff
85605e82fe4SLen Sorensen || i2c_smbus_read_byte_data(new_client, 5) != 0xff
85705e82fe4SLen Sorensen || i2c_smbus_read_byte_data(new_client, 6) != 0xff)
85805e82fe4SLen Sorensen return -ENODEV;
85905e82fe4SLen Sorensen is_lm75a = 1;
860e76f67b5SJean Delvare hyst = i2c_smbus_read_byte_data(new_client, 2);
861e76f67b5SJean Delvare os = i2c_smbus_read_byte_data(new_client, 3);
86205e82fe4SLen Sorensen } else { /* Traditional style LM75 detection */
86305e82fe4SLen Sorensen /* Unused addresses */
864e76f67b5SJean Delvare hyst = i2c_smbus_read_byte_data(new_client, 2);
865e76f67b5SJean Delvare if (i2c_smbus_read_byte_data(new_client, 4) != hyst
866e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 5) != hyst
867e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 6) != hyst
868e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 7) != hyst)
8698ff69eebSJean Delvare return -ENODEV;
870e76f67b5SJean Delvare os = i2c_smbus_read_byte_data(new_client, 3);
871e76f67b5SJean Delvare if (i2c_smbus_read_byte_data(new_client, 4) != os
872e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 5) != os
873e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 6) != os
874e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, 7) != os)
8758ff69eebSJean Delvare return -ENODEV;
87605e82fe4SLen Sorensen }
8774ad40cc5SGuenter Roeck /*
8784ad40cc5SGuenter Roeck * It is very unlikely that this is a LM75 if both
8794ad40cc5SGuenter Roeck * hysteresis and temperature limit registers are 0.
8804ad40cc5SGuenter Roeck */
8814ad40cc5SGuenter Roeck if (hyst == 0 && os == 0)
8824ad40cc5SGuenter Roeck return -ENODEV;
8838d5d45fbSJean Delvare
8848d5d45fbSJean Delvare /* Addresses cycling */
885e76f67b5SJean Delvare for (i = 8; i <= 248; i += 40) {
8868d5d45fbSJean Delvare if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
887e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, i + 2) != hyst
888e76f67b5SJean Delvare || i2c_smbus_read_byte_data(new_client, i + 3) != os)
8898ff69eebSJean Delvare return -ENODEV;
89005e82fe4SLen Sorensen if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7)
89105e82fe4SLen Sorensen != LM75A_ID)
89205e82fe4SLen Sorensen return -ENODEV;
8938d5d45fbSJean Delvare }
8948d5d45fbSJean Delvare
895f2f394dbSWolfram Sang strscpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE);
8968d5d45fbSJean Delvare
8978d5d45fbSJean Delvare return 0;
8988d5d45fbSJean Delvare }
8998d5d45fbSJean Delvare
9009914518eSShubhrajyoti Datta #ifdef CONFIG_PM
lm75_suspend(struct device * dev)9019914518eSShubhrajyoti Datta static int lm75_suspend(struct device *dev)
9029914518eSShubhrajyoti Datta {
9039914518eSShubhrajyoti Datta int status;
9049914518eSShubhrajyoti Datta struct i2c_client *client = to_i2c_client(dev);
9058cbf2172SMichal Orzel
90638aefb41SGuenter Roeck status = i2c_smbus_read_byte_data(client, LM75_REG_CONF);
9079914518eSShubhrajyoti Datta if (status < 0) {
9089914518eSShubhrajyoti Datta dev_dbg(&client->dev, "Can't read config? %d\n", status);
9099914518eSShubhrajyoti Datta return status;
9109914518eSShubhrajyoti Datta }
9119914518eSShubhrajyoti Datta status = status | LM75_SHUTDOWN;
91238aefb41SGuenter Roeck i2c_smbus_write_byte_data(client, LM75_REG_CONF, status);
9139914518eSShubhrajyoti Datta return 0;
9149914518eSShubhrajyoti Datta }
9159914518eSShubhrajyoti Datta
lm75_resume(struct device * dev)9169914518eSShubhrajyoti Datta static int lm75_resume(struct device *dev)
9179914518eSShubhrajyoti Datta {
9189914518eSShubhrajyoti Datta int status;
9199914518eSShubhrajyoti Datta struct i2c_client *client = to_i2c_client(dev);
9208cbf2172SMichal Orzel
92138aefb41SGuenter Roeck status = i2c_smbus_read_byte_data(client, LM75_REG_CONF);
9229914518eSShubhrajyoti Datta if (status < 0) {
9239914518eSShubhrajyoti Datta dev_dbg(&client->dev, "Can't read config? %d\n", status);
9249914518eSShubhrajyoti Datta return status;
9259914518eSShubhrajyoti Datta }
9269914518eSShubhrajyoti Datta status = status & ~LM75_SHUTDOWN;
92738aefb41SGuenter Roeck i2c_smbus_write_byte_data(client, LM75_REG_CONF, status);
9289914518eSShubhrajyoti Datta return 0;
9299914518eSShubhrajyoti Datta }
9309914518eSShubhrajyoti Datta
9319914518eSShubhrajyoti Datta static const struct dev_pm_ops lm75_dev_pm_ops = {
9329914518eSShubhrajyoti Datta .suspend = lm75_suspend,
9339914518eSShubhrajyoti Datta .resume = lm75_resume,
9349914518eSShubhrajyoti Datta };
9359914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS (&lm75_dev_pm_ops)
9369914518eSShubhrajyoti Datta #else
9379914518eSShubhrajyoti Datta #define LM75_DEV_PM_OPS NULL
9389914518eSShubhrajyoti Datta #endif /* CONFIG_PM */
9399914518eSShubhrajyoti Datta
9408ff69eebSJean Delvare static struct i2c_driver lm75_driver = {
9418ff69eebSJean Delvare .class = I2C_CLASS_HWMON,
94201a52397SDavid Brownell .driver = {
9438ff69eebSJean Delvare .name = "lm75",
944e97a45f1SJavier Martinez Canillas .of_match_table = of_match_ptr(lm75_of_match),
9459914518eSShubhrajyoti Datta .pm = LM75_DEV_PM_OPS,
94601a52397SDavid Brownell },
9471975d167SUwe Kleine-König .probe = lm75_probe,
9488ff69eebSJean Delvare .id_table = lm75_ids,
9498ff69eebSJean Delvare .detect = lm75_detect,
950c3813d6aSJean Delvare .address_list = normal_i2c,
95101a52397SDavid Brownell };
95201a52397SDavid Brownell
953f0967eeaSAxel Lin module_i2c_driver(lm75_driver);
9548d5d45fbSJean Delvare
9558d5d45fbSJean Delvare MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
9568d5d45fbSJean Delvare MODULE_DESCRIPTION("LM75 driver");
9578d5d45fbSJean Delvare MODULE_LICENSE("GPL");
958