Commit | Line | Data |
---|---|---|
74ba9207 | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4 | 2 | /* |
caaa0f36 S |
3 | * lm75.c - Part of lm_sensors, Linux kernel modules for hardware |
4 | * monitoring | |
5 | * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> | |
caaa0f36 | 6 | */ |
1da177e4 | 7 | |
1da177e4 LT |
8 | #include <linux/module.h> |
9 | #include <linux/init.h> | |
10 | #include <linux/slab.h> | |
11 | #include <linux/jiffies.h> | |
12 | #include <linux/i2c.h> | |
943b0830 | 13 | #include <linux/hwmon.h> |
9ca8e40c | 14 | #include <linux/hwmon-sysfs.h> |
943b0830 | 15 | #include <linux/err.h> |
e97a45f1 | 16 | #include <linux/of_device.h> |
22e73183 | 17 | #include <linux/of.h> |
e65365fe | 18 | #include <linux/regmap.h> |
1da177e4 LT |
19 | #include "lm75.h" |
20 | ||
21 | ||
01a52397 DB |
22 | /* |
23 | * This driver handles the LM75 and compatible digital temperature sensors. | |
01a52397 DB |
24 | */ |
25 | ||
9ebd3d82 | 26 | enum lm75_type { /* keep sorted in alphabetical order */ |
e96f9d89 | 27 | adt75, |
1f86df49 | 28 | ds1775, |
9ebd3d82 | 29 | ds75, |
3fbc81e3 | 30 | ds7505, |
c98d6c65 | 31 | g751, |
1f86df49 | 32 | lm75, |
9ebd3d82 | 33 | lm75a, |
799fc602 | 34 | lm75b, |
9ebd3d82 DB |
35 | max6625, |
36 | max6626, | |
a54ca77a | 37 | max31725, |
9ebd3d82 DB |
38 | mcp980x, |
39 | stds75, | |
2e9a41bb | 40 | stlm75, |
9ebd3d82 DB |
41 | tcn75, |
42 | tmp100, | |
43 | tmp101, | |
6d034059 | 44 | tmp105, |
c83959f8 | 45 | tmp112, |
9ebd3d82 DB |
46 | tmp175, |
47 | tmp275, | |
48 | tmp75, | |
39abe9d8 | 49 | tmp75b, |
9c32e815 | 50 | tmp75c, |
9ebd3d82 DB |
51 | }; |
52 | ||
8ff69eeb | 53 | /* Addresses scanned */ |
25e9c86d | 54 | static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, |
1da177e4 | 55 | 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; |
1da177e4 | 56 | |
1da177e4 | 57 | /* The LM75 registers */ |
e65365fe | 58 | #define LM75_REG_TEMP 0x00 |
1da177e4 | 59 | #define LM75_REG_CONF 0x01 |
e65365fe GR |
60 | #define LM75_REG_HYST 0x02 |
61 | #define LM75_REG_MAX 0x03 | |
1da177e4 LT |
62 | |
63 | /* Each client has this additional data */ | |
64 | struct lm75_data { | |
d663ec49 | 65 | struct i2c_client *client; |
e65365fe | 66 | struct regmap *regmap; |
9ebd3d82 | 67 | u8 orig_conf; |
a54ca77a | 68 | u8 resolution; /* In bits, between 9 and 16 */ |
87d0621a | 69 | u8 resolution_limits; |
e65365fe | 70 | unsigned int sample_time; /* In ms */ |
1da177e4 LT |
71 | }; |
72 | ||
01a52397 DB |
73 | /*-----------------------------------------------------------------------*/ |
74 | ||
22e73183 EV |
75 | static inline long lm75_reg_to_mc(s16 temp, u8 resolution) |
76 | { | |
77 | return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); | |
78 | } | |
79 | ||
08b02433 GR |
80 | static int lm75_read(struct device *dev, enum hwmon_sensor_types type, |
81 | u32 attr, int channel, long *val) | |
22e73183 | 82 | { |
e65365fe | 83 | struct lm75_data *data = dev_get_drvdata(dev); |
08b02433 GR |
84 | unsigned int regval; |
85 | int err, reg; | |
86 | ||
87 | switch (type) { | |
88 | case hwmon_chip: | |
89 | switch (attr) { | |
90 | case hwmon_chip_update_interval: | |
91 | *val = data->sample_time; | |
ccffe776 | 92 | break; |
08b02433 GR |
93 | default: |
94 | return -EINVAL; | |
95 | } | |
96 | break; | |
97 | case hwmon_temp: | |
98 | switch (attr) { | |
99 | case hwmon_temp_input: | |
100 | reg = LM75_REG_TEMP; | |
101 | break; | |
102 | case hwmon_temp_max: | |
103 | reg = LM75_REG_MAX; | |
104 | break; | |
105 | case hwmon_temp_max_hyst: | |
106 | reg = LM75_REG_HYST; | |
107 | break; | |
108 | default: | |
109 | return -EINVAL; | |
110 | } | |
111 | err = regmap_read(data->regmap, reg, ®val); | |
112 | if (err < 0) | |
113 | return err; | |
114 | ||
115 | *val = lm75_reg_to_mc(regval, data->resolution); | |
116 | break; | |
117 | default: | |
118 | return -EINVAL; | |
119 | } | |
22e73183 EV |
120 | return 0; |
121 | } | |
122 | ||
08b02433 GR |
123 | static int lm75_write(struct device *dev, enum hwmon_sensor_types type, |
124 | u32 attr, int channel, long temp) | |
9ca8e40c | 125 | { |
e65365fe | 126 | struct lm75_data *data = dev_get_drvdata(dev); |
87d0621a | 127 | u8 resolution; |
08b02433 GR |
128 | int reg; |
129 | ||
130 | if (type != hwmon_temp) | |
131 | return -EINVAL; | |
e3cd9528 | 132 | |
08b02433 GR |
133 | switch (attr) { |
134 | case hwmon_temp_max: | |
135 | reg = LM75_REG_MAX; | |
136 | break; | |
137 | case hwmon_temp_max_hyst: | |
138 | reg = LM75_REG_HYST; | |
139 | break; | |
140 | default: | |
141 | return -EINVAL; | |
142 | } | |
9ca8e40c | 143 | |
87d0621a JD |
144 | /* |
145 | * Resolution of limit registers is assumed to be the same as the | |
146 | * temperature input register resolution unless given explicitly. | |
147 | */ | |
08b02433 | 148 | if (data->resolution_limits) |
87d0621a JD |
149 | resolution = data->resolution_limits; |
150 | else | |
151 | resolution = data->resolution; | |
152 | ||
87d0621a | 153 | temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); |
e65365fe GR |
154 | temp = DIV_ROUND_CLOSEST(temp << (resolution - 8), |
155 | 1000) << (16 - resolution); | |
e65365fe | 156 | |
08b02433 | 157 | return regmap_write(data->regmap, reg, temp); |
1da177e4 | 158 | } |
1da177e4 | 159 | |
08b02433 GR |
160 | static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type, |
161 | u32 attr, int channel) | |
5f7e5e29 | 162 | { |
08b02433 GR |
163 | switch (type) { |
164 | case hwmon_chip: | |
165 | switch (attr) { | |
166 | case hwmon_chip_update_interval: | |
e6ab6e0e | 167 | return 0444; |
08b02433 GR |
168 | } |
169 | break; | |
170 | case hwmon_temp: | |
171 | switch (attr) { | |
172 | case hwmon_temp_input: | |
e6ab6e0e | 173 | return 0444; |
08b02433 GR |
174 | case hwmon_temp_max: |
175 | case hwmon_temp_max_hyst: | |
e6ab6e0e | 176 | return 0644; |
08b02433 GR |
177 | } |
178 | break; | |
179 | default: | |
180 | break; | |
181 | } | |
182 | return 0; | |
5f7e5e29 GR |
183 | } |
184 | ||
08b02433 | 185 | static const struct hwmon_channel_info *lm75_info[] = { |
e4f6fed1 GR |
186 | HWMON_CHANNEL_INFO(chip, |
187 | HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL), | |
188 | HWMON_CHANNEL_INFO(temp, | |
189 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), | |
08b02433 GR |
190 | NULL |
191 | }; | |
192 | ||
193 | static const struct hwmon_ops lm75_hwmon_ops = { | |
194 | .is_visible = lm75_is_visible, | |
195 | .read = lm75_read, | |
196 | .write = lm75_write, | |
197 | }; | |
198 | ||
199 | static const struct hwmon_chip_info lm75_chip_info = { | |
200 | .ops = &lm75_hwmon_ops, | |
201 | .info = lm75_info, | |
202 | }; | |
9ebd3d82 | 203 | |
e65365fe GR |
204 | static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg) |
205 | { | |
206 | return reg != LM75_REG_TEMP; | |
207 | } | |
208 | ||
209 | static bool lm75_is_volatile_reg(struct device *dev, unsigned int reg) | |
210 | { | |
211 | return reg == LM75_REG_TEMP; | |
212 | } | |
213 | ||
214 | static const struct regmap_config lm75_regmap_config = { | |
215 | .reg_bits = 8, | |
216 | .val_bits = 16, | |
217 | .max_register = LM75_REG_MAX, | |
218 | .writeable_reg = lm75_is_writeable_reg, | |
219 | .volatile_reg = lm75_is_volatile_reg, | |
220 | .val_format_endian = REGMAP_ENDIAN_BIG, | |
221 | .cache_type = REGCACHE_RBTREE, | |
1c96a2f6 DF |
222 | .use_single_read = true, |
223 | .use_single_write = true, | |
e65365fe GR |
224 | }; |
225 | ||
9e37d3e2 GR |
226 | static void lm75_remove(void *data) |
227 | { | |
228 | struct lm75_data *lm75 = data; | |
229 | struct i2c_client *client = lm75->client; | |
230 | ||
231 | i2c_smbus_write_byte_data(client, LM75_REG_CONF, lm75->orig_conf); | |
232 | } | |
233 | ||
9ebd3d82 DB |
234 | static int |
235 | lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | |
236 | { | |
d663ec49 | 237 | struct device *dev = &client->dev; |
9e37d3e2 | 238 | struct device *hwmon_dev; |
9ebd3d82 | 239 | struct lm75_data *data; |
90e2b545 | 240 | int status, err; |
9ebd3d82 DB |
241 | u8 set_mask, clr_mask; |
242 | int new; | |
e97a45f1 JMC |
243 | enum lm75_type kind; |
244 | ||
245 | if (client->dev.of_node) | |
246 | kind = (enum lm75_type)of_device_get_match_data(&client->dev); | |
247 | else | |
248 | kind = id->driver_data; | |
9ebd3d82 DB |
249 | |
250 | if (!i2c_check_functionality(client->adapter, | |
251 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) | |
252 | return -EIO; | |
253 | ||
d663ec49 | 254 | data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); |
9ebd3d82 DB |
255 | if (!data) |
256 | return -ENOMEM; | |
257 | ||
d663ec49 | 258 | data->client = client; |
e65365fe GR |
259 | |
260 | data->regmap = devm_regmap_init_i2c(client, &lm75_regmap_config); | |
261 | if (IS_ERR(data->regmap)) | |
262 | return PTR_ERR(data->regmap); | |
9ebd3d82 DB |
263 | |
264 | /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. | |
265 | * Then tweak to be more precise when appropriate. | |
266 | */ | |
267 | set_mask = 0; | |
8a5c5cc6 JD |
268 | clr_mask = LM75_SHUTDOWN; /* continuous conversions */ |
269 | ||
0cd2c72d | 270 | switch (kind) { |
8a5c5cc6 JD |
271 | case adt75: |
272 | clr_mask |= 1 << 5; /* not one-shot mode */ | |
0cd2c72d | 273 | data->resolution = 12; |
e65365fe | 274 | data->sample_time = MSEC_PER_SEC / 8; |
8a5c5cc6 JD |
275 | break; |
276 | case ds1775: | |
277 | case ds75: | |
278 | case stds75: | |
0cd2c72d JD |
279 | clr_mask |= 3 << 5; |
280 | set_mask |= 2 << 5; /* 11-bit mode */ | |
281 | data->resolution = 11; | |
e65365fe | 282 | data->sample_time = MSEC_PER_SEC; |
0cd2c72d | 283 | break; |
2e9a41bb JT |
284 | case stlm75: |
285 | data->resolution = 9; | |
286 | data->sample_time = MSEC_PER_SEC / 5; | |
287 | break; | |
3fbc81e3 JD |
288 | case ds7505: |
289 | set_mask |= 3 << 5; /* 12-bit mode */ | |
290 | data->resolution = 12; | |
e65365fe | 291 | data->sample_time = MSEC_PER_SEC / 4; |
3fbc81e3 | 292 | break; |
c98d6c65 | 293 | case g751: |
0cd2c72d JD |
294 | case lm75: |
295 | case lm75a: | |
296 | data->resolution = 9; | |
e65365fe | 297 | data->sample_time = MSEC_PER_SEC / 2; |
0cd2c72d | 298 | break; |
799fc602 MT |
299 | case lm75b: |
300 | data->resolution = 11; | |
e65365fe | 301 | data->sample_time = MSEC_PER_SEC / 4; |
799fc602 | 302 | break; |
0cd2c72d JD |
303 | case max6625: |
304 | data->resolution = 9; | |
e65365fe | 305 | data->sample_time = MSEC_PER_SEC / 4; |
0cd2c72d JD |
306 | break; |
307 | case max6626: | |
308 | data->resolution = 12; | |
309 | data->resolution_limits = 9; | |
e65365fe | 310 | data->sample_time = MSEC_PER_SEC / 4; |
0cd2c72d | 311 | break; |
a54ca77a KY |
312 | case max31725: |
313 | data->resolution = 16; | |
314 | data->sample_time = MSEC_PER_SEC / 8; | |
315 | break; | |
0cd2c72d JD |
316 | case tcn75: |
317 | data->resolution = 9; | |
e65365fe | 318 | data->sample_time = MSEC_PER_SEC / 8; |
8a5c5cc6 JD |
319 | break; |
320 | case mcp980x: | |
0cd2c72d JD |
321 | data->resolution_limits = 9; |
322 | /* fall through */ | |
8a5c5cc6 JD |
323 | case tmp100: |
324 | case tmp101: | |
0cd2c72d JD |
325 | set_mask |= 3 << 5; /* 12-bit mode */ |
326 | data->resolution = 12; | |
e65365fe | 327 | data->sample_time = MSEC_PER_SEC; |
0cd2c72d JD |
328 | clr_mask |= 1 << 7; /* not one-shot mode */ |
329 | break; | |
c83959f8 FK |
330 | case tmp112: |
331 | set_mask |= 3 << 5; /* 12-bit mode */ | |
332 | clr_mask |= 1 << 7; /* not one-shot mode */ | |
333 | data->resolution = 12; | |
e65365fe | 334 | data->sample_time = MSEC_PER_SEC / 4; |
c83959f8 | 335 | break; |
8a5c5cc6 JD |
336 | case tmp105: |
337 | case tmp175: | |
338 | case tmp275: | |
339 | case tmp75: | |
0cd2c72d | 340 | set_mask |= 3 << 5; /* 12-bit mode */ |
8a5c5cc6 | 341 | clr_mask |= 1 << 7; /* not one-shot mode */ |
0cd2c72d | 342 | data->resolution = 12; |
e65365fe | 343 | data->sample_time = MSEC_PER_SEC / 2; |
8a5c5cc6 | 344 | break; |
39abe9d8 | 345 | case tmp75b: /* not one-shot mode, Conversion rate 37Hz */ |
a95a4f3f | 346 | clr_mask |= 1 << 7 | 0x3 << 5; |
39abe9d8 IPPS |
347 | data->resolution = 12; |
348 | data->sample_time = MSEC_PER_SEC / 37; | |
349 | break; | |
9c32e815 BG |
350 | case tmp75c: |
351 | clr_mask |= 1 << 5; /* not one-shot mode */ | |
352 | data->resolution = 12; | |
e65365fe | 353 | data->sample_time = MSEC_PER_SEC / 4; |
9c32e815 | 354 | break; |
8a5c5cc6 | 355 | } |
9ebd3d82 DB |
356 | |
357 | /* configure as specified */ | |
38aefb41 | 358 | status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); |
9ebd3d82 | 359 | if (status < 0) { |
d663ec49 | 360 | dev_dbg(dev, "Can't read config? %d\n", status); |
13ac7a01 | 361 | return status; |
9ebd3d82 DB |
362 | } |
363 | data->orig_conf = status; | |
364 | new = status & ~clr_mask; | |
365 | new |= set_mask; | |
366 | if (status != new) | |
38aefb41 | 367 | i2c_smbus_write_byte_data(client, LM75_REG_CONF, new); |
9ebd3d82 | 368 | |
90e2b545 GR |
369 | err = devm_add_action_or_reset(dev, lm75_remove, data); |
370 | if (err) | |
371 | return err; | |
9ebd3d82 | 372 | |
9e37d3e2 | 373 | dev_dbg(dev, "Config %02x\n", new); |
22e73183 | 374 | |
08b02433 GR |
375 | hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, |
376 | data, &lm75_chip_info, | |
377 | NULL); | |
9e37d3e2 GR |
378 | if (IS_ERR(hwmon_dev)) |
379 | return PTR_ERR(hwmon_dev); | |
9ebd3d82 | 380 | |
9e37d3e2 | 381 | dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name); |
9ebd3d82 | 382 | |
9ebd3d82 DB |
383 | return 0; |
384 | } | |
385 | ||
386 | static const struct i2c_device_id lm75_ids[] = { | |
e96f9d89 | 387 | { "adt75", adt75, }, |
9ebd3d82 DB |
388 | { "ds1775", ds1775, }, |
389 | { "ds75", ds75, }, | |
3fbc81e3 | 390 | { "ds7505", ds7505, }, |
c98d6c65 | 391 | { "g751", g751, }, |
9ebd3d82 DB |
392 | { "lm75", lm75, }, |
393 | { "lm75a", lm75a, }, | |
799fc602 | 394 | { "lm75b", lm75b, }, |
9ebd3d82 DB |
395 | { "max6625", max6625, }, |
396 | { "max6626", max6626, }, | |
a54ca77a KY |
397 | { "max31725", max31725, }, |
398 | { "max31726", max31725, }, | |
9ebd3d82 DB |
399 | { "mcp980x", mcp980x, }, |
400 | { "stds75", stds75, }, | |
2e9a41bb | 401 | { "stlm75", stlm75, }, |
9ebd3d82 DB |
402 | { "tcn75", tcn75, }, |
403 | { "tmp100", tmp100, }, | |
404 | { "tmp101", tmp101, }, | |
6d034059 | 405 | { "tmp105", tmp105, }, |
c83959f8 | 406 | { "tmp112", tmp112, }, |
9ebd3d82 DB |
407 | { "tmp175", tmp175, }, |
408 | { "tmp275", tmp275, }, | |
409 | { "tmp75", tmp75, }, | |
39abe9d8 | 410 | { "tmp75b", tmp75b, }, |
9c32e815 | 411 | { "tmp75c", tmp75c, }, |
9ebd3d82 DB |
412 | { /* LIST END */ } |
413 | }; | |
414 | MODULE_DEVICE_TABLE(i2c, lm75_ids); | |
415 | ||
ffa83e78 | 416 | static const struct of_device_id __maybe_unused lm75_of_match[] = { |
e97a45f1 JMC |
417 | { |
418 | .compatible = "adi,adt75", | |
419 | .data = (void *)adt75 | |
420 | }, | |
421 | { | |
422 | .compatible = "dallas,ds1775", | |
423 | .data = (void *)ds1775 | |
424 | }, | |
425 | { | |
426 | .compatible = "dallas,ds75", | |
427 | .data = (void *)ds75 | |
428 | }, | |
429 | { | |
430 | .compatible = "dallas,ds7505", | |
431 | .data = (void *)ds7505 | |
432 | }, | |
433 | { | |
434 | .compatible = "gmt,g751", | |
435 | .data = (void *)g751 | |
436 | }, | |
437 | { | |
438 | .compatible = "national,lm75", | |
439 | .data = (void *)lm75 | |
440 | }, | |
441 | { | |
442 | .compatible = "national,lm75a", | |
443 | .data = (void *)lm75a | |
444 | }, | |
445 | { | |
446 | .compatible = "national,lm75b", | |
447 | .data = (void *)lm75b | |
448 | }, | |
449 | { | |
450 | .compatible = "maxim,max6625", | |
451 | .data = (void *)max6625 | |
452 | }, | |
453 | { | |
454 | .compatible = "maxim,max6626", | |
455 | .data = (void *)max6626 | |
456 | }, | |
a54ca77a KY |
457 | { |
458 | .compatible = "maxim,max31725", | |
459 | .data = (void *)max31725 | |
460 | }, | |
461 | { | |
462 | .compatible = "maxim,max31726", | |
463 | .data = (void *)max31725 | |
464 | }, | |
e97a45f1 JMC |
465 | { |
466 | .compatible = "maxim,mcp980x", | |
467 | .data = (void *)mcp980x | |
468 | }, | |
469 | { | |
470 | .compatible = "st,stds75", | |
471 | .data = (void *)stds75 | |
472 | }, | |
2e9a41bb JT |
473 | { |
474 | .compatible = "st,stlm75", | |
475 | .data = (void *)stlm75 | |
476 | }, | |
e97a45f1 JMC |
477 | { |
478 | .compatible = "microchip,tcn75", | |
479 | .data = (void *)tcn75 | |
480 | }, | |
481 | { | |
482 | .compatible = "ti,tmp100", | |
483 | .data = (void *)tmp100 | |
484 | }, | |
485 | { | |
486 | .compatible = "ti,tmp101", | |
487 | .data = (void *)tmp101 | |
488 | }, | |
489 | { | |
490 | .compatible = "ti,tmp105", | |
491 | .data = (void *)tmp105 | |
492 | }, | |
493 | { | |
494 | .compatible = "ti,tmp112", | |
495 | .data = (void *)tmp112 | |
496 | }, | |
497 | { | |
498 | .compatible = "ti,tmp175", | |
499 | .data = (void *)tmp175 | |
500 | }, | |
501 | { | |
502 | .compatible = "ti,tmp275", | |
503 | .data = (void *)tmp275 | |
504 | }, | |
505 | { | |
506 | .compatible = "ti,tmp75", | |
507 | .data = (void *)tmp75 | |
508 | }, | |
39abe9d8 IPPS |
509 | { |
510 | .compatible = "ti,tmp75b", | |
511 | .data = (void *)tmp75b | |
512 | }, | |
e97a45f1 JMC |
513 | { |
514 | .compatible = "ti,tmp75c", | |
515 | .data = (void *)tmp75c | |
516 | }, | |
517 | { }, | |
518 | }; | |
519 | MODULE_DEVICE_TABLE(of, lm75_of_match); | |
520 | ||
05e82fe4 LS |
521 | #define LM75A_ID 0xA1 |
522 | ||
8ff69eeb | 523 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
310ec792 | 524 | static int lm75_detect(struct i2c_client *new_client, |
8ff69eeb | 525 | struct i2c_board_info *info) |
1da177e4 | 526 | { |
8ff69eeb | 527 | struct i2c_adapter *adapter = new_client->adapter; |
1da177e4 | 528 | int i; |
e76f67b5 | 529 | int conf, hyst, os; |
05e82fe4 | 530 | bool is_lm75a = 0; |
1da177e4 | 531 | |
1da177e4 LT |
532 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
533 | I2C_FUNC_SMBUS_WORD_DATA)) | |
8ff69eeb | 534 | return -ENODEV; |
1da177e4 | 535 | |
426343ef JD |
536 | /* |
537 | * Now, we do the remaining detection. There is no identification- | |
538 | * dedicated register so we have to rely on several tricks: | |
539 | * unused bits, registers cycling over 8-address boundaries, | |
540 | * addresses 0x04-0x07 returning the last read value. | |
541 | * The cycling+unused addresses combination is not tested, | |
542 | * since it would significantly slow the detection down and would | |
543 | * hardly add any value. | |
544 | * | |
545 | * The National Semiconductor LM75A is different than earlier | |
546 | * LM75s. It has an ID byte of 0xaX (where X is the chip | |
547 | * revision, with 1 being the only revision in existence) in | |
548 | * register 7, and unused registers return 0xff rather than the | |
549 | * last read value. | |
550 | * | |
551 | * Note that this function only detects the original National | |
552 | * Semiconductor LM75 and the LM75A. Clones from other vendors | |
553 | * aren't detected, on purpose, because they are typically never | |
554 | * found on PC hardware. They are found on embedded designs where | |
555 | * they can be instantiated explicitly so detection is not needed. | |
556 | * The absence of identification registers on all these clones | |
557 | * would make their exhaustive detection very difficult and weak, | |
558 | * and odds are that the driver would bind to unsupported devices. | |
559 | */ | |
1da177e4 | 560 | |
e76f67b5 | 561 | /* Unused bits */ |
52df6440 | 562 | conf = i2c_smbus_read_byte_data(new_client, 1); |
e76f67b5 JD |
563 | if (conf & 0xe0) |
564 | return -ENODEV; | |
05e82fe4 LS |
565 | |
566 | /* First check for LM75A */ | |
567 | if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { | |
568 | /* LM75A returns 0xff on unused registers so | |
569 | just to be sure we check for that too. */ | |
570 | if (i2c_smbus_read_byte_data(new_client, 4) != 0xff | |
571 | || i2c_smbus_read_byte_data(new_client, 5) != 0xff | |
572 | || i2c_smbus_read_byte_data(new_client, 6) != 0xff) | |
573 | return -ENODEV; | |
574 | is_lm75a = 1; | |
e76f67b5 JD |
575 | hyst = i2c_smbus_read_byte_data(new_client, 2); |
576 | os = i2c_smbus_read_byte_data(new_client, 3); | |
05e82fe4 LS |
577 | } else { /* Traditional style LM75 detection */ |
578 | /* Unused addresses */ | |
e76f67b5 JD |
579 | hyst = i2c_smbus_read_byte_data(new_client, 2); |
580 | if (i2c_smbus_read_byte_data(new_client, 4) != hyst | |
581 | || i2c_smbus_read_byte_data(new_client, 5) != hyst | |
582 | || i2c_smbus_read_byte_data(new_client, 6) != hyst | |
583 | || i2c_smbus_read_byte_data(new_client, 7) != hyst) | |
05e82fe4 | 584 | return -ENODEV; |
e76f67b5 JD |
585 | os = i2c_smbus_read_byte_data(new_client, 3); |
586 | if (i2c_smbus_read_byte_data(new_client, 4) != os | |
587 | || i2c_smbus_read_byte_data(new_client, 5) != os | |
588 | || i2c_smbus_read_byte_data(new_client, 6) != os | |
589 | || i2c_smbus_read_byte_data(new_client, 7) != os) | |
05e82fe4 LS |
590 | return -ENODEV; |
591 | } | |
4ad40cc5 GR |
592 | /* |
593 | * It is very unlikely that this is a LM75 if both | |
594 | * hysteresis and temperature limit registers are 0. | |
595 | */ | |
596 | if (hyst == 0 && os == 0) | |
597 | return -ENODEV; | |
1da177e4 | 598 | |
52df6440 | 599 | /* Addresses cycling */ |
e76f67b5 | 600 | for (i = 8; i <= 248; i += 40) { |
52df6440 | 601 | if (i2c_smbus_read_byte_data(new_client, i + 1) != conf |
e76f67b5 JD |
602 | || i2c_smbus_read_byte_data(new_client, i + 2) != hyst |
603 | || i2c_smbus_read_byte_data(new_client, i + 3) != os) | |
52df6440 | 604 | return -ENODEV; |
05e82fe4 LS |
605 | if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) |
606 | != LM75A_ID) | |
607 | return -ENODEV; | |
1da177e4 LT |
608 | } |
609 | ||
05e82fe4 | 610 | strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); |
c1685f61 | 611 | |
1da177e4 | 612 | return 0; |
01a52397 DB |
613 | } |
614 | ||
9914518e SD |
615 | #ifdef CONFIG_PM |
616 | static int lm75_suspend(struct device *dev) | |
617 | { | |
618 | int status; | |
619 | struct i2c_client *client = to_i2c_client(dev); | |
38aefb41 | 620 | status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); |
9914518e SD |
621 | if (status < 0) { |
622 | dev_dbg(&client->dev, "Can't read config? %d\n", status); | |
623 | return status; | |
624 | } | |
625 | status = status | LM75_SHUTDOWN; | |
38aefb41 | 626 | i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); |
9914518e SD |
627 | return 0; |
628 | } | |
629 | ||
630 | static int lm75_resume(struct device *dev) | |
631 | { | |
632 | int status; | |
633 | struct i2c_client *client = to_i2c_client(dev); | |
38aefb41 | 634 | status = i2c_smbus_read_byte_data(client, LM75_REG_CONF); |
9914518e SD |
635 | if (status < 0) { |
636 | dev_dbg(&client->dev, "Can't read config? %d\n", status); | |
637 | return status; | |
638 | } | |
639 | status = status & ~LM75_SHUTDOWN; | |
38aefb41 | 640 | i2c_smbus_write_byte_data(client, LM75_REG_CONF, status); |
9914518e SD |
641 | return 0; |
642 | } | |
643 | ||
644 | static const struct dev_pm_ops lm75_dev_pm_ops = { | |
645 | .suspend = lm75_suspend, | |
646 | .resume = lm75_resume, | |
647 | }; | |
648 | #define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) | |
649 | #else | |
650 | #define LM75_DEV_PM_OPS NULL | |
651 | #endif /* CONFIG_PM */ | |
652 | ||
8ff69eeb JD |
653 | static struct i2c_driver lm75_driver = { |
654 | .class = I2C_CLASS_HWMON, | |
01a52397 | 655 | .driver = { |
8ff69eeb | 656 | .name = "lm75", |
e97a45f1 | 657 | .of_match_table = of_match_ptr(lm75_of_match), |
9914518e | 658 | .pm = LM75_DEV_PM_OPS, |
01a52397 | 659 | }, |
8ff69eeb | 660 | .probe = lm75_probe, |
8ff69eeb JD |
661 | .id_table = lm75_ids, |
662 | .detect = lm75_detect, | |
c3813d6a | 663 | .address_list = normal_i2c, |
01a52397 DB |
664 | }; |
665 | ||
f0967eea | 666 | module_i2c_driver(lm75_driver); |
1da177e4 LT |
667 | |
668 | MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); | |
669 | MODULE_DESCRIPTION("LM75 driver"); | |
670 | MODULE_LICENSE("GPL"); |