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