Beispiel #1
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 date
   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 adm1025_in(struct i2c_client *client, int operation, int ctl_name,
		int *nrels_mag, long *results)
{

	int scales[6] = { 250, 225, 330, 500, 1200, 330 };

	struct adm1025_data *data = client->data;
	int nr = ctl_name - ADM1025_SYSCTL_IN0;

	if (operation == SENSORS_PROC_REAL_INFO)
		*nrels_mag = 2;
	else if (operation == SENSORS_PROC_REAL_READ) {
		adm1025_update_client(client);
		results[0] =
		    IN_FROM_REG(data->in_min[nr], nr) * scales[nr] / 192;
		results[1] =
		    IN_FROM_REG(data->in_max[nr], nr) * scales[nr] / 192;
		results[2] =
		    IN_FROM_REG(data->in[nr], nr) * scales[nr] / 192;
		*nrels_mag = 3;
	} else if (operation == SENSORS_PROC_REAL_WRITE) {
		if (*nrels_mag >= 1) {
			data->in_min[nr] =
			    IN_TO_REG((results[0] * 192) / scales[nr], nr);
			adm1025_write_value(client, ADM1025_REG_IN_MIN(nr),
					    data->in_min[nr]);
		}
		if (*nrels_mag >= 2) {
			data->in_max[nr] =
			    IN_TO_REG((results[1] * 192) / scales[nr], nr);
			adm1025_write_value(client, ADM1025_REG_IN_MAX(nr),
					    data->in_max[nr]);
		}
	}
}
Beispiel #2
0
void adm1025_update_client(struct i2c_client *client)
{
	struct adm1025_data *data = client->data;
	u8 i;

	down(&data->update_lock);

	if (
	    (jiffies - data->last_updated >
	     (data->type == adm1025 ? HZ / 2 : HZ * 2))
	    || (jiffies < data->last_updated) || !data->valid) {

#ifdef DEBUG
		printk("Starting adm1025 update\n");
#endif
		for (i = 0; i <= 5; i++) {
			data->in[i] =
			    adm1025_read_value(client, ADM1025_REG_IN(i));
			data->in_min[i] =
			    adm1025_read_value(client,
					       ADM1025_REG_IN_MIN(i));
			data->in_max[i] =
			    adm1025_read_value(client,
					       ADM1025_REG_IN_MAX(i));
		}
		data->temp =
		    adm1025_read_value(client, ADM1025_REG_TEMP);
		data->rtemp =
		    adm1025_read_value(client, ADM1025_REG_RTEMP);
#ifdef DEBUG
		printk("The temp is %2x\n",data->temp);
#endif
		data->temp_max =
		    adm1025_read_value(client, ADM1025_REG_TEMP_HIGH);
		data->temp_min =
		    adm1025_read_value(client, ADM1025_REG_TEMP_LOW);
		data->rtemp_max =
		    adm1025_read_value(client, ADM1025_REG_RTEMP_HIGH);
		data->rtemp_min =
		    adm1025_read_value(client, ADM1025_REG_RTEMP_LOW);

		i = adm1025_read_value(client, ADM1025_REG_VID);
		data->vid = i & 0x0f;
		data->vid |=
		    (adm1025_read_value(client, ADM1025_REG_VID4) & 0x01)
		    << 4;

		data->alarms =
		    adm1025_read_value(client,
				       ADM1025_REG_INT1_STAT) +
		    (adm1025_read_value(client, ADM1025_REG_INT2_STAT) <<
		     8);
		data->last_updated = jiffies;
		data->valid = 1;
	}

	up(&data->update_lock);
}
Beispiel #3
0
static void adm1025_init_client(struct i2c_client *client)
{
	u8 reg;
	struct adm1025_data *data = i2c_get_clientdata(client);
	int i;

	data->vrm = vid_which_vrm();

	/*
	 * Set high limits
	 * Usually we avoid setting limits on driver init, but it happens
	 * that the ADM1025 comes with stupid default limits (all registers
	 * set to 0). In case the chip has not gone through any limit
	 * setting yet, we better set the high limits to the max so that
	 * no alarm triggers.
	 */
	for (i = 0; i < 6; i++) {
		reg = i2c_smbus_read_byte_data(client,
					       ADM1025_REG_IN_MAX(i));
		if (reg == 0)
			i2c_smbus_write_byte_data(client,
						  ADM1025_REG_IN_MAX(i),
						  0xFF);
	}
	for (i = 0; i < 2; i++) {
		reg = i2c_smbus_read_byte_data(client,
					       ADM1025_REG_TEMP_HIGH(i));
		if (reg == 0)
			i2c_smbus_write_byte_data(client,
						  ADM1025_REG_TEMP_HIGH(i),
						  0x7F);
	}

	/*
	 * Start the conversions
	 */
	reg = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
	if (!(reg & 0x01))
		i2c_smbus_write_byte_data(client, ADM1025_REG_CONFIG,
					  (reg&0x7E)|0x01);
}
static void adm1025_init_client(struct i2c_client *client)
{
	u8 reg;
	struct adm1025_data *data = i2c_get_clientdata(client);
	int i;

	data->vrm = vid_which_vrm();

	/*
                   
                                                                  
                                                                    
                                                              
                                                                 
                      
  */
	for (i = 0; i < 6; i++) {
		reg = i2c_smbus_read_byte_data(client,
					       ADM1025_REG_IN_MAX(i));
		if (reg == 0)
			i2c_smbus_write_byte_data(client,
						  ADM1025_REG_IN_MAX(i),
						  0xFF);
	}
	for (i = 0; i < 2; i++) {
		reg = i2c_smbus_read_byte_data(client,
					       ADM1025_REG_TEMP_HIGH(i));
		if (reg == 0)
			i2c_smbus_write_byte_data(client,
						  ADM1025_REG_TEMP_HIGH(i),
						  0x7F);
	}

	/*
                         
  */
	reg = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
	if (!(reg & 0x01))
		i2c_smbus_write_byte_data(client, ADM1025_REG_CONFIG,
					  (reg&0x7E)|0x01);
}
Beispiel #5
0
static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
			  const char *buf, size_t count)
{
	int index = to_sensor_dev_attr(attr)->index;
	struct i2c_client *client = to_i2c_client(dev);
	struct adm1025_data *data = i2c_get_clientdata(client);
	long val = simple_strtol(buf, NULL, 10);

	mutex_lock(&data->update_lock);
	data->in_max[index] = IN_TO_REG(val, in_scale[index]);
	i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MAX(index),
				  data->in_max[index]);
	mutex_unlock(&data->update_lock);
	return count;
}
Beispiel #6
0
static struct adm1025_data *adm1025_update_device(struct device *dev)
{
	struct adm1025_data *data = dev_get_drvdata(dev);
	struct i2c_client *client = data->client;

