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

smsc47m192.c (20319B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * smsc47m192.c - Support for hardware monitoring block of
      4 *		  SMSC LPC47M192 and compatible Super I/O chips
      5 *
      6 * Copyright (C) 2006  Hartmut Rick <linux@rick.claranet.de>
      7 *
      8 * Derived from lm78.c and other chip drivers.
      9 */
     10
     11#include <linux/module.h>
     12#include <linux/init.h>
     13#include <linux/slab.h>
     14#include <linux/jiffies.h>
     15#include <linux/i2c.h>
     16#include <linux/hwmon.h>
     17#include <linux/hwmon-sysfs.h>
     18#include <linux/hwmon-vid.h>
     19#include <linux/err.h>
     20#include <linux/sysfs.h>
     21#include <linux/mutex.h>
     22
     23/* Addresses to scan */
     24static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
     25
     26/* SMSC47M192 registers */
     27#define SMSC47M192_REG_IN(nr)		((nr) < 6 ? (0x20 + (nr)) : \
     28					(0x50 + (nr) - 6))
     29#define SMSC47M192_REG_IN_MAX(nr)	((nr) < 6 ? (0x2b + (nr) * 2) : \
     30					(0x54 + (((nr) - 6) * 2)))
     31#define SMSC47M192_REG_IN_MIN(nr)	((nr) < 6 ? (0x2c + (nr) * 2) : \
     32					(0x55 + (((nr) - 6) * 2)))
     33static u8 SMSC47M192_REG_TEMP[3] =	{ 0x27, 0x26, 0x52 };
     34static u8 SMSC47M192_REG_TEMP_MAX[3] =	{ 0x39, 0x37, 0x58 };
     35static u8 SMSC47M192_REG_TEMP_MIN[3] =	{ 0x3A, 0x38, 0x59 };
     36#define SMSC47M192_REG_TEMP_OFFSET(nr)	((nr) == 2 ? 0x1e : 0x1f)
     37#define SMSC47M192_REG_ALARM1		0x41
     38#define SMSC47M192_REG_ALARM2		0x42
     39#define SMSC47M192_REG_VID		0x47
     40#define SMSC47M192_REG_VID4		0x49
     41#define SMSC47M192_REG_CONFIG		0x40
     42#define SMSC47M192_REG_SFR		0x4f
     43#define SMSC47M192_REG_COMPANY_ID	0x3e
     44#define SMSC47M192_REG_VERSION		0x3f
     45
     46/* generalised scaling with integer rounding */
     47static inline int SCALE(long val, int mul, int div)
     48{
     49	if (val < 0)
     50		return (val * mul - div / 2) / div;
     51	else
     52		return (val * mul + div / 2) / div;
     53}
     54
     55/* Conversions */
     56
     57/* smsc47m192 internally scales voltage measurements */
     58static const u16 nom_mv[] = { 2500, 2250, 3300, 5000, 12000, 3300, 1500, 1800 };
     59
     60static inline unsigned int IN_FROM_REG(u8 reg, int n)
     61{
     62	return SCALE(reg, nom_mv[n], 192);
     63}
     64
     65static inline u8 IN_TO_REG(unsigned long val, int n)
     66{
     67	val = clamp_val(val, 0, nom_mv[n] * 255 / 192);
     68	return SCALE(val, 192, nom_mv[n]);
     69}
     70
     71/*
     72 * TEMP: 0.001 degC units (-128C to +127C)
     73 * REG: 1C/bit, two's complement
     74 */
     75static inline s8 TEMP_TO_REG(long val)
     76{
     77	return SCALE(clamp_val(val, -128000, 127000), 1, 1000);
     78}
     79
     80static inline int TEMP_FROM_REG(s8 val)
     81{
     82	return val * 1000;
     83}
     84
     85struct smsc47m192_data {
     86	struct i2c_client *client;
     87	const struct attribute_group *groups[3];
     88	struct mutex update_lock;
     89	bool valid;		/* true if following fields are valid */
     90	unsigned long last_updated;	/* In jiffies */
     91
     92	u8 in[8];		/* Register value */
     93	u8 in_max[8];		/* Register value */
     94	u8 in_min[8];		/* Register value */
     95	s8 temp[3];		/* Register value */
     96	s8 temp_max[3];		/* Register value */
     97	s8 temp_min[3];		/* Register value */
     98	s8 temp_offset[3];	/* Register value */
     99	u16 alarms;		/* Register encoding, combined */
    100	u8 vid;			/* Register encoding, combined */
    101	u8 vrm;
    102};
    103
    104static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
    105{
    106	struct smsc47m192_data *data = dev_get_drvdata(dev);
    107	struct i2c_client *client = data->client;
    108	int i, config;
    109
    110	mutex_lock(&data->update_lock);
    111
    112	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
    113	 || !data->valid) {
    114		u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
    115
    116		dev_dbg(&client->dev, "Starting smsc47m192 update\n");
    117
    118		for (i = 0; i <= 7; i++) {
    119			data->in[i] = i2c_smbus_read_byte_data(client,
    120						SMSC47M192_REG_IN(i));
    121			data->in_min[i] = i2c_smbus_read_byte_data(client,
    122						SMSC47M192_REG_IN_MIN(i));
    123			data->in_max[i] = i2c_smbus_read_byte_data(client,
    124						SMSC47M192_REG_IN_MAX(i));
    125		}
    126		for (i = 0; i < 3; i++) {
    127			data->temp[i] = i2c_smbus_read_byte_data(client,
    128						SMSC47M192_REG_TEMP[i]);
    129			data->temp_max[i] = i2c_smbus_read_byte_data(client,
    130						SMSC47M192_REG_TEMP_MAX[i]);
    131			data->temp_min[i] = i2c_smbus_read_byte_data(client,
    132						SMSC47M192_REG_TEMP_MIN[i]);
    133		}
    134		for (i = 1; i < 3; i++)
    135			data->temp_offset[i] = i2c_smbus_read_byte_data(client,
    136						SMSC47M192_REG_TEMP_OFFSET(i));
    137		/*
    138		 * first offset is temp_offset[0] if SFR bit 4 is set,
    139		 * temp_offset[1] otherwise
    140		 */
    141		if (sfr & 0x10) {
    142			data->temp_offset[0] = data->temp_offset[1];
    143			data->temp_offset[1] = 0;
    144		} else
    145			data->temp_offset[0] = 0;
    146
    147		data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID)
    148			    & 0x0f;
    149		config = i2c_smbus_read_byte_data(client,
    150						  SMSC47M192_REG_CONFIG);
    151		if (config & 0x20)
    152			data->vid |= (i2c_smbus_read_byte_data(client,
    153					SMSC47M192_REG_VID4) & 0x01) << 4;
    154		data->alarms = i2c_smbus_read_byte_data(client,
    155						SMSC47M192_REG_ALARM1) |
    156			       (i2c_smbus_read_byte_data(client,
    157						SMSC47M192_REG_ALARM2) << 8);
    158
    159		data->last_updated = jiffies;
    160		data->valid = true;
    161	}
    162
    163	mutex_unlock(&data->update_lock);
    164
    165	return data;
    166}
    167
    168/* Voltages */
    169static ssize_t in_show(struct device *dev, struct device_attribute *attr,
    170		       char *buf)
    171{
    172	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    173	int nr = sensor_attr->index;
    174	struct smsc47m192_data *data = smsc47m192_update_device(dev);
    175	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr));
    176}
    177
    178static ssize_t in_min_show(struct device *dev, struct device_attribute *attr,
    179			   char *buf)
    180{
    181	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    182	int nr = sensor_attr->index;
    183	struct smsc47m192_data *data = smsc47m192_update_device(dev);
    184	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr));
    185}
    186
    187static ssize_t in_max_show(struct device *dev, struct device_attribute *attr,
    188			   char *buf)
    189{
    190	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    191	int nr = sensor_attr->index;
    192	struct smsc47m192_data *data = smsc47m192_update_device(dev);
    193	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr));
    194}
    195
    196static ssize_t in_min_store(struct device *dev, struct device_attribute *attr,
    197			    const char *buf, size_t count)
    198{
    199	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    200	int nr = sensor_attr->index;
    201	struct smsc47m192_data *data = dev_get_drvdata(dev);
    202	struct i2c_client *client = data->client;
    203	unsigned long val;
    204	int err;
    205
    206	err = kstrtoul(buf, 10, &val);
    207	if (err)
    208		return err;
    209
    210	mutex_lock(&data->update_lock);
    211	data->in_min[nr] = IN_TO_REG(val, nr);
    212	i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr),
    213							data->in_min[nr]);
    214	mutex_unlock(&data->update_lock);
    215	return count;
    216}
    217
    218static ssize_t in_max_store(struct device *dev, struct device_attribute *attr,
    219			    const char *buf, size_t count)
    220{
    221	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    222	int nr = sensor_attr->index;
    223	struct smsc47m192_data *data = dev_get_drvdata(dev);
    224	struct i2c_client *client = data->client;
    225	unsigned long val;
    226	int err;
    227
    228	err = kstrtoul(buf, 10, &val);
    229	if (err)
    230		return err;
    231
    232	mutex_lock(&data->update_lock);
    233	data->in_max[nr] = IN_TO_REG(val, nr);
    234	i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr),
    235							data->in_max[nr]);
    236	mutex_unlock(&data->update_lock);
    237	return count;
    238}
    239
    240static SENSOR_DEVICE_ATTR_RO(in0_input, in, 0);
    241static SENSOR_DEVICE_ATTR_RW(in0_min, in_min, 0);
    242static SENSOR_DEVICE_ATTR_RW(in0_max, in_max, 0);
    243static SENSOR_DEVICE_ATTR_RO(in1_input, in, 1);
    244static SENSOR_DEVICE_ATTR_RW(in1_min, in_min, 1);
    245static SENSOR_DEVICE_ATTR_RW(in1_max, in_max, 1);
    246static SENSOR_DEVICE_ATTR_RO(in2_input, in, 2);
    247static SENSOR_DEVICE_ATTR_RW(in2_min, in_min, 2);
    248static SENSOR_DEVICE_ATTR_RW(in2_max, in_max, 2);
    249static SENSOR_DEVICE_ATTR_RO(in3_input, in, 3);
    250static SENSOR_DEVICE_ATTR_RW(in3_min, in_min, 3);
    251static SENSOR_DEVICE_ATTR_RW(in3_max, in_max, 3);
    252static SENSOR_DEVICE_ATTR_RO(in4_input, in, 4);
    253static SENSOR_DEVICE_ATTR_RW(in4_min, in_min, 4);
    254static SENSOR_DEVICE_ATTR_RW(in4_max, in_max, 4);
    255static SENSOR_DEVICE_ATTR_RO(in5_input, in, 5);
    256static SENSOR_DEVICE_ATTR_RW(in5_min, in_min, 5);
    257static SENSOR_DEVICE_ATTR_RW(in5_max, in_max, 5);
    258static SENSOR_DEVICE_ATTR_RO(in6_input, in, 6);
    259static SENSOR_DEVICE_ATTR_RW(in6_min, in_min, 6);
    260static SENSOR_DEVICE_ATTR_RW(in6_max, in_max, 6);
    261static SENSOR_DEVICE_ATTR_RO(in7_input, in, 7);
    262static SENSOR_DEVICE_ATTR_RW(in7_min, in_min, 7);
    263static SENSOR_DEVICE_ATTR_RW(in7_max, in_max, 7);
    264
    265/* Temperatures */
    266static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
    267			 char *buf)
    268{
    269	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    270	int nr = sensor_attr->index;
    271	struct smsc47m192_data *data = smsc47m192_update_device(dev);
    272	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
    273}
    274
    275static ssize_t temp_min_show(struct device *dev,
    276			     struct device_attribute *attr, char *buf)
    277{
    278	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    279	int nr = sensor_attr->index;
    280	struct smsc47m192_data *data = smsc47m192_update_device(dev);
    281	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
    282}
    283
    284static ssize_t temp_max_show(struct device *dev,
    285			     struct device_attribute *attr, char *buf)
    286{
    287	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    288	int nr = sensor_attr->index;
    289	struct smsc47m192_data *data = smsc47m192_update_device(dev);
    290	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
    291}
    292
    293static ssize_t temp_min_store(struct device *dev,
    294			      struct device_attribute *attr, const char *buf,
    295			      size_t count)
    296{
    297	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    298	int nr = sensor_attr->index;
    299	struct smsc47m192_data *data = dev_get_drvdata(dev);
    300	struct i2c_client *client = data->client;
    301	long val;
    302	int err;
    303
    304	err = kstrtol(buf, 10, &val);
    305	if (err)
    306		return err;
    307
    308	mutex_lock(&data->update_lock);
    309	data->temp_min[nr] = TEMP_TO_REG(val);
    310	i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr],
    311						data->temp_min[nr]);
    312	mutex_unlock(&data->update_lock);
    313	return count;
    314}
    315
    316static ssize_t temp_max_store(struct device *dev,
    317			      struct device_attribute *attr, const char *buf,
    318			      size_t count)
    319{
    320	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    321	int nr = sensor_attr->index;
    322	struct smsc47m192_data *data = dev_get_drvdata(dev);
    323	struct i2c_client *client = data->client;
    324	long val;
    325	int err;
    326
    327	err = kstrtol(buf, 10, &val);
    328	if (err)
    329		return err;
    330
    331	mutex_lock(&data->update_lock);
    332	data->temp_max[nr] = TEMP_TO_REG(val);
    333	i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr],
    334						data->temp_max[nr]);
    335	mutex_unlock(&data->update_lock);
    336	return count;
    337}
    338
    339static ssize_t temp_offset_show(struct device *dev,
    340				struct device_attribute *attr, char *buf)
    341{
    342	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    343	int nr = sensor_attr->index;
    344	struct smsc47m192_data *data = smsc47m192_update_device(dev);
    345	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_offset[nr]));
    346}
    347
    348static ssize_t temp_offset_store(struct device *dev,
    349				 struct device_attribute *attr,
    350				 const char *buf, size_t count)
    351{
    352	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    353	int nr = sensor_attr->index;
    354	struct smsc47m192_data *data = dev_get_drvdata(dev);
    355	struct i2c_client *client = data->client;
    356	u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
    357	long val;
    358	int err;
    359
    360	err = kstrtol(buf, 10, &val);
    361	if (err)
    362		return err;
    363
    364	mutex_lock(&data->update_lock);
    365	data->temp_offset[nr] = TEMP_TO_REG(val);
    366	if (nr > 1)
    367		i2c_smbus_write_byte_data(client,
    368			SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]);
    369	else if (data->temp_offset[nr] != 0) {
    370		/*
    371		 * offset[0] and offset[1] share the same register,
    372		 * SFR bit 4 activates offset[0]
    373		 */
    374		i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR,
    375					(sfr & 0xef) | (nr == 0 ? 0x10 : 0));
    376		data->temp_offset[1-nr] = 0;
    377		i2c_smbus_write_byte_data(client,
    378			SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]);
    379	} else if ((sfr & 0x10) == (nr == 0 ? 0x10 : 0))
    380		i2c_smbus_write_byte_data(client,
    381					SMSC47M192_REG_TEMP_OFFSET(nr), 0);
    382	mutex_unlock(&data->update_lock);
    383	return count;
    384}
    385
    386static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
    387static SENSOR_DEVICE_ATTR_RW(temp1_min, temp_min, 0);
    388static SENSOR_DEVICE_ATTR_RW(temp1_max, temp_max, 0);
    389static SENSOR_DEVICE_ATTR_RW(temp1_offset, temp_offset, 0);
    390static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);
    391static SENSOR_DEVICE_ATTR_RW(temp2_min, temp_min, 1);
    392static SENSOR_DEVICE_ATTR_RW(temp2_max, temp_max, 1);
    393static SENSOR_DEVICE_ATTR_RW(temp2_offset, temp_offset, 1);
    394static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
    395static SENSOR_DEVICE_ATTR_RW(temp3_min, temp_min, 2);
    396static SENSOR_DEVICE_ATTR_RW(temp3_max, temp_max, 2);
    397static SENSOR_DEVICE_ATTR_RW(temp3_offset, temp_offset, 2);
    398
    399/* VID */
    400static ssize_t cpu0_vid_show(struct device *dev,
    401			     struct device_attribute *attr, char *buf)
    402{
    403	struct smsc47m192_data *data = smsc47m192_update_device(dev);
    404	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
    405}
    406static DEVICE_ATTR_RO(cpu0_vid);
    407
    408static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
    409		char *buf)
    410{
    411	struct smsc47m192_data *data = dev_get_drvdata(dev);
    412	return sprintf(buf, "%d\n", data->vrm);
    413}
    414
    415static ssize_t vrm_store(struct device *dev, struct device_attribute *attr,
    416			 const char *buf, size_t count)
    417{
    418	struct smsc47m192_data *data = dev_get_drvdata(dev);
    419	unsigned long val;
    420	int err;
    421
    422	err = kstrtoul(buf, 10, &val);
    423	if (err)
    424		return err;
    425	if (val > 255)
    426		return -EINVAL;
    427
    428	data->vrm = val;
    429	return count;
    430}
    431static DEVICE_ATTR_RW(vrm);
    432
    433/* Alarms */
    434static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,
    435			  char *buf)
    436{
    437	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
    438	int nr = sensor_attr->index;
    439	struct smsc47m192_data *data = smsc47m192_update_device(dev);
    440	return sprintf(buf, "%u\n", (data->alarms & nr) ? 1 : 0);
    441}
    442
    443static SENSOR_DEVICE_ATTR_RO(temp1_alarm, alarm, 0x0010);
    444static SENSOR_DEVICE_ATTR_RO(temp2_alarm, alarm, 0x0020);
    445static SENSOR_DEVICE_ATTR_RO(temp3_alarm, alarm, 0x0040);
    446static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 0x4000);
    447static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, 0x8000);
    448static SENSOR_DEVICE_ATTR_RO(in0_alarm, alarm, 0x0001);
    449static SENSOR_DEVICE_ATTR_RO(in1_alarm, alarm, 0x0002);
    450static SENSOR_DEVICE_ATTR_RO(in2_alarm, alarm, 0x0004);
    451static SENSOR_DEVICE_ATTR_RO(in3_alarm, alarm, 0x0008);
    452static SENSOR_DEVICE_ATTR_RO(in4_alarm, alarm, 0x0100);
    453static SENSOR_DEVICE_ATTR_RO(in5_alarm, alarm, 0x0200);
    454static SENSOR_DEVICE_ATTR_RO(in6_alarm, alarm, 0x0400);
    455static SENSOR_DEVICE_ATTR_RO(in7_alarm, alarm, 0x0800);
    456
    457static struct attribute *smsc47m192_attributes[] = {
    458	&sensor_dev_attr_in0_input.dev_attr.attr,
    459	&sensor_dev_attr_in0_min.dev_attr.attr,
    460	&sensor_dev_attr_in0_max.dev_attr.attr,
    461	&sensor_dev_attr_in0_alarm.dev_attr.attr,
    462	&sensor_dev_attr_in1_input.dev_attr.attr,
    463	&sensor_dev_attr_in1_min.dev_attr.attr,
    464	&sensor_dev_attr_in1_max.dev_attr.attr,
    465	&sensor_dev_attr_in1_alarm.dev_attr.attr,
    466	&sensor_dev_attr_in2_input.dev_attr.attr,
    467	&sensor_dev_attr_in2_min.dev_attr.attr,
    468	&sensor_dev_attr_in2_max.dev_attr.attr,
    469	&sensor_dev_attr_in2_alarm.dev_attr.attr,
    470	&sensor_dev_attr_in3_input.dev_attr.attr,
    471	&sensor_dev_attr_in3_min.dev_attr.attr,
    472	&sensor_dev_attr_in3_max.dev_attr.attr,
    473	&sensor_dev_attr_in3_alarm.dev_attr.attr,
    474	&sensor_dev_attr_in5_input.dev_attr.attr,
    475	&sensor_dev_attr_in5_min.dev_attr.attr,
    476	&sensor_dev_attr_in5_max.dev_attr.attr,
    477	&sensor_dev_attr_in5_alarm.dev_attr.attr,
    478	&sensor_dev_attr_in6_input.dev_attr.attr,
    479	&sensor_dev_attr_in6_min.dev_attr.attr,
    480	&sensor_dev_attr_in6_max.dev_attr.attr,
    481	&sensor_dev_attr_in6_alarm.dev_attr.attr,
    482	&sensor_dev_attr_in7_input.dev_attr.attr,
    483	&sensor_dev_attr_in7_min.dev_attr.attr,
    484	&sensor_dev_attr_in7_max.dev_attr.attr,
    485	&sensor_dev_attr_in7_alarm.dev_attr.attr,
    486
    487	&sensor_dev_attr_temp1_input.dev_attr.attr,
    488	&sensor_dev_attr_temp1_max.dev_attr.attr,
    489	&sensor_dev_attr_temp1_min.dev_attr.attr,
    490	&sensor_dev_attr_temp1_offset.dev_attr.attr,
    491	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
    492	&sensor_dev_attr_temp2_input.dev_attr.attr,
    493	&sensor_dev_attr_temp2_max.dev_attr.attr,
    494	&sensor_dev_attr_temp2_min.dev_attr.attr,
    495	&sensor_dev_attr_temp2_offset.dev_attr.attr,
    496	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
    497	&sensor_dev_attr_temp2_fault.dev_attr.attr,
    498	&sensor_dev_attr_temp3_input.dev_attr.attr,
    499	&sensor_dev_attr_temp3_max.dev_attr.attr,
    500	&sensor_dev_attr_temp3_min.dev_attr.attr,
    501	&sensor_dev_attr_temp3_offset.dev_attr.attr,
    502	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
    503	&sensor_dev_attr_temp3_fault.dev_attr.attr,
    504
    505	&dev_attr_cpu0_vid.attr,
    506	&dev_attr_vrm.attr,
    507	NULL
    508};
    509
    510static const struct attribute_group smsc47m192_group = {
    511	.attrs = smsc47m192_attributes,
    512};
    513
    514static struct attribute *smsc47m192_attributes_in4[] = {
    515	&sensor_dev_attr_in4_input.dev_attr.attr,
    516	&sensor_dev_attr_in4_min.dev_attr.attr,
    517	&sensor_dev_attr_in4_max.dev_attr.attr,
    518	&sensor_dev_attr_in4_alarm.dev_attr.attr,
    519	NULL
    520};
    521
    522static const struct attribute_group smsc47m192_group_in4 = {
    523	.attrs = smsc47m192_attributes_in4,
    524};
    525
    526static void smsc47m192_init_client(struct i2c_client *client)
    527{
    528	int i;
    529	u8 config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
    530	u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
    531
    532	/* select cycle mode (pause 1 sec between updates) */
    533	i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR,
    534						(sfr & 0xfd) | 0x02);
    535	if (!(config & 0x01)) {
    536		/* initialize alarm limits */
    537		for (i = 0; i < 8; i++) {
    538			i2c_smbus_write_byte_data(client,
    539				SMSC47M192_REG_IN_MIN(i), 0);
    540			i2c_smbus_write_byte_data(client,
    541				SMSC47M192_REG_IN_MAX(i), 0xff);
    542		}
    543		for (i = 0; i < 3; i++) {
    544			i2c_smbus_write_byte_data(client,
    545				SMSC47M192_REG_TEMP_MIN[i], 0x80);
    546			i2c_smbus_write_byte_data(client,
    547				SMSC47M192_REG_TEMP_MAX[i], 0x7f);
    548		}
    549
    550		/* start monitoring */
    551		i2c_smbus_write_byte_data(client, SMSC47M192_REG_CONFIG,
    552						(config & 0xf7) | 0x01);
    553	}
    554}
    555
    556/* Return 0 if detection is successful, -ENODEV otherwise */
    557static int smsc47m192_detect(struct i2c_client *client,
    558			     struct i2c_board_info *info)
    559{
    560	struct i2c_adapter *adapter = client->adapter;
    561	int version;
    562
    563	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
    564		return -ENODEV;
    565
    566	/* Detection criteria from sensors_detect script */
    567	version = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VERSION);
    568	if (i2c_smbus_read_byte_data(client,
    569				SMSC47M192_REG_COMPANY_ID) == 0x55
    570	 && (version & 0xf0) == 0x20
    571	 && (i2c_smbus_read_byte_data(client,
    572				SMSC47M192_REG_VID) & 0x70) == 0x00
    573	 && (i2c_smbus_read_byte_data(client,
    574				SMSC47M192_REG_VID4) & 0xfe) == 0x80) {
    575		dev_info(&adapter->dev,
    576			 "found SMSC47M192 or compatible, "
    577			 "version 2, stepping A%d\n", version & 0x0f);
    578	} else {
    579		dev_dbg(&adapter->dev,
    580			"SMSC47M192 detection failed at 0x%02x\n",
    581			client->addr);
    582		return -ENODEV;
    583	}
    584
    585	strlcpy(info->type, "smsc47m192", I2C_NAME_SIZE);
    586
    587	return 0;
    588}
    589
    590static int smsc47m192_probe(struct i2c_client *client)
    591{
    592	struct device *dev = &client->dev;
    593	struct device *hwmon_dev;
    594	struct smsc47m192_data *data;
    595	int config;
    596
    597	data = devm_kzalloc(dev, sizeof(struct smsc47m192_data), GFP_KERNEL);
    598	if (!data)
    599		return -ENOMEM;
    600
    601	data->client = client;
    602	data->vrm = vid_which_vrm();
    603	mutex_init(&data->update_lock);
    604
    605	/* Initialize the SMSC47M192 chip */
    606	smsc47m192_init_client(client);
    607
    608	/* sysfs hooks */
    609	data->groups[0] = &smsc47m192_group;
    610	/* Pin 110 is either in4 (+12V) or VID4 */
    611	config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
    612	if (!(config & 0x20))
    613		data->groups[1] = &smsc47m192_group_in4;
    614
    615	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
    616							   data, data->groups);
    617	return PTR_ERR_OR_ZERO(hwmon_dev);
    618}
    619
    620static const struct i2c_device_id smsc47m192_id[] = {
    621	{ "smsc47m192", 0 },
    622	{ }
    623};
    624MODULE_DEVICE_TABLE(i2c, smsc47m192_id);
    625
    626static struct i2c_driver smsc47m192_driver = {
    627	.class		= I2C_CLASS_HWMON,
    628	.driver = {
    629		.name	= "smsc47m192",
    630	},
    631	.probe_new	= smsc47m192_probe,
    632	.id_table	= smsc47m192_id,
    633	.detect		= smsc47m192_detect,
    634	.address_list	= normal_i2c,
    635};
    636
    637module_i2c_driver(smsc47m192_driver);
    638
    639MODULE_AUTHOR("Hartmut Rick <linux@rick.claranet.de>");
    640MODULE_DESCRIPTION("SMSC47M192 driver");
    641MODULE_LICENSE("GPL");