GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / hwmon / max31827.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * max31827.c - Support for Maxim Low-Power Switch
4  *
5  * Copyright (c) 2023 Daniel Matyas <daniel.matyas@analog.com>
6  */
7
8 #include <linux/bitfield.h>
9 #include <linux/bitops.h>
10 #include <linux/delay.h>
11 #include <linux/hwmon.h>
12 #include <linux/i2c.h>
13 #include <linux/mutex.h>
14 #include <linux/regmap.h>
15 #include <linux/regulator/consumer.h>
16
17 #define MAX31827_T_REG                  0x0
18 #define MAX31827_CONFIGURATION_REG      0x2
19 #define MAX31827_TH_REG                 0x4
20 #define MAX31827_TL_REG                 0x6
21 #define MAX31827_TH_HYST_REG            0x8
22 #define MAX31827_TL_HYST_REG            0xA
23
24 #define MAX31827_CONFIGURATION_1SHOT_MASK       BIT(0)
25 #define MAX31827_CONFIGURATION_CNV_RATE_MASK    GENMASK(3, 1)
26 #define MAX31827_CONFIGURATION_U_TEMP_STAT_MASK BIT(14)
27 #define MAX31827_CONFIGURATION_O_TEMP_STAT_MASK BIT(15)
28
29 #define MAX31827_12_BIT_CNV_TIME        140
30
31 #define MAX31827_16_BIT_TO_M_DGR(x)     (sign_extend32(x, 15) * 1000 / 16)
32 #define MAX31827_M_DGR_TO_16_BIT(x)     (((x) << 4) / 1000)
33 #define MAX31827_DEVICE_ENABLE(x)       ((x) ? 0xA : 0x0)
34
35 enum max31827_cnv {
36         MAX31827_CNV_1_DIV_64_HZ = 1,
37         MAX31827_CNV_1_DIV_32_HZ,
38         MAX31827_CNV_1_DIV_16_HZ,
39         MAX31827_CNV_1_DIV_4_HZ,
40         MAX31827_CNV_1_HZ,
41         MAX31827_CNV_4_HZ,
42         MAX31827_CNV_8_HZ,
43 };
44
45 static const u16 max31827_conversions[] = {
46         [MAX31827_CNV_1_DIV_64_HZ] = 64000,
47         [MAX31827_CNV_1_DIV_32_HZ] = 32000,
48         [MAX31827_CNV_1_DIV_16_HZ] = 16000,
49         [MAX31827_CNV_1_DIV_4_HZ] = 4000,
50         [MAX31827_CNV_1_HZ] = 1000,
51         [MAX31827_CNV_4_HZ] = 250,
52         [MAX31827_CNV_8_HZ] = 125,
53 };
54
55 struct max31827_state {
56         /*
57          * Prevent simultaneous access to the i2c client.
58          */
59         struct mutex lock;
60         struct regmap *regmap;
61         bool enable;
62 };
63
64 static const struct regmap_config max31827_regmap = {
65         .reg_bits = 8,
66         .val_bits = 16,
67         .max_register = 0xA,
68 };
69
70 static int shutdown_write(struct max31827_state *st, unsigned int reg,
71                           unsigned int val)
72 {
73         unsigned int cfg;
74         unsigned int cnv_rate;
75         int ret;
76
77         /*
78          * Before the Temperature Threshold Alarm and Alarm Hysteresis Threshold
79          * register values are changed over I2C, the part must be in shutdown
80          * mode.
81          *
82          * Mutex is used to ensure, that some other process doesn't change the
83          * configuration register.
84          */
85         mutex_lock(&st->lock);
86
87         if (!st->enable) {
88                 ret = regmap_write(st->regmap, reg, val);
89                 goto unlock;
90         }
91
92         ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &cfg);
93         if (ret)
94                 goto unlock;
95
96         cnv_rate = MAX31827_CONFIGURATION_CNV_RATE_MASK & cfg;
97         cfg = cfg & ~(MAX31827_CONFIGURATION_1SHOT_MASK |
98                       MAX31827_CONFIGURATION_CNV_RATE_MASK);
99         ret = regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, cfg);
100         if (ret)
101                 goto unlock;
102
103         ret = regmap_write(st->regmap, reg, val);
104         if (ret)
105                 goto unlock;
106
107         ret = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG,
108                                  MAX31827_CONFIGURATION_CNV_RATE_MASK,
109                                  cnv_rate);
110
111 unlock:
112         mutex_unlock(&st->lock);
113         return ret;
114 }
115
116 static int write_alarm_val(struct max31827_state *st, unsigned int reg,
117                            long val)
118 {
119         val = MAX31827_M_DGR_TO_16_BIT(val);
120
121         return shutdown_write(st, reg, val);
122 }
123
124 static umode_t max31827_is_visible(const void *state,
125                                    enum hwmon_sensor_types type, u32 attr,
126                                    int channel)
127 {
128         if (type == hwmon_temp) {
129                 switch (attr) {
130                 case hwmon_temp_enable:
131                 case hwmon_temp_max:
132                 case hwmon_temp_min:
133                 case hwmon_temp_max_hyst:
134                 case hwmon_temp_min_hyst:
135                         return 0644;
136                 case hwmon_temp_input:
137                 case hwmon_temp_min_alarm:
138                 case hwmon_temp_max_alarm:
139                         return 0444;
140                 default:
141                         return 0;
142                 }
143         } else if (type == hwmon_chip) {
144                 if (attr == hwmon_chip_update_interval)
145                         return 0644;
146         }
147
148         return 0;
149 }
150
151 static int max31827_read(struct device *dev, enum hwmon_sensor_types type,
152                          u32 attr, int channel, long *val)
153 {
154         struct max31827_state *st = dev_get_drvdata(dev);
155         unsigned int uval;
156         int ret = 0;
157
158         switch (type) {
159         case hwmon_temp:
160                 switch (attr) {
161                 case hwmon_temp_enable:
162                         ret = regmap_read(st->regmap,
163                                           MAX31827_CONFIGURATION_REG, &uval);
164                         if (ret)
165                                 break;
166
167                         uval = FIELD_GET(MAX31827_CONFIGURATION_1SHOT_MASK |
168                                          MAX31827_CONFIGURATION_CNV_RATE_MASK,
169                                          uval);
170                         *val = !!uval;
171
172                         break;
173                 case hwmon_temp_input:
174                         mutex_lock(&st->lock);
175
176                         if (!st->enable) {
177                                 /*
178                                  * This operation requires mutex protection,
179                                  * because the chip configuration should not
180                                  * be changed during the conversion process.
181                                  */
182
183                                 ret = regmap_update_bits(st->regmap,
184                                                          MAX31827_CONFIGURATION_REG,
185                                                          MAX31827_CONFIGURATION_1SHOT_MASK,
186                                                          1);
187                                 if (ret) {
188                                         mutex_unlock(&st->lock);
189                                         return ret;
190                                 }
191
192                                 msleep(MAX31827_12_BIT_CNV_TIME);
193                         }
194                         ret = regmap_read(st->regmap, MAX31827_T_REG, &uval);
195
196                         mutex_unlock(&st->lock);
197
198                         if (ret)
199                                 break;
200
201                         *val = MAX31827_16_BIT_TO_M_DGR(uval);
202
203                         break;
204                 case hwmon_temp_max:
205                         ret = regmap_read(st->regmap, MAX31827_TH_REG, &uval);
206                         if (ret)
207                                 break;
208
209                         *val = MAX31827_16_BIT_TO_M_DGR(uval);
210                         break;
211                 case hwmon_temp_max_hyst:
212                         ret = regmap_read(st->regmap, MAX31827_TH_HYST_REG,
213                                           &uval);
214                         if (ret)
215                                 break;
216
217                         *val = MAX31827_16_BIT_TO_M_DGR(uval);
218                         break;
219                 case hwmon_temp_max_alarm:
220                         ret = regmap_read(st->regmap,
221                                           MAX31827_CONFIGURATION_REG, &uval);
222                         if (ret)
223                                 break;
224
225                         *val = FIELD_GET(MAX31827_CONFIGURATION_O_TEMP_STAT_MASK,
226                                          uval);
227                         break;
228                 case hwmon_temp_min:
229                         ret = regmap_read(st->regmap, MAX31827_TL_REG, &uval);
230                         if (ret)
231                                 break;
232
233                         *val = MAX31827_16_BIT_TO_M_DGR(uval);
234                         break;
235                 case hwmon_temp_min_hyst:
236                         ret = regmap_read(st->regmap, MAX31827_TL_HYST_REG,
237                                           &uval);
238                         if (ret)
239                                 break;
240
241                         *val = MAX31827_16_BIT_TO_M_DGR(uval);
242                         break;
243                 case hwmon_temp_min_alarm:
244                         ret = regmap_read(st->regmap,
245                                           MAX31827_CONFIGURATION_REG, &uval);
246                         if (ret)
247                                 break;
248
249                         *val = FIELD_GET(MAX31827_CONFIGURATION_U_TEMP_STAT_MASK,
250                                          uval);
251                         break;
252                 default:
253                         ret = -EOPNOTSUPP;
254                         break;
255                 }
256
257                 break;
258
259         case hwmon_chip:
260                 if (attr == hwmon_chip_update_interval) {
261                         ret = regmap_read(st->regmap,
262                                           MAX31827_CONFIGURATION_REG, &uval);
263                         if (ret)
264                                 break;
265
266                         uval = FIELD_GET(MAX31827_CONFIGURATION_CNV_RATE_MASK,
267                                          uval);
268                         *val = max31827_conversions[uval];
269                 }
270                 break;
271
272         default:
273                 ret = -EOPNOTSUPP;
274                 break;
275         }
276
277         return ret;
278 }
279
280 static int max31827_write(struct device *dev, enum hwmon_sensor_types type,
281                           u32 attr, int channel, long val)
282 {
283         struct max31827_state *st = dev_get_drvdata(dev);
284         int res = 1;
285         int ret;
286
287         switch (type) {
288         case hwmon_temp:
289                 switch (attr) {
290                 case hwmon_temp_enable:
291                         if (val >> 1)
292                                 return -EINVAL;
293
294                         mutex_lock(&st->lock);
295                         /**
296                          * The chip should not be enabled while a conversion is
297                          * performed. Neither should the chip be enabled when
298                          * the alarm values are changed.
299                          */
300
301                         st->enable = val;
302
303                         ret = regmap_update_bits(st->regmap,
304                                                  MAX31827_CONFIGURATION_REG,
305                                                  MAX31827_CONFIGURATION_1SHOT_MASK |
306                                                  MAX31827_CONFIGURATION_CNV_RATE_MASK,
307                                                  MAX31827_DEVICE_ENABLE(val));
308
309                         mutex_unlock(&st->lock);
310
311                         return ret;
312
313                 case hwmon_temp_max:
314                         return write_alarm_val(st, MAX31827_TH_REG, val);
315
316                 case hwmon_temp_max_hyst:
317                         return write_alarm_val(st, MAX31827_TH_HYST_REG, val);
318
319                 case hwmon_temp_min:
320                         return write_alarm_val(st, MAX31827_TL_REG, val);
321
322                 case hwmon_temp_min_hyst:
323                         return write_alarm_val(st, MAX31827_TL_HYST_REG, val);
324
325                 default:
326                         return -EOPNOTSUPP;
327                 }
328
329         case hwmon_chip:
330                 if (attr == hwmon_chip_update_interval) {
331                         if (!st->enable)
332                                 return -EINVAL;
333
334                         /*
335                          * Convert the desired conversion rate into register
336                          * bits. res is already initialized with 1.
337                          *
338                          * This was inspired by lm73 driver.
339                          */
340                         while (res < ARRAY_SIZE(max31827_conversions) &&
341                                val < max31827_conversions[res])
342                                 res++;
343
344                         if (res == ARRAY_SIZE(max31827_conversions) ||
345                             val != max31827_conversions[res])
346                                 return -EINVAL;
347
348                         res = FIELD_PREP(MAX31827_CONFIGURATION_CNV_RATE_MASK,
349                                          res);
350
351                         return regmap_update_bits(st->regmap,
352                                                   MAX31827_CONFIGURATION_REG,
353                                                   MAX31827_CONFIGURATION_CNV_RATE_MASK,
354                                                   res);
355                 }
356                 break;
357
358         default:
359                 return -EOPNOTSUPP;
360         }
361
362         return -EOPNOTSUPP;
363 }
364
365 static int max31827_init_client(struct max31827_state *st)
366 {
367         st->enable = true;
368
369         return regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG,
370                                   MAX31827_CONFIGURATION_1SHOT_MASK |
371                                           MAX31827_CONFIGURATION_CNV_RATE_MASK,
372                                   MAX31827_DEVICE_ENABLE(1));
373 }
374
375 static const struct hwmon_channel_info *max31827_info[] = {
376         HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_MIN |
377                                          HWMON_T_MIN_HYST | HWMON_T_MIN_ALARM |
378                                          HWMON_T_MAX | HWMON_T_MAX_HYST |
379                                          HWMON_T_MAX_ALARM),
380         HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
381         NULL,
382 };
383
384 static const struct hwmon_ops max31827_hwmon_ops = {
385         .is_visible = max31827_is_visible,
386         .read = max31827_read,
387         .write = max31827_write,
388 };
389
390 static const struct hwmon_chip_info max31827_chip_info = {
391         .ops = &max31827_hwmon_ops,
392         .info = max31827_info,
393 };
394
395 static int max31827_probe(struct i2c_client *client)
396 {
397         struct device *dev = &client->dev;
398         struct device *hwmon_dev;
399         struct max31827_state *st;
400         int err;
401
402         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
403                 return -EOPNOTSUPP;
404
405         st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
406         if (!st)
407                 return -ENOMEM;
408
409         mutex_init(&st->lock);
410
411         st->regmap = devm_regmap_init_i2c(client, &max31827_regmap);
412         if (IS_ERR(st->regmap))
413                 return dev_err_probe(dev, PTR_ERR(st->regmap),
414                                      "Failed to allocate regmap.\n");
415
416         err = devm_regulator_get_enable(dev, "vref");
417         if (err)
418                 return dev_err_probe(dev, err, "failed to enable regulator\n");
419
420         err = max31827_init_client(st);
421         if (err)
422                 return err;
423
424         hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, st,
425                                                          &max31827_chip_info,
426                                                          NULL);
427
428         return PTR_ERR_OR_ZERO(hwmon_dev);
429 }
430
431 static const struct i2c_device_id max31827_i2c_ids[] = {
432         { "max31827", 0 },
433         { }
434 };
435 MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids);
436
437 static const struct of_device_id max31827_of_match[] = {
438         { .compatible = "adi,max31827" },
439         { }
440 };
441 MODULE_DEVICE_TABLE(of, max31827_of_match);
442
443 static struct i2c_driver max31827_driver = {
444         .class = I2C_CLASS_HWMON,
445         .driver = {
446                 .name = "max31827",
447                 .of_match_table = max31827_of_match,
448         },
449         .probe = max31827_probe,
450         .id_table = max31827_i2c_ids,
451 };
452 module_i2c_driver(max31827_driver);
453
454 MODULE_AUTHOR("Daniel Matyas <daniel.matyas@analog.com>");
455 MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver");
456 MODULE_LICENSE("GPL");