root/drivers/hwmon/nct7904.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nct7904_bank_lock
  2. nct7904_bank_release
  3. nct7904_read_reg
  4. nct7904_read_reg16
  5. nct7904_write_reg
  6. nct7904_read_fan
  7. nct7904_fan_is_visible
  8. nct7904_read_in
  9. nct7904_in_is_visible
  10. nct7904_read_temp
  11. nct7904_temp_is_visible
  12. nct7904_read_pwm
  13. nct7904_write_temp
  14. nct7904_write_fan
  15. nct7904_write_in
  16. nct7904_write_pwm
  17. nct7904_pwm_is_visible
  18. nct7904_read
  19. nct7904_write
  20. nct7904_is_visible
  21. nct7904_detect
  22. nct7904_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * nct7904.c - driver for Nuvoton NCT7904D.
   4  *
   5  * Copyright (c) 2015 Kontron
   6  * Author: Vadim V. Vlasov <vvlasov@dev.rtsoft.ru>
   7  *
   8  * Copyright (c) 2019 Advantech
   9  * Author: Amy.Shih <amy.shih@advantech.com.tw>
  10  */
  11 
  12 #include <linux/module.h>
  13 #include <linux/device.h>
  14 #include <linux/init.h>
  15 #include <linux/i2c.h>
  16 #include <linux/mutex.h>
  17 #include <linux/hwmon.h>
  18 
  19 #define VENDOR_ID_REG           0x7A    /* Any bank */
  20 #define NUVOTON_ID              0x50
  21 #define CHIP_ID_REG             0x7B    /* Any bank */
  22 #define NCT7904_ID              0xC5
  23 #define DEVICE_ID_REG           0x7C    /* Any bank */
  24 
  25 #define BANK_SEL_REG            0xFF
  26 #define BANK_0                  0x00
  27 #define BANK_1                  0x01
  28 #define BANK_2                  0x02
  29 #define BANK_3                  0x03
  30 #define BANK_4                  0x04
  31 #define BANK_MAX                0x04
  32 
  33 #define FANIN_MAX               12      /* Counted from 1 */
  34 #define VSEN_MAX                21      /* VSEN1..14, 3VDD, VBAT, V3VSB,
  35                                            LTD (not a voltage), VSEN17..19 */
  36 #define FANCTL_MAX              4       /* Counted from 1 */
  37 #define TCPU_MAX                8       /* Counted from 1 */
  38 #define TEMP_MAX                4       /* Counted from 1 */
  39 
  40 #define VT_ADC_CTRL0_REG        0x20    /* Bank 0 */
  41 #define VT_ADC_CTRL1_REG        0x21    /* Bank 0 */
  42 #define VT_ADC_CTRL2_REG        0x22    /* Bank 0 */
  43 #define FANIN_CTRL0_REG         0x24
  44 #define FANIN_CTRL1_REG         0x25
  45 #define DTS_T_CTRL0_REG         0x26
  46 #define DTS_T_CTRL1_REG         0x27
  47 #define VT_ADC_MD_REG           0x2E
  48 
  49 #define VSEN1_HV_LL_REG         0x02    /* Bank 1; 2 regs (HV/LV) per sensor */
  50 #define VSEN1_LV_LL_REG         0x03    /* Bank 1; 2 regs (HV/LV) per sensor */
  51 #define VSEN1_HV_HL_REG         0x00    /* Bank 1; 2 regs (HV/LV) per sensor */
  52 #define VSEN1_LV_HL_REG         0x01    /* Bank 1; 2 regs (HV/LV) per sensor */
  53 #define SMI_STS1_REG            0xC1    /* Bank 0; SMI Status Register */
  54 #define SMI_STS3_REG            0xC3    /* Bank 0; SMI Status Register */
  55 #define SMI_STS5_REG            0xC5    /* Bank 0; SMI Status Register */
  56 #define SMI_STS7_REG            0xC7    /* Bank 0; SMI Status Register */
  57 #define SMI_STS8_REG            0xC8    /* Bank 0; SMI Status Register */
  58 
  59 #define VSEN1_HV_REG            0x40    /* Bank 0; 2 regs (HV/LV) per sensor */
  60 #define TEMP_CH1_HV_REG         0x42    /* Bank 0; same as VSEN2_HV */
  61 #define LTD_HV_REG              0x62    /* Bank 0; 2 regs in VSEN range */
  62 #define LTD_HV_HL_REG           0x44    /* Bank 1; 1 reg for LTD */
  63 #define LTD_LV_HL_REG           0x45    /* Bank 1; 1 reg for LTD */
  64 #define LTD_HV_LL_REG           0x46    /* Bank 1; 1 reg for LTD */
  65 #define LTD_LV_LL_REG           0x47    /* Bank 1; 1 reg for LTD */
  66 #define TEMP_CH1_CH_REG         0x05    /* Bank 1; 1 reg for LTD */
  67 #define TEMP_CH1_W_REG          0x06    /* Bank 1; 1 reg for LTD */
  68 #define TEMP_CH1_WH_REG         0x07    /* Bank 1; 1 reg for LTD */
  69 #define TEMP_CH1_C_REG          0x04    /* Bank 1; 1 reg per sensor */
  70 #define DTS_T_CPU1_C_REG        0x90    /* Bank 1; 1 reg per sensor */
  71 #define DTS_T_CPU1_CH_REG       0x91    /* Bank 1; 1 reg per sensor */
  72 #define DTS_T_CPU1_W_REG        0x92    /* Bank 1; 1 reg per sensor */
  73 #define DTS_T_CPU1_WH_REG       0x93    /* Bank 1; 1 reg per sensor */
  74 #define FANIN1_HV_REG           0x80    /* Bank 0; 2 regs (HV/LV) per sensor */
  75 #define FANIN1_HV_HL_REG        0x60    /* Bank 1; 2 regs (HV/LV) per sensor */
  76 #define FANIN1_LV_HL_REG        0x61    /* Bank 1; 2 regs (HV/LV) per sensor */
  77 #define T_CPU1_HV_REG           0xA0    /* Bank 0; 2 regs (HV/LV) per sensor */
  78 
  79 #define PRTS_REG                0x03    /* Bank 2 */
  80 #define PFE_REG                 0x00    /* Bank 2; PECI Function Enable */
  81 #define TSI_CTRL_REG            0x50    /* Bank 2; TSI Control Register */
  82 #define FANCTL1_FMR_REG         0x00    /* Bank 3; 1 reg per channel */
  83 #define FANCTL1_OUT_REG         0x10    /* Bank 3; 1 reg per channel */
  84 
  85 #define VOLT_MONITOR_MODE       0x0
  86 #define THERMAL_DIODE_MODE      0x1
  87 #define THERMISTOR_MODE         0x3
  88 
  89 #define ENABLE_TSI      BIT(1)
  90 
  91 static const unsigned short normal_i2c[] = {
  92         0x2d, 0x2e, I2C_CLIENT_END
  93 };
  94 
  95 struct nct7904_data {
  96         struct i2c_client *client;
  97         struct mutex bank_lock;
  98         int bank_sel;
  99         u32 fanin_mask;
 100         u32 vsen_mask;
 101         u32 tcpu_mask;
 102         u8 fan_mode[FANCTL_MAX];
 103         u8 enable_dts;
 104         u8 has_dts;
 105         u8 temp_mode; /* 0: TR mode, 1: TD mode */
 106         u8 fan_alarm[2];
 107         u8 vsen_alarm[3];
 108 };
 109 
 110 /* Access functions */
 111 static int nct7904_bank_lock(struct nct7904_data *data, unsigned int bank)
 112 {
 113         int ret;
 114 
 115         mutex_lock(&data->bank_lock);
 116         if (data->bank_sel == bank)
 117                 return 0;
 118         ret = i2c_smbus_write_byte_data(data->client, BANK_SEL_REG, bank);
 119         if (ret == 0)
 120                 data->bank_sel = bank;
 121         else
 122                 data->bank_sel = -1;
 123         return ret;
 124 }
 125 
 126 static inline void nct7904_bank_release(struct nct7904_data *data)
 127 {
 128         mutex_unlock(&data->bank_lock);
 129 }
 130 
 131 /* Read 1-byte register. Returns unsigned reg or -ERRNO on error. */
 132 static int nct7904_read_reg(struct nct7904_data *data,
 133                             unsigned int bank, unsigned int reg)
 134 {
 135         struct i2c_client *client = data->client;
 136         int ret;
 137 
 138         ret = nct7904_bank_lock(data, bank);
 139         if (ret == 0)
 140                 ret = i2c_smbus_read_byte_data(client, reg);
 141 
 142         nct7904_bank_release(data);
 143         return ret;
 144 }
 145 
 146 /*
 147  * Read 2-byte register. Returns register in big-endian format or
 148  * -ERRNO on error.
 149  */
 150 static int nct7904_read_reg16(struct nct7904_data *data,
 151                               unsigned int bank, unsigned int reg)
 152 {
 153         struct i2c_client *client = data->client;
 154         int ret, hi;
 155 
 156         ret = nct7904_bank_lock(data, bank);
 157         if (ret == 0) {
 158                 ret = i2c_smbus_read_byte_data(client, reg);
 159                 if (ret >= 0) {
 160                         hi = ret;
 161                         ret = i2c_smbus_read_byte_data(client, reg + 1);
 162                         if (ret >= 0)
 163                                 ret |= hi << 8;
 164                 }
 165         }
 166 
 167         nct7904_bank_release(data);
 168         return ret;
 169 }
 170 
 171 /* Write 1-byte register. Returns 0 or -ERRNO on error. */
 172 static int nct7904_write_reg(struct nct7904_data *data,
 173                              unsigned int bank, unsigned int reg, u8 val)
 174 {
 175         struct i2c_client *client = data->client;
 176         int ret;
 177 
 178         ret = nct7904_bank_lock(data, bank);
 179         if (ret == 0)
 180                 ret = i2c_smbus_write_byte_data(client, reg, val);
 181 
 182         nct7904_bank_release(data);
 183         return ret;
 184 }
 185 
 186 static int nct7904_read_fan(struct device *dev, u32 attr, int channel,
 187                             long *val)
 188 {
 189         struct nct7904_data *data = dev_get_drvdata(dev);
 190         unsigned int cnt, rpm;
 191         int ret;
 192 
 193         switch (attr) {
 194         case hwmon_fan_input:
 195                 ret = nct7904_read_reg16(data, BANK_0,
 196                                          FANIN1_HV_REG + channel * 2);
 197                 if (ret < 0)
 198                         return ret;
 199                 cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
 200                 if (cnt == 0x1fff)
 201                         rpm = 0;
 202                 else
 203                         rpm = 1350000 / cnt;
 204                 *val = rpm;
 205                 return 0;
 206         case hwmon_fan_min:
 207                 ret = nct7904_read_reg16(data, BANK_1,
 208                                          FANIN1_HV_HL_REG + channel * 2);
 209                 if (ret < 0)
 210                         return ret;
 211                 cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
 212                 if (cnt == 0x1fff)
 213                         rpm = 0;
 214                 else
 215                         rpm = 1350000 / cnt;
 216                 *val = rpm;
 217                 return 0;
 218         case hwmon_fan_alarm:
 219                 ret = nct7904_read_reg(data, BANK_0,
 220                                        SMI_STS5_REG + (channel >> 3));
 221                 if (ret < 0)
 222                         return ret;
 223                 if (!data->fan_alarm[channel >> 3])
 224                         data->fan_alarm[channel >> 3] = ret & 0xff;
 225                 else
 226                         /* If there is new alarm showing up */
 227                         data->fan_alarm[channel >> 3] |= (ret & 0xff);
 228                 *val = (data->fan_alarm[channel >> 3] >> (channel & 0x07)) & 1;
 229                 /* Needs to clean the alarm if alarm existing */
 230                 if (*val)
 231                         data->fan_alarm[channel >> 3] ^= 1 << (channel & 0x07);
 232                 return 0;
 233         default:
 234                 return -EOPNOTSUPP;
 235         }
 236 }
 237 
 238 static umode_t nct7904_fan_is_visible(const void *_data, u32 attr, int channel)
 239 {
 240         const struct nct7904_data *data = _data;
 241 
 242         switch (attr) {
 243         case hwmon_fan_input:
 244         case hwmon_fan_alarm:
 245                 if (data->fanin_mask & (1 << channel))
 246                         return 0444;
 247                 break;
 248         case hwmon_fan_min:
 249                 if (data->fanin_mask & (1 << channel))
 250                         return 0644;
 251                 break;
 252         default:
 253                 break;
 254         }
 255 
 256         return 0;
 257 }
 258 
 259 static u8 nct7904_chan_to_index[] = {
 260         0,      /* Not used */
 261         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 262         18, 19, 20, 16
 263 };
 264 
 265 static int nct7904_read_in(struct device *dev, u32 attr, int channel,
 266                            long *val)
 267 {
 268         struct nct7904_data *data = dev_get_drvdata(dev);
 269         int ret, volt, index;
 270 
 271         index = nct7904_chan_to_index[channel];
 272 
 273         switch (attr) {
 274         case hwmon_in_input:
 275                 ret = nct7904_read_reg16(data, BANK_0,
 276                                          VSEN1_HV_REG + index * 2);
 277                 if (ret < 0)
 278                         return ret;
 279                 volt = ((ret & 0xff00) >> 5) | (ret & 0x7);
 280                 if (index < 14)
 281                         volt *= 2; /* 0.002V scale */
 282                 else
 283                         volt *= 6; /* 0.006V scale */
 284                 *val = volt;
 285                 return 0;
 286         case hwmon_in_min:
 287                 ret = nct7904_read_reg16(data, BANK_1,
 288                                          VSEN1_HV_LL_REG + index * 4);
 289                 if (ret < 0)
 290                         return ret;
 291                 volt = ((ret & 0xff00) >> 5) | (ret & 0x7);
 292                 if (index < 14)
 293                         volt *= 2; /* 0.002V scale */
 294                 else
 295                         volt *= 6; /* 0.006V scale */
 296                 *val = volt;
 297                 return 0;
 298         case hwmon_in_max:
 299                 ret = nct7904_read_reg16(data, BANK_1,
 300                                          VSEN1_HV_HL_REG + index * 4);
 301                 if (ret < 0)
 302                         return ret;
 303                 volt = ((ret & 0xff00) >> 5) | (ret & 0x7);
 304                 if (index < 14)
 305                         volt *= 2; /* 0.002V scale */
 306                 else
 307                         volt *= 6; /* 0.006V scale */
 308                 *val = volt;
 309                 return 0;
 310         case hwmon_in_alarm:
 311                 ret = nct7904_read_reg(data, BANK_0,
 312                                        SMI_STS1_REG + (index >> 3));
 313                 if (ret < 0)
 314                         return ret;
 315                 if (!data->vsen_alarm[index >> 3])
 316                         data->vsen_alarm[index >> 3] = ret & 0xff;
 317                 else
 318                         /* If there is new alarm showing up */
 319                         data->vsen_alarm[index >> 3] |= (ret & 0xff);
 320                 *val = (data->vsen_alarm[index >> 3] >> (index & 0x07)) & 1;
 321                 /* Needs to clean the alarm if alarm existing */
 322                 if (*val)
 323                         data->vsen_alarm[index >> 3] ^= 1 << (index & 0x07);
 324                 return 0;
 325         default:
 326                 return -EOPNOTSUPP;
 327         }
 328 }
 329 
 330 static umode_t nct7904_in_is_visible(const void *_data, u32 attr, int channel)
 331 {
 332         const struct nct7904_data *data = _data;
 333         int index = nct7904_chan_to_index[channel];
 334 
 335         switch (attr) {
 336         case hwmon_in_input:
 337         case hwmon_in_alarm:
 338                 if (channel > 0 && (data->vsen_mask & BIT(index)))
 339                         return 0444;
 340                 break;
 341         case hwmon_in_min:
 342         case hwmon_in_max:
 343                 if (channel > 0 && (data->vsen_mask & BIT(index)))
 344                         return 0644;
 345                 break;
 346         default:
 347                 break;
 348         }
 349 
 350         return 0;
 351 }
 352 
 353 static int nct7904_read_temp(struct device *dev, u32 attr, int channel,
 354                              long *val)
 355 {
 356         struct nct7904_data *data = dev_get_drvdata(dev);
 357         int ret, temp;
 358         unsigned int reg1, reg2, reg3;
 359         s8 temps;
 360 
 361         switch (attr) {
 362         case hwmon_temp_input:
 363                 if (channel == 4)
 364                         ret = nct7904_read_reg16(data, BANK_0, LTD_HV_REG);
 365                 else if (channel < 5)
 366                         ret = nct7904_read_reg16(data, BANK_0,
 367                                                  TEMP_CH1_HV_REG + channel * 4);
 368                 else
 369                         ret = nct7904_read_reg16(data, BANK_0,
 370                                                  T_CPU1_HV_REG + (channel - 5)
 371                                                  * 2);
 372                 if (ret < 0)
 373                         return ret;
 374                 temp = ((ret & 0xff00) >> 5) | (ret & 0x7);
 375                 *val = sign_extend32(temp, 10) * 125;
 376                 return 0;
 377         case hwmon_temp_alarm:
 378                 if (channel == 4) {
 379                         ret = nct7904_read_reg(data, BANK_0,
 380                                                SMI_STS3_REG);
 381                         if (ret < 0)
 382                                 return ret;
 383                         *val = (ret >> 1) & 1;
 384                 } else if (channel < 4) {
 385                         ret = nct7904_read_reg(data, BANK_0,
 386                                                SMI_STS1_REG);
 387                         if (ret < 0)
 388                                 return ret;
 389                         *val = (ret >> (((channel * 2) + 1) & 0x07)) & 1;
 390                 } else {
 391                         if ((channel - 5) < 4) {
 392                                 ret = nct7904_read_reg(data, BANK_0,
 393                                                        SMI_STS7_REG +
 394                                                        ((channel - 5) >> 3));
 395                                 if (ret < 0)
 396                                         return ret;
 397                                 *val = (ret >> ((channel - 5) & 0x07)) & 1;
 398                         } else {
 399                                 ret = nct7904_read_reg(data, BANK_0,
 400                                                        SMI_STS8_REG +
 401                                                        ((channel - 5) >> 3));
 402                                 if (ret < 0)
 403                                         return ret;
 404                                 *val = (ret >> (((channel - 5) & 0x07) - 4))
 405                                                         & 1;
 406                         }
 407                 }
 408                 return 0;
 409         case hwmon_temp_type:
 410                 if (channel < 5) {
 411                         if ((data->tcpu_mask >> channel) & 0x01) {
 412                                 if ((data->temp_mode >> channel) & 0x01)
 413                                         *val = 3; /* TD */
 414                                 else
 415                                         *val = 4; /* TR */
 416                         } else {
 417                                 *val = 0;
 418                         }
 419                 } else {
 420                         if ((data->has_dts >> (channel - 5)) & 0x01) {
 421                                 if (data->enable_dts & ENABLE_TSI)
 422                                         *val = 5; /* TSI */
 423                                 else
 424                                         *val = 6; /* PECI */
 425                         } else {
 426                                 *val = 0;
 427                         }
 428                 }
 429                 return 0;
 430         case hwmon_temp_max:
 431                 reg1 = LTD_HV_LL_REG;
 432                 reg2 = TEMP_CH1_W_REG;
 433                 reg3 = DTS_T_CPU1_W_REG;
 434                 break;
 435         case hwmon_temp_max_hyst:
 436                 reg1 = LTD_LV_LL_REG;
 437                 reg2 = TEMP_CH1_WH_REG;
 438                 reg3 = DTS_T_CPU1_WH_REG;
 439                 break;
 440         case hwmon_temp_crit:
 441                 reg1 = LTD_HV_HL_REG;
 442                 reg2 = TEMP_CH1_C_REG;
 443                 reg3 = DTS_T_CPU1_C_REG;
 444                 break;
 445         case hwmon_temp_crit_hyst:
 446                 reg1 = LTD_LV_HL_REG;
 447                 reg2 = TEMP_CH1_CH_REG;
 448                 reg3 = DTS_T_CPU1_CH_REG;
 449                 break;
 450         default:
 451                 return -EOPNOTSUPP;
 452         }
 453 
 454         if (channel == 4)
 455                 ret = nct7904_read_reg(data, BANK_1, reg1);
 456         else if (channel < 5)
 457                 ret = nct7904_read_reg(data, BANK_1,
 458                                        reg2 + channel * 8);
 459         else
 460                 ret = nct7904_read_reg(data, BANK_1,
 461                                        reg3 + (channel - 5) * 4);
 462 
 463         if (ret < 0)
 464                 return ret;
 465         temps = ret;
 466         *val = temps * 1000;
 467         return 0;
 468 }
 469 
 470 static umode_t nct7904_temp_is_visible(const void *_data, u32 attr, int channel)
 471 {
 472         const struct nct7904_data *data = _data;
 473 
 474         switch (attr) {
 475         case hwmon_temp_input:
 476         case hwmon_temp_alarm:
 477         case hwmon_temp_type:
 478                 if (channel < 5) {
 479                         if (data->tcpu_mask & BIT(channel))
 480                                 return 0444;
 481                 } else {
 482                         if (data->has_dts & BIT(channel - 5))
 483                                 return 0444;
 484                 }
 485                 break;
 486         case hwmon_temp_max:
 487         case hwmon_temp_max_hyst:
 488         case hwmon_temp_crit:
 489         case hwmon_temp_crit_hyst:
 490                 if (channel < 5) {
 491                         if (data->tcpu_mask & BIT(channel))
 492                                 return 0644;
 493                 } else {
 494                         if (data->has_dts & BIT(channel - 5))
 495                                 return 0644;
 496                 }
 497                 break;
 498         default:
 499                 break;
 500         }
 501 
 502         return 0;
 503 }
 504 
 505 static int nct7904_read_pwm(struct device *dev, u32 attr, int channel,
 506                             long *val)
 507 {
 508         struct nct7904_data *data = dev_get_drvdata(dev);
 509         int ret;
 510 
 511         switch (attr) {
 512         case hwmon_pwm_input:
 513                 ret = nct7904_read_reg(data, BANK_3, FANCTL1_OUT_REG + channel);
 514                 if (ret < 0)
 515                         return ret;
 516                 *val = ret;
 517                 return 0;
 518         case hwmon_pwm_enable:
 519                 ret = nct7904_read_reg(data, BANK_3, FANCTL1_FMR_REG + channel);
 520                 if (ret < 0)
 521                         return ret;
 522 
 523                 *val = ret ? 2 : 1;
 524                 return 0;
 525         default:
 526                 return -EOPNOTSUPP;
 527         }
 528 }
 529 
 530 static int nct7904_write_temp(struct device *dev, u32 attr, int channel,
 531                               long val)
 532 {
 533         struct nct7904_data *data = dev_get_drvdata(dev);
 534         int ret;
 535         unsigned int reg1, reg2, reg3;
 536 
 537         val = clamp_val(val / 1000, -128, 127);
 538 
 539         switch (attr) {
 540         case hwmon_temp_max:
 541                 reg1 = LTD_HV_LL_REG;
 542                 reg2 = TEMP_CH1_W_REG;
 543                 reg3 = DTS_T_CPU1_W_REG;
 544                 break;
 545         case hwmon_temp_max_hyst:
 546                 reg1 = LTD_LV_LL_REG;
 547                 reg2 = TEMP_CH1_WH_REG;
 548                 reg3 = DTS_T_CPU1_WH_REG;
 549                 break;
 550         case hwmon_temp_crit:
 551                 reg1 = LTD_HV_HL_REG;
 552                 reg2 = TEMP_CH1_C_REG;
 553                 reg3 = DTS_T_CPU1_C_REG;
 554                 break;
 555         case hwmon_temp_crit_hyst:
 556                 reg1 = LTD_LV_HL_REG;
 557                 reg2 = TEMP_CH1_CH_REG;
 558                 reg3 = DTS_T_CPU1_CH_REG;
 559                 break;
 560         default:
 561                 return -EOPNOTSUPP;
 562         }
 563         if (channel == 4)
 564                 ret = nct7904_write_reg(data, BANK_1, reg1, val);
 565         else if (channel < 5)
 566                 ret = nct7904_write_reg(data, BANK_1,
 567                                         reg2 + channel * 8, val);
 568         else
 569                 ret = nct7904_write_reg(data, BANK_1,
 570                                         reg3 + (channel - 5) * 4, val);
 571 
 572         return ret;
 573 }
 574 
 575 static int nct7904_write_fan(struct device *dev, u32 attr, int channel,
 576                              long val)
 577 {
 578         struct nct7904_data *data = dev_get_drvdata(dev);
 579         int ret;
 580         u8 tmp;
 581 
 582         switch (attr) {
 583         case hwmon_fan_min:
 584                 if (val <= 0)
 585                         return -EINVAL;
 586 
 587                 val = clamp_val(DIV_ROUND_CLOSEST(1350000, val), 1, 0x1fff);
 588                 tmp = (val >> 5) & 0xff;
 589                 ret = nct7904_write_reg(data, BANK_1,
 590                                         FANIN1_HV_HL_REG + channel * 2, tmp);
 591                 if (ret < 0)
 592                         return ret;
 593                 tmp = val & 0x1f;
 594                 ret = nct7904_write_reg(data, BANK_1,
 595                                         FANIN1_LV_HL_REG + channel * 2, tmp);
 596                 return ret;
 597         default:
 598                 return -EOPNOTSUPP;
 599         }
 600 }
 601 
 602 static int nct7904_write_in(struct device *dev, u32 attr, int channel,
 603                             long val)
 604 {
 605         struct nct7904_data *data = dev_get_drvdata(dev);
 606         int ret, index, tmp;
 607 
 608         index = nct7904_chan_to_index[channel];
 609 
 610         if (index < 14)
 611                 val = val / 2; /* 0.002V scale */
 612         else
 613                 val = val / 6; /* 0.006V scale */
 614 
 615         val = clamp_val(val, 0, 0x7ff);
 616 
 617         switch (attr) {
 618         case hwmon_in_min:
 619                 tmp = nct7904_read_reg(data, BANK_1,
 620                                        VSEN1_LV_LL_REG + index * 4);
 621                 if (tmp < 0)
 622                         return tmp;
 623                 tmp &= ~0x7;
 624                 tmp |= val & 0x7;
 625                 ret = nct7904_write_reg(data, BANK_1,
 626                                         VSEN1_LV_LL_REG + index * 4, tmp);
 627                 if (ret < 0)
 628                         return ret;
 629                 tmp = nct7904_read_reg(data, BANK_1,
 630                                        VSEN1_HV_LL_REG + index * 4);
 631                 if (tmp < 0)
 632                         return tmp;
 633                 tmp = (val >> 3) & 0xff;
 634                 ret = nct7904_write_reg(data, BANK_1,
 635                                         VSEN1_HV_LL_REG + index * 4, tmp);
 636                 return ret;
 637         case hwmon_in_max:
 638                 tmp = nct7904_read_reg(data, BANK_1,
 639                                        VSEN1_LV_HL_REG + index * 4);
 640                 if (tmp < 0)
 641                         return tmp;
 642                 tmp &= ~0x7;
 643                 tmp |= val & 0x7;
 644                 ret = nct7904_write_reg(data, BANK_1,
 645                                         VSEN1_LV_HL_REG + index * 4, tmp);
 646                 if (ret < 0)
 647                         return ret;
 648                 tmp = nct7904_read_reg(data, BANK_1,
 649                                        VSEN1_HV_HL_REG + index * 4);
 650                 if (tmp < 0)
 651                         return tmp;
 652                 tmp = (val >> 3) & 0xff;
 653                 ret = nct7904_write_reg(data, BANK_1,
 654                                         VSEN1_HV_HL_REG + index * 4, tmp);
 655                 return ret;
 656         default:
 657                 return -EOPNOTSUPP;
 658         }
 659 }
 660 
 661 static int nct7904_write_pwm(struct device *dev, u32 attr, int channel,
 662                              long val)
 663 {
 664         struct nct7904_data *data = dev_get_drvdata(dev);
 665         int ret;
 666 
 667         switch (attr) {
 668         case hwmon_pwm_input:
 669                 if (val < 0 || val > 255)
 670                         return -EINVAL;
 671                 ret = nct7904_write_reg(data, BANK_3, FANCTL1_OUT_REG + channel,
 672                                         val);
 673                 return ret;
 674         case hwmon_pwm_enable:
 675                 if (val < 1 || val > 2 ||
 676                     (val == 2 && !data->fan_mode[channel]))
 677                         return -EINVAL;
 678                 ret = nct7904_write_reg(data, BANK_3, FANCTL1_FMR_REG + channel,
 679                                         val == 2 ? data->fan_mode[channel] : 0);
 680                 return ret;
 681         default:
 682                 return -EOPNOTSUPP;
 683         }
 684 }
 685 
 686 static umode_t nct7904_pwm_is_visible(const void *_data, u32 attr, int channel)
 687 {
 688         switch (attr) {
 689         case hwmon_pwm_input:
 690         case hwmon_pwm_enable:
 691                 return 0644;
 692         default:
 693                 return 0;
 694         }
 695 }
 696 
 697 static int nct7904_read(struct device *dev, enum hwmon_sensor_types type,
 698                         u32 attr, int channel, long *val)
 699 {
 700         switch (type) {
 701         case hwmon_in:
 702                 return nct7904_read_in(dev, attr, channel, val);
 703         case hwmon_fan:
 704                 return nct7904_read_fan(dev, attr, channel, val);
 705         case hwmon_pwm:
 706                 return nct7904_read_pwm(dev, attr, channel, val);
 707         case hwmon_temp:
 708                 return nct7904_read_temp(dev, attr, channel, val);
 709         default:
 710                 return -EOPNOTSUPP;
 711         }
 712 }
 713 
 714 static int nct7904_write(struct device *dev, enum hwmon_sensor_types type,
 715                          u32 attr, int channel, long val)
 716 {
 717         switch (type) {
 718         case hwmon_in:
 719                 return nct7904_write_in(dev, attr, channel, val);
 720         case hwmon_fan:
 721                 return nct7904_write_fan(dev, attr, channel, val);
 722         case hwmon_pwm:
 723                 return nct7904_write_pwm(dev, attr, channel, val);
 724         case hwmon_temp:
 725                 return nct7904_write_temp(dev, attr, channel, val);
 726         default:
 727                 return -EOPNOTSUPP;
 728         }
 729 }
 730 
 731 static umode_t nct7904_is_visible(const void *data,
 732                                   enum hwmon_sensor_types type,
 733                                   u32 attr, int channel)
 734 {
 735         switch (type) {
 736         case hwmon_in:
 737                 return nct7904_in_is_visible(data, attr, channel);
 738         case hwmon_fan:
 739                 return nct7904_fan_is_visible(data, attr, channel);
 740         case hwmon_pwm:
 741                 return nct7904_pwm_is_visible(data, attr, channel);
 742         case hwmon_temp:
 743                 return nct7904_temp_is_visible(data, attr, channel);
 744         default:
 745                 return 0;
 746         }
 747 }
 748 
 749 /* Return 0 if detection is successful, -ENODEV otherwise */
 750 static int nct7904_detect(struct i2c_client *client,
 751                           struct i2c_board_info *info)
 752 {
 753         struct i2c_adapter *adapter = client->adapter;
 754 
 755         if (!i2c_check_functionality(adapter,
 756                                      I2C_FUNC_SMBUS_READ_BYTE |
 757                                      I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
 758                 return -ENODEV;
 759 
 760         /* Determine the chip type. */
 761         if (i2c_smbus_read_byte_data(client, VENDOR_ID_REG) != NUVOTON_ID ||
 762             i2c_smbus_read_byte_data(client, CHIP_ID_REG) != NCT7904_ID ||
 763             (i2c_smbus_read_byte_data(client, DEVICE_ID_REG) & 0xf0) != 0x50 ||
 764             (i2c_smbus_read_byte_data(client, BANK_SEL_REG) & 0xf8) != 0x00)
 765                 return -ENODEV;
 766 
 767         strlcpy(info->type, "nct7904", I2C_NAME_SIZE);
 768 
 769         return 0;
 770 }
 771 
 772 static const struct hwmon_channel_info *nct7904_info[] = {
 773         HWMON_CHANNEL_INFO(in,
 774                            /* dummy, skipped in is_visible */
 775                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 776                            HWMON_I_ALARM,
 777                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 778                            HWMON_I_ALARM,
 779                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 780                            HWMON_I_ALARM,
 781                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 782                            HWMON_I_ALARM,
 783                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 784                            HWMON_I_ALARM,
 785                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 786                            HWMON_I_ALARM,
 787                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 788                            HWMON_I_ALARM,
 789                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 790                            HWMON_I_ALARM,
 791                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 792                            HWMON_I_ALARM,
 793                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 794                            HWMON_I_ALARM,
 795                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 796                            HWMON_I_ALARM,
 797                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 798                            HWMON_I_ALARM,
 799                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 800                            HWMON_I_ALARM,
 801                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 802                            HWMON_I_ALARM,
 803                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 804                            HWMON_I_ALARM,
 805                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 806                            HWMON_I_ALARM,
 807                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 808                            HWMON_I_ALARM,
 809                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 810                            HWMON_I_ALARM,
 811                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 812                            HWMON_I_ALARM,
 813                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 814                            HWMON_I_ALARM,
 815                            HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
 816                            HWMON_I_ALARM),
 817         HWMON_CHANNEL_INFO(fan,
 818                            HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
 819                            HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
 820                            HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
 821                            HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
 822                            HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
 823                            HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
 824                            HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
 825                            HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM),
 826         HWMON_CHANNEL_INFO(pwm,
 827                            HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
 828                            HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
 829                            HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
 830                            HWMON_PWM_INPUT | HWMON_PWM_ENABLE),
 831         HWMON_CHANNEL_INFO(temp,
 832                            HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
 833                            HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
 834                            HWMON_T_CRIT_HYST,
 835                            HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
 836                            HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
 837                            HWMON_T_CRIT_HYST,
 838                            HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
 839                            HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
 840                            HWMON_T_CRIT_HYST,
 841                            HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
 842                            HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
 843                            HWMON_T_CRIT_HYST,
 844                            HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
 845                            HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
 846                            HWMON_T_CRIT_HYST,
 847                            HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
 848                            HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
 849                            HWMON_T_CRIT_HYST,
 850                            HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
 851                            HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
 852                            HWMON_T_CRIT_HYST,
 853                            HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
 854                            HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
 855                            HWMON_T_CRIT_HYST,
 856                            HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
 857                            HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
 858                            HWMON_T_CRIT_HYST),
 859         NULL
 860 };
 861 
 862 static const struct hwmon_ops nct7904_hwmon_ops = {
 863         .is_visible = nct7904_is_visible,
 864         .read = nct7904_read,
 865         .write = nct7904_write,
 866 };
 867 
 868 static const struct hwmon_chip_info nct7904_chip_info = {
 869         .ops = &nct7904_hwmon_ops,
 870         .info = nct7904_info,
 871 };
 872 
 873 static int nct7904_probe(struct i2c_client *client,
 874                          const struct i2c_device_id *id)
 875 {
 876         struct nct7904_data *data;
 877         struct device *hwmon_dev;
 878         struct device *dev = &client->dev;
 879         int ret, i;
 880         u32 mask;
 881         u8 val, bit;
 882 
 883         data = devm_kzalloc(dev, sizeof(struct nct7904_data), GFP_KERNEL);
 884         if (!data)
 885                 return -ENOMEM;
 886 
 887         data->client = client;
 888         mutex_init(&data->bank_lock);
 889         data->bank_sel = -1;
 890 
 891         /* Setup sensor groups. */
 892         /* FANIN attributes */
 893         ret = nct7904_read_reg16(data, BANK_0, FANIN_CTRL0_REG);
 894         if (ret < 0)
 895                 return ret;
 896         data->fanin_mask = (ret >> 8) | ((ret & 0xff) << 8);
 897 
 898         /*
 899          * VSEN attributes
 900          *
 901          * Note: voltage sensors overlap with external temperature
 902          * sensors. So, if we ever decide to support the latter
 903          * we will have to adjust 'vsen_mask' accordingly.
 904          */
 905         mask = 0;
 906         ret = nct7904_read_reg16(data, BANK_0, VT_ADC_CTRL0_REG);
 907         if (ret >= 0)
 908                 mask = (ret >> 8) | ((ret & 0xff) << 8);
 909         ret = nct7904_read_reg(data, BANK_0, VT_ADC_CTRL2_REG);
 910         if (ret >= 0)
 911                 mask |= (ret << 16);
 912         data->vsen_mask = mask;
 913 
 914         /* CPU_TEMP attributes */
 915         ret = nct7904_read_reg(data, BANK_0, VT_ADC_CTRL0_REG);
 916         if (ret < 0)
 917                 return ret;
 918 
 919         if ((ret & 0x6) == 0x6)
 920                 data->tcpu_mask |= 1; /* TR1 */
 921         if ((ret & 0x18) == 0x18)
 922                 data->tcpu_mask |= 2; /* TR2 */
 923         if ((ret & 0x20) == 0x20)
 924                 data->tcpu_mask |= 4; /* TR3 */
 925         if ((ret & 0x80) == 0x80)
 926                 data->tcpu_mask |= 8; /* TR4 */
 927 
 928         /* LTD */
 929         ret = nct7904_read_reg(data, BANK_0, VT_ADC_CTRL2_REG);
 930         if (ret < 0)
 931                 return ret;
 932         if ((ret & 0x02) == 0x02)
 933                 data->tcpu_mask |= 0x10;
 934 
 935         /* Multi-Function detecting for Volt and TR/TD */
 936         ret = nct7904_read_reg(data, BANK_0, VT_ADC_MD_REG);
 937         if (ret < 0)
 938                 return ret;
 939 
 940         data->temp_mode = 0;
 941         for (i = 0; i < 4; i++) {
 942                 val = (ret >> (i * 2)) & 0x03;
 943                 bit = (1 << i);
 944                 if (val == VOLT_MONITOR_MODE) {
 945                         data->tcpu_mask &= ~bit;
 946                 } else if (val == THERMAL_DIODE_MODE && i < 2) {
 947                         data->temp_mode |= bit;
 948                         data->vsen_mask &= ~(0x06 << (i * 2));
 949                 } else if (val == THERMISTOR_MODE) {
 950                         data->vsen_mask &= ~(0x02 << (i * 2));
 951                 } else {
 952                         /* Reserved */
 953                         data->tcpu_mask &= ~bit;
 954                         data->vsen_mask &= ~(0x06 << (i * 2));
 955                 }
 956         }
 957 
 958         /* PECI */
 959         ret = nct7904_read_reg(data, BANK_2, PFE_REG);
 960         if (ret < 0)
 961                 return ret;
 962         if (ret & 0x80) {
 963                 data->enable_dts = 1; /* Enable DTS & PECI */
 964         } else {
 965                 ret = nct7904_read_reg(data, BANK_2, TSI_CTRL_REG);
 966                 if (ret < 0)
 967                         return ret;
 968                 if (ret & 0x80)
 969                         data->enable_dts = 0x3; /* Enable DTS & TSI */
 970         }
 971 
 972         /* Check DTS enable status */
 973         if (data->enable_dts) {
 974                 ret = nct7904_read_reg(data, BANK_0, DTS_T_CTRL0_REG);
 975                 if (ret < 0)
 976                         return ret;
 977                 data->has_dts = ret & 0xF;
 978                 if (data->enable_dts & ENABLE_TSI) {
 979                         ret = nct7904_read_reg(data, BANK_0, DTS_T_CTRL1_REG);
 980                         if (ret < 0)
 981                                 return ret;
 982                         data->has_dts |= (ret & 0xF) << 4;
 983                 }
 984         }
 985 
 986         for (i = 0; i < FANCTL_MAX; i++) {
 987                 ret = nct7904_read_reg(data, BANK_3, FANCTL1_FMR_REG + i);
 988                 if (ret < 0)
 989                         return ret;
 990                 data->fan_mode[i] = ret;
 991         }
 992 
 993         hwmon_dev =
 994                 devm_hwmon_device_register_with_info(dev, client->name, data,
 995                                                      &nct7904_chip_info, NULL);
 996         return PTR_ERR_OR_ZERO(hwmon_dev);
 997 }
 998 
 999 static const struct i2c_device_id nct7904_id[] = {
1000         {"nct7904", 0},
1001         {}
1002 };
1003 MODULE_DEVICE_TABLE(i2c, nct7904_id);
1004 
1005 static struct i2c_driver nct7904_driver = {
1006         .class = I2C_CLASS_HWMON,
1007         .driver = {
1008                 .name = "nct7904",
1009         },
1010         .probe = nct7904_probe,
1011         .id_table = nct7904_id,
1012         .detect = nct7904_detect,
1013         .address_list = normal_i2c,
1014 };
1015 
1016 module_i2c_driver(nct7904_driver);
1017 
1018 MODULE_AUTHOR("Vadim V. Vlasov <vvlasov@dev.rtsoft.ru>");
1019 MODULE_DESCRIPTION("Hwmon driver for NUVOTON NCT7904");
1020 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */