/* Return 0 for in4 and disallow writes if pin used for temp */ void sis5595_in(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_IN0; if (operation == SENSORS_PROC_REAL_INFO) *nrels_mag = 2; else if (operation == SENSORS_PROC_REAL_READ) { if(nr <= 3 || data->maxins == 4) { sis5595_update_client(client); results[0] = IN_FROM_REG(data->in_min[nr]); results[1] = IN_FROM_REG(data->in_max[nr]); results[2] = IN_FROM_REG(data->in[nr]); } else { results[0] = 0; results[1] = 0; results[2] = 0; } *nrels_mag = 3; } else if (operation == SENSORS_PROC_REAL_WRITE) { if(nr <= 3 || data->maxins == 4) { if (*nrels_mag >= 1) { data->in_min[nr] = IN_TO_REG(results[0]); sis5595_write_value(client, SIS5595_REG_IN_MIN(nr), data->in_min[nr]); } if (*nrels_mag >= 2) { data->in_max[nr] = IN_TO_REG(results[1]); sis5595_write_value(client, SIS5595_REG_IN_MAX(nr), data->in_max[nr]); } } } }
/* 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]); } } }
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_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; }
/* 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); }
static void set_in_max(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->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]); lm87_write_value(client, nr<6 ? LM87_REG_IN_MAX(nr) : LM87_REG_AIN_MAX(nr-6), data->in_max[nr]); mutex_unlock(&data->update_lock); }
static ssize_t set_in_max(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); unsigned long val = simple_strtoul(buf, NULL, 10); int nr = attr->index; mutex_lock(&data->update_lock); data->in_max[nr] = IN_TO_REG(val); lm78_write_value(data, LM78_REG_IN_MAX(nr), data->in_max[nr]); 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) { 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; }
static ssize_t set_in_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; int err; err = kstrtoul(buf, 10, &val); if (err) return err; mutex_lock(&data->update_lock); data->in_min[nr] = IN_TO_REG(val); lm78_write_value(data, LM78_REG_IN_MIN(nr), data->in_min[nr]); 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) { 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; }
static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct smsc47m192_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->in_max[nr] = IN_TO_REG(val, nr); i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr), data->in_max[nr]); 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); }
/* 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 ); }
/* 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); }