xref: /linux/drivers/hwmon/max127.c (revision 1975d167869ef03102771d6267582623d6e07058)
18efd1014STao Ren // SPDX-License-Identifier: GPL-2.0+
28efd1014STao Ren /*
38efd1014STao Ren  * Hardware monitoring driver for MAX127.
48efd1014STao Ren  *
58efd1014STao Ren  * Copyright (c) 2020 Facebook Inc.
68efd1014STao Ren  */
78efd1014STao Ren 
88efd1014STao Ren #include <linux/err.h>
98efd1014STao Ren #include <linux/hwmon.h>
108efd1014STao Ren #include <linux/i2c.h>
118efd1014STao Ren #include <linux/init.h>
128efd1014STao Ren #include <linux/module.h>
138efd1014STao Ren 
148efd1014STao Ren /*
158efd1014STao Ren  * MAX127 Control Byte. Refer to MAX127 datasheet, Table 1 "Control-Byte
168efd1014STao Ren  * Format" for details.
178efd1014STao Ren  */
188efd1014STao Ren #define MAX127_CTRL_START	BIT(7)
198efd1014STao Ren #define MAX127_CTRL_SEL_SHIFT	4
208efd1014STao Ren #define MAX127_CTRL_RNG		BIT(3)
218efd1014STao Ren #define MAX127_CTRL_BIP		BIT(2)
228efd1014STao Ren #define MAX127_CTRL_PD1		BIT(1)
238efd1014STao Ren #define MAX127_CTRL_PD0		BIT(0)
248efd1014STao Ren 
258efd1014STao Ren #define MAX127_NUM_CHANNELS	8
268efd1014STao Ren #define MAX127_SET_CHANNEL(ch)	(((ch) & 7) << MAX127_CTRL_SEL_SHIFT)
278efd1014STao Ren 
288efd1014STao Ren /*
298efd1014STao Ren  * MAX127 channel input ranges. Refer to MAX127 datasheet, Table 3 "Range
308efd1014STao Ren  * and Polarity Selection" for details.
318efd1014STao Ren  */
328efd1014STao Ren #define MAX127_FULL_RANGE	10000	/* 10V */
338efd1014STao Ren #define MAX127_HALF_RANGE	5000	/* 5V */
348efd1014STao Ren 
358efd1014STao Ren /*
368efd1014STao Ren  * MAX127 returns 2 bytes at read:
378efd1014STao Ren  *   - the first byte contains data[11:4].
388efd1014STao Ren  *   - the second byte contains data[3:0] (MSB) and 4 dummy 0s (LSB).
398efd1014STao Ren  * Refer to MAX127 datasheet, "Read a Conversion (Read Cycle)" section
408efd1014STao Ren  * for details.
418efd1014STao Ren  */
428efd1014STao Ren #define MAX127_DATA_LEN		2
438efd1014STao Ren #define MAX127_DATA_SHIFT	4
448efd1014STao Ren 
458efd1014STao Ren #define MAX127_SIGN_BIT		BIT(11)
468efd1014STao Ren 
478efd1014STao Ren struct max127_data {
488efd1014STao Ren 	struct mutex lock;
498efd1014STao Ren 	struct i2c_client *client;
508efd1014STao Ren 	u8 ctrl_byte[MAX127_NUM_CHANNELS];
518efd1014STao Ren };
528efd1014STao Ren 
538efd1014STao Ren static int max127_select_channel(struct i2c_client *client, u8 ctrl_byte)
548efd1014STao Ren {
558efd1014STao Ren 	int status;
568efd1014STao Ren 	struct i2c_msg msg = {
578efd1014STao Ren 		.addr = client->addr,
588efd1014STao Ren 		.flags = 0,
598efd1014STao Ren 		.len = sizeof(ctrl_byte),
608efd1014STao Ren 		.buf = &ctrl_byte,
618efd1014STao Ren 	};
628efd1014STao Ren 
638efd1014STao Ren 	status = i2c_transfer(client->adapter, &msg, 1);
648efd1014STao Ren 	if (status < 0)
658efd1014STao Ren 		return status;
668efd1014STao Ren 	if (status != 1)
678efd1014STao Ren 		return -EIO;
688efd1014STao Ren 
698efd1014STao Ren 	return 0;
708efd1014STao Ren }
718efd1014STao Ren 
728efd1014STao Ren static int max127_read_channel(struct i2c_client *client, long *val)
738efd1014STao Ren {
748efd1014STao Ren 	int status;
758efd1014STao Ren 	u8 i2c_data[MAX127_DATA_LEN];
768efd1014STao Ren 	struct i2c_msg msg = {
778efd1014STao Ren 		.addr = client->addr,
788efd1014STao Ren 		.flags = I2C_M_RD,
798efd1014STao Ren 		.len = sizeof(i2c_data),
808efd1014STao Ren 		.buf = i2c_data,
818efd1014STao Ren 	};
828efd1014STao Ren 
838efd1014STao Ren 	status = i2c_transfer(client->adapter, &msg, 1);
848efd1014STao Ren 	if (status < 0)
858efd1014STao Ren 		return status;
868efd1014STao Ren 	if (status != 1)
878efd1014STao Ren 		return -EIO;
888efd1014STao Ren 
898efd1014STao Ren 	*val = (i2c_data[1] >> MAX127_DATA_SHIFT) |
908efd1014STao Ren 		((u16)i2c_data[0] << MAX127_DATA_SHIFT);
918efd1014STao Ren 	return 0;
928efd1014STao Ren }
938efd1014STao Ren 
948efd1014STao Ren static long max127_process_raw(u8 ctrl_byte, long raw)
958efd1014STao Ren {
968efd1014STao Ren 	long scale, weight;
978efd1014STao Ren 
988efd1014STao Ren 	/*
998efd1014STao Ren 	 * MAX127's data coding is binary in unipolar mode with 1 LSB =
1008efd1014STao Ren 	 * (Full-Scale/4096) and two’s complement binary in bipolar mode
1018efd1014STao Ren 	 * with 1 LSB = [(2 x |FS|)/4096].
1028efd1014STao Ren 	 * Refer to MAX127 datasheet, "Transfer Function" section for
1038efd1014STao Ren 	 * details.
1048efd1014STao Ren 	 */
1058efd1014STao Ren 	scale = (ctrl_byte & MAX127_CTRL_RNG) ? MAX127_FULL_RANGE :
1068efd1014STao Ren 						MAX127_HALF_RANGE;
1078efd1014STao Ren 	if (ctrl_byte & MAX127_CTRL_BIP) {
1088efd1014STao Ren 		weight = (raw & MAX127_SIGN_BIT);
1098efd1014STao Ren 		raw &= ~MAX127_SIGN_BIT;
1108efd1014STao Ren 		raw -= weight;
1118efd1014STao Ren 		raw *= 2;
1128efd1014STao Ren 	}
1138efd1014STao Ren 
1148efd1014STao Ren 	return raw * scale / 4096;
1158efd1014STao Ren }
1168efd1014STao Ren 
1178efd1014STao Ren static int max127_read_input(struct max127_data *data, int channel, long *val)
1188efd1014STao Ren {
1198efd1014STao Ren 	long raw;
1208efd1014STao Ren 	int status;
1218efd1014STao Ren 	struct i2c_client *client = data->client;
1228efd1014STao Ren 	u8 ctrl_byte = data->ctrl_byte[channel];
1238efd1014STao Ren 
1248efd1014STao Ren 	mutex_lock(&data->lock);
1258efd1014STao Ren 
1268efd1014STao Ren 	status = max127_select_channel(client, ctrl_byte);
1278efd1014STao Ren 	if (status)
1288efd1014STao Ren 		goto exit;
1298efd1014STao Ren 
1308efd1014STao Ren 	status = max127_read_channel(client, &raw);
1318efd1014STao Ren 	if (status)
1328efd1014STao Ren 		goto exit;
1338efd1014STao Ren 
1348efd1014STao Ren 	*val = max127_process_raw(ctrl_byte, raw);
1358efd1014STao Ren 
1368efd1014STao Ren exit:
1378efd1014STao Ren 	mutex_unlock(&data->lock);
1388efd1014STao Ren 	return status;
1398efd1014STao Ren }
1408efd1014STao Ren 
1418efd1014STao Ren static int max127_read_min(struct max127_data *data, int channel, long *val)
1428efd1014STao Ren {
1438efd1014STao Ren 	u8 rng_bip = (data->ctrl_byte[channel] >> 2) & 3;
1448efd1014STao Ren 	static const int min_input_map[4] = {
1458efd1014STao Ren 		0,			/* RNG=0, BIP=0 */
1468efd1014STao Ren 		-MAX127_HALF_RANGE,	/* RNG=0, BIP=1 */
1478efd1014STao Ren 		0,			/* RNG=1, BIP=0 */
1488efd1014STao Ren 		-MAX127_FULL_RANGE,	/* RNG=1, BIP=1 */
1498efd1014STao Ren 	};
1508efd1014STao Ren 
1518efd1014STao Ren 	*val = min_input_map[rng_bip];
1528efd1014STao Ren 	return 0;
1538efd1014STao Ren }
1548efd1014STao Ren 
1558efd1014STao Ren static int max127_read_max(struct max127_data *data, int channel, long *val)
1568efd1014STao Ren {
1578efd1014STao Ren 	u8 rng_bip = (data->ctrl_byte[channel] >> 2) & 3;
1588efd1014STao Ren 	static const int max_input_map[4] = {
1598efd1014STao Ren 		MAX127_HALF_RANGE,	/* RNG=0, BIP=0 */
1608efd1014STao Ren 		MAX127_HALF_RANGE,	/* RNG=0, BIP=1 */
1618efd1014STao Ren 		MAX127_FULL_RANGE,	/* RNG=1, BIP=0 */
1628efd1014STao Ren 		MAX127_FULL_RANGE,	/* RNG=1, BIP=1 */
1638efd1014STao Ren 	};
1648efd1014STao Ren 
1658efd1014STao Ren 	*val = max_input_map[rng_bip];
1668efd1014STao Ren 	return 0;
1678efd1014STao Ren }
1688efd1014STao Ren 
1698efd1014STao Ren static int max127_write_min(struct max127_data *data, int channel, long val)
1708efd1014STao Ren {
1718efd1014STao Ren 	u8 ctrl;
1728efd1014STao Ren 
1738efd1014STao Ren 	mutex_lock(&data->lock);
1748efd1014STao Ren 
1758efd1014STao Ren 	ctrl = data->ctrl_byte[channel];
1768efd1014STao Ren 	if (val <= -MAX127_FULL_RANGE) {
1778efd1014STao Ren 		ctrl |= (MAX127_CTRL_RNG | MAX127_CTRL_BIP);
1788efd1014STao Ren 	} else if (val < 0) {
1798efd1014STao Ren 		ctrl |= MAX127_CTRL_BIP;
1808efd1014STao Ren 		ctrl &= ~MAX127_CTRL_RNG;
1818efd1014STao Ren 	} else {
1828efd1014STao Ren 		ctrl &= ~MAX127_CTRL_BIP;
1838efd1014STao Ren 	}
1848efd1014STao Ren 	data->ctrl_byte[channel] = ctrl;
1858efd1014STao Ren 
1868efd1014STao Ren 	mutex_unlock(&data->lock);
1878efd1014STao Ren 
1888efd1014STao Ren 	return 0;
1898efd1014STao Ren }
1908efd1014STao Ren 
1918efd1014STao Ren static int max127_write_max(struct max127_data *data, int channel, long val)
1928efd1014STao Ren {
1938efd1014STao Ren 	mutex_lock(&data->lock);
1948efd1014STao Ren 
1958efd1014STao Ren 	if (val >= MAX127_FULL_RANGE)
1968efd1014STao Ren 		data->ctrl_byte[channel] |= MAX127_CTRL_RNG;
1978efd1014STao Ren 	else
1988efd1014STao Ren 		data->ctrl_byte[channel] &= ~MAX127_CTRL_RNG;
1998efd1014STao Ren 
2008efd1014STao Ren 	mutex_unlock(&data->lock);
2018efd1014STao Ren 
2028efd1014STao Ren 	return 0;
2038efd1014STao Ren }
2048efd1014STao Ren 
2058efd1014STao Ren static umode_t max127_is_visible(const void *_data,
2068efd1014STao Ren 				 enum hwmon_sensor_types type,
2078efd1014STao Ren 				 u32 attr, int channel)
2088efd1014STao Ren {
2098efd1014STao Ren 	if (type == hwmon_in) {
2108efd1014STao Ren 		switch (attr) {
2118efd1014STao Ren 		case hwmon_in_input:
2128efd1014STao Ren 			return 0444;
2138efd1014STao Ren 
2148efd1014STao Ren 		case hwmon_in_min:
2158efd1014STao Ren 		case hwmon_in_max:
2168efd1014STao Ren 			return 0644;
2178efd1014STao Ren 
2188efd1014STao Ren 		default:
2198efd1014STao Ren 			break;
2208efd1014STao Ren 		}
2218efd1014STao Ren 	}
2228efd1014STao Ren 
2238efd1014STao Ren 	return 0;
2248efd1014STao Ren }
2258efd1014STao Ren 
2268efd1014STao Ren static int max127_read(struct device *dev, enum hwmon_sensor_types type,
2278efd1014STao Ren 			u32 attr, int channel, long *val)
2288efd1014STao Ren {
2298efd1014STao Ren 	int status;
2308efd1014STao Ren 	struct max127_data *data = dev_get_drvdata(dev);
2318efd1014STao Ren 
2328efd1014STao Ren 	if (type != hwmon_in)
2338efd1014STao Ren 		return -EOPNOTSUPP;
2348efd1014STao Ren 
2358efd1014STao Ren 	switch (attr) {
2368efd1014STao Ren 	case hwmon_in_input:
2378efd1014STao Ren 		status = max127_read_input(data, channel, val);
2388efd1014STao Ren 		break;
2398efd1014STao Ren 
2408efd1014STao Ren 	case hwmon_in_min:
2418efd1014STao Ren 		status = max127_read_min(data, channel, val);
2428efd1014STao Ren 		break;
2438efd1014STao Ren 
2448efd1014STao Ren 	case hwmon_in_max:
2458efd1014STao Ren 		status = max127_read_max(data, channel, val);
2468efd1014STao Ren 		break;
2478efd1014STao Ren 
2488efd1014STao Ren 	default:
2498efd1014STao Ren 		status = -EOPNOTSUPP;
2508efd1014STao Ren 		break;
2518efd1014STao Ren 	}
2528efd1014STao Ren 
2538efd1014STao Ren 	return status;
2548efd1014STao Ren }
2558efd1014STao Ren 
2568efd1014STao Ren static int max127_write(struct device *dev, enum hwmon_sensor_types type,
2578efd1014STao Ren 			u32 attr, int channel, long val)
2588efd1014STao Ren {
2598efd1014STao Ren 	int status;
2608efd1014STao Ren 	struct max127_data *data = dev_get_drvdata(dev);
2618efd1014STao Ren 
2628efd1014STao Ren 	if (type != hwmon_in)
2638efd1014STao Ren 		return -EOPNOTSUPP;
2648efd1014STao Ren 
2658efd1014STao Ren 	switch (attr) {
2668efd1014STao Ren 	case hwmon_in_min:
2678efd1014STao Ren 		status = max127_write_min(data, channel, val);
2688efd1014STao Ren 		break;
2698efd1014STao Ren 
2708efd1014STao Ren 	case hwmon_in_max:
2718efd1014STao Ren 		status = max127_write_max(data, channel, val);
2728efd1014STao Ren 		break;
2738efd1014STao Ren 
2748efd1014STao Ren 	default:
2758efd1014STao Ren 		status = -EOPNOTSUPP;
2768efd1014STao Ren 		break;
2778efd1014STao Ren 	}
2788efd1014STao Ren 
2798efd1014STao Ren 	return status;
2808efd1014STao Ren }
2818efd1014STao Ren 
2828efd1014STao Ren static const struct hwmon_ops max127_hwmon_ops = {
2838efd1014STao Ren 	.is_visible = max127_is_visible,
2848efd1014STao Ren 	.read = max127_read,
2858efd1014STao Ren 	.write = max127_write,
2868efd1014STao Ren };
2878efd1014STao Ren 
2882b1aec84SKrzysztof Kozlowski static const struct hwmon_channel_info * const max127_info[] = {
2898efd1014STao Ren 	HWMON_CHANNEL_INFO(in,
2908efd1014STao Ren 			   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX,
2918efd1014STao Ren 			   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX,
2928efd1014STao Ren 			   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX,
2938efd1014STao Ren 			   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX,
2948efd1014STao Ren 			   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX,
2958efd1014STao Ren 			   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX,
2968efd1014STao Ren 			   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX,
2978efd1014STao Ren 			   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX),
2988efd1014STao Ren 	NULL,
2998efd1014STao Ren };
3008efd1014STao Ren 
3018efd1014STao Ren static const struct hwmon_chip_info max127_chip_info = {
3028efd1014STao Ren 	.ops = &max127_hwmon_ops,
3038efd1014STao Ren 	.info = max127_info,
3048efd1014STao Ren };
3058efd1014STao Ren 
306deeab9eaSStephen Kitt static int max127_probe(struct i2c_client *client)
3078efd1014STao Ren {
3088efd1014STao Ren 	int i;
3098efd1014STao Ren 	struct device *hwmon_dev;
3108efd1014STao Ren 	struct max127_data *data;
3118efd1014STao Ren 	struct device *dev = &client->dev;
3128efd1014STao Ren 
3138efd1014STao Ren 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
3148efd1014STao Ren 	if (!data)
3158efd1014STao Ren 		return -ENOMEM;
3168efd1014STao Ren 
3178efd1014STao Ren 	data->client = client;
3188efd1014STao Ren 	mutex_init(&data->lock);
3198efd1014STao Ren 	for (i = 0; i < ARRAY_SIZE(data->ctrl_byte); i++)
3208efd1014STao Ren 		data->ctrl_byte[i] = (MAX127_CTRL_START |
3218efd1014STao Ren 				      MAX127_SET_CHANNEL(i));
3228efd1014STao Ren 
3238efd1014STao Ren 	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
3248efd1014STao Ren 							 data,
3258efd1014STao Ren 							 &max127_chip_info,
3268efd1014STao Ren 							 NULL);
3278efd1014STao Ren 
3288efd1014STao Ren 	return PTR_ERR_OR_ZERO(hwmon_dev);
3298efd1014STao Ren }
3308efd1014STao Ren 
3318efd1014STao Ren static const struct i2c_device_id max127_id[] = {
3328efd1014STao Ren 	{ "max127", 0 },
3338efd1014STao Ren 	{ }
3348efd1014STao Ren };
3358efd1014STao Ren MODULE_DEVICE_TABLE(i2c, max127_id);
3368efd1014STao Ren 
3378efd1014STao Ren static struct i2c_driver max127_driver = {
3388efd1014STao Ren 	.class		= I2C_CLASS_HWMON,
3398efd1014STao Ren 	.driver = {
3408efd1014STao Ren 		.name	= "max127",
3418efd1014STao Ren 	},
342*1975d167SUwe Kleine-König 	.probe		= max127_probe,
3438efd1014STao Ren 	.id_table	= max127_id,
3448efd1014STao Ren };
3458efd1014STao Ren 
3468efd1014STao Ren module_i2c_driver(max127_driver);
3478efd1014STao Ren 
3488efd1014STao Ren MODULE_LICENSE("GPL");
3498efd1014STao Ren MODULE_AUTHOR("Mike Choi <mikechoi@fb.com>");
3508efd1014STao Ren MODULE_AUTHOR("Tao Ren <rentao.bupt@gmail.com>");
3518efd1014STao Ren MODULE_DESCRIPTION("MAX127 Hardware Monitoring driver");
352