Exemplo n.º 1
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;
}
Exemplo n.º 2
0
static ssize_t set_fan_div(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;

	switch (v) {
	case 1: r = 0; break;
	case 2: r = 1; break;
	case 4: r = 2; break;
	case 8: r = 3; break;
	default:
		dev_err(&client->dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v);
		return -EINVAL;
	}

	mutex_lock(&data->update_lock);
	data->fan_div[n] = r;

	if (n == 0)
		gl520_write_value(client, GL520_REG_FAN_DIV,
				  (gl520_read_value(client, GL520_REG_FAN_DIV)
				   & ~0xc0) | (r << 6));
	else
		gl520_write_value(client, GL520_REG_FAN_DIV,
				  (gl520_read_value(client, GL520_REG_FAN_DIV)
				   & ~0x30) | (r << 4));

	mutex_unlock(&data->update_lock);
	return count;
}
Exemplo n.º 3
0
static ssize_t set_beep(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 bitnr = to_sensor_dev_attr(attr)->index;
	unsigned long bit;

	int err;

	err = kstrtoul(buf, 10, &bit);
	if (err)
		return err;
	if (bit & ~1)
		return -EINVAL;

	mutex_lock(&data->update_lock);
	data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
	if (bit)
		data->beep_mask |= (1 << bitnr);
	else
		data->beep_mask &= ~(1 << bitnr);
	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
	mutex_unlock(&data->update_lock);
	return count;
}
Exemplo n.º 4
0
static ssize_t set_in_max(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;
	long v = simple_strtol(buf, NULL, 10);
	u8 r;

	if (n == 0)
		r = VDD_TO_REG(v);
	else
		r = IN_TO_REG(v);

	mutex_lock(&data->update_lock);

	data->in_max[n] = r;

	if (n < 4)
		gl520_write_value(client, GL520_REG_IN_MAX[n],
				  (gl520_read_value(client, GL520_REG_IN_MAX[n])
				   & ~0xff00) | (r << 8));
	else
		gl520_write_value(client, GL520_REG_IN_MAX[n], r);

	mutex_unlock(&data->update_lock);
	return count;
}
Exemplo n.º 5
0
static ssize_t set_in_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;
	u8 r;
	long v;
	int err;

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

	mutex_lock(&data->update_lock);

	if (n == 0)
		r = VDD_TO_REG(v);
	else
		r = IN_TO_REG(v);

	data->in_min[n] = r;

	if (n < 4)
		gl520_write_value(client, GL520_REG_IN_MIN[n],
				  (gl520_read_value(client, GL520_REG_IN_MIN[n])
				   & ~0xff) | r);
	else
		gl520_write_value(client, GL520_REG_IN_MIN[n], r);

	mutex_unlock(&data->update_lock);
	return count;
}
Exemplo n.º 6
0
/* Return 0 if detection is successful, -ENODEV otherwise */
static int gl520_detect(struct i2c_client *client, struct i2c_board_info *info)
{
	struct i2c_adapter *adapter = client->adapter;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
				     I2C_FUNC_SMBUS_WORD_DATA))
		return -ENODEV;

	/* Determine the chip type. */
	if ((gl520_read_value(client, GL520_REG_CHIP_ID) != 0x20) ||
	    ((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) ||
	    ((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) {
		dev_dbg(&client->dev, "Unknown chip type, skipping\n");
		return -ENODEV;
	}

	strlcpy(info->type, "gl520sm", I2C_NAME_SIZE);

	return 0;
}
Exemplo n.º 7
0
static ssize_t set_beep_enable(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);
	u8 r = simple_strtoul(buf, NULL, 10)?0:1;

	mutex_lock(&data->update_lock);
	data->beep_enable = !r;
	gl520_write_value(client, GL520_REG_BEEP_ENABLE,
			  (gl520_read_value(client, GL520_REG_BEEP_ENABLE)
			   & ~0x04) | (r << 2));
	mutex_unlock(&data->update_lock);
	return count;
}
Exemplo n.º 8
0
static ssize_t set_fan_off(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);
	u8 r = simple_strtoul(buf, NULL, 10)?1:0;

	mutex_lock(&data->update_lock);
	data->fan_off = r;
	gl520_write_value(client, GL520_REG_FAN_OFF,
			  (gl520_read_value(client, GL520_REG_FAN_OFF)
			   & ~0x0c) | (r << 2));
	mutex_unlock(&data->update_lock);
	return count;
}
Exemplo n.º 9
0
static ssize_t set_beep_enable(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);
	u8 r;
	unsigned long v;
	int err;

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

	r = (v ? 0 : 1);

	mutex_lock(&data->update_lock);
	data->beep_enable = !r;
	gl520_write_value(client, GL520_REG_BEEP_ENABLE,
			  (gl520_read_value(client, GL520_REG_BEEP_ENABLE)
			   & ~0x04) | (r << 2));
	mutex_unlock(&data->update_lock);
	return count;
}
Exemplo n.º 10
0
static ssize_t set_fan_off(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);
	u8 r;
	unsigned long v;
	int err;

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

	r = (v ? 1 : 0);

	mutex_lock(&data->update_lock);
	data->fan_off = r;
	gl520_write_value(client, GL520_REG_FAN_OFF,
			  (gl520_read_value(client, GL520_REG_FAN_OFF)
			   & ~0x0c) | (r << 2));
	mutex_unlock(&data->update_lock);
	return count;
}
Exemplo n.º 11
0
/* Called when we have found a new GL520SM. */
static void gl520_init_client(struct i2c_client *client)
{
	struct gl520_data *data = i2c_get_clientdata(client);
	u8 oldconf, conf;

	conf = oldconf = gl520_read_value(client, GL520_REG_CONF);

	data->alarm_mask = 0xff;
	data->vrm = vid_which_vrm();

	if (extra_sensor_type == 1)
		conf &= ~0x10;
	else if (extra_sensor_type == 2)
		conf |= 0x10;
	data->two_temps = !(conf & 0x10);

	/* If IRQ# is disabled, we can safely force comparator mode */
	if (!(conf & 0x20))
		conf &= 0xf7;

	/* Enable monitoring if needed */
	conf |= 0x40;

	if (conf != oldconf)
		gl520_write_value(client, GL520_REG_CONF, conf);

	gl520_update_device(&(client->dev));

	if (data->fan_min[0] == 0)
		data->alarm_mask &= ~0x20;
	if (data->fan_min[1] == 0)
		data->alarm_mask &= ~0x40;

	data->beep_mask &= data->alarm_mask;
	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
}
Exemplo n.º 12
0
static struct gl520_data *gl520_update_device(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct gl520_data *data = i2c_get_clientdata(client);
	int val, i;

	mutex_lock(&data->update_lock);

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

		dev_dbg(&client->dev, "Starting gl520sm update\n");

		data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
		data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
		data->vid = gl520_read_value(client, GL520_REG_VID_INPUT) & 0x1f;

		for (i = 0; i < 4; i++) {
			data->in_input[i] = gl520_read_value(client,
							GL520_REG_IN_INPUT[i]);
			val = gl520_read_value(client, GL520_REG_IN_LIMIT[i]);
			data->in_min[i] = val & 0xff;
			data->in_max[i] = (val >> 8) & 0xff;
		}

		val = gl520_read_value(client, GL520_REG_FAN_INPUT);
		data->fan_input[0] = (val >> 8) & 0xff;
		data->fan_input[1] = val & 0xff;

		val = gl520_read_value(client, GL520_REG_FAN_MIN);
		data->fan_min[0] = (val >> 8) & 0xff;
		data->fan_min[1] = val & 0xff;

		data->temp_input[0] = gl520_read_value(client,
						GL520_REG_TEMP_INPUT[0]);
		data->temp_max[0] = gl520_read_value(client,
						GL520_REG_TEMP_MAX[0]);
		data->temp_max_hyst[0] = gl520_read_value(client,
						GL520_REG_TEMP_MAX_HYST[0]);

		val = gl520_read_value(client, GL520_REG_FAN_DIV);
		data->fan_div[0] = (val >> 6) & 0x03;
		data->fan_div[1] = (val >> 4) & 0x03;
		data->fan_off = (val >> 2) & 0x01;

		data->alarms &= data->alarm_mask;

		val = gl520_read_value(client, GL520_REG_CONF);
		data->beep_enable = !((val >> 2) & 1);

		/* Temp1 and Vin4 are the same input */
		if (data->two_temps) {
			data->temp_input[1] = gl520_read_value(client,
						GL520_REG_TEMP_INPUT[1]);
			data->temp_max[1] = gl520_read_value(client,
						GL520_REG_TEMP_MAX[1]);
			data->temp_max_hyst[1] = gl520_read_value(client,
						GL520_REG_TEMP_MAX_HYST[1]);
		} else {
			data->in_input[4] = gl520_read_value(client,
						GL520_REG_IN_INPUT[4]);
			data->in_min[4] = gl520_read_value(client,
						GL520_REG_IN_MIN[4]);
			data->in_max[4] = gl520_read_value(client,
						GL520_REG_IN_MAX[4]);
		}

		data->last_updated = jiffies;
		data->valid = 1;
	}
