1*38b04ad0SIbrahim Tilki // SPDX-License-Identifier: GPL-2.0-only 2*38b04ad0SIbrahim Tilki 3*38b04ad0SIbrahim Tilki #include <linux/bitfield.h> 4*38b04ad0SIbrahim Tilki #include <linux/bits.h> 5*38b04ad0SIbrahim Tilki #include <linux/err.h> 6*38b04ad0SIbrahim Tilki #include <linux/hwmon.h> 7*38b04ad0SIbrahim Tilki #include <linux/hwmon-sysfs.h> 8*38b04ad0SIbrahim Tilki #include <linux/i2c.h> 9*38b04ad0SIbrahim Tilki #include <linux/regmap.h> 10*38b04ad0SIbrahim Tilki #include <linux/util_macros.h> 11*38b04ad0SIbrahim Tilki 12*38b04ad0SIbrahim Tilki #define REG_CR1 0x00 13*38b04ad0SIbrahim Tilki #define CR1_HYST BIT(5) 14*38b04ad0SIbrahim Tilki #define CR1_DRV GENMASK(4, 3) 15*38b04ad0SIbrahim Tilki #define CR1_TEMP_SRC GENMASK(1, 0) 16*38b04ad0SIbrahim Tilki #define REG_CR2 0x01 17*38b04ad0SIbrahim Tilki #define CR2_STBY BIT(7) 18*38b04ad0SIbrahim Tilki #define CR2_ALERTS BIT(6) 19*38b04ad0SIbrahim Tilki #define CR2_DFC BIT(0) 20*38b04ad0SIbrahim Tilki #define REG_CR3 0x02 21*38b04ad0SIbrahim Tilki #define REG_PWMR 0x50 22*38b04ad0SIbrahim Tilki #define REG_PWMV 0x51 23*38b04ad0SIbrahim Tilki #define REG_STATUS 0x5A 24*38b04ad0SIbrahim Tilki #define STATUS_ALARM_CRIT(ch) BIT(2 + 2 * (ch)) 25*38b04ad0SIbrahim Tilki #define STATUS_ALARM_MAX(ch) BIT(3 + 2 * (ch)) 26*38b04ad0SIbrahim Tilki #define STATUS_RDFA BIT(6) 27*38b04ad0SIbrahim Tilki 28*38b04ad0SIbrahim Tilki #define REG_TACH(ch) (0x52 + (ch) * 2) 29*38b04ad0SIbrahim Tilki #define REG_TEMP_INPUT(ch) (0x56 + (ch) * 2) 30*38b04ad0SIbrahim Tilki #define REG_TEMP_MAX(ch) (0x06 + (ch) * 2) 31*38b04ad0SIbrahim Tilki #define REG_TEMP_CRIT(ch) (0x0A + (ch) * 2) 32*38b04ad0SIbrahim Tilki 33*38b04ad0SIbrahim Tilki #define TEMP11_FROM_REG(reg) ((reg) / 32 * 125) 34*38b04ad0SIbrahim Tilki #define TEMP11_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), -128000, \ 35*38b04ad0SIbrahim Tilki 127875), 125) * 32) 36*38b04ad0SIbrahim Tilki 37*38b04ad0SIbrahim Tilki #define LUT_SIZE 48 38*38b04ad0SIbrahim Tilki 39*38b04ad0SIbrahim Tilki #define REG_LUT(index) (0x20 + (index)) 40*38b04ad0SIbrahim Tilki 41*38b04ad0SIbrahim Tilki struct max31760_state { 42*38b04ad0SIbrahim Tilki struct regmap *regmap; 43*38b04ad0SIbrahim Tilki 44*38b04ad0SIbrahim Tilki struct lut_attribute { 45*38b04ad0SIbrahim Tilki char name[24]; 46*38b04ad0SIbrahim Tilki struct sensor_device_attribute sda; 47*38b04ad0SIbrahim Tilki } lut[LUT_SIZE]; 48*38b04ad0SIbrahim Tilki 49*38b04ad0SIbrahim Tilki struct attribute *attrs[LUT_SIZE + 2]; 50*38b04ad0SIbrahim Tilki struct attribute_group group; 51*38b04ad0SIbrahim Tilki const struct attribute_group *groups[2]; 52*38b04ad0SIbrahim Tilki }; 53*38b04ad0SIbrahim Tilki 54*38b04ad0SIbrahim Tilki static bool max31760_volatile_reg(struct device *dev, unsigned int reg) 55*38b04ad0SIbrahim Tilki { 56*38b04ad0SIbrahim Tilki return reg > 0x50; 57*38b04ad0SIbrahim Tilki } 58*38b04ad0SIbrahim Tilki 59*38b04ad0SIbrahim Tilki static const struct regmap_config regmap_config = { 60*38b04ad0SIbrahim Tilki .reg_bits = 8, 61*38b04ad0SIbrahim Tilki .val_bits = 8, 62*38b04ad0SIbrahim Tilki .max_register = 0x5B, 63*38b04ad0SIbrahim Tilki .cache_type = REGCACHE_RBTREE, 64*38b04ad0SIbrahim Tilki .volatile_reg = max31760_volatile_reg, 65*38b04ad0SIbrahim Tilki }; 66*38b04ad0SIbrahim Tilki 67*38b04ad0SIbrahim Tilki static const int max31760_pwm_freq[] = {33, 150, 1500, 25000}; 68*38b04ad0SIbrahim Tilki 69*38b04ad0SIbrahim Tilki static int tach_to_rpm(u16 tach) 70*38b04ad0SIbrahim Tilki { 71*38b04ad0SIbrahim Tilki if (tach == 0) 72*38b04ad0SIbrahim Tilki tach = 1; 73*38b04ad0SIbrahim Tilki 74*38b04ad0SIbrahim Tilki return 60 * 100000 / tach / 2; 75*38b04ad0SIbrahim Tilki } 76*38b04ad0SIbrahim Tilki 77*38b04ad0SIbrahim Tilki static int max31760_read(struct device *dev, enum hwmon_sensor_types type, 78*38b04ad0SIbrahim Tilki u32 attr, int channel, long *val) 79*38b04ad0SIbrahim Tilki { 80*38b04ad0SIbrahim Tilki struct max31760_state *state = dev_get_drvdata(dev); 81*38b04ad0SIbrahim Tilki unsigned int regval; 82*38b04ad0SIbrahim Tilki unsigned int reg_temp; 83*38b04ad0SIbrahim Tilki s16 temp; 84*38b04ad0SIbrahim Tilki u8 reg[2]; 85*38b04ad0SIbrahim Tilki int ret; 86*38b04ad0SIbrahim Tilki 87*38b04ad0SIbrahim Tilki switch (type) { 88*38b04ad0SIbrahim Tilki case hwmon_temp: 89*38b04ad0SIbrahim Tilki switch (attr) { 90*38b04ad0SIbrahim Tilki case hwmon_temp_fault: 91*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_STATUS, ®val); 92*38b04ad0SIbrahim Tilki if (ret) 93*38b04ad0SIbrahim Tilki return ret; 94*38b04ad0SIbrahim Tilki 95*38b04ad0SIbrahim Tilki *val = FIELD_GET(STATUS_RDFA, regval); 96*38b04ad0SIbrahim Tilki 97*38b04ad0SIbrahim Tilki return 0; 98*38b04ad0SIbrahim Tilki case hwmon_temp_max_alarm: 99*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_STATUS, ®val); 100*38b04ad0SIbrahim Tilki if (ret) 101*38b04ad0SIbrahim Tilki return ret; 102*38b04ad0SIbrahim Tilki 103*38b04ad0SIbrahim Tilki if (channel) 104*38b04ad0SIbrahim Tilki *val = FIELD_GET(STATUS_ALARM_MAX(1), regval); 105*38b04ad0SIbrahim Tilki else 106*38b04ad0SIbrahim Tilki *val = FIELD_GET(STATUS_ALARM_MAX(0), regval); 107*38b04ad0SIbrahim Tilki 108*38b04ad0SIbrahim Tilki return 0; 109*38b04ad0SIbrahim Tilki case hwmon_temp_crit_alarm: 110*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_STATUS, ®val); 111*38b04ad0SIbrahim Tilki if (ret) 112*38b04ad0SIbrahim Tilki return ret; 113*38b04ad0SIbrahim Tilki 114*38b04ad0SIbrahim Tilki if (channel) 115*38b04ad0SIbrahim Tilki *val = FIELD_GET(STATUS_ALARM_CRIT(1), regval); 116*38b04ad0SIbrahim Tilki else 117*38b04ad0SIbrahim Tilki *val = FIELD_GET(STATUS_ALARM_CRIT(0), regval); 118*38b04ad0SIbrahim Tilki 119*38b04ad0SIbrahim Tilki return 0; 120*38b04ad0SIbrahim Tilki case hwmon_temp_input: 121*38b04ad0SIbrahim Tilki reg_temp = REG_TEMP_INPUT(channel); 122*38b04ad0SIbrahim Tilki break; 123*38b04ad0SIbrahim Tilki case hwmon_temp_max: 124*38b04ad0SIbrahim Tilki reg_temp = REG_TEMP_MAX(channel); 125*38b04ad0SIbrahim Tilki break; 126*38b04ad0SIbrahim Tilki case hwmon_temp_crit: 127*38b04ad0SIbrahim Tilki reg_temp = REG_TEMP_CRIT(channel); 128*38b04ad0SIbrahim Tilki break; 129*38b04ad0SIbrahim Tilki default: 130*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 131*38b04ad0SIbrahim Tilki } 132*38b04ad0SIbrahim Tilki 133*38b04ad0SIbrahim Tilki ret = regmap_bulk_read(state->regmap, reg_temp, reg, 2); 134*38b04ad0SIbrahim Tilki if (ret) 135*38b04ad0SIbrahim Tilki return ret; 136*38b04ad0SIbrahim Tilki 137*38b04ad0SIbrahim Tilki temp = (reg[0] << 8) | reg[1]; 138*38b04ad0SIbrahim Tilki 139*38b04ad0SIbrahim Tilki *val = TEMP11_FROM_REG(temp); 140*38b04ad0SIbrahim Tilki 141*38b04ad0SIbrahim Tilki return 0; 142*38b04ad0SIbrahim Tilki case hwmon_fan: 143*38b04ad0SIbrahim Tilki switch (attr) { 144*38b04ad0SIbrahim Tilki case hwmon_fan_input: 145*38b04ad0SIbrahim Tilki ret = regmap_bulk_read(state->regmap, REG_TACH(channel), reg, 2); 146*38b04ad0SIbrahim Tilki if (ret) 147*38b04ad0SIbrahim Tilki return ret; 148*38b04ad0SIbrahim Tilki 149*38b04ad0SIbrahim Tilki *val = tach_to_rpm(reg[0] * 256 + reg[1]); 150*38b04ad0SIbrahim Tilki 151*38b04ad0SIbrahim Tilki return 0; 152*38b04ad0SIbrahim Tilki case hwmon_fan_fault: 153*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_STATUS, ®val); 154*38b04ad0SIbrahim Tilki if (ret) 155*38b04ad0SIbrahim Tilki return ret; 156*38b04ad0SIbrahim Tilki 157*38b04ad0SIbrahim Tilki if (channel) 158*38b04ad0SIbrahim Tilki *val = FIELD_GET(BIT(1), regval); 159*38b04ad0SIbrahim Tilki else 160*38b04ad0SIbrahim Tilki *val = FIELD_GET(BIT(0), regval); 161*38b04ad0SIbrahim Tilki 162*38b04ad0SIbrahim Tilki return 0; 163*38b04ad0SIbrahim Tilki case hwmon_fan_enable: 164*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_CR3, ®val); 165*38b04ad0SIbrahim Tilki if (ret) 166*38b04ad0SIbrahim Tilki return ret; 167*38b04ad0SIbrahim Tilki 168*38b04ad0SIbrahim Tilki if (channel) 169*38b04ad0SIbrahim Tilki *val = FIELD_GET(BIT(1), regval); 170*38b04ad0SIbrahim Tilki else 171*38b04ad0SIbrahim Tilki *val = FIELD_GET(BIT(0), regval); 172*38b04ad0SIbrahim Tilki 173*38b04ad0SIbrahim Tilki return 0; 174*38b04ad0SIbrahim Tilki default: 175*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 176*38b04ad0SIbrahim Tilki } 177*38b04ad0SIbrahim Tilki case hwmon_pwm: 178*38b04ad0SIbrahim Tilki switch (attr) { 179*38b04ad0SIbrahim Tilki case hwmon_pwm_input: 180*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_PWMV, ®val); 181*38b04ad0SIbrahim Tilki if (ret) 182*38b04ad0SIbrahim Tilki return ret; 183*38b04ad0SIbrahim Tilki 184*38b04ad0SIbrahim Tilki *val = regval; 185*38b04ad0SIbrahim Tilki 186*38b04ad0SIbrahim Tilki return 0; 187*38b04ad0SIbrahim Tilki case hwmon_pwm_freq: 188*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_CR1, ®val); 189*38b04ad0SIbrahim Tilki if (ret) 190*38b04ad0SIbrahim Tilki return ret; 191*38b04ad0SIbrahim Tilki 192*38b04ad0SIbrahim Tilki regval = FIELD_GET(CR1_DRV, regval); 193*38b04ad0SIbrahim Tilki if (regval >= ARRAY_SIZE(max31760_pwm_freq)) 194*38b04ad0SIbrahim Tilki return -EINVAL; 195*38b04ad0SIbrahim Tilki 196*38b04ad0SIbrahim Tilki *val = max31760_pwm_freq[regval]; 197*38b04ad0SIbrahim Tilki 198*38b04ad0SIbrahim Tilki return 0; 199*38b04ad0SIbrahim Tilki case hwmon_pwm_enable: 200*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_CR2, ®val); 201*38b04ad0SIbrahim Tilki if (ret) 202*38b04ad0SIbrahim Tilki return ret; 203*38b04ad0SIbrahim Tilki 204*38b04ad0SIbrahim Tilki *val = 2 - FIELD_GET(CR2_DFC, regval); 205*38b04ad0SIbrahim Tilki 206*38b04ad0SIbrahim Tilki return 0; 207*38b04ad0SIbrahim Tilki case hwmon_pwm_auto_channels_temp: 208*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_CR1, ®val); 209*38b04ad0SIbrahim Tilki if (ret) 210*38b04ad0SIbrahim Tilki return ret; 211*38b04ad0SIbrahim Tilki 212*38b04ad0SIbrahim Tilki switch (FIELD_GET(CR1_TEMP_SRC, regval)) { 213*38b04ad0SIbrahim Tilki case 0: 214*38b04ad0SIbrahim Tilki *val = 2; 215*38b04ad0SIbrahim Tilki break; 216*38b04ad0SIbrahim Tilki case 1: 217*38b04ad0SIbrahim Tilki *val = 1; 218*38b04ad0SIbrahim Tilki break; 219*38b04ad0SIbrahim Tilki case 2: 220*38b04ad0SIbrahim Tilki case 3: 221*38b04ad0SIbrahim Tilki *val = 3; 222*38b04ad0SIbrahim Tilki break; 223*38b04ad0SIbrahim Tilki default: 224*38b04ad0SIbrahim Tilki return -EINVAL; 225*38b04ad0SIbrahim Tilki } 226*38b04ad0SIbrahim Tilki 227*38b04ad0SIbrahim Tilki return 0; 228*38b04ad0SIbrahim Tilki default: 229*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 230*38b04ad0SIbrahim Tilki } 231*38b04ad0SIbrahim Tilki default: 232*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 233*38b04ad0SIbrahim Tilki } 234*38b04ad0SIbrahim Tilki } 235*38b04ad0SIbrahim Tilki 236*38b04ad0SIbrahim Tilki static int max31760_write(struct device *dev, enum hwmon_sensor_types type, 237*38b04ad0SIbrahim Tilki u32 attr, int channel, long val) 238*38b04ad0SIbrahim Tilki { 239*38b04ad0SIbrahim Tilki struct max31760_state *state = dev_get_drvdata(dev); 240*38b04ad0SIbrahim Tilki unsigned int pwm_index; 241*38b04ad0SIbrahim Tilki unsigned int reg_temp; 242*38b04ad0SIbrahim Tilki int temp; 243*38b04ad0SIbrahim Tilki u8 reg_val[2]; 244*38b04ad0SIbrahim Tilki 245*38b04ad0SIbrahim Tilki switch (type) { 246*38b04ad0SIbrahim Tilki case hwmon_temp: 247*38b04ad0SIbrahim Tilki switch (attr) { 248*38b04ad0SIbrahim Tilki case hwmon_temp_max: 249*38b04ad0SIbrahim Tilki reg_temp = REG_TEMP_MAX(channel); 250*38b04ad0SIbrahim Tilki break; 251*38b04ad0SIbrahim Tilki case hwmon_temp_crit: 252*38b04ad0SIbrahim Tilki reg_temp = REG_TEMP_CRIT(channel); 253*38b04ad0SIbrahim Tilki break; 254*38b04ad0SIbrahim Tilki default: 255*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 256*38b04ad0SIbrahim Tilki } 257*38b04ad0SIbrahim Tilki 258*38b04ad0SIbrahim Tilki temp = TEMP11_TO_REG(val); 259*38b04ad0SIbrahim Tilki reg_val[0] = temp >> 8; 260*38b04ad0SIbrahim Tilki reg_val[1] = temp & 0xFF; 261*38b04ad0SIbrahim Tilki 262*38b04ad0SIbrahim Tilki return regmap_bulk_write(state->regmap, reg_temp, reg_val, 2); 263*38b04ad0SIbrahim Tilki case hwmon_fan: 264*38b04ad0SIbrahim Tilki switch (attr) { 265*38b04ad0SIbrahim Tilki case hwmon_fan_enable: 266*38b04ad0SIbrahim Tilki if (val == 0) 267*38b04ad0SIbrahim Tilki return regmap_clear_bits(state->regmap, REG_CR3, BIT(channel)); 268*38b04ad0SIbrahim Tilki 269*38b04ad0SIbrahim Tilki if (val == 1) 270*38b04ad0SIbrahim Tilki return regmap_set_bits(state->regmap, REG_CR3, BIT(channel)); 271*38b04ad0SIbrahim Tilki 272*38b04ad0SIbrahim Tilki return -EINVAL; 273*38b04ad0SIbrahim Tilki default: 274*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 275*38b04ad0SIbrahim Tilki } 276*38b04ad0SIbrahim Tilki case hwmon_pwm: 277*38b04ad0SIbrahim Tilki switch (attr) { 278*38b04ad0SIbrahim Tilki case hwmon_pwm_input: 279*38b04ad0SIbrahim Tilki if (val < 0 || val > 255) 280*38b04ad0SIbrahim Tilki return -EINVAL; 281*38b04ad0SIbrahim Tilki 282*38b04ad0SIbrahim Tilki return regmap_write(state->regmap, REG_PWMR, val); 283*38b04ad0SIbrahim Tilki case hwmon_pwm_enable: 284*38b04ad0SIbrahim Tilki if (val == 1) 285*38b04ad0SIbrahim Tilki return regmap_set_bits(state->regmap, REG_CR2, CR2_DFC); 286*38b04ad0SIbrahim Tilki 287*38b04ad0SIbrahim Tilki if (val == 2) 288*38b04ad0SIbrahim Tilki return regmap_clear_bits(state->regmap, REG_CR2, CR2_DFC); 289*38b04ad0SIbrahim Tilki 290*38b04ad0SIbrahim Tilki return -EINVAL; 291*38b04ad0SIbrahim Tilki case hwmon_pwm_freq: 292*38b04ad0SIbrahim Tilki pwm_index = find_closest(val, max31760_pwm_freq, 293*38b04ad0SIbrahim Tilki ARRAY_SIZE(max31760_pwm_freq)); 294*38b04ad0SIbrahim Tilki 295*38b04ad0SIbrahim Tilki return regmap_update_bits(state->regmap, 296*38b04ad0SIbrahim Tilki REG_CR1, CR1_DRV, 297*38b04ad0SIbrahim Tilki FIELD_PREP(CR1_DRV, pwm_index)); 298*38b04ad0SIbrahim Tilki case hwmon_pwm_auto_channels_temp: 299*38b04ad0SIbrahim Tilki switch (val) { 300*38b04ad0SIbrahim Tilki case 1: 301*38b04ad0SIbrahim Tilki break; 302*38b04ad0SIbrahim Tilki case 2: 303*38b04ad0SIbrahim Tilki val = 0; 304*38b04ad0SIbrahim Tilki break; 305*38b04ad0SIbrahim Tilki case 3: 306*38b04ad0SIbrahim Tilki val = 2; 307*38b04ad0SIbrahim Tilki break; 308*38b04ad0SIbrahim Tilki default: 309*38b04ad0SIbrahim Tilki return -EINVAL; 310*38b04ad0SIbrahim Tilki } 311*38b04ad0SIbrahim Tilki 312*38b04ad0SIbrahim Tilki return regmap_update_bits(state->regmap, REG_CR1, CR1_TEMP_SRC, val); 313*38b04ad0SIbrahim Tilki default: 314*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 315*38b04ad0SIbrahim Tilki } 316*38b04ad0SIbrahim Tilki default: 317*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 318*38b04ad0SIbrahim Tilki } 319*38b04ad0SIbrahim Tilki } 320*38b04ad0SIbrahim Tilki 321*38b04ad0SIbrahim Tilki static const struct hwmon_channel_info *max31760_info[] = { 322*38b04ad0SIbrahim Tilki HWMON_CHANNEL_INFO(chip, 323*38b04ad0SIbrahim Tilki HWMON_C_REGISTER_TZ), 324*38b04ad0SIbrahim Tilki HWMON_CHANNEL_INFO(fan, 325*38b04ad0SIbrahim Tilki HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_ENABLE, 326*38b04ad0SIbrahim Tilki HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_ENABLE), 327*38b04ad0SIbrahim Tilki HWMON_CHANNEL_INFO(temp, 328*38b04ad0SIbrahim Tilki HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT | 329*38b04ad0SIbrahim Tilki HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_LABEL, 330*38b04ad0SIbrahim Tilki HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | 331*38b04ad0SIbrahim Tilki HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_LABEL), 332*38b04ad0SIbrahim Tilki HWMON_CHANNEL_INFO(pwm, 333*38b04ad0SIbrahim Tilki HWMON_PWM_ENABLE | HWMON_PWM_FREQ | HWMON_PWM_INPUT | 334*38b04ad0SIbrahim Tilki HWMON_PWM_AUTO_CHANNELS_TEMP), 335*38b04ad0SIbrahim Tilki NULL 336*38b04ad0SIbrahim Tilki }; 337*38b04ad0SIbrahim Tilki 338*38b04ad0SIbrahim Tilki static umode_t max31760_is_visible(const void *data, 339*38b04ad0SIbrahim Tilki enum hwmon_sensor_types type, 340*38b04ad0SIbrahim Tilki u32 attr, int channel) 341*38b04ad0SIbrahim Tilki { 342*38b04ad0SIbrahim Tilki switch (type) { 343*38b04ad0SIbrahim Tilki case hwmon_temp: 344*38b04ad0SIbrahim Tilki switch (attr) { 345*38b04ad0SIbrahim Tilki case hwmon_temp_input: 346*38b04ad0SIbrahim Tilki case hwmon_temp_max_alarm: 347*38b04ad0SIbrahim Tilki case hwmon_temp_crit_alarm: 348*38b04ad0SIbrahim Tilki case hwmon_temp_fault: 349*38b04ad0SIbrahim Tilki case hwmon_temp_label: 350*38b04ad0SIbrahim Tilki return 0444; 351*38b04ad0SIbrahim Tilki case hwmon_temp_max: 352*38b04ad0SIbrahim Tilki case hwmon_temp_crit: 353*38b04ad0SIbrahim Tilki return 0644; 354*38b04ad0SIbrahim Tilki default: 355*38b04ad0SIbrahim Tilki return 0; 356*38b04ad0SIbrahim Tilki } 357*38b04ad0SIbrahim Tilki case hwmon_fan: 358*38b04ad0SIbrahim Tilki switch (attr) { 359*38b04ad0SIbrahim Tilki case hwmon_fan_input: 360*38b04ad0SIbrahim Tilki case hwmon_fan_fault: 361*38b04ad0SIbrahim Tilki return 0444; 362*38b04ad0SIbrahim Tilki case hwmon_fan_enable: 363*38b04ad0SIbrahim Tilki return 0644; 364*38b04ad0SIbrahim Tilki default: 365*38b04ad0SIbrahim Tilki return 0; 366*38b04ad0SIbrahim Tilki } 367*38b04ad0SIbrahim Tilki case hwmon_pwm: 368*38b04ad0SIbrahim Tilki switch (attr) { 369*38b04ad0SIbrahim Tilki case hwmon_pwm_enable: 370*38b04ad0SIbrahim Tilki case hwmon_pwm_input: 371*38b04ad0SIbrahim Tilki case hwmon_pwm_freq: 372*38b04ad0SIbrahim Tilki case hwmon_pwm_auto_channels_temp: 373*38b04ad0SIbrahim Tilki return 0644; 374*38b04ad0SIbrahim Tilki default: 375*38b04ad0SIbrahim Tilki return 0; 376*38b04ad0SIbrahim Tilki } 377*38b04ad0SIbrahim Tilki default: 378*38b04ad0SIbrahim Tilki return 0; 379*38b04ad0SIbrahim Tilki } 380*38b04ad0SIbrahim Tilki } 381*38b04ad0SIbrahim Tilki 382*38b04ad0SIbrahim Tilki static int max31760_read_string(struct device *dev, 383*38b04ad0SIbrahim Tilki enum hwmon_sensor_types type, 384*38b04ad0SIbrahim Tilki u32 attr, int channel, const char **str) 385*38b04ad0SIbrahim Tilki { 386*38b04ad0SIbrahim Tilki switch (type) { 387*38b04ad0SIbrahim Tilki case hwmon_temp: 388*38b04ad0SIbrahim Tilki if (attr != hwmon_temp_label) 389*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 390*38b04ad0SIbrahim Tilki 391*38b04ad0SIbrahim Tilki *str = channel ? "local" : "remote"; 392*38b04ad0SIbrahim Tilki 393*38b04ad0SIbrahim Tilki return 0; 394*38b04ad0SIbrahim Tilki default: 395*38b04ad0SIbrahim Tilki return -EOPNOTSUPP; 396*38b04ad0SIbrahim Tilki } 397*38b04ad0SIbrahim Tilki } 398*38b04ad0SIbrahim Tilki 399*38b04ad0SIbrahim Tilki static const struct hwmon_ops max31760_hwmon_ops = { 400*38b04ad0SIbrahim Tilki .is_visible = max31760_is_visible, 401*38b04ad0SIbrahim Tilki .read = max31760_read, 402*38b04ad0SIbrahim Tilki .write = max31760_write, 403*38b04ad0SIbrahim Tilki .read_string = max31760_read_string 404*38b04ad0SIbrahim Tilki }; 405*38b04ad0SIbrahim Tilki 406*38b04ad0SIbrahim Tilki static const struct hwmon_chip_info max31760_chip_info = { 407*38b04ad0SIbrahim Tilki .ops = &max31760_hwmon_ops, 408*38b04ad0SIbrahim Tilki .info = max31760_info, 409*38b04ad0SIbrahim Tilki }; 410*38b04ad0SIbrahim Tilki 411*38b04ad0SIbrahim Tilki static ssize_t lut_show(struct device *dev, 412*38b04ad0SIbrahim Tilki struct device_attribute *devattr, char *buf) 413*38b04ad0SIbrahim Tilki { 414*38b04ad0SIbrahim Tilki struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); 415*38b04ad0SIbrahim Tilki struct max31760_state *state = dev_get_drvdata(dev); 416*38b04ad0SIbrahim Tilki int ret; 417*38b04ad0SIbrahim Tilki unsigned int regval; 418*38b04ad0SIbrahim Tilki 419*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_LUT(sda->index), ®val); 420*38b04ad0SIbrahim Tilki if (ret) 421*38b04ad0SIbrahim Tilki return ret; 422*38b04ad0SIbrahim Tilki 423*38b04ad0SIbrahim Tilki return sysfs_emit(buf, "%d\n", regval); 424*38b04ad0SIbrahim Tilki } 425*38b04ad0SIbrahim Tilki 426*38b04ad0SIbrahim Tilki static ssize_t lut_store(struct device *dev, 427*38b04ad0SIbrahim Tilki struct device_attribute *devattr, 428*38b04ad0SIbrahim Tilki const char *buf, size_t count) 429*38b04ad0SIbrahim Tilki { 430*38b04ad0SIbrahim Tilki struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); 431*38b04ad0SIbrahim Tilki struct max31760_state *state = dev_get_drvdata(dev); 432*38b04ad0SIbrahim Tilki int ret; 433*38b04ad0SIbrahim Tilki u8 pwm; 434*38b04ad0SIbrahim Tilki 435*38b04ad0SIbrahim Tilki ret = kstrtou8(buf, 10, &pwm); 436*38b04ad0SIbrahim Tilki if (ret) 437*38b04ad0SIbrahim Tilki return ret; 438*38b04ad0SIbrahim Tilki 439*38b04ad0SIbrahim Tilki ret = regmap_write(state->regmap, REG_LUT(sda->index), pwm); 440*38b04ad0SIbrahim Tilki if (ret) 441*38b04ad0SIbrahim Tilki return ret; 442*38b04ad0SIbrahim Tilki 443*38b04ad0SIbrahim Tilki return count; 444*38b04ad0SIbrahim Tilki } 445*38b04ad0SIbrahim Tilki 446*38b04ad0SIbrahim Tilki static ssize_t pwm1_auto_point_temp_hyst_show(struct device *dev, 447*38b04ad0SIbrahim Tilki struct device_attribute *attr, 448*38b04ad0SIbrahim Tilki char *buf) 449*38b04ad0SIbrahim Tilki { 450*38b04ad0SIbrahim Tilki struct max31760_state *state = dev_get_drvdata(dev); 451*38b04ad0SIbrahim Tilki unsigned int regval; 452*38b04ad0SIbrahim Tilki int ret; 453*38b04ad0SIbrahim Tilki 454*38b04ad0SIbrahim Tilki ret = regmap_read(state->regmap, REG_CR1, ®val); 455*38b04ad0SIbrahim Tilki if (ret) 456*38b04ad0SIbrahim Tilki return ret; 457*38b04ad0SIbrahim Tilki 458*38b04ad0SIbrahim Tilki return sysfs_emit(buf, "%d\n", (1 + (int)FIELD_GET(CR1_HYST, regval)) * 2000); 459*38b04ad0SIbrahim Tilki } 460*38b04ad0SIbrahim Tilki 461*38b04ad0SIbrahim Tilki static ssize_t pwm1_auto_point_temp_hyst_store(struct device *dev, 462*38b04ad0SIbrahim Tilki struct device_attribute *attr, 463*38b04ad0SIbrahim Tilki const char *buf, 464*38b04ad0SIbrahim Tilki size_t count) 465*38b04ad0SIbrahim Tilki { 466*38b04ad0SIbrahim Tilki struct max31760_state *state = dev_get_drvdata(dev); 467*38b04ad0SIbrahim Tilki unsigned int hyst; 468*38b04ad0SIbrahim Tilki int ret; 469*38b04ad0SIbrahim Tilki 470*38b04ad0SIbrahim Tilki ret = kstrtou32(buf, 10, &hyst); 471*38b04ad0SIbrahim Tilki if (ret) 472*38b04ad0SIbrahim Tilki return ret; 473*38b04ad0SIbrahim Tilki 474*38b04ad0SIbrahim Tilki if (hyst < 3000) 475*38b04ad0SIbrahim Tilki ret = regmap_clear_bits(state->regmap, REG_CR1, CR1_HYST); 476*38b04ad0SIbrahim Tilki else 477*38b04ad0SIbrahim Tilki ret = regmap_set_bits(state->regmap, REG_CR1, CR1_HYST); 478*38b04ad0SIbrahim Tilki 479*38b04ad0SIbrahim Tilki if (ret) 480*38b04ad0SIbrahim Tilki return ret; 481*38b04ad0SIbrahim Tilki 482*38b04ad0SIbrahim Tilki return count; 483*38b04ad0SIbrahim Tilki } 484*38b04ad0SIbrahim Tilki 485*38b04ad0SIbrahim Tilki static DEVICE_ATTR_RW(pwm1_auto_point_temp_hyst); 486*38b04ad0SIbrahim Tilki 487*38b04ad0SIbrahim Tilki static void max31760_create_lut_nodes(struct max31760_state *state) 488*38b04ad0SIbrahim Tilki { 489*38b04ad0SIbrahim Tilki int i; 490*38b04ad0SIbrahim Tilki struct sensor_device_attribute *sda; 491*38b04ad0SIbrahim Tilki struct lut_attribute *lut; 492*38b04ad0SIbrahim Tilki 493*38b04ad0SIbrahim Tilki for (i = 0; i < LUT_SIZE; ++i) { 494*38b04ad0SIbrahim Tilki lut = &state->lut[i]; 495*38b04ad0SIbrahim Tilki sda = &lut->sda; 496*38b04ad0SIbrahim Tilki 497*38b04ad0SIbrahim Tilki snprintf(lut->name, sizeof(lut->name), 498*38b04ad0SIbrahim Tilki "pwm1_auto_point%d_pwm", i + 1); 499*38b04ad0SIbrahim Tilki 500*38b04ad0SIbrahim Tilki sda->dev_attr.attr.mode = 0644; 501*38b04ad0SIbrahim Tilki sda->index = i; 502*38b04ad0SIbrahim Tilki sda->dev_attr.show = lut_show; 503*38b04ad0SIbrahim Tilki sda->dev_attr.store = lut_store; 504*38b04ad0SIbrahim Tilki sda->dev_attr.attr.name = lut->name; 505*38b04ad0SIbrahim Tilki 506*38b04ad0SIbrahim Tilki sysfs_attr_init(&sda->dev_attr.attr); 507*38b04ad0SIbrahim Tilki 508*38b04ad0SIbrahim Tilki state->attrs[i] = &sda->dev_attr.attr; 509*38b04ad0SIbrahim Tilki } 510*38b04ad0SIbrahim Tilki 511*38b04ad0SIbrahim Tilki state->attrs[i] = &dev_attr_pwm1_auto_point_temp_hyst.attr; 512*38b04ad0SIbrahim Tilki 513*38b04ad0SIbrahim Tilki state->group.attrs = state->attrs; 514*38b04ad0SIbrahim Tilki state->groups[0] = &state->group; 515*38b04ad0SIbrahim Tilki } 516*38b04ad0SIbrahim Tilki 517*38b04ad0SIbrahim Tilki static int max31760_probe(struct i2c_client *client) 518*38b04ad0SIbrahim Tilki { 519*38b04ad0SIbrahim Tilki struct device *dev = &client->dev; 520*38b04ad0SIbrahim Tilki struct max31760_state *state; 521*38b04ad0SIbrahim Tilki struct device *hwmon_dev; 522*38b04ad0SIbrahim Tilki int ret; 523*38b04ad0SIbrahim Tilki 524*38b04ad0SIbrahim Tilki state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); 525*38b04ad0SIbrahim Tilki if (!state) 526*38b04ad0SIbrahim Tilki return -ENOMEM; 527*38b04ad0SIbrahim Tilki 528*38b04ad0SIbrahim Tilki state->regmap = devm_regmap_init_i2c(client, ®map_config); 529*38b04ad0SIbrahim Tilki if (IS_ERR(state->regmap)) 530*38b04ad0SIbrahim Tilki return dev_err_probe(dev, 531*38b04ad0SIbrahim Tilki PTR_ERR(state->regmap), 532*38b04ad0SIbrahim Tilki "regmap initialization failed\n"); 533*38b04ad0SIbrahim Tilki 534*38b04ad0SIbrahim Tilki dev_set_drvdata(dev, state); 535*38b04ad0SIbrahim Tilki 536*38b04ad0SIbrahim Tilki /* Set alert output to comparator mode */ 537*38b04ad0SIbrahim Tilki ret = regmap_set_bits(state->regmap, REG_CR2, CR2_ALERTS); 538*38b04ad0SIbrahim Tilki if (ret) 539*38b04ad0SIbrahim Tilki return dev_err_probe(dev, ret, "cannot write register\n"); 540*38b04ad0SIbrahim Tilki 541*38b04ad0SIbrahim Tilki max31760_create_lut_nodes(state); 542*38b04ad0SIbrahim Tilki 543*38b04ad0SIbrahim Tilki hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 544*38b04ad0SIbrahim Tilki state, 545*38b04ad0SIbrahim Tilki &max31760_chip_info, 546*38b04ad0SIbrahim Tilki state->groups); 547*38b04ad0SIbrahim Tilki 548*38b04ad0SIbrahim Tilki return PTR_ERR_OR_ZERO(hwmon_dev); 549*38b04ad0SIbrahim Tilki } 550*38b04ad0SIbrahim Tilki 551*38b04ad0SIbrahim Tilki static const struct of_device_id max31760_of_match[] = { 552*38b04ad0SIbrahim Tilki {.compatible = "adi,max31760"}, 553*38b04ad0SIbrahim Tilki { } 554*38b04ad0SIbrahim Tilki }; 555*38b04ad0SIbrahim Tilki MODULE_DEVICE_TABLE(of, max31760_of_match); 556*38b04ad0SIbrahim Tilki 557*38b04ad0SIbrahim Tilki static const struct i2c_device_id max31760_id[] = { 558*38b04ad0SIbrahim Tilki {"max31760"}, 559*38b04ad0SIbrahim Tilki { } 560*38b04ad0SIbrahim Tilki }; 561*38b04ad0SIbrahim Tilki MODULE_DEVICE_TABLE(i2c, max31760_id); 562*38b04ad0SIbrahim Tilki 563*38b04ad0SIbrahim Tilki static int max31760_suspend(struct device *dev) 564*38b04ad0SIbrahim Tilki { 565*38b04ad0SIbrahim Tilki struct max31760_state *state = dev_get_drvdata(dev); 566*38b04ad0SIbrahim Tilki 567*38b04ad0SIbrahim Tilki return regmap_set_bits(state->regmap, REG_CR2, CR2_STBY); 568*38b04ad0SIbrahim Tilki } 569*38b04ad0SIbrahim Tilki 570*38b04ad0SIbrahim Tilki static int max31760_resume(struct device *dev) 571*38b04ad0SIbrahim Tilki { 572*38b04ad0SIbrahim Tilki struct max31760_state *state = dev_get_drvdata(dev); 573*38b04ad0SIbrahim Tilki 574*38b04ad0SIbrahim Tilki return regmap_clear_bits(state->regmap, REG_CR2, CR2_STBY); 575*38b04ad0SIbrahim Tilki } 576*38b04ad0SIbrahim Tilki 577*38b04ad0SIbrahim Tilki static DEFINE_SIMPLE_DEV_PM_OPS(max31760_pm_ops, max31760_suspend, 578*38b04ad0SIbrahim Tilki max31760_resume); 579*38b04ad0SIbrahim Tilki 580*38b04ad0SIbrahim Tilki static struct i2c_driver max31760_driver = { 581*38b04ad0SIbrahim Tilki .class = I2C_CLASS_HWMON, 582*38b04ad0SIbrahim Tilki .driver = { 583*38b04ad0SIbrahim Tilki .name = "max31760", 584*38b04ad0SIbrahim Tilki .of_match_table = max31760_of_match, 585*38b04ad0SIbrahim Tilki .pm = pm_ptr(&max31760_pm_ops) 586*38b04ad0SIbrahim Tilki }, 587*38b04ad0SIbrahim Tilki .probe_new = max31760_probe, 588*38b04ad0SIbrahim Tilki .id_table = max31760_id 589*38b04ad0SIbrahim Tilki }; 590*38b04ad0SIbrahim Tilki module_i2c_driver(max31760_driver); 591*38b04ad0SIbrahim Tilki 592*38b04ad0SIbrahim Tilki MODULE_AUTHOR("Ibrahim Tilki <Ibrahim.Tilki@analog.com>"); 593*38b04ad0SIbrahim Tilki MODULE_DESCRIPTION("Analog Devices MAX31760 Fan Speed Controller"); 594*38b04ad0SIbrahim Tilki MODULE_SOFTDEP("pre: regmap_i2c"); 595*38b04ad0SIbrahim Tilki MODULE_VERSION("1.0"); 596*38b04ad0SIbrahim Tilki MODULE_LICENSE("GPL"); 597