brintos

brintos / linux-shallow public Read only

0
0
Text · 13.5 KiB · f569133 Raw
564 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * max31790.c - Part of lm_sensors, Linux kernel modules for hardware4 *             monitoring.5 *6 * (C) 2015 by Il Han <corone.il.han@gmail.com>7 */8 9#include <linux/err.h>10#include <linux/hwmon.h>11#include <linux/i2c.h>12#include <linux/init.h>13#include <linux/jiffies.h>14#include <linux/module.h>15#include <linux/slab.h>16 17/* MAX31790 registers */18#define MAX31790_REG_GLOBAL_CONFIG	0x0019#define MAX31790_REG_FAN_CONFIG(ch)	(0x02 + (ch))20#define MAX31790_REG_FAN_DYNAMICS(ch)	(0x08 + (ch))21#define MAX31790_REG_FAN_FAULT_STATUS2	0x1022#define MAX31790_REG_FAN_FAULT_STATUS1	0x1123#define MAX31790_REG_TACH_COUNT(ch)	(0x18 + (ch) * 2)24#define MAX31790_REG_PWM_DUTY_CYCLE(ch)	(0x30 + (ch) * 2)25#define MAX31790_REG_PWMOUT(ch)		(0x40 + (ch) * 2)26#define MAX31790_REG_TARGET_COUNT(ch)	(0x50 + (ch) * 2)27 28/* Fan Config register bits */29#define MAX31790_FAN_CFG_RPM_MODE	0x8030#define MAX31790_FAN_CFG_CTRL_MON	0x1031#define MAX31790_FAN_CFG_TACH_INPUT_EN	0x0832#define MAX31790_FAN_CFG_TACH_INPUT	0x0133 34/* Fan Dynamics register bits */35#define MAX31790_FAN_DYN_SR_SHIFT	536#define MAX31790_FAN_DYN_SR_MASK	0xE037#define SR_FROM_REG(reg)		(((reg) & MAX31790_FAN_DYN_SR_MASK) \38					 >> MAX31790_FAN_DYN_SR_SHIFT)39 40#define FAN_RPM_MIN			12041#define FAN_RPM_MAX			786432042 43#define FAN_COUNT_REG_MAX		0xffe044 45#define RPM_FROM_REG(reg, sr)		(((reg) >> 4) ? \46					 ((60 * (sr) * 8192) / ((reg) >> 4)) : \47					 FAN_RPM_MAX)48#define RPM_TO_REG(rpm, sr)		((60 * (sr) * 8192) / ((rpm) * 2))49 50#define NR_CHANNEL			651 52#define PWM_INPUT_SCALE	25553#define MAX31790_REG_PWMOUT_SCALE	51154 55/*56 * Client data (each client gets its own)57 */58struct max31790_data {59	struct i2c_client *client;60	struct mutex update_lock;61	bool valid; /* zero until following fields are valid */62	unsigned long last_updated; /* in jiffies */63 64	/* register values */65	u8 fan_config[NR_CHANNEL];66	u8 fan_dynamics[NR_CHANNEL];67	u16 fault_status;68	u16 tach[NR_CHANNEL * 2];69	u16 pwm[NR_CHANNEL];70	u16 target_count[NR_CHANNEL];71};72 73static struct max31790_data *max31790_update_device(struct device *dev)74{75	struct max31790_data *data = dev_get_drvdata(dev);76	struct i2c_client *client = data->client;77	struct max31790_data *ret = data;78	int i;79	int rv;80 81	mutex_lock(&data->update_lock);82 83	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {84		rv = i2c_smbus_read_byte_data(client,85				MAX31790_REG_FAN_FAULT_STATUS1);86		if (rv < 0)87			goto abort;88		data->fault_status |= rv & 0x3F;89 90		rv = i2c_smbus_read_byte_data(client,91				MAX31790_REG_FAN_FAULT_STATUS2);92		if (rv < 0)93			goto abort;94		data->fault_status |= (rv & 0x3F) << 6;95 96		for (i = 0; i < NR_CHANNEL; i++) {97			rv = i2c_smbus_read_word_swapped(client,98					MAX31790_REG_TACH_COUNT(i));99			if (rv < 0)100				goto abort;101			data->tach[i] = rv;102 103			if (data->fan_config[i]104			    & MAX31790_FAN_CFG_TACH_INPUT) {105				rv = i2c_smbus_read_word_swapped(client,106					MAX31790_REG_TACH_COUNT(NR_CHANNEL107								+ i));108				if (rv < 0)109					goto abort;110				data->tach[NR_CHANNEL + i] = rv;111			} else {112				rv = i2c_smbus_read_word_swapped(client,113						MAX31790_REG_PWM_DUTY_CYCLE(i));114				if (rv < 0)115					goto abort;116				data->pwm[i] = rv;117 118				rv = i2c_smbus_read_word_swapped(client,119						MAX31790_REG_TARGET_COUNT(i));120				if (rv < 0)121					goto abort;122				data->target_count[i] = rv;123			}124		}125 126		data->last_updated = jiffies;127		data->valid = true;128	}129	goto done;130 131abort:132	data->valid = false;133	ret = ERR_PTR(rv);134 135done:136	mutex_unlock(&data->update_lock);137 138	return ret;139}140 141static const u8 tach_period[8] = { 1, 2, 4, 8, 16, 32, 32, 32 };142 143static u8 get_tach_period(u8 fan_dynamics)144{145	return tach_period[SR_FROM_REG(fan_dynamics)];146}147 148static u8 bits_for_tach_period(int rpm)149{150	u8 bits;151 152	if (rpm < 500)153		bits = 0x0;154	else if (rpm < 1000)155		bits = 0x1;156	else if (rpm < 2000)157		bits = 0x2;158	else if (rpm < 4000)159		bits = 0x3;160	else if (rpm < 8000)161		bits = 0x4;162	else163		bits = 0x5;164 165	return bits;166}167 168static int max31790_read_fan(struct device *dev, u32 attr, int channel,169			     long *val)170{171	struct max31790_data *data = max31790_update_device(dev);172	int sr, rpm;173 174	if (IS_ERR(data))175		return PTR_ERR(data);176 177	switch (attr) {178	case hwmon_fan_input:179		sr = get_tach_period(data->fan_dynamics[channel % NR_CHANNEL]);180		if (data->tach[channel] == FAN_COUNT_REG_MAX)181			rpm = 0;182		else183			rpm = RPM_FROM_REG(data->tach[channel], sr);184		*val = rpm;185		return 0;186	case hwmon_fan_target:187		sr = get_tach_period(data->fan_dynamics[channel]);188		rpm = RPM_FROM_REG(data->target_count[channel], sr);189		*val = rpm;190		return 0;191	case hwmon_fan_fault:192		mutex_lock(&data->update_lock);193		*val = !!(data->fault_status & (1 << channel));194		data->fault_status &= ~(1 << channel);195		/*196		 * If a fault bit is set, we need to write into one of the fan197		 * configuration registers to clear it. Note that this also198		 * clears the fault for the companion channel if enabled.199		 */200		if (*val) {201			int reg = MAX31790_REG_TARGET_COUNT(channel % NR_CHANNEL);202 203			i2c_smbus_write_byte_data(data->client, reg,204						  data->target_count[channel % NR_CHANNEL] >> 8);205		}206		mutex_unlock(&data->update_lock);207		return 0;208	case hwmon_fan_enable:209		*val = !!(data->fan_config[channel] & MAX31790_FAN_CFG_TACH_INPUT_EN);210		return 0;211	default:212		return -EOPNOTSUPP;213	}214}215 216static int max31790_write_fan(struct device *dev, u32 attr, int channel,217			      long val)218{219	struct max31790_data *data = dev_get_drvdata(dev);220	struct i2c_client *client = data->client;221	int target_count;222	int err = 0;223	u8 bits, fan_config;224	int sr;225 226	mutex_lock(&data->update_lock);227 228	switch (attr) {229	case hwmon_fan_target:230		val = clamp_val(val, FAN_RPM_MIN, FAN_RPM_MAX);231		bits = bits_for_tach_period(val);232		data->fan_dynamics[channel] =233			((data->fan_dynamics[channel] &234			  ~MAX31790_FAN_DYN_SR_MASK) |235			 (bits << MAX31790_FAN_DYN_SR_SHIFT));236		err = i2c_smbus_write_byte_data(client,237					MAX31790_REG_FAN_DYNAMICS(channel),238					data->fan_dynamics[channel]);239		if (err < 0)240			break;241 242		sr = get_tach_period(data->fan_dynamics[channel]);243		target_count = RPM_TO_REG(val, sr);244		target_count = clamp_val(target_count, 0x1, 0x7FF);245 246		data->target_count[channel] = target_count << 5;247 248		err = i2c_smbus_write_word_swapped(client,249					MAX31790_REG_TARGET_COUNT(channel),250					data->target_count[channel]);251		break;252	case hwmon_fan_enable:253		fan_config = data->fan_config[channel];254		if (val == 0) {255			fan_config &= ~MAX31790_FAN_CFG_TACH_INPUT_EN;256		} else if (val == 1) {257			fan_config |= MAX31790_FAN_CFG_TACH_INPUT_EN;258		} else {259			err = -EINVAL;260			break;261		}262		if (fan_config != data->fan_config[channel]) {263			err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel),264							fan_config);265			if (!err)266				data->fan_config[channel] = fan_config;267		}268		break;269	default:270		err = -EOPNOTSUPP;271		break;272	}273 274	mutex_unlock(&data->update_lock);275 276	return err;277}278 279static umode_t max31790_fan_is_visible(const void *_data, u32 attr, int channel)280{281	const struct max31790_data *data = _data;282	u8 fan_config = data->fan_config[channel % NR_CHANNEL];283 284	switch (attr) {285	case hwmon_fan_input:286	case hwmon_fan_fault:287		if (channel < NR_CHANNEL ||288		    (fan_config & MAX31790_FAN_CFG_TACH_INPUT))289			return 0444;290		return 0;291	case hwmon_fan_target:292		if (channel < NR_CHANNEL &&293		    !(fan_config & MAX31790_FAN_CFG_TACH_INPUT))294			return 0644;295		return 0;296	case hwmon_fan_enable:297		if (channel < NR_CHANNEL)298			return 0644;299		return 0;300	default:301		return 0;302	}303}304 305static int max31790_read_pwm(struct device *dev, u32 attr, int channel,306			     long *val)307{308	struct max31790_data *data = max31790_update_device(dev);309	u8 fan_config;310 311	if (IS_ERR(data))312		return PTR_ERR(data);313 314	fan_config = data->fan_config[channel];315 316	switch (attr) {317	case hwmon_pwm_input:318		*val = data->pwm[channel] >> 8;319		return 0;320	case hwmon_pwm_enable:321		if (fan_config & MAX31790_FAN_CFG_CTRL_MON)322			*val = 0;323		else if (fan_config & MAX31790_FAN_CFG_RPM_MODE)324			*val = 2;325		else326			*val = 1;327		return 0;328	default:329		return -EOPNOTSUPP;330	}331}332 333static int max31790_write_pwm(struct device *dev, u32 attr, int channel,334			      long val)335{336	struct max31790_data *data = dev_get_drvdata(dev);337	struct i2c_client *client = data->client;338	u8 fan_config;339	int err = 0;340 341	mutex_lock(&data->update_lock);342 343	switch (attr) {344	case hwmon_pwm_input:345		if (val < 0 || val > 255) {346			err = -EINVAL;347			break;348		}349 350		val = DIV_ROUND_CLOSEST(val * MAX31790_REG_PWMOUT_SCALE,351					PWM_INPUT_SCALE);352		data->valid = false;353		err = i2c_smbus_write_word_swapped(client,354						   MAX31790_REG_PWMOUT(channel),355						   val << 7);356		break;357	case hwmon_pwm_enable:358		fan_config = data->fan_config[channel];359		if (val == 0) {360			fan_config |= MAX31790_FAN_CFG_CTRL_MON;361			/*362			 * Disable RPM mode; otherwise disabling fan speed363			 * monitoring is not possible.364			 */365			fan_config &= ~MAX31790_FAN_CFG_RPM_MODE;366		} else if (val == 1) {367			fan_config &= ~(MAX31790_FAN_CFG_CTRL_MON | MAX31790_FAN_CFG_RPM_MODE);368		} else if (val == 2) {369			fan_config &= ~MAX31790_FAN_CFG_CTRL_MON;370			/*371			 * The chip sets MAX31790_FAN_CFG_TACH_INPUT_EN on its372			 * own if MAX31790_FAN_CFG_RPM_MODE is set.373			 * Do it here as well to reflect the actual register374			 * value in the cache.375			 */376			fan_config |= (MAX31790_FAN_CFG_RPM_MODE | MAX31790_FAN_CFG_TACH_INPUT_EN);377		} else {378			err = -EINVAL;379			break;380		}381		if (fan_config != data->fan_config[channel]) {382			err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel),383							fan_config);384			if (!err)385				data->fan_config[channel] = fan_config;386		}387		break;388	default:389		err = -EOPNOTSUPP;390		break;391	}392 393	mutex_unlock(&data->update_lock);394 395	return err;396}397 398static umode_t max31790_pwm_is_visible(const void *_data, u32 attr, int channel)399{400	const struct max31790_data *data = _data;401	u8 fan_config = data->fan_config[channel];402 403	switch (attr) {404	case hwmon_pwm_input:405	case hwmon_pwm_enable:406		if (!(fan_config & MAX31790_FAN_CFG_TACH_INPUT))407			return 0644;408		return 0;409	default:410		return 0;411	}412}413 414static int max31790_read(struct device *dev, enum hwmon_sensor_types type,415			 u32 attr, int channel, long *val)416{417	switch (type) {418	case hwmon_fan:419		return max31790_read_fan(dev, attr, channel, val);420	case hwmon_pwm:421		return max31790_read_pwm(dev, attr, channel, val);422	default:423		return -EOPNOTSUPP;424	}425}426 427static int max31790_write(struct device *dev, enum hwmon_sensor_types type,428			  u32 attr, int channel, long val)429{430	switch (type) {431	case hwmon_fan:432		return max31790_write_fan(dev, attr, channel, val);433	case hwmon_pwm:434		return max31790_write_pwm(dev, attr, channel, val);435	default:436		return -EOPNOTSUPP;437	}438}439 440static umode_t max31790_is_visible(const void *data,441				   enum hwmon_sensor_types type,442				   u32 attr, int channel)443{444	switch (type) {445	case hwmon_fan:446		return max31790_fan_is_visible(data, attr, channel);447	case hwmon_pwm:448		return max31790_pwm_is_visible(data, attr, channel);449	default:450		return 0;451	}452}453 454static const struct hwmon_channel_info * const max31790_info[] = {455	HWMON_CHANNEL_INFO(fan,456			   HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE,457			   HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE,458			   HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE,459			   HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE,460			   HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE,461			   HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE,462			   HWMON_F_INPUT | HWMON_F_FAULT,463			   HWMON_F_INPUT | HWMON_F_FAULT,464			   HWMON_F_INPUT | HWMON_F_FAULT,465			   HWMON_F_INPUT | HWMON_F_FAULT,466			   HWMON_F_INPUT | HWMON_F_FAULT,467			   HWMON_F_INPUT | HWMON_F_FAULT),468	HWMON_CHANNEL_INFO(pwm,469			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,470			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,471			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,472			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,473			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,474			   HWMON_PWM_INPUT | HWMON_PWM_ENABLE),475	NULL476};477 478static const struct hwmon_ops max31790_hwmon_ops = {479	.is_visible = max31790_is_visible,480	.read = max31790_read,481	.write = max31790_write,482};483 484static const struct hwmon_chip_info max31790_chip_info = {485	.ops = &max31790_hwmon_ops,486	.info = max31790_info,487};488 489static int max31790_init_client(struct i2c_client *client,490				struct max31790_data *data)491{492	int i, rv;493 494	for (i = 0; i < NR_CHANNEL; i++) {495		rv = i2c_smbus_read_byte_data(client,496				MAX31790_REG_FAN_CONFIG(i));497		if (rv < 0)498			return rv;499		data->fan_config[i] = rv;500 501		rv = i2c_smbus_read_byte_data(client,502				MAX31790_REG_FAN_DYNAMICS(i));503		if (rv < 0)504			return rv;505		data->fan_dynamics[i] = rv;506	}507 508	return 0;509}510 511static int max31790_probe(struct i2c_client *client)512{513	struct i2c_adapter *adapter = client->adapter;514	struct device *dev = &client->dev;515	struct max31790_data *data;516	struct device *hwmon_dev;517	int err;518 519	if (!i2c_check_functionality(adapter,520			I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))521		return -ENODEV;522 523	data = devm_kzalloc(dev, sizeof(struct max31790_data), GFP_KERNEL);524	if (!data)525		return -ENOMEM;526 527	data->client = client;528	mutex_init(&data->update_lock);529 530	/*531	 * Initialize the max31790 chip532	 */533	err = max31790_init_client(client, data);534	if (err)535		return err;536 537	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,538							 data,539							 &max31790_chip_info,540							 NULL);541 542	return PTR_ERR_OR_ZERO(hwmon_dev);543}544 545static const struct i2c_device_id max31790_id[] = {546	{ "max31790" },547	{ }548};549MODULE_DEVICE_TABLE(i2c, max31790_id);550 551static struct i2c_driver max31790_driver = {552	.probe		= max31790_probe,553	.driver = {554		.name	= "max31790",555	},556	.id_table	= max31790_id,557};558 559module_i2c_driver(max31790_driver);560 561MODULE_AUTHOR("Il Han <corone.il.han@gmail.com>");562MODULE_DESCRIPTION("MAX31790 sensor driver");563MODULE_LICENSE("GPL");564