linux/drivers/hwmon/lm92.c
<<
>>
Prefs
   1/*
   2 * lm92 - Hardware monitoring driver
   3 * Copyright (C) 2005-2008  Jean Delvare <khali@linux-fr.org>
   4 *
   5 * Based on the lm90 driver, with some ideas taken from the lm_sensors
   6 * lm92 driver as well.
   7 *
   8 * The LM92 is a sensor chip made by National Semiconductor. It reports
   9 * its own temperature with a 0.0625 deg resolution and a 0.33 deg
  10 * accuracy. Complete datasheet can be obtained from National's website
  11 * at:
  12 *   http://www.national.com/pf/LM/LM92.html
  13 *
  14 * This driver also supports the MAX6635 sensor chip made by Maxim.
  15 * This chip is compatible with the LM92, but has a lesser accuracy
  16 * (1.0 deg). Complete datasheet can be obtained from Maxim's website
  17 * at:
  18 *   http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3074
  19 *
  20 * Since the LM92 was the first chipset supported by this driver, most
  21 * comments will refer to this chipset, but are actually general and
  22 * concern all supported chipsets, unless mentioned otherwise.
  23 *
  24 * Support could easily be added for the National Semiconductor LM76
  25 * and Maxim MAX6633 and MAX6634 chips, which are mostly compatible
  26 * with the LM92.
  27 *
  28 * This program is free software; you can redistribute it and/or modify
  29 * it under the terms of the GNU General Public License as published by
  30 * the Free Software Foundation; either version 2 of the License, or
  31 * (at your option) any later version.
  32 *
  33 * This program is distributed in the hope that it will be useful,
  34 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  36 * GNU General Public License for more details.
  37 *
  38 * You should have received a copy of the GNU General Public License
  39 * along with this program; if not, write to the Free Software
  40 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  41 */
  42
  43#include <linux/module.h>
  44#include <linux/init.h>
  45#include <linux/slab.h>
  46#include <linux/i2c.h>
  47#include <linux/hwmon.h>
  48#include <linux/hwmon-sysfs.h>
  49#include <linux/err.h>
  50#include <linux/mutex.h>
  51
  52/* The LM92 and MAX6635 have 2 two-state pins for address selection,
  53   resulting in 4 possible addresses. */
  54static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
  55                                                I2C_CLIENT_END };
  56
  57/* The LM92 registers */
  58#define LM92_REG_CONFIG                 0x01 /* 8-bit, RW */
  59#define LM92_REG_TEMP                   0x00 /* 16-bit, RO */
  60#define LM92_REG_TEMP_HYST              0x02 /* 16-bit, RW */
  61#define LM92_REG_TEMP_CRIT              0x03 /* 16-bit, RW */
  62#define LM92_REG_TEMP_LOW               0x04 /* 16-bit, RW */
  63#define LM92_REG_TEMP_HIGH              0x05 /* 16-bit, RW */
  64#define LM92_REG_MAN_ID                 0x07 /* 16-bit, RO, LM92 only */
  65
  66/* The LM92 uses signed 13-bit values with LSB = 0.0625 degree Celsius,
  67   left-justified in 16-bit registers. No rounding is done, with such
  68   a resolution it's just not worth it. Note that the MAX6635 doesn't
  69   make use of the 4 lower bits for limits (i.e. effective resolution
  70   for limits is 1 degree Celsius). */
  71static inline int TEMP_FROM_REG(s16 reg)
  72{
  73        return reg / 8 * 625 / 10;
  74}
  75
  76static inline s16 TEMP_TO_REG(int val)
  77{
  78        if (val <= -60000)
  79                return -60000 * 10 / 625 * 8;
  80        if (val >= 160000)
  81                return 160000 * 10 / 625 * 8;
  82        return val * 10 / 625 * 8;
  83}
  84
  85/* Alarm flags are stored in the 3 LSB of the temperature register */
  86static inline u8 ALARMS_FROM_REG(s16 reg)
  87{
  88        return reg & 0x0007;
  89}
  90
  91/* Driver data (common to all clients) */
  92static struct i2c_driver lm92_driver;
  93
  94/* Client data (each client gets its own) */
  95struct lm92_data {
  96        struct device *hwmon_dev;
  97        struct mutex update_lock;
  98        char valid; /* zero until following fields are valid */
  99        unsigned long last_updated; /* in jiffies */
 100
 101        /* registers values */
 102        s16 temp1_input, temp1_crit, temp1_min, temp1_max, temp1_hyst;
 103};
 104
 105
 106/*
 107 * Sysfs attributes and callback functions
 108 */
 109
 110static struct lm92_data *lm92_update_device(struct device *dev)
 111{
 112        struct i2c_client *client = to_i2c_client(dev);
 113        struct lm92_data *data = i2c_get_clientdata(client);
 114
 115        mutex_lock(&data->update_lock);
 116
 117        if (time_after(jiffies, data->last_updated + HZ)
 118         || !data->valid) {
 119                dev_dbg(&client->dev, "Updating lm92 data\n");
 120                data->temp1_input = swab16(i2c_smbus_read_word_data(client,
 121                                    LM92_REG_TEMP));
 122                data->temp1_hyst = swab16(i2c_smbus_read_word_data(client,
 123                                    LM92_REG_TEMP_HYST));
 124                data->temp1_crit = swab16(i2c_smbus_read_word_data(client,
 125                                    LM92_REG_TEMP_CRIT));
 126                data->temp1_min = swab16(i2c_smbus_read_word_data(client,
 127                                    LM92_REG_TEMP_LOW));
 128                data->temp1_max = swab16(i2c_smbus_read_word_data(client,
 129                                    LM92_REG_TEMP_HIGH));
 130
 131                data->last_updated = jiffies;
 132                data->valid = 1;
 133        }
 134
 135        mutex_unlock(&data->update_lock);
 136
 137        return data;
 138}
 139
 140#define show_temp(value) \
 141static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
 142{ \
 143        struct lm92_data *data = lm92_update_device(dev); \
 144        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
 145}
 146show_temp(temp1_input);
 147show_temp(temp1_crit);
 148show_temp(temp1_min);
 149show_temp(temp1_max);
 150
 151#define set_temp(value, reg) \
 152static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
 153        size_t count) \
 154{ \
 155        struct i2c_client *client = to_i2c_client(dev); \
 156        struct lm92_data *data = i2c_get_clientdata(client); \
 157        long val = simple_strtol(buf, NULL, 10); \
 158 \
 159        mutex_lock(&data->update_lock); \
 160        data->value = TEMP_TO_REG(val); \
 161        i2c_smbus_write_word_data(client, reg, swab16(data->value)); \
 162        mutex_unlock(&data->update_lock); \
 163        return count; \
 164}
 165set_temp(temp1_crit, LM92_REG_TEMP_CRIT);
 166set_temp(temp1_min, LM92_REG_TEMP_LOW);
 167set_temp(temp1_max, LM92_REG_TEMP_HIGH);
 168
 169static ssize_t show_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf)
 170{
 171        struct lm92_data *data = lm92_update_device(dev);
 172        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_crit)
 173                       - TEMP_FROM_REG(data->temp1_hyst));
 174}
 175static ssize_t show_temp1_max_hyst(struct device *dev, struct device_attribute *attr, char *buf)
 176{
 177        struct lm92_data *data = lm92_update_device(dev);
 178        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_max)
 179                       - TEMP_FROM_REG(data->temp1_hyst));
 180}
 181static ssize_t show_temp1_min_hyst(struct device *dev, struct device_attribute *attr, char *buf)
 182{
 183        struct lm92_data *data = lm92_update_device(dev);
 184        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_min)
 185                       + TEMP_FROM_REG(data->temp1_hyst));
 186}
 187
 188static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf,
 189        size_t count)
 190{
 191        struct i2c_client *client = to_i2c_client(dev);
 192        struct lm92_data *data = i2c_get_clientdata(client);
 193        long val = simple_strtol(buf, NULL, 10);
 194
 195        mutex_lock(&data->update_lock);
 196        data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val;
 197        i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST,
 198                                  swab16(TEMP_TO_REG(data->temp1_hyst)));
 199        mutex_unlock(&data->update_lock);
 200        return count;
 201}
 202
 203static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
 204{
 205        struct lm92_data *data = lm92_update_device(dev);
 206        return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input));
 207}
 208
 209static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
 210                          char *buf)
 211{
 212        int bitnr = to_sensor_dev_attr(attr)->index;
 213        struct lm92_data *data = lm92_update_device(dev);
 214        return sprintf(buf, "%d\n", (data->temp1_input >> bitnr) & 1);
 215}
 216
 217static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL);
 218static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp1_crit,
 219        set_temp1_crit);
 220static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp1_crit_hyst,
 221        set_temp1_crit_hyst);
 222static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp1_min,
 223        set_temp1_min);
 224static DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_temp1_min_hyst, NULL);
 225static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_max,
 226        set_temp1_max);
 227static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp1_max_hyst, NULL);
 228static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 229static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2);
 230static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0);
 231static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1);
 232
 233
 234/*
 235 * Detection and registration
 236 */
 237
 238static void lm92_init_client(struct i2c_client *client)
 239{
 240        u8 config;
 241
 242        /* Start the conversions if needed */
 243        config = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
 244        if (config & 0x01)
 245                i2c_smbus_write_byte_data(client, LM92_REG_CONFIG,
 246                                          config & 0xFE);
 247}
 248
 249/* The MAX6635 has no identification register, so we have to use tricks
 250   to identify it reliably. This is somewhat slow.
 251   Note that we do NOT rely on the 2 MSB of the configuration register
 252   always reading 0, as suggested by the datasheet, because it was once
 253   reported not to be true. */
 254static int max6635_check(struct i2c_client *client)
 255{
 256        u16 temp_low, temp_high, temp_hyst, temp_crit;
 257        u8 conf;
 258        int i;
 259
 260        /* No manufacturer ID register, so a read from this address will
 261           always return the last read value. */
 262        temp_low = i2c_smbus_read_word_data(client, LM92_REG_TEMP_LOW);
 263        if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_low)
 264                return 0;
 265        temp_high = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HIGH);
 266        if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_high)
 267                return 0;
 268        
 269        /* Limits are stored as integer values (signed, 9-bit). */
 270        if ((temp_low & 0x7f00) || (temp_high & 0x7f00))
 271                return 0;
 272        temp_hyst = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HYST);
 273        temp_crit = i2c_smbus_read_word_data(client, LM92_REG_TEMP_CRIT);
 274        if ((temp_hyst & 0x7f00) || (temp_crit & 0x7f00))
 275                return 0;
 276
 277        /* Registers addresses were found to cycle over 16-byte boundaries.
 278           We don't test all registers with all offsets so as to save some
 279           reads and time, but this should still be sufficient to dismiss
 280           non-MAX6635 chips. */
 281        conf = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
 282        for (i=16; i<96; i*=2) {
 283                if (temp_hyst != i2c_smbus_read_word_data(client,
 284                                 LM92_REG_TEMP_HYST + i - 16)
 285                 || temp_crit != i2c_smbus_read_word_data(client,
 286                                 LM92_REG_TEMP_CRIT + i)
 287                 || temp_low != i2c_smbus_read_word_data(client,
 288                                LM92_REG_TEMP_LOW + i + 16)
 289                 || temp_high != i2c_smbus_read_word_data(client,
 290                                 LM92_REG_TEMP_HIGH + i + 32)
 291                 || conf != i2c_smbus_read_byte_data(client,
 292                            LM92_REG_CONFIG + i))
 293                        return 0;
 294        }
 295
 296        return 1;
 297}
 298
 299static struct attribute *lm92_attributes[] = {
 300        &dev_attr_temp1_input.attr,
 301        &dev_attr_temp1_crit.attr,
 302        &dev_attr_temp1_crit_hyst.attr,
 303        &dev_attr_temp1_min.attr,
 304        &dev_attr_temp1_min_hyst.attr,
 305        &dev_attr_temp1_max.attr,
 306        &dev_attr_temp1_max_hyst.attr,
 307        &dev_attr_alarms.attr,
 308        &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
 309        &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
 310        &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
 311        NULL
 312};
 313
 314static const struct attribute_group lm92_group = {
 315        .attrs = lm92_attributes,
 316};
 317
 318/* Return 0 if detection is successful, -ENODEV otherwise */
 319static int lm92_detect(struct i2c_client *new_client,
 320                       struct i2c_board_info *info)
 321{
 322        struct i2c_adapter *adapter = new_client->adapter;
 323        u8 config;
 324        u16 man_id;
 325
 326        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
 327                                            | I2C_FUNC_SMBUS_WORD_DATA))
 328                return -ENODEV;
 329
 330        config = i2c_smbus_read_byte_data(new_client, LM92_REG_CONFIG);
 331        man_id = i2c_smbus_read_word_data(new_client, LM92_REG_MAN_ID);
 332
 333        if ((config & 0xe0) == 0x00 && man_id == 0x0180)
 334                pr_info("lm92: Found National Semiconductor LM92 chip\n");
 335        else if (max6635_check(new_client))
 336                pr_info("lm92: Found Maxim MAX6635 chip\n");
 337        else
 338                return -ENODEV;
 339
 340        strlcpy(info->type, "lm92", I2C_NAME_SIZE);
 341
 342        return 0;
 343}
 344
 345static int lm92_probe(struct i2c_client *new_client,
 346                      const struct i2c_device_id *id)
 347{
 348        struct lm92_data *data;
 349        int err;
 350
 351        data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL);
 352        if (!data) {
 353                err = -ENOMEM;
 354                goto exit;
 355        }
 356
 357        i2c_set_clientdata(new_client, data);
 358        data->valid = 0;
 359        mutex_init(&data->update_lock);
 360
 361        /* Initialize the chipset */
 362        lm92_init_client(new_client);
 363
 364        /* Register sysfs hooks */
 365        if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group)))
 366                goto exit_free;
 367
 368        data->hwmon_dev = hwmon_device_register(&new_client->dev);
 369        if (IS_ERR(data->hwmon_dev)) {
 370                err = PTR_ERR(data->hwmon_dev);
 371                goto exit_remove;
 372        }
 373
 374        return 0;
 375
 376exit_remove:
 377        sysfs_remove_group(&new_client->dev.kobj, &lm92_group);
 378exit_free:
 379        kfree(data);
 380exit:
 381        return err;
 382}
 383
 384static int lm92_remove(struct i2c_client *client)
 385{
 386        struct lm92_data *data = i2c_get_clientdata(client);
 387
 388        hwmon_device_unregister(data->hwmon_dev);
 389        sysfs_remove_group(&client->dev.kobj, &lm92_group);
 390
 391        kfree(data);
 392        return 0;
 393}
 394
 395
 396/*
 397 * Module and driver stuff
 398 */
 399
 400static const struct i2c_device_id lm92_id[] = {
 401        { "lm92", 0 },
 402        /* max6635 could be added here */
 403        { }
 404};
 405MODULE_DEVICE_TABLE(i2c, lm92_id);
 406
 407static struct i2c_driver lm92_driver = {
 408        .class          = I2C_CLASS_HWMON,
 409        .driver = {
 410                .name   = "lm92",
 411        },
 412        .probe          = lm92_probe,
 413        .remove         = lm92_remove,
 414        .id_table       = lm92_id,
 415        .detect         = lm92_detect,
 416        .address_list   = normal_i2c,
 417};
 418
 419static int __init sensors_lm92_init(void)
 420{
 421        return i2c_add_driver(&lm92_driver);
 422}
 423
 424static void __exit sensors_lm92_exit(void)
 425{
 426        i2c_del_driver(&lm92_driver);
 427}
 428
 429MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
 430MODULE_DESCRIPTION("LM92/MAX6635 driver");
 431MODULE_LICENSE("GPL");
 432
 433module_init(sensors_lm92_init);
 434module_exit(sensors_lm92_exit);
 435