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; }
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; }
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; }
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; }
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; }
static ssize_t set_beep_mask(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); mutex_lock(&data->update_lock); r &= data->alarm_mask; data->beep_mask = r; gl520_write_value(client, GL520_REG_BEEP_MASK, r); mutex_unlock(&data->update_lock); return count; }
static ssize_t set_temp_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); mutex_lock(&data->update_lock); data->temp_max[n] = TEMP_TO_REG(v); gl520_write_value(client, GL520_REG_TEMP_MAX[n], data->temp_max[n]); mutex_unlock(&data->update_lock); return count; }
/* 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); }
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; }
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; }
static ssize_t set_beep_mask(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); unsigned long r; int err; err = kstrtoul(buf, 10, &r); if (err) return err; mutex_lock(&data->update_lock); r &= data->alarm_mask; data->beep_mask = r; gl520_write_value(client, GL520_REG_BEEP_MASK, r); mutex_unlock(&data->update_lock); return count; }
static ssize_t set_temp_max_hyst(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; int err; err = kstrtol(buf, 10, &v); if (err) return err; mutex_lock(&data->update_lock); data->temp_max_hyst[n] = TEMP_TO_REG(v); gl520_write_value(client, GL520_REG_TEMP_MAX_HYST[n], data->temp_max_hyst[n]); mutex_unlock(&data->update_lock); return count; }
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; }
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; }
/* 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); }