Exemplo n.º 13
0
void gl520_update_client(struct i2c_client *client)
{
	struct gl520_data *data = client->data;
	int val;

	down(&data->update_lock);

	if ((jiffies - data->last_updated > HZ + HZ / 2) ||
	    (jiffies < data->last_updated) || !data->valid) {

#ifdef DEBUG
		printk("Starting gl520 update\n");
#endif

		data->alarms = gl520_read_value(client, GL520_REG_INT);
		data->beeps = gl520_read_value(client, GL520_REG_ALARM);
		data->vid = gl520_read_value(client, GL520_REG_VID) & 0x1f;

		val = gl520_read_value(client, GL520_REG_VDD_LIMIT);
		data->voltage_min[0] = val & 0xff;
		data->voltage_max[0] = (val >> 8) & 0xff;
		val = gl520_read_value(client, GL520_REG_VIN1_LIMIT);
		data->voltage_min[1] = val & 0xff;
		data->voltage_max[1] = (val >> 8) & 0xff;
		val = gl520_read_value(client, GL520_REG_VIN2_LIMIT);
		data->voltage_min[2] = val & 0xff;
		data->voltage_max[2] = (val >> 8) & 0xff;
		val = gl520_read_value(client, GL520_REG_VIN3_LIMIT);
		data->voltage_min[3] = val & 0xff;
		data->voltage_max[3] = (val >> 8) & 0xff;

		val = gl520_read_value(client, GL520_REG_FAN_COUNT);
		data->fan[0] = (val >> 8) & 0xff;
		data->fan[1] = val & 0xff;

		val = gl520_read_value(client, GL520_REG_FAN_LIMIT);
		data->fan_min[0] = (val >> 8) & 0xff;
		data->fan_min[1] = val & 0xff;

		data->temp[0] = gl520_read_value(client, GL520_REG_TEMP1);
		data->temp_over[0] =
		    gl520_read_value(client, GL520_REG_TEMP1_OVER);
		data->temp_hyst[0] =
		    gl520_read_value(client, GL520_REG_TEMP1_HYST);

		val = gl520_read_value(client, GL520_REG_MISC);
		data->fan_div[0] = (val >> 6) & 0x03;
		data->fan_div[1] = (val >> 4) & 0x03;

		data->alarms &= data->alarm_mask;

		val = gl520_read_value(client, GL520_REG_CONF);
		data->beep_enable = (val >> 2) & 1;

		data->voltage[0] = gl520_read_value(client, GL520_REG_VDD);
		data->voltage[1] =
		    gl520_read_value(client, GL520_REG_VIN1);
		data->voltage[2] =
		    gl520_read_value(client, GL520_REG_VIN2);
		data->voltage[3] =
		    gl520_read_value(client, GL520_REG_VIN3);

		/* Temp1 and Vin4 are the same input */
		data->temp[1] = gl520_read_value(client, GL520_REG_TEMP2);
		data->temp_over[1] =
		    gl520_read_value(client, GL520_REG_TEMP2_OVER);
		data->temp_hyst[1] =
		    gl520_read_value(client, GL520_REG_TEMP2_HYST);

		data->voltage[4] =
		    gl520_read_value(client, GL520_REG_VIN4);
		data->voltage_min[4] =
		    gl520_read_value(client, GL520_REG_VIN4_MIN);
		data->voltage_max[4] =
		    gl520_read_value(client, GL520_REG_VIN4_MAX);

		data->last_updated = jiffies;
		data->valid = 1;
	}
Exemplo n.º 14
0
static int gl520_detect(struct i2c_adapter *adapter, int address,
			unsigned short flags, int kind)
{
	int i;
	struct i2c_client *new_client;
	struct gl520_data *data;
	int err = 0;
	const char *type_name = "";
	char client_name[32];

	/* Make sure we aren't probing the ISA bus!! This is just a safety check
	   at this moment; i2c_detect really won't call us. */
#ifdef DEBUG
	if (i2c_is_isa_adapter(adapter)) {
		printk
		    ("gl520sm.o: gl520_detect called for an ISA bus adapter?!?\n");
		return 0;
	}
#endif

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
				     I2C_FUNC_SMBUS_WORD_DATA))
		    goto ERROR0;

	/* OK. For now, we presume we have a valid client. We now create the
	   client structure, even though we cannot fill it completely yet.
	   But it allows us to access gl520_{read,write}_value. */

	if (!(new_client = kmalloc(sizeof(struct i2c_client) +
				   sizeof(struct gl520_data),
				   GFP_KERNEL))) {
		err = -ENOMEM;
		goto ERROR0;
	}

	data = (struct gl520_data *) (new_client + 1);
	new_client->addr = address;
	new_client->data = data;
	new_client->adapter = adapter;
	new_client->driver = &gl520_driver;
	new_client->flags = 0;

	/* Determine the chip type. */

	if (gl520_read_value(new_client, GL520_REG_CHIP_ID) != 0x20) {
		printk
		    ("gl520sm.o: Ignoring 'force' parameter for unknown chip at "
		     "adapter %d, address 0x%02x\n",
		     i2c_adapter_id(adapter), address);
		goto ERROR1;
	} else {
		kind = gl520sm;
	}

	i = gl520_read_value(new_client, GL520_REG_REVISION);
	if (kind == gl520sm) {
		type_name = "gl520sm";
		sprintf(client_name, "GL520SM Revision %02x chip", i);
	} else {
#ifdef DEBUG
		printk("gl520sm.o: Internal error: unknown kind (%d)?!?",
		       kind);
#endif
		goto ERROR1;
	}

	/* Fill in the remaining client fields and put it into the global list */
	strcpy(new_client->name, client_name);
	data->type = kind;

	new_client->id = gl520_id++;
	data->valid = 0;
	init_MUTEX(&data->update_lock);

	/* Tell the I2C layer a new client has arrived */
	if ((err = i2c_attach_client(new_client)))
		goto ERROR3;

	/* Register a new directory entry with module sensors */
	if ((i = i2c_register_entry(new_client,
					type_name,
					gl520_dir_table_template,
					THIS_MODULE)) < 0) {
		err = i;
		goto ERROR4;
	}
	data->sysctl_id = i;

	/* Initialize the GL520SM chip */
	data->two_temps = 1;
	data->alarm_mask = 0xff;
	gl520_init_client(new_client);
	return 0;

/* OK, this is not exactly good programming practice, usually. But it is
   very code-efficient in this case. */

      ERROR4:
	i2c_detach_client(new_client);
      ERROR3:
      ERROR1:
	kfree(new_client);
      ERROR0:
	return err;
}