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

adm1029.c (10607B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * adm1029.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
      4 *
      5 * Copyright (C) 2006 Corentin LABBE <clabbe.montjoie@gmail.com>
      6 *
      7 * Based on LM83 Driver by Jean Delvare <jdelvare@suse.de>
      8 *
      9 * Give only processor, motherboard temperatures and fan tachs
     10 * Very rare chip please let me know if you use it
     11 *
     12 * http://www.analog.com/UploadedFiles/Data_Sheets/ADM1029.pdf
     13 */
     14
     15#include <linux/module.h>
     16#include <linux/init.h>
     17#include <linux/slab.h>
     18#include <linux/jiffies.h>
     19#include <linux/i2c.h>
     20#include <linux/hwmon-sysfs.h>
     21#include <linux/hwmon.h>
     22#include <linux/err.h>
     23#include <linux/mutex.h>
     24
     25/*
     26 * Addresses to scan
     27 */
     28
     29static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
     30						0x2e, 0x2f, I2C_CLIENT_END
     31};
     32
     33/*
     34 * The ADM1029 registers
     35 * Manufacturer ID is 0x41 for Analog Devices
     36 */
     37
     38#define ADM1029_REG_MAN_ID			0x0D
     39#define ADM1029_REG_CHIP_ID			0x0E
     40#define ADM1029_REG_CONFIG			0x01
     41#define ADM1029_REG_NB_FAN_SUPPORT		0x02
     42
     43#define ADM1029_REG_TEMP_DEVICES_INSTALLED	0x06
     44
     45#define ADM1029_REG_LOCAL_TEMP			0xA0
     46#define ADM1029_REG_REMOTE1_TEMP		0xA1
     47#define ADM1029_REG_REMOTE2_TEMP		0xA2
     48
     49#define ADM1029_REG_LOCAL_TEMP_HIGH		0x90
     50#define ADM1029_REG_REMOTE1_TEMP_HIGH		0x91
     51#define ADM1029_REG_REMOTE2_TEMP_HIGH		0x92
     52
     53#define ADM1029_REG_LOCAL_TEMP_LOW		0x98
     54#define ADM1029_REG_REMOTE1_TEMP_LOW		0x99
     55#define ADM1029_REG_REMOTE2_TEMP_LOW		0x9A
     56
     57#define ADM1029_REG_FAN1			0x70
     58#define ADM1029_REG_FAN2			0x71
     59
     60#define ADM1029_REG_FAN1_MIN			0x78
     61#define ADM1029_REG_FAN2_MIN			0x79
     62
     63#define ADM1029_REG_FAN1_CONFIG			0x68
     64#define ADM1029_REG_FAN2_CONFIG			0x69
     65
     66#define TEMP_FROM_REG(val)	((val) * 1000)
     67
     68#define DIV_FROM_REG(val)	(1 << (((val) >> 6) - 1))
     69
     70/* Registers to be checked by adm1029_update_device() */
     71static const u8 ADM1029_REG_TEMP[] = {
     72	ADM1029_REG_LOCAL_TEMP,
     73	ADM1029_REG_REMOTE1_TEMP,
     74	ADM1029_REG_REMOTE2_TEMP,
     75	ADM1029_REG_LOCAL_TEMP_HIGH,
     76	ADM1029_REG_REMOTE1_TEMP_HIGH,
     77	ADM1029_REG_REMOTE2_TEMP_HIGH,
     78	ADM1029_REG_LOCAL_TEMP_LOW,
     79	ADM1029_REG_REMOTE1_TEMP_LOW,
     80	ADM1029_REG_REMOTE2_TEMP_LOW,
     81};
     82
     83static const u8 ADM1029_REG_FAN[] = {
     84	ADM1029_REG_FAN1,
     85	ADM1029_REG_FAN2,
     86	ADM1029_REG_FAN1_MIN,
     87	ADM1029_REG_FAN2_MIN,
     88};
     89
     90static const u8 ADM1029_REG_FAN_DIV[] = {
     91	ADM1029_REG_FAN1_CONFIG,
     92	ADM1029_REG_FAN2_CONFIG,
     93};
     94
     95/*
     96 * Client data (each client gets its own)
     97 */
     98
     99struct adm1029_data {
    100	struct i2c_client *client;
    101	struct mutex update_lock; /* protect register access */
    102	bool valid;		/* false until following fields are valid */
    103	unsigned long last_updated;	/* in jiffies */
    104
    105	/* registers values, signed for temperature, unsigned for other stuff */
    106	s8 temp[ARRAY_SIZE(ADM1029_REG_TEMP)];
    107	u8 fan[ARRAY_SIZE(ADM1029_REG_FAN)];
    108	u8 fan_div[ARRAY_SIZE(ADM1029_REG_FAN_DIV)];
    109};
    110
    111/*
    112 * function that update the status of the chips (temperature for example)
    113 */
    114static struct adm1029_data *adm1029_update_device(struct device *dev)
    115{
    116	struct adm1029_data *data = dev_get_drvdata(dev);
    117	struct i2c_client *client = data->client;
    118
    119	mutex_lock(&data->update_lock);
    120	/*
    121	 * Use the "cache" Luke, don't recheck values
    122	 * if there are already checked not a long time later
    123	 */
    124	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
    125		int nr;
    126
    127		dev_dbg(&client->dev, "Updating adm1029 data\n");
    128
    129		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_TEMP); nr++) {
    130			data->temp[nr] =
    131			    i2c_smbus_read_byte_data(client,
    132						     ADM1029_REG_TEMP[nr]);
    133		}
    134		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN); nr++) {
    135			data->fan[nr] =
    136			    i2c_smbus_read_byte_data(client,
    137						     ADM1029_REG_FAN[nr]);
    138		}
    139		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN_DIV); nr++) {
    140			data->fan_div[nr] =
    141			    i2c_smbus_read_byte_data(client,
    142						     ADM1029_REG_FAN_DIV[nr]);
    143		}
    144
    145		data->last_updated = jiffies;
    146		data->valid = true;
    147	}
    148
    149	mutex_unlock(&data->update_lock);
    150
    151	return data;
    152}
    153
    154/*
    155 * Sysfs stuff
    156 */
    157
    158static ssize_t
    159temp_show(struct device *dev, struct device_attribute *devattr, char *buf)
    160{
    161	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
    162	struct adm1029_data *data = adm1029_update_device(dev);
    163
    164	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
    165}
    166
    167static ssize_t
    168fan_show(struct device *dev, struct device_attribute *devattr, char *buf)
    169{
    170	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
    171	struct adm1029_data *data = adm1029_update_device(dev);
    172	u16 val;
    173
    174	if (data->fan[attr->index] == 0 ||
    175	    (data->fan_div[attr->index] & 0xC0) == 0 ||
    176	    data->fan[attr->index] == 255) {
    177		return sprintf(buf, "0\n");
    178	}
    179
    180	val = 1880 * 120 / DIV_FROM_REG(data->fan_div[attr->index])
    181	    / data->fan[attr->index];
    182	return sprintf(buf, "%d\n", val);
    183}
    184
    185static ssize_t
    186fan_div_show(struct device *dev, struct device_attribute *devattr, char *buf)
    187{
    188	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
    189	struct adm1029_data *data = adm1029_update_device(dev);
    190
    191	if ((data->fan_div[attr->index] & 0xC0) == 0)
    192		return sprintf(buf, "0\n");
    193	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
    194}
    195
    196static ssize_t fan_div_store(struct device *dev,
    197			     struct device_attribute *devattr,
    198			     const char *buf, size_t count)
    199{
    200	struct adm1029_data *data = dev_get_drvdata(dev);
    201	struct i2c_client *client = data->client;
    202	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
    203	u8 reg;
    204	long val;
    205	int ret = kstrtol(buf, 10, &val);
    206
    207	if (ret < 0)
    208		return ret;
    209
    210	mutex_lock(&data->update_lock);
    211
    212	/*Read actual config */
    213	reg = i2c_smbus_read_byte_data(client,
    214				       ADM1029_REG_FAN_DIV[attr->index]);
    215
    216	switch (val) {
    217	case 1:
    218		val = 1;
    219		break;
    220	case 2:
    221		val = 2;
    222		break;
    223	case 4:
    224		val = 3;
    225		break;
    226	default:
    227		mutex_unlock(&data->update_lock);
    228		dev_err(&client->dev,
    229			"fan_div value %ld not supported. Choose one of 1, 2 or 4!\n",
    230			val);
    231		return -EINVAL;
    232	}
    233	/* Update the value */
    234	reg = (reg & 0x3F) | (val << 6);
    235
    236	/* Update the cache */
    237	data->fan_div[attr->index] = reg;
    238
    239	/* Write value */
    240	i2c_smbus_write_byte_data(client,
    241				  ADM1029_REG_FAN_DIV[attr->index], reg);
    242	mutex_unlock(&data->update_lock);
    243
    244	return count;
    245}
    246
    247/* Access rights on sysfs. */
    248static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
    249static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);
    250static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
    251
    252static SENSOR_DEVICE_ATTR_RO(temp1_max, temp, 3);
    253static SENSOR_DEVICE_ATTR_RO(temp2_max, temp, 4);
    254static SENSOR_DEVICE_ATTR_RO(temp3_max, temp, 5);
    255
    256static SENSOR_DEVICE_ATTR_RO(temp1_min, temp, 6);
    257static SENSOR_DEVICE_ATTR_RO(temp2_min, temp, 7);
    258static SENSOR_DEVICE_ATTR_RO(temp3_min, temp, 8);
    259
    260static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0);
    261static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 1);
    262
    263static SENSOR_DEVICE_ATTR_RO(fan1_min, fan, 2);
    264static SENSOR_DEVICE_ATTR_RO(fan2_min, fan, 3);
    265
    266static SENSOR_DEVICE_ATTR_RW(fan1_div, fan_div, 0);
    267static SENSOR_DEVICE_ATTR_RW(fan2_div, fan_div, 1);
    268
    269static struct attribute *adm1029_attrs[] = {
    270	&sensor_dev_attr_temp1_input.dev_attr.attr,
    271	&sensor_dev_attr_temp1_min.dev_attr.attr,
    272	&sensor_dev_attr_temp1_max.dev_attr.attr,
    273	&sensor_dev_attr_temp2_input.dev_attr.attr,
    274	&sensor_dev_attr_temp2_min.dev_attr.attr,
    275	&sensor_dev_attr_temp2_max.dev_attr.attr,
    276	&sensor_dev_attr_temp3_input.dev_attr.attr,
    277	&sensor_dev_attr_temp3_min.dev_attr.attr,
    278	&sensor_dev_attr_temp3_max.dev_attr.attr,
    279	&sensor_dev_attr_fan1_input.dev_attr.attr,
    280	&sensor_dev_attr_fan2_input.dev_attr.attr,
    281	&sensor_dev_attr_fan1_min.dev_attr.attr,
    282	&sensor_dev_attr_fan2_min.dev_attr.attr,
    283	&sensor_dev_attr_fan1_div.dev_attr.attr,
    284	&sensor_dev_attr_fan2_div.dev_attr.attr,
    285	NULL
    286};
    287
    288ATTRIBUTE_GROUPS(adm1029);
    289
    290/*
    291 * Real code
    292 */
    293
    294/* Return 0 if detection is successful, -ENODEV otherwise */
    295static int adm1029_detect(struct i2c_client *client,
    296			  struct i2c_board_info *info)
    297{
    298	struct i2c_adapter *adapter = client->adapter;
    299	u8 man_id, chip_id, temp_devices_installed, nb_fan_support;
    300
    301	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
    302		return -ENODEV;
    303
    304	/*
    305	 * ADM1029 doesn't have CHIP ID, check just MAN ID
    306	 * For better detection we check also ADM1029_TEMP_DEVICES_INSTALLED,
    307	 * ADM1029_REG_NB_FAN_SUPPORT and compare it with possible values
    308	 * documented
    309	 */
    310
    311	man_id = i2c_smbus_read_byte_data(client, ADM1029_REG_MAN_ID);
    312	chip_id = i2c_smbus_read_byte_data(client, ADM1029_REG_CHIP_ID);
    313	temp_devices_installed = i2c_smbus_read_byte_data(client,
    314					ADM1029_REG_TEMP_DEVICES_INSTALLED);
    315	nb_fan_support = i2c_smbus_read_byte_data(client,
    316						  ADM1029_REG_NB_FAN_SUPPORT);
    317	/* 0x41 is Analog Devices */
    318	if (man_id != 0x41 || (temp_devices_installed & 0xf9) != 0x01 ||
    319	    nb_fan_support != 0x03)
    320		return -ENODEV;
    321
    322	if ((chip_id & 0xF0) != 0x00) {
    323		/*
    324		 * There are no "official" CHIP ID, so actually
    325		 * we use Major/Minor revision for that
    326		 */
    327		pr_info("Unknown major revision %x, please let us know\n",
    328			chip_id);
    329		return -ENODEV;
    330	}
    331
    332	strlcpy(info->type, "adm1029", I2C_NAME_SIZE);
    333
    334	return 0;
    335}
    336
    337static int adm1029_init_client(struct i2c_client *client)
    338{
    339	u8 config;
    340
    341	config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
    342	if ((config & 0x10) == 0) {
    343		i2c_smbus_write_byte_data(client, ADM1029_REG_CONFIG,
    344					  config | 0x10);
    345	}
    346	/* recheck config */
    347	config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
    348	if ((config & 0x10) == 0) {
    349		dev_err(&client->dev, "Initialization failed!\n");
    350		return 0;
    351	}
    352	return 1;
    353}
    354
    355static int adm1029_probe(struct i2c_client *client)
    356{
    357	struct device *dev = &client->dev;
    358	struct adm1029_data *data;
    359	struct device *hwmon_dev;
    360
    361	data = devm_kzalloc(dev, sizeof(struct adm1029_data), GFP_KERNEL);
    362	if (!data)
    363		return -ENOMEM;
    364
    365	data->client = client;
    366	mutex_init(&data->update_lock);
    367
    368	/*
    369	 * Initialize the ADM1029 chip
    370	 * Check config register
    371	 */
    372	if (adm1029_init_client(client) == 0)
    373		return -ENODEV;
    374
    375	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
    376							   data,
    377							   adm1029_groups);
    378	return PTR_ERR_OR_ZERO(hwmon_dev);
    379}
    380
    381static const struct i2c_device_id adm1029_id[] = {
    382	{ "adm1029", 0 },
    383	{ }
    384};
    385MODULE_DEVICE_TABLE(i2c, adm1029_id);
    386
    387static struct i2c_driver adm1029_driver = {
    388	.class		= I2C_CLASS_HWMON,
    389	.driver = {
    390		.name = "adm1029",
    391	},
    392	.probe_new	= adm1029_probe,
    393	.id_table	= adm1029_id,
    394	.detect		= adm1029_detect,
    395	.address_list	= normal_i2c,
    396};
    397
    398module_i2c_driver(adm1029_driver);
    399
    400MODULE_AUTHOR("Corentin LABBE <clabbe.montjoie@gmail.com>");
    401MODULE_DESCRIPTION("adm1029 driver");
    402MODULE_LICENSE("GPL v2");