/* * Note: we save and restore the fan minimum here, because its value is * determined in part by the fan divisor. This follows the principle of * least surprise; the user doesn't expect the fan minimum to change just * because the divisor changed. */ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = dev_get_drvdata(dev); int nr = attr->index; unsigned long min; u8 reg; unsigned long val; int err; err = kstrtoul(buf, 10, &val); if (err) return err; mutex_lock(&data->update_lock); min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); switch (val) { case 1: data->fan_div[nr] = 0; break; case 2: data->fan_div[nr] = 1; break; case 4: data->fan_div[nr] = 2; break; case 8: data->fan_div[nr] = 3; break; default: dev_err(dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", val); mutex_unlock(&data->update_lock); return -EINVAL; } reg = lm78_read_value(data, LM78_REG_VID_FANDIV); switch (nr) { case 0: reg = (reg & 0xcf) | (data->fan_div[nr] << 4); break; case 1: reg = (reg & 0x3f) | (data->fan_div[nr] << 6); break; } lm78_write_value(data, LM78_REG_VID_FANDIV, reg); data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); mutex_unlock(&data->update_lock); return count; }
static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct lm78_data *data = dev_get_drvdata(dev); long val = simple_strtol(buf, NULL, 10); mutex_lock(&data->update_lock); data->temp_hyst = TEMP_TO_REG(val); lm78_write_value(data, LM78_REG_TEMP_HYST, data->temp_hyst); mutex_unlock(&data->update_lock); return count; }
static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = dev_get_drvdata(dev); int nr = attr->index; unsigned long val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); mutex_unlock(&data->update_lock); return count; }
static ssize_t set_temp_over(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct lm78_data *data = dev_get_drvdata(dev); long val; int err; err = kstrtol(buf, 10, &val); if (err) return err; mutex_lock(&data->update_lock); data->temp_over = TEMP_TO_REG(val); lm78_write_value(data, LM78_REG_TEMP_OVER, data->temp_over); mutex_unlock(&data->update_lock); return count; }
static void lm78_init_device(struct lm78_data *data) { u8 config; int i; /* Start monitoring */ config = lm78_read_value(data, LM78_REG_CONFIG); if ((config & 0x09) != 0x01) lm78_write_value(data, LM78_REG_CONFIG, (config & 0xf7) | 0x01); /* A few vars need to be filled upon startup */ for (i = 0; i < 3; i++) { data->fan_min[i] = lm78_read_value(data, LM78_REG_FAN_MIN(i)); } mutex_init(&data->update_lock); }
static ssize_t set_in_max(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = dev_get_drvdata(dev); int nr = attr->index; unsigned long val; int err; err = kstrtoul(buf, 10, &val); if (err) return err; mutex_lock(&data->update_lock); data->in_max[nr] = IN_TO_REG(val); lm78_write_value(data, LM78_REG_IN_MAX(nr), data->in_max[nr]); mutex_unlock(&data->update_lock); return count; }
static void lm78_init_device(struct lm78_data *data) { u8 config; int i; config = lm78_read_value(data, LM78_REG_CONFIG); if ((config & 0x09) != 0x01) lm78_write_value(data, LM78_REG_CONFIG, (config & 0xf7) | 0x01); for (i = 0; i < 3; i++) { data->fan_min[i] = lm78_read_value(data, LM78_REG_FAN_MIN(i)); } mutex_init(&data->update_lock); }