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;
}
Esempio n. 4
0
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;
}
Esempio n. 6
0
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;
}