Merge tag 'drm-misc-next-fixes-2023-09-11' of git://anongit.freedesktop.org/drm/drm...
[linux-block.git] / drivers / hwmon / max31730.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Driver for MAX31730 3-Channel Remote Temperature Sensor
4  *
5  * Copyright (c) 2019 Guenter Roeck <linux@roeck-us.net>
6  */
7
8 #include <linux/bits.h>
9 #include <linux/err.h>
10 #include <linux/i2c.h>
11 #include <linux/init.h>
12 #include <linux/hwmon.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/slab.h>
16
17 /* Addresses scanned */
18 static const unsigned short normal_i2c[] = { 0x1c, 0x1d, 0x1e, 0x1f, 0x4c,
19                                              0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
20
21 /* The MAX31730 registers */
22 #define MAX31730_REG_TEMP               0x00
23 #define MAX31730_REG_CONF               0x13
24 #define  MAX31730_STOP                  BIT(7)
25 #define  MAX31730_EXTRANGE              BIT(1)
26 #define MAX31730_REG_TEMP_OFFSET        0x16
27 #define  MAX31730_TEMP_OFFSET_BASELINE  0x77
28 #define MAX31730_REG_OFFSET_ENABLE      0x17
29 #define MAX31730_REG_TEMP_MAX           0x20
30 #define MAX31730_REG_TEMP_MIN           0x30
31 #define MAX31730_REG_STATUS_HIGH        0x32
32 #define MAX31730_REG_STATUS_LOW         0x33
33 #define MAX31730_REG_CHANNEL_ENABLE     0x35
34 #define MAX31730_REG_TEMP_FAULT         0x36
35
36 #define MAX31730_REG_MFG_ID             0x50
37 #define  MAX31730_MFG_ID                0x4d
38 #define MAX31730_REG_MFG_REV            0x51
39 #define  MAX31730_MFG_REV               0x01
40
41 #define MAX31730_TEMP_MIN               (-128000)
42 #define MAX31730_TEMP_MAX               127937
43
44 /* Each client has this additional data */
45 struct max31730_data {
46         struct i2c_client       *client;
47         u8                      orig_conf;
48         u8                      current_conf;
49         u8                      offset_enable;
50         u8                      channel_enable;
51 };
52
53 /*-----------------------------------------------------------------------*/
54
55 static inline long max31730_reg_to_mc(s16 temp)
56 {
57         return DIV_ROUND_CLOSEST((temp >> 4) * 1000, 16);
58 }
59
60 static int max31730_write_config(struct max31730_data *data, u8 set_mask,
61                                  u8 clr_mask)
62 {
63         u8 value;
64
65         clr_mask |= MAX31730_EXTRANGE;
66         value = data->current_conf & ~clr_mask;
67         value |= set_mask;
68
69         if (data->current_conf != value) {
70                 s32 err;
71
72                 err = i2c_smbus_write_byte_data(data->client, MAX31730_REG_CONF,
73                                                 value);
74                 if (err)
75                         return err;
76                 data->current_conf = value;
77         }
78         return 0;
79 }
80
81 static int max31730_set_enable(struct i2c_client *client, int reg,
82                                u8 *confdata, int channel, bool enable)
83 {
84         u8 regval = *confdata;
85         int err;
86
87         if (enable)
88                 regval |= BIT(channel);
89         else
90                 regval &= ~BIT(channel);
91
92         if (regval != *confdata) {
93                 err = i2c_smbus_write_byte_data(client, reg, regval);
94                 if (err)
95                         return err;
96                 *confdata = regval;
97         }
98         return 0;
99 }
100
101 static int max31730_set_offset_enable(struct max31730_data *data, int channel,
102                                       bool enable)
103 {
104         return max31730_set_enable(data->client, MAX31730_REG_OFFSET_ENABLE,
105                                    &data->offset_enable, channel, enable);
106 }
107
108 static int max31730_set_channel_enable(struct max31730_data *data, int channel,
109                                        bool enable)
110 {
111         return max31730_set_enable(data->client, MAX31730_REG_CHANNEL_ENABLE,
112                                    &data->channel_enable, channel, enable);
113 }
114
115 static int max31730_read(struct device *dev, enum hwmon_sensor_types type,
116                          u32 attr, int channel, long *val)
117 {
118         struct max31730_data *data = dev_get_drvdata(dev);
119         int regval, reg, offset;
120
121         if (type != hwmon_temp)
122                 return -EINVAL;
123
124         switch (attr) {
125         case hwmon_temp_input:
126                 if (!(data->channel_enable & BIT(channel)))
127                         return -ENODATA;
128                 reg = MAX31730_REG_TEMP + (channel * 2);
129                 break;
130         case hwmon_temp_max:
131                 reg = MAX31730_REG_TEMP_MAX + (channel * 2);
132                 break;
133         case hwmon_temp_min:
134                 reg = MAX31730_REG_TEMP_MIN;
135                 break;
136         case hwmon_temp_enable:
137                 *val = !!(data->channel_enable & BIT(channel));
138                 return 0;
139         case hwmon_temp_offset:
140                 if (!channel)
141                         return -EINVAL;
142                 if (!(data->offset_enable & BIT(channel))) {
143                         *val = 0;
144                         return 0;
145                 }
146                 offset = i2c_smbus_read_byte_data(data->client,
147                                                   MAX31730_REG_TEMP_OFFSET);
148                 if (offset < 0)
149                         return offset;
150                 *val = (offset - MAX31730_TEMP_OFFSET_BASELINE) * 125;
151                 return 0;
152         case hwmon_temp_fault:
153                 regval = i2c_smbus_read_byte_data(data->client,
154                                                   MAX31730_REG_TEMP_FAULT);
155                 if (regval < 0)
156                         return regval;
157                 *val = !!(regval & BIT(channel));
158                 return 0;
159         case hwmon_temp_min_alarm:
160                 regval = i2c_smbus_read_byte_data(data->client,
161                                                   MAX31730_REG_STATUS_LOW);
162                 if (regval < 0)
163                         return regval;
164                 *val = !!(regval & BIT(channel));
165                 return 0;
166         case hwmon_temp_max_alarm:
167                 regval = i2c_smbus_read_byte_data(data->client,
168                                                   MAX31730_REG_STATUS_HIGH);
169                 if (regval < 0)
170                         return regval;
171                 *val = !!(regval & BIT(channel));
172                 return 0;
173         default:
174                 return -EINVAL;
175         }
176         regval = i2c_smbus_read_word_swapped(data->client, reg);
177         if (regval < 0)
178                 return regval;
179
180         *val = max31730_reg_to_mc(regval);
181
182         return 0;
183 }
184
185 static int max31730_write(struct device *dev, enum hwmon_sensor_types type,
186                           u32 attr, int channel, long val)
187 {
188         struct max31730_data *data = dev_get_drvdata(dev);
189         int reg, err;
190
191         if (type != hwmon_temp)
192                 return -EINVAL;
193
194         switch (attr) {
195         case hwmon_temp_max:
196                 reg = MAX31730_REG_TEMP_MAX + channel * 2;
197                 break;
198         case hwmon_temp_min:
199                 reg = MAX31730_REG_TEMP_MIN;
200                 break;
201         case hwmon_temp_enable:
202                 if (val != 0 && val != 1)
203                         return -EINVAL;
204                 return max31730_set_channel_enable(data, channel, val);
205         case hwmon_temp_offset:
206                 val = clamp_val(val, -14875, 17000) + 14875;
207                 val = DIV_ROUND_CLOSEST(val, 125);
208                 err = max31730_set_offset_enable(data, channel,
209                                         val != MAX31730_TEMP_OFFSET_BASELINE);
210                 if (err)
211                         return err;
212                 return i2c_smbus_write_byte_data(data->client,
213                                                  MAX31730_REG_TEMP_OFFSET, val);
214         default:
215                 return -EINVAL;
216         }
217
218         val = clamp_val(val, MAX31730_TEMP_MIN, MAX31730_TEMP_MAX);
219         val = DIV_ROUND_CLOSEST(val << 4, 1000) << 4;
220
221         return i2c_smbus_write_word_swapped(data->client, reg, (u16)val);
222 }
223
224 static umode_t max31730_is_visible(const void *data,
225                                    enum hwmon_sensor_types type,
226                                    u32 attr, int channel)
227 {
228         switch (type) {
229         case hwmon_temp:
230                 switch (attr) {
231                 case hwmon_temp_input:
232                 case hwmon_temp_min_alarm:
233                 case hwmon_temp_max_alarm:
234                 case hwmon_temp_fault:
235                         return 0444;
236                 case hwmon_temp_min:
237                         return channel ? 0444 : 0644;
238                 case hwmon_temp_offset:
239                 case hwmon_temp_enable:
240                 case hwmon_temp_max:
241                         return 0644;
242                 }
243                 break;
244         default:
245                 break;
246         }
247         return 0;
248 }
249
250 static const struct hwmon_channel_info * const max31730_info[] = {
251         HWMON_CHANNEL_INFO(chip,
252                            HWMON_C_REGISTER_TZ),
253         HWMON_CHANNEL_INFO(temp,
254                            HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
255                            HWMON_T_ENABLE |
256                            HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM,
257                            HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
258                            HWMON_T_OFFSET | HWMON_T_ENABLE |
259                            HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
260                            HWMON_T_FAULT,
261                            HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
262                            HWMON_T_OFFSET | HWMON_T_ENABLE |
263                            HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
264                            HWMON_T_FAULT,
265                            HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
266                            HWMON_T_OFFSET | HWMON_T_ENABLE |
267                            HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |
268                            HWMON_T_FAULT
269                            ),
270         NULL
271 };
272
273 static const struct hwmon_ops max31730_hwmon_ops = {
274         .is_visible = max31730_is_visible,
275         .read = max31730_read,
276         .write = max31730_write,
277 };
278
279 static const struct hwmon_chip_info max31730_chip_info = {
280         .ops = &max31730_hwmon_ops,
281         .info = max31730_info,
282 };
283
284 static void max31730_remove(void *data)
285 {
286         struct max31730_data *max31730 = data;
287         struct i2c_client *client = max31730->client;
288
289         i2c_smbus_write_byte_data(client, MAX31730_REG_CONF,
290                                   max31730->orig_conf);
291 }
292
293 static int
294 max31730_probe(struct i2c_client *client)
295 {
296         struct device *dev = &client->dev;
297         struct device *hwmon_dev;
298         struct max31730_data *data;
299         int status, err;
300
301         if (!i2c_check_functionality(client->adapter,
302                         I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
303                 return -EIO;
304
305         data = devm_kzalloc(dev, sizeof(struct max31730_data), GFP_KERNEL);
306         if (!data)
307                 return -ENOMEM;
308
309         data->client = client;
310
311         /* Cache original configuration and enable status */
312         status = i2c_smbus_read_byte_data(client, MAX31730_REG_CHANNEL_ENABLE);
313         if (status < 0)
314                 return status;
315         data->channel_enable = status;
316
317         status = i2c_smbus_read_byte_data(client, MAX31730_REG_OFFSET_ENABLE);
318         if (status < 0)
319                 return status;
320         data->offset_enable = status;
321
322         status = i2c_smbus_read_byte_data(client, MAX31730_REG_CONF);
323         if (status < 0)
324                 return status;
325         data->orig_conf = status;
326         data->current_conf = status;
327
328         err = max31730_write_config(data,
329                                     data->channel_enable ? 0 : MAX31730_STOP,
330                                     data->channel_enable ? MAX31730_STOP : 0);
331         if (err)
332                 return err;
333
334         dev_set_drvdata(dev, data);
335
336         err = devm_add_action_or_reset(dev, max31730_remove, data);
337         if (err)
338                 return err;
339
340         hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
341                                                          data,
342                                                          &max31730_chip_info,
343                                                          NULL);
344         return PTR_ERR_OR_ZERO(hwmon_dev);
345 }
346
347 static const struct i2c_device_id max31730_ids[] = {
348         { "max31730", 0, },
349         { }
350 };
351 MODULE_DEVICE_TABLE(i2c, max31730_ids);
352
353 static const struct of_device_id __maybe_unused max31730_of_match[] = {
354         {
355                 .compatible = "maxim,max31730",
356         },
357         { },
358 };
359 MODULE_DEVICE_TABLE(of, max31730_of_match);
360
361 static bool max31730_check_reg_temp(struct i2c_client *client,
362                                     int reg)
363 {
364         int regval;
365
366         regval = i2c_smbus_read_byte_data(client, reg + 1);
367         return regval < 0 || (regval & 0x0f);
368 }
369
370 /* Return 0 if detection is successful, -ENODEV otherwise */
371 static int max31730_detect(struct i2c_client *client,
372                            struct i2c_board_info *info)
373 {
374         struct i2c_adapter *adapter = client->adapter;
375         int regval;
376         int i;
377
378         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
379                                      I2C_FUNC_SMBUS_WORD_DATA))
380                 return -ENODEV;
381
382         regval = i2c_smbus_read_byte_data(client, MAX31730_REG_MFG_ID);
383         if (regval != MAX31730_MFG_ID)
384                 return -ENODEV;
385         regval = i2c_smbus_read_byte_data(client, MAX31730_REG_MFG_REV);
386         if (regval != MAX31730_MFG_REV)
387                 return -ENODEV;
388
389         /* lower 4 bit of temperature and limit registers must be 0 */
390         if (max31730_check_reg_temp(client, MAX31730_REG_TEMP_MIN))
391                 return -ENODEV;
392
393         for (i = 0; i < 4; i++) {
394                 if (max31730_check_reg_temp(client, MAX31730_REG_TEMP + i * 2))
395                         return -ENODEV;
396                 if (max31730_check_reg_temp(client,
397                                             MAX31730_REG_TEMP_MAX + i * 2))
398                         return -ENODEV;
399         }
400
401         strscpy(info->type, "max31730", I2C_NAME_SIZE);
402
403         return 0;
404 }
405
406 static int max31730_suspend(struct device *dev)
407 {
408         struct max31730_data *data = dev_get_drvdata(dev);
409
410         return max31730_write_config(data, MAX31730_STOP, 0);
411 }
412
413 static int max31730_resume(struct device *dev)
414 {
415         struct max31730_data *data = dev_get_drvdata(dev);
416
417         return max31730_write_config(data, 0, MAX31730_STOP);
418 }
419
420 static DEFINE_SIMPLE_DEV_PM_OPS(max31730_pm_ops, max31730_suspend, max31730_resume);
421
422 static struct i2c_driver max31730_driver = {
423         .class          = I2C_CLASS_HWMON,
424         .driver = {
425                 .name   = "max31730",
426                 .of_match_table = of_match_ptr(max31730_of_match),
427                 .pm     = pm_sleep_ptr(&max31730_pm_ops),
428         },
429         .probe          = max31730_probe,
430         .id_table       = max31730_ids,
431         .detect         = max31730_detect,
432         .address_list   = normal_i2c,
433 };
434
435 module_i2c_driver(max31730_driver);
436
437 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
438 MODULE_DESCRIPTION("MAX31730 driver");
439 MODULE_LICENSE("GPL");