cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

max6620.c (11626B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Hardware monitoring driver for Maxim MAX6620
      4 *
      5 * Originally from L. Grunenberg.
      6 * (C) 2012 by L. Grunenberg <contact@lgrunenberg.de>
      7 *
      8 * Copyright (c) 2021 Dell Inc. or its subsidiaries. All Rights Reserved.
      9 *
     10 * based on code written by :
     11 * 2007 by Hans J. Koch <hjk@hansjkoch.de>
     12 * John Morris <john.morris@spirentcom.com>
     13 * Copyright (c) 2003 Spirent Communications
     14 * and Claus Gindhart <claus.gindhart@kontron.com>
     15 *
     16 * This module has only been tested with the MAX6620 chip.
     17 *
     18 * The datasheet was last seen at:
     19 *
     20 *        http://pdfserv.maxim-ic.com/en/ds/MAX6620.pdf
     21 *
     22 */
     23
     24#include <linux/bits.h>
     25#include <linux/err.h>
     26#include <linux/hwmon.h>
     27#include <linux/i2c.h>
     28#include <linux/init.h>
     29#include <linux/jiffies.h>
     30#include <linux/module.h>
     31#include <linux/slab.h>
     32
     33/*
     34 * MAX 6620 registers
     35 */
     36
     37#define MAX6620_REG_CONFIG	0x00
     38#define MAX6620_REG_FAULT	0x01
     39#define MAX6620_REG_CONF_FAN0	0x02
     40#define MAX6620_REG_CONF_FAN1	0x03
     41#define MAX6620_REG_CONF_FAN2	0x04
     42#define MAX6620_REG_CONF_FAN3	0x05
     43#define MAX6620_REG_DYN_FAN0	0x06
     44#define MAX6620_REG_DYN_FAN1	0x07
     45#define MAX6620_REG_DYN_FAN2	0x08
     46#define MAX6620_REG_DYN_FAN3	0x09
     47#define MAX6620_REG_TACH0	0x10
     48#define MAX6620_REG_TACH1	0x12
     49#define MAX6620_REG_TACH2	0x14
     50#define MAX6620_REG_TACH3	0x16
     51#define MAX6620_REG_VOLT0	0x18
     52#define MAX6620_REG_VOLT1	0x1A
     53#define MAX6620_REG_VOLT2	0x1C
     54#define MAX6620_REG_VOLT3	0x1E
     55#define MAX6620_REG_TAR0	0x20
     56#define MAX6620_REG_TAR1	0x22
     57#define MAX6620_REG_TAR2	0x24
     58#define MAX6620_REG_TAR3	0x26
     59#define MAX6620_REG_DAC0	0x28
     60#define MAX6620_REG_DAC1	0x2A
     61#define MAX6620_REG_DAC2	0x2C
     62#define MAX6620_REG_DAC3	0x2E
     63
     64/*
     65 * Config register bits
     66 */
     67
     68#define MAX6620_CFG_RUN		BIT(7)
     69#define MAX6620_CFG_POR		BIT(6)
     70#define MAX6620_CFG_TIMEOUT	BIT(5)
     71#define MAX6620_CFG_FULLFAN	BIT(4)
     72#define MAX6620_CFG_OSC		BIT(3)
     73#define MAX6620_CFG_WD_MASK	(BIT(2) | BIT(1))
     74#define MAX6620_CFG_WD_2	BIT(1)
     75#define MAX6620_CFG_WD_6	BIT(2)
     76#define MAX6620_CFG_WD10	(BIT(2) | BIT(1))
     77#define MAX6620_CFG_WD		BIT(0)
     78
     79/*
     80 * Failure status register bits
     81 */
     82
     83#define MAX6620_FAIL_TACH0	BIT(4)
     84#define MAX6620_FAIL_TACH1	BIT(5)
     85#define MAX6620_FAIL_TACH2	BIT(6)
     86#define MAX6620_FAIL_TACH3	BIT(7)
     87#define MAX6620_FAIL_MASK0	BIT(0)
     88#define MAX6620_FAIL_MASK1	BIT(1)
     89#define MAX6620_FAIL_MASK2	BIT(2)
     90#define MAX6620_FAIL_MASK3	BIT(3)
     91
     92#define MAX6620_CLOCK_FREQ	8192 /* Clock frequency in Hz */
     93#define MAX6620_PULSE_PER_REV	2 /* Tachometer pulses per revolution */
     94
     95/* Minimum and maximum values of the FAN-RPM */
     96#define FAN_RPM_MIN	240
     97#define FAN_RPM_MAX	30000
     98
     99static const u8 config_reg[] = {
    100	MAX6620_REG_CONF_FAN0,
    101	MAX6620_REG_CONF_FAN1,
    102	MAX6620_REG_CONF_FAN2,
    103	MAX6620_REG_CONF_FAN3,
    104};
    105
    106static const u8 dyn_reg[] = {
    107	MAX6620_REG_DYN_FAN0,
    108	MAX6620_REG_DYN_FAN1,
    109	MAX6620_REG_DYN_FAN2,
    110	MAX6620_REG_DYN_FAN3,
    111};
    112
    113static const u8 tach_reg[] = {
    114	MAX6620_REG_TACH0,
    115	MAX6620_REG_TACH1,
    116	MAX6620_REG_TACH2,
    117	MAX6620_REG_TACH3,
    118};
    119
    120static const u8 target_reg[] = {
    121	MAX6620_REG_TAR0,
    122	MAX6620_REG_TAR1,
    123	MAX6620_REG_TAR2,
    124	MAX6620_REG_TAR3,
    125};
    126
    127/*
    128 * Client data (each client gets its own)
    129 */
    130
    131struct max6620_data {
    132	struct i2c_client *client;
    133	struct mutex update_lock;
    134	bool valid; /* false until following fields are valid */
    135	unsigned long last_updated; /* in jiffies */
    136
    137	/* register values */
    138	u8 fancfg[4];
    139	u8 fandyn[4];
    140	u8 fault;
    141	u16 tach[4];
    142	u16 target[4];
    143};
    144
    145static u8 max6620_fan_div_from_reg(u8 val)
    146{
    147	return BIT((val & 0xE0) >> 5);
    148}
    149
    150static u16 max6620_fan_rpm_to_tach(u8 div, int rpm)
    151{
    152	return (60 * div * MAX6620_CLOCK_FREQ) / (rpm * MAX6620_PULSE_PER_REV);
    153}
    154
    155static int max6620_fan_tach_to_rpm(u8 div, u16 tach)
    156{
    157	return (60 * div * MAX6620_CLOCK_FREQ) / (tach * MAX6620_PULSE_PER_REV);
    158}
    159
    160static int max6620_update_device(struct device *dev)
    161{
    162	struct max6620_data *data = dev_get_drvdata(dev);
    163	struct i2c_client *client = data->client;
    164	int i;
    165	int ret = 0;
    166
    167	mutex_lock(&data->update_lock);
    168
    169	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
    170		for (i = 0; i < 4; i++) {
    171			ret = i2c_smbus_read_byte_data(client, config_reg[i]);
    172			if (ret < 0)
    173				goto error;
    174			data->fancfg[i] = ret;
    175
    176			ret = i2c_smbus_read_byte_data(client, dyn_reg[i]);
    177			if (ret < 0)
    178				goto error;
    179			data->fandyn[i] = ret;
    180
    181			ret = i2c_smbus_read_byte_data(client, tach_reg[i]);
    182			if (ret < 0)
    183				goto error;
    184			data->tach[i] = (ret << 3) & 0x7f8;
    185			ret = i2c_smbus_read_byte_data(client, tach_reg[i] + 1);
    186			if (ret < 0)
    187				goto error;
    188			data->tach[i] |= (ret >> 5) & 0x7;
    189
    190			ret = i2c_smbus_read_byte_data(client, target_reg[i]);
    191			if (ret < 0)
    192				goto error;
    193			data->target[i] = (ret << 3) & 0x7f8;
    194			ret = i2c_smbus_read_byte_data(client, target_reg[i] + 1);
    195			if (ret < 0)
    196				goto error;
    197			data->target[i] |= (ret >> 5) & 0x7;
    198		}
    199
    200		/*
    201		 * Alarms are cleared on read in case the condition that
    202		 * caused the alarm is removed. Keep the value latched here
    203		 * for providing the register through different alarm files.
    204		 */
    205		ret = i2c_smbus_read_byte_data(client, MAX6620_REG_FAULT);
    206		if (ret < 0)
    207			goto error;
    208		data->fault |= (ret >> 4) & (ret & 0x0F);
    209
    210		data->last_updated = jiffies;
    211		data->valid = true;
    212	}
    213
    214error:
    215	mutex_unlock(&data->update_lock);
    216	return ret;
    217}
    218
    219static umode_t
    220max6620_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
    221		   int channel)
    222{
    223	switch (type) {
    224	case hwmon_fan:
    225		switch (attr) {
    226		case hwmon_fan_alarm:
    227		case hwmon_fan_input:
    228			return 0444;
    229		case hwmon_fan_div:
    230		case hwmon_fan_target:
    231			return 0644;
    232		default:
    233			break;
    234		}
    235		break;
    236	default:
    237		break;
    238	}
    239
    240	return 0;
    241}
    242
    243static int
    244max6620_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
    245	     int channel, long *val)
    246{
    247	struct max6620_data *data;
    248	struct i2c_client *client;
    249	int ret;
    250	u8 div;
    251	u8 val1;
    252	u8 val2;
    253
    254	ret = max6620_update_device(dev);
    255	if (ret < 0)
    256		return ret;
    257	data = dev_get_drvdata(dev);
    258	client = data->client;
    259
    260	switch (type) {
    261	case hwmon_fan:
    262		switch (attr) {
    263		case hwmon_fan_alarm:
    264			mutex_lock(&data->update_lock);
    265			*val = !!(data->fault & BIT(channel));
    266
    267			/* Setting TACH count to re-enable fan fault detection */
    268			if (*val == 1) {
    269				val1 = (data->target[channel] >> 3) & 0xff;
    270				val2 = (data->target[channel] << 5) & 0xe0;
    271				ret = i2c_smbus_write_byte_data(client,
    272								target_reg[channel], val1);
    273				if (ret < 0) {
    274					mutex_unlock(&data->update_lock);
    275					return ret;
    276				}
    277				ret = i2c_smbus_write_byte_data(client,
    278								target_reg[channel] + 1, val2);
    279				if (ret < 0) {
    280					mutex_unlock(&data->update_lock);
    281					return ret;
    282				}
    283
    284				data->fault &= ~BIT(channel);
    285			}
    286			mutex_unlock(&data->update_lock);
    287
    288			break;
    289		case hwmon_fan_div:
    290			*val = max6620_fan_div_from_reg(data->fandyn[channel]);
    291			break;
    292		case hwmon_fan_input:
    293			if (data->tach[channel] == 0) {
    294				*val = 0;
    295			} else {
    296				div = max6620_fan_div_from_reg(data->fandyn[channel]);
    297				*val = max6620_fan_tach_to_rpm(div, data->tach[channel]);
    298			}
    299			break;
    300		case hwmon_fan_target:
    301			if (data->target[channel] == 0) {
    302				*val = 0;
    303			} else {
    304				div = max6620_fan_div_from_reg(data->fandyn[channel]);
    305				*val = max6620_fan_tach_to_rpm(div, data->target[channel]);
    306			}
    307			break;
    308		default:
    309			return -EOPNOTSUPP;
    310		}
    311		break;
    312
    313	default:
    314		return -EOPNOTSUPP;
    315	}
    316
    317	return 0;
    318}
    319
    320static int
    321max6620_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
    322	      int channel, long val)
    323{
    324	struct max6620_data *data;
    325	struct i2c_client *client;
    326	int ret;
    327	u8 div;
    328	u16 tach;
    329	u8 val1;
    330	u8 val2;
    331
    332	ret = max6620_update_device(dev);
    333	if (ret < 0)
    334		return ret;
    335	data = dev_get_drvdata(dev);
    336	client = data->client;
    337	mutex_lock(&data->update_lock);
    338
    339	switch (type) {
    340	case hwmon_fan:
    341		switch (attr) {
    342		case hwmon_fan_div:
    343			switch (val) {
    344			case 1:
    345				div = 0;
    346				break;
    347			case 2:
    348				div = 1;
    349				break;
    350			case 4:
    351				div = 2;
    352				break;
    353			case 8:
    354				div = 3;
    355				break;
    356			case 16:
    357				div = 4;
    358				break;
    359			case 32:
    360				div = 5;
    361				break;
    362			default:
    363				ret = -EINVAL;
    364				goto error;
    365			}
    366			data->fandyn[channel] &= 0x1F;
    367			data->fandyn[channel] |= div << 5;
    368			ret = i2c_smbus_write_byte_data(client, dyn_reg[channel],
    369							data->fandyn[channel]);
    370			break;
    371		case hwmon_fan_target:
    372			val = clamp_val(val, FAN_RPM_MIN, FAN_RPM_MAX);
    373			div = max6620_fan_div_from_reg(data->fandyn[channel]);
    374			tach = max6620_fan_rpm_to_tach(div, val);
    375			val1 = (tach >> 3) & 0xff;
    376			val2 = (tach << 5) & 0xe0;
    377			ret = i2c_smbus_write_byte_data(client, target_reg[channel], val1);
    378			if (ret < 0)
    379				break;
    380			ret = i2c_smbus_write_byte_data(client, target_reg[channel] + 1, val2);
    381			if (ret < 0)
    382				break;
    383
    384			/* Setting TACH count re-enables fan fault detection */
    385			data->fault &= ~BIT(channel);
    386
    387			break;
    388		default:
    389			ret = -EOPNOTSUPP;
    390			break;
    391		}
    392		break;
    393
    394	default:
    395		ret = -EOPNOTSUPP;
    396		break;
    397	}
    398
    399error:
    400	mutex_unlock(&data->update_lock);
    401	return ret;
    402}
    403
    404static const struct hwmon_channel_info *max6620_info[] = {
    405	HWMON_CHANNEL_INFO(fan,
    406			   HWMON_F_INPUT | HWMON_F_DIV | HWMON_F_TARGET | HWMON_F_ALARM,
    407			   HWMON_F_INPUT | HWMON_F_DIV | HWMON_F_TARGET | HWMON_F_ALARM,
    408			   HWMON_F_INPUT | HWMON_F_DIV | HWMON_F_TARGET | HWMON_F_ALARM,
    409			   HWMON_F_INPUT | HWMON_F_DIV | HWMON_F_TARGET | HWMON_F_ALARM),
    410	NULL
    411};
    412
    413static const struct hwmon_ops max6620_hwmon_ops = {
    414	.read = max6620_read,
    415	.write = max6620_write,
    416	.is_visible = max6620_is_visible,
    417};
    418
    419static const struct hwmon_chip_info max6620_chip_info = {
    420	.ops = &max6620_hwmon_ops,
    421	.info = max6620_info,
    422};
    423
    424static int max6620_init_client(struct max6620_data *data)
    425{
    426	struct i2c_client *client = data->client;
    427	int config;
    428	int err;
    429	int i;
    430	int reg;
    431
    432	config = i2c_smbus_read_byte_data(client, MAX6620_REG_CONFIG);
    433	if (config < 0) {
    434		dev_err(&client->dev, "Error reading config, aborting.\n");
    435		return config;
    436	}
    437
    438	/*
    439	 * Set bit 4, disable other fans from going full speed on a fail
    440	 * failure.
    441	 */
    442	err = i2c_smbus_write_byte_data(client, MAX6620_REG_CONFIG, config | 0x10);
    443	if (err < 0) {
    444		dev_err(&client->dev, "Config write error, aborting.\n");
    445		return err;
    446	}
    447
    448	for (i = 0; i < 4; i++) {
    449		reg = i2c_smbus_read_byte_data(client, config_reg[i]);
    450		if (reg < 0)
    451			return reg;
    452		data->fancfg[i] = reg;
    453
    454		/* Enable RPM mode */
    455		data->fancfg[i] |= 0xa8;
    456		err = i2c_smbus_write_byte_data(client, config_reg[i], data->fancfg[i]);
    457		if (err < 0)
    458			return err;
    459
    460		/* 2 counts (001) and Rate change 100 (0.125 secs) */
    461		data->fandyn[i] = 0x30;
    462		err = i2c_smbus_write_byte_data(client, dyn_reg[i], data->fandyn[i]);
    463		if (err < 0)
    464			return err;
    465	}
    466	return 0;
    467}
    468
    469static int max6620_probe(struct i2c_client *client)
    470{
    471	struct device *dev = &client->dev;
    472	struct max6620_data *data;
    473	struct device *hwmon_dev;
    474	int err;
    475
    476	data = devm_kzalloc(dev, sizeof(struct max6620_data), GFP_KERNEL);
    477	if (!data)
    478		return -ENOMEM;
    479
    480	data->client = client;
    481	mutex_init(&data->update_lock);
    482
    483	err = max6620_init_client(data);
    484	if (err)
    485		return err;
    486
    487	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
    488							 data,
    489							 &max6620_chip_info,
    490							 NULL);
    491
    492	return PTR_ERR_OR_ZERO(hwmon_dev);
    493}
    494
    495static const struct i2c_device_id max6620_id[] = {
    496	{ "max6620", 0 },
    497	{ }
    498};
    499MODULE_DEVICE_TABLE(i2c, max6620_id);
    500
    501static struct i2c_driver max6620_driver = {
    502	.class		= I2C_CLASS_HWMON,
    503	.driver = {
    504		.name	= "max6620",
    505	},
    506	.probe_new	= max6620_probe,
    507	.id_table	= max6620_id,
    508};
    509
    510module_i2c_driver(max6620_driver);
    511
    512MODULE_AUTHOR("Lucas Grunenberg");
    513MODULE_DESCRIPTION("MAX6620 sensor driver");
    514MODULE_LICENSE("GPL");