0x104, 0x204, 0x304, 0x804, 0x904 };
static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
0x105, 0x205, 0x305, 0x805, 0x905 };
-static const u16 NCT6775_REG_FAN_START_OUTPUT[] = {
- 0x106, 0x206, 0x306, 0x806, 0x906 };
-static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
- 0x107, 0x207, 0x307, 0x807, 0x907 };
+static const u16 NCT6775_REG_FAN_START_OUTPUT[]
+ = { 0x106, 0x206, 0x306, 0x806, 0x906 };
+static const u16 NCT6775_REG_FAN_STOP_TIME[]
+ = { 0x107, 0x207, 0x307, 0x807, 0x907 };
static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309, 0x809, 0x909 };
static const u16 NCT6775_REG_PWM_READ[] = { 0x01, 0x03, 0x11, 0x13, 0x15 };
-static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
-static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642};
-static const u16 NCT6779_REG_TOLERANCE_H[] = {
- 0x10c, 0x20c, 0x30c, 0x40c, 0x50c };
+static const u16 NCT6779_REG_TOLERANCE_H[]
+ = { 0x10c, 0x20c, 0x30c, 0x40c, 0x50c };
static const u16 NCT6779_REG_FAN[] = { 0x4c0, 0x4c2, 0x4c4, 0x4c6, 0x4c8 };
-static const u16 NCT6775_REG_TEMP[]
- = { 0x27, 0x150, 0x250, 0x73, 0x75, 0x77, 0x62b, 0x62c, 0x62d };
-static const u16 NCT6775_REG_TEMP_CONFIG[]
- = { 0, 0x152, 0x252, 0, 0, 0, 0x628, 0x629, 0x62A };
-static const u16 NCT6775_REG_TEMP_HYST[]
- = { 0x3a, 0x153, 0x253, 0, 0, 0, 0x673, 0x678, 0x67D };
-static const u16 NCT6775_REG_TEMP_OVER[]
- = { 0x39, 0x155, 0x255, 0, 0, 0, 0x672, 0x677, 0x67C };
-static const u16 NCT6775_REG_TEMP_SOURCE[]
- = { 0x621, 0x622, 0x623, 0x100, 0x200, 0x300, 0x624, 0x625, 0x626 };
-
-static const u16 NCT6776_REG_TEMP_CONFIG[]
- = { 0x18, 0x152, 0x252, 0, 0, 0, 0x628, 0x629, 0x62A };
-
-static const u16 NCT6779_REG_TEMP[]
- = { 0x27, 0x150, 0x73, 0x75, 0x77, 0x79, 0x7b };
-static const u16 NCT6779_REG_TEMP_CONFIG[]
- = { 0x18, 0x152, 0, 0, 0, 0, 0 };
-static const u16 NCT6779_REG_TEMP_SOURCE[]
- = { 0x621, 0x622, 0x100, 0x200, 0x300, 0x800, 0x900 };
-static const u16 NCT6779_REG_TEMP_HYST[]
- = { 0x3a, 0x153, 0, 0, 0, 0, 0, 0, 0 };
-static const u16 NCT6779_REG_TEMP_OVER[]
- = { 0x39, 0x155, 0, 0, 0, 0, 0, 0, 0 };
-
-static const u16 NCT6775_REG_AUTO_BASE[] = {
- 0x100, 0x200, 0x300, 0x800, 0x900 };
+static const u16 NCT6775_REG_TEMP[11]
+ = { 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d, 0x73, 0x75, 0x77 };
+static const u16 NCT6775_REG_TEMP_CONFIG[11]
+ = { 0, 0x152, 0x252, 0x628, 0x629, 0x62A };
+static const u16 NCT6775_REG_TEMP_HYST[11]
+ = { 0x3a, 0x153, 0x253, 0x673, 0x678, 0x67D };
+static const u16 NCT6775_REG_TEMP_OVER[11]
+ = { 0x39, 0x155, 0x255, 0x672, 0x677, 0x67C };
+static const u16 NCT6775_REG_TEMP_SOURCE[11]
+ = { 0x621, 0x622, 0x623, 0x624, 0x625, 0x626, 0x100, 0x200, 0x300,
+ 0x800, 0x900 };
+
+static const u16 NCT6776_REG_TEMP_CONFIG[11]
+ = { 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A };
+
+static const u16 NCT6779_REG_TEMP[11]
+ = { 0x27, 0x150, 0, 0, 0, 0, 0x73, 0x75, 0x77, 0x79, 0x7b };
+
+static const u16 NCT6775_REG_AUTO_BASE[]
+ = { 0x100, 0x200, 0x300, 0x800, 0x900 };
#define NCT6775_REG_AUTO_TEMP(nr, p) (NCT6775_REG_AUTO_BASE[nr] + 0x21 + (p))
#define NCT6775_REG_AUTO_PWM(nr, p) (NCT6775_REG_AUTO_BASE[nr] + 0x27 + (p))
#define NUM_REG_TEMP ARRAY_SIZE(NCT6775_REG_TEMP)
+static inline int reg_to_pwm_enable(int pwm, int mode)
+{
+ if (mode == 0 && pwm == 255)
+ return 0; /* off */
+ if (mode == 3) /* SmartFan III */
+ return 2; /* convert to thermal cruise */
+ if (mode < 3)
+ return mode + 1;
+ return 4; /* SmartFan IV */
+}
+
+static inline int pwm_enable_to_reg(int mode)
+{
+ if (mode == 0)
+ return 0;
+ if (mode < 4)
+ return mode - 1;
+ return 4;
+}
+
static int is_word_sized(u16 reg)
{
return ((((reg & 0xff00) == 0x100
const u16 *REG_FAN_MIN;
const u16 *REG_FAN_START_OUTPUT;
const u16 *REG_FAN_STOP_OUTPUT;
- const u16 *REG_FAN_MAX_OUTPUT;
- const u16 *REG_FAN_STEP_OUTPUT;
unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
u8 caseopen;
u8 pwm_mode[5]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
- u8 pwm_enable[5]; /* 1->manual
+ u8 pwm_enable[5]; /* 0->off
+ * 1->manual
* 2->thermal cruise mode (also called SmartFan I)
* 3->fan speed cruise mode
- * 4->variable thermal cruise (also called
- * SmartFan III)
- * 5->enhanced variable thermal cruise (also called
- * SmartFan IV)
+ * 4->enhanced variable thermal cruise (also called
+ * SmartFan IV)
*/
u8 pwm_num; /* number of pwm */
u8 pwm[5];
u8 fan_stop_time[5]; /* time at minimum before disabling fan */
u8 fan_step_up_time[5];
u8 fan_step_down_time[5];
- u8 fan_max_output[5]; /* maximum fan speed */
- u8 fan_step_output[5]; /* rate of change output value */
/* Automatic fan speed control registers */
int auto_pwm_num;
struct nct6775_data *data = dev_get_drvdata(dev);
struct nct6775_sio_data *sio_data = dev->platform_data;
int i;
- int pwmcfg, fanmodecfg, mode, tol;
+ int pwmcfg, fanmodecfg, tol;
for (i = 0; i < data->pwm_num; i++) {
if (!i) {
fanmodecfg = nct6775_read_value(data,
NCT6775_REG_FAN_MODE[i]);
data->pwm[i] = nct6775_read_value(data, NCT6775_REG_PWM[i]);
- mode = ((fanmodecfg >> 4) & 7);
- if (data->pwm[i] == 255 && mode == 0)
- data->pwm_enable[i] = 0;
- else
- data->pwm_enable[i] = mode + 1;
+ data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[i],
+ (fanmodecfg >> 4) & 7);
+
data->tolerance[i][0] = fanmodecfg & 0x0f;
if (sio_data->kind == nct6779) {
tol = nct6775_read_value(data,
data->fan_step_down_time[i] =
nct6775_read_value(data, NCT6775_REG_FAN_STEP_DOWN_TIME[i]);
- if (data->REG_FAN_MAX_OUTPUT)
- data->fan_max_output[i] =
- nct6775_read_value(data,
- data->REG_FAN_MAX_OUTPUT[i]);
-
- if (data->REG_FAN_STEP_OUTPUT)
- data->fan_step_output[i] =
- nct6775_read_value(data,
- data->REG_FAN_STEP_OUTPUT[i]);
-
data->target_temp[i] =
nct6775_read_value(data,
data->REG_TARGET[i]) &
SENSOR_ATTR(temp7_input, S_IRUGO, show_temp, NULL, 6),
SENSOR_ATTR(temp8_input, S_IRUGO, show_temp, NULL, 7),
SENSOR_ATTR(temp9_input, S_IRUGO, show_temp, NULL, 8),
+ SENSOR_ATTR(temp10_input, S_IRUGO, show_temp, NULL, 9),
+ SENSOR_ATTR(temp11_input, S_IRUGO, show_temp, NULL, 10),
};
static struct sensor_device_attribute sda_temp_label[] = {
SENSOR_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3),
SENSOR_ATTR(temp5_label, S_IRUGO, show_temp_label, NULL, 4),
SENSOR_ATTR(temp6_label, S_IRUGO, show_temp_label, NULL, 5),
- SENSOR_ATTR(temp7_label, S_IRUGO, show_temp_label, NULL, 6),
- SENSOR_ATTR(temp8_label, S_IRUGO, show_temp_label, NULL, 7),
- SENSOR_ATTR(temp9_label, S_IRUGO, show_temp_label, NULL, 8),
};
static struct sensor_device_attribute sda_temp_max[] = {
store_temp_max, 4),
SENSOR_ATTR(temp6_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 5),
- SENSOR_ATTR(temp7_max, S_IRUGO | S_IWUSR, show_temp_max,
- store_temp_max, 6),
- SENSOR_ATTR(temp8_max, S_IRUGO | S_IWUSR, show_temp_max,
- store_temp_max, 7),
- SENSOR_ATTR(temp9_max, S_IRUGO | S_IWUSR, show_temp_max,
- store_temp_max, 8),
};
static struct sensor_device_attribute sda_temp_max_hyst[] = {
store_temp_max_hyst, 4),
SENSOR_ATTR(temp6_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 5),
- SENSOR_ATTR(temp7_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
- store_temp_max_hyst, 6),
- SENSOR_ATTR(temp8_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
- store_temp_max_hyst, 7),
- SENSOR_ATTR(temp9_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
- store_temp_max_hyst, 8),
};
static struct sensor_device_attribute sda_temp_alarm[] = {
const char *buf, size_t count)
{
struct nct6775_data *data = dev_get_drvdata(dev);
- struct nct6775_sio_data *sio_data = dev->platform_data;
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
unsigned long val;
if (err < 0)
return err;
- if (val > 5)
+ if (val > 4)
return -EINVAL;
- /* SmartFan III mode is only supported on NCT6775F */
- if (sio_data->kind != nct6775 && val == 4)
- return -EINVAL;
-
- if (val == 5 && check_trip_points(data, nr)) {
+ if (val == 4 && check_trip_points(data, nr)) {
dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
dev_err(dev, "Adjust trip points and try again\n");
return -EINVAL;
/*
* turn off pwm control: select manual mode, set pwm to maximum
*/
- val = 1;
data->pwm[nr] = 255;
nct6775_write_value(data, NCT6775_REG_PWM[nr], 255);
}
reg = nct6775_read_value(data, NCT6775_REG_FAN_MODE[nr]);
reg &= 0x0f;
- reg |= (val - 1) << 4;
+ reg |= (pwm_enable_to_reg(val) << 4);
nct6775_write_value(data, NCT6775_REG_FAN_MODE[nr], reg);
mutex_unlock(&data->update_lock);
return count;
}
+static ssize_t
+show_pwm_temp_src(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct nct6775_data *data = nct6775_update_device(dev);
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+ return sprintf(buf, "%d\n", data->temp_src[nr]);
+}
+
+static ssize_t
+store_pwm_temp_src(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct nct6775_data *data = nct6775_update_device(dev);
+ struct nct6775_sio_data *sio_data = dev->platform_data;
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+ unsigned long val;
+ int err;
+ int reg;
+ static const int max_src[] = {
+ ARRAY_SIZE(nct6775_temp_label),
+ ARRAY_SIZE(nct6776_temp_label),
+ ARRAY_SIZE(nct6779_temp_label)
+ };
+
+ err = kstrtoul(buf, 10, &val);
+ if (err < 0)
+ return err;
+ if (val == 0 || val >= max_src[sio_data->kind])
+ return -EINVAL;
-static ssize_t show_target_temp(struct device *dev,
- struct device_attribute *attr, char *buf)
+ if (!strlen(data->temp_label[val]))
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->temp_src[nr] = val;
+ reg = nct6775_read_value(data, NCT6775_REG_TEMP_SOURCE[nr]);
+ reg &= 0xe0;
+ reg |= val;
+ nct6775_write_value(data, NCT6775_REG_TEMP_SOURCE[nr], reg);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t
+show_target_temp(struct device *dev, struct device_attribute *attr, char *buf)
{
struct nct6775_data *data = nct6775_update_device(dev);
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
return count;
}
-static ssize_t show_auto_temp_hyst(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t
+show_auto_temp_hyst(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct nct6775_data *data = nct6775_update_device(dev);
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
store_pwm_enable, 4);
+static SENSOR_DEVICE_ATTR(pwm1_temp_src, S_IWUSR | S_IRUGO, show_pwm_temp_src,
+ store_pwm_temp_src, 6);
+static SENSOR_DEVICE_ATTR(pwm2_temp_src, S_IWUSR | S_IRUGO, show_pwm_temp_src,
+ store_pwm_temp_src, 7);
+static SENSOR_DEVICE_ATTR(pwm3_temp_src, S_IWUSR | S_IRUGO, show_pwm_temp_src,
+ store_pwm_temp_src, 8);
+static SENSOR_DEVICE_ATTR(pwm4_temp_src, S_IWUSR | S_IRUGO, show_pwm_temp_src,
+ store_pwm_temp_src, 9);
+static SENSOR_DEVICE_ATTR(pwm5_temp_src, S_IWUSR | S_IRUGO, show_pwm_temp_src,
+ store_pwm_temp_src, 10);
+
static SENSOR_DEVICE_ATTR(pwm1_target, S_IWUSR | S_IRUGO, show_target_temp,
store_target_temp, 0);
static SENSOR_DEVICE_ATTR(pwm2_target, S_IWUSR | S_IRUGO, show_target_temp,
fan_functions(fan_start_output, FAN_START_OUTPUT)
fan_functions(fan_stop_output, FAN_STOP_OUTPUT)
-fan_functions(fan_max_output, FAN_MAX_OUTPUT)
-fan_functions(fan_step_output, FAN_STEP_OUTPUT)
#define fan_step_functions(reg, REG) \
static ssize_t show_##reg(struct device *dev, \
static SENSOR_DEVICE_ATTR(pwm5_stop_output, S_IWUSR | S_IRUGO,
show_fan_stop_output, store_fan_stop_output, 4);
-static struct attribute *nct6775_attributes_pwm[5][10] = {
+static struct attribute *nct6775_attributes_pwm[5][11] = {
{
&sensor_dev_attr_pwm1.dev_attr.attr,
&sensor_dev_attr_pwm1_mode.dev_attr.attr,
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm1_temp_src.dev_attr.attr,
&sensor_dev_attr_pwm1_target.dev_attr.attr,
&sensor_dev_attr_pwm1_stop_time.dev_attr.attr,
&sensor_dev_attr_pwm1_step_up_time.dev_attr.attr,
&sensor_dev_attr_pwm2.dev_attr.attr,
&sensor_dev_attr_pwm2_mode.dev_attr.attr,
&sensor_dev_attr_pwm2_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm2_temp_src.dev_attr.attr,
&sensor_dev_attr_pwm2_target.dev_attr.attr,
&sensor_dev_attr_pwm2_stop_time.dev_attr.attr,
&sensor_dev_attr_pwm2_step_up_time.dev_attr.attr,
&sensor_dev_attr_pwm3.dev_attr.attr,
&sensor_dev_attr_pwm3_mode.dev_attr.attr,
&sensor_dev_attr_pwm3_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm3_temp_src.dev_attr.attr,
&sensor_dev_attr_pwm3_target.dev_attr.attr,
&sensor_dev_attr_pwm3_stop_time.dev_attr.attr,
&sensor_dev_attr_pwm3_step_up_time.dev_attr.attr,
&sensor_dev_attr_pwm4.dev_attr.attr,
&sensor_dev_attr_pwm4_mode.dev_attr.attr,
&sensor_dev_attr_pwm4_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm4_temp_src.dev_attr.attr,
&sensor_dev_attr_pwm4_target.dev_attr.attr,
&sensor_dev_attr_pwm4_stop_time.dev_attr.attr,
&sensor_dev_attr_pwm4_step_up_time.dev_attr.attr,
&sensor_dev_attr_pwm5.dev_attr.attr,
&sensor_dev_attr_pwm5_mode.dev_attr.attr,
&sensor_dev_attr_pwm5_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm5_temp_src.dev_attr.attr,
&sensor_dev_attr_pwm5_target.dev_attr.attr,
&sensor_dev_attr_pwm5_stop_time.dev_attr.attr,
&sensor_dev_attr_pwm5_step_up_time.dev_attr.attr,
{ .attrs = nct6775_attributes_pwm[4] },
};
-/*
- * max and step settings are not supported on all chips.
- * Need to check support while generating/removing attribute files.
- */
-static struct sensor_device_attribute sda_sf3_max_step_arrays[] = {
- SENSOR_ATTR(pwm1_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
- store_fan_max_output, 0),
- SENSOR_ATTR(pwm1_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
- store_fan_step_output, 0),
- SENSOR_ATTR(pwm2_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
- store_fan_max_output, 1),
- SENSOR_ATTR(pwm2_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
- store_fan_step_output, 1),
- SENSOR_ATTR(pwm3_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
- store_fan_max_output, 2),
- SENSOR_ATTR(pwm3_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
- store_fan_step_output, 2),
- SENSOR_ATTR(pwm4_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
- store_fan_max_output, 3),
- SENSOR_ATTR(pwm4_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
- store_fan_step_output, 3),
- SENSOR_ATTR(pwm5_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
- store_fan_max_output, 4),
- SENSOR_ATTR(pwm5_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
- store_fan_step_output, 4),
-};
-
static ssize_t show_auto_pwm(struct device *dev, struct device_attribute *attr,
char *buf)
{
&sda_auto_pwm_arrays[j].dev_attr);
}
- for (i = 0; i < ARRAY_SIZE(sda_sf3_max_step_arrays); i++)
- device_remove_file(dev, &sda_sf3_max_step_arrays[i].dev_attr);
-
for (i = 0; i < data->in_num; i++)
sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
if (!(data->have_temp & (1 << i)))
continue;
device_remove_file(dev, &sda_temp_input[i].dev_attr);
+ if (i > 5)
+ continue;
device_remove_file(dev, &sda_temp_label[i].dev_attr);
device_remove_file(dev, &sda_temp_max[i].dev_attr);
device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
struct nct6775_data *data;
struct resource *res;
int i, err = 0;
+ int mask = 0;
+ const u16 *reg_temp, *reg_temp_config;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!request_region(res->start, IOREGION_LENGTH, DRVNAME)) {
data->have_temp = 0;
/* Deal with temperature register setup first. */
- if (sio_data->kind == nct6775 || sio_data->kind == nct6776) {
- int mask = 0;
+ switch(sio_data->kind == nct6775) {
+ case nct6775:
+ reg_temp = NCT6775_REG_TEMP;
+ reg_temp_config = NCT6775_REG_TEMP_CONFIG;
+ case nct6776:
+ reg_temp = NCT6775_REG_TEMP;
+ reg_temp_config = NCT6776_REG_TEMP_CONFIG;
+ break;
+ case nct6779:
+ reg_temp = NCT6779_REG_TEMP;
+ reg_temp_config = NCT6776_REG_TEMP_CONFIG;
+ break;
+ }
- /*
- * Display temperature sensor output only if it monitors
- * a source other than one already reported. Always display
- * first three temperature registers, though.
- */
- for (i = 0; i < NUM_REG_TEMP; i++) {
- u8 src;
-
- data->reg_temp[i] = NCT6775_REG_TEMP[i];
- data->reg_temp_over[i] = NCT6775_REG_TEMP_OVER[i];
- data->reg_temp_hyst[i] = NCT6775_REG_TEMP_HYST[i];
- if (sio_data->kind == nct6775)
- data->reg_temp_config[i]
- = NCT6775_REG_TEMP_CONFIG[i];
- else
- data->reg_temp_config[i]
- = NCT6776_REG_TEMP_CONFIG[i];
-
- src = nct6775_read_value(data,
- NCT6775_REG_TEMP_SOURCE[i]);
- src &= 0x1f;
- if (src && !(mask & (1 << src))) {
- data->have_temp |= 1 << i;
- mask |= 1 << src;
- }
+ for (i = 0; i < NUM_REG_TEMP; i++) {
+ u8 src;
+
+ if (reg_temp[i] == 0)
+ continue;
+
+ data->reg_temp[i] = reg_temp[i];
+ data->reg_temp_over[i] = NCT6775_REG_TEMP_OVER[i];
+ data->reg_temp_hyst[i] = NCT6775_REG_TEMP_HYST[i];
+ data->reg_temp_config[i] = reg_temp_config[i];
+
+ src = nct6775_read_value(data, NCT6775_REG_TEMP_SOURCE[i]);
+ src &= 0x1f;
+
+ /* Always display temp6..10 (fan control sources) if enabled */
+ if (src && (i > 5 || !(mask & (1 << src)))) {
+ data->have_temp |= 1 << i;
+ mask |= 1 << src;
+ }
- data->temp_src[i] = src;
+ data->temp_src[i] = src;
+ if (i < 6) {
/*
- * Now do some register swapping if index 0..2 don't
+ * Do some register swapping if index 0..2 don't
* point to SYSTIN(1), CPUIN(2), and AUXIN(3).
* Idea is to have the first three attributes
* report SYSTIN, CPUIN, and AUXIN if possible
* without overriding the basic system configuration.
+ * Do this only for the first six temperature sources;
+ * the remaining temperatures are fan control sources,
+ * and we don't want to touch those.
*/
if (i > 0 && data->temp_src[0] != 1
&& data->temp_src[i] == 1)
&& data->temp_src[i] == 3)
w82627ehf_swap_tempreg(data, 2, i);
}
- if (sio_data->kind == nct6776) {
- /*
- * On NCT6776, AUXTIN and VIN3 pins are shared.
- * Only way to detect it is to check if AUXTIN is used
- * as a temperature source, and if that source is
- * enabled.
- *
- * If that is the case, disable in6, which reports VIN3.
- * Otherwise disable temp3.
- */
- if (data->temp_src[2] == 3) {
- u8 reg;
-
- if (data->reg_temp_config[2])
- reg = nct6775_read_value(data,
- data->reg_temp_config[2]);
- else
- reg = 0; /* Assume AUXTIN is used */
-
- if (reg & 0x01)
- data->have_temp &= ~(1 << 2);
- else
- data->have_in &= ~(1 << 6);
- }
- data->temp_label = nct6776_temp_label;
- } else {
- data->temp_label = nct6775_temp_label;
- }
- } else if (sio_data->kind == nct6779) {
- int mask = 0;
+ }
+ switch (sio_data->kind) {
+ case nct6775:
+ data->temp_label = nct6775_temp_label;
+ break;
+ case nct6776:
/*
- * Display temperature sensor output only if it monitors
- * a source other than one already reported. Always display
- * first three temperature registers, though.
+ * On NCT6776, AUXTIN and VIN3 pins are shared.
+ * Only way to detect it is to check if AUXTIN is used
+ * as a temperature source, and if that source is
+ * enabled.
+ *
+ * If that is the case, disable in6, which reports VIN3.
+ * Otherwise disable temp3.
*/
- for (i = 0; i < ARRAY_SIZE(NCT6779_REG_TEMP); i++) {
- u8 src;
-
- data->reg_temp[i] = NCT6779_REG_TEMP[i];
- data->reg_temp_over[i] = NCT6779_REG_TEMP_OVER[i];
- data->reg_temp_hyst[i] = NCT6779_REG_TEMP_HYST[i];
- data->reg_temp_config[i] = NCT6779_REG_TEMP_CONFIG[i];
-
- src = nct6775_read_value(data,
- NCT6779_REG_TEMP_SOURCE[i]);
- src &= 0x1f;
- if (src && !(mask & (1 << src))) {
- data->have_temp |= 1 << i;
- mask |= 1 << src;
- }
+ if (data->temp_src[2] == 3) {
+ u8 reg;
- data->temp_src[i] = src;
+ if (data->reg_temp_config[2])
+ reg = nct6775_read_value(data,
+ data->reg_temp_config[2]);
+ else
+ reg = 0; /* Assume AUXTIN is used */
- /*
- * Now do some register swapping if index 0..2 don't
- * point to SYSTIN(1), CPUIN(2), and AUXIN(3).
- * Idea is to have the first three attributes
- * report SYSTIN, CPUIN, and AUXIN if possible
- * without overriding the basic system configuration.
- */
- if (i > 0 && data->temp_src[0] != 1
- && data->temp_src[i] == 1)
- w82627ehf_swap_tempreg(data, 0, i);
- if (i > 1 && data->temp_src[1] != 2
- && data->temp_src[i] == 2)
- w82627ehf_swap_tempreg(data, 1, i);
- if (i > 2 && data->temp_src[2] != 3
- && data->temp_src[i] == 3)
- w82627ehf_swap_tempreg(data, 2, i);
+ if (reg & 0x01)
+ data->have_temp &= ~(1 << 2);
+ else
+ data->have_in &= ~(1 << 6);
}
- data->temp_label = nct6779_temp_label;
-
+ data->temp_label = nct6776_temp_label;
+ case nct6779:
/*
* Shared pins:
* VIN4 / AUXTIN0
if (data->temp_src[i] == 6) /* AUXTIN0 */
data->have_in &= ~(1 << 14); /* no VIN7 */
}
+ data->temp_label = nct6779_temp_label;
+ break;
}
if (sio_data->kind == nct6775) {
data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
data->REG_FAN_START_OUTPUT = NCT6775_REG_FAN_START_OUTPUT;
data->REG_FAN_STOP_OUTPUT = NCT6775_REG_FAN_STOP_OUTPUT;
- data->REG_FAN_MAX_OUTPUT = NCT6775_REG_FAN_MAX_OUTPUT;
- data->REG_FAN_STEP_OUTPUT = NCT6775_REG_FAN_STEP_OUTPUT;
} else if (sio_data->kind == nct6776) {
data->has_fan_div = false;
data->fan_from_reg = fan_from_reg13;
goto exit_remove;
}
- if (data->REG_FAN_STEP_OUTPUT) {
- for (i = 0; i < ARRAY_SIZE(sda_sf3_max_step_arrays); i++) {
- struct sensor_device_attribute *attr =
- &sda_sf3_max_step_arrays[i];
- if (!(data->has_pwm & (1 << attr->index)))
- continue;
- err = device_create_file(dev, &attr->dev_attr);
- if (err)
- goto exit_remove;
- }
- }
-
for (i = 0; i < data->in_num; i++) {
if (!(data->have_in & (1 << i)))
continue;
err = device_create_file(dev, &sda_temp_input[i].dev_attr);
if (err)
goto exit_remove;
+ if (i > 5)
+ continue;
if (data->temp_label) {
err = device_create_file(dev,
&sda_temp_label[i].dev_attr);