linux/drivers/hwmon/adm9240.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * adm9240.c    Part of lm_sensors, Linux kernel modules for hardware
   4 *              monitoring
   5 *
   6 * Copyright (C) 1999   Frodo Looijaard <frodol@dds.nl>
   7 *                      Philip Edelbrock <phil@netroedge.com>
   8 * Copyright (C) 2003   Michiel Rook <michiel@grendelproject.nl>
   9 * Copyright (C) 2005   Grant Coady <gcoady.lk@gmail.com> with valuable
  10 *                              guidance from Jean Delvare
  11 *
  12 * Driver supports      Analog Devices          ADM9240
  13 *                      Dallas Semiconductor    DS1780
  14 *                      National Semiconductor  LM81
  15 *
  16 * ADM9240 is the reference, DS1780 and LM81 are register compatibles
  17 *
  18 * Voltage      Six inputs are scaled by chip, VID also reported
  19 * Temperature  Chip temperature to 0.5'C, maximum and max_hysteris
  20 * Fans         2 fans, low speed alarm, automatic fan clock divider
  21 * Alarms       16-bit map of active alarms
  22 * Analog Out   0..1250 mV output
  23 *
  24 * Chassis Intrusion: clear CI latch with 'echo 0 > intrusion0_alarm'
  25 *
  26 * Test hardware: Intel SE440BX-2 desktop motherboard --Grant
  27 *
  28 * LM81 extended temp reading not implemented
  29 */
  30
  31#include <linux/bits.h>
  32#include <linux/init.h>
  33#include <linux/module.h>
  34#include <linux/slab.h>
  35#include <linux/i2c.h>
  36#include <linux/hwmon-sysfs.h>
  37#include <linux/hwmon.h>
  38#include <linux/hwmon-vid.h>
  39#include <linux/err.h>
  40#include <linux/mutex.h>
  41#include <linux/regmap.h>
  42
  43/* Addresses to scan */
  44static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
  45                                        I2C_CLIENT_END };
  46
  47enum chips { adm9240, ds1780, lm81 };
  48
  49/* ADM9240 registers */
  50#define ADM9240_REG_MAN_ID              0x3e
  51#define ADM9240_REG_DIE_REV             0x3f
  52#define ADM9240_REG_CONFIG              0x40
  53
  54#define ADM9240_REG_IN(nr)              (0x20 + (nr))   /* 0..5 */
  55#define ADM9240_REG_IN_MAX(nr)          (0x2b + (nr) * 2)
  56#define ADM9240_REG_IN_MIN(nr)          (0x2c + (nr) * 2)
  57#define ADM9240_REG_FAN(nr)             (0x28 + (nr))   /* 0..1 */
  58#define ADM9240_REG_FAN_MIN(nr)         (0x3b + (nr))
  59#define ADM9240_REG_INT(nr)             (0x41 + (nr))
  60#define ADM9240_REG_INT_MASK(nr)        (0x43 + (nr))
  61#define ADM9240_REG_TEMP                0x27
  62#define ADM9240_REG_TEMP_MAX(nr)        (0x39 + (nr)) /* 0, 1 = high, hyst */
  63#define ADM9240_REG_ANALOG_OUT          0x19
  64#define ADM9240_REG_CHASSIS_CLEAR       0x46
  65#define ADM9240_REG_VID_FAN_DIV         0x47
  66#define ADM9240_REG_I2C_ADDR            0x48
  67#define ADM9240_REG_VID4                0x49
  68#define ADM9240_REG_TEMP_CONF           0x4b
  69
  70/* generalised scaling with integer rounding */
  71static inline int SCALE(long val, int mul, int div)
  72{
  73        if (val < 0)
  74                return (val * mul - div / 2) / div;
  75        else
  76                return (val * mul + div / 2) / div;
  77}
  78
  79/* adm9240 internally scales voltage measurements */
  80static const u16 nom_mv[] = { 2500, 2700, 3300, 5000, 12000, 2700 };
  81
  82static inline unsigned int IN_FROM_REG(u8 reg, int n)
  83{
  84        return SCALE(reg, nom_mv[n], 192);
  85}
  86
  87static inline u8 IN_TO_REG(unsigned long val, int n)
  88{
  89        val = clamp_val(val, 0, nom_mv[n] * 255 / 192);
  90        return SCALE(val, 192, nom_mv[n]);
  91}
  92
  93/* temperature range: -40..125, 127 disables temperature alarm */
  94static inline s8 TEMP_TO_REG(long val)
  95{
  96        val = clamp_val(val, -40000, 127000);
  97        return SCALE(val, 1, 1000);
  98}
  99
 100/* two fans, each with low fan speed limit */
 101static inline unsigned int FAN_FROM_REG(u8 reg, u8 div)
 102{
 103        if (!reg) /* error */
 104                return -1;
 105
 106        if (reg == 255)
 107                return 0;
 108
 109        return SCALE(1350000, 1, reg * div);
 110}
 111
 112/* analog out 0..1250mV */
 113static inline u8 AOUT_TO_REG(unsigned long val)
 114{
 115        val = clamp_val(val, 0, 1250);
 116        return SCALE(val, 255, 1250);
 117}
 118
 119static inline unsigned int AOUT_FROM_REG(u8 reg)
 120{
 121        return SCALE(reg, 1250, 255);
 122}
 123
 124/* per client data */
 125struct adm9240_data {
 126        struct device *dev;
 127        struct regmap *regmap;
 128        struct mutex update_lock;
 129
 130        u8 fan_div[2];          /* rw   fan1_div, read-only accessor */
 131        u8 vrm;                 /* --   vrm set on startup, no accessor */
 132};
 133
 134/* write new fan div, callers must hold data->update_lock */
 135static int adm9240_write_fan_div(struct adm9240_data *data, int channel, u8 fan_div)
 136{
 137        unsigned int reg, old, shift = (channel + 2) * 2;
 138        int err;
 139
 140        err = regmap_read(data->regmap, ADM9240_REG_VID_FAN_DIV, &reg);
 141        if (err < 0)
 142                return err;
 143        old = (reg >> shift) & 3;
 144        reg &= ~(3 << shift);
 145        reg |= (fan_div << shift);
 146        err = regmap_write(data->regmap, ADM9240_REG_VID_FAN_DIV, reg);
 147        if (err < 0)
 148                return err;
 149        dev_dbg(data->dev,
 150                "fan%d clock divider changed from %lu to %lu\n",
 151                channel + 1, BIT(old), BIT(fan_div));
 152
 153        return 0;
 154}
 155
 156/*
 157 * set fan speed low limit:
 158 *
 159 * - value is zero: disable fan speed low limit alarm
 160 *
 161 * - value is below fan speed measurement range: enable fan speed low
 162 *   limit alarm to be asserted while fan speed too slow to measure
 163 *
 164 * - otherwise: select fan clock divider to suit fan speed low limit,
 165 *   measurement code may adjust registers to ensure fan speed reading
 166 */
 167static int adm9240_fan_min_write(struct adm9240_data *data, int channel, long val)
 168{
 169        u8 new_div;
 170        u8 fan_min;
 171        int err;
 172
 173        mutex_lock(&data->update_lock);
 174
 175        if (!val) {
 176                fan_min = 255;
 177                new_div = data->fan_div[channel];
 178
 179                dev_dbg(data->dev, "fan%u low limit set disabled\n", channel + 1);
 180        } else if (val < 1350000 / (8 * 254)) {
 181                new_div = 3;
 182                fan_min = 254;
 183
 184                dev_dbg(data->dev, "fan%u low limit set minimum %u\n",
 185                        channel + 1, FAN_FROM_REG(254, BIT(new_div)));
 186        } else {
 187                unsigned int new_min = 1350000 / val;
 188
 189                new_div = 0;
 190                while (new_min > 192 && new_div < 3) {
 191                        new_div++;
 192                        new_min /= 2;
 193                }
 194                if (!new_min) /* keep > 0 */
 195                        new_min++;
 196
 197                fan_min = new_min;
 198
 199                dev_dbg(data->dev, "fan%u low limit set fan speed %u\n",
 200                        channel + 1, FAN_FROM_REG(new_min, BIT(new_div)));
 201        }
 202
 203        if (new_div != data->fan_div[channel]) {
 204                data->fan_div[channel] = new_div;
 205                adm9240_write_fan_div(data, channel, new_div);
 206        }
 207        err = regmap_write(data->regmap, ADM9240_REG_FAN_MIN(channel), fan_min);
 208
 209        mutex_unlock(&data->update_lock);
 210
 211        return err;
 212}
 213
 214static ssize_t cpu0_vid_show(struct device *dev,
 215                             struct device_attribute *attr, char *buf)
 216{
 217        struct adm9240_data *data = dev_get_drvdata(dev);
 218        unsigned int regval;
 219        int err;
 220        u8 vid;
 221
 222        err = regmap_read(data->regmap, ADM9240_REG_VID_FAN_DIV, &regval);
 223        if (err < 0)
 224                return err;
 225        vid = regval & 0x0f;
 226        err = regmap_read(data->regmap, ADM9240_REG_VID4, &regval);
 227        if (err < 0)
 228                return err;
 229        vid |= (regval & 1) << 4;
 230        return sprintf(buf, "%d\n", vid_from_reg(vid, data->vrm));
 231}
 232static DEVICE_ATTR_RO(cpu0_vid);
 233
 234static ssize_t aout_output_show(struct device *dev,
 235                                struct device_attribute *attr, char *buf)
 236{
 237        struct adm9240_data *data = dev_get_drvdata(dev);
 238        unsigned int regval;
 239        int err;
 240
 241        err = regmap_read(data->regmap, ADM9240_REG_ANALOG_OUT, &regval);
 242        if (err)
 243                return err;
 244
 245        return sprintf(buf, "%d\n", AOUT_FROM_REG(regval));
 246}
 247
 248static ssize_t aout_output_store(struct device *dev,
 249                                 struct device_attribute *attr,
 250                                 const char *buf, size_t count)
 251{
 252        struct adm9240_data *data = dev_get_drvdata(dev);
 253        long val;
 254        int err;
 255
 256        err = kstrtol(buf, 10, &val);
 257        if (err)
 258                return err;
 259
 260        err = regmap_write(data->regmap, ADM9240_REG_ANALOG_OUT, AOUT_TO_REG(val));
 261        return err < 0 ? err : count;
 262}
 263static DEVICE_ATTR_RW(aout_output);
 264
 265static struct attribute *adm9240_attrs[] = {
 266        &dev_attr_aout_output.attr,
 267        &dev_attr_cpu0_vid.attr,
 268        NULL
 269};
 270
 271ATTRIBUTE_GROUPS(adm9240);
 272
 273/*** sensor chip detect and driver install ***/
 274
 275/* Return 0 if detection is successful, -ENODEV otherwise */
 276static int adm9240_detect(struct i2c_client *new_client,
 277                          struct i2c_board_info *info)
 278{
 279        struct i2c_adapter *adapter = new_client->adapter;
 280        const char *name = "";
 281        int address = new_client->addr;
 282        u8 man_id, die_rev;
 283
 284        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 285                return -ENODEV;
 286
 287        /* verify chip: reg address should match i2c address */
 288        if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR) != address)
 289                return -ENODEV;
 290
 291        /* check known chip manufacturer */
 292        man_id = i2c_smbus_read_byte_data(new_client, ADM9240_REG_MAN_ID);
 293        if (man_id == 0x23)
 294                name = "adm9240";
 295        else if (man_id == 0xda)
 296                name = "ds1780";
 297        else if (man_id == 0x01)
 298                name = "lm81";
 299        else
 300                return -ENODEV;
 301
 302        /* successful detect, print chip info */
 303        die_rev = i2c_smbus_read_byte_data(new_client, ADM9240_REG_DIE_REV);
 304        dev_info(&adapter->dev, "found %s revision %u\n",
 305                 man_id == 0x23 ? "ADM9240" :
 306                 man_id == 0xda ? "DS1780" : "LM81", die_rev);
 307
 308        strscpy(info->type, name, I2C_NAME_SIZE);
 309
 310        return 0;
 311}
 312
 313static int adm9240_init_client(struct adm9240_data *data)
 314{
 315        unsigned int regval;
 316        u8 conf, mode;
 317        int err;
 318
 319        err = regmap_raw_read(data->regmap, ADM9240_REG_CONFIG, &conf, 1);
 320        if (err < 0)
 321                return err;
 322        err = regmap_raw_read(data->regmap, ADM9240_REG_TEMP_CONF, &mode, 1);
 323        if (err < 0)
 324                return err;
 325        mode &= 3;
 326
 327        data->vrm = vid_which_vrm(); /* need this to report vid as mV */
 328
 329        dev_info(data->dev, "Using VRM: %d.%d\n", data->vrm / 10,
 330                 data->vrm % 10);
 331
 332        if (conf & 1) { /* measurement cycle running: report state */
 333
 334                dev_info(data->dev, "status: config 0x%02x mode %u\n",
 335                         conf, mode);
 336
 337        } else { /* cold start: open limits before starting chip */
 338                int i;
 339
 340                for (i = 0; i < 6; i++) {
 341                        err = regmap_write(data->regmap,
 342                                           ADM9240_REG_IN_MIN(i), 0);
 343                        if (err < 0)
 344                                return err;
 345                        err = regmap_write(data->regmap,
 346                                           ADM9240_REG_IN_MAX(i), 255);
 347                        if (err < 0)
 348                                return err;
 349                }
 350                for (i = 0; i < 2; i++) {
 351                        err = regmap_write(data->regmap,
 352                                           ADM9240_REG_FAN_MIN(i), 255);
 353                        if (err < 0)
 354                                return err;
 355                }
 356                for (i = 0; i < 2; i++) {
 357                        err = regmap_write(data->regmap,
 358                                           ADM9240_REG_TEMP_MAX(i), 127);
 359                        if (err < 0)
 360                                return err;
 361                }
 362
 363                /* start measurement cycle */
 364                err = regmap_write(data->regmap, ADM9240_REG_CONFIG, 1);
 365                if (err < 0)
 366                        return err;
 367
 368                dev_info(data->dev,
 369                         "cold start: config was 0x%02x mode %u\n", conf, mode);
 370        }
 371
 372        /* read fan divs */
 373        err = regmap_read(data->regmap, ADM9240_REG_VID_FAN_DIV, &regval);
 374        if (err < 0)
 375                return err;
 376        data->fan_div[0] = (regval >> 4) & 3;
 377        data->fan_div[1] = (regval >> 6) & 3;
 378        return 0;
 379}
 380
 381static int adm9240_chip_read(struct device *dev, u32 attr, long *val)
 382{
 383        struct adm9240_data *data = dev_get_drvdata(dev);
 384        u8 regs[2];
 385        int err;
 386
 387        switch (attr) {
 388        case hwmon_chip_alarms:
 389                err = regmap_bulk_read(data->regmap, ADM9240_REG_INT(0), &regs, 2);
 390                if (err < 0)
 391                        return err;
 392                *val = regs[0] | regs[1] << 8;
 393                break;
 394        default:
 395                return -EOPNOTSUPP;
 396        }
 397        return 0;
 398}
 399
 400static int adm9240_intrusion_read(struct device *dev, u32 attr, long *val)
 401{
 402        struct adm9240_data *data = dev_get_drvdata(dev);
 403        unsigned int regval;
 404        int err;
 405
 406        switch (attr) {
 407        case hwmon_intrusion_alarm:
 408                err = regmap_read(data->regmap, ADM9240_REG_INT(1), &regval);
 409                if (err < 0)
 410                        return err;
 411                *val = !!(regval & BIT(4));
 412                break;
 413        default:
 414                return -EOPNOTSUPP;
 415        }
 416        return 0;
 417}
 418
 419static int adm9240_intrusion_write(struct device *dev, u32 attr, long val)
 420{
 421        struct adm9240_data *data = dev_get_drvdata(dev);
 422        int err;
 423
 424        switch (attr) {
 425        case hwmon_intrusion_alarm:
 426                if (val)
 427                        return -EINVAL;
 428                err = regmap_write(data->regmap, ADM9240_REG_CHASSIS_CLEAR, 0x80);
 429                if (err < 0)
 430                        return err;
 431                dev_dbg(data->dev, "chassis intrusion latch cleared\n");
 432                break;
 433        default:
 434                return -EOPNOTSUPP;
 435        }
 436        return 0;
 437}
 438
 439static int adm9240_in_read(struct device *dev, u32 attr, int channel, long *val)
 440{
 441        struct adm9240_data *data = dev_get_drvdata(dev);
 442        unsigned int regval;
 443        int reg;
 444        int err;
 445
 446        switch (attr) {
 447        case hwmon_in_input:
 448                reg = ADM9240_REG_IN(channel);
 449                break;
 450        case hwmon_in_min:
 451                reg = ADM9240_REG_IN_MIN(channel);
 452                break;
 453        case hwmon_in_max:
 454                reg = ADM9240_REG_IN_MAX(channel);
 455                break;
 456        case hwmon_in_alarm:
 457                if (channel < 4) {
 458                        reg = ADM9240_REG_INT(0);
 459                } else {
 460                        reg = ADM9240_REG_INT(1);
 461                        channel -= 4;
 462                }
 463                err = regmap_read(data->regmap, reg, &regval);
 464                if (err < 0)
 465                        return err;
 466                *val = !!(regval & BIT(channel));
 467                return 0;
 468        default:
 469                return -EOPNOTSUPP;
 470        }
 471        err = regmap_read(data->regmap, reg, &regval);
 472        if (err < 0)
 473                return err;
 474        *val = IN_FROM_REG(regval, channel);
 475        return 0;
 476}
 477
 478static int adm9240_in_write(struct device *dev, u32 attr, int channel, long val)
 479{
 480        struct adm9240_data *data = dev_get_drvdata(dev);
 481        int reg;
 482
 483        switch (attr) {
 484        case hwmon_in_min:
 485                reg = ADM9240_REG_IN_MIN(channel);
 486                break;
 487        case hwmon_in_max:
 488                reg = ADM9240_REG_IN_MAX(channel);
 489                break;
 490        default:
 491                return -EOPNOTSUPP;
 492        }
 493        return regmap_write(data->regmap, reg, IN_TO_REG(val, channel));
 494}
 495
 496static int adm9240_fan_read(struct device *dev, u32 attr, int channel, long *val)
 497{
 498        struct adm9240_data *data = dev_get_drvdata(dev);
 499        unsigned int regval;
 500        int err;
 501
 502        switch (attr) {
 503        case hwmon_fan_input:
 504                err = regmap_read(data->regmap, ADM9240_REG_FAN(channel), &regval);
 505                if (err < 0)
 506                        return err;
 507                if (regval == 255 && data->fan_div[channel] < 3) {
 508                        /* adjust fan clock divider on overflow */
 509                        err = adm9240_write_fan_div(data, channel,
 510                                                    ++data->fan_div[channel]);
 511                        if (err)
 512                                return err;
 513                }
 514                *val = FAN_FROM_REG(regval, BIT(data->fan_div[channel]));
 515                break;
 516        case hwmon_fan_div:
 517                *val = BIT(data->fan_div[channel]);
 518                break;
 519        case hwmon_fan_min:
 520                err = regmap_read(data->regmap, ADM9240_REG_FAN_MIN(channel), &regval);
 521                if (err < 0)
 522                        return err;
 523                *val = FAN_FROM_REG(regval, BIT(data->fan_div[channel]));
 524                break;
 525        case hwmon_fan_alarm:
 526                err = regmap_read(data->regmap, ADM9240_REG_INT(0), &regval);
 527                if (err < 0)
 528                        return err;
 529                *val = !!(regval & BIT(channel + 6));
 530                break;
 531        default:
 532                return -EOPNOTSUPP;
 533        }
 534        return 0;
 535}
 536
 537static int adm9240_fan_write(struct device *dev, u32 attr, int channel, long val)
 538{
 539        struct adm9240_data *data = dev_get_drvdata(dev);
 540        int err;
 541
 542        switch (attr) {
 543        case hwmon_fan_min:
 544                err = adm9240_fan_min_write(data, channel, val);
 545                if (err < 0)
 546                        return err;
 547                break;
 548        default:
 549                return -EOPNOTSUPP;
 550        }
 551        return 0;
 552}
 553
 554static int adm9240_temp_read(struct device *dev, u32 attr, int channel, long *val)
 555{
 556        struct adm9240_data *data = dev_get_drvdata(dev);
 557        unsigned int regval;
 558        int err, temp;
 559
 560        switch (attr) {
 561        case hwmon_temp_input:
 562                err = regmap_read(data->regmap, ADM9240_REG_TEMP, &regval);
 563                if (err < 0)
 564                        return err;
 565                temp = regval << 1;
 566                err = regmap_read(data->regmap, ADM9240_REG_TEMP_CONF, &regval);
 567                if (err < 0)
 568                        return err;
 569                temp |= regval >> 7;
 570                *val = sign_extend32(temp, 8) * 500;
 571                break;
 572        case hwmon_temp_max:
 573                err = regmap_read(data->regmap, ADM9240_REG_TEMP_MAX(0), &regval);
 574                if (err < 0)
 575                        return err;
 576                *val = (s8)regval * 1000;
 577                break;
 578        case hwmon_temp_max_hyst:
 579                err = regmap_read(data->regmap, ADM9240_REG_TEMP_MAX(1), &regval);
 580                if (err < 0)
 581                        return err;
 582                *val = (s8)regval * 1000;
 583                break;
 584        case hwmon_temp_alarm:
 585                err = regmap_read(data->regmap, ADM9240_REG_INT(0), &regval);
 586                if (err < 0)
 587                        return err;
 588                *val = !!(regval & BIT(4));
 589                break;
 590        default:
 591                return -EOPNOTSUPP;
 592        }
 593        return 0;
 594}
 595
 596static int adm9240_temp_write(struct device *dev, u32 attr, int channel, long val)
 597{
 598        struct adm9240_data *data = dev_get_drvdata(dev);
 599        int reg;
 600
 601        switch (attr) {
 602        case hwmon_temp_max:
 603                reg = ADM9240_REG_TEMP_MAX(0);
 604                break;
 605        case hwmon_temp_max_hyst:
 606                reg = ADM9240_REG_TEMP_MAX(1);
 607                break;
 608        default:
 609                return -EOPNOTSUPP;
 610        }
 611        return regmap_write(data->regmap, reg, TEMP_TO_REG(val));
 612}
 613
 614static int adm9240_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
 615                        int channel, long *val)
 616{
 617        switch (type) {
 618        case hwmon_chip:
 619                return adm9240_chip_read(dev, attr, val);
 620        case hwmon_intrusion:
 621                return adm9240_intrusion_read(dev, attr, val);
 622        case hwmon_in:
 623                return adm9240_in_read(dev, attr, channel, val);
 624        case hwmon_fan:
 625                return adm9240_fan_read(dev, attr, channel, val);
 626        case hwmon_temp:
 627                return adm9240_temp_read(dev, attr, channel, val);
 628        default:
 629                return -EOPNOTSUPP;
 630        }
 631}
 632
 633static int adm9240_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
 634                         int channel, long val)
 635{
 636        switch (type) {
 637        case hwmon_intrusion:
 638                return adm9240_intrusion_write(dev, attr, val);
 639        case hwmon_in:
 640                return adm9240_in_write(dev, attr, channel, val);
 641        case hwmon_fan:
 642                return adm9240_fan_write(dev, attr, channel, val);
 643        case hwmon_temp:
 644                return adm9240_temp_write(dev, attr, channel, val);
 645        default:
 646                return -EOPNOTSUPP;
 647        }
 648}
 649
 650static umode_t adm9240_is_visible(const void *_data, enum hwmon_sensor_types type,
 651                                  u32 attr, int channel)
 652{
 653        umode_t mode = 0;
 654
 655        switch (type) {
 656        case hwmon_chip:
 657                switch (attr) {
 658                case hwmon_chip_alarms:
 659                        mode = 0444;
 660                        break;
 661                default:
 662                        break;
 663                }
 664                break;
 665        case hwmon_intrusion:
 666                switch (attr) {
 667                case hwmon_intrusion_alarm:
 668                        mode = 0644;
 669                        break;
 670                default:
 671                        break;
 672                }
 673                break;
 674        case hwmon_temp:
 675                switch (attr) {
 676                case hwmon_temp:
 677                case hwmon_temp_alarm:
 678                        mode = 0444;
 679                        break;
 680                case hwmon_temp_max:
 681                case hwmon_temp_max_hyst:
 682                        mode = 0644;
 683                        break;
 684                default:
 685                        break;
 686                }
 687                break;
 688        case hwmon_fan:
 689                switch (attr) {
 690                case hwmon_fan_input:
 691                case hwmon_fan_div:
 692                case hwmon_fan_alarm:
 693                        mode = 0444;
 694                        break;
 695                case hwmon_fan_min:
 696                        mode = 0644;
 697                        break;
 698                default:
 699                        break;
 700                }
 701                break;
 702        case hwmon_in:
 703                switch (attr) {
 704                case hwmon_in_input:
 705                case hwmon_in_alarm:
 706                        mode = 0444;
 707                        break;
 708                case hwmon_in_min:
 709                case hwmon_in_max:
 710                        mode = 0644;
 711                        break;
 712                default:
 713                        break;
 714                }
 715                break;
 716        default:
 717                break;
 718        }
 719        return mode;
 720}
 721
 722static const struct hwmon_ops adm9240_hwmon_ops = {
 723        .is_visible = adm9240_is_visible,
 724        .read = adm9240_read,
 725        .write = adm9240_write,
 726};
 727
 728static const struct hwmon_channel_info *adm9240_info[] = {
 729        HWMON_CHANNEL_INFO(chip, HWMON_C_ALARMS),
 730        HWMON_CHANNEL_INFO(intrusion, HWMON_INTRUSION_ALARM),
 731        HWMON_CHANNEL_INFO(temp,
 732                           HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST | HWMON_T_ALARM),
 733        HWMON_CHANNEL_INFO(in,
 734                           HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM,
 735                           HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM,
 736                           HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM,
 737                           HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM,
 738                           HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM,
 739                           HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_ALARM),
 740        HWMON_CHANNEL_INFO(fan,
 741                           HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_DIV | HWMON_F_ALARM,
 742                           HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_DIV | HWMON_F_ALARM),
 743        NULL
 744};
 745
 746static const struct hwmon_chip_info adm9240_chip_info = {
 747        .ops = &adm9240_hwmon_ops,
 748        .info = adm9240_info,
 749};
 750
 751static bool adm9240_volatile_reg(struct device *dev, unsigned int reg)
 752{
 753        switch (reg) {
 754        case ADM9240_REG_IN(0) ... ADM9240_REG_IN(5):
 755        case ADM9240_REG_FAN(0) ... ADM9240_REG_FAN(1):
 756        case ADM9240_REG_INT(0) ... ADM9240_REG_INT(1):
 757        case ADM9240_REG_TEMP:
 758        case ADM9240_REG_TEMP_CONF:
 759        case ADM9240_REG_VID_FAN_DIV:
 760        case ADM9240_REG_VID4:
 761        case ADM9240_REG_ANALOG_OUT:
 762                return true;
 763        default:
 764                return false;
 765        }
 766}
 767
 768static const struct regmap_config adm9240_regmap_config = {
 769        .reg_bits = 8,
 770        .val_bits = 8,
 771        .use_single_read = true,
 772        .use_single_write = true,
 773        .volatile_reg = adm9240_volatile_reg,
 774};
 775
 776static int adm9240_probe(struct i2c_client *client)
 777{
 778        struct device *dev = &client->dev;
 779        struct device *hwmon_dev;
 780        struct adm9240_data *data;
 781        int err;
 782
 783        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 784        if (!data)
 785                return -ENOMEM;
 786
 787        data->dev = dev;
 788        mutex_init(&data->update_lock);
 789        data->regmap = devm_regmap_init_i2c(client, &adm9240_regmap_config);
 790        if (IS_ERR(data->regmap))
 791                return PTR_ERR(data->regmap);
 792
 793        err = adm9240_init_client(data);
 794        if (err < 0)
 795                return err;
 796
 797        hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
 798                                                         &adm9240_chip_info,
 799                                                         adm9240_groups);
 800        return PTR_ERR_OR_ZERO(hwmon_dev);
 801}
 802
 803static const struct i2c_device_id adm9240_id[] = {
 804        { "adm9240", adm9240 },
 805        { "ds1780", ds1780 },
 806        { "lm81", lm81 },
 807        { }
 808};
 809MODULE_DEVICE_TABLE(i2c, adm9240_id);
 810
 811static struct i2c_driver adm9240_driver = {
 812        .class          = I2C_CLASS_HWMON,
 813        .driver = {
 814                .name   = "adm9240",
 815        },
 816        .probe_new      = adm9240_probe,
 817        .id_table       = adm9240_id,
 818        .detect         = adm9240_detect,
 819        .address_list   = normal_i2c,
 820};
 821
 822module_i2c_driver(adm9240_driver);
 823
 824MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, "
 825                "Grant Coady <gcoady.lk@gmail.com> and others");
 826MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver");
 827MODULE_LICENSE("GPL");
 828