+#define show_pwm_reg(reg) \
+static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct w83627ehf_data *data = w83627ehf_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]); \
+}
+
+show_pwm_reg(pwm_mode)
+show_pwm_reg(pwm_enable)
+show_pwm_reg(pwm)
+
+static ssize_t
+store_pwm_mode(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83627ehf_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+ u32 val = simple_strtoul(buf, NULL, 10);
+ u16 reg;
+
+ if (val > 1)
+ return -EINVAL;
+ mutex_lock(&data->update_lock);
+ reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]);
+ data->pwm_mode[nr] = val;
+ reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]);
+ if (!val)
+ reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr];
+ w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+store_pwm(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83627ehf_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+ u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255);
+
+ mutex_lock(&data->update_lock);
+ data->pwm[nr] = val;
+ w83627ehf_write_value(client, W83627EHF_REG_PWM[nr], val);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+store_pwm_enable(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83627ehf_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+ u32 val = simple_strtoul(buf, NULL, 10);
+ u16 reg;
+
+ if (!val || (val > 2)) /* only modes 1 and 2 are supported */
+ return -EINVAL;
+ mutex_lock(&data->update_lock);
+ reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]);
+ data->pwm_enable[nr] = val;
+ reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]);
+ reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr];
+ w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+
+#define show_tol_temp(reg) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct w83627ehf_data *data = w83627ehf_update_device(dev); \
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+ int nr = sensor_attr->index; \
+ return sprintf(buf, "%d\n", temp1_from_reg(data->reg[nr])); \
+}
+
+show_tol_temp(tolerance)
+show_tol_temp(target_temp)
+
+static ssize_t
+store_target_temp(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83627ehf_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+ u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000);
+
+ mutex_lock(&data->update_lock);
+ data->target_temp[nr] = val;
+ w83627ehf_write_value(client, W83627EHF_REG_TARGET[nr], val);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+store_tolerance(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83627ehf_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+ u16 reg;
+ /* Limit the temp to 0C - 15C */
+ u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000);
+
+ mutex_lock(&data->update_lock);
+ reg = w83627ehf_read_value(client, W83627EHF_REG_TOLERANCE[nr]);
+ data->tolerance[nr] = val;
+ if (nr == 1)
+ reg = (reg & 0x0f) | (val << 4);
+ else
+ reg = (reg & 0xf0) | val;
+ w83627ehf_write_value(client, W83627EHF_REG_TOLERANCE[nr], reg);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static struct sensor_device_attribute sda_pwm[] = {
+ SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0),
+ SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1),
+ SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2),
+ SENSOR_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3),
+};
+
+static struct sensor_device_attribute sda_pwm_mode[] = {
+ SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
+ store_pwm_mode, 0),
+ SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
+ store_pwm_mode, 1),
+ SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
+ store_pwm_mode, 2),
+ SENSOR_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
+ store_pwm_mode, 3),
+};
+
+static struct sensor_device_attribute sda_pwm_enable[] = {
+ SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+ store_pwm_enable, 0),
+ SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+ store_pwm_enable, 1),
+ SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+ store_pwm_enable, 2),
+ SENSOR_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
+ store_pwm_enable, 3),
+};
+
+static struct sensor_device_attribute sda_target_temp[] = {
+ SENSOR_ATTR(pwm1_target, S_IWUSR | S_IRUGO, show_target_temp,
+ store_target_temp, 0),
+ SENSOR_ATTR(pwm2_target, S_IWUSR | S_IRUGO, show_target_temp,
+ store_target_temp, 1),
+ SENSOR_ATTR(pwm3_target, S_IWUSR | S_IRUGO, show_target_temp,
+ store_target_temp, 2),
+ SENSOR_ATTR(pwm4_target, S_IWUSR | S_IRUGO, show_target_temp,
+ store_target_temp, 3),
+};
+
+static struct sensor_device_attribute sda_tolerance[] = {
+ SENSOR_ATTR(pwm1_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
+ store_tolerance, 0),
+ SENSOR_ATTR(pwm2_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
+ store_tolerance, 1),
+ SENSOR_ATTR(pwm3_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
+ store_tolerance, 2),
+ SENSOR_ATTR(pwm4_tolerance, S_IWUSR | S_IRUGO, show_tolerance,
+ store_tolerance, 3),
+};
+
+static void device_create_file_pwm(struct device *dev, int i)
+{
+ device_create_file(dev, &sda_pwm[i].dev_attr);
+ device_create_file(dev, &sda_pwm_mode[i].dev_attr);
+ device_create_file(dev, &sda_pwm_enable[i].dev_attr);
+ device_create_file(dev, &sda_target_temp[i].dev_attr);
+ device_create_file(dev, &sda_tolerance[i].dev_attr);
+}
+
+/* Smart Fan registers */
+
+#define fan_functions(reg, REG) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct w83627ehf_data *data = w83627ehf_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 i2c_client *client = to_i2c_client(dev); \
+ struct w83627ehf_data *data = i2c_get_clientdata(client); \
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+ int nr = sensor_attr->index; \
+ u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \
+ mutex_lock(&data->update_lock); \
+ data->reg[nr] = val; \
+ w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \
+ mutex_unlock(&data->update_lock); \
+ return count; \
+}
+
+fan_functions(fan_min_output, FAN_MIN_OUTPUT)
+
+#define fan_time_functions(reg, REG) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct w83627ehf_data *data = w83627ehf_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 i2c_client *client = to_i2c_client(dev); \
+ struct w83627ehf_data *data = i2c_get_clientdata(client); \
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+ int nr = sensor_attr->index; \
+ u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \
+ data->pwm_mode[nr]); \
+ mutex_lock(&data->update_lock); \
+ data->reg[nr] = val; \
+ w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \
+ mutex_unlock(&data->update_lock); \
+ return count; \
+} \
+
+fan_time_functions(fan_stop_time, FAN_STOP_TIME)
+
+
+static struct sensor_device_attribute sda_sf3_arrays_fan4[] = {
+ SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
+ store_fan_stop_time, 3),
+ SENSOR_ATTR(pwm4_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
+ store_fan_min_output, 3),
+};
+
+static struct sensor_device_attribute sda_sf3_arrays[] = {
+ SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
+ store_fan_stop_time, 0),
+ SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
+ store_fan_stop_time, 1),
+ SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
+ store_fan_stop_time, 2),
+ SENSOR_ATTR(pwm1_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
+ store_fan_min_output, 0),
+ SENSOR_ATTR(pwm2_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
+ store_fan_min_output, 1),
+ SENSOR_ATTR(pwm3_min_output, S_IWUSR | S_IRUGO, show_fan_min_output,
+ store_fan_min_output, 2),
+};
+