	mutex_lock(&data->update_lock);

	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
		int i;

		dev_dbg(&client->dev, "Updating data.\n");
		for (i = 0; i < 6; i++) {
			data->in[i] = i2c_smbus_read_byte_data(client,
				      ADM1025_REG_IN(i));
			data->in_min[i] = i2c_smbus_read_byte_data(client,
					  ADM1025_REG_IN_MIN(i));
			data->in_max[i] = i2c_smbus_read_byte_data(client,
					  ADM1025_REG_IN_MAX(i));
		}
		for (i = 0; i < 2; i++) {
			data->temp[i] = i2c_smbus_read_byte_data(client,
					ADM1025_REG_TEMP(i));
			data->temp_min[i] = i2c_smbus_read_byte_data(client,
					    ADM1025_REG_TEMP_LOW(i));
			data->temp_max[i] = i2c_smbus_read_byte_data(client,
					    ADM1025_REG_TEMP_HIGH(i));
		}
		data->alarms = i2c_smbus_read_byte_data(client,
			       ADM1025_REG_STATUS1)
			     | (i2c_smbus_read_byte_data(client,
				ADM1025_REG_STATUS2) << 8);
		data->vid = (i2c_smbus_read_byte_data(client,
			     ADM1025_REG_VID) & 0x0f)
			  | ((i2c_smbus_read_byte_data(client,
			      ADM1025_REG_VID4) & 0x01) << 4);

