X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fhwmon%2Fw83793.c;h=c2b7834ecaa96613984411c687bdd619fd86180e;hb=46bed4dfe5f95f1fc8f68ead592a7e295bbbe01e;hp=c12ac5abc2bb4e16cf9876d4f147bb4b10792515;hpb=40b20c257a13c5a526ac540bc5e43d0fdf29792a;p=linux-2.6-omap-h63xx.git diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index c12ac5abc2b..c2b7834ecaa 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -117,6 +117,7 @@ static const u16 W83793_REG_IN[][3] = { /* Low Bits of Vcore A/B Vtt Read/High/Low */ static const u16 W83793_REG_IN_LOW_BITS[] = { 0x1b, 0x68, 0x69 }; static u8 scale_in[] = { 2, 2, 2, 16, 16, 16, 8, 24, 24, 16 }; +static u8 scale_in_add[] = { 0, 0, 0, 0, 0, 0, 0, 150, 150, 0 }; #define W83793_REG_FAN(index) (0x23 + 2 * (index)) /* High byte */ #define W83793_REG_FAN_MIN(index) (0x90 + 2 * (index)) /* High byte */ @@ -203,6 +204,7 @@ struct w83793_data { u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ u8 has_pwm; + u8 has_temp; u8 pwm_enable; /* Register value, each Temp has 1 bit */ u8 pwm_uptime; /* Register value */ u8 pwm_downtime; /* Register value */ @@ -500,7 +502,7 @@ store_temp(struct device *dev, struct device_attribute *attr, each has 4 mode:(2 bits) 0: Stop monitor 1: Use internal temp sensor(default) - 2: Use sensor in AMD CPU and get result by AMDSI + 2: Reserved 3: Use sensor in Intel CPU and get result by PECI TR1-TR2 @@ -509,8 +511,8 @@ store_temp(struct device *dev, struct device_attribute *attr, 1: To enable temp sensors monitor */ -/* 0 disable, 5 AMDSI, 6 PECI */ -static u8 TO_TEMP_MODE[] = { 0, 0, 5, 6 }; +/* 0 disable, 6 PECI */ +static u8 TO_TEMP_MODE[] = { 0, 0, 0, 6 }; static ssize_t show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) @@ -550,11 +552,10 @@ store_temp_mode(struct device *dev, struct device_attribute *attr, u8 val = simple_strtoul(buf, NULL, 10); /* transform the sysfs interface values into table above */ - if ((val == 5 || val == 6) && (index < 4)) { + if ((val == 6) && (index < 4)) { val -= 3; } else if ((val == 3 && index < 4) - || (val == 4 && index >= 4) - || val == 0) { + || (val == 4 && index >= 4)) { /* transform diode or thermistor into internal enable */ val = !!val; } else { @@ -839,7 +840,9 @@ show_in(struct device *dev, struct device_attribute *attr, char *buf) val <<= 2; val += (data->in_low_bits[nr] >> (index * 2)) & 0x3; } - return sprintf(buf, "%d\n", val * scale_in[index]); + /* voltage inputs 5VDD and 5VSB needs 150mV offset */ + val = val * scale_in[index] + scale_in_add[index]; + return sprintf(buf, "%d\n", val); } static ssize_t @@ -859,6 +862,10 @@ store_in(struct device *dev, struct device_attribute *attr, scale_in[index] / 2) / scale_in[index]; mutex_lock(&data->update_lock); if (index > 2) { + /* fix the limit values of 5VDD and 5VSB to ALARM mechanism */ + if (1 == nr || 2 == nr) { + val -= scale_in_add[index] / scale_in[index]; + } val = SENSORS_LIMIT(val, 0, 255); } else { val = SENSORS_LIMIT(val, 0, 0x3FF); @@ -979,12 +986,6 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { SENSOR_ATTR_IN(7), SENSOR_ATTR_IN(8), SENSOR_ATTR_IN(9), - SENSOR_ATTR_TEMP(1), - SENSOR_ATTR_TEMP(2), - SENSOR_ATTR_TEMP(3), - SENSOR_ATTR_TEMP(4), - SENSOR_ATTR_TEMP(5), - SENSOR_ATTR_TEMP(6), SENSOR_ATTR_FAN(1), SENSOR_ATTR_FAN(2), SENSOR_ATTR_FAN(3), @@ -995,6 +996,15 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { SENSOR_ATTR_PWM(3), }; +static struct sensor_device_attribute_2 w83793_temp[] = { + SENSOR_ATTR_TEMP(1), + SENSOR_ATTR_TEMP(2), + SENSOR_ATTR_TEMP(3), + SENSOR_ATTR_TEMP(4), + SENSOR_ATTR_TEMP(5), + SENSOR_ATTR_TEMP(6), +}; + /* Fan6-Fan12 */ static struct sensor_device_attribute_2 w83793_left_fan[] = { SENSOR_ATTR_FAN(6), @@ -1075,6 +1085,9 @@ static int w83793_detach_client(struct i2c_client *client) for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) device_remove_file(dev, &w83793_left_pwm[i].dev_attr); + + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) + device_remove_file(dev, &w83793_temp[i].dev_attr); } if ((err = i2c_detach_client(client))) @@ -1187,6 +1200,7 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) struct w83793_data *data; int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; + int files_temp = ARRAY_SIZE(w83793_temp) / 6; int err = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { @@ -1313,6 +1327,23 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) data->has_pwm |= 0x80; } + /* check the temp1-6 mode, ignore former AMDSI selected inputs */ + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]); + if (tmp & 0x01) + data->has_temp |= 0x01; + if (tmp & 0x04) + data->has_temp |= 0x02; + if (tmp & 0x10) + data->has_temp |= 0x04; + if (tmp & 0x40) + data->has_temp |= 0x08; + + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[1]); + if (tmp & 0x01) + data->has_temp |= 0x10; + if (tmp & 0x02) + data->has_temp |= 0x20; + /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { err = device_create_file(dev, @@ -1328,6 +1359,19 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) } + for (i = 0; i < 6; i++) { + int j; + if (!(data->has_temp & (1 << i))) + continue; + for (j = 0; j < files_temp; j++) { + err = device_create_file(dev, + &w83793_temp[(i) * files_temp + + j].dev_attr); + if (err) + goto exit_remove; + } + } + for (i = 5; i < 12; i++) { int j; if (!(data->has_fan & (1 << i))) @@ -1377,6 +1421,9 @@ exit_remove: for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) device_remove_file(dev, &w83793_left_pwm[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) + device_remove_file(dev, &w83793_temp[i].dev_attr); + if (data->lm75[0] != NULL) { i2c_detach_client(data->lm75[0]); kfree(data->lm75[0]); @@ -1428,6 +1475,8 @@ static void w83793_update_nonvolatile(struct device *dev) } for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) { + if (!(data->has_temp & (1 << i))) + continue; data->temp_fan_map[i] = w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i)); for (j = 1; j < 5; j++) { @@ -1510,9 +1559,12 @@ static struct w83793_data *w83793_update_device(struct device *dev) w83793_read_value(client, W83793_REG_FAN(i) + 1); } - for (i = 0; i < ARRAY_SIZE(data->temp); i++) + for (i = 0; i < ARRAY_SIZE(data->temp); i++) { + if (!(data->has_temp & (1 << i))) + continue; data->temp[i][TEMP_READ] = w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]); + } data->temp_low_bits = w83793_read_value(client, W83793_REG_TEMP_LOW_BITS);