-#define fan_functions(reg, REG) \
-static ssize_t show_##reg(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->reg[nr]); \
-} \
-static ssize_t \
-store_##reg(struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct nct6775_data *data = dev_get_drvdata(dev); \
- struct sensor_device_attribute *sensor_attr = \
- to_sensor_dev_attr(attr); \
- int nr = sensor_attr->index; \
- unsigned long val; \
- int err; \
- err = kstrtoul(buf, 10, &val); \
- if (err < 0) \
- return err; \
- val = SENSORS_LIMIT(val, 1, 255); \
- mutex_lock(&data->update_lock); \
- data->reg[nr] = val; \
- nct6775_write_value(data, data->REG_##REG[nr], val); \
- mutex_unlock(&data->update_lock); \
- return count; \
-}
-
-fan_functions(fan_start_output, FAN_START_OUTPUT)
-fan_functions(fan_stop_output, FAN_STOP_OUTPUT)
-
-#define fan_step_functions(reg, REG) \
-static ssize_t show_##reg(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", \
- step_time_from_reg(data->reg[nr], \
- data->pwm_mode[nr])); \
-} \
-static ssize_t store_##reg(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct nct6775_data *data = dev_get_drvdata(dev); \
- struct sensor_device_attribute *sensor_attr = \
- to_sensor_dev_attr(attr); \
- int nr = sensor_attr->index; \
- unsigned long val; \
- int err; \
- err = kstrtoul(buf, 10, &val); \
- if (err < 0) \
- return err; \
- val = step_time_to_reg(val, data->pwm_mode[nr]); \
- mutex_lock(&data->update_lock); \
- data->reg[nr] = val; \
- nct6775_write_value(data, NCT6775_REG_##REG[nr], val); \
- mutex_unlock(&data->update_lock); \
- return count; \
-}
-
-fan_step_functions(fan_stop_time, FAN_STOP_TIME)
-fan_step_functions(fan_step_up_time, FAN_STEP_UP_TIME)
-fan_step_functions(fan_step_down_time, FAN_STEP_DOWN_TIME)
-
-static ssize_t show_name(struct device *dev, struct device_attribute *attr,
- char *buf)
+static ssize_t
+show_pwm_sel_enable(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);
+
+ return sprintf(buf, "%d\n",
+ data->pwm_sel_enable[sattr->index][sattr->nr]);
+}
+
+static ssize_t
+store_pwm_sel_enable(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct nct6775_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ int nr = sattr->nr;
+ int index = sattr->index;
+ unsigned long val;
+ int err;
+ u8 reg;
+ static const u8 bit[] = { 0x80, 0x80, 0x01 };
+
+
+ err = kstrtoul(buf, 10, &val);
+ if (err < 0)
+ return err;
+
+ if (val > 1)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->pwm_sel_enable[index][nr] = val;
+ reg = nct6775_read_value(data, data->REG_TEMP_SEL[index][nr]);
+ reg &= ~bit[index];
+ if (val)
+ reg |= bit[index];
+ nct6775_write_value(data, data->REG_TEMP_SEL[index][nr], reg);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+show_weight_temp(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);
+ int nr = sattr->nr;
+ int index = sattr->index;
+
+ return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000);
+}
+
+static ssize_t
+store_weight_temp(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct nct6775_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ int nr = sattr->nr;
+ int index = sattr->index;
+ unsigned long val;
+ int err;
+
+ err = kstrtoul(buf, 10, &val);
+ if (err < 0)
+ return err;
+
+ val = SENSORS_LIMIT(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
+
+ mutex_lock(&data->update_lock);
+ data->weight_temp[index][nr] = val;
+ nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR_2(pwm1_stop_output_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 0, 0);
+static SENSOR_DEVICE_ATTR_2(pwm2_stop_output_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 1, 0);
+static SENSOR_DEVICE_ATTR_2(pwm3_stop_output_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 2, 0);
+static SENSOR_DEVICE_ATTR_2(pwm4_stop_output_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 3, 0);
+static SENSOR_DEVICE_ATTR_2(pwm5_stop_output_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 4, 0);
+
+static SENSOR_DEVICE_ATTR_2(pwm1_weight_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 0, 1);
+static SENSOR_DEVICE_ATTR_2(pwm2_weight_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 1, 1);
+static SENSOR_DEVICE_ATTR_2(pwm3_weight_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 2, 1);
+static SENSOR_DEVICE_ATTR_2(pwm4_weight_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 3, 1);
+static SENSOR_DEVICE_ATTR_2(pwm5_weight_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 4, 1);
+
+static SENSOR_DEVICE_ATTR_2(pwm1_step_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 0, 2);
+static SENSOR_DEVICE_ATTR_2(pwm2_step_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 1, 2);
+static SENSOR_DEVICE_ATTR_2(pwm3_step_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 2, 2);
+static SENSOR_DEVICE_ATTR_2(pwm4_step_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 3, 2);
+static SENSOR_DEVICE_ATTR_2(pwm5_step_enable, S_IWUSR | S_IRUGO,
+ show_pwm_sel_enable, store_pwm_sel_enable, 4, 2);
+
+static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_sel, S_IWUSR | S_IRUGO,
+ show_pwm_temp_sel, store_pwm_temp_sel, 0, 1);
+static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_sel, S_IWUSR | S_IRUGO,
+ show_pwm_temp_sel, store_pwm_temp_sel, 1, 1);
+static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_sel, S_IWUSR | S_IRUGO,
+ show_pwm_temp_sel, store_pwm_temp_sel, 2, 1);
+static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_sel, S_IWUSR | S_IRUGO,
+ show_pwm_temp_sel, store_pwm_temp_sel, 3, 1);
+static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_sel, S_IWUSR | S_IRUGO,
+ show_pwm_temp_sel, store_pwm_temp_sel, 4, 1);
+
+static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 0, 0);
+static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 1, 0);
+static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 2, 0);
+static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 3, 0);
+static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 4, 0);
+
+static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_tol, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 0, 1);
+static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_tol, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 1, 1);
+static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_tol, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 2, 1);
+static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_tol, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 3, 1);
+static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_tol, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 4, 1);
+
+static SENSOR_DEVICE_ATTR_2(pwm1_weight_temp_step_base, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 0, 2);
+static SENSOR_DEVICE_ATTR_2(pwm2_weight_temp_step_base, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 1, 2);
+static SENSOR_DEVICE_ATTR_2(pwm3_weight_temp_step_base, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 2, 2);
+static SENSOR_DEVICE_ATTR_2(pwm4_weight_temp_step_base, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 3, 2);
+static SENSOR_DEVICE_ATTR_2(pwm5_weight_temp_step_base, S_IWUSR | S_IRUGO,
+ show_weight_temp, store_weight_temp, 4, 2);
+
+static SENSOR_DEVICE_ATTR_2(pwm1_weight_duty_step, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 0, 5);
+static SENSOR_DEVICE_ATTR_2(pwm2_weight_duty_step, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 1, 5);
+static SENSOR_DEVICE_ATTR_2(pwm3_weight_duty_step, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 2, 5);
+static SENSOR_DEVICE_ATTR_2(pwm4_weight_duty_step, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 3, 5);
+static SENSOR_DEVICE_ATTR_2(pwm5_weight_duty_step, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 4, 5);
+
+/* duty_base is not supported on all chips */
+static struct sensor_device_attribute_2 sda_weight_duty_base[] = {
+ SENSOR_ATTR_2(pwm1_weight_duty_base, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 0, 6),
+ SENSOR_ATTR_2(pwm2_weight_duty_base, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 1, 6),
+ SENSOR_ATTR_2(pwm3_weight_duty_base, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 2, 6),
+ SENSOR_ATTR_2(pwm4_weight_duty_base, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 3, 6),
+ SENSOR_ATTR_2(pwm5_weight_duty_base, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 4, 6),
+};
+
+static ssize_t
+show_fan_time(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);
+ int nr = sattr->nr;
+ int index = sattr->index;
+
+ return sprintf(buf, "%d\n",
+ step_time_from_reg(data->fan_time[index][nr],
+ data->pwm_mode[nr]));
+}
+
+static ssize_t
+store_fan_time(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct nct6775_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ int nr = sattr->nr;
+ int index = sattr->index;
+ unsigned long val;
+ int err;
+
+ err = kstrtoul(buf, 10, &val);
+ if (err < 0)
+ return err;
+
+ val = step_time_to_reg(val, data->pwm_mode[nr]);
+ mutex_lock(&data->update_lock);
+ data->fan_time[index][nr] = val;
+ nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+show_name(struct device *dev, struct device_attribute *attr, char *buf)