static int abituguru_send_address(struct abituguru_data *data,
                                  u8 bank_addr, u8 sensor_addr, int retries)
{
    int report_errors = retries;

    for (;;) {
        if (abituguru_ready(data) != 0)
            return -EIO;
        outb(bank_addr, data->addr + ABIT_UGURU_DATA);
        data->uguru_ready = 0;

        if (abituguru_wait(data, ABIT_UGURU_STATUS_INPUT)) {
            if (retries) {
                ABIT_UGURU_DEBUG(3, "timeout exceeded "
                                 "waiting for more input state, %d "
                                 "tries remaining\n", retries);
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule_timeout(ABIT_UGURU_RETRY_DELAY);
                retries--;
                continue;
            }
            if (report_errors)
                ABIT_UGURU_DEBUG(1, "timeout exceeded "
                                 "waiting for more input state "
                                 "(bank: %d)\n", (int)bank_addr);
            return -EBUSY;
        }
        outb(sensor_addr, data->addr + ABIT_UGURU_CMD);
        return 0;
    }
}
static struct abituguru_data *abituguru_update_device(struct device *dev)
{
    int i, err;
    struct abituguru_data *data = dev_get_drvdata(dev);

    char success = 1;

    mutex_lock(&data->update_lock);
    if (time_after(jiffies, data->last_updated + HZ)) {
        success = 0;
        err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0,
                             data->alarms, 3, 0);
        if (err != 3)
            goto LEAVE_UPDATE;
        for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) {
            err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK1,
                                 i, &data->bank1_value[i], 1, 0);
            if (err != 1)
                goto LEAVE_UPDATE;
            err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1,
                                 i, data->bank1_settings[i], 3, 0);
            if (err != 3)
                goto LEAVE_UPDATE;
        }
        for (i = 0; i < data->bank2_sensors; i++) {
            err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i,
                                 &data->bank2_value[i], 1, 0);
            if (err != 1)
                goto LEAVE_UPDATE;
        }

        success = 1;
        data->update_timeouts = 0;