		data->last_updated = jiffies;
		data->valid = 1;
	}

	mutex_unlock(&data->update_lock);

	return data;
}
Beispiel #7
0
static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
			  const char *buf, size_t count)
{
	int index = to_sensor_dev_attr(attr)->index;
	struct adm1025_data *data = dev_get_drvdata(dev);
	struct i2c_client *client = data->client;
	long val;
	int err;

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

	mutex_lock(&data->update_lock);
	data->in_max[index] = IN_TO_REG(val, in_scale[index]);
	i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MAX(index),
				  data->in_max[index]);
	mutex_unlock(&data->update_lock);
	return count;
}
Beispiel #8
0
/* Called when we have found a new ADM1025. It should set limits, etc. */
void adm1025_init_client(struct i2c_client *client)
{
	struct adm1025_data *data = client->data;

	data->vrm = DEFAULT_VRM;
	/* Reset all except Watchdog values and last conversion values
	   This sets fan-divs to 2, among others. This makes most other
	   initializations unnecessary */
	adm1025_write_value(client, ADM1025_REG_CONFIG, 0x80);

	adm1025_write_value(client, ADM1025_REG_IN_MIN(0),
			    IN_TO_REG(ADM1025_INIT_IN_MIN_0, 0));
	adm1025_write_value(client, ADM1025_REG_IN_MAX(0),
			    IN_TO_REG(ADM1025_INIT_IN_MAX_0, 0));
	adm1025_write_value(client, ADM1025_REG_IN_MIN(1),
			    IN_TO_REG(ADM1025_INIT_IN_MIN_1, 1));
	adm1025_write_value(client, ADM1025_REG_IN_MAX(1),
			    IN_TO_REG(ADM1025_INIT_IN_MAX_1, 1));
	adm1025_write_value(client, ADM1025_REG_IN_MIN(2),
			    IN_TO_REG(ADM1025_INIT_IN_MIN_2, 2));
	adm1025_write_value(client, ADM1025_REG_IN_MAX(2),
			    IN_TO_REG(ADM1025_INIT_IN_MAX_2, 2));
	adm1025_write_value(client, ADM1025_REG_IN_MIN(3),
			    IN_TO_REG(ADM1025_INIT_IN_MIN_3, 3));
	adm1025_write_value(client, ADM1025_REG_IN_MAX(3),
			    IN_TO_REG(ADM1025_INIT_IN_MAX_3, 3));
	adm1025_write_value(client, ADM1025_REG_IN_MIN(4),
			    IN_TO_REG(ADM1025_INIT_IN_MIN_4, 4));
	adm1025_write_value(client, ADM1025_REG_IN_MAX(4),
			    IN_TO_REG(ADM1025_INIT_IN_MAX_4, 4));
	adm1025_write_value(client, ADM1025_REG_IN_MIN(5),
			    IN_TO_REG(ADM1025_INIT_IN_MIN_5, 5));
	adm1025_write_value(client, ADM1025_REG_IN_MAX(5),
			    IN_TO_REG(ADM1025_INIT_IN_MAX_5, 5));

	adm1025_write_value(client, ADM1025_REG_RTEMP_HIGH,
			    TEMP_LIMIT_TO_REG(ADM1025_INIT_RTEMP_MAX));
	adm1025_write_value(client, ADM1025_REG_RTEMP_LOW,
			    TEMP_LIMIT_TO_REG(ADM1025_INIT_RTEMP_MIN));
	adm1025_write_value(client, ADM1025_REG_TEMP_HIGH,
			    TEMP_LIMIT_TO_REG(ADM1025_INIT_TEMP_MAX));
	adm1025_write_value(client, ADM1025_REG_TEMP_LOW,
			    TEMP_LIMIT_TO_REG(ADM1025_INIT_TEMP_MIN));

	/* Start monitoring */
	adm1025_write_value(client, ADM1025_REG_CONFIG, 0x01);
}