Example #1
0
void sis5595_fan(struct i2c_client *client, int operation, int ctl_name,
		 int *nrels_mag, long *results)
{
	struct sis5595_data *data = client->data;
	int nr = ctl_name - SIS5595_SYSCTL_FAN1 + 1;

	if (operation == SENSORS_PROC_REAL_INFO)
		*nrels_mag = 0;
	else if (operation == SENSORS_PROC_REAL_READ) {
		sis5595_update_client(client);
		results[0] = FAN_FROM_REG(data->fan_min[nr - 1],
					  DIV_FROM_REG(data->fan_div[nr - 1]));
		results[1] = FAN_FROM_REG(data->fan[nr - 1],
					  DIV_FROM_REG(data->fan_div[nr - 1]));
		*nrels_mag = 2;
	} else if (operation == SENSORS_PROC_REAL_WRITE) {
		if (*nrels_mag >= 1) {
			data->fan_min[nr - 1] = FAN_TO_REG(results[0],
							   DIV_FROM_REG
							   (data->
							    fan_div[nr-1]));
			sis5595_write_value(client,
					    SIS5595_REG_FAN_MIN(nr),
					    data->fan_min[nr - 1]);
		}
	}
}
Example #2
0
static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
			   const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct gl520_data *data = i2c_get_clientdata(client);
	int n = to_sensor_dev_attr(attr)->index;
	unsigned long v = simple_strtoul(buf, NULL, 10);
	u8 r;

	mutex_lock(&data->update_lock);
	r = FAN_TO_REG(v, data->fan_div[n]);
	data->fan_min[n] = r;

	if (n == 0)
		gl520_write_value(client, GL520_REG_FAN_MIN,
				  (gl520_read_value(client, GL520_REG_FAN_MIN)
				   & ~0xff00) | (r << 8));
	else
		gl520_write_value(client, GL520_REG_FAN_MIN,
				  (gl520_read_value(client, GL520_REG_FAN_MIN)
				   & ~0xff) | r);

	data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
	if (data->fan_min[n] == 0)
		data->alarm_mask &= (n == 0) ? ~0x20 : ~0x40;
	else
		data->alarm_mask |= (n == 0) ? 0x20 : 0x40;
	data->beep_mask &= data->alarm_mask;
	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);

	mutex_unlock(&data->update_lock);
	return count;
}
Example #3
0
void maxi99_fan(struct i2c_client *client, int operation, int ctl_name,
		int *nrels_mag, long *results)
{
	struct maxi_data *data = client->data;
	int nr;

	nr = ctl_name - MAXI_SYSCTL_FAN1 + 1;

	if (operation == SENSORS_PROC_REAL_INFO)
		*nrels_mag = 0;
	else if (operation == SENSORS_PROC_REAL_READ) {
		maxi99_update_client(client, fan, nr - 1);
		results[0] = FAN99_FROM_REG(data->fan_min[nr - 1]);	/* min rpm */
		results[1] = data->fan_div[nr - 1];	/* divisor */
		results[2] = FAN99_FROM_REG(data->fan[nr - 1]);	/* rpm */
		*nrels_mag = 3;
	} else if (operation == SENSORS_PROC_REAL_WRITE) {
#ifndef NOWRITE
		/* still to do */
		if (*nrels_mag >= 1) {
			data->fan_min[nr - 1] = FAN_TO_REG(results[0]);
			maxi_write_value(client, MAXI_REG_FAN_MIN(nr),
					 data->fan_min[nr - 1]);
		}
#endif
	}
}
Example #4
0
/* The next few functions are the call-back functions of the /proc/sys and
   sysctl files. Which function is used is defined in the ctl_table in
   the extra1 field.
   Each function must return the magnitude (power of 10 to divide the data
   with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
   put a maximum of *nrels elements in results reflecting the data of this
   file, and set *nrels to the number it actually put in it, if operation==
   SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
   results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
   Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
   large enough (by checking the incoming value of *nrels). This is not very
   good practice, but as long as you put less than about 5 values in results,
   you can assume it is large enough. */
