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
42struct 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
51static const struct regmap_config max31827_regmap = {
52	.reg_bits = 8,
53	.val_bits = 16,
54	.max_register = 0xA,
55};
56
57static 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
97unlock:
98	mutex_unlock(&st->lock);
99	return ret;
100}
101
102static 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
129static 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
283static 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
379static 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
389static 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
398static const struct hwmon_ops max31827_hwmon_ops = {
399	.is_visible = max31827_is_visible,
400	.read = max31827_read,
401	.write = max31827_write,
402};
403
404static const struct hwmon_chip_info max31827_chip_info = {
405	.ops = &max31827_hwmon_ops,
406	.info = max31827_info,
407};
408
409static 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
441static const struct i2c_device_id max31827_i2c_ids[] = {
442	{ "max31827", 0 },
443	{ }
444};
445MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids);
446
447static const struct of_device_id max31827_of_match[] = {
448	{ .compatible = "adi,max31827" },
449	{ }
450};
451MODULE_DEVICE_TABLE(of, max31827_of_match);
452
453static 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};
462module_i2c_driver(max31827_driver);
463
464MODULE_AUTHOR("Daniel Matyas <daniel.matyas@analog.com>");
465MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver");
466MODULE_LICENSE("GPL");
467