1c0b4e3abSDarrick J. Wong /* 2c0b4e3abSDarrick J. Wong * A hwmon driver for the Analog Devices ADT7462 3c0b4e3abSDarrick J. Wong * Copyright (C) 2008 IBM 4c0b4e3abSDarrick J. Wong * 55407e051SDarrick J. Wong * Author: Darrick J. Wong <darrick.wong@oracle.com> 6c0b4e3abSDarrick J. Wong * 7c0b4e3abSDarrick J. Wong * This program is free software; you can redistribute it and/or modify 8c0b4e3abSDarrick J. Wong * it under the terms of the GNU General Public License as published by 9c0b4e3abSDarrick J. Wong * the Free Software Foundation; either version 2 of the License, or 10c0b4e3abSDarrick J. Wong * (at your option) any later version. 11c0b4e3abSDarrick J. Wong * 12c0b4e3abSDarrick J. Wong * This program is distributed in the hope that it will be useful, 13c0b4e3abSDarrick J. Wong * but WITHOUT ANY WARRANTY; without even the implied warranty of 14c0b4e3abSDarrick J. Wong * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15c0b4e3abSDarrick J. Wong * GNU General Public License for more details. 16c0b4e3abSDarrick J. Wong * 17c0b4e3abSDarrick J. Wong * You should have received a copy of the GNU General Public License 18c0b4e3abSDarrick J. Wong * along with this program; if not, write to the Free Software 19c0b4e3abSDarrick J. Wong * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20c0b4e3abSDarrick J. Wong */ 21c0b4e3abSDarrick J. Wong 22c0b4e3abSDarrick J. Wong #include <linux/module.h> 23c0b4e3abSDarrick J. Wong #include <linux/jiffies.h> 24c0b4e3abSDarrick J. Wong #include <linux/i2c.h> 25c0b4e3abSDarrick J. Wong #include <linux/hwmon.h> 26c0b4e3abSDarrick J. Wong #include <linux/hwmon-sysfs.h> 27c0b4e3abSDarrick J. Wong #include <linux/err.h> 28c0b4e3abSDarrick J. Wong #include <linux/mutex.h> 29c0b4e3abSDarrick J. Wong #include <linux/log2.h> 305a0e3ad6STejun Heo #include <linux/slab.h> 31c0b4e3abSDarrick J. Wong 32c0b4e3abSDarrick J. Wong /* Addresses to scan */ 33c0b4e3abSDarrick J. Wong static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; 34c0b4e3abSDarrick J. Wong 35c0b4e3abSDarrick J. Wong /* ADT7462 registers */ 36c0b4e3abSDarrick J. Wong #define ADT7462_REG_DEVICE 0x3D 37c0b4e3abSDarrick J. Wong #define ADT7462_REG_VENDOR 0x3E 38c0b4e3abSDarrick J. Wong #define ADT7462_REG_REVISION 0x3F 39c0b4e3abSDarrick J. Wong 40c0b4e3abSDarrick J. Wong #define ADT7462_REG_MIN_TEMP_BASE_ADDR 0x44 41c0b4e3abSDarrick J. Wong #define ADT7462_REG_MIN_TEMP_MAX_ADDR 0x47 42c0b4e3abSDarrick J. Wong #define ADT7462_REG_MAX_TEMP_BASE_ADDR 0x48 43c0b4e3abSDarrick J. Wong #define ADT7462_REG_MAX_TEMP_MAX_ADDR 0x4B 44c0b4e3abSDarrick J. Wong #define ADT7462_REG_TEMP_BASE_ADDR 0x88 45c0b4e3abSDarrick J. Wong #define ADT7462_REG_TEMP_MAX_ADDR 0x8F 46c0b4e3abSDarrick J. Wong 47c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_BASE_ADDR 0x98 48c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_MAX_ADDR 0x9F 49c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN2_BASE_ADDR 0xA2 50c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN2_MAX_ADDR 0xA9 51c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_ENABLE 0x07 52c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_MIN_BASE_ADDR 0x78 53c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_MIN_MAX_ADDR 0x7F 54c0b4e3abSDarrick J. Wong 55c0b4e3abSDarrick J. Wong #define ADT7462_REG_CFG2 0x02 56c0b4e3abSDarrick J. Wong #define ADT7462_FSPD_MASK 0x20 57c0b4e3abSDarrick J. Wong 58c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_BASE_ADDR 0xAA 59c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_MAX_ADDR 0xAD 60c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_MIN_BASE_ADDR 0x28 61c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_MIN_MAX_ADDR 0x2B 62c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_MAX 0x2C 63c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR 0x5C 64c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TEMP_MIN_MAX_ADDR 0x5F 65c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR 0x60 66c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TEMP_RANGE_MAX_ADDR 0x63 67c0b4e3abSDarrick J. Wong #define ADT7462_PWM_HYST_MASK 0x0F 68c0b4e3abSDarrick J. Wong #define ADT7462_PWM_RANGE_MASK 0xF0 69c0b4e3abSDarrick J. Wong #define ADT7462_PWM_RANGE_SHIFT 4 70c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_CFG_BASE_ADDR 0x21 71c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_CFG_MAX_ADDR 0x24 72c0b4e3abSDarrick J. Wong #define ADT7462_PWM_CHANNEL_MASK 0xE0 73c0b4e3abSDarrick J. Wong #define ADT7462_PWM_CHANNEL_SHIFT 5 74c0b4e3abSDarrick J. Wong 75c0b4e3abSDarrick J. Wong #define ADT7462_REG_PIN_CFG_BASE_ADDR 0x10 76c0b4e3abSDarrick J. Wong #define ADT7462_REG_PIN_CFG_MAX_ADDR 0x13 77c0b4e3abSDarrick J. Wong #define ADT7462_PIN7_INPUT 0x01 /* cfg0 */ 78c0b4e3abSDarrick J. Wong #define ADT7462_DIODE3_INPUT 0x20 79c0b4e3abSDarrick J. Wong #define ADT7462_DIODE1_INPUT 0x40 80c0b4e3abSDarrick J. Wong #define ADT7462_VID_INPUT 0x80 81c0b4e3abSDarrick J. Wong #define ADT7462_PIN22_INPUT 0x04 /* cfg1 */ 82c0b4e3abSDarrick J. Wong #define ADT7462_PIN21_INPUT 0x08 83c0b4e3abSDarrick J. Wong #define ADT7462_PIN19_INPUT 0x10 84c0b4e3abSDarrick J. Wong #define ADT7462_PIN15_INPUT 0x20 85c0b4e3abSDarrick J. Wong #define ADT7462_PIN13_INPUT 0x40 86c0b4e3abSDarrick J. Wong #define ADT7462_PIN8_INPUT 0x80 87c0b4e3abSDarrick J. Wong #define ADT7462_PIN23_MASK 0x03 88c0b4e3abSDarrick J. Wong #define ADT7462_PIN23_SHIFT 0 89c0b4e3abSDarrick J. Wong #define ADT7462_PIN26_MASK 0x0C /* cfg2 */ 90c0b4e3abSDarrick J. Wong #define ADT7462_PIN26_SHIFT 2 91c0b4e3abSDarrick J. Wong #define ADT7462_PIN25_MASK 0x30 92c0b4e3abSDarrick J. Wong #define ADT7462_PIN25_SHIFT 4 93c0b4e3abSDarrick J. Wong #define ADT7462_PIN24_MASK 0xC0 94c0b4e3abSDarrick J. Wong #define ADT7462_PIN24_SHIFT 6 95c0b4e3abSDarrick J. Wong #define ADT7462_PIN26_VOLT_INPUT 0x08 96c0b4e3abSDarrick J. Wong #define ADT7462_PIN25_VOLT_INPUT 0x20 97bb595c92SRoger Blofeld #define ADT7462_PIN28_SHIFT 4 /* cfg3 */ 98c0b4e3abSDarrick J. Wong #define ADT7462_PIN28_VOLT 0x5 99c0b4e3abSDarrick J. Wong 100c0b4e3abSDarrick J. Wong #define ADT7462_REG_ALARM1 0xB8 101c0b4e3abSDarrick J. Wong #define ADT7462_LT_ALARM 0x02 102c0b4e3abSDarrick J. Wong #define ADT7462_R1T_ALARM 0x04 103c0b4e3abSDarrick J. Wong #define ADT7462_R2T_ALARM 0x08 104c0b4e3abSDarrick J. Wong #define ADT7462_R3T_ALARM 0x10 105c0b4e3abSDarrick J. Wong #define ADT7462_REG_ALARM2 0xBB 106c0b4e3abSDarrick J. Wong #define ADT7462_V0_ALARM 0x01 107c0b4e3abSDarrick J. Wong #define ADT7462_V1_ALARM 0x02 108c0b4e3abSDarrick J. Wong #define ADT7462_V2_ALARM 0x04 109c0b4e3abSDarrick J. Wong #define ADT7462_V3_ALARM 0x08 110c0b4e3abSDarrick J. Wong #define ADT7462_V4_ALARM 0x10 111c0b4e3abSDarrick J. Wong #define ADT7462_V5_ALARM 0x20 112c0b4e3abSDarrick J. Wong #define ADT7462_V6_ALARM 0x40 113c0b4e3abSDarrick J. Wong #define ADT7462_V7_ALARM 0x80 114c0b4e3abSDarrick J. Wong #define ADT7462_REG_ALARM3 0xBC 115c0b4e3abSDarrick J. Wong #define ADT7462_V8_ALARM 0x08 116c0b4e3abSDarrick J. Wong #define ADT7462_V9_ALARM 0x10 117c0b4e3abSDarrick J. Wong #define ADT7462_V10_ALARM 0x20 118c0b4e3abSDarrick J. Wong #define ADT7462_V11_ALARM 0x40 119c0b4e3abSDarrick J. Wong #define ADT7462_V12_ALARM 0x80 120c0b4e3abSDarrick J. Wong #define ADT7462_REG_ALARM4 0xBD 121c0b4e3abSDarrick J. Wong #define ADT7462_F0_ALARM 0x01 122c0b4e3abSDarrick J. Wong #define ADT7462_F1_ALARM 0x02 123c0b4e3abSDarrick J. Wong #define ADT7462_F2_ALARM 0x04 124c0b4e3abSDarrick J. Wong #define ADT7462_F3_ALARM 0x08 125c0b4e3abSDarrick J. Wong #define ADT7462_F4_ALARM 0x10 126c0b4e3abSDarrick J. Wong #define ADT7462_F5_ALARM 0x20 127c0b4e3abSDarrick J. Wong #define ADT7462_F6_ALARM 0x40 128c0b4e3abSDarrick J. Wong #define ADT7462_F7_ALARM 0x80 129c0b4e3abSDarrick J. Wong #define ADT7462_ALARM1 0x0000 130c0b4e3abSDarrick J. Wong #define ADT7462_ALARM2 0x0100 131c0b4e3abSDarrick J. Wong #define ADT7462_ALARM3 0x0200 132c0b4e3abSDarrick J. Wong #define ADT7462_ALARM4 0x0300 133c0b4e3abSDarrick J. Wong #define ADT7462_ALARM_REG_SHIFT 8 134c0b4e3abSDarrick J. Wong #define ADT7462_ALARM_FLAG_MASK 0x0F 135c0b4e3abSDarrick J. Wong 136c0b4e3abSDarrick J. Wong #define ADT7462_TEMP_COUNT 4 137724cc331SGuenter Roeck #define ADT7462_TEMP_REG(x) (ADT7462_REG_TEMP_BASE_ADDR + ((x) * 2)) 138c0b4e3abSDarrick J. Wong #define ADT7462_TEMP_MIN_REG(x) (ADT7462_REG_MIN_TEMP_BASE_ADDR + (x)) 139c0b4e3abSDarrick J. Wong #define ADT7462_TEMP_MAX_REG(x) (ADT7462_REG_MAX_TEMP_BASE_ADDR + (x)) 140c0b4e3abSDarrick J. Wong #define TEMP_FRAC_OFFSET 6 141c0b4e3abSDarrick J. Wong 142c0b4e3abSDarrick J. Wong #define ADT7462_FAN_COUNT 8 143c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_MIN(x) (ADT7462_REG_FAN_MIN_BASE_ADDR + (x)) 144c0b4e3abSDarrick J. Wong 145c0b4e3abSDarrick J. Wong #define ADT7462_PWM_COUNT 4 146c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM(x) (ADT7462_REG_PWM_BASE_ADDR + (x)) 147c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_MIN(x) (ADT7462_REG_PWM_MIN_BASE_ADDR + (x)) 148c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TMIN(x) \ 149c0b4e3abSDarrick J. Wong (ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR + (x)) 150c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TRANGE(x) \ 151c0b4e3abSDarrick J. Wong (ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR + (x)) 152c0b4e3abSDarrick J. Wong 153c0b4e3abSDarrick J. Wong #define ADT7462_PIN_CFG_REG_COUNT 4 154c0b4e3abSDarrick J. Wong #define ADT7462_REG_PIN_CFG(x) (ADT7462_REG_PIN_CFG_BASE_ADDR + (x)) 155c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_CFG(x) (ADT7462_REG_PWM_CFG_BASE_ADDR + (x)) 156c0b4e3abSDarrick J. Wong 157c0b4e3abSDarrick J. Wong #define ADT7462_ALARM_REG_COUNT 4 158c0b4e3abSDarrick J. Wong 159c0b4e3abSDarrick J. Wong /* 160c0b4e3abSDarrick J. Wong * The chip can measure 13 different voltage sources: 161c0b4e3abSDarrick J. Wong * 162c0b4e3abSDarrick J. Wong * 1. +12V1 (pin 7) 163c0b4e3abSDarrick J. Wong * 2. Vccp1/+2.5V/+1.8V/+1.5V (pin 23) 164c0b4e3abSDarrick J. Wong * 3. +12V3 (pin 22) 165c0b4e3abSDarrick J. Wong * 4. +5V (pin 21) 166c0b4e3abSDarrick J. Wong * 5. +1.25V/+0.9V (pin 19) 167c0b4e3abSDarrick J. Wong * 6. +2.5V/+1.8V (pin 15) 168c0b4e3abSDarrick J. Wong * 7. +3.3v (pin 13) 169c0b4e3abSDarrick J. Wong * 8. +12V2 (pin 8) 170c0b4e3abSDarrick J. Wong * 9. Vbatt/FSB_Vtt (pin 26) 171c0b4e3abSDarrick J. Wong * A. +3.3V/+1.2V1 (pin 25) 172c0b4e3abSDarrick J. Wong * B. Vccp2/+2.5V/+1.8V/+1.5V (pin 24) 173c0b4e3abSDarrick J. Wong * C. +1.5V ICH (only if BOTH pin 28/29 are set to +1.5V) 174c0b4e3abSDarrick J. Wong * D. +1.5V 3GPIO (only if BOTH pin 28/29 are set to +1.5V) 175c0b4e3abSDarrick J. Wong * 176c0b4e3abSDarrick J. Wong * Each of these 13 has a factor to convert raw to voltage. Even better, 177c0b4e3abSDarrick J. Wong * the pins can be connected to other sensors (tach/gpio/hot/etc), which 178c0b4e3abSDarrick J. Wong * makes the bookkeeping tricky. 179c0b4e3abSDarrick J. Wong * 180c0b4e3abSDarrick J. Wong * Some, but not all, of these voltages have low/high limits. 181c0b4e3abSDarrick J. Wong */ 18285f8d3e5SRay Copeland #define ADT7462_VOLT_COUNT 13 183c0b4e3abSDarrick J. Wong 184c0b4e3abSDarrick J. Wong #define ADT7462_VENDOR 0x41 185c0b4e3abSDarrick J. Wong #define ADT7462_DEVICE 0x62 186c0b4e3abSDarrick J. Wong /* datasheet only mentions a revision 4 */ 187c0b4e3abSDarrick J. Wong #define ADT7462_REVISION 0x04 188c0b4e3abSDarrick J. Wong 189c0b4e3abSDarrick J. Wong /* How often do we reread sensors values? (In jiffies) */ 190c0b4e3abSDarrick J. Wong #define SENSOR_REFRESH_INTERVAL (2 * HZ) 191c0b4e3abSDarrick J. Wong 192c0b4e3abSDarrick J. Wong /* How often do we reread sensor limit values? (In jiffies) */ 193c0b4e3abSDarrick J. Wong #define LIMIT_REFRESH_INTERVAL (60 * HZ) 194c0b4e3abSDarrick J. Wong 195c0b4e3abSDarrick J. Wong /* datasheet says to divide this number by the fan reading to get fan rpm */ 196c0b4e3abSDarrick J. Wong #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) 197c0b4e3abSDarrick J. Wong #define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM 198c0b4e3abSDarrick J. Wong #define FAN_PERIOD_INVALID 65535 199c0b4e3abSDarrick J. Wong #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) 200c0b4e3abSDarrick J. Wong 201c0b4e3abSDarrick J. Wong #define MASK_AND_SHIFT(value, prefix) \ 202c0b4e3abSDarrick J. Wong (((value) & prefix##_MASK) >> prefix##_SHIFT) 203c0b4e3abSDarrick J. Wong 204c0b4e3abSDarrick J. Wong struct adt7462_data { 205573bfe67SAxel Lin struct i2c_client *client; 206c0b4e3abSDarrick J. Wong struct mutex lock; 207c0b4e3abSDarrick J. Wong char sensors_valid; 208c0b4e3abSDarrick J. Wong char limits_valid; 209c0b4e3abSDarrick J. Wong unsigned long sensors_last_updated; /* In jiffies */ 210c0b4e3abSDarrick J. Wong unsigned long limits_last_updated; /* In jiffies */ 211c0b4e3abSDarrick J. Wong 212c0b4e3abSDarrick J. Wong u8 temp[ADT7462_TEMP_COUNT]; 213c0b4e3abSDarrick J. Wong /* bits 6-7 are quarter pieces of temp */ 214c0b4e3abSDarrick J. Wong u8 temp_frac[ADT7462_TEMP_COUNT]; 215c0b4e3abSDarrick J. Wong u8 temp_min[ADT7462_TEMP_COUNT]; 216c0b4e3abSDarrick J. Wong u8 temp_max[ADT7462_TEMP_COUNT]; 217c0b4e3abSDarrick J. Wong u16 fan[ADT7462_FAN_COUNT]; 218c0b4e3abSDarrick J. Wong u8 fan_enabled; 219c0b4e3abSDarrick J. Wong u8 fan_min[ADT7462_FAN_COUNT]; 220c0b4e3abSDarrick J. Wong u8 cfg2; 221c0b4e3abSDarrick J. Wong u8 pwm[ADT7462_PWM_COUNT]; 222c0b4e3abSDarrick J. Wong u8 pin_cfg[ADT7462_PIN_CFG_REG_COUNT]; 223c0b4e3abSDarrick J. Wong u8 voltages[ADT7462_VOLT_COUNT]; 224c0b4e3abSDarrick J. Wong u8 volt_max[ADT7462_VOLT_COUNT]; 225c0b4e3abSDarrick J. Wong u8 volt_min[ADT7462_VOLT_COUNT]; 226c0b4e3abSDarrick J. Wong u8 pwm_min[ADT7462_PWM_COUNT]; 227c0b4e3abSDarrick J. Wong u8 pwm_tmin[ADT7462_PWM_COUNT]; 228c0b4e3abSDarrick J. Wong u8 pwm_trange[ADT7462_PWM_COUNT]; 229c0b4e3abSDarrick J. Wong u8 pwm_max; /* only one per chip */ 230c0b4e3abSDarrick J. Wong u8 pwm_cfg[ADT7462_PWM_COUNT]; 231c0b4e3abSDarrick J. Wong u8 alarms[ADT7462_ALARM_REG_COUNT]; 232c0b4e3abSDarrick J. Wong }; 233c0b4e3abSDarrick J. Wong 234c0b4e3abSDarrick J. Wong /* 235c0b4e3abSDarrick J. Wong * 16-bit registers on the ADT7462 are low-byte first. The data sheet says 236c0b4e3abSDarrick J. Wong * that the low byte must be read before the high byte. 237c0b4e3abSDarrick J. Wong */ 238c0b4e3abSDarrick J. Wong static inline int adt7462_read_word_data(struct i2c_client *client, u8 reg) 239c0b4e3abSDarrick J. Wong { 240c0b4e3abSDarrick J. Wong u16 foo; 241c0b4e3abSDarrick J. Wong foo = i2c_smbus_read_byte_data(client, reg); 242c0b4e3abSDarrick J. Wong foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8); 243c0b4e3abSDarrick J. Wong return foo; 244c0b4e3abSDarrick J. Wong } 245c0b4e3abSDarrick J. Wong 246c0b4e3abSDarrick J. Wong /* For some reason these registers are not contiguous. */ 247c0b4e3abSDarrick J. Wong static int ADT7462_REG_FAN(int fan) 248c0b4e3abSDarrick J. Wong { 249c0b4e3abSDarrick J. Wong if (fan < 4) 250c0b4e3abSDarrick J. Wong return ADT7462_REG_FAN_BASE_ADDR + (2 * fan); 251c0b4e3abSDarrick J. Wong return ADT7462_REG_FAN2_BASE_ADDR + (2 * (fan - 4)); 252c0b4e3abSDarrick J. Wong } 253c0b4e3abSDarrick J. Wong 254c0b4e3abSDarrick J. Wong /* Voltage registers are scattered everywhere */ 255c0b4e3abSDarrick J. Wong static int ADT7462_REG_VOLT_MAX(struct adt7462_data *data, int which) 256c0b4e3abSDarrick J. Wong { 257c0b4e3abSDarrick J. Wong switch (which) { 258c0b4e3abSDarrick J. Wong case 0: 259c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) 260c0b4e3abSDarrick J. Wong return 0x7C; 261c0b4e3abSDarrick J. Wong break; 262c0b4e3abSDarrick J. Wong case 1: 263c0b4e3abSDarrick J. Wong return 0x69; 264c0b4e3abSDarrick J. Wong case 2: 265c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) 266c0b4e3abSDarrick J. Wong return 0x7F; 267c0b4e3abSDarrick J. Wong break; 268c0b4e3abSDarrick J. Wong case 3: 269c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) 270c0b4e3abSDarrick J. Wong return 0x7E; 271c0b4e3abSDarrick J. Wong break; 272c0b4e3abSDarrick J. Wong case 4: 273c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) 274c0b4e3abSDarrick J. Wong return 0x4B; 275c0b4e3abSDarrick J. Wong break; 276c0b4e3abSDarrick J. Wong case 5: 277c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) 278c0b4e3abSDarrick J. Wong return 0x49; 279c0b4e3abSDarrick J. Wong break; 280c0b4e3abSDarrick J. Wong case 6: 281c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) 282c0b4e3abSDarrick J. Wong return 0x68; 283c0b4e3abSDarrick J. Wong break; 284c0b4e3abSDarrick J. Wong case 7: 285c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) 286c0b4e3abSDarrick J. Wong return 0x7D; 287c0b4e3abSDarrick J. Wong break; 288c0b4e3abSDarrick J. Wong case 8: 289c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) 290c0b4e3abSDarrick J. Wong return 0x6C; 291c0b4e3abSDarrick J. Wong break; 292c0b4e3abSDarrick J. Wong case 9: 293c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) 294c0b4e3abSDarrick J. Wong return 0x6B; 295c0b4e3abSDarrick J. Wong break; 296c0b4e3abSDarrick J. Wong case 10: 297c0b4e3abSDarrick J. Wong return 0x6A; 298c0b4e3abSDarrick J. Wong case 11: 299c0b4e3abSDarrick J. Wong if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == 300c0b4e3abSDarrick J. Wong ADT7462_PIN28_VOLT && 301c0b4e3abSDarrick J. Wong !(data->pin_cfg[0] & ADT7462_VID_INPUT)) 302c0b4e3abSDarrick J. Wong return 0x50; 303c0b4e3abSDarrick J. Wong break; 304c0b4e3abSDarrick J. Wong case 12: 305c0b4e3abSDarrick J. Wong if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == 306c0b4e3abSDarrick J. Wong ADT7462_PIN28_VOLT && 307c0b4e3abSDarrick J. Wong !(data->pin_cfg[0] & ADT7462_VID_INPUT)) 308c0b4e3abSDarrick J. Wong return 0x4C; 309c0b4e3abSDarrick J. Wong break; 310c0b4e3abSDarrick J. Wong } 311a4bf06d5SDan Carpenter return 0; 312c0b4e3abSDarrick J. Wong } 313c0b4e3abSDarrick J. Wong 314c0b4e3abSDarrick J. Wong static int ADT7462_REG_VOLT_MIN(struct adt7462_data *data, int which) 315c0b4e3abSDarrick J. Wong { 316c0b4e3abSDarrick J. Wong switch (which) { 317c0b4e3abSDarrick J. Wong case 0: 318c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) 319c0b4e3abSDarrick J. Wong return 0x6D; 320c0b4e3abSDarrick J. Wong break; 321c0b4e3abSDarrick J. Wong case 1: 322c0b4e3abSDarrick J. Wong return 0x72; 323c0b4e3abSDarrick J. Wong case 2: 324c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) 325c0b4e3abSDarrick J. Wong return 0x6F; 326c0b4e3abSDarrick J. Wong break; 327c0b4e3abSDarrick J. Wong case 3: 328c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) 329c0b4e3abSDarrick J. Wong return 0x71; 330c0b4e3abSDarrick J. Wong break; 331c0b4e3abSDarrick J. Wong case 4: 332c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) 333c0b4e3abSDarrick J. Wong return 0x47; 334c0b4e3abSDarrick J. Wong break; 335c0b4e3abSDarrick J. Wong case 5: 336c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) 337c0b4e3abSDarrick J. Wong return 0x45; 338c0b4e3abSDarrick J. Wong break; 339c0b4e3abSDarrick J. Wong case 6: 340c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) 341c0b4e3abSDarrick J. Wong return 0x70; 342c0b4e3abSDarrick J. Wong break; 343c0b4e3abSDarrick J. Wong case 7: 344c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) 345c0b4e3abSDarrick J. Wong return 0x6E; 346c0b4e3abSDarrick J. Wong break; 347c0b4e3abSDarrick J. Wong case 8: 348c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) 349c0b4e3abSDarrick J. Wong return 0x75; 350c0b4e3abSDarrick J. Wong break; 351c0b4e3abSDarrick J. Wong case 9: 352c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) 353c0b4e3abSDarrick J. Wong return 0x74; 354c0b4e3abSDarrick J. Wong break; 355c0b4e3abSDarrick J. Wong case 10: 356c0b4e3abSDarrick J. Wong return 0x73; 357c0b4e3abSDarrick J. Wong case 11: 358c0b4e3abSDarrick J. Wong if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == 359c0b4e3abSDarrick J. Wong ADT7462_PIN28_VOLT && 360c0b4e3abSDarrick J. Wong !(data->pin_cfg[0] & ADT7462_VID_INPUT)) 361c0b4e3abSDarrick J. Wong return 0x76; 362c0b4e3abSDarrick J. Wong break; 363c0b4e3abSDarrick J. Wong case 12: 364c0b4e3abSDarrick J. Wong if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == 365c0b4e3abSDarrick J. Wong ADT7462_PIN28_VOLT && 366c0b4e3abSDarrick J. Wong !(data->pin_cfg[0] & ADT7462_VID_INPUT)) 367c0b4e3abSDarrick J. Wong return 0x77; 368c0b4e3abSDarrick J. Wong break; 369c0b4e3abSDarrick J. Wong } 370a4bf06d5SDan Carpenter return 0; 371c0b4e3abSDarrick J. Wong } 372c0b4e3abSDarrick J. Wong 373c0b4e3abSDarrick J. Wong static int ADT7462_REG_VOLT(struct adt7462_data *data, int which) 374c0b4e3abSDarrick J. Wong { 375c0b4e3abSDarrick J. Wong switch (which) { 376c0b4e3abSDarrick J. Wong case 0: 377c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) 378c0b4e3abSDarrick J. Wong return 0xA3; 379c0b4e3abSDarrick J. Wong break; 380c0b4e3abSDarrick J. Wong case 1: 381c0b4e3abSDarrick J. Wong return 0x90; 382c0b4e3abSDarrick J. Wong case 2: 383c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) 384c0b4e3abSDarrick J. Wong return 0xA9; 385c0b4e3abSDarrick J. Wong break; 386c0b4e3abSDarrick J. Wong case 3: 387c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) 388c0b4e3abSDarrick J. Wong return 0xA7; 389c0b4e3abSDarrick J. Wong break; 390c0b4e3abSDarrick J. Wong case 4: 391c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) 392c0b4e3abSDarrick J. Wong return 0x8F; 393c0b4e3abSDarrick J. Wong break; 394c0b4e3abSDarrick J. Wong case 5: 395c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) 396c0b4e3abSDarrick J. Wong return 0x8B; 397c0b4e3abSDarrick J. Wong break; 398c0b4e3abSDarrick J. Wong case 6: 399c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) 400c0b4e3abSDarrick J. Wong return 0x96; 401c0b4e3abSDarrick J. Wong break; 402c0b4e3abSDarrick J. Wong case 7: 403c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) 404c0b4e3abSDarrick J. Wong return 0xA5; 405c0b4e3abSDarrick J. Wong break; 406c0b4e3abSDarrick J. Wong case 8: 407c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) 408c0b4e3abSDarrick J. Wong return 0x93; 409c0b4e3abSDarrick J. Wong break; 410c0b4e3abSDarrick J. Wong case 9: 411c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) 412c0b4e3abSDarrick J. Wong return 0x92; 413c0b4e3abSDarrick J. Wong break; 414c0b4e3abSDarrick J. Wong case 10: 415c0b4e3abSDarrick J. Wong return 0x91; 416c0b4e3abSDarrick J. Wong case 11: 417c0b4e3abSDarrick J. Wong if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == 418c0b4e3abSDarrick J. Wong ADT7462_PIN28_VOLT && 419c0b4e3abSDarrick J. Wong !(data->pin_cfg[0] & ADT7462_VID_INPUT)) 420c0b4e3abSDarrick J. Wong return 0x94; 421c0b4e3abSDarrick J. Wong break; 422c0b4e3abSDarrick J. Wong case 12: 423c0b4e3abSDarrick J. Wong if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == 424c0b4e3abSDarrick J. Wong ADT7462_PIN28_VOLT && 425c0b4e3abSDarrick J. Wong !(data->pin_cfg[0] & ADT7462_VID_INPUT)) 426c0b4e3abSDarrick J. Wong return 0x95; 427c0b4e3abSDarrick J. Wong break; 428c0b4e3abSDarrick J. Wong } 429c0b4e3abSDarrick J. Wong return -ENODEV; 430c0b4e3abSDarrick J. Wong } 431c0b4e3abSDarrick J. Wong 432c0b4e3abSDarrick J. Wong /* Provide labels for sysfs */ 433c0b4e3abSDarrick J. Wong static const char *voltage_label(struct adt7462_data *data, int which) 434c0b4e3abSDarrick J. Wong { 435c0b4e3abSDarrick J. Wong switch (which) { 436c0b4e3abSDarrick J. Wong case 0: 437c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) 438c0b4e3abSDarrick J. Wong return "+12V1"; 439c0b4e3abSDarrick J. Wong break; 440c0b4e3abSDarrick J. Wong case 1: 441c0b4e3abSDarrick J. Wong switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { 442c0b4e3abSDarrick J. Wong case 0: 443c0b4e3abSDarrick J. Wong return "Vccp1"; 444c0b4e3abSDarrick J. Wong case 1: 445c0b4e3abSDarrick J. Wong return "+2.5V"; 446c0b4e3abSDarrick J. Wong case 2: 447c0b4e3abSDarrick J. Wong return "+1.8V"; 448c0b4e3abSDarrick J. Wong case 3: 449c0b4e3abSDarrick J. Wong return "+1.5V"; 450c0b4e3abSDarrick J. Wong } 451c0b4e3abSDarrick J. Wong case 2: 452c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) 453c0b4e3abSDarrick J. Wong return "+12V3"; 454c0b4e3abSDarrick J. Wong break; 455c0b4e3abSDarrick J. Wong case 3: 456c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) 457c0b4e3abSDarrick J. Wong return "+5V"; 458c0b4e3abSDarrick J. Wong break; 459c0b4e3abSDarrick J. Wong case 4: 460c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { 461c0b4e3abSDarrick J. Wong if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) 462c0b4e3abSDarrick J. Wong return "+0.9V"; 463c0b4e3abSDarrick J. Wong return "+1.25V"; 464c0b4e3abSDarrick J. Wong } 465c0b4e3abSDarrick J. Wong break; 466c0b4e3abSDarrick J. Wong case 5: 467c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { 468c0b4e3abSDarrick J. Wong if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) 469c0b4e3abSDarrick J. Wong return "+1.8V"; 470c0b4e3abSDarrick J. Wong return "+2.5V"; 471c0b4e3abSDarrick J. Wong } 472c0b4e3abSDarrick J. Wong break; 473c0b4e3abSDarrick J. Wong case 6: 474c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) 475c0b4e3abSDarrick J. Wong return "+3.3V"; 476c0b4e3abSDarrick J. Wong break; 477c0b4e3abSDarrick J. Wong case 7: 478c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) 479c0b4e3abSDarrick J. Wong return "+12V2"; 480c0b4e3abSDarrick J. Wong break; 481c0b4e3abSDarrick J. Wong case 8: 482c0b4e3abSDarrick J. Wong switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { 483c0b4e3abSDarrick J. Wong case 0: 484c0b4e3abSDarrick J. Wong return "Vbatt"; 485c0b4e3abSDarrick J. Wong case 1: 486c0b4e3abSDarrick J. Wong return "FSB_Vtt"; 487c0b4e3abSDarrick J. Wong } 488c0b4e3abSDarrick J. Wong break; 489c0b4e3abSDarrick J. Wong case 9: 490c0b4e3abSDarrick J. Wong switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { 491c0b4e3abSDarrick J. Wong case 0: 492c0b4e3abSDarrick J. Wong return "+3.3V"; 493c0b4e3abSDarrick J. Wong case 1: 494c0b4e3abSDarrick J. Wong return "+1.2V1"; 495c0b4e3abSDarrick J. Wong } 496c0b4e3abSDarrick J. Wong break; 497c0b4e3abSDarrick J. Wong case 10: 498c0b4e3abSDarrick J. Wong switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { 499c0b4e3abSDarrick J. Wong case 0: 500c0b4e3abSDarrick J. Wong return "Vccp2"; 501c0b4e3abSDarrick J. Wong case 1: 502c0b4e3abSDarrick J. Wong return "+2.5V"; 503c0b4e3abSDarrick J. Wong case 2: 504c0b4e3abSDarrick J. Wong return "+1.8V"; 505c0b4e3abSDarrick J. Wong case 3: 506c0b4e3abSDarrick J. Wong return "+1.5"; 507c0b4e3abSDarrick J. Wong } 508c0b4e3abSDarrick J. Wong case 11: 509c0b4e3abSDarrick J. Wong if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == 510c0b4e3abSDarrick J. Wong ADT7462_PIN28_VOLT && 511c0b4e3abSDarrick J. Wong !(data->pin_cfg[0] & ADT7462_VID_INPUT)) 512c0b4e3abSDarrick J. Wong return "+1.5V ICH"; 513c0b4e3abSDarrick J. Wong break; 514c0b4e3abSDarrick J. Wong case 12: 515c0b4e3abSDarrick J. Wong if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == 516c0b4e3abSDarrick J. Wong ADT7462_PIN28_VOLT && 517c0b4e3abSDarrick J. Wong !(data->pin_cfg[0] & ADT7462_VID_INPUT)) 518c0b4e3abSDarrick J. Wong return "+1.5V 3GPIO"; 519c0b4e3abSDarrick J. Wong break; 520c0b4e3abSDarrick J. Wong } 521c0b4e3abSDarrick J. Wong return "N/A"; 522c0b4e3abSDarrick J. Wong } 523c0b4e3abSDarrick J. Wong 524c0b4e3abSDarrick J. Wong /* Multipliers are actually in uV, not mV. */ 525c0b4e3abSDarrick J. Wong static int voltage_multiplier(struct adt7462_data *data, int which) 526c0b4e3abSDarrick J. Wong { 527c0b4e3abSDarrick J. Wong switch (which) { 528c0b4e3abSDarrick J. Wong case 0: 529c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) 530c0b4e3abSDarrick J. Wong return 62500; 531c0b4e3abSDarrick J. Wong break; 532c0b4e3abSDarrick J. Wong case 1: 533c0b4e3abSDarrick J. Wong switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { 534c0b4e3abSDarrick J. Wong case 0: 535c0b4e3abSDarrick J. Wong if (data->pin_cfg[0] & ADT7462_VID_INPUT) 536c0b4e3abSDarrick J. Wong return 12500; 537c0b4e3abSDarrick J. Wong return 6250; 538c0b4e3abSDarrick J. Wong case 1: 539c0b4e3abSDarrick J. Wong return 13000; 540c0b4e3abSDarrick J. Wong case 2: 541c0b4e3abSDarrick J. Wong return 9400; 542c0b4e3abSDarrick J. Wong case 3: 543c0b4e3abSDarrick J. Wong return 7800; 544c0b4e3abSDarrick J. Wong } 545c0b4e3abSDarrick J. Wong case 2: 546c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) 547c0b4e3abSDarrick J. Wong return 62500; 548c0b4e3abSDarrick J. Wong break; 549c0b4e3abSDarrick J. Wong case 3: 550c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) 551c0b4e3abSDarrick J. Wong return 26000; 552c0b4e3abSDarrick J. Wong break; 553c0b4e3abSDarrick J. Wong case 4: 554c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { 555c0b4e3abSDarrick J. Wong if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) 556c0b4e3abSDarrick J. Wong return 4690; 557c0b4e3abSDarrick J. Wong return 6500; 558c0b4e3abSDarrick J. Wong } 559c0b4e3abSDarrick J. Wong break; 560c0b4e3abSDarrick J. Wong case 5: 561c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { 562c0b4e3abSDarrick J. Wong if (data->pin_cfg[1] & ADT7462_PIN15_INPUT) 563c0b4e3abSDarrick J. Wong return 9400; 564c0b4e3abSDarrick J. Wong return 13000; 565c0b4e3abSDarrick J. Wong } 566c0b4e3abSDarrick J. Wong break; 567c0b4e3abSDarrick J. Wong case 6: 568c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) 569c0b4e3abSDarrick J. Wong return 17200; 570c0b4e3abSDarrick J. Wong break; 571c0b4e3abSDarrick J. Wong case 7: 572c0b4e3abSDarrick J. Wong if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) 573c0b4e3abSDarrick J. Wong return 62500; 574c0b4e3abSDarrick J. Wong break; 575c0b4e3abSDarrick J. Wong case 8: 576c0b4e3abSDarrick J. Wong switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { 577c0b4e3abSDarrick J. Wong case 0: 578c0b4e3abSDarrick J. Wong return 15600; 579c0b4e3abSDarrick J. Wong case 1: 580c0b4e3abSDarrick J. Wong return 6250; 581c0b4e3abSDarrick J. Wong } 582c0b4e3abSDarrick J. Wong break; 583c0b4e3abSDarrick J. Wong case 9: 584c0b4e3abSDarrick J. Wong switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { 585c0b4e3abSDarrick J. Wong case 0: 586c0b4e3abSDarrick J. Wong return 17200; 587c0b4e3abSDarrick J. Wong case 1: 588c0b4e3abSDarrick J. Wong return 6250; 589c0b4e3abSDarrick J. Wong } 590c0b4e3abSDarrick J. Wong break; 591c0b4e3abSDarrick J. Wong case 10: 592c0b4e3abSDarrick J. Wong switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { 593c0b4e3abSDarrick J. Wong case 0: 594c0b4e3abSDarrick J. Wong return 6250; 595c0b4e3abSDarrick J. Wong case 1: 596c0b4e3abSDarrick J. Wong return 13000; 597c0b4e3abSDarrick J. Wong case 2: 598c0b4e3abSDarrick J. Wong return 9400; 599c0b4e3abSDarrick J. Wong case 3: 600c0b4e3abSDarrick J. Wong return 7800; 601c0b4e3abSDarrick J. Wong } 602c0b4e3abSDarrick J. Wong case 11: 603c0b4e3abSDarrick J. Wong case 12: 604c0b4e3abSDarrick J. Wong if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == 605c0b4e3abSDarrick J. Wong ADT7462_PIN28_VOLT && 606c0b4e3abSDarrick J. Wong !(data->pin_cfg[0] & ADT7462_VID_INPUT)) 607c0b4e3abSDarrick J. Wong return 7800; 608c0b4e3abSDarrick J. Wong } 609c0b4e3abSDarrick J. Wong return 0; 610c0b4e3abSDarrick J. Wong } 611c0b4e3abSDarrick J. Wong 612c0b4e3abSDarrick J. Wong static int temp_enabled(struct adt7462_data *data, int which) 613c0b4e3abSDarrick J. Wong { 614c0b4e3abSDarrick J. Wong switch (which) { 615c0b4e3abSDarrick J. Wong case 0: 616c0b4e3abSDarrick J. Wong case 2: 617c0b4e3abSDarrick J. Wong return 1; 618c0b4e3abSDarrick J. Wong case 1: 619c0b4e3abSDarrick J. Wong if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) 620c0b4e3abSDarrick J. Wong return 1; 621c0b4e3abSDarrick J. Wong break; 622c0b4e3abSDarrick J. Wong case 3: 623c0b4e3abSDarrick J. Wong if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) 624c0b4e3abSDarrick J. Wong return 1; 625c0b4e3abSDarrick J. Wong break; 626c0b4e3abSDarrick J. Wong } 627c0b4e3abSDarrick J. Wong return 0; 628c0b4e3abSDarrick J. Wong } 629c0b4e3abSDarrick J. Wong 630c0b4e3abSDarrick J. Wong static const char *temp_label(struct adt7462_data *data, int which) 631c0b4e3abSDarrick J. Wong { 632c0b4e3abSDarrick J. Wong switch (which) { 633c0b4e3abSDarrick J. Wong case 0: 634c0b4e3abSDarrick J. Wong return "local"; 635c0b4e3abSDarrick J. Wong case 1: 636c0b4e3abSDarrick J. Wong if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) 637c0b4e3abSDarrick J. Wong return "remote1"; 638c0b4e3abSDarrick J. Wong break; 639c0b4e3abSDarrick J. Wong case 2: 640c0b4e3abSDarrick J. Wong return "remote2"; 641c0b4e3abSDarrick J. Wong case 3: 642c0b4e3abSDarrick J. Wong if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) 643c0b4e3abSDarrick J. Wong return "remote3"; 644c0b4e3abSDarrick J. Wong break; 645c0b4e3abSDarrick J. Wong } 646c0b4e3abSDarrick J. Wong return "N/A"; 647c0b4e3abSDarrick J. Wong } 648c0b4e3abSDarrick J. Wong 649c0b4e3abSDarrick J. Wong /* Map Trange register values to mC */ 650c0b4e3abSDarrick J. Wong #define NUM_TRANGE_VALUES 16 651c0b4e3abSDarrick J. Wong static const int trange_values[NUM_TRANGE_VALUES] = { 652c0b4e3abSDarrick J. Wong 2000, 653c0b4e3abSDarrick J. Wong 2500, 654c0b4e3abSDarrick J. Wong 3300, 655c0b4e3abSDarrick J. Wong 4000, 656c0b4e3abSDarrick J. Wong 5000, 657c0b4e3abSDarrick J. Wong 6700, 658c0b4e3abSDarrick J. Wong 8000, 659c0b4e3abSDarrick J. Wong 10000, 660c0b4e3abSDarrick J. Wong 13300, 661c0b4e3abSDarrick J. Wong 16000, 662c0b4e3abSDarrick J. Wong 20000, 663c0b4e3abSDarrick J. Wong 26700, 664c0b4e3abSDarrick J. Wong 32000, 665c0b4e3abSDarrick J. Wong 40000, 666c0b4e3abSDarrick J. Wong 53300, 667c0b4e3abSDarrick J. Wong 80000 668c0b4e3abSDarrick J. Wong }; 669c0b4e3abSDarrick J. Wong 670c0b4e3abSDarrick J. Wong static int find_trange_value(int trange) 671c0b4e3abSDarrick J. Wong { 672c0b4e3abSDarrick J. Wong int i; 673c0b4e3abSDarrick J. Wong 674c0b4e3abSDarrick J. Wong for (i = 0; i < NUM_TRANGE_VALUES; i++) 675c0b4e3abSDarrick J. Wong if (trange_values[i] == trange) 676c0b4e3abSDarrick J. Wong return i; 677c0b4e3abSDarrick J. Wong 678bb34c0daSGuenter Roeck return -EINVAL; 679c0b4e3abSDarrick J. Wong } 680c0b4e3abSDarrick J. Wong 681c0b4e3abSDarrick J. Wong static struct adt7462_data *adt7462_update_device(struct device *dev) 682c0b4e3abSDarrick J. Wong { 683573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 684573bfe67SAxel Lin struct i2c_client *client = data->client; 685c0b4e3abSDarrick J. Wong unsigned long local_jiffies = jiffies; 686c0b4e3abSDarrick J. Wong int i; 687c0b4e3abSDarrick J. Wong 688c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 689c0b4e3abSDarrick J. Wong if (time_before(local_jiffies, data->sensors_last_updated + 690c0b4e3abSDarrick J. Wong SENSOR_REFRESH_INTERVAL) 691c0b4e3abSDarrick J. Wong && data->sensors_valid) 692c0b4e3abSDarrick J. Wong goto no_sensor_update; 693c0b4e3abSDarrick J. Wong 694c0b4e3abSDarrick J. Wong for (i = 0; i < ADT7462_TEMP_COUNT; i++) { 695c0b4e3abSDarrick J. Wong /* 696c0b4e3abSDarrick J. Wong * Reading the fractional register locks the integral 697c0b4e3abSDarrick J. Wong * register until both have been read. 698c0b4e3abSDarrick J. Wong */ 699c0b4e3abSDarrick J. Wong data->temp_frac[i] = i2c_smbus_read_byte_data(client, 700c0b4e3abSDarrick J. Wong ADT7462_TEMP_REG(i)); 701c0b4e3abSDarrick J. Wong data->temp[i] = i2c_smbus_read_byte_data(client, 702c0b4e3abSDarrick J. Wong ADT7462_TEMP_REG(i) + 1); 703c0b4e3abSDarrick J. Wong } 704c0b4e3abSDarrick J. Wong 705c0b4e3abSDarrick J. Wong for (i = 0; i < ADT7462_FAN_COUNT; i++) 706c0b4e3abSDarrick J. Wong data->fan[i] = adt7462_read_word_data(client, 707c0b4e3abSDarrick J. Wong ADT7462_REG_FAN(i)); 708c0b4e3abSDarrick J. Wong 709c0b4e3abSDarrick J. Wong data->fan_enabled = i2c_smbus_read_byte_data(client, 710c0b4e3abSDarrick J. Wong ADT7462_REG_FAN_ENABLE); 711c0b4e3abSDarrick J. Wong 712c0b4e3abSDarrick J. Wong for (i = 0; i < ADT7462_PWM_COUNT; i++) 713c0b4e3abSDarrick J. Wong data->pwm[i] = i2c_smbus_read_byte_data(client, 714c0b4e3abSDarrick J. Wong ADT7462_REG_PWM(i)); 715c0b4e3abSDarrick J. Wong 716c0b4e3abSDarrick J. Wong for (i = 0; i < ADT7462_PIN_CFG_REG_COUNT; i++) 717c0b4e3abSDarrick J. Wong data->pin_cfg[i] = i2c_smbus_read_byte_data(client, 718c0b4e3abSDarrick J. Wong ADT7462_REG_PIN_CFG(i)); 719c0b4e3abSDarrick J. Wong 720c0b4e3abSDarrick J. Wong for (i = 0; i < ADT7462_VOLT_COUNT; i++) { 721c0b4e3abSDarrick J. Wong int reg = ADT7462_REG_VOLT(data, i); 722c0b4e3abSDarrick J. Wong if (!reg) 723c0b4e3abSDarrick J. Wong data->voltages[i] = 0; 724c0b4e3abSDarrick J. Wong else 725c0b4e3abSDarrick J. Wong data->voltages[i] = i2c_smbus_read_byte_data(client, 726c0b4e3abSDarrick J. Wong reg); 727c0b4e3abSDarrick J. Wong } 728c0b4e3abSDarrick J. Wong 729c0b4e3abSDarrick J. Wong data->alarms[0] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM1); 730c0b4e3abSDarrick J. Wong data->alarms[1] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM2); 731c0b4e3abSDarrick J. Wong data->alarms[2] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM3); 732c0b4e3abSDarrick J. Wong data->alarms[3] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM4); 733c0b4e3abSDarrick J. Wong 734c0b4e3abSDarrick J. Wong data->sensors_last_updated = local_jiffies; 735c0b4e3abSDarrick J. Wong data->sensors_valid = 1; 736c0b4e3abSDarrick J. Wong 737c0b4e3abSDarrick J. Wong no_sensor_update: 738c0b4e3abSDarrick J. Wong if (time_before(local_jiffies, data->limits_last_updated + 739c0b4e3abSDarrick J. Wong LIMIT_REFRESH_INTERVAL) 740c0b4e3abSDarrick J. Wong && data->limits_valid) 741c0b4e3abSDarrick J. Wong goto out; 742c0b4e3abSDarrick J. Wong 743c0b4e3abSDarrick J. Wong for (i = 0; i < ADT7462_TEMP_COUNT; i++) { 744c0b4e3abSDarrick J. Wong data->temp_min[i] = i2c_smbus_read_byte_data(client, 745c0b4e3abSDarrick J. Wong ADT7462_TEMP_MIN_REG(i)); 746c0b4e3abSDarrick J. Wong data->temp_max[i] = i2c_smbus_read_byte_data(client, 747c0b4e3abSDarrick J. Wong ADT7462_TEMP_MAX_REG(i)); 748c0b4e3abSDarrick J. Wong } 749c0b4e3abSDarrick J. Wong 750c0b4e3abSDarrick J. Wong for (i = 0; i < ADT7462_FAN_COUNT; i++) 751c0b4e3abSDarrick J. Wong data->fan_min[i] = i2c_smbus_read_byte_data(client, 752c0b4e3abSDarrick J. Wong ADT7462_REG_FAN_MIN(i)); 753c0b4e3abSDarrick J. Wong 754c0b4e3abSDarrick J. Wong for (i = 0; i < ADT7462_VOLT_COUNT; i++) { 755c0b4e3abSDarrick J. Wong int reg = ADT7462_REG_VOLT_MAX(data, i); 756c0b4e3abSDarrick J. Wong data->volt_max[i] = 757c0b4e3abSDarrick J. Wong (reg ? i2c_smbus_read_byte_data(client, reg) : 0); 758c0b4e3abSDarrick J. Wong 759c0b4e3abSDarrick J. Wong reg = ADT7462_REG_VOLT_MIN(data, i); 760c0b4e3abSDarrick J. Wong data->volt_min[i] = 761c0b4e3abSDarrick J. Wong (reg ? i2c_smbus_read_byte_data(client, reg) : 0); 762c0b4e3abSDarrick J. Wong } 763c0b4e3abSDarrick J. Wong 764c0b4e3abSDarrick J. Wong for (i = 0; i < ADT7462_PWM_COUNT; i++) { 765c0b4e3abSDarrick J. Wong data->pwm_min[i] = i2c_smbus_read_byte_data(client, 766c0b4e3abSDarrick J. Wong ADT7462_REG_PWM_MIN(i)); 767c0b4e3abSDarrick J. Wong data->pwm_tmin[i] = i2c_smbus_read_byte_data(client, 768c0b4e3abSDarrick J. Wong ADT7462_REG_PWM_TMIN(i)); 769c0b4e3abSDarrick J. Wong data->pwm_trange[i] = i2c_smbus_read_byte_data(client, 770c0b4e3abSDarrick J. Wong ADT7462_REG_PWM_TRANGE(i)); 771c0b4e3abSDarrick J. Wong data->pwm_cfg[i] = i2c_smbus_read_byte_data(client, 772c0b4e3abSDarrick J. Wong ADT7462_REG_PWM_CFG(i)); 773c0b4e3abSDarrick J. Wong } 774c0b4e3abSDarrick J. Wong 775c0b4e3abSDarrick J. Wong data->pwm_max = i2c_smbus_read_byte_data(client, ADT7462_REG_PWM_MAX); 776c0b4e3abSDarrick J. Wong 777c0b4e3abSDarrick J. Wong data->cfg2 = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); 778c0b4e3abSDarrick J. Wong 779c0b4e3abSDarrick J. Wong data->limits_last_updated = local_jiffies; 780c0b4e3abSDarrick J. Wong data->limits_valid = 1; 781c0b4e3abSDarrick J. Wong 782c0b4e3abSDarrick J. Wong out: 783c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 784c0b4e3abSDarrick J. Wong return data; 785c0b4e3abSDarrick J. Wong } 786c0b4e3abSDarrick J. Wong 787c0b4e3abSDarrick J. Wong static ssize_t show_temp_min(struct device *dev, 788c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 789c0b4e3abSDarrick J. Wong char *buf) 790c0b4e3abSDarrick J. Wong { 791c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 792c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 793c0b4e3abSDarrick J. Wong 794c0b4e3abSDarrick J. Wong if (!temp_enabled(data, attr->index)) 795c0b4e3abSDarrick J. Wong return sprintf(buf, "0\n"); 796c0b4e3abSDarrick J. Wong 797c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", 1000 * (data->temp_min[attr->index] - 64)); 798c0b4e3abSDarrick J. Wong } 799c0b4e3abSDarrick J. Wong 800c0b4e3abSDarrick J. Wong static ssize_t set_temp_min(struct device *dev, 801c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 802c0b4e3abSDarrick J. Wong const char *buf, 803c0b4e3abSDarrick J. Wong size_t count) 804c0b4e3abSDarrick J. Wong { 805c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 806573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 807573bfe67SAxel Lin struct i2c_client *client = data->client; 808c0b4e3abSDarrick J. Wong long temp; 809c0b4e3abSDarrick J. Wong 810179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) 811c0b4e3abSDarrick J. Wong return -EINVAL; 812c0b4e3abSDarrick J. Wong 813*b94793b4SGuenter Roeck temp = clamp_val(temp, -64000, 191000); 8148f8c1fb0SDarrick J. Wong temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; 815c0b4e3abSDarrick J. Wong 816c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 817c0b4e3abSDarrick J. Wong data->temp_min[attr->index] = temp; 818c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_TEMP_MIN_REG(attr->index), 819c0b4e3abSDarrick J. Wong temp); 820c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 821c0b4e3abSDarrick J. Wong 822c0b4e3abSDarrick J. Wong return count; 823c0b4e3abSDarrick J. Wong } 824c0b4e3abSDarrick J. Wong 825c0b4e3abSDarrick J. Wong static ssize_t show_temp_max(struct device *dev, 826c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 827c0b4e3abSDarrick J. Wong char *buf) 828c0b4e3abSDarrick J. Wong { 829c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 830c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 831c0b4e3abSDarrick J. Wong 832c0b4e3abSDarrick J. Wong if (!temp_enabled(data, attr->index)) 833c0b4e3abSDarrick J. Wong return sprintf(buf, "0\n"); 834c0b4e3abSDarrick J. Wong 835c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", 1000 * (data->temp_max[attr->index] - 64)); 836c0b4e3abSDarrick J. Wong } 837c0b4e3abSDarrick J. Wong 838c0b4e3abSDarrick J. Wong static ssize_t set_temp_max(struct device *dev, 839c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 840c0b4e3abSDarrick J. Wong const char *buf, 841c0b4e3abSDarrick J. Wong size_t count) 842c0b4e3abSDarrick J. Wong { 843c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 844573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 845573bfe67SAxel Lin struct i2c_client *client = data->client; 846c0b4e3abSDarrick J. Wong long temp; 847c0b4e3abSDarrick J. Wong 848179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) 849c0b4e3abSDarrick J. Wong return -EINVAL; 850c0b4e3abSDarrick J. Wong 851*b94793b4SGuenter Roeck temp = clamp_val(temp, -64000, 191000); 8528f8c1fb0SDarrick J. Wong temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; 853c0b4e3abSDarrick J. Wong 854c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 855c0b4e3abSDarrick J. Wong data->temp_max[attr->index] = temp; 856c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_TEMP_MAX_REG(attr->index), 857c0b4e3abSDarrick J. Wong temp); 858c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 859c0b4e3abSDarrick J. Wong 860c0b4e3abSDarrick J. Wong return count; 861c0b4e3abSDarrick J. Wong } 862c0b4e3abSDarrick J. Wong 863c0b4e3abSDarrick J. Wong static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, 864c0b4e3abSDarrick J. Wong char *buf) 865c0b4e3abSDarrick J. Wong { 866c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 867c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 868c0b4e3abSDarrick J. Wong u8 frac = data->temp_frac[attr->index] >> TEMP_FRAC_OFFSET; 869c0b4e3abSDarrick J. Wong 870c0b4e3abSDarrick J. Wong if (!temp_enabled(data, attr->index)) 871c0b4e3abSDarrick J. Wong return sprintf(buf, "0\n"); 872c0b4e3abSDarrick J. Wong 873c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", 1000 * (data->temp[attr->index] - 64) + 874c0b4e3abSDarrick J. Wong 250 * frac); 875c0b4e3abSDarrick J. Wong } 876c0b4e3abSDarrick J. Wong 877c0b4e3abSDarrick J. Wong static ssize_t show_temp_label(struct device *dev, 878c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 879c0b4e3abSDarrick J. Wong char *buf) 880c0b4e3abSDarrick J. Wong { 881c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 882c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 883c0b4e3abSDarrick J. Wong 884c0b4e3abSDarrick J. Wong return sprintf(buf, "%s\n", temp_label(data, attr->index)); 885c0b4e3abSDarrick J. Wong } 886c0b4e3abSDarrick J. Wong 887c0b4e3abSDarrick J. Wong static ssize_t show_volt_max(struct device *dev, 888c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 889c0b4e3abSDarrick J. Wong char *buf) 890c0b4e3abSDarrick J. Wong { 891c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 892c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 893c0b4e3abSDarrick J. Wong int x = voltage_multiplier(data, attr->index); 894c0b4e3abSDarrick J. Wong 895c0b4e3abSDarrick J. Wong x *= data->volt_max[attr->index]; 896c0b4e3abSDarrick J. Wong x /= 1000; /* convert from uV to mV */ 897c0b4e3abSDarrick J. Wong 898c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", x); 899c0b4e3abSDarrick J. Wong } 900c0b4e3abSDarrick J. Wong 901c0b4e3abSDarrick J. Wong static ssize_t set_volt_max(struct device *dev, 902c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 903c0b4e3abSDarrick J. Wong const char *buf, 904c0b4e3abSDarrick J. Wong size_t count) 905c0b4e3abSDarrick J. Wong { 906c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 907573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 908573bfe67SAxel Lin struct i2c_client *client = data->client; 909c0b4e3abSDarrick J. Wong int x = voltage_multiplier(data, attr->index); 910c0b4e3abSDarrick J. Wong long temp; 911c0b4e3abSDarrick J. Wong 912179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp) || !x) 913c0b4e3abSDarrick J. Wong return -EINVAL; 914c0b4e3abSDarrick J. Wong 915*b94793b4SGuenter Roeck temp = clamp_val(temp, 0, 255 * x / 1000); 916c0b4e3abSDarrick J. Wong temp *= 1000; /* convert mV to uV */ 9178f8c1fb0SDarrick J. Wong temp = DIV_ROUND_CLOSEST(temp, x); 918c0b4e3abSDarrick J. Wong 919c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 920c0b4e3abSDarrick J. Wong data->volt_max[attr->index] = temp; 921c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, 922c0b4e3abSDarrick J. Wong ADT7462_REG_VOLT_MAX(data, attr->index), 923c0b4e3abSDarrick J. Wong temp); 924c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 925c0b4e3abSDarrick J. Wong 926c0b4e3abSDarrick J. Wong return count; 927c0b4e3abSDarrick J. Wong } 928c0b4e3abSDarrick J. Wong 929c0b4e3abSDarrick J. Wong static ssize_t show_volt_min(struct device *dev, 930c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 931c0b4e3abSDarrick J. Wong char *buf) 932c0b4e3abSDarrick J. Wong { 933c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 934c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 935c0b4e3abSDarrick J. Wong int x = voltage_multiplier(data, attr->index); 936c0b4e3abSDarrick J. Wong 937c0b4e3abSDarrick J. Wong x *= data->volt_min[attr->index]; 938c0b4e3abSDarrick J. Wong x /= 1000; /* convert from uV to mV */ 939c0b4e3abSDarrick J. Wong 940c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", x); 941c0b4e3abSDarrick J. Wong } 942c0b4e3abSDarrick J. Wong 943c0b4e3abSDarrick J. Wong static ssize_t set_volt_min(struct device *dev, 944c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 945c0b4e3abSDarrick J. Wong const char *buf, 946c0b4e3abSDarrick J. Wong size_t count) 947c0b4e3abSDarrick J. Wong { 948c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 949573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 950573bfe67SAxel Lin struct i2c_client *client = data->client; 951c0b4e3abSDarrick J. Wong int x = voltage_multiplier(data, attr->index); 952c0b4e3abSDarrick J. Wong long temp; 953c0b4e3abSDarrick J. Wong 954179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp) || !x) 955c0b4e3abSDarrick J. Wong return -EINVAL; 956c0b4e3abSDarrick J. Wong 957*b94793b4SGuenter Roeck temp = clamp_val(temp, 0, 255 * x / 1000); 958c0b4e3abSDarrick J. Wong temp *= 1000; /* convert mV to uV */ 9598f8c1fb0SDarrick J. Wong temp = DIV_ROUND_CLOSEST(temp, x); 960c0b4e3abSDarrick J. Wong 961c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 962c0b4e3abSDarrick J. Wong data->volt_min[attr->index] = temp; 963c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, 964c0b4e3abSDarrick J. Wong ADT7462_REG_VOLT_MIN(data, attr->index), 965c0b4e3abSDarrick J. Wong temp); 966c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 967c0b4e3abSDarrick J. Wong 968c0b4e3abSDarrick J. Wong return count; 969c0b4e3abSDarrick J. Wong } 970c0b4e3abSDarrick J. Wong 971c0b4e3abSDarrick J. Wong static ssize_t show_voltage(struct device *dev, 972c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 973c0b4e3abSDarrick J. Wong char *buf) 974c0b4e3abSDarrick J. Wong { 975c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 976c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 977c0b4e3abSDarrick J. Wong int x = voltage_multiplier(data, attr->index); 978c0b4e3abSDarrick J. Wong 979c0b4e3abSDarrick J. Wong x *= data->voltages[attr->index]; 980c0b4e3abSDarrick J. Wong x /= 1000; /* convert from uV to mV */ 981c0b4e3abSDarrick J. Wong 982c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", x); 983c0b4e3abSDarrick J. Wong } 984c0b4e3abSDarrick J. Wong 985c0b4e3abSDarrick J. Wong static ssize_t show_voltage_label(struct device *dev, 986c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 987c0b4e3abSDarrick J. Wong char *buf) 988c0b4e3abSDarrick J. Wong { 989c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 990c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 991c0b4e3abSDarrick J. Wong 992c0b4e3abSDarrick J. Wong return sprintf(buf, "%s\n", voltage_label(data, attr->index)); 993c0b4e3abSDarrick J. Wong } 994c0b4e3abSDarrick J. Wong 995c0b4e3abSDarrick J. Wong static ssize_t show_alarm(struct device *dev, 996c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 997c0b4e3abSDarrick J. Wong char *buf) 998c0b4e3abSDarrick J. Wong { 999c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1000c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1001c0b4e3abSDarrick J. Wong int reg = attr->index >> ADT7462_ALARM_REG_SHIFT; 1002c0b4e3abSDarrick J. Wong int mask = attr->index & ADT7462_ALARM_FLAG_MASK; 1003c0b4e3abSDarrick J. Wong 1004c0b4e3abSDarrick J. Wong if (data->alarms[reg] & mask) 1005c0b4e3abSDarrick J. Wong return sprintf(buf, "1\n"); 1006c0b4e3abSDarrick J. Wong else 1007c0b4e3abSDarrick J. Wong return sprintf(buf, "0\n"); 1008c0b4e3abSDarrick J. Wong } 1009c0b4e3abSDarrick J. Wong 1010c0b4e3abSDarrick J. Wong static int fan_enabled(struct adt7462_data *data, int fan) 1011c0b4e3abSDarrick J. Wong { 1012c0b4e3abSDarrick J. Wong return data->fan_enabled & (1 << fan); 1013c0b4e3abSDarrick J. Wong } 1014c0b4e3abSDarrick J. Wong 1015c0b4e3abSDarrick J. Wong static ssize_t show_fan_min(struct device *dev, 1016c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1017c0b4e3abSDarrick J. Wong char *buf) 1018c0b4e3abSDarrick J. Wong { 1019c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1020c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1021c0b4e3abSDarrick J. Wong u16 temp; 1022c0b4e3abSDarrick J. Wong 1023c0b4e3abSDarrick J. Wong /* Only the MSB of the min fan period is stored... */ 1024c0b4e3abSDarrick J. Wong temp = data->fan_min[attr->index]; 1025c0b4e3abSDarrick J. Wong temp <<= 8; 1026c0b4e3abSDarrick J. Wong 1027c0b4e3abSDarrick J. Wong if (!fan_enabled(data, attr->index) || 1028c0b4e3abSDarrick J. Wong !FAN_DATA_VALID(temp)) 1029c0b4e3abSDarrick J. Wong return sprintf(buf, "0\n"); 1030c0b4e3abSDarrick J. Wong 1031c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", FAN_PERIOD_TO_RPM(temp)); 1032c0b4e3abSDarrick J. Wong } 1033c0b4e3abSDarrick J. Wong 1034c0b4e3abSDarrick J. Wong static ssize_t set_fan_min(struct device *dev, 1035c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1036c0b4e3abSDarrick J. Wong const char *buf, size_t count) 1037c0b4e3abSDarrick J. Wong { 1038c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1039573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1040573bfe67SAxel Lin struct i2c_client *client = data->client; 1041c0b4e3abSDarrick J. Wong long temp; 1042c0b4e3abSDarrick J. Wong 1043179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp) || !temp || 1044c0b4e3abSDarrick J. Wong !fan_enabled(data, attr->index)) 1045c0b4e3abSDarrick J. Wong return -EINVAL; 1046c0b4e3abSDarrick J. Wong 1047c0b4e3abSDarrick J. Wong temp = FAN_RPM_TO_PERIOD(temp); 1048c0b4e3abSDarrick J. Wong temp >>= 8; 10492a844c14SGuenter Roeck temp = clamp_val(temp, 1, 255); 1050c0b4e3abSDarrick J. Wong 1051c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 1052c0b4e3abSDarrick J. Wong data->fan_min[attr->index] = temp; 1053c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_REG_FAN_MIN(attr->index), 1054c0b4e3abSDarrick J. Wong temp); 1055c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 1056c0b4e3abSDarrick J. Wong 1057c0b4e3abSDarrick J. Wong return count; 1058c0b4e3abSDarrick J. Wong } 1059c0b4e3abSDarrick J. Wong 1060c0b4e3abSDarrick J. Wong static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, 1061c0b4e3abSDarrick J. Wong char *buf) 1062c0b4e3abSDarrick J. Wong { 1063c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1064c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1065c0b4e3abSDarrick J. Wong 1066c0b4e3abSDarrick J. Wong if (!fan_enabled(data, attr->index) || 1067c0b4e3abSDarrick J. Wong !FAN_DATA_VALID(data->fan[attr->index])) 1068c0b4e3abSDarrick J. Wong return sprintf(buf, "0\n"); 1069c0b4e3abSDarrick J. Wong 1070c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", 1071c0b4e3abSDarrick J. Wong FAN_PERIOD_TO_RPM(data->fan[attr->index])); 1072c0b4e3abSDarrick J. Wong } 1073c0b4e3abSDarrick J. Wong 1074c0b4e3abSDarrick J. Wong static ssize_t show_force_pwm_max(struct device *dev, 1075c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1076c0b4e3abSDarrick J. Wong char *buf) 1077c0b4e3abSDarrick J. Wong { 1078c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1079c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", (data->cfg2 & ADT7462_FSPD_MASK ? 1 : 0)); 1080c0b4e3abSDarrick J. Wong } 1081c0b4e3abSDarrick J. Wong 1082c0b4e3abSDarrick J. Wong static ssize_t set_force_pwm_max(struct device *dev, 1083c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1084c0b4e3abSDarrick J. Wong const char *buf, 1085c0b4e3abSDarrick J. Wong size_t count) 1086c0b4e3abSDarrick J. Wong { 1087573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1088573bfe67SAxel Lin struct i2c_client *client = data->client; 1089c0b4e3abSDarrick J. Wong long temp; 1090c0b4e3abSDarrick J. Wong u8 reg; 1091c0b4e3abSDarrick J. Wong 1092179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp)) 1093c0b4e3abSDarrick J. Wong return -EINVAL; 1094c0b4e3abSDarrick J. Wong 1095c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 1096c0b4e3abSDarrick J. Wong reg = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); 1097c0b4e3abSDarrick J. Wong if (temp) 1098c0b4e3abSDarrick J. Wong reg |= ADT7462_FSPD_MASK; 1099c0b4e3abSDarrick J. Wong else 1100c0b4e3abSDarrick J. Wong reg &= ~ADT7462_FSPD_MASK; 1101c0b4e3abSDarrick J. Wong data->cfg2 = reg; 1102c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_REG_CFG2, reg); 1103c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 1104c0b4e3abSDarrick J. Wong 1105c0b4e3abSDarrick J. Wong return count; 1106c0b4e3abSDarrick J. Wong } 1107c0b4e3abSDarrick J. Wong 1108c0b4e3abSDarrick J. Wong static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, 1109c0b4e3abSDarrick J. Wong char *buf) 1110c0b4e3abSDarrick J. Wong { 1111c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1112c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1113c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", data->pwm[attr->index]); 1114c0b4e3abSDarrick J. Wong } 1115c0b4e3abSDarrick J. Wong 1116c0b4e3abSDarrick J. Wong static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, 1117c0b4e3abSDarrick J. Wong const char *buf, size_t count) 1118c0b4e3abSDarrick J. Wong { 1119c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1120573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1121573bfe67SAxel Lin struct i2c_client *client = data->client; 1122c0b4e3abSDarrick J. Wong long temp; 1123c0b4e3abSDarrick J. Wong 1124179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp)) 1125c0b4e3abSDarrick J. Wong return -EINVAL; 1126c0b4e3abSDarrick J. Wong 11272a844c14SGuenter Roeck temp = clamp_val(temp, 0, 255); 1128c0b4e3abSDarrick J. Wong 1129c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 1130c0b4e3abSDarrick J. Wong data->pwm[attr->index] = temp; 1131c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_REG_PWM(attr->index), temp); 1132c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 1133c0b4e3abSDarrick J. Wong 1134c0b4e3abSDarrick J. Wong return count; 1135c0b4e3abSDarrick J. Wong } 1136c0b4e3abSDarrick J. Wong 1137c0b4e3abSDarrick J. Wong static ssize_t show_pwm_max(struct device *dev, 1138c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1139c0b4e3abSDarrick J. Wong char *buf) 1140c0b4e3abSDarrick J. Wong { 1141c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1142c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", data->pwm_max); 1143c0b4e3abSDarrick J. Wong } 1144c0b4e3abSDarrick J. Wong 1145c0b4e3abSDarrick J. Wong static ssize_t set_pwm_max(struct device *dev, 1146c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1147c0b4e3abSDarrick J. Wong const char *buf, 1148c0b4e3abSDarrick J. Wong size_t count) 1149c0b4e3abSDarrick J. Wong { 1150573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1151573bfe67SAxel Lin struct i2c_client *client = data->client; 1152c0b4e3abSDarrick J. Wong long temp; 1153c0b4e3abSDarrick J. Wong 1154179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp)) 1155c0b4e3abSDarrick J. Wong return -EINVAL; 1156c0b4e3abSDarrick J. Wong 11572a844c14SGuenter Roeck temp = clamp_val(temp, 0, 255); 1158c0b4e3abSDarrick J. Wong 1159c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 1160c0b4e3abSDarrick J. Wong data->pwm_max = temp; 1161c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MAX, temp); 1162c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 1163c0b4e3abSDarrick J. Wong 1164c0b4e3abSDarrick J. Wong return count; 1165c0b4e3abSDarrick J. Wong } 1166c0b4e3abSDarrick J. Wong 1167c0b4e3abSDarrick J. Wong static ssize_t show_pwm_min(struct device *dev, 1168c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1169c0b4e3abSDarrick J. Wong char *buf) 1170c0b4e3abSDarrick J. Wong { 1171c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1172c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1173c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", data->pwm_min[attr->index]); 1174c0b4e3abSDarrick J. Wong } 1175c0b4e3abSDarrick J. Wong 1176c0b4e3abSDarrick J. Wong static ssize_t set_pwm_min(struct device *dev, 1177c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1178c0b4e3abSDarrick J. Wong const char *buf, 1179c0b4e3abSDarrick J. Wong size_t count) 1180c0b4e3abSDarrick J. Wong { 1181c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1182573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1183573bfe67SAxel Lin struct i2c_client *client = data->client; 1184c0b4e3abSDarrick J. Wong long temp; 1185c0b4e3abSDarrick J. Wong 1186179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp)) 1187c0b4e3abSDarrick J. Wong return -EINVAL; 1188c0b4e3abSDarrick J. Wong 11892a844c14SGuenter Roeck temp = clamp_val(temp, 0, 255); 1190c0b4e3abSDarrick J. Wong 1191c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 1192c0b4e3abSDarrick J. Wong data->pwm_min[attr->index] = temp; 1193c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MIN(attr->index), 1194c0b4e3abSDarrick J. Wong temp); 1195c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 1196c0b4e3abSDarrick J. Wong 1197c0b4e3abSDarrick J. Wong return count; 1198c0b4e3abSDarrick J. Wong } 1199c0b4e3abSDarrick J. Wong 1200c0b4e3abSDarrick J. Wong static ssize_t show_pwm_hyst(struct device *dev, 1201c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1202c0b4e3abSDarrick J. Wong char *buf) 1203c0b4e3abSDarrick J. Wong { 1204c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1205c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1206c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", 1000 * 1207c0b4e3abSDarrick J. Wong (data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK)); 1208c0b4e3abSDarrick J. Wong } 1209c0b4e3abSDarrick J. Wong 1210c0b4e3abSDarrick J. Wong static ssize_t set_pwm_hyst(struct device *dev, 1211c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1212c0b4e3abSDarrick J. Wong const char *buf, 1213c0b4e3abSDarrick J. Wong size_t count) 1214c0b4e3abSDarrick J. Wong { 1215c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1216573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1217573bfe67SAxel Lin struct i2c_client *client = data->client; 1218c0b4e3abSDarrick J. Wong long temp; 1219c0b4e3abSDarrick J. Wong 1220179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp)) 1221c0b4e3abSDarrick J. Wong return -EINVAL; 1222c0b4e3abSDarrick J. Wong 1223*b94793b4SGuenter Roeck temp = clamp_val(temp, 0, 15000); 12248f8c1fb0SDarrick J. Wong temp = DIV_ROUND_CLOSEST(temp, 1000); 1225c0b4e3abSDarrick J. Wong 1226c0b4e3abSDarrick J. Wong /* package things up */ 1227c0b4e3abSDarrick J. Wong temp &= ADT7462_PWM_HYST_MASK; 1228c0b4e3abSDarrick J. Wong temp |= data->pwm_trange[attr->index] & ADT7462_PWM_RANGE_MASK; 1229c0b4e3abSDarrick J. Wong 1230c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 1231c0b4e3abSDarrick J. Wong data->pwm_trange[attr->index] = temp; 1232c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), 1233c0b4e3abSDarrick J. Wong temp); 1234c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 1235c0b4e3abSDarrick J. Wong 1236c0b4e3abSDarrick J. Wong return count; 1237c0b4e3abSDarrick J. Wong } 1238c0b4e3abSDarrick J. Wong 1239c0b4e3abSDarrick J. Wong static ssize_t show_pwm_tmax(struct device *dev, 1240c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1241c0b4e3abSDarrick J. Wong char *buf) 1242c0b4e3abSDarrick J. Wong { 1243c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1244c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1245c0b4e3abSDarrick J. Wong 1246c0b4e3abSDarrick J. Wong /* tmax = tmin + trange */ 1247c0b4e3abSDarrick J. Wong int trange = trange_values[data->pwm_trange[attr->index] >> 1248c0b4e3abSDarrick J. Wong ADT7462_PWM_RANGE_SHIFT]; 1249c0b4e3abSDarrick J. Wong int tmin = (data->pwm_tmin[attr->index] - 64) * 1000; 1250c0b4e3abSDarrick J. Wong 1251c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", tmin + trange); 1252c0b4e3abSDarrick J. Wong } 1253c0b4e3abSDarrick J. Wong 1254c0b4e3abSDarrick J. Wong static ssize_t set_pwm_tmax(struct device *dev, 1255c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1256c0b4e3abSDarrick J. Wong const char *buf, 1257c0b4e3abSDarrick J. Wong size_t count) 1258c0b4e3abSDarrick J. Wong { 1259c0b4e3abSDarrick J. Wong int temp; 1260c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1261573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1262573bfe67SAxel Lin struct i2c_client *client = data->client; 1263c0b4e3abSDarrick J. Wong int tmin, trange_value; 1264c0b4e3abSDarrick J. Wong long trange; 1265c0b4e3abSDarrick J. Wong 1266179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &trange)) 1267c0b4e3abSDarrick J. Wong return -EINVAL; 1268c0b4e3abSDarrick J. Wong 1269c0b4e3abSDarrick J. Wong /* trange = tmax - tmin */ 1270c0b4e3abSDarrick J. Wong tmin = (data->pwm_tmin[attr->index] - 64) * 1000; 1271c0b4e3abSDarrick J. Wong trange_value = find_trange_value(trange - tmin); 1272c0b4e3abSDarrick J. Wong if (trange_value < 0) 1273bb34c0daSGuenter Roeck return trange_value; 1274c0b4e3abSDarrick J. Wong 1275c0b4e3abSDarrick J. Wong temp = trange_value << ADT7462_PWM_RANGE_SHIFT; 1276c0b4e3abSDarrick J. Wong temp |= data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK; 1277c0b4e3abSDarrick J. Wong 1278c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 1279c0b4e3abSDarrick J. Wong data->pwm_trange[attr->index] = temp; 1280c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), 1281c0b4e3abSDarrick J. Wong temp); 1282c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 1283c0b4e3abSDarrick J. Wong 1284c0b4e3abSDarrick J. Wong return count; 1285c0b4e3abSDarrick J. Wong } 1286c0b4e3abSDarrick J. Wong 1287c0b4e3abSDarrick J. Wong static ssize_t show_pwm_tmin(struct device *dev, 1288c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1289c0b4e3abSDarrick J. Wong char *buf) 1290c0b4e3abSDarrick J. Wong { 1291c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1292c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1293c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", 1000 * (data->pwm_tmin[attr->index] - 64)); 1294c0b4e3abSDarrick J. Wong } 1295c0b4e3abSDarrick J. Wong 1296c0b4e3abSDarrick J. Wong static ssize_t set_pwm_tmin(struct device *dev, 1297c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1298c0b4e3abSDarrick J. Wong const char *buf, 1299c0b4e3abSDarrick J. Wong size_t count) 1300c0b4e3abSDarrick J. Wong { 1301c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1302573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1303573bfe67SAxel Lin struct i2c_client *client = data->client; 1304c0b4e3abSDarrick J. Wong long temp; 1305c0b4e3abSDarrick J. Wong 1306179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp)) 1307c0b4e3abSDarrick J. Wong return -EINVAL; 1308c0b4e3abSDarrick J. Wong 1309*b94793b4SGuenter Roeck temp = clamp_val(temp, -64000, 191000); 13108f8c1fb0SDarrick J. Wong temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; 1311c0b4e3abSDarrick J. Wong 1312c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 1313c0b4e3abSDarrick J. Wong data->pwm_tmin[attr->index] = temp; 1314c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TMIN(attr->index), 1315c0b4e3abSDarrick J. Wong temp); 1316c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 1317c0b4e3abSDarrick J. Wong 1318c0b4e3abSDarrick J. Wong return count; 1319c0b4e3abSDarrick J. Wong } 1320c0b4e3abSDarrick J. Wong 1321c0b4e3abSDarrick J. Wong static ssize_t show_pwm_auto(struct device *dev, 1322c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1323c0b4e3abSDarrick J. Wong char *buf) 1324c0b4e3abSDarrick J. Wong { 1325c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1326c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1327c0b4e3abSDarrick J. Wong int cfg = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; 1328c0b4e3abSDarrick J. Wong 1329c0b4e3abSDarrick J. Wong switch (cfg) { 1330c0b4e3abSDarrick J. Wong case 4: /* off */ 1331c0b4e3abSDarrick J. Wong return sprintf(buf, "0\n"); 1332c0b4e3abSDarrick J. Wong case 7: /* manual */ 1333c0b4e3abSDarrick J. Wong return sprintf(buf, "1\n"); 1334c0b4e3abSDarrick J. Wong default: /* automatic */ 1335c0b4e3abSDarrick J. Wong return sprintf(buf, "2\n"); 1336c0b4e3abSDarrick J. Wong } 1337c0b4e3abSDarrick J. Wong } 1338c0b4e3abSDarrick J. Wong 1339c0b4e3abSDarrick J. Wong static void set_pwm_channel(struct i2c_client *client, 1340c0b4e3abSDarrick J. Wong struct adt7462_data *data, 1341c0b4e3abSDarrick J. Wong int which, 1342c0b4e3abSDarrick J. Wong int value) 1343c0b4e3abSDarrick J. Wong { 1344c0b4e3abSDarrick J. Wong int temp = data->pwm_cfg[which] & ~ADT7462_PWM_CHANNEL_MASK; 1345c0b4e3abSDarrick J. Wong temp |= value << ADT7462_PWM_CHANNEL_SHIFT; 1346c0b4e3abSDarrick J. Wong 1347c0b4e3abSDarrick J. Wong mutex_lock(&data->lock); 1348c0b4e3abSDarrick J. Wong data->pwm_cfg[which] = temp; 1349c0b4e3abSDarrick J. Wong i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_CFG(which), temp); 1350c0b4e3abSDarrick J. Wong mutex_unlock(&data->lock); 1351c0b4e3abSDarrick J. Wong } 1352c0b4e3abSDarrick J. Wong 1353c0b4e3abSDarrick J. Wong static ssize_t set_pwm_auto(struct device *dev, 1354c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1355c0b4e3abSDarrick J. Wong const char *buf, 1356c0b4e3abSDarrick J. Wong size_t count) 1357c0b4e3abSDarrick J. Wong { 1358c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1359573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1360573bfe67SAxel Lin struct i2c_client *client = data->client; 1361c0b4e3abSDarrick J. Wong long temp; 1362c0b4e3abSDarrick J. Wong 1363179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp)) 1364c0b4e3abSDarrick J. Wong return -EINVAL; 1365c0b4e3abSDarrick J. Wong 1366c0b4e3abSDarrick J. Wong switch (temp) { 1367c0b4e3abSDarrick J. Wong case 0: /* off */ 1368c0b4e3abSDarrick J. Wong set_pwm_channel(client, data, attr->index, 4); 1369c0b4e3abSDarrick J. Wong return count; 1370c0b4e3abSDarrick J. Wong case 1: /* manual */ 1371c0b4e3abSDarrick J. Wong set_pwm_channel(client, data, attr->index, 7); 1372c0b4e3abSDarrick J. Wong return count; 1373c0b4e3abSDarrick J. Wong default: 1374c0b4e3abSDarrick J. Wong return -EINVAL; 1375c0b4e3abSDarrick J. Wong } 1376c0b4e3abSDarrick J. Wong } 1377c0b4e3abSDarrick J. Wong 1378c0b4e3abSDarrick J. Wong static ssize_t show_pwm_auto_temp(struct device *dev, 1379c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1380c0b4e3abSDarrick J. Wong char *buf) 1381c0b4e3abSDarrick J. Wong { 1382c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1383c0b4e3abSDarrick J. Wong struct adt7462_data *data = adt7462_update_device(dev); 1384c0b4e3abSDarrick J. Wong int channel = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; 1385c0b4e3abSDarrick J. Wong 1386c0b4e3abSDarrick J. Wong switch (channel) { 1387c0b4e3abSDarrick J. Wong case 0: /* temp[1234] only */ 1388c0b4e3abSDarrick J. Wong case 1: 1389c0b4e3abSDarrick J. Wong case 2: 1390c0b4e3abSDarrick J. Wong case 3: 1391c0b4e3abSDarrick J. Wong return sprintf(buf, "%d\n", (1 << channel)); 1392c0b4e3abSDarrick J. Wong case 5: /* temp1 & temp4 */ 1393c0b4e3abSDarrick J. Wong return sprintf(buf, "9\n"); 1394c0b4e3abSDarrick J. Wong case 6: 1395c0b4e3abSDarrick J. Wong return sprintf(buf, "15\n"); 1396c0b4e3abSDarrick J. Wong default: 1397c0b4e3abSDarrick J. Wong return sprintf(buf, "0\n"); 1398c0b4e3abSDarrick J. Wong } 1399c0b4e3abSDarrick J. Wong } 1400c0b4e3abSDarrick J. Wong 1401c0b4e3abSDarrick J. Wong static int cvt_auto_temp(int input) 1402c0b4e3abSDarrick J. Wong { 1403c0b4e3abSDarrick J. Wong if (input == 0xF) 1404c0b4e3abSDarrick J. Wong return 6; 1405c0b4e3abSDarrick J. Wong if (input == 0x9) 1406c0b4e3abSDarrick J. Wong return 5; 1407c0b4e3abSDarrick J. Wong if (input < 1 || !is_power_of_2(input)) 1408c0b4e3abSDarrick J. Wong return -EINVAL; 1409c0b4e3abSDarrick J. Wong return ilog2(input); 1410c0b4e3abSDarrick J. Wong } 1411c0b4e3abSDarrick J. Wong 1412c0b4e3abSDarrick J. Wong static ssize_t set_pwm_auto_temp(struct device *dev, 1413c0b4e3abSDarrick J. Wong struct device_attribute *devattr, 1414c0b4e3abSDarrick J. Wong const char *buf, 1415c0b4e3abSDarrick J. Wong size_t count) 1416c0b4e3abSDarrick J. Wong { 1417c0b4e3abSDarrick J. Wong struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 1418573bfe67SAxel Lin struct adt7462_data *data = dev_get_drvdata(dev); 1419573bfe67SAxel Lin struct i2c_client *client = data->client; 1420c0b4e3abSDarrick J. Wong long temp; 1421c0b4e3abSDarrick J. Wong 1422179c4fdbSFrans Meulenbroeks if (kstrtol(buf, 10, &temp)) 1423c0b4e3abSDarrick J. Wong return -EINVAL; 1424c0b4e3abSDarrick J. Wong 1425c0b4e3abSDarrick J. Wong temp = cvt_auto_temp(temp); 1426c0b4e3abSDarrick J. Wong if (temp < 0) 1427c0b4e3abSDarrick J. Wong return temp; 1428c0b4e3abSDarrick J. Wong 1429c0b4e3abSDarrick J. Wong set_pwm_channel(client, data, attr->index, temp); 1430c0b4e3abSDarrick J. Wong 1431c0b4e3abSDarrick J. Wong return count; 1432c0b4e3abSDarrick J. Wong } 1433c0b4e3abSDarrick J. Wong 1434c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, 1435c0b4e3abSDarrick J. Wong set_temp_max, 0); 1436c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, 1437c0b4e3abSDarrick J. Wong set_temp_max, 1); 1438c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, 1439c0b4e3abSDarrick J. Wong set_temp_max, 2); 1440c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max, 1441c0b4e3abSDarrick J. Wong set_temp_max, 3); 1442c0b4e3abSDarrick J. Wong 1443c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, 1444c0b4e3abSDarrick J. Wong set_temp_min, 0); 1445c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, 1446c0b4e3abSDarrick J. Wong set_temp_min, 1); 1447c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min, 1448c0b4e3abSDarrick J. Wong set_temp_min, 2); 1449c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_temp_min, 1450c0b4e3abSDarrick J. Wong set_temp_min, 3); 1451c0b4e3abSDarrick J. Wong 1452c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 1453c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); 1454c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); 1455c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); 1456c0b4e3abSDarrick J. Wong 1457c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0); 1458c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1); 1459c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2); 1460c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3); 1461c0b4e3abSDarrick J. Wong 1462c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 1463c0b4e3abSDarrick J. Wong ADT7462_ALARM1 | ADT7462_LT_ALARM); 1464c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 1465c0b4e3abSDarrick J. Wong ADT7462_ALARM1 | ADT7462_R1T_ALARM); 1466c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 1467c0b4e3abSDarrick J. Wong ADT7462_ALARM1 | ADT7462_R2T_ALARM); 1468c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, 1469c0b4e3abSDarrick J. Wong ADT7462_ALARM1 | ADT7462_R3T_ALARM); 1470c0b4e3abSDarrick J. Wong 1471c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max, 1472c0b4e3abSDarrick J. Wong set_volt_max, 0); 1473c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max, 1474c0b4e3abSDarrick J. Wong set_volt_max, 1); 1475c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, show_volt_max, 1476c0b4e3abSDarrick J. Wong set_volt_max, 2); 1477c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, show_volt_max, 1478c0b4e3abSDarrick J. Wong set_volt_max, 3); 1479c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, show_volt_max, 1480c0b4e3abSDarrick J. Wong set_volt_max, 4); 1481c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, show_volt_max, 1482c0b4e3abSDarrick J. Wong set_volt_max, 5); 1483c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, show_volt_max, 1484c0b4e3abSDarrick J. Wong set_volt_max, 6); 1485c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, show_volt_max, 1486c0b4e3abSDarrick J. Wong set_volt_max, 7); 1487c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_max, S_IWUSR | S_IRUGO, show_volt_max, 1488c0b4e3abSDarrick J. Wong set_volt_max, 8); 1489c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_max, S_IWUSR | S_IRUGO, show_volt_max, 1490c0b4e3abSDarrick J. Wong set_volt_max, 9); 1491c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_max, S_IWUSR | S_IRUGO, show_volt_max, 1492c0b4e3abSDarrick J. Wong set_volt_max, 10); 1493c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_max, S_IWUSR | S_IRUGO, show_volt_max, 1494c0b4e3abSDarrick J. Wong set_volt_max, 11); 1495c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_max, S_IWUSR | S_IRUGO, show_volt_max, 1496c0b4e3abSDarrick J. Wong set_volt_max, 12); 1497c0b4e3abSDarrick J. Wong 1498c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min, 1499c0b4e3abSDarrick J. Wong set_volt_min, 0); 1500c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min, 1501c0b4e3abSDarrick J. Wong set_volt_min, 1); 1502c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, show_volt_min, 1503c0b4e3abSDarrick J. Wong set_volt_min, 2); 1504c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, show_volt_min, 1505c0b4e3abSDarrick J. Wong set_volt_min, 3); 1506c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, show_volt_min, 1507c0b4e3abSDarrick J. Wong set_volt_min, 4); 1508c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, show_volt_min, 1509c0b4e3abSDarrick J. Wong set_volt_min, 5); 1510c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, show_volt_min, 1511c0b4e3abSDarrick J. Wong set_volt_min, 6); 1512c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, show_volt_min, 1513c0b4e3abSDarrick J. Wong set_volt_min, 7); 1514c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_min, S_IWUSR | S_IRUGO, show_volt_min, 1515c0b4e3abSDarrick J. Wong set_volt_min, 8); 1516c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_min, S_IWUSR | S_IRUGO, show_volt_min, 1517c0b4e3abSDarrick J. Wong set_volt_min, 9); 1518c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_min, S_IWUSR | S_IRUGO, show_volt_min, 1519c0b4e3abSDarrick J. Wong set_volt_min, 10); 1520c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_min, S_IWUSR | S_IRUGO, show_volt_min, 1521c0b4e3abSDarrick J. Wong set_volt_min, 11); 1522c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_min, S_IWUSR | S_IRUGO, show_volt_min, 1523c0b4e3abSDarrick J. Wong set_volt_min, 12); 1524c0b4e3abSDarrick J. Wong 1525c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0); 1526c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1); 1527c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2); 1528c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3); 1529c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4); 1530c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5); 1531c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6); 1532c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7); 1533c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8); 1534c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9); 1535c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10); 1536c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11); 1537c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12); 1538c0b4e3abSDarrick J. Wong 1539c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_voltage_label, NULL, 0); 1540c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_voltage_label, NULL, 1); 1541c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_voltage_label, NULL, 2); 1542c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_voltage_label, NULL, 3); 1543c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_voltage_label, NULL, 4); 1544c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_voltage_label, NULL, 5); 1545c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_voltage_label, NULL, 6); 1546c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_voltage_label, NULL, 7); 1547c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_voltage_label, NULL, 8); 1548c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_voltage_label, NULL, 9); 1549c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_voltage_label, NULL, 10); 1550c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_voltage_label, NULL, 11); 1551c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, show_voltage_label, NULL, 12); 1552c0b4e3abSDarrick J. Wong 1553c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1554c0b4e3abSDarrick J. Wong ADT7462_ALARM2 | ADT7462_V0_ALARM); 1555c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 1556c0b4e3abSDarrick J. Wong ADT7462_ALARM2 | ADT7462_V7_ALARM); 1557c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 1558c0b4e3abSDarrick J. Wong ADT7462_ALARM2 | ADT7462_V2_ALARM); 1559c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 1560c0b4e3abSDarrick J. Wong ADT7462_ALARM2 | ADT7462_V6_ALARM); 1561c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 1562c0b4e3abSDarrick J. Wong ADT7462_ALARM2 | ADT7462_V5_ALARM); 1563c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 1564c0b4e3abSDarrick J. Wong ADT7462_ALARM2 | ADT7462_V4_ALARM); 1565c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 1566c0b4e3abSDarrick J. Wong ADT7462_ALARM2 | ADT7462_V3_ALARM); 1567c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 1568c0b4e3abSDarrick J. Wong ADT7462_ALARM2 | ADT7462_V1_ALARM); 1569c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 1570c0b4e3abSDarrick J. Wong ADT7462_ALARM3 | ADT7462_V10_ALARM); 1571c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 1572c0b4e3abSDarrick J. Wong ADT7462_ALARM3 | ADT7462_V9_ALARM); 1573c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, 1574c0b4e3abSDarrick J. Wong ADT7462_ALARM3 | ADT7462_V8_ALARM); 1575c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, 1576c0b4e3abSDarrick J. Wong ADT7462_ALARM3 | ADT7462_V11_ALARM); 1577c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, 1578c0b4e3abSDarrick J. Wong ADT7462_ALARM3 | ADT7462_V12_ALARM); 1579c0b4e3abSDarrick J. Wong 1580c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, 1581c0b4e3abSDarrick J. Wong set_fan_min, 0); 1582c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, 1583c0b4e3abSDarrick J. Wong set_fan_min, 1); 1584c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, 1585c0b4e3abSDarrick J. Wong set_fan_min, 2); 1586c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, 1587c0b4e3abSDarrick J. Wong set_fan_min, 3); 1588c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, 1589c0b4e3abSDarrick J. Wong set_fan_min, 4); 1590c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, 1591c0b4e3abSDarrick J. Wong set_fan_min, 5); 1592c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, 1593c0b4e3abSDarrick J. Wong set_fan_min, 6); 1594c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO, show_fan_min, 1595c0b4e3abSDarrick J. Wong set_fan_min, 7); 1596c0b4e3abSDarrick J. Wong 1597c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); 1598c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); 1599c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); 1600c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); 1601c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); 1602c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); 1603c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); 1604c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); 1605c0b4e3abSDarrick J. Wong 1606c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 1607c0b4e3abSDarrick J. Wong ADT7462_ALARM4 | ADT7462_F0_ALARM); 1608c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 1609c0b4e3abSDarrick J. Wong ADT7462_ALARM4 | ADT7462_F1_ALARM); 1610c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 1611c0b4e3abSDarrick J. Wong ADT7462_ALARM4 | ADT7462_F2_ALARM); 1612c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 1613c0b4e3abSDarrick J. Wong ADT7462_ALARM4 | ADT7462_F3_ALARM); 1614c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 1615c0b4e3abSDarrick J. Wong ADT7462_ALARM4 | ADT7462_F4_ALARM); 1616c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 1617c0b4e3abSDarrick J. Wong ADT7462_ALARM4 | ADT7462_F5_ALARM); 1618c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_alarm, NULL, 1619c0b4e3abSDarrick J. Wong ADT7462_ALARM4 | ADT7462_F6_ALARM); 1620c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_alarm, NULL, 1621c0b4e3abSDarrick J. Wong ADT7462_ALARM4 | ADT7462_F7_ALARM); 1622c0b4e3abSDarrick J. Wong 1623c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(force_pwm_max, S_IWUSR | S_IRUGO, 1624c0b4e3abSDarrick J. Wong show_force_pwm_max, set_force_pwm_max, 0); 1625c0b4e3abSDarrick J. Wong 1626c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); 1627c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); 1628c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); 1629c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); 1630c0b4e3abSDarrick J. Wong 1631c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, 1632c0b4e3abSDarrick J. Wong show_pwm_min, set_pwm_min, 0); 1633c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, 1634c0b4e3abSDarrick J. Wong show_pwm_min, set_pwm_min, 1); 1635c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, 1636c0b4e3abSDarrick J. Wong show_pwm_min, set_pwm_min, 2); 1637c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO, 1638c0b4e3abSDarrick J. Wong show_pwm_min, set_pwm_min, 3); 1639c0b4e3abSDarrick J. Wong 1640c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, 1641c0b4e3abSDarrick J. Wong show_pwm_max, set_pwm_max, 0); 1642c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, 1643c0b4e3abSDarrick J. Wong show_pwm_max, set_pwm_max, 1); 1644c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, 1645c0b4e3abSDarrick J. Wong show_pwm_max, set_pwm_max, 2); 1646c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO, 1647c0b4e3abSDarrick J. Wong show_pwm_max, set_pwm_max, 3); 1648c0b4e3abSDarrick J. Wong 1649c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_auto_point1_hyst, S_IWUSR | S_IRUGO, 1650c0b4e3abSDarrick J. Wong show_pwm_hyst, set_pwm_hyst, 0); 1651c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_auto_point1_hyst, S_IWUSR | S_IRUGO, 1652c0b4e3abSDarrick J. Wong show_pwm_hyst, set_pwm_hyst, 1); 1653c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_auto_point1_hyst, S_IWUSR | S_IRUGO, 1654c0b4e3abSDarrick J. Wong show_pwm_hyst, set_pwm_hyst, 2); 1655c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_auto_point1_hyst, S_IWUSR | S_IRUGO, 1656c0b4e3abSDarrick J. Wong show_pwm_hyst, set_pwm_hyst, 3); 1657c0b4e3abSDarrick J. Wong 1658c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_auto_point2_hyst, S_IWUSR | S_IRUGO, 1659c0b4e3abSDarrick J. Wong show_pwm_hyst, set_pwm_hyst, 0); 1660c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_auto_point2_hyst, S_IWUSR | S_IRUGO, 1661c0b4e3abSDarrick J. Wong show_pwm_hyst, set_pwm_hyst, 1); 1662c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_auto_point2_hyst, S_IWUSR | S_IRUGO, 1663c0b4e3abSDarrick J. Wong show_pwm_hyst, set_pwm_hyst, 2); 1664c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_auto_point2_hyst, S_IWUSR | S_IRUGO, 1665c0b4e3abSDarrick J. Wong show_pwm_hyst, set_pwm_hyst, 3); 1666c0b4e3abSDarrick J. Wong 1667c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO, 1668c0b4e3abSDarrick J. Wong show_pwm_tmin, set_pwm_tmin, 0); 1669c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO, 1670c0b4e3abSDarrick J. Wong show_pwm_tmin, set_pwm_tmin, 1); 1671c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO, 1672c0b4e3abSDarrick J. Wong show_pwm_tmin, set_pwm_tmin, 2); 1673c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_auto_point1_temp, S_IWUSR | S_IRUGO, 1674c0b4e3abSDarrick J. Wong show_pwm_tmin, set_pwm_tmin, 3); 1675c0b4e3abSDarrick J. Wong 1676c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO, 1677c0b4e3abSDarrick J. Wong show_pwm_tmax, set_pwm_tmax, 0); 1678c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, 1679c0b4e3abSDarrick J. Wong show_pwm_tmax, set_pwm_tmax, 1); 1680c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO, 1681c0b4e3abSDarrick J. Wong show_pwm_tmax, set_pwm_tmax, 2); 1682c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_auto_point2_temp, S_IWUSR | S_IRUGO, 1683c0b4e3abSDarrick J. Wong show_pwm_tmax, set_pwm_tmax, 3); 1684c0b4e3abSDarrick J. Wong 1685c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto, 1686c0b4e3abSDarrick J. Wong set_pwm_auto, 0); 1687c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto, 1688c0b4e3abSDarrick J. Wong set_pwm_auto, 1); 1689c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto, 1690c0b4e3abSDarrick J. Wong set_pwm_auto, 2); 1691c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto, 1692c0b4e3abSDarrick J. Wong set_pwm_auto, 3); 1693c0b4e3abSDarrick J. Wong 1694c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO, 1695c0b4e3abSDarrick J. Wong show_pwm_auto_temp, set_pwm_auto_temp, 0); 1696c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO, 1697c0b4e3abSDarrick J. Wong show_pwm_auto_temp, set_pwm_auto_temp, 1); 1698c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, 1699c0b4e3abSDarrick J. Wong show_pwm_auto_temp, set_pwm_auto_temp, 2); 1700c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, 1701c0b4e3abSDarrick J. Wong show_pwm_auto_temp, set_pwm_auto_temp, 3); 1702c0b4e3abSDarrick J. Wong 1703573bfe67SAxel Lin static struct attribute *adt7462_attrs[] = { 1704c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp1_max.dev_attr.attr, 1705c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp2_max.dev_attr.attr, 1706c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp3_max.dev_attr.attr, 1707c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp4_max.dev_attr.attr, 1708c0b4e3abSDarrick J. Wong 1709c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp1_min.dev_attr.attr, 1710c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp2_min.dev_attr.attr, 1711c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp3_min.dev_attr.attr, 1712c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp4_min.dev_attr.attr, 1713c0b4e3abSDarrick J. Wong 1714c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp1_input.dev_attr.attr, 1715c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp2_input.dev_attr.attr, 1716c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp3_input.dev_attr.attr, 1717c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp4_input.dev_attr.attr, 1718c0b4e3abSDarrick J. Wong 1719c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp1_label.dev_attr.attr, 1720c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp2_label.dev_attr.attr, 1721c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp3_label.dev_attr.attr, 1722c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp4_label.dev_attr.attr, 1723c0b4e3abSDarrick J. Wong 1724c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp1_alarm.dev_attr.attr, 1725c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp2_alarm.dev_attr.attr, 1726c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp3_alarm.dev_attr.attr, 1727c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp4_alarm.dev_attr.attr, 1728c0b4e3abSDarrick J. Wong 1729c0b4e3abSDarrick J. Wong &sensor_dev_attr_in1_max.dev_attr.attr, 1730c0b4e3abSDarrick J. Wong &sensor_dev_attr_in2_max.dev_attr.attr, 1731c0b4e3abSDarrick J. Wong &sensor_dev_attr_in3_max.dev_attr.attr, 1732c0b4e3abSDarrick J. Wong &sensor_dev_attr_in4_max.dev_attr.attr, 1733c0b4e3abSDarrick J. Wong &sensor_dev_attr_in5_max.dev_attr.attr, 1734c0b4e3abSDarrick J. Wong &sensor_dev_attr_in6_max.dev_attr.attr, 1735c0b4e3abSDarrick J. Wong &sensor_dev_attr_in7_max.dev_attr.attr, 1736c0b4e3abSDarrick J. Wong &sensor_dev_attr_in8_max.dev_attr.attr, 1737c0b4e3abSDarrick J. Wong &sensor_dev_attr_in9_max.dev_attr.attr, 1738c0b4e3abSDarrick J. Wong &sensor_dev_attr_in10_max.dev_attr.attr, 1739c0b4e3abSDarrick J. Wong &sensor_dev_attr_in11_max.dev_attr.attr, 1740c0b4e3abSDarrick J. Wong &sensor_dev_attr_in12_max.dev_attr.attr, 1741c0b4e3abSDarrick J. Wong &sensor_dev_attr_in13_max.dev_attr.attr, 1742c0b4e3abSDarrick J. Wong 1743c0b4e3abSDarrick J. Wong &sensor_dev_attr_in1_min.dev_attr.attr, 1744c0b4e3abSDarrick J. Wong &sensor_dev_attr_in2_min.dev_attr.attr, 1745c0b4e3abSDarrick J. Wong &sensor_dev_attr_in3_min.dev_attr.attr, 1746c0b4e3abSDarrick J. Wong &sensor_dev_attr_in4_min.dev_attr.attr, 1747c0b4e3abSDarrick J. Wong &sensor_dev_attr_in5_min.dev_attr.attr, 1748c0b4e3abSDarrick J. Wong &sensor_dev_attr_in6_min.dev_attr.attr, 1749c0b4e3abSDarrick J. Wong &sensor_dev_attr_in7_min.dev_attr.attr, 1750c0b4e3abSDarrick J. Wong &sensor_dev_attr_in8_min.dev_attr.attr, 1751c0b4e3abSDarrick J. Wong &sensor_dev_attr_in9_min.dev_attr.attr, 1752c0b4e3abSDarrick J. Wong &sensor_dev_attr_in10_min.dev_attr.attr, 1753c0b4e3abSDarrick J. Wong &sensor_dev_attr_in11_min.dev_attr.attr, 1754c0b4e3abSDarrick J. Wong &sensor_dev_attr_in12_min.dev_attr.attr, 1755c0b4e3abSDarrick J. Wong &sensor_dev_attr_in13_min.dev_attr.attr, 1756c0b4e3abSDarrick J. Wong 1757c0b4e3abSDarrick J. Wong &sensor_dev_attr_in1_input.dev_attr.attr, 1758c0b4e3abSDarrick J. Wong &sensor_dev_attr_in2_input.dev_attr.attr, 1759c0b4e3abSDarrick J. Wong &sensor_dev_attr_in3_input.dev_attr.attr, 1760c0b4e3abSDarrick J. Wong &sensor_dev_attr_in4_input.dev_attr.attr, 1761c0b4e3abSDarrick J. Wong &sensor_dev_attr_in5_input.dev_attr.attr, 1762c0b4e3abSDarrick J. Wong &sensor_dev_attr_in6_input.dev_attr.attr, 1763c0b4e3abSDarrick J. Wong &sensor_dev_attr_in7_input.dev_attr.attr, 1764c0b4e3abSDarrick J. Wong &sensor_dev_attr_in8_input.dev_attr.attr, 1765c0b4e3abSDarrick J. Wong &sensor_dev_attr_in9_input.dev_attr.attr, 1766c0b4e3abSDarrick J. Wong &sensor_dev_attr_in10_input.dev_attr.attr, 1767c0b4e3abSDarrick J. Wong &sensor_dev_attr_in11_input.dev_attr.attr, 1768c0b4e3abSDarrick J. Wong &sensor_dev_attr_in12_input.dev_attr.attr, 1769c0b4e3abSDarrick J. Wong &sensor_dev_attr_in13_input.dev_attr.attr, 1770c0b4e3abSDarrick J. Wong 1771c0b4e3abSDarrick J. Wong &sensor_dev_attr_in1_label.dev_attr.attr, 1772c0b4e3abSDarrick J. Wong &sensor_dev_attr_in2_label.dev_attr.attr, 1773c0b4e3abSDarrick J. Wong &sensor_dev_attr_in3_label.dev_attr.attr, 1774c0b4e3abSDarrick J. Wong &sensor_dev_attr_in4_label.dev_attr.attr, 1775c0b4e3abSDarrick J. Wong &sensor_dev_attr_in5_label.dev_attr.attr, 1776c0b4e3abSDarrick J. Wong &sensor_dev_attr_in6_label.dev_attr.attr, 1777c0b4e3abSDarrick J. Wong &sensor_dev_attr_in7_label.dev_attr.attr, 1778c0b4e3abSDarrick J. Wong &sensor_dev_attr_in8_label.dev_attr.attr, 1779c0b4e3abSDarrick J. Wong &sensor_dev_attr_in9_label.dev_attr.attr, 1780c0b4e3abSDarrick J. Wong &sensor_dev_attr_in10_label.dev_attr.attr, 1781c0b4e3abSDarrick J. Wong &sensor_dev_attr_in11_label.dev_attr.attr, 1782c0b4e3abSDarrick J. Wong &sensor_dev_attr_in12_label.dev_attr.attr, 1783c0b4e3abSDarrick J. Wong &sensor_dev_attr_in13_label.dev_attr.attr, 1784c0b4e3abSDarrick J. Wong 1785c0b4e3abSDarrick J. Wong &sensor_dev_attr_in1_alarm.dev_attr.attr, 1786c0b4e3abSDarrick J. Wong &sensor_dev_attr_in2_alarm.dev_attr.attr, 1787c0b4e3abSDarrick J. Wong &sensor_dev_attr_in3_alarm.dev_attr.attr, 1788c0b4e3abSDarrick J. Wong &sensor_dev_attr_in4_alarm.dev_attr.attr, 1789c0b4e3abSDarrick J. Wong &sensor_dev_attr_in5_alarm.dev_attr.attr, 1790c0b4e3abSDarrick J. Wong &sensor_dev_attr_in6_alarm.dev_attr.attr, 1791c0b4e3abSDarrick J. Wong &sensor_dev_attr_in7_alarm.dev_attr.attr, 1792c0b4e3abSDarrick J. Wong &sensor_dev_attr_in8_alarm.dev_attr.attr, 1793c0b4e3abSDarrick J. Wong &sensor_dev_attr_in9_alarm.dev_attr.attr, 1794c0b4e3abSDarrick J. Wong &sensor_dev_attr_in10_alarm.dev_attr.attr, 1795c0b4e3abSDarrick J. Wong &sensor_dev_attr_in11_alarm.dev_attr.attr, 1796c0b4e3abSDarrick J. Wong &sensor_dev_attr_in12_alarm.dev_attr.attr, 1797c0b4e3abSDarrick J. Wong &sensor_dev_attr_in13_alarm.dev_attr.attr, 1798c0b4e3abSDarrick J. Wong 1799c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan1_min.dev_attr.attr, 1800c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan2_min.dev_attr.attr, 1801c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan3_min.dev_attr.attr, 1802c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan4_min.dev_attr.attr, 1803c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan5_min.dev_attr.attr, 1804c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan6_min.dev_attr.attr, 1805c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan7_min.dev_attr.attr, 1806c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan8_min.dev_attr.attr, 1807c0b4e3abSDarrick J. Wong 1808c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan1_input.dev_attr.attr, 1809c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan2_input.dev_attr.attr, 1810c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan3_input.dev_attr.attr, 1811c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan4_input.dev_attr.attr, 1812c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan5_input.dev_attr.attr, 1813c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan6_input.dev_attr.attr, 1814c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan7_input.dev_attr.attr, 1815c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan8_input.dev_attr.attr, 1816c0b4e3abSDarrick J. Wong 1817c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan1_alarm.dev_attr.attr, 1818c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan2_alarm.dev_attr.attr, 1819c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan3_alarm.dev_attr.attr, 1820c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan4_alarm.dev_attr.attr, 1821c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan5_alarm.dev_attr.attr, 1822c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan6_alarm.dev_attr.attr, 1823c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan7_alarm.dev_attr.attr, 1824c0b4e3abSDarrick J. Wong &sensor_dev_attr_fan8_alarm.dev_attr.attr, 1825c0b4e3abSDarrick J. Wong 1826c0b4e3abSDarrick J. Wong &sensor_dev_attr_force_pwm_max.dev_attr.attr, 1827c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm1.dev_attr.attr, 1828c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm2.dev_attr.attr, 1829c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm3.dev_attr.attr, 1830c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm4.dev_attr.attr, 1831c0b4e3abSDarrick J. Wong 1832c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, 1833c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, 1834c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, 1835c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm4_auto_point1_pwm.dev_attr.attr, 1836c0b4e3abSDarrick J. Wong 1837c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, 1838c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, 1839c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, 1840c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm4_auto_point2_pwm.dev_attr.attr, 1841c0b4e3abSDarrick J. Wong 1842c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp1_auto_point1_hyst.dev_attr.attr, 1843c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp2_auto_point1_hyst.dev_attr.attr, 1844c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp3_auto_point1_hyst.dev_attr.attr, 1845c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp4_auto_point1_hyst.dev_attr.attr, 1846c0b4e3abSDarrick J. Wong 1847c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp1_auto_point2_hyst.dev_attr.attr, 1848c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp2_auto_point2_hyst.dev_attr.attr, 1849c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp3_auto_point2_hyst.dev_attr.attr, 1850c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp4_auto_point2_hyst.dev_attr.attr, 1851c0b4e3abSDarrick J. Wong 1852c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, 1853c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, 1854c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, 1855c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp4_auto_point1_temp.dev_attr.attr, 1856c0b4e3abSDarrick J. Wong 1857c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, 1858c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, 1859c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, 1860c0b4e3abSDarrick J. Wong &sensor_dev_attr_temp4_auto_point2_temp.dev_attr.attr, 1861c0b4e3abSDarrick J. Wong 1862c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm1_enable.dev_attr.attr, 1863c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm2_enable.dev_attr.attr, 1864c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm3_enable.dev_attr.attr, 1865c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm4_enable.dev_attr.attr, 1866c0b4e3abSDarrick J. Wong 1867c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, 1868c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, 1869c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, 1870c0b4e3abSDarrick J. Wong &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr, 1871c0b4e3abSDarrick J. Wong NULL 1872c0b4e3abSDarrick J. Wong }; 1873c0b4e3abSDarrick J. Wong 1874573bfe67SAxel Lin ATTRIBUTE_GROUPS(adt7462); 1875573bfe67SAxel Lin 1876c0b4e3abSDarrick J. Wong /* Return 0 if detection is successful, -ENODEV otherwise */ 1877310ec792SJean Delvare static int adt7462_detect(struct i2c_client *client, 1878c0b4e3abSDarrick J. Wong struct i2c_board_info *info) 1879c0b4e3abSDarrick J. Wong { 1880c0b4e3abSDarrick J. Wong struct i2c_adapter *adapter = client->adapter; 188152df6440SJean Delvare int vendor, device, revision; 1882c0b4e3abSDarrick J. Wong 1883c0b4e3abSDarrick J. Wong if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1884c0b4e3abSDarrick J. Wong return -ENODEV; 1885c0b4e3abSDarrick J. Wong 1886c0b4e3abSDarrick J. Wong vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR); 1887c0b4e3abSDarrick J. Wong if (vendor != ADT7462_VENDOR) 1888c0b4e3abSDarrick J. Wong return -ENODEV; 1889c0b4e3abSDarrick J. Wong 1890c0b4e3abSDarrick J. Wong device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE); 1891c0b4e3abSDarrick J. Wong if (device != ADT7462_DEVICE) 1892c0b4e3abSDarrick J. Wong return -ENODEV; 1893c0b4e3abSDarrick J. Wong 189452df6440SJean Delvare revision = i2c_smbus_read_byte_data(client, ADT7462_REG_REVISION); 1895c0b4e3abSDarrick J. Wong if (revision != ADT7462_REVISION) 1896c0b4e3abSDarrick J. Wong return -ENODEV; 1897c0b4e3abSDarrick J. Wong 1898c0b4e3abSDarrick J. Wong strlcpy(info->type, "adt7462", I2C_NAME_SIZE); 1899c0b4e3abSDarrick J. Wong 1900c0b4e3abSDarrick J. Wong return 0; 1901c0b4e3abSDarrick J. Wong } 1902c0b4e3abSDarrick J. Wong 1903c0b4e3abSDarrick J. Wong static int adt7462_probe(struct i2c_client *client, 1904c0b4e3abSDarrick J. Wong const struct i2c_device_id *id) 1905c0b4e3abSDarrick J. Wong { 1906573bfe67SAxel Lin struct device *dev = &client->dev; 1907c0b4e3abSDarrick J. Wong struct adt7462_data *data; 1908573bfe67SAxel Lin struct device *hwmon_dev; 1909c0b4e3abSDarrick J. Wong 1910573bfe67SAxel Lin data = devm_kzalloc(dev, sizeof(struct adt7462_data), GFP_KERNEL); 191108808300SGuenter Roeck if (!data) 191208808300SGuenter Roeck return -ENOMEM; 1913c0b4e3abSDarrick J. Wong 1914573bfe67SAxel Lin data->client = client; 1915c0b4e3abSDarrick J. Wong mutex_init(&data->lock); 1916c0b4e3abSDarrick J. Wong 1917c0b4e3abSDarrick J. Wong dev_info(&client->dev, "%s chip found\n", client->name); 1918c0b4e3abSDarrick J. Wong 1919573bfe67SAxel Lin hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 1920573bfe67SAxel Lin data, 1921573bfe67SAxel Lin adt7462_groups); 1922573bfe67SAxel Lin return PTR_ERR_OR_ZERO(hwmon_dev); 1923c0b4e3abSDarrick J. Wong } 1924c0b4e3abSDarrick J. Wong 1925a2cc2428SAxel Lin static const struct i2c_device_id adt7462_id[] = { 1926a2cc2428SAxel Lin { "adt7462", 0 }, 1927a2cc2428SAxel Lin { } 1928a2cc2428SAxel Lin }; 1929a2cc2428SAxel Lin MODULE_DEVICE_TABLE(i2c, adt7462_id); 1930a2cc2428SAxel Lin 1931a2cc2428SAxel Lin static struct i2c_driver adt7462_driver = { 1932a2cc2428SAxel Lin .class = I2C_CLASS_HWMON, 1933a2cc2428SAxel Lin .driver = { 1934a2cc2428SAxel Lin .name = "adt7462", 1935a2cc2428SAxel Lin }, 1936a2cc2428SAxel Lin .probe = adt7462_probe, 1937a2cc2428SAxel Lin .id_table = adt7462_id, 1938a2cc2428SAxel Lin .detect = adt7462_detect, 1939a2cc2428SAxel Lin .address_list = normal_i2c, 1940a2cc2428SAxel Lin }; 1941a2cc2428SAxel Lin 1942f0967eeaSAxel Lin module_i2c_driver(adt7462_driver); 1943c0b4e3abSDarrick J. Wong 19445407e051SDarrick J. Wong MODULE_AUTHOR("Darrick J. Wong <darrick.wong@oracle.com>"); 1945c0b4e3abSDarrick J. Wong MODULE_DESCRIPTION("ADT7462 driver"); 1946c0b4e3abSDarrick J. Wong MODULE_LICENSE("GPL"); 1947