1 // SPDX-License-Identifier: GPL-2.0
3 * max31827.c - Support for Maxim Low-Power Switch
5 * Copyright (c) 2023 Daniel Matyas <daniel.matyas@analog.com>
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>
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
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)
28 #define MAX31827_12_BIT_CNV_TIME 141
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
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)
42 struct max31827_state {
44 * Prevent simultaneous access to the i2c client.
47 struct regmap *regmap;
51 static const struct regmap_config max31827_regmap = {
57 static int write_alarm_val(struct max31827_state *st, unsigned int reg,
64 val = MAX31827_M_DGR_TO_16_BIT(val);
67 * Before the Temperature Threshold Alarm and Alarm Hysteresis Threshold
68 * register values are changed over I2C, the part must be in shutdown
71 * Mutex is used to ensure, that some other process doesn't change the
72 * configuration register.
74 mutex_lock(&st->lock);
77 ret = regmap_write(st->regmap, reg, val);
81 ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &cfg);
85 tmp = cfg & ~(MAX31827_CONFIGURATION_1SHOT_MASK |
86 MAX31827_CONFIGURATION_CNV_RATE_MASK);
87 ret = regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, tmp);
91 ret = regmap_write(st->regmap, reg, val);
95 ret = regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, cfg);
98 mutex_unlock(&st->lock);
102 static umode_t max31827_is_visible(const void *state,
103 enum hwmon_sensor_types type, u32 attr,
106 if (type == hwmon_temp) {
108 case hwmon_temp_enable:
111 case hwmon_temp_max_hyst:
112 case hwmon_temp_min_hyst:
114 case hwmon_temp_input:
115 case hwmon_temp_min_alarm:
116 case hwmon_temp_max_alarm:
121 } else if (type == hwmon_chip) {
122 if (attr == hwmon_chip_update_interval)
129 static int max31827_read(struct device *dev, enum hwmon_sensor_types type,
130 u32 attr, int channel, long *val)
132 struct max31827_state *st = dev_get_drvdata(dev);
139 case hwmon_temp_enable:
140 ret = regmap_read(st->regmap,
141 MAX31827_CONFIGURATION_REG, &uval);
145 uval = FIELD_GET(MAX31827_CONFIGURATION_1SHOT_MASK |
146 MAX31827_CONFIGURATION_CNV_RATE_MASK,
151 case hwmon_temp_input:
152 mutex_lock(&st->lock);
156 * This operation requires mutex protection,
157 * because the chip configuration should not
158 * be changed during the conversion process.
161 ret = regmap_update_bits(st->regmap,
162 MAX31827_CONFIGURATION_REG,
163 MAX31827_CONFIGURATION_1SHOT_MASK,
166 mutex_unlock(&st->lock);
170 msleep(MAX31827_12_BIT_CNV_TIME);
172 ret = regmap_read(st->regmap, MAX31827_T_REG, &uval);
174 mutex_unlock(&st->lock);
179 *val = MAX31827_16_BIT_TO_M_DGR(uval);
183 ret = regmap_read(st->regmap, MAX31827_TH_REG, &uval);
187 *val = MAX31827_16_BIT_TO_M_DGR(uval);
189 case hwmon_temp_max_hyst:
190 ret = regmap_read(st->regmap, MAX31827_TH_HYST_REG,
195 *val = MAX31827_16_BIT_TO_M_DGR(uval);
197 case hwmon_temp_max_alarm:
198 ret = regmap_read(st->regmap,
199 MAX31827_CONFIGURATION_REG, &uval);
203 *val = FIELD_GET(MAX31827_CONFIGURATION_O_TEMP_STAT_MASK,
207 ret = regmap_read(st->regmap, MAX31827_TL_REG, &uval);
211 *val = MAX31827_16_BIT_TO_M_DGR(uval);
213 case hwmon_temp_min_hyst:
214 ret = regmap_read(st->regmap, MAX31827_TL_HYST_REG,
219 *val = MAX31827_16_BIT_TO_M_DGR(uval);
221 case hwmon_temp_min_alarm:
222 ret = regmap_read(st->regmap,
223 MAX31827_CONFIGURATION_REG, &uval);
227 *val = FIELD_GET(MAX31827_CONFIGURATION_U_TEMP_STAT_MASK,
238 if (attr == hwmon_chip_update_interval) {
239 ret = regmap_read(st->regmap,
240 MAX31827_CONFIGURATION_REG, &uval);
244 uval = FIELD_GET(MAX31827_CONFIGURATION_CNV_RATE_MASK,
247 case MAX31827_CNV_1_DIV_64_HZ:
250 case MAX31827_CNV_1_DIV_32_HZ:
253 case MAX31827_CNV_1_DIV_16_HZ:
256 case MAX31827_CNV_1_DIV_4_HZ:
259 case MAX31827_CNV_1_HZ:
262 case MAX31827_CNV_4_HZ:
265 case MAX31827_CNV_8_HZ:
283 static int max31827_write(struct device *dev, enum hwmon_sensor_types type,
284 u32 attr, int channel, long val)
286 struct max31827_state *st = dev_get_drvdata(dev);
292 case hwmon_temp_enable:
296 mutex_lock(&st->lock);
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.
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));
311 mutex_unlock(&st->lock);
316 return write_alarm_val(st, MAX31827_TH_REG, val);
318 case hwmon_temp_max_hyst:
319 return write_alarm_val(st, MAX31827_TH_HYST_REG, val);
322 return write_alarm_val(st, MAX31827_TL_REG, val);
324 case hwmon_temp_min_hyst:
325 return write_alarm_val(st, MAX31827_TL_HYST_REG, val);
332 if (attr == hwmon_chip_update_interval) {
338 val = MAX31827_CNV_8_HZ;
341 val = MAX31827_CNV_4_HZ;
344 val = MAX31827_CNV_1_HZ;
347 val = MAX31827_CNV_1_DIV_4_HZ;
350 val = MAX31827_CNV_1_DIV_16_HZ;
353 val = MAX31827_CNV_1_DIV_32_HZ;
356 val = MAX31827_CNV_1_DIV_64_HZ;
362 val = FIELD_PREP(MAX31827_CONFIGURATION_CNV_RATE_MASK,
365 return regmap_update_bits(st->regmap,
366 MAX31827_CONFIGURATION_REG,
367 MAX31827_CONFIGURATION_CNV_RATE_MASK,
379 static int max31827_init_client(struct max31827_state *st)
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));
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 |
394 HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
398 static const struct hwmon_ops max31827_hwmon_ops = {
399 .is_visible = max31827_is_visible,
400 .read = max31827_read,
401 .write = max31827_write,
404 static const struct hwmon_chip_info max31827_chip_info = {
405 .ops = &max31827_hwmon_ops,
406 .info = max31827_info,
409 static int max31827_probe(struct i2c_client *client)
411 struct device *dev = &client->dev;
412 struct device *hwmon_dev;
413 struct max31827_state *st;
416 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
419 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
423 mutex_init(&st->lock);
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");
430 err = max31827_init_client(st);
434 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, st,
438 return PTR_ERR_OR_ZERO(hwmon_dev);
441 static const struct i2c_device_id max31827_i2c_ids[] = {
445 MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids);
447 static const struct of_device_id max31827_of_match[] = {
448 { .compatible = "adi,max31827" },
451 MODULE_DEVICE_TABLE(of, max31827_of_match);
453 static struct i2c_driver max31827_driver = {
454 .class = I2C_CLASS_HWMON,
457 .of_match_table = max31827_of_match,
459 .probe = max31827_probe,
460 .id_table = max31827_i2c_ids,
462 module_i2c_driver(max31827_driver);
464 MODULE_AUTHOR("Daniel Matyas <daniel.matyas@analog.com>");
465 MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver");
466 MODULE_LICENSE("GPL");