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