diff options
Diffstat (limited to 'drivers/hwmon/max31790.c')
| -rw-r--r-- | drivers/hwmon/max31790.c | 101 |
1 files changed, 52 insertions, 49 deletions
diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c index 7e9362f6dc29..4f6171a17d9f 100644 --- a/drivers/hwmon/max31790.c +++ b/drivers/hwmon/max31790.c @@ -49,12 +49,14 @@ #define NR_CHANNEL 6 +#define PWM_INPUT_SCALE 255 +#define MAX31790_REG_PWMOUT_SCALE 511 + /* * Client data (each client gets its own) */ struct max31790_data { struct i2c_client *client; - struct mutex update_lock; bool valid; /* zero until following fields are valid */ unsigned long last_updated; /* in jiffies */ @@ -71,30 +73,27 @@ static struct max31790_data *max31790_update_device(struct device *dev) { struct max31790_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; - struct max31790_data *ret = data; - int i; - int rv; - - mutex_lock(&data->update_lock); + int i, rv; if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + data->valid = false; rv = i2c_smbus_read_byte_data(client, MAX31790_REG_FAN_FAULT_STATUS1); if (rv < 0) - goto abort; + return ERR_PTR(rv); data->fault_status |= rv & 0x3F; rv = i2c_smbus_read_byte_data(client, MAX31790_REG_FAN_FAULT_STATUS2); if (rv < 0) - goto abort; + return ERR_PTR(rv); data->fault_status |= (rv & 0x3F) << 6; for (i = 0; i < NR_CHANNEL; i++) { rv = i2c_smbus_read_word_swapped(client, MAX31790_REG_TACH_COUNT(i)); if (rv < 0) - goto abort; + return ERR_PTR(rv); data->tach[i] = rv; if (data->fan_config[i] @@ -103,19 +102,19 @@ static struct max31790_data *max31790_update_device(struct device *dev) MAX31790_REG_TACH_COUNT(NR_CHANNEL + i)); if (rv < 0) - goto abort; + return ERR_PTR(rv); data->tach[NR_CHANNEL + i] = rv; } else { rv = i2c_smbus_read_word_swapped(client, MAX31790_REG_PWM_DUTY_CYCLE(i)); if (rv < 0) - goto abort; + return ERR_PTR(rv); data->pwm[i] = rv; rv = i2c_smbus_read_word_swapped(client, MAX31790_REG_TARGET_COUNT(i)); if (rv < 0) - goto abort; + return ERR_PTR(rv); data->target_count[i] = rv; } } @@ -123,16 +122,7 @@ static struct max31790_data *max31790_update_device(struct device *dev) data->last_updated = jiffies; data->valid = true; } - goto done; - -abort: - data->valid = false; - ret = ERR_PTR(rv); - -done: - mutex_unlock(&data->update_lock); - - return ret; + return data; } static const u8 tach_period[8] = { 1, 2, 4, 8, 16, 32, 32, 32 }; @@ -186,7 +176,6 @@ static int max31790_read_fan(struct device *dev, u32 attr, int channel, *val = rpm; return 0; case hwmon_fan_fault: - mutex_lock(&data->update_lock); *val = !!(data->fault_status & (1 << channel)); data->fault_status &= ~(1 << channel); /* @@ -197,10 +186,12 @@ static int max31790_read_fan(struct device *dev, u32 attr, int channel, if (*val) { int reg = MAX31790_REG_TARGET_COUNT(channel % NR_CHANNEL); - i2c_smbus_write_byte_data(data->client, reg, - data->target_count[channel % NR_CHANNEL] >> 8); + return i2c_smbus_write_byte_data(data->client, reg, + data->target_count[channel % NR_CHANNEL] >> 8); } - mutex_unlock(&data->update_lock); + return 0; + case hwmon_fan_enable: + *val = !!(data->fan_config[channel] & MAX31790_FAN_CFG_TACH_INPUT_EN); return 0; default: return -EOPNOTSUPP; @@ -214,11 +205,9 @@ static int max31790_write_fan(struct device *dev, u32 attr, int channel, struct i2c_client *client = data->client; int target_count; int err = 0; - u8 bits; + u8 bits, fan_config; int sr; - mutex_lock(&data->update_lock); - switch (attr) { case hwmon_fan_target: val = clamp_val(val, FAN_RPM_MIN, FAN_RPM_MAX); @@ -243,13 +232,27 @@ static int max31790_write_fan(struct device *dev, u32 attr, int channel, MAX31790_REG_TARGET_COUNT(channel), data->target_count[channel]); break; + case hwmon_fan_enable: + fan_config = data->fan_config[channel]; + if (val == 0) { + fan_config &= ~MAX31790_FAN_CFG_TACH_INPUT_EN; + } else if (val == 1) { + fan_config |= MAX31790_FAN_CFG_TACH_INPUT_EN; + } else { + err = -EINVAL; + break; + } + if (fan_config != data->fan_config[channel]) { + err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel), + fan_config); + if (!err) + data->fan_config[channel] = fan_config; + } + break; default: err = -EOPNOTSUPP; break; } - - mutex_unlock(&data->update_lock); - return err; } @@ -270,6 +273,10 @@ static umode_t max31790_fan_is_visible(const void *_data, u32 attr, int channel) !(fan_config & MAX31790_FAN_CFG_TACH_INPUT)) return 0644; return 0; + case hwmon_fan_enable: + if (channel < NR_CHANNEL) + return 0644; + return 0; default: return 0; } @@ -311,18 +318,19 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel, u8 fan_config; int err = 0; - mutex_lock(&data->update_lock); - switch (attr) { case hwmon_pwm_input: if (val < 0 || val > 255) { err = -EINVAL; break; } + + val = DIV_ROUND_CLOSEST(val * MAX31790_REG_PWMOUT_SCALE, + PWM_INPUT_SCALE); data->valid = false; err = i2c_smbus_write_word_swapped(client, MAX31790_REG_PWMOUT(channel), - val << 8); + val << 7); break; case hwmon_pwm_enable: fan_config = data->fan_config[channel]; @@ -359,9 +367,6 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel, err = -EOPNOTSUPP; break; } - - mutex_unlock(&data->update_lock); - return err; } @@ -421,14 +426,14 @@ static umode_t max31790_is_visible(const void *data, } } -static const struct hwmon_channel_info *max31790_info[] = { +static const struct hwmon_channel_info * const max31790_info[] = { HWMON_CHANNEL_INFO(fan, - HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, - HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, - HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, - HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, - HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, - HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT, + HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE, + HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE, + HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE, + HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE, + HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE, + HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT | HWMON_F_ENABLE, HWMON_F_INPUT | HWMON_F_FAULT, HWMON_F_INPUT | HWMON_F_FAULT, HWMON_F_INPUT | HWMON_F_FAULT, @@ -495,7 +500,6 @@ static int max31790_probe(struct i2c_client *client) return -ENOMEM; data->client = client; - mutex_init(&data->update_lock); /* * Initialize the max31790 chip @@ -513,14 +517,13 @@ static int max31790_probe(struct i2c_client *client) } static const struct i2c_device_id max31790_id[] = { - { "max31790", 0 }, + { "max31790" }, { } }; MODULE_DEVICE_TABLE(i2c, max31790_id); static struct i2c_driver max31790_driver = { - .class = I2C_CLASS_HWMON, - .probe_new = max31790_probe, + .probe = max31790_probe, .driver = { .name = "max31790", }, |