LEAVE_UPDATE:

        if (!success && (err == -EBUSY || err >= 0)) {

            if (data->update_timeouts < 255u)
                data->update_timeouts++;
            if (data->update_timeouts <= ABIT_UGURU_MAX_TIMEOUTS) {
                ABIT_UGURU_DEBUG(3, "timeout exceeded, will "
                                 "try again next update\n");

                success = 1;
            } else
                ABIT_UGURU_DEBUG(1, "timeout exceeded %d "
                                 "times waiting for more input state\n",
                                 (int)data->update_timeouts);
        }

        if (success)
            data->last_updated = jiffies;
    }
    mutex_unlock(&data->update_lock);

    if (success)
        return data;
    else
        return NULL;
}
Ejemplo n.º 3
0
static int abituguru_write(struct abituguru_data *data,
	u8 bank_addr, u8 sensor_addr, u8 *buf, int count)
{
	
	int i, timeout = ABIT_UGURU_READY_TIMEOUT;

	
	i = abituguru_send_address(data, bank_addr, sensor_addr,
		ABIT_UGURU_MAX_RETRIES);
	if (i)
		return i;

	
	for (i = 0; i < count; i++) {
		if (abituguru_wait(data, ABIT_UGURU_STATUS_WRITE)) {
			ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for "
				"write state (bank: %d, sensor: %d)\n",
				(int)bank_addr, (int)sensor_addr);
			break;
		}
		outb(buf[i], data->addr + ABIT_UGURU_CMD);
	}

	
	if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) {
		ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for read state "
			"after write (bank: %d, sensor: %d)\n", (int)bank_addr,
			(int)sensor_addr);
		return -EIO;
	}

	
	while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) {
		timeout--;
		if (timeout == 0) {
			ABIT_UGURU_DEBUG(1, "CMD reg does not hold 0xAC after "
				"write (bank: %d, sensor: %d)\n",
				(int)bank_addr, (int)sensor_addr);
			return -EIO;
		}
		msleep(0);
	}

	
	abituguru_ready(data);

	return i;
}
static int abituguru_read(struct abituguru_data *data,
                          u8 bank_addr, u8 sensor_addr, u8 *buf, int count, int retries)
{
    int i;


    i = abituguru_send_address(data, bank_addr, sensor_addr, retries);
    if (i)
        return i;


    for (i = 0; i < count; i++) {
        if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) {
            ABIT_UGURU_DEBUG(retries ? 1 : 3,
                             "timeout exceeded waiting for "
                             "read state (bank: %d, sensor: %d)\n",
                             (int)bank_addr, (int)sensor_addr);
            break;
        }
        buf[i] = inb(data->addr + ABIT_UGURU_CMD);
    }


    abituguru_ready(data);

    return i;
}
Ejemplo n.º 5
0
static int abituguru_ready(struct abituguru_data *data)
{
	int timeout = ABIT_UGURU_READY_TIMEOUT;

	if (data->uguru_ready)
		return 0;

	
	outb(0x00, data->addr + ABIT_UGURU_DATA);

	
	if (abituguru_wait(data, ABIT_UGURU_STATUS_READY)) {
		ABIT_UGURU_DEBUG(1,
			"timeout exceeded waiting for ready state\n");
		return -EIO;
	}

	
	while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) {
		timeout--;
		if (timeout == 0) {
			ABIT_UGURU_DEBUG(1,
			   "CMD reg does not hold 0xAC after ready command\n");
			return -EIO;
		}
		msleep(0);
	}

	
	timeout = ABIT_UGURU_READY_TIMEOUT;
	while (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT) {
		timeout--;
		if (timeout == 0) {
			ABIT_UGURU_DEBUG(1,
				"state != more input after ready command\n");
			return -EIO;
		}
		msleep(0);
	}

	data->uguru_ready = 1;
	return 0;
}
static int __init abituguru_detect(void)
{
    u8 cmd_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_CMD);
    u8 data_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_DATA);
    if (((data_val == 0x00) || (data_val == 0x08)) &&
            ((cmd_val == 0x00) || (cmd_val == 0xAC)))
        return ABIT_UGURU_BASE;

    ABIT_UGURU_DEBUG(2, "no Abit uGuru found, data = 0x%02X, cmd = "
                     "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val);

    if (force) {
        pr_info("Assuming Abit uGuru is present because of \"force\" parameter\n");
        return ABIT_UGURU_BASE;
    }


    return -ENODEV;
}
Ejemplo n.º 7
0
static void __devinit
abituguru_detect_no_bank2_sensors(struct abituguru_data *data)
{
	int i;

	if (fan_sensors > 0 && fan_sensors <= ABIT_UGURU_MAX_BANK2_SENSORS) {
		data->bank2_sensors = fan_sensors;
		ABIT_UGURU_DEBUG(2, "assuming %d fan sensors because of "
			"\"fan_sensors\" module param\n",
			(int)data->bank2_sensors);
		return;
	}

	ABIT_UGURU_DEBUG(2, "detecting number of fan sensors\n");
	for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) {
		
		if (data->bank2_settings[i][0] & ~0xC9) {
			ABIT_UGURU_DEBUG(2, "  bank2 sensor %d does not seem "
				"to be a fan sensor: settings[0] = %02X\n",
				i, (unsigned int)data->bank2_settings[i][0]);
			break;
		}

		
		if (data->bank2_settings[i][1] <
				abituguru_bank2_min_threshold) {
			ABIT_UGURU_DEBUG(2, "  bank2 sensor %d does not seem "
				"to be a fan sensor: the threshold (%d) is "
				"below the minimum (%d)\n", i,
				(int)data->bank2_settings[i][1],
				(int)abituguru_bank2_min_threshold);
			break;
		}
		if (data->bank2_settings[i][1] >
				abituguru_bank2_max_threshold) {
			ABIT_UGURU_DEBUG(2, "  bank2 sensor %d does not seem "
				"to be a fan sensor: the threshold (%d) is "
				"above the maximum (%d)\n", i,
				(int)data->bank2_settings[i][1],
				(int)abituguru_bank2_max_threshold);
			break;
		}
	}

	data->bank2_sensors = i;
	ABIT_UGURU_DEBUG(2, " found: %d fan sensors\n",
		(int)data->bank2_sensors);
}
static void __devinit
abituguru_detect_no_pwms(struct abituguru_data *data)
{
    int i, j;

    if (pwms > 0 && pwms <= ABIT_UGURU_MAX_PWMS) {
        data->pwms = pwms;
        ABIT_UGURU_DEBUG(2, "assuming %d PWM outputs because of "
                         "\"pwms\" module param\n", (int)data->pwms);
        return;
    }

    ABIT_UGURU_DEBUG(2, "detecting number of PWM outputs\n");
    for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) {
        if (data->pwm_settings[i][0] & ~0x8F) {
            ABIT_UGURU_DEBUG(2, "  pwm channel %d does not seem "
                             "to be a pwm channel: settings[0] = %02X\n",
                             i, (unsigned int)data->pwm_settings[i][0]);
            break;
        }

        for (j = 0; j < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR];
                j++) {
            if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][j] ==
                    (data->pwm_settings[i][0] & 0x0F))
                break;
        }
        if (j == data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) {
            ABIT_UGURU_DEBUG(2, "  pwm channel %d does not seem "
                             "to be a pwm channel: %d is not a valid temp "
                             "sensor address\n", i,
                             data->pwm_settings[i][0] & 0x0F);
            break;
        }


        for (j = 1; j < 5; j++) {
            u8 min;

            if ((i == 0) && ((j == 1) || (j == 2)))
                min = 77;
            else
                min = abituguru_pwm_min[j];
            if (data->pwm_settings[i][j] < min) {
                ABIT_UGURU_DEBUG(2, "  pwm channel %d does "
                                 "not seem to be a pwm channel: "
                                 "setting %d (%d) is below the minimum "
                                 "value (%d)\n", i, j,
                                 (int)data->pwm_settings[i][j],
                                 (int)min);
                goto abituguru_detect_no_pwms_exit;
            }
            if (data->pwm_settings[i][j] > abituguru_pwm_max[j]) {
                ABIT_UGURU_DEBUG(2, "  pwm channel %d does "
                                 "not seem to be a pwm channel: "
                                 "setting %d (%d) is above the maximum "
                                 "value (%d)\n", i, j,
                                 (int)data->pwm_settings[i][j],
                                 (int)abituguru_pwm_max[j]);
                goto abituguru_detect_no_pwms_exit;
            }
        }


        if (data->pwm_settings[i][1] >= data->pwm_settings[i][2]) {
            ABIT_UGURU_DEBUG(2, "  pwm channel %d does not seem "
                             "to be a pwm channel: min pwm (%d) >= "
                             "max pwm (%d)\n", i,
                             (int)data->pwm_settings[i][1],
                             (int)data->pwm_settings[i][2]);
            break;
        }
        if (data->pwm_settings[i][3] >= data->pwm_settings[i][4]) {
            ABIT_UGURU_DEBUG(2, "  pwm channel %d does not seem "
                             "to be a pwm channel: min temp (%d) >= "
                             "max temp (%d)\n", i,
                             (int)data->pwm_settings[i][3],
                             (int)data->pwm_settings[i][4]);
            break;
        }
    }

abituguru_detect_no_pwms_exit:
    data->pwms = i;
    ABIT_UGURU_DEBUG(2, " found: %d PWM outputs\n", (int)data->pwms);
}
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;
}