void maxi_fan(struct i2c_client *client, int operation, int ctl_name,
	      int *nrels_mag, long *results)
{
	struct maxi_data *data = client->data;
	int nr;

	if (data->type == nba) {
		maxi99_fan(client, operation, ctl_name, nrels_mag,
			   results);
		return;
	}

	nr = ctl_name - MAXI_SYSCTL_FAN1 + 1;

	if (operation == SENSORS_PROC_REAL_INFO)
		*nrels_mag = 0;
	else if (operation == SENSORS_PROC_REAL_READ) {
		maxi_update_client(client);
		results[0] = FAN_FROM_REG(data->fan_min[nr - 1]);
		results[1] = data->fan_div[nr - 1];
		results[2] = FAN_FROM_REG(data->fan[nr - 1]);
		*nrels_mag = 3;
	} else if (operation == SENSORS_PROC_REAL_WRITE) {
#ifndef NOWRITE
		if (*nrels_mag >= 1) {
			data->fan_min[nr - 1] = FAN_TO_REG(results[0]);
			maxi_write_value(client, MAXI_REG_FAN_MIN(nr),
					 data->fan_min[nr - 1]);
		}
#endif
	}
}
Example #5
0
/* Called when we have found a new SIS5595. It should set limits, etc. */
void sis5595_init_client(struct i2c_client *client)
{
	struct sis5595_data *data = client->data;

	/* Reset all except Watchdog values and last conversion values
	   This sets fan-divs to 2, among others */
	sis5595_write_value(client, SIS5595_REG_CONFIG, 0x80);

	sis5595_write_value(client, SIS5595_REG_IN_MIN(0),
			    IN_TO_REG(SIS5595_INIT_IN_MIN_0));
	sis5595_write_value(client, SIS5595_REG_IN_MAX(0),
			    IN_TO_REG(SIS5595_INIT_IN_MAX_0));
	sis5595_write_value(client, SIS5595_REG_IN_MIN(1),
			    IN_TO_REG(SIS5595_INIT_IN_MIN_1));
	sis5595_write_value(client, SIS5595_REG_IN_MAX(1),
			    IN_TO_REG(SIS5595_INIT_IN_MAX_1));
	sis5595_write_value(client, SIS5595_REG_IN_MIN(2),
			    IN_TO_REG(SIS5595_INIT_IN_MIN_2));
	sis5595_write_value(client, SIS5595_REG_IN_MAX(2),
			    IN_TO_REG(SIS5595_INIT_IN_MAX_2));
	sis5595_write_value(client, SIS5595_REG_IN_MIN(3),
			    IN_TO_REG(SIS5595_INIT_IN_MIN_3));
	sis5595_write_value(client, SIS5595_REG_IN_MAX(3),
			    IN_TO_REG(SIS5595_INIT_IN_MAX_3));
	sis5595_write_value(client, SIS5595_REG_FAN_MIN(1),
			    FAN_TO_REG(SIS5595_INIT_FAN_MIN_1, 2));
	sis5595_write_value(client, SIS5595_REG_FAN_MIN(2),
			    FAN_TO_REG(SIS5595_INIT_FAN_MIN_2, 2));
	if(data->maxins == 4) {
		sis5595_write_value(client, SIS5595_REG_IN_MIN(4),
				    IN_TO_REG(SIS5595_INIT_IN_MIN_4));
		sis5595_write_value(client, SIS5595_REG_IN_MAX(4),
				    IN_TO_REG(SIS5595_INIT_IN_MAX_4));
	} else {
		sis5595_write_value(client, SIS5595_REG_TEMP_OVER,
				    TEMP_TO_REG(SIS5595_INIT_TEMP_OVER));
		sis5595_write_value(client, SIS5595_REG_TEMP_HYST,
				    TEMP_TO_REG(SIS5595_INIT_TEMP_HYST));
	}

	/* Start monitoring */
	sis5595_write_value(client, SIS5595_REG_CONFIG,
			    (sis5595_read_value(client, SIS5595_REG_CONFIG)
			     & 0xf7) | 0x01);

}
Example #6
0
/* Called when we have found a new GL520SM. It should set limits, etc. */
void gl520_init_client(struct i2c_client *client)
{
	/* Power-on defaults (bit 7=1) */
	gl520_write_value(client, GL520_REG_CONF, 0x80);

	/* No noisy output (bit 2=1), Comparator mode (bit 3=0), two fans (bit4=0),
	   standby mode (bit6=0) */
	gl520_write_value(client, GL520_REG_CONF, 0x04);

	/* Never interrupts */
	gl520_write_value(client, GL520_REG_MASK, 0x00);

	gl520_write_value(client, GL520_REG_TEMP1_HYST,
			  TEMP_TO_REG(GL520_INIT_TEMP_HYST));
	gl520_write_value(client, GL520_REG_TEMP1_OVER,
			  TEMP_TO_REG(GL520_INIT_TEMP_OVER));

	/* We set Temp2, but not Vin4. */
	gl520_write_value(client, GL520_REG_TEMP2_HYST,
			  TEMP_TO_REG(GL520_INIT_TEMP_HYST));
	gl520_write_value(client, GL520_REG_TEMP2_OVER,
			  TEMP_TO_REG(GL520_INIT_TEMP_OVER));

	gl520_write_value(client, GL520_REG_MISC, (DIV_TO_REG(2) << 6) |
			  (DIV_TO_REG(2) << 4));
	gl520_write_value(client, GL520_REG_FAN_LIMIT,
			  (FAN_TO_REG(GL520_INIT_FAN_MIN_1, 2) << 8) |
			  FAN_TO_REG(GL520_INIT_FAN_MIN_2, 2));

	gl520_write_value(client, GL520_REG_VIN1_LIMIT,
			  (IN_TO_REG(GL520_INIT_VIN_MAX_1) << 8) |
			  IN_TO_REG(GL520_INIT_VIN_MIN_1));
	gl520_write_value(client, GL520_REG_VIN2_LIMIT,
			  (IN_TO_REG(GL520_INIT_VIN_MAX_2) << 8) |
			  IN_TO_REG(GL520_INIT_VIN_MIN_2));
	gl520_write_value(client, GL520_REG_VIN3_LIMIT,
			  (IN_TO_REG(GL520_INIT_VIN_MAX_3) << 8) |
			  IN_TO_REG(GL520_INIT_VIN_MIN_3));
	gl520_write_value(client, GL520_REG_VDD_LIMIT,
			  (VDD_TO_REG(GL520_INIT_VDD_MAX) << 8) |
			  VDD_TO_REG(GL520_INIT_VDD_MIN));

	/* Clear status register (bit 5=1), start (bit6=1) */
	gl520_write_value(client, GL520_REG_CONF, 0x24);
	gl520_write_value(client, GL520_REG_CONF, 0x44);
}
Example #7
0
File: lm78.c Project: 020gzh/linux
/*
 * 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;
}
Example #8
0
static void set_fan_min(struct device *dev, const char *buf, int nr)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm87_data *data = i2c_get_clientdata(client);
	long val = simple_strtol(buf, NULL, 10);

	mutex_lock(&data->update_lock);
	data->fan_min[nr] = FAN_TO_REG(val,
			    FAN_DIV_FROM_REG(data->fan_div[nr]));
	lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]);
	mutex_unlock(&data->update_lock);
}
Example #9
0
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;
}
Example #10
0
static ssize_t set_fan(struct device *dev, struct device_attribute *dummy,
		       const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm63_data *data = i2c_get_clientdata(client);
	unsigned long val = simple_strtoul(buf, NULL, 10);

	mutex_lock(&data->update_lock);
	data->fan[1] = FAN_TO_REG(val);
	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB,
				  data->fan[1] & 0xFF);
	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB,
				  data->fan[1] >> 8);
	mutex_unlock(&data->update_lock);
	return count;
}
Example #11
0
/* Note: we save and restore the fan minimum here, because its value is
   determined in part by the fan clock divider.  This follows the principle
   of least surprise; the user doesn't expect the fan minimum to change just
   because the divider changed. */
