1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Driver for the ADT7411 (I2C/SPI 8 channel 10 bit ADC & temperature-sensor) |
4 | * |
5 | * Copyright (C) 2008, 2010 Pengutronix |
6 | * |
7 | * TODO: SPI, use power-down mode for suspend?, interrupt handling? |
8 | */ |
9 | |
10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> |
12 | #include <linux/init.h> |
13 | #include <linux/err.h> |
14 | #include <linux/mutex.h> |
15 | #include <linux/jiffies.h> |
16 | #include <linux/i2c.h> |
17 | #include <linux/hwmon.h> |
18 | #include <linux/hwmon-sysfs.h> |
19 | #include <linux/slab.h> |
20 | |
21 | #define ADT7411_REG_STAT_1 0x00 |
22 | #define ADT7411_STAT_1_INT_TEMP_HIGH BIT(0) |
23 | #define ADT7411_STAT_1_INT_TEMP_LOW BIT(1) |
24 | #define ADT7411_STAT_1_EXT_TEMP_HIGH_AIN1 BIT(2) |
25 | #define ADT7411_STAT_1_EXT_TEMP_LOW BIT(3) |
26 | #define ADT7411_STAT_1_EXT_TEMP_FAULT BIT(4) |
27 | #define ADT7411_STAT_1_AIN2 BIT(5) |
28 | #define ADT7411_STAT_1_AIN3 BIT(6) |
29 | #define ADT7411_STAT_1_AIN4 BIT(7) |
30 | #define ADT7411_REG_STAT_2 0x01 |
31 | #define ADT7411_STAT_2_AIN5 BIT(0) |
32 | #define ADT7411_STAT_2_AIN6 BIT(1) |
33 | #define ADT7411_STAT_2_AIN7 BIT(2) |
34 | #define ADT7411_STAT_2_AIN8 BIT(3) |
35 | #define ADT7411_STAT_2_VDD BIT(4) |
36 | #define ADT7411_REG_INT_TEMP_VDD_LSB 0x03 |
37 | #define ADT7411_REG_EXT_TEMP_AIN14_LSB 0x04 |
38 | #define ADT7411_REG_VDD_MSB 0x06 |
39 | #define ADT7411_REG_INT_TEMP_MSB 0x07 |
40 | #define ADT7411_REG_EXT_TEMP_AIN1_MSB 0x08 |
41 | |
42 | #define ADT7411_REG_CFG1 0x18 |
43 | #define ADT7411_CFG1_START_MONITOR BIT(0) |
44 | #define ADT7411_CFG1_RESERVED_BIT1 BIT(1) |
45 | #define ADT7411_CFG1_EXT_TDM BIT(2) |
46 | #define ADT7411_CFG1_RESERVED_BIT3 BIT(3) |
47 | |
48 | #define ADT7411_REG_CFG2 0x19 |
49 | #define ADT7411_CFG2_DISABLE_AVG BIT(5) |
50 | |
51 | #define ADT7411_REG_CFG3 0x1a |
52 | #define ADT7411_CFG3_ADC_CLK_225 BIT(0) |
53 | #define ADT7411_CFG3_RESERVED_BIT1 BIT(1) |
54 | #define ADT7411_CFG3_RESERVED_BIT2 BIT(2) |
55 | #define ADT7411_CFG3_RESERVED_BIT3 BIT(3) |
56 | #define ADT7411_CFG3_REF_VDD BIT(4) |
57 | |
58 | #define ADT7411_REG_VDD_HIGH 0x23 |
59 | #define ADT7411_REG_VDD_LOW 0x24 |
60 | #define ADT7411_REG_TEMP_HIGH(nr) (0x25 + 2 * (nr)) |
61 | #define ADT7411_REG_TEMP_LOW(nr) (0x26 + 2 * (nr)) |
62 | #define ADT7411_REG_IN_HIGH(nr) ((nr) > 1 \ |
63 | ? 0x2b + 2 * ((nr)-2) \ |
64 | : 0x27) |
65 | #define ADT7411_REG_IN_LOW(nr) ((nr) > 1 \ |
66 | ? 0x2c + 2 * ((nr)-2) \ |
67 | : 0x28) |
68 | |
69 | #define ADT7411_REG_DEVICE_ID 0x4d |
70 | #define ADT7411_REG_MANUFACTURER_ID 0x4e |
71 | |
72 | #define ADT7411_DEVICE_ID 0x2 |
73 | #define ADT7411_MANUFACTURER_ID 0x41 |
74 | |
75 | static const unsigned short normal_i2c[] = { 0x48, 0x4a, 0x4b, I2C_CLIENT_END }; |
76 | |
77 | static const u8 adt7411_in_alarm_reg[] = { |
78 | ADT7411_REG_STAT_2, |
79 | ADT7411_REG_STAT_1, |
80 | ADT7411_REG_STAT_1, |
81 | ADT7411_REG_STAT_1, |
82 | ADT7411_REG_STAT_1, |
83 | ADT7411_REG_STAT_2, |
84 | ADT7411_REG_STAT_2, |
85 | ADT7411_REG_STAT_2, |
86 | ADT7411_REG_STAT_2, |
87 | }; |
88 | |
89 | static const u8 adt7411_in_alarm_bits[] = { |
90 | ADT7411_STAT_2_VDD, |
91 | ADT7411_STAT_1_EXT_TEMP_HIGH_AIN1, |
92 | ADT7411_STAT_1_AIN2, |
93 | ADT7411_STAT_1_AIN3, |
94 | ADT7411_STAT_1_AIN4, |
95 | ADT7411_STAT_2_AIN5, |
96 | ADT7411_STAT_2_AIN6, |
97 | ADT7411_STAT_2_AIN7, |
98 | ADT7411_STAT_2_AIN8, |
99 | }; |
100 | |
101 | struct adt7411_data { |
102 | struct mutex device_lock; /* for "atomic" device accesses */ |
103 | struct mutex update_lock; |
104 | unsigned long next_update; |
105 | long vref_cached; |
106 | struct i2c_client *client; |
107 | bool use_ext_temp; |
108 | }; |
109 | |
110 | /* |
111 | * When reading a register containing (up to 4) lsb, all associated |
112 | * msb-registers get locked by the hardware. After _one_ of those msb is read, |
113 | * _all_ are unlocked. In order to use this locking correctly, reading lsb/msb |
114 | * is protected here with a mutex, too. |
115 | */ |
116 | static int adt7411_read_10_bit(struct i2c_client *client, u8 lsb_reg, |
117 | u8 msb_reg, u8 lsb_shift) |
118 | { |
119 | struct adt7411_data *data = i2c_get_clientdata(client); |
120 | int val, tmp; |
121 | |
122 | mutex_lock(&data->device_lock); |
123 | |
124 | val = i2c_smbus_read_byte_data(client, command: lsb_reg); |
125 | if (val < 0) |
126 | goto exit_unlock; |
127 | |
128 | tmp = (val >> lsb_shift) & 3; |
129 | val = i2c_smbus_read_byte_data(client, command: msb_reg); |
130 | |
131 | if (val >= 0) |
132 | val = (val << 2) | tmp; |
133 | |
134 | exit_unlock: |
135 | mutex_unlock(lock: &data->device_lock); |
136 | |
137 | return val; |
138 | } |
139 | |
140 | static int adt7411_modify_bit(struct i2c_client *client, u8 reg, u8 bit, |
141 | bool flag) |
142 | { |
143 | struct adt7411_data *data = i2c_get_clientdata(client); |
144 | int ret, val; |
145 | |
146 | mutex_lock(&data->device_lock); |
147 | |
148 | ret = i2c_smbus_read_byte_data(client, command: reg); |
149 | if (ret < 0) |
150 | goto exit_unlock; |
151 | |
152 | if (flag) |
153 | val = ret | bit; |
154 | else |
155 | val = ret & ~bit; |
156 | |
157 | ret = i2c_smbus_write_byte_data(client, command: reg, value: val); |
158 | |
159 | exit_unlock: |
160 | mutex_unlock(lock: &data->device_lock); |
161 | return ret; |
162 | } |
163 | |
164 | static ssize_t adt7411_show_bit(struct device *dev, |
165 | struct device_attribute *attr, char *buf) |
166 | { |
167 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); |
168 | struct adt7411_data *data = dev_get_drvdata(dev); |
169 | struct i2c_client *client = data->client; |
170 | int ret = i2c_smbus_read_byte_data(client, command: attr2->index); |
171 | |
172 | return ret < 0 ? ret : sprintf(buf, fmt: "%u\n" , !!(ret & attr2->nr)); |
173 | } |
174 | |
175 | static ssize_t adt7411_set_bit(struct device *dev, |
176 | struct device_attribute *attr, const char *buf, |
177 | size_t count) |
178 | { |
179 | struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr); |
180 | struct adt7411_data *data = dev_get_drvdata(dev); |
181 | struct i2c_client *client = data->client; |
182 | int ret; |
183 | unsigned long flag; |
184 | |
185 | ret = kstrtoul(s: buf, base: 0, res: &flag); |
186 | if (ret || flag > 1) |
187 | return -EINVAL; |
188 | |
189 | ret = adt7411_modify_bit(client, reg: s_attr2->index, bit: s_attr2->nr, flag); |
190 | |
191 | /* force update */ |
192 | mutex_lock(&data->update_lock); |
193 | data->next_update = jiffies; |
194 | mutex_unlock(lock: &data->update_lock); |
195 | |
196 | return ret < 0 ? ret : count; |
197 | } |
198 | |
199 | #define ADT7411_BIT_ATTR(__name, __reg, __bit) \ |
200 | SENSOR_DEVICE_ATTR_2(__name, S_IRUGO | S_IWUSR, adt7411_show_bit, \ |
201 | adt7411_set_bit, __bit, __reg) |
202 | |
203 | static ADT7411_BIT_ATTR(no_average, ADT7411_REG_CFG2, ADT7411_CFG2_DISABLE_AVG); |
204 | static ADT7411_BIT_ATTR(fast_sampling, ADT7411_REG_CFG3, ADT7411_CFG3_ADC_CLK_225); |
205 | static ADT7411_BIT_ATTR(adc_ref_vdd, ADT7411_REG_CFG3, ADT7411_CFG3_REF_VDD); |
206 | |
207 | static struct attribute *adt7411_attrs[] = { |
208 | &sensor_dev_attr_no_average.dev_attr.attr, |
209 | &sensor_dev_attr_fast_sampling.dev_attr.attr, |
210 | &sensor_dev_attr_adc_ref_vdd.dev_attr.attr, |
211 | NULL |
212 | }; |
213 | ATTRIBUTE_GROUPS(adt7411); |
214 | |
215 | static int adt7411_read_in_alarm(struct device *dev, int channel, long *val) |
216 | { |
217 | struct adt7411_data *data = dev_get_drvdata(dev); |
218 | struct i2c_client *client = data->client; |
219 | int ret; |
220 | |
221 | ret = i2c_smbus_read_byte_data(client, command: adt7411_in_alarm_reg[channel]); |
222 | if (ret < 0) |
223 | return ret; |
224 | *val = !!(ret & adt7411_in_alarm_bits[channel]); |
225 | return 0; |
226 | } |
227 | |
228 | static int adt7411_read_in_vdd(struct device *dev, u32 attr, long *val) |
229 | { |
230 | struct adt7411_data *data = dev_get_drvdata(dev); |
231 | struct i2c_client *client = data->client; |
232 | int ret; |
233 | |
234 | switch (attr) { |
235 | case hwmon_in_input: |
236 | ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB, |
237 | ADT7411_REG_VDD_MSB, lsb_shift: 2); |
238 | if (ret < 0) |
239 | return ret; |
240 | *val = ret * 7000 / 1024; |
241 | return 0; |
242 | case hwmon_in_min: |
243 | ret = i2c_smbus_read_byte_data(client, ADT7411_REG_VDD_LOW); |
244 | if (ret < 0) |
245 | return ret; |
246 | *val = ret * 7000 / 256; |
247 | return 0; |
248 | case hwmon_in_max: |
249 | ret = i2c_smbus_read_byte_data(client, ADT7411_REG_VDD_HIGH); |
250 | if (ret < 0) |
251 | return ret; |
252 | *val = ret * 7000 / 256; |
253 | return 0; |
254 | case hwmon_in_alarm: |
255 | return adt7411_read_in_alarm(dev, channel: 0, val); |
256 | default: |
257 | return -EOPNOTSUPP; |
258 | } |
259 | } |
260 | |
261 | static int adt7411_update_vref(struct device *dev) |
262 | { |
263 | struct adt7411_data *data = dev_get_drvdata(dev); |
264 | struct i2c_client *client = data->client; |
265 | int val; |
266 | |
267 | if (time_after_eq(jiffies, data->next_update)) { |
268 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_CFG3); |
269 | if (val < 0) |
270 | return val; |
271 | |
272 | if (val & ADT7411_CFG3_REF_VDD) { |
273 | val = adt7411_read_in_vdd(dev, attr: hwmon_in_input, |
274 | val: &data->vref_cached); |
275 | if (val < 0) |
276 | return val; |
277 | } else { |
278 | data->vref_cached = 2250; |
279 | } |
280 | |
281 | data->next_update = jiffies + HZ; |
282 | } |
283 | |
284 | return 0; |
285 | } |
286 | |
287 | static int adt7411_read_in_chan(struct device *dev, u32 attr, int channel, |
288 | long *val) |
289 | { |
290 | struct adt7411_data *data = dev_get_drvdata(dev); |
291 | struct i2c_client *client = data->client; |
292 | |
293 | int ret; |
294 | int reg, lsb_reg, lsb_shift; |
295 | int nr = channel - 1; |
296 | |
297 | mutex_lock(&data->update_lock); |
298 | ret = adt7411_update_vref(dev); |
299 | if (ret < 0) |
300 | goto exit_unlock; |
301 | |
302 | switch (attr) { |
303 | case hwmon_in_input: |
304 | lsb_reg = ADT7411_REG_EXT_TEMP_AIN14_LSB + (nr >> 2); |
305 | lsb_shift = 2 * (nr & 0x03); |
306 | ret = adt7411_read_10_bit(client, lsb_reg, |
307 | ADT7411_REG_EXT_TEMP_AIN1_MSB + nr, |
308 | lsb_shift); |
309 | if (ret < 0) |
310 | goto exit_unlock; |
311 | *val = ret * data->vref_cached / 1024; |
312 | ret = 0; |
313 | break; |
314 | case hwmon_in_min: |
315 | case hwmon_in_max: |
316 | reg = (attr == hwmon_in_min) |
317 | ? ADT7411_REG_IN_LOW(channel) |
318 | : ADT7411_REG_IN_HIGH(channel); |
319 | ret = i2c_smbus_read_byte_data(client, command: reg); |
320 | if (ret < 0) |
321 | goto exit_unlock; |
322 | *val = ret * data->vref_cached / 256; |
323 | ret = 0; |
324 | break; |
325 | case hwmon_in_alarm: |
326 | ret = adt7411_read_in_alarm(dev, channel, val); |
327 | break; |
328 | default: |
329 | ret = -EOPNOTSUPP; |
330 | break; |
331 | } |
332 | exit_unlock: |
333 | mutex_unlock(lock: &data->update_lock); |
334 | return ret; |
335 | } |
336 | |
337 | static int adt7411_read_in(struct device *dev, u32 attr, int channel, |
338 | long *val) |
339 | { |
340 | if (channel == 0) |
341 | return adt7411_read_in_vdd(dev, attr, val); |
342 | else |
343 | return adt7411_read_in_chan(dev, attr, channel, val); |
344 | } |
345 | |
346 | |
347 | static int adt7411_read_temp_alarm(struct device *dev, u32 attr, int channel, |
348 | long *val) |
349 | { |
350 | struct adt7411_data *data = dev_get_drvdata(dev); |
351 | struct i2c_client *client = data->client; |
352 | int ret, bit; |
353 | |
354 | ret = i2c_smbus_read_byte_data(client, ADT7411_REG_STAT_1); |
355 | if (ret < 0) |
356 | return ret; |
357 | |
358 | switch (attr) { |
359 | case hwmon_temp_min_alarm: |
360 | bit = channel ? ADT7411_STAT_1_EXT_TEMP_LOW |
361 | : ADT7411_STAT_1_INT_TEMP_LOW; |
362 | break; |
363 | case hwmon_temp_max_alarm: |
364 | bit = channel ? ADT7411_STAT_1_EXT_TEMP_HIGH_AIN1 |
365 | : ADT7411_STAT_1_INT_TEMP_HIGH; |
366 | break; |
367 | case hwmon_temp_fault: |
368 | bit = ADT7411_STAT_1_EXT_TEMP_FAULT; |
369 | break; |
370 | default: |
371 | return -EOPNOTSUPP; |
372 | } |
373 | |
374 | *val = !!(ret & bit); |
375 | return 0; |
376 | } |
377 | |
378 | static int adt7411_read_temp(struct device *dev, u32 attr, int channel, |
379 | long *val) |
380 | { |
381 | struct adt7411_data *data = dev_get_drvdata(dev); |
382 | struct i2c_client *client = data->client; |
383 | int ret, reg, regl, regh; |
384 | |
385 | switch (attr) { |
386 | case hwmon_temp_input: |
387 | regl = channel ? ADT7411_REG_EXT_TEMP_AIN14_LSB : |
388 | ADT7411_REG_INT_TEMP_VDD_LSB; |
389 | regh = channel ? ADT7411_REG_EXT_TEMP_AIN1_MSB : |
390 | ADT7411_REG_INT_TEMP_MSB; |
391 | ret = adt7411_read_10_bit(client, lsb_reg: regl, msb_reg: regh, lsb_shift: 0); |
392 | if (ret < 0) |
393 | return ret; |
394 | ret = ret & 0x200 ? ret - 0x400 : ret; /* 10 bit signed */ |
395 | *val = ret * 250; |
396 | return 0; |
397 | case hwmon_temp_min: |
398 | case hwmon_temp_max: |
399 | reg = (attr == hwmon_temp_min) |
400 | ? ADT7411_REG_TEMP_LOW(channel) |
401 | : ADT7411_REG_TEMP_HIGH(channel); |
402 | ret = i2c_smbus_read_byte_data(client, command: reg); |
403 | if (ret < 0) |
404 | return ret; |
405 | ret = ret & 0x80 ? ret - 0x100 : ret; /* 8 bit signed */ |
406 | *val = ret * 1000; |
407 | return 0; |
408 | case hwmon_temp_min_alarm: |
409 | case hwmon_temp_max_alarm: |
410 | case hwmon_temp_fault: |
411 | return adt7411_read_temp_alarm(dev, attr, channel, val); |
412 | default: |
413 | return -EOPNOTSUPP; |
414 | } |
415 | } |
416 | |
417 | static int adt7411_read(struct device *dev, enum hwmon_sensor_types type, |
418 | u32 attr, int channel, long *val) |
419 | { |
420 | switch (type) { |
421 | case hwmon_in: |
422 | return adt7411_read_in(dev, attr, channel, val); |
423 | case hwmon_temp: |
424 | return adt7411_read_temp(dev, attr, channel, val); |
425 | default: |
426 | return -EOPNOTSUPP; |
427 | } |
428 | } |
429 | |
430 | static int adt7411_write_in_vdd(struct device *dev, u32 attr, long val) |
431 | { |
432 | struct adt7411_data *data = dev_get_drvdata(dev); |
433 | struct i2c_client *client = data->client; |
434 | int reg; |
435 | |
436 | val = clamp_val(val, 0, 255 * 7000 / 256); |
437 | val = DIV_ROUND_CLOSEST(val * 256, 7000); |
438 | |
439 | switch (attr) { |
440 | case hwmon_in_min: |
441 | reg = ADT7411_REG_VDD_LOW; |
442 | break; |
443 | case hwmon_in_max: |
444 | reg = ADT7411_REG_VDD_HIGH; |
445 | break; |
446 | default: |
447 | return -EOPNOTSUPP; |
448 | } |
449 | |
450 | return i2c_smbus_write_byte_data(client, command: reg, value: val); |
451 | } |
452 | |
453 | static int adt7411_write_in_chan(struct device *dev, u32 attr, int channel, |
454 | long val) |
455 | { |
456 | struct adt7411_data *data = dev_get_drvdata(dev); |
457 | struct i2c_client *client = data->client; |
458 | int ret, reg; |
459 | |
460 | mutex_lock(&data->update_lock); |
461 | ret = adt7411_update_vref(dev); |
462 | if (ret < 0) |
463 | goto exit_unlock; |
464 | val = clamp_val(val, 0, 255 * data->vref_cached / 256); |
465 | val = DIV_ROUND_CLOSEST(val * 256, data->vref_cached); |
466 | |
467 | switch (attr) { |
468 | case hwmon_in_min: |
469 | reg = ADT7411_REG_IN_LOW(channel); |
470 | break; |
471 | case hwmon_in_max: |
472 | reg = ADT7411_REG_IN_HIGH(channel); |
473 | break; |
474 | default: |
475 | ret = -EOPNOTSUPP; |
476 | goto exit_unlock; |
477 | } |
478 | |
479 | ret = i2c_smbus_write_byte_data(client, command: reg, value: val); |
480 | exit_unlock: |
481 | mutex_unlock(lock: &data->update_lock); |
482 | return ret; |
483 | } |
484 | |
485 | static int adt7411_write_in(struct device *dev, u32 attr, int channel, |
486 | long val) |
487 | { |
488 | if (channel == 0) |
489 | return adt7411_write_in_vdd(dev, attr, val); |
490 | else |
491 | return adt7411_write_in_chan(dev, attr, channel, val); |
492 | } |
493 | |
494 | static int adt7411_write_temp(struct device *dev, u32 attr, int channel, |
495 | long val) |
496 | { |
497 | struct adt7411_data *data = dev_get_drvdata(dev); |
498 | struct i2c_client *client = data->client; |
499 | int reg; |
500 | |
501 | val = clamp_val(val, -128000, 127000); |
502 | val = DIV_ROUND_CLOSEST(val, 1000); |
503 | |
504 | switch (attr) { |
505 | case hwmon_temp_min: |
506 | reg = ADT7411_REG_TEMP_LOW(channel); |
507 | break; |
508 | case hwmon_temp_max: |
509 | reg = ADT7411_REG_TEMP_HIGH(channel); |
510 | break; |
511 | default: |
512 | return -EOPNOTSUPP; |
513 | } |
514 | |
515 | return i2c_smbus_write_byte_data(client, command: reg, value: val); |
516 | } |
517 | |
518 | static int adt7411_write(struct device *dev, enum hwmon_sensor_types type, |
519 | u32 attr, int channel, long val) |
520 | { |
521 | switch (type) { |
522 | case hwmon_in: |
523 | return adt7411_write_in(dev, attr, channel, val); |
524 | case hwmon_temp: |
525 | return adt7411_write_temp(dev, attr, channel, val); |
526 | default: |
527 | return -EOPNOTSUPP; |
528 | } |
529 | } |
530 | |
531 | static umode_t adt7411_is_visible(const void *_data, |
532 | enum hwmon_sensor_types type, |
533 | u32 attr, int channel) |
534 | { |
535 | const struct adt7411_data *data = _data; |
536 | bool visible; |
537 | |
538 | switch (type) { |
539 | case hwmon_in: |
540 | visible = channel == 0 || channel >= 3 || !data->use_ext_temp; |
541 | switch (attr) { |
542 | case hwmon_in_input: |
543 | case hwmon_in_alarm: |
544 | return visible ? S_IRUGO : 0; |
545 | case hwmon_in_min: |
546 | case hwmon_in_max: |
547 | return visible ? S_IRUGO | S_IWUSR : 0; |
548 | } |
549 | break; |
550 | case hwmon_temp: |
551 | visible = channel == 0 || data->use_ext_temp; |
552 | switch (attr) { |
553 | case hwmon_temp_input: |
554 | case hwmon_temp_min_alarm: |
555 | case hwmon_temp_max_alarm: |
556 | case hwmon_temp_fault: |
557 | return visible ? S_IRUGO : 0; |
558 | case hwmon_temp_min: |
559 | case hwmon_temp_max: |
560 | return visible ? S_IRUGO | S_IWUSR : 0; |
561 | } |
562 | break; |
563 | default: |
564 | break; |
565 | } |
566 | return 0; |
567 | } |
568 | |
569 | static int adt7411_detect(struct i2c_client *client, |
570 | struct i2c_board_info *info) |
571 | { |
572 | int val; |
573 | |
574 | if (!i2c_check_functionality(adap: client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
575 | return -ENODEV; |
576 | |
577 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_MANUFACTURER_ID); |
578 | if (val < 0 || val != ADT7411_MANUFACTURER_ID) { |
579 | dev_dbg(&client->dev, |
580 | "Wrong manufacturer ID. Got %d, expected %d\n" , |
581 | val, ADT7411_MANUFACTURER_ID); |
582 | return -ENODEV; |
583 | } |
584 | |
585 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_DEVICE_ID); |
586 | if (val < 0 || val != ADT7411_DEVICE_ID) { |
587 | dev_dbg(&client->dev, |
588 | "Wrong device ID. Got %d, expected %d\n" , |
589 | val, ADT7411_DEVICE_ID); |
590 | return -ENODEV; |
591 | } |
592 | |
593 | strscpy(info->type, "adt7411" , I2C_NAME_SIZE); |
594 | |
595 | return 0; |
596 | } |
597 | |
598 | static int adt7411_init_device(struct adt7411_data *data) |
599 | { |
600 | int ret; |
601 | u8 val; |
602 | |
603 | ret = i2c_smbus_read_byte_data(client: data->client, ADT7411_REG_CFG3); |
604 | if (ret < 0) |
605 | return ret; |
606 | |
607 | /* |
608 | * We must only write zero to bit 1 and bit 2 and only one to bit 3 |
609 | * according to the datasheet. |
610 | */ |
611 | val = ret; |
612 | val &= ~(ADT7411_CFG3_RESERVED_BIT1 | ADT7411_CFG3_RESERVED_BIT2); |
613 | val |= ADT7411_CFG3_RESERVED_BIT3; |
614 | |
615 | ret = i2c_smbus_write_byte_data(client: data->client, ADT7411_REG_CFG3, value: val); |
616 | if (ret < 0) |
617 | return ret; |
618 | |
619 | ret = i2c_smbus_read_byte_data(client: data->client, ADT7411_REG_CFG1); |
620 | if (ret < 0) |
621 | return ret; |
622 | |
623 | data->use_ext_temp = ret & ADT7411_CFG1_EXT_TDM; |
624 | |
625 | /* |
626 | * We must only write zero to bit 1 and only one to bit 3 according to |
627 | * the datasheet. |
628 | */ |
629 | val = ret; |
630 | val &= ~ADT7411_CFG1_RESERVED_BIT1; |
631 | val |= ADT7411_CFG1_RESERVED_BIT3; |
632 | |
633 | /* enable monitoring */ |
634 | val |= ADT7411_CFG1_START_MONITOR; |
635 | |
636 | return i2c_smbus_write_byte_data(client: data->client, ADT7411_REG_CFG1, value: val); |
637 | } |
638 | |
639 | static const struct hwmon_channel_info * const adt7411_info[] = { |
640 | HWMON_CHANNEL_INFO(in, |
641 | HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM, |
642 | HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM, |
643 | HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM, |
644 | HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM, |
645 | HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM, |
646 | HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM, |
647 | HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM, |
648 | HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM, |
649 | HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM), |
650 | HWMON_CHANNEL_INFO(temp, |
651 | HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MIN_ALARM | |
652 | HWMON_T_MAX | HWMON_T_MAX_ALARM, |
653 | HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MIN_ALARM | |
654 | HWMON_T_MAX | HWMON_T_MAX_ALARM | HWMON_T_FAULT), |
655 | NULL |
656 | }; |
657 | |
658 | static const struct hwmon_ops adt7411_hwmon_ops = { |
659 | .is_visible = adt7411_is_visible, |
660 | .read = adt7411_read, |
661 | .write = adt7411_write, |
662 | }; |
663 | |
664 | static const struct hwmon_chip_info adt7411_chip_info = { |
665 | .ops = &adt7411_hwmon_ops, |
666 | .info = adt7411_info, |
667 | }; |
668 | |
669 | static int adt7411_probe(struct i2c_client *client) |
670 | { |
671 | struct device *dev = &client->dev; |
672 | struct adt7411_data *data; |
673 | struct device *hwmon_dev; |
674 | int ret; |
675 | |
676 | data = devm_kzalloc(dev, size: sizeof(*data), GFP_KERNEL); |
677 | if (!data) |
678 | return -ENOMEM; |
679 | |
680 | i2c_set_clientdata(client, data); |
681 | data->client = client; |
682 | mutex_init(&data->device_lock); |
683 | mutex_init(&data->update_lock); |
684 | |
685 | ret = adt7411_init_device(data); |
686 | if (ret < 0) |
687 | return ret; |
688 | |
689 | /* force update on first occasion */ |
690 | data->next_update = jiffies; |
691 | |
692 | hwmon_dev = devm_hwmon_device_register_with_info(dev, name: client->name, |
693 | drvdata: data, |
694 | info: &adt7411_chip_info, |
695 | extra_groups: adt7411_groups); |
696 | return PTR_ERR_OR_ZERO(ptr: hwmon_dev); |
697 | } |
698 | |
699 | static const struct i2c_device_id adt7411_id[] = { |
700 | { "adt7411" , 0 }, |
701 | { } |
702 | }; |
703 | MODULE_DEVICE_TABLE(i2c, adt7411_id); |
704 | |
705 | static struct i2c_driver adt7411_driver = { |
706 | .driver = { |
707 | .name = "adt7411" , |
708 | }, |
709 | .probe = adt7411_probe, |
710 | .id_table = adt7411_id, |
711 | .detect = adt7411_detect, |
712 | .address_list = normal_i2c, |
713 | .class = I2C_CLASS_HWMON, |
714 | }; |
715 | |
716 | module_i2c_driver(adt7411_driver); |
717 | |
718 | MODULE_AUTHOR("Sascha Hauer, Wolfram Sang <kernel@pengutronix.de>" ); |
719 | MODULE_DESCRIPTION("ADT7411 driver" ); |
720 | MODULE_LICENSE("GPL v2" ); |
721 | |