static ssize_t store_bank2_mask(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); ssize_t ret; u8 orig_val; unsigned long mask; ret = kstrtoul(buf, 10, &mask); if (ret) return ret; ret = count; mutex_lock(&data->update_lock); orig_val = data->bank2_settings[attr->index][0]; if (mask) data->bank2_settings[attr->index][0] |= attr->nr; else data->bank2_settings[attr->index][0] &= ~attr->nr; if ((data->bank2_settings[attr->index][0] != orig_val) && (abituguru_write(data, ABIT_UGURU_SENSOR_BANK2 + 2, attr->index, data->bank2_settings[attr->index], 2) < 1)) { data->bank2_settings[attr->index][0] = orig_val; ret = -EIO; } mutex_unlock(&data->update_lock); return ret; }
static ssize_t store_pwm_sensor(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); ssize_t ret; unsigned long val; u8 orig_val; u8 address; ret = kstrtoul(buf, 10, &val); if (ret) return ret; if (val == 0 || val > data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) return -EINVAL; val -= 1; ret = count; mutex_lock(&data->update_lock); orig_val = data->pwm_settings[attr->index][0]; address = data->bank1_address[ABIT_UGURU_TEMP_SENSOR][val]; data->pwm_settings[attr->index][0] &= 0xF0; data->pwm_settings[attr->index][0] |= address; if (data->pwm_settings[attr->index][0] != orig_val) { if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, attr->index, data->pwm_settings[attr->index], 5) < 1) { data->pwm_settings[attr->index][0] = orig_val; ret = -EIO; } } mutex_unlock(&data->update_lock); return ret; }
static ssize_t store_bank2_setting(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); unsigned long val; ssize_t ret; ret = kstrtoul(buf, 10, &val); if (ret) return ret; ret = count; val = (val * 255 + ABIT_UGURU_FAN_MAX / 2) / ABIT_UGURU_FAN_MAX; if (val < abituguru_bank2_min_threshold || val > abituguru_bank2_max_threshold) return -EINVAL; mutex_lock(&data->update_lock); if (data->bank2_settings[attr->index][attr->nr] != val) { u8 orig_val = data->bank2_settings[attr->index][attr->nr]; data->bank2_settings[attr->index][attr->nr] = val; if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK2 + 2, attr->index, data->bank2_settings[attr->index], 2) <= attr->nr) { data->bank2_settings[attr->index][attr->nr] = orig_val; ret = -EIO; } } mutex_unlock(&data->update_lock); return ret; }
static ssize_t store_pwm_enable(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); u8 orig_val, user_val = simple_strtoul(buf, NULL, 10); ssize_t ret = count; mutex_lock(&data->update_lock); orig_val = data->pwm_settings[attr->index][0]; switch (user_val) { case 0: data->pwm_settings[attr->index][0] &= ~ABIT_UGURU_FAN_PWM_ENABLE; break; case 2: data->pwm_settings[attr->index][0] |= ABIT_UGURU_FAN_PWM_ENABLE; break; default: ret = -EINVAL; } if ((data->pwm_settings[attr->index][0] != orig_val) && (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, attr->index, data->pwm_settings[attr->index], 5) < 1)) { data->pwm_settings[attr->index][0] = orig_val; ret = -EIO; } mutex_unlock(&data->update_lock); return ret; }
static ssize_t store_pwm_setting(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); u8 min; unsigned long val; ssize_t ret; ret = kstrtoul(buf, 10, &val); if (ret) return ret; ret = count; val = (val + abituguru_pwm_settings_multiplier[attr->nr] / 2) / abituguru_pwm_settings_multiplier[attr->nr]; if ((attr->index == 0) && ((attr->nr == 1) || (attr->nr == 2))) min = 77; else min = abituguru_pwm_min[attr->nr]; if (val < min || val > abituguru_pwm_max[attr->nr]) return -EINVAL; mutex_lock(&data->update_lock); if ((attr->nr & 1) && (val >= data->pwm_settings[attr->index][attr->nr + 1])) ret = -EINVAL; else if (!(attr->nr & 1) && (val <= data->pwm_settings[attr->index][attr->nr - 1])) ret = -EINVAL; else if (data->pwm_settings[attr->index][attr->nr] != val) { u8 orig_val = data->pwm_settings[attr->index][attr->nr]; data->pwm_settings[attr->index][attr->nr] = val; if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, attr->index, data->pwm_settings[attr->index], 5) <= attr->nr) { data->pwm_settings[attr->index][attr->nr] = orig_val; ret = -EIO; } } mutex_unlock(&data->update_lock); return ret; }
static ssize_t store_bank1_setting(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); struct abituguru_data *data = dev_get_drvdata(dev); u8 val = (simple_strtoul(buf, NULL, 10) * 255 + data->bank1_max_value[attr->index]/2) / data->bank1_max_value[attr->index]; ssize_t ret = count; mutex_lock(&data->update_lock); if (data->bank1_settings[attr->index][attr->nr] != val) { u8 orig_val = data->bank1_settings[attr->index][attr->nr]; data->bank1_settings[attr->index][attr->nr] = val; if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, attr->index, data->bank1_settings[attr->index], 3) <= attr->nr) { data->bank1_settings[attr->index][attr->nr] = orig_val; ret = -EIO; } } mutex_unlock(&data->update_lock); return ret; }
static int __devinit abituguru_detect_bank1_sensor_type(struct abituguru_data *data, u8 sensor_addr) { u8 val, test_flag, buf[3]; int i, ret = -ENODEV; if (bank1_types[sensor_addr] >= ABIT_UGURU_IN_SENSOR && bank1_types[sensor_addr] <= ABIT_UGURU_NC) { ABIT_UGURU_DEBUG(2, "assuming sensor type %d for bank1 sensor " "%d because of \"bank1_types\" module param\n", bank1_types[sensor_addr], (int)sensor_addr); return bank1_types[sensor_addr]; } if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, sensor_addr, &val, 1, ABIT_UGURU_MAX_RETRIES) != 1) return -ENODEV; if ((val < 10u) || (val > 250u)) { pr_warn("bank1-sensor: %d reading (%d) too close to limits, " "unable to determine sensor type, skipping sensor\n", (int)sensor_addr, (int)val); return ABIT_UGURU_NC; } ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); if (val <= 240u) { buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; buf[1] = 245; buf[2] = 250; test_flag = ABIT_UGURU_VOLT_LOW_ALARM_FLAG; } else { buf[0] = ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE; buf[1] = 5; buf[2] = 10; test_flag = ABIT_UGURU_VOLT_HIGH_ALARM_FLAG; } if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, buf, 3) != 3) goto abituguru_detect_bank1_sensor_type_exit; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/50); if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, ABIT_UGURU_MAX_RETRIES) != 3) goto abituguru_detect_bank1_sensor_type_exit; if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, sensor_addr, buf, 3, ABIT_UGURU_MAX_RETRIES) != 3) goto abituguru_detect_bank1_sensor_type_exit; if (buf[0] & test_flag) { ABIT_UGURU_DEBUG(2, " found volt sensor\n"); ret = ABIT_UGURU_IN_SENSOR; goto abituguru_detect_bank1_sensor_type_exit; } else ABIT_UGURU_DEBUG(2, " alarm raised during volt " "sensor test, but volt range flag not set\n"); } else ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " "test\n"); buf[0] = ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE; buf[1] = 5; buf[2] = 10; if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, buf, 3) != 3) goto abituguru_detect_bank1_sensor_type_exit; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/20); if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, ABIT_UGURU_MAX_RETRIES) != 3) goto abituguru_detect_bank1_sensor_type_exit; if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, sensor_addr, buf, 3, ABIT_UGURU_MAX_RETRIES) != 3) goto abituguru_detect_bank1_sensor_type_exit; if (buf[0] & ABIT_UGURU_TEMP_HIGH_ALARM_FLAG) { ABIT_UGURU_DEBUG(2, " found temp sensor\n"); ret = ABIT_UGURU_TEMP_SENSOR; goto abituguru_detect_bank1_sensor_type_exit; } else ABIT_UGURU_DEBUG(2, " alarm raised during temp " "sensor test, but temp high flag not set\n"); } else ABIT_UGURU_DEBUG(2, " alarm not raised during temp sensor " "test\n"); ret = ABIT_UGURU_NC; abituguru_detect_bank1_sensor_type_exit: for (i = 0; i < 3; i++) if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, data->bank1_settings[sensor_addr], 3) == 3) break; if (i == 3) { pr_err("Fatal error could not restore original settings. %s %s\n", never_happen, report_this); return -ENODEV; } return ret; }