static ssize_t set_fan_div(struct device *dev, const char *buf,
		size_t count, int nr)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm87_data *data = i2c_get_clientdata(client);
	long val = simple_strtol(buf, NULL, 10);
	unsigned long min;
	u8 reg;

	mutex_lock(&data->update_lock);
	min = FAN_FROM_REG(data->fan_min[nr],
			   FAN_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:
		mutex_unlock(&data->update_lock);
		return -EINVAL;
	}

	reg = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
	switch (nr) {
	case 0:
	    reg = (reg & 0xCF) | (data->fan_div[0] << 4);
	    break;
	case 1:
	    reg = (reg & 0x3F) | (data->fan_div[1] << 6);
	    break;
	}
	lm87_write_value(client, LM87_REG_VID_FAN_DIV, reg);

	data->fan_min[nr] = FAN_TO_REG(min, val);
	lm87_write_value(client, LM87_REG_FAN_MIN(nr),
			 data->fan_min[nr]);
	mutex_unlock(&data->update_lock);

	return count;
}
Example #12
0
static ssize_t set_fan(struct device *dev, struct device_attribute *dummy,
		       const char *buf, size_t count)
{
	struct lm63_data *data = dev_get_drvdata(dev);
	struct i2c_client *client = data->client;
	unsigned long val;
	int err;

	err = kstrtoul(buf, 10, &val);
	if (err)
		return err;

	mutex_lock(&data->update_lock);
	data->fan[1] = FAN_TO_REG(val);
	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB,
				  data->fan[1] & 0xFF);
	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB,
				  data->fan[1] >> 8);
	mutex_unlock(&data->update_lock);
	return count;
}
Example #13
0
/* Called when we have found a new MTP008. It should set limits, etc. */
void mtp008_init_client(struct i2c_client *client)
{
	int vid;
	u8 save1, save2;
	struct mtp008_data *data;

	data = client->data;

	/*
	 * Initialize the Myson MTP008 hardware monitoring chip.
	 * Save the pin settings that the BIOS hopefully set.
	 */
	save1 = mtp008_read_value(client, MTP008_REG_PIN_CTRL1);
	save2 = mtp008_read_value(client, MTP008_REG_PIN_CTRL2);
	mtp008_write_value(client, MTP008_REG_CONFIG,
	     (mtp008_read_value(client, MTP008_REG_CONFIG) & 0x7f) | 0x80);
	mtp008_write_value(client, MTP008_REG_PIN_CTRL1, save1);
	mtp008_write_value(client, MTP008_REG_PIN_CTRL2, save2);

	mtp008_getsensortype(data, save2);

	/*
	 * Retrieve the VID setting (needed for the default limits).
	 */
	vid = mtp008_read_value(client, MTP008_REG_VID_FANDIV) & 0x0f;
	vid |= (mtp008_read_value(client, MTP008_REG_RESET_VID4) & 0x01) << 4;
	vid = VID_FROM_REG(vid);

	/*
	 * Set the default limits.
	 *
	 * Setting temp sensors is done as follows:
	 *
	 *          Register 0x57: 0 0 0 0 x x x x
	 *                                 | \ / +-- AIN5/VT3
	 *                                 |  +----- AIN4/VT2/PII
	 *                                 +-------- VT1/PII
	 */

	mtp008_write_value(client, MTP008_REG_IN_MAX(0),
			   IN_TO_REG(MTP008_INIT_IN_MAX_0));
	mtp008_write_value(client, MTP008_REG_IN_MIN(0),
			   IN_TO_REG(MTP008_INIT_IN_MIN_0));
	mtp008_write_value(client, MTP008_REG_IN_MAX(1),
			   IN_TO_REG(MTP008_INIT_IN_MAX_1));
	mtp008_write_value(client, MTP008_REG_IN_MIN(1),
			   IN_TO_REG(MTP008_INIT_IN_MIN_1));
	mtp008_write_value(client, MTP008_REG_IN_MAX(2),
			   IN_TO_REG(MTP008_INIT_IN_MAX_2));
	mtp008_write_value(client, MTP008_REG_IN_MIN(2),
			   IN_TO_REG(MTP008_INIT_IN_MIN_2));
	mtp008_write_value(client, MTP008_REG_IN_MAX(3),
			   IN_TO_REG(MTP008_INIT_IN_MAX_3));
	mtp008_write_value(client, MTP008_REG_IN_MIN(3),
			   IN_TO_REG(MTP008_INIT_IN_MIN_3));

	mtp008_write_value(client, MTP008_REG_IN_MAX(5),
			   IN_TO_REG(MTP008_INIT_IN_MAX_5));
	mtp008_write_value(client, MTP008_REG_IN_MIN(5),
			   IN_TO_REG(MTP008_INIT_IN_MIN_5));
	mtp008_write_value(client, MTP008_REG_IN_MAX(6),
			   IN_TO_REG(MTP008_INIT_IN_MAX_6));
	mtp008_write_value(client, MTP008_REG_IN_MIN(6),
			   IN_TO_REG(MTP008_INIT_IN_MIN_6));

	mtp008_write_value(client, MTP008_REG_TEMP_MAX,
			   TEMP_TO_REG(MTP008_INIT_TEMP_OVER));
	mtp008_write_value(client, MTP008_REG_TEMP_MIN,
			   TEMP_TO_REG(MTP008_INIT_TEMP_HYST));
	mtp008_write_value(client, MTP008_REG_IN_MAX(4),
			   TEMP_TO_REG(MTP008_INIT_TEMP2_OVER));
	mtp008_write_value(client, MTP008_REG_IN_MIN(4),
			   TEMP_TO_REG(MTP008_INIT_TEMP2_HYST));

	mtp008_write_value(client, MTP008_REG_FAN_MIN(1),
			   FAN_TO_REG(MTP008_INIT_FAN_MIN_1, 2));
	mtp008_write_value(client, MTP008_REG_FAN_MIN(2),
			   FAN_TO_REG(MTP008_INIT_FAN_MIN_2, 2));
	mtp008_write_value(client, MTP008_REG_FAN_MIN(3),
			   FAN_TO_REG(MTP008_INIT_FAN_MIN_3, 2));

	/*
	 * Start monitoring.
	 */
	mtp008_write_value(
		client, MTP008_REG_CONFIG,
		(mtp008_read_value(client, MTP008_REG_CONFIG) & 0xf7) | 0x01
	);
}