^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * max31790.c - Part of lm_sensors, Linux kernel modules for hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * monitoring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (C) 2015 by Il Han <corone.il.han@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* MAX31790 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define MAX31790_REG_GLOBAL_CONFIG 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define MAX31790_REG_FAN_CONFIG(ch) (0x02 + (ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define MAX31790_REG_FAN_DYNAMICS(ch) (0x08 + (ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define MAX31790_REG_FAN_FAULT_STATUS2 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define MAX31790_REG_FAN_FAULT_STATUS1 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define MAX31790_REG_TACH_COUNT(ch) (0x18 + (ch) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define MAX31790_REG_PWM_DUTY_CYCLE(ch) (0x30 + (ch) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define MAX31790_REG_PWMOUT(ch) (0x40 + (ch) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define MAX31790_REG_TARGET_COUNT(ch) (0x50 + (ch) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Fan Config register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define MAX31790_FAN_CFG_RPM_MODE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define MAX31790_FAN_CFG_CTRL_MON 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MAX31790_FAN_CFG_TACH_INPUT_EN 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MAX31790_FAN_CFG_TACH_INPUT 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Fan Dynamics register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MAX31790_FAN_DYN_SR_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define MAX31790_FAN_DYN_SR_MASK 0xE0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SR_FROM_REG(reg) (((reg) & MAX31790_FAN_DYN_SR_MASK) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) >> MAX31790_FAN_DYN_SR_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FAN_RPM_MIN 120
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define FAN_RPM_MAX 7864320
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define RPM_FROM_REG(reg, sr) (((reg) >> 4) ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ((60 * (sr) * 8192) / ((reg) >> 4)) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) FAN_RPM_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define RPM_TO_REG(rpm, sr) ((60 * (sr) * 8192) / ((rpm) * 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define NR_CHANNEL 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Client data (each client gets its own)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct max31790_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) bool valid; /* zero until following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned long last_updated; /* in jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u8 fan_config[NR_CHANNEL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u8 fan_dynamics[NR_CHANNEL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u16 fault_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u16 tach[NR_CHANNEL * 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) u16 pwm[NR_CHANNEL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u16 target_count[NR_CHANNEL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static struct max31790_data *max31790_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct max31790_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct max31790_data *ret = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) rv = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) MAX31790_REG_FAN_FAULT_STATUS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) data->fault_status = rv & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) rv = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) MAX31790_REG_FAN_FAULT_STATUS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) data->fault_status |= (rv & 0x3F) << 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) for (i = 0; i < NR_CHANNEL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) rv = i2c_smbus_read_word_swapped(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) MAX31790_REG_TACH_COUNT(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) data->tach[i] = rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (data->fan_config[i]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) & MAX31790_FAN_CFG_TACH_INPUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) rv = i2c_smbus_read_word_swapped(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MAX31790_REG_TACH_COUNT(NR_CHANNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) + i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) data->tach[NR_CHANNEL + i] = rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) rv = i2c_smbus_read_word_swapped(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) MAX31790_REG_PWM_DUTY_CYCLE(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) data->pwm[i] = rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) rv = i2c_smbus_read_word_swapped(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) MAX31790_REG_TARGET_COUNT(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) data->target_count[i] = rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) data->valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) data->valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ret = ERR_PTR(rv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static const u8 tach_period[8] = { 1, 2, 4, 8, 16, 32, 32, 32 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static u8 get_tach_period(u8 fan_dynamics)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return tach_period[SR_FROM_REG(fan_dynamics)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static u8 bits_for_tach_period(int rpm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u8 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (rpm < 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) bits = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) else if (rpm < 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) bits = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) else if (rpm < 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) bits = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) else if (rpm < 4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) bits = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) else if (rpm < 8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) bits = 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) bits = 0x5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int max31790_read_fan(struct device *dev, u32 attr, int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct max31790_data *data = max31790_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int sr, rpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case hwmon_fan_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) sr = get_tach_period(data->fan_dynamics[channel % NR_CHANNEL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) rpm = RPM_FROM_REG(data->tach[channel], sr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) *val = rpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case hwmon_fan_target:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) sr = get_tach_period(data->fan_dynamics[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) rpm = RPM_FROM_REG(data->target_count[channel], sr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) *val = rpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case hwmon_fan_fault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *val = !!(data->fault_status & (1 << channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int max31790_write_fan(struct device *dev, u32 attr, int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct max31790_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int target_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) u8 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case hwmon_fan_target:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) val = clamp_val(val, FAN_RPM_MIN, FAN_RPM_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) bits = bits_for_tach_period(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) data->fan_dynamics[channel] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ((data->fan_dynamics[channel] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ~MAX31790_FAN_DYN_SR_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) (bits << MAX31790_FAN_DYN_SR_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) err = i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) MAX31790_REG_FAN_DYNAMICS(channel),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) data->fan_dynamics[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) sr = get_tach_period(data->fan_dynamics[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) target_count = RPM_TO_REG(val, sr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) target_count = clamp_val(target_count, 0x1, 0x7FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) data->target_count[channel] = target_count << 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) err = i2c_smbus_write_word_swapped(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) MAX31790_REG_TARGET_COUNT(channel),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) data->target_count[channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static umode_t max31790_fan_is_visible(const void *_data, u32 attr, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) const struct max31790_data *data = _data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u8 fan_config = data->fan_config[channel % NR_CHANNEL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case hwmon_fan_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case hwmon_fan_fault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (channel < NR_CHANNEL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) (fan_config & MAX31790_FAN_CFG_TACH_INPUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case hwmon_fan_target:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (channel < NR_CHANNEL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) !(fan_config & MAX31790_FAN_CFG_TACH_INPUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return 0644;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static int max31790_read_pwm(struct device *dev, u32 attr, int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct max31790_data *data = max31790_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u8 fan_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) fan_config = data->fan_config[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case hwmon_pwm_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *val = data->pwm[channel] >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case hwmon_pwm_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (fan_config & MAX31790_FAN_CFG_CTRL_MON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) else if (fan_config & MAX31790_FAN_CFG_RPM_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) *val = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static int max31790_write_pwm(struct device *dev, u32 attr, int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct max31790_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) u8 fan_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) case hwmon_pwm_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (val < 0 || val > 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) data->valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) err = i2c_smbus_write_word_swapped(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) MAX31790_REG_PWMOUT(channel),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) val << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case hwmon_pwm_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) fan_config = data->fan_config[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (val == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) fan_config |= MAX31790_FAN_CFG_CTRL_MON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * Disable RPM mode; otherwise disabling fan speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * monitoring is not possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) fan_config &= ~MAX31790_FAN_CFG_RPM_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) } else if (val == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) fan_config &= ~(MAX31790_FAN_CFG_CTRL_MON | MAX31790_FAN_CFG_RPM_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) } else if (val == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) fan_config &= ~MAX31790_FAN_CFG_CTRL_MON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * The chip sets MAX31790_FAN_CFG_TACH_INPUT_EN on its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * own if MAX31790_FAN_CFG_RPM_MODE is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * Do it here as well to reflect the actual register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * value in the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) fan_config |= (MAX31790_FAN_CFG_RPM_MODE | MAX31790_FAN_CFG_TACH_INPUT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (fan_config != data->fan_config[channel]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) fan_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) data->fan_config[channel] = fan_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static umode_t max31790_pwm_is_visible(const void *_data, u32 attr, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) const struct max31790_data *data = _data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) u8 fan_config = data->fan_config[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case hwmon_pwm_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case hwmon_pwm_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!(fan_config & MAX31790_FAN_CFG_TACH_INPUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return 0644;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int max31790_read(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) u32 attr, int channel, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) case hwmon_fan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return max31790_read_fan(dev, attr, channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case hwmon_pwm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return max31790_read_pwm(dev, attr, channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int max31790_write(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) u32 attr, int channel, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case hwmon_fan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return max31790_write_fan(dev, attr, channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) case hwmon_pwm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return max31790_write_pwm(dev, attr, channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static umode_t max31790_is_visible(const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) u32 attr, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) case hwmon_fan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return max31790_fan_is_visible(data, attr, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) case hwmon_pwm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return max31790_pwm_is_visible(data, attr, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static const struct hwmon_channel_info *max31790_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) HWMON_CHANNEL_INFO(fan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) HWMON_F_INPUT | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) HWMON_F_INPUT | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) HWMON_F_INPUT | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) HWMON_F_INPUT | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) HWMON_F_INPUT | HWMON_F_FAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) HWMON_F_INPUT | HWMON_F_FAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) HWMON_CHANNEL_INFO(pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) HWMON_PWM_INPUT | HWMON_PWM_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static const struct hwmon_ops max31790_hwmon_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .is_visible = max31790_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .read = max31790_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .write = max31790_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static const struct hwmon_chip_info max31790_chip_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .ops = &max31790_hwmon_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .info = max31790_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static int max31790_init_client(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct max31790_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int i, rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) for (i = 0; i < NR_CHANNEL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) rv = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) MAX31790_REG_FAN_CONFIG(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) data->fan_config[i] = rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) rv = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) MAX31790_REG_FAN_DYNAMICS(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) data->fan_dynamics[i] = rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int max31790_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct max31790_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (!i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) data = devm_kzalloc(dev, sizeof(struct max31790_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * Initialize the max31790 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) err = max31790_init_client(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) &max31790_chip_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return PTR_ERR_OR_ZERO(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static const struct i2c_device_id max31790_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) { "max31790", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) MODULE_DEVICE_TABLE(i2c, max31790_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static struct i2c_driver max31790_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .class = I2C_CLASS_HWMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .probe_new = max31790_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .name = "max31790",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .id_table = max31790_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) module_i2c_driver(max31790_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) MODULE_AUTHOR("Il Han <corone.il.han@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) MODULE_DESCRIPTION("MAX31790 sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) MODULE_LICENSE("GPL");