Commit 266cd583 authored by Dr. David Alan Gilbert's avatar Dr. David Alan Gilbert Committed by Guenter Roeck

hwmon: (w83627ehf) convert to with_info interface

Convert the old hwmon_device_register code to
devm_hwmon_device_register_with_info.
Signed-off-by: default avatarDr. David Alan Gilbert <linux@treblig.org>
Link: https://lore.kernel.org/r/20191124202030.45360-3-linux@treblig.orgSigned-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent a470f11c
...@@ -417,8 +417,8 @@ static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scale_in) ...@@ -417,8 +417,8 @@ static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scale_in)
struct w83627ehf_data { struct w83627ehf_data {
int addr; /* IO base of hw monitor block */ int addr; /* IO base of hw monitor block */
const char *name; const char *name;
enum kinds kind; /* Convenience copy of sio_data->kind */
struct device *hwmon_dev;
struct mutex lock; struct mutex lock;
u16 reg_temp[NUM_REG_TEMP]; u16 reg_temp[NUM_REG_TEMP];
...@@ -494,6 +494,7 @@ struct w83627ehf_data { ...@@ -494,6 +494,7 @@ struct w83627ehf_data {
u16 have_temp_offset; u16 have_temp_offset;
u8 in6_skip:1; u8 in6_skip:1;
u8 temp3_val_only:1; u8 temp3_val_only:1;
u8 have_vid:1;
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* Remember extra register values over suspend/resume */ /* Remember extra register values over suspend/resume */
...@@ -666,11 +667,9 @@ static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr) ...@@ -666,11 +667,9 @@ static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr)
static void w83627ehf_write_fan_div_common(struct device *dev, static void w83627ehf_write_fan_div_common(struct device *dev,
struct w83627ehf_data *data, int nr) struct w83627ehf_data *data, int nr)
{ {
struct w83627ehf_sio_data *sio_data = dev_get_platdata(dev); if (data->kind == nct6776)
if (sio_data->kind == nct6776)
; /* no dividers, do nothing */ ; /* no dividers, do nothing */
else if (sio_data->kind == nct6775) else if (data->kind == nct6775)
nct6775_write_fan_div(data, nr); nct6775_write_fan_div(data, nr);
else else
w83627ehf_write_fan_div(data, nr); w83627ehf_write_fan_div(data, nr);
...@@ -717,11 +716,9 @@ static void w83627ehf_update_fan_div(struct w83627ehf_data *data) ...@@ -717,11 +716,9 @@ static void w83627ehf_update_fan_div(struct w83627ehf_data *data)
static void w83627ehf_update_fan_div_common(struct device *dev, static void w83627ehf_update_fan_div_common(struct device *dev,
struct w83627ehf_data *data) struct w83627ehf_data *data)
{ {
struct w83627ehf_sio_data *sio_data = dev_get_platdata(dev); if (data->kind == nct6776)
if (sio_data->kind == nct6776)
; /* no dividers, do nothing */ ; /* no dividers, do nothing */
else if (sio_data->kind == nct6775) else if (data->kind == nct6775)
nct6775_update_fan_div(data); nct6775_update_fan_div(data);
else else
w83627ehf_update_fan_div(data); w83627ehf_update_fan_div(data);
...@@ -786,7 +783,6 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) ...@@ -786,7 +783,6 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
{ {
struct w83627ehf_data *data = dev_get_drvdata(dev); struct w83627ehf_data *data = dev_get_drvdata(dev);
struct w83627ehf_sio_data *sio_data = dev_get_platdata(dev); struct w83627ehf_sio_data *sio_data = dev_get_platdata(dev);
int i; int i;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
...@@ -923,156 +919,33 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) ...@@ -923,156 +919,33 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
return data; return data;
} }
/*
* Sysfs callback functions
*/
#define show_in_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, "%ld\n", in_from_reg(data->reg[nr], nr, \
data->scale_in)); \
}
show_in_reg(in)
show_in_reg(in_min)
show_in_reg(in_max)
#define store_in_reg(REG, reg) \ #define store_in_reg(REG, reg) \
static ssize_t \ static int \
store_in_##reg(struct device *dev, struct device_attribute *attr, \ store_in_##reg(struct device *dev, struct w83627ehf_data *data, int channel, \
const char *buf, size_t count) \ long val) \
{ \ { \
struct w83627ehf_data *data = dev_get_drvdata(dev); \ if (val < 0) \
struct sensor_device_attribute *sensor_attr = \ return -EINVAL; \
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; \
mutex_lock(&data->update_lock); \ mutex_lock(&data->update_lock); \
data->in_##reg[nr] = in_to_reg(val, nr, data->scale_in); \ data->in_##reg[channel] = in_to_reg(val, channel, data->scale_in); \
w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \ w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(channel), \
data->in_##reg[nr]); \ data->in_##reg[channel]); \
mutex_unlock(&data->update_lock); \ mutex_unlock(&data->update_lock); \
return count; \ return 0; \
} }
store_in_reg(MIN, min) store_in_reg(MIN, min)
store_in_reg(MAX, max) store_in_reg(MAX, max)
static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, static int
char *buf) store_fan_min(struct device *dev, struct w83627ehf_data *data, int channel,
{ long val)
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, "%u\n", (data->alarms >> nr) & 0x01);
}
static struct sensor_device_attribute sda_in_input[] = {
SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9),
};
static struct sensor_device_attribute sda_in_alarm[] = {
SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0),
SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1),
SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2),
SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3),
SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8),
SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 21),
SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 20),
SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16),
SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17),
SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 19),
};
static struct sensor_device_attribute sda_in_min[] = {
SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0),
SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1),
SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2),
SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3),
SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4),
SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5),
SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6),
SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7),
SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8),
SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9),
};
static struct sensor_device_attribute sda_in_max[] = {
SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0),
SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1),
SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2),
SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3),
SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4),
SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5),
SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6),
SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7),
SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8),
SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9),
};
static ssize_t
show_fan(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->rpm[nr]);
}
static ssize_t
show_fan_min(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->fan_from_reg_min(data->fan_min[nr],
data->fan_div[nr]));
}
static ssize_t
show_fan_div(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, "%u\n", div_from_reg(data->fan_div[nr]));
}
static ssize_t
store_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ {
struct w83627ehf_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;
unsigned int reg; unsigned int reg;
u8 new_div; u8 new_div;
err = kstrtoul(buf, 10, &val); if (val < 0)
if (err < 0) return -EINVAL;
return err;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
if (!data->has_fan_div) { if (!data->has_fan_div) {
...@@ -1088,34 +961,35 @@ store_fan_min(struct device *dev, struct device_attribute *attr, ...@@ -1088,34 +961,35 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
val = 1350000U / val; val = 1350000U / val;
val = (val & 0x1f) | ((val << 3) & 0xff00); val = (val & 0x1f) | ((val << 3) & 0xff00);
} }
data->fan_min[nr] = val; data->fan_min[channel] = val;
goto done; /* Leave fan divider alone */ goto done; /* Leave fan divider alone */
} }
if (!val) { if (!val) {
/* No min limit, alarm disabled */ /* No min limit, alarm disabled */
data->fan_min[nr] = 255; data->fan_min[channel] = 255;
new_div = data->fan_div[nr]; /* No change */ new_div = data->fan_div[channel]; /* No change */
dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1); dev_info(dev, "fan%u low limit and alarm disabled\n",
channel + 1);
} else if ((reg = 1350000U / val) >= 128 * 255) { } else if ((reg = 1350000U / val) >= 128 * 255) {
/* /*
* Speed below this value cannot possibly be represented, * Speed below this value cannot possibly be represented,
* even with the highest divider (128) * even with the highest divider (128)
*/ */
data->fan_min[nr] = 254; data->fan_min[channel] = 254;
new_div = 7; /* 128 == (1 << 7) */ new_div = 7; /* 128 == (1 << 7) */
dev_warn(dev, dev_warn(dev,
"fan%u low limit %lu below minimum %u, set to minimum\n", "fan%u low limit %lu below minimum %u, set to minimum\n",
nr + 1, val, data->fan_from_reg_min(254, 7)); channel + 1, val, data->fan_from_reg_min(254, 7));
} else if (!reg) { } else if (!reg) {
/* /*
* Speed above this value cannot possibly be represented, * Speed above this value cannot possibly be represented,
* even with the lowest divider (1) * even with the lowest divider (1)
*/ */
data->fan_min[nr] = 1; data->fan_min[channel] = 1;
new_div = 0; /* 1 == (1 << 0) */ new_div = 0; /* 1 == (1 << 0) */
dev_warn(dev, dev_warn(dev,
"fan%u low limit %lu above maximum %u, set to maximum\n", "fan%u low limit %lu above maximum %u, set to maximum\n",
nr + 1, val, data->fan_from_reg_min(1, 0)); channel + 1, val, data->fan_from_reg_min(1, 0));
} else { } else {
/* /*
* Automatically pick the best divider, i.e. the one such * Automatically pick the best divider, i.e. the one such
...@@ -1127,362 +1001,133 @@ store_fan_min(struct device *dev, struct device_attribute *attr, ...@@ -1127,362 +1001,133 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
reg >>= 1; reg >>= 1;
new_div++; new_div++;
} }
data->fan_min[nr] = reg; data->fan_min[channel] = reg;
} }
/* /*
* Write both the fan clock divider (if it changed) and the new * Write both the fan clock divider (if it changed) and the new
* fan min (unconditionally) * fan min (unconditionally)
*/ */
if (new_div != data->fan_div[nr]) { if (new_div != data->fan_div[channel]) {
dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
nr + 1, div_from_reg(data->fan_div[nr]), channel + 1, div_from_reg(data->fan_div[channel]),
div_from_reg(new_div)); div_from_reg(new_div));
data->fan_div[nr] = new_div; data->fan_div[channel] = new_div;
w83627ehf_write_fan_div_common(dev, data, nr); w83627ehf_write_fan_div_common(dev, data, channel);
/* Give the chip time to sample a new speed value */ /* Give the chip time to sample a new speed value */
data->last_updated = jiffies; data->last_updated = jiffies;
} }
done: done:
w83627ehf_write_value(data, data->REG_FAN_MIN[nr], w83627ehf_write_value(data, data->REG_FAN_MIN[channel],
data->fan_min[nr]); data->fan_min[channel]);
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return 0;
}
static struct sensor_device_attribute sda_fan_input[] = {
SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
};
static struct sensor_device_attribute sda_fan_alarm[] = {
SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6),
SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7),
SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11),
SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 10),
SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 23),
};
static struct sensor_device_attribute sda_fan_min[] = {
SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 0),
SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 1),
SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 2),
SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 3),
SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 4),
};
static struct sensor_device_attribute sda_fan_div[] = {
SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3),
SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
};
static ssize_t
show_temp_label(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, "%s\n", data->temp_label[data->temp_src[nr]]);
}
#define show_temp_reg(addr, 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", LM75_TEMP_FROM_REG(data->reg[nr])); \
} }
show_temp_reg(reg_temp, temp);
show_temp_reg(reg_temp_over, temp_max);
show_temp_reg(reg_temp_hyst, temp_max_hyst);
#define store_temp_reg(addr, reg) \ #define store_temp_reg(addr, reg) \
static ssize_t \ static int \
store_##reg(struct device *dev, struct device_attribute *attr, \ store_##reg(struct device *dev, struct w83627ehf_data *data, int channel, \
const char *buf, size_t count) \ long val) \
{ \ { \
struct w83627ehf_data *data = dev_get_drvdata(dev); \
struct sensor_device_attribute *sensor_attr = \
to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \
int err; \
long val; \
err = kstrtol(buf, 10, &val); \
if (err < 0) \
return err; \
mutex_lock(&data->update_lock); \ mutex_lock(&data->update_lock); \
data->reg[nr] = LM75_TEMP_TO_REG(val); \ data->reg[channel] = LM75_TEMP_TO_REG(val); \
w83627ehf_write_temp(data, data->addr[nr], data->reg[nr]); \ w83627ehf_write_temp(data, data->addr[channel], data->reg[channel]); \
mutex_unlock(&data->update_lock); \ mutex_unlock(&data->update_lock); \
return count; \ return 0; \
} }
store_temp_reg(reg_temp_over, temp_max); store_temp_reg(reg_temp_over, temp_max);
store_temp_reg(reg_temp_hyst, temp_max_hyst); store_temp_reg(reg_temp_hyst, temp_max_hyst);
static ssize_t static int
show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf) store_temp_offset(struct device *dev, struct w83627ehf_data *data, int channel,
long val)
{ {
struct w83627ehf_data *data = w83627ehf_update_device(dev);
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
return sprintf(buf, "%d\n",
data->temp_offset[sensor_attr->index] * 1000);
}
static ssize_t
store_temp_offset(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct w83627ehf_data *data = dev_get_drvdata(dev);
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
long val;
int err;
err = kstrtol(buf, 10, &val);
if (err < 0)
return err;
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
data->temp_offset[nr] = val; data->temp_offset[channel] = val;
w83627ehf_write_value(data, W83627EHF_REG_TEMP_OFFSET[nr], val); w83627ehf_write_value(data, W83627EHF_REG_TEMP_OFFSET[channel], val);
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return 0;
}
static ssize_t
show_temp_type(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", (int)data->temp_type[nr]);
}
static struct sensor_device_attribute sda_temp_input[] = {
SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0),
SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1),
SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2),
SENSOR_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3),
SENSOR_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4),
SENSOR_ATTR(temp6_input, S_IRUGO, show_temp, NULL, 5),
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),
};
static struct sensor_device_attribute sda_temp_label[] = {
SENSOR_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0),
SENSOR_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1),
SENSOR_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2),
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[] = {
SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 0),
SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 1),
SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 2),
SENSOR_ATTR(temp4_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 3),
SENSOR_ATTR(temp5_max, S_IRUGO | S_IWUSR, show_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[] = {
SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 0),
SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 1),
SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 2),
SENSOR_ATTR(temp4_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 3),
SENSOR_ATTR(temp5_max_hyst, S_IRUGO | S_IWUSR, show_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[] = {
SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4),
SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5),
SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),
};
static struct sensor_device_attribute sda_temp_type[] = {
SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
};
static struct sensor_device_attribute sda_temp_offset[] = {
SENSOR_ATTR(temp1_offset, S_IRUGO | S_IWUSR, show_temp_offset,
store_temp_offset, 0),
SENSOR_ATTR(temp2_offset, S_IRUGO | S_IWUSR, show_temp_offset,
store_temp_offset, 1),
SENSOR_ATTR(temp3_offset, S_IRUGO | S_IWUSR, show_temp_offset,
store_temp_offset, 2),
};
#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) static int
show_pwm_reg(pwm_enable) store_pwm_mode(struct device *dev, struct w83627ehf_data *data, int channel,
show_pwm_reg(pwm) long val)
static ssize_t
store_pwm_mode(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ {
struct w83627ehf_data *data = dev_get_drvdata(dev);
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
struct w83627ehf_sio_data *sio_data = dev_get_platdata(dev);
int nr = sensor_attr->index;
unsigned long val;
int err;
u16 reg; u16 reg;
err = kstrtoul(buf, 10, &val); if (val < 0 || val > 1)
if (err < 0)
return err;
if (val > 1)
return -EINVAL; return -EINVAL;
/* On NCT67766F, DC mode is only supported for pwm1 */ /* On NCT67766F, DC mode is only supported for pwm1 */
if (sio_data->kind == nct6776 && nr && val != 1) if (data->kind == nct6776 && channel && val != 1)
return -EINVAL; return -EINVAL;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[channel]);
data->pwm_mode[nr] = val; data->pwm_mode[channel] = val;
reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[channel]);
if (!val) if (!val)
reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; reg |= 1 << W83627EHF_PWM_MODE_SHIFT[channel];
w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[channel], reg);
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return 0;
} }
static ssize_t static int
store_pwm(struct device *dev, struct device_attribute *attr, store_pwm(struct device *dev, struct w83627ehf_data *data, int channel,
const char *buf, size_t count) long val)
{ {
struct w83627ehf_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 = clamp_val(val, 0, 255); val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
data->pwm[nr] = val; data->pwm[channel] = val;
w83627ehf_write_value(data, data->REG_PWM[nr], val); w83627ehf_write_value(data, data->REG_PWM[channel], val);
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return 0;
} }
static ssize_t static int
store_pwm_enable(struct device *dev, struct device_attribute *attr, store_pwm_enable(struct device *dev, struct w83627ehf_data *data, int channel,
const char *buf, size_t count) long val)
{ {
struct w83627ehf_data *data = dev_get_drvdata(dev);
struct w83627ehf_sio_data *sio_data = dev_get_platdata(dev);
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
unsigned long val;
int err;
u16 reg; u16 reg;
err = kstrtoul(buf, 10, &val); if (!val || val < 0 ||
if (err < 0) (val > 4 && val != data->pwm_enable_orig[channel]))
return err;
if (!val || (val > 4 && val != data->pwm_enable_orig[nr]))
return -EINVAL; return -EINVAL;
/* SmartFan III mode is not supported on NCT6776F */ /* SmartFan III mode is not supported on NCT6776F */
if (sio_data->kind == nct6776 && val == 4) if (data->kind == nct6776 && val == 4)
return -EINVAL; return -EINVAL;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
data->pwm_enable[nr] = val; data->pwm_enable[channel] = val;
if (sio_data->kind == nct6775 || sio_data->kind == nct6776) { if (data->kind == nct6775 || data->kind == nct6776) {
reg = w83627ehf_read_value(data, reg = w83627ehf_read_value(data,
NCT6775_REG_FAN_MODE[nr]); NCT6775_REG_FAN_MODE[channel]);
reg &= 0x0f; reg &= 0x0f;
reg |= (val - 1) << 4; reg |= (val - 1) << 4;
w83627ehf_write_value(data, w83627ehf_write_value(data,
NCT6775_REG_FAN_MODE[nr], reg); NCT6775_REG_FAN_MODE[channel], reg);
} else { } else {
reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); reg = w83627ehf_read_value(data,
reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); W83627EHF_REG_PWM_ENABLE[channel]);
reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[channel]);
w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[channel];
w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[channel],
reg);
} }
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return 0;
} }
#define show_tol_temp(reg) \ #define show_tol_temp(reg) \
static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
char *buf) \ char *buf) \
{ \ { \
struct w83627ehf_data *data = w83627ehf_update_device(dev); \ struct w83627ehf_data *data = w83627ehf_update_device(dev->parent); \
struct sensor_device_attribute *sensor_attr = \ struct sensor_device_attribute *sensor_attr = \
to_sensor_dev_attr(attr); \ to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \ int nr = sensor_attr->index; \
...@@ -1520,7 +1165,6 @@ store_tolerance(struct device *dev, struct device_attribute *attr, ...@@ -1520,7 +1165,6 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct w83627ehf_data *data = dev_get_drvdata(dev); struct w83627ehf_data *data = dev_get_drvdata(dev);
struct w83627ehf_sio_data *sio_data = dev_get_platdata(dev);
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index; int nr = sensor_attr->index;
u16 reg; u16 reg;
...@@ -1535,9 +1179,9 @@ store_tolerance(struct device *dev, struct device_attribute *attr, ...@@ -1535,9 +1179,9 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 15); val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 15);
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
if (sio_data->kind == nct6775 || sio_data->kind == nct6776) { if (data->kind == nct6775 || data->kind == nct6776) {
/* Limit tolerance further for NCT6776F */ /* Limit tolerance further for NCT6776F */
if (sio_data->kind == nct6776 && val > 7) if (data->kind == nct6776 && val > 7)
val = 7; val = 7;
reg = w83627ehf_read_value(data, NCT6775_REG_FAN_MODE[nr]); reg = w83627ehf_read_value(data, NCT6775_REG_FAN_MODE[nr]);
reg = (reg & 0xf0) | val; reg = (reg & 0xf0) | val;
...@@ -1555,56 +1199,23 @@ store_tolerance(struct device *dev, struct device_attribute *attr, ...@@ -1555,56 +1199,23 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
return count; return count;
} }
static struct sensor_device_attribute sda_pwm[] = { SENSOR_DEVICE_ATTR(pwm1_target, 0644, show_target_temp,
SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0), store_target_temp, 0);
SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), SENSOR_DEVICE_ATTR(pwm2_target, 0644, show_target_temp,
SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2), store_target_temp, 1);
SENSOR_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3), SENSOR_DEVICE_ATTR(pwm3_target, 0644, show_target_temp,
}; store_target_temp, 2);
SENSOR_DEVICE_ATTR(pwm4_target, 0644, show_target_temp,
static struct sensor_device_attribute sda_pwm_mode[] = { store_target_temp, 3);
SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
store_pwm_mode, 0), SENSOR_DEVICE_ATTR(pwm1_tolerance, 0644, show_tolerance,
SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode, store_tolerance, 0);
store_pwm_mode, 1), SENSOR_DEVICE_ATTR(pwm2_tolerance, 0644, show_tolerance,
SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode, store_tolerance, 1);
store_pwm_mode, 2), SENSOR_DEVICE_ATTR(pwm3_tolerance, 0644, show_tolerance,
SENSOR_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode, store_tolerance, 2);
store_pwm_mode, 3), SENSOR_DEVICE_ATTR(pwm4_tolerance, 0644, show_tolerance,
}; store_tolerance, 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),
};
/* Smart Fan registers */ /* Smart Fan registers */
...@@ -1612,7 +1223,7 @@ static struct sensor_device_attribute sda_tolerance[] = { ...@@ -1612,7 +1223,7 @@ static struct sensor_device_attribute sda_tolerance[] = {
static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
char *buf) \ char *buf) \
{ \ { \
struct w83627ehf_data *data = w83627ehf_update_device(dev); \ struct w83627ehf_data *data = w83627ehf_update_device(dev->parent); \
struct sensor_device_attribute *sensor_attr = \ struct sensor_device_attribute *sensor_attr = \
to_sensor_dev_attr(attr); \ to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \ int nr = sensor_attr->index; \
...@@ -1648,7 +1259,7 @@ fan_functions(fan_step_output, FAN_STEP_OUTPUT) ...@@ -1648,7 +1259,7 @@ fan_functions(fan_step_output, FAN_STEP_OUTPUT)
static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
char *buf) \ char *buf) \
{ \ { \
struct w83627ehf_data *data = w83627ehf_update_device(dev); \ struct w83627ehf_data *data = w83627ehf_update_device(dev->parent); \
struct sensor_device_attribute *sensor_attr = \ struct sensor_device_attribute *sensor_attr = \
to_sensor_dev_attr(attr); \ to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \ int nr = sensor_attr->index; \
...@@ -1680,71 +1291,54 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ ...@@ -1680,71 +1291,54 @@ store_##reg(struct device *dev, struct device_attribute *attr, \
fan_time_functions(fan_stop_time, FAN_STOP_TIME) fan_time_functions(fan_stop_time, FAN_STOP_TIME)
static ssize_t name_show(struct device *dev, struct device_attribute *attr, SENSOR_DEVICE_ATTR(pwm4_stop_time, 0644, show_fan_stop_time,
char *buf) store_fan_stop_time, 3);
{ SENSOR_DEVICE_ATTR(pwm4_start_output, 0644, show_fan_start_output,
struct w83627ehf_data *data = dev_get_drvdata(dev); store_fan_start_output, 3);
SENSOR_DEVICE_ATTR(pwm4_stop_output, 0644, show_fan_stop_output,
return sprintf(buf, "%s\n", data->name); store_fan_stop_output, 3);
} SENSOR_DEVICE_ATTR(pwm4_max_output, 0644, show_fan_max_output,
static DEVICE_ATTR_RO(name); store_fan_max_output, 3);
SENSOR_DEVICE_ATTR(pwm4_step_output, 0644, show_fan_step_output,
static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { store_fan_step_output, 3);
SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
store_fan_stop_time, 3), SENSOR_DEVICE_ATTR(pwm3_stop_time, 0644, show_fan_stop_time,
SENSOR_ATTR(pwm4_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, store_fan_stop_time, 2);
store_fan_start_output, 3), SENSOR_DEVICE_ATTR(pwm3_start_output, 0644, show_fan_start_output,
SENSOR_ATTR(pwm4_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, store_fan_start_output, 2);
store_fan_stop_output, 3), SENSOR_DEVICE_ATTR(pwm3_stop_output, 0644, show_fan_stop_output,
SENSOR_ATTR(pwm4_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, store_fan_stop_output, 2);
store_fan_max_output, 3),
SENSOR_ATTR(pwm4_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, SENSOR_DEVICE_ATTR(pwm1_stop_time, 0644, show_fan_stop_time,
store_fan_step_output, 3), store_fan_stop_time, 0);
}; SENSOR_DEVICE_ATTR(pwm2_stop_time, 0644, show_fan_stop_time,
store_fan_stop_time, 1);
static struct sensor_device_attribute sda_sf3_arrays_fan3[] = { SENSOR_DEVICE_ATTR(pwm1_start_output, 0644, show_fan_start_output,
SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, store_fan_start_output, 0);
store_fan_stop_time, 2), SENSOR_DEVICE_ATTR(pwm2_start_output, 0644, show_fan_start_output,
SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, store_fan_start_output, 1);
store_fan_start_output, 2), SENSOR_DEVICE_ATTR(pwm1_stop_output, 0644, show_fan_stop_output,
SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, store_fan_stop_output, 0);
store_fan_stop_output, 2), SENSOR_DEVICE_ATTR(pwm2_stop_output, 0644, show_fan_stop_output,
}; store_fan_stop_output, 1);
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(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
store_fan_start_output, 0),
SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
store_fan_start_output, 1),
SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
store_fan_stop_output, 0),
SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
store_fan_stop_output, 1),
};
/* /*
* pwm1 and pwm3 don't support max and step settings on all chips. * pwm1 and pwm3 don't support max and step settings on all chips.
* Need to check support while generating/removing attribute files. * Need to check support while generating/removing attribute files.
*/ */
static struct sensor_device_attribute sda_sf3_max_step_arrays[] = { SENSOR_DEVICE_ATTR(pwm1_max_output, 0644, show_fan_max_output,
SENSOR_ATTR(pwm1_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, store_fan_max_output, 0);
store_fan_max_output, 0), SENSOR_DEVICE_ATTR(pwm1_step_output, 0644, show_fan_step_output,
SENSOR_ATTR(pwm1_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, store_fan_step_output, 0);
store_fan_step_output, 0), SENSOR_DEVICE_ATTR(pwm2_max_output, 0644, show_fan_max_output,
SENSOR_ATTR(pwm2_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, store_fan_max_output, 1);
store_fan_max_output, 1), SENSOR_DEVICE_ATTR(pwm2_step_output, 0644, show_fan_step_output,
SENSOR_ATTR(pwm2_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, store_fan_step_output, 1);
store_fan_step_output, 1), SENSOR_DEVICE_ATTR(pwm3_max_output, 0644, show_fan_max_output,
SENSOR_ATTR(pwm3_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, store_fan_max_output, 2);
store_fan_max_output, 2), SENSOR_DEVICE_ATTR(pwm3_step_output, 0644, show_fan_step_output,
SENSOR_ATTR(pwm3_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, store_fan_step_output, 2);
store_fan_step_output, 2),
};
static ssize_t static ssize_t
cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf) cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf)
...@@ -1752,32 +1346,21 @@ cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -1752,32 +1346,21 @@ cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf)
struct w83627ehf_data *data = dev_get_drvdata(dev); struct w83627ehf_data *data = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
} }
static DEVICE_ATTR_RO(cpu0_vid); DEVICE_ATTR_RO(cpu0_vid);
/* Case open detection */ /* Case open detection */
static int
static ssize_t clear_caseopen(struct device *dev, struct w83627ehf_data *data, int channel,
show_caseopen(struct device *dev, struct device_attribute *attr, char *buf) long val)
{
struct w83627ehf_data *data = w83627ehf_update_device(dev);
return sprintf(buf, "%d\n",
!!(data->caseopen & to_sensor_dev_attr_2(attr)->index));
}
static ssize_t
clear_caseopen(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{ {
struct w83627ehf_data *data = dev_get_drvdata(dev); u16 masks[] = { 0x80, 0x40 };
unsigned long val;
u16 reg, mask; u16 reg, mask;
if (kstrtoul(buf, 10, &val) || val != 0) if (val != 0 || channel > 1)
return -EINVAL; return -EINVAL;
mask = to_sensor_dev_attr_2(attr)->nr; mask = masks[channel];
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
reg = w83627ehf_read_value(data, W83627EHF_REG_CASEOPEN_CLR); reg = w83627ehf_read_value(data, W83627EHF_REG_CASEOPEN_CLR);
...@@ -1786,85 +1369,116 @@ clear_caseopen(struct device *dev, struct device_attribute *attr, ...@@ -1786,85 +1369,116 @@ clear_caseopen(struct device *dev, struct device_attribute *attr,
data->valid = 0; /* Force cache refresh */ data->valid = 0; /* Force cache refresh */
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return 0;
} }
static struct sensor_device_attribute_2 sda_caseopen[] = { static umode_t w83627ehf_attrs_visible(struct kobject *kobj,
SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_caseopen, struct attribute *a, int n)
clear_caseopen, 0x80, 0x10),
SENSOR_ATTR_2(intrusion1_alarm, S_IWUSR | S_IRUGO, show_caseopen,
clear_caseopen, 0x40, 0x40),
};
/*
* Driver and device management
*/
static void w83627ehf_device_remove_files(struct device *dev)
{ {
/* struct device *dev = container_of(kobj, struct device, kobj);
* some entries in the following arrays may not have been used in
* device_create_file(), but device_remove_file() will ignore them
*/
int i;
struct w83627ehf_data *data = dev_get_drvdata(dev); struct w83627ehf_data *data = dev_get_drvdata(dev);
struct device_attribute *devattr;
struct sensor_device_attribute *sda;
devattr = container_of(a, struct device_attribute, attr);
/* Not sensor */
if (devattr->show == cpu0_vid_show && data->have_vid)
return a->mode;
sda = (struct sensor_device_attribute *)devattr;
if (sda->index < 2 &&
(devattr->show == show_fan_stop_time ||
devattr->show == show_fan_start_output ||
devattr->show == show_fan_stop_output))
return a->mode;
if (sda->index < 3 &&
(devattr->show == show_fan_max_output ||
devattr->show == show_fan_step_output) &&
data->REG_FAN_STEP_OUTPUT &&
data->REG_FAN_STEP_OUTPUT[sda->index] != 0xff)
return a->mode;
/* if fan3 and fan4 are enabled create the files for them */
if (sda->index == 2 &&
(data->has_fan & (1 << 2)) && data->pwm_num >= 3 &&
(devattr->show == show_fan_stop_time ||
devattr->show == show_fan_start_output ||
devattr->show == show_fan_stop_output))
return a->mode;
if (sda->index == 3 &&
(data->has_fan & (1 << 3)) && data->pwm_num >= 4 &&
(devattr->show == show_fan_stop_time ||
devattr->show == show_fan_start_output ||
devattr->show == show_fan_stop_output ||
devattr->show == show_fan_max_output ||
devattr->show == show_fan_step_output))
return a->mode;
if ((devattr->show == show_target_temp ||
devattr->show == show_tolerance) &&
(data->has_fan & (1 << sda->index)) &&
sda->index < data->pwm_num)
return a->mode;
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) return 0;
device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); }
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->REG_FAN_STEP_OUTPUT &&
data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff)
device_remove_file(dev, &attr->dev_attr);
}
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++)
device_remove_file(dev, &sda_sf3_arrays_fan3[i].dev_attr);
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
for (i = 0; i < data->in_num; i++) {
if ((i == 6) && data->in6_skip)
continue;
device_remove_file(dev, &sda_in_input[i].dev_attr);
device_remove_file(dev, &sda_in_alarm[i].dev_attr);
device_remove_file(dev, &sda_in_min[i].dev_attr);
device_remove_file(dev, &sda_in_max[i].dev_attr);
}
for (i = 0; i < 5; i++) {
device_remove_file(dev, &sda_fan_input[i].dev_attr);
device_remove_file(dev, &sda_fan_alarm[i].dev_attr);
device_remove_file(dev, &sda_fan_div[i].dev_attr);
device_remove_file(dev, &sda_fan_min[i].dev_attr);
}
for (i = 0; i < data->pwm_num; i++) {
device_remove_file(dev, &sda_pwm[i].dev_attr);
device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
device_remove_file(dev, &sda_target_temp[i].dev_attr);
device_remove_file(dev, &sda_tolerance[i].dev_attr);
}
for (i = 0; i < NUM_REG_TEMP; i++) {
if (!(data->have_temp & (1 << i)))
continue;
device_remove_file(dev, &sda_temp_input[i].dev_attr);
device_remove_file(dev, &sda_temp_label[i].dev_attr);
if (i == 2 && data->temp3_val_only)
continue;
device_remove_file(dev, &sda_temp_max[i].dev_attr);
device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
if (i > 2)
continue;
device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
device_remove_file(dev, &sda_temp_type[i].dev_attr);
device_remove_file(dev, &sda_temp_offset[i].dev_attr);
}
device_remove_file(dev, &sda_caseopen[0].dev_attr); /* These groups handle non-standard attributes used in this device */
device_remove_file(dev, &sda_caseopen[1].dev_attr); static struct attribute *w83627ehf_attrs[] = {
&sensor_dev_attr_pwm1_stop_time.dev_attr.attr,
&sensor_dev_attr_pwm1_start_output.dev_attr.attr,
&sensor_dev_attr_pwm1_stop_output.dev_attr.attr,
&sensor_dev_attr_pwm1_max_output.dev_attr.attr,
&sensor_dev_attr_pwm1_step_output.dev_attr.attr,
&sensor_dev_attr_pwm1_target.dev_attr.attr,
&sensor_dev_attr_pwm1_tolerance.dev_attr.attr,
&sensor_dev_attr_pwm2_stop_time.dev_attr.attr,
&sensor_dev_attr_pwm2_start_output.dev_attr.attr,
&sensor_dev_attr_pwm2_stop_output.dev_attr.attr,
&sensor_dev_attr_pwm2_max_output.dev_attr.attr,
&sensor_dev_attr_pwm2_step_output.dev_attr.attr,
&sensor_dev_attr_pwm2_target.dev_attr.attr,
&sensor_dev_attr_pwm2_tolerance.dev_attr.attr,
&sensor_dev_attr_pwm3_stop_time.dev_attr.attr,
&sensor_dev_attr_pwm3_start_output.dev_attr.attr,
&sensor_dev_attr_pwm3_stop_output.dev_attr.attr,
&sensor_dev_attr_pwm3_max_output.dev_attr.attr,
&sensor_dev_attr_pwm3_step_output.dev_attr.attr,
&sensor_dev_attr_pwm3_target.dev_attr.attr,
&sensor_dev_attr_pwm3_tolerance.dev_attr.attr,
&sensor_dev_attr_pwm4_stop_time.dev_attr.attr,
&sensor_dev_attr_pwm4_start_output.dev_attr.attr,
&sensor_dev_attr_pwm4_stop_output.dev_attr.attr,
&sensor_dev_attr_pwm4_max_output.dev_attr.attr,
&sensor_dev_attr_pwm4_step_output.dev_attr.attr,
&sensor_dev_attr_pwm4_target.dev_attr.attr,
&sensor_dev_attr_pwm4_tolerance.dev_attr.attr,
&dev_attr_cpu0_vid.attr,
NULL
};
device_remove_file(dev, &dev_attr_name); static const struct attribute_group w83627ehf_group = {
device_remove_file(dev, &dev_attr_cpu0_vid); .attrs = w83627ehf_attrs,
} .is_visible = w83627ehf_attrs_visible,
};
static const struct attribute_group *w83627ehf_groups[] = {
&w83627ehf_group,
NULL
};
/*
* Driver and device management
*/
/* Get the monitoring functions started */ /* Get the monitoring functions started */
static inline void w83627ehf_init_device(struct w83627ehf_data *data, static inline void w83627ehf_init_device(struct w83627ehf_data *data,
...@@ -2035,6 +1649,369 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data, ...@@ -2035,6 +1649,369 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
} }
} }
static umode_t
w83627ehf_is_visible(const void *drvdata, enum hwmon_sensor_types type,
u32 attr, int channel)
{
const struct w83627ehf_data *data = drvdata;
switch (type) {
case hwmon_temp:
/* channel 0.., name 1.. */
if (!(data->have_temp & (1 << channel)))
return 0;
if (attr == hwmon_temp_input || attr == hwmon_temp_label)
return 0444;
if (channel == 2 && data->temp3_val_only)
return 0;
if (attr == hwmon_temp_max) {
if (data->reg_temp_over[channel])
return 0644;
else
return 0;
}
if (attr == hwmon_temp_max_hyst) {
if (data->reg_temp_hyst[channel])
return 0644;
else
return 0;
}
if (channel > 2)
return 0;
if (attr == hwmon_temp_alarm || attr == hwmon_temp_type)
return 0444;
if (attr == hwmon_temp_offset) {
if (data->have_temp_offset & (1 << channel))
return 0644;
else
return 0;
}
break;
case hwmon_fan:
/* channel 0.., name 1.. */
if (!(data->has_fan & (1 << channel)))
return 0;
if (attr == hwmon_fan_input || attr == hwmon_fan_alarm)
return 0444;
if (attr == hwmon_fan_div) {
if (data->kind != nct6776)
return 0444;
else
return 0;
}
if (attr == hwmon_fan_min) {
if (data->has_fan_min & (1 << channel))
return 0644;
else
return 0;
}
break;
case hwmon_in:
/* channel 0.., name 0.. */
if (channel >= data->in_num)
return 0;
if (channel == 6 && data->in6_skip)
return 0;
if (attr == hwmon_in_alarm || attr == hwmon_in_input)
return 0444;
if (attr == hwmon_in_min || attr == hwmon_in_max)
return 0644;
break;
case hwmon_pwm:
/* channel 0.., name 1.. */
if (!(data->has_fan & (1 << channel)) ||
channel >= data->pwm_num)
return 0;
if (attr == hwmon_pwm_mode || attr == hwmon_pwm_enable ||
attr == hwmon_pwm_input)
return 0644;
break;
case hwmon_intrusion:
if (channel == 0 ||
(channel == 1 && data->kind == nct6776))
return 0644;
return 0;
default: /* Shouldn't happen */
return 0;
}
return 0; /* Shouldn't happen */
}
static int
w83627ehf_do_read_temp(struct w83627ehf_data *data, u32 attr,
int channel, long *val)
{
switch (attr) {
case hwmon_temp_input:
*val = LM75_TEMP_FROM_REG(data->temp[channel]);
return 0;
case hwmon_temp_max:
*val = LM75_TEMP_FROM_REG(data->temp_max[channel]);
return 0;
case hwmon_temp_max_hyst:
*val = LM75_TEMP_FROM_REG(data->temp_max_hyst[channel]);
return 0;
case hwmon_temp_offset:
*val = data->temp_offset[channel] * 1000;
return 0;
case hwmon_temp_type:
*val = (int)data->temp_type[channel];
return 0;
case hwmon_temp_alarm:
if (channel < 3) {
int bit[] = { 4, 5, 13 };
*val = (data->alarms >> bit[channel]) & 1;
return 0;
}
break;
default:
break;
}
return -EOPNOTSUPP;
}
static int
w83627ehf_do_read_in(struct w83627ehf_data *data, u32 attr,
int channel, long *val)
{
switch (attr) {
case hwmon_in_input:
*val = in_from_reg(data->in[channel], channel, data->scale_in);
return 0;
case hwmon_in_min:
*val = in_from_reg(data->in_min[channel], channel,
data->scale_in);
return 0;
case hwmon_in_max:
*val = in_from_reg(data->in_max[channel], channel,
data->scale_in);
return 0;
case hwmon_in_alarm:
if (channel < 10) {
int bit[] = { 0, 1, 2, 3, 8, 21, 20, 16, 17, 19 };
*val = (data->alarms >> bit[channel]) & 1;
return 0;
}
break;
default:
break;
}
return -EOPNOTSUPP;
}
static int
w83627ehf_do_read_fan(struct w83627ehf_data *data, u32 attr,
int channel, long *val)
{
switch (attr) {
case hwmon_fan_input:
*val = data->rpm[channel];
return 0;
case hwmon_fan_min:
*val = data->fan_from_reg_min(data->fan_min[channel],
data->fan_div[channel]);
return 0;
case hwmon_fan_div:
*val = div_from_reg(data->fan_div[channel]);
return 0;
case hwmon_fan_alarm:
if (channel < 5) {
int bit[] = { 6, 7, 11, 10, 23 };
*val = (data->alarms >> bit[channel]) & 1;
return 0;
}
break;
default:
break;
}
return -EOPNOTSUPP;
}
static int
w83627ehf_do_read_pwm(struct w83627ehf_data *data, u32 attr,
int channel, long *val)
{
switch (attr) {
case hwmon_pwm_input:
*val = data->pwm[channel];
return 0;
case hwmon_pwm_enable:
*val = data->pwm_enable[channel];
return 0;
case hwmon_pwm_mode:
*val = data->pwm_enable[channel];
return 0;
default:
break;
}
return -EOPNOTSUPP;
}
static int
w83627ehf_do_read_intrusion(struct w83627ehf_data *data, u32 attr,
int channel, long *val)
{
unsigned int masks[] = { 0x10, 0x40 };
if (attr != hwmon_intrusion_alarm || channel > 1)
return -EOPNOTSUPP; /* shouldn't happen */
*val = !!(data->caseopen & masks[channel]);
return 0;
}
static int
w83627ehf_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{
struct w83627ehf_data *data = w83627ehf_update_device(dev->parent);
switch (type) {
case hwmon_fan:
return w83627ehf_do_read_fan(data, attr, channel, val);
case hwmon_in:
return w83627ehf_do_read_in(data, attr, channel, val);
case hwmon_pwm:
return w83627ehf_do_read_pwm(data, attr, channel, val);
case hwmon_temp:
return w83627ehf_do_read_temp(data, attr, channel, val);
case hwmon_intrusion:
return w83627ehf_do_read_intrusion(data, attr, channel, val);
default:
break;
}
return -EOPNOTSUPP;
}
static int
w83627ehf_read_string(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, const char **str)
{
struct w83627ehf_data *data = dev_get_drvdata(dev);
switch (type) {
case hwmon_temp:
if (attr == hwmon_temp_label) {
*str = data->temp_label[data->temp_src[channel]];
return 0;
}
break;
default:
break;
}
/* Nothing else should be read as a string */
return -EOPNOTSUPP;
}
static int
w83627ehf_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{
struct w83627ehf_data *data = dev_get_drvdata(dev);
if (type == hwmon_in && attr == hwmon_in_min)
return store_in_min(dev, data, channel, val);
if (type == hwmon_in && attr == hwmon_in_max)
return store_in_max(dev, data, channel, val);
if (type == hwmon_fan && attr == hwmon_fan_min)
return store_fan_min(dev, data, channel, val);
if (type == hwmon_temp && attr == hwmon_temp_max)
return store_temp_max(dev, data, channel, val);
if (type == hwmon_temp && attr == hwmon_temp_max_hyst)
return store_temp_max_hyst(dev, data, channel, val);
if (type == hwmon_temp && attr == hwmon_temp_offset)
return store_temp_offset(dev, data, channel, val);
if (type == hwmon_pwm && attr == hwmon_pwm_mode)
return store_pwm_mode(dev, data, channel, val);
if (type == hwmon_pwm && attr == hwmon_pwm_enable)
return store_pwm_enable(dev, data, channel, val);
if (type == hwmon_pwm && attr == hwmon_pwm_input)
return store_pwm(dev, data, channel, val);
if (type == hwmon_intrusion && attr == hwmon_intrusion_alarm)
return clear_caseopen(dev, data, channel, val);
return -EOPNOTSUPP;
}
static const struct hwmon_ops w83627ehf_ops = {
.is_visible = w83627ehf_is_visible,
.read = w83627ehf_read,
.read_string = w83627ehf_read_string,
.write = w83627ehf_write,
};
static const struct hwmon_channel_info *w83627ehf_info[] = {
HWMON_CHANNEL_INFO(fan,
HWMON_F_ALARM | HWMON_F_DIV | HWMON_F_INPUT | HWMON_F_MIN,
HWMON_F_ALARM | HWMON_F_DIV | HWMON_F_INPUT | HWMON_F_MIN,
HWMON_F_ALARM | HWMON_F_DIV | HWMON_F_INPUT | HWMON_F_MIN,
HWMON_F_ALARM | HWMON_F_DIV | HWMON_F_INPUT | HWMON_F_MIN,
HWMON_F_ALARM | HWMON_F_DIV | HWMON_F_INPUT | HWMON_F_MIN),
HWMON_CHANNEL_INFO(in,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN,
HWMON_I_ALARM | HWMON_I_INPUT | HWMON_I_MAX | HWMON_I_MIN),
HWMON_CHANNEL_INFO(pwm,
HWMON_PWM_ENABLE | HWMON_PWM_INPUT | HWMON_PWM_MODE,
HWMON_PWM_ENABLE | HWMON_PWM_INPUT | HWMON_PWM_MODE,
HWMON_PWM_ENABLE | HWMON_PWM_INPUT | HWMON_PWM_MODE,
HWMON_PWM_ENABLE | HWMON_PWM_INPUT | HWMON_PWM_MODE),
HWMON_CHANNEL_INFO(temp,
HWMON_T_ALARM | HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX |
HWMON_T_MAX_HYST | HWMON_T_OFFSET | HWMON_T_TYPE,
HWMON_T_ALARM | HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX |
HWMON_T_MAX_HYST | HWMON_T_OFFSET | HWMON_T_TYPE,
HWMON_T_ALARM | HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX |
HWMON_T_MAX_HYST | HWMON_T_OFFSET | HWMON_T_TYPE,
HWMON_T_ALARM | HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX |
HWMON_T_MAX_HYST | HWMON_T_OFFSET | HWMON_T_TYPE,
HWMON_T_ALARM | HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX |
HWMON_T_MAX_HYST | HWMON_T_OFFSET | HWMON_T_TYPE,
HWMON_T_ALARM | HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX |
HWMON_T_MAX_HYST | HWMON_T_OFFSET | HWMON_T_TYPE,
HWMON_T_ALARM | HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX |
HWMON_T_MAX_HYST | HWMON_T_OFFSET | HWMON_T_TYPE,
HWMON_T_ALARM | HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX |
HWMON_T_MAX_HYST | HWMON_T_OFFSET | HWMON_T_TYPE,
HWMON_T_ALARM | HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_MAX |
HWMON_T_MAX_HYST | HWMON_T_OFFSET | HWMON_T_TYPE),
HWMON_CHANNEL_INFO(intrusion,
HWMON_INTRUSION_ALARM,
HWMON_INTRUSION_ALARM),
NULL
};
static const struct hwmon_chip_info w83627ehf_chip_info = {
.ops = &w83627ehf_ops,
.info = w83627ehf_info,
};
static int w83627ehf_probe(struct platform_device *pdev) static int w83627ehf_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -2043,6 +2020,7 @@ static int w83627ehf_probe(struct platform_device *pdev) ...@@ -2043,6 +2020,7 @@ static int w83627ehf_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
u8 en_vrm10; u8 en_vrm10;
int i, err = 0; int i, err = 0;
struct device *hwmon_dev;
res = platform_get_resource(pdev, IORESOURCE_IO, 0); res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!request_region(res->start, IOREGION_LENGTH, DRVNAME)) { if (!request_region(res->start, IOREGION_LENGTH, DRVNAME)) {
...@@ -2064,6 +2042,7 @@ static int w83627ehf_probe(struct platform_device *pdev) ...@@ -2064,6 +2042,7 @@ static int w83627ehf_probe(struct platform_device *pdev)
mutex_init(&data->lock); mutex_init(&data->lock);
mutex_init(&data->update_lock); mutex_init(&data->update_lock);
data->name = w83627ehf_device_names[sio_data->kind]; data->name = w83627ehf_device_names[sio_data->kind];
data->kind = sio_data->kind;
data->bank = 0xff; /* Force initial bank selection */ data->bank = 0xff; /* Force initial bank selection */
platform_set_drvdata(pdev, data); platform_set_drvdata(pdev, data);
...@@ -2356,11 +2335,7 @@ static int w83627ehf_probe(struct platform_device *pdev) ...@@ -2356,11 +2335,7 @@ static int w83627ehf_probe(struct platform_device *pdev)
*/ */
superio_select(sio_data->sioreg, W83667HG_LD_VID); superio_select(sio_data->sioreg, W83667HG_LD_VID);
data->vid = superio_inb(sio_data->sioreg, 0xe3); data->vid = superio_inb(sio_data->sioreg, 0xe3);
err = device_create_file(dev, &dev_attr_cpu0_vid); data->have_vid = true;
if (err) {
superio_exit(sio_data->sioreg);
goto exit_release;
}
} else if (sio_data->kind != w83627uhg) { } else if (sio_data->kind != w83627uhg) {
superio_select(sio_data->sioreg, W83627EHF_LD_HWM); superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
...@@ -2394,12 +2369,7 @@ static int w83627ehf_probe(struct platform_device *pdev) ...@@ -2394,12 +2369,7 @@ static int w83627ehf_probe(struct platform_device *pdev)
SIO_REG_VID_DATA); SIO_REG_VID_DATA);
if (sio_data->kind == w83627ehf) /* 6 VID pins only */ if (sio_data->kind == w83627ehf) /* 6 VID pins only */
data->vid &= 0x3f; data->vid &= 0x3f;
data->have_vid = true;
err = device_create_file(dev, &dev_attr_cpu0_vid);
if (err) {
superio_exit(sio_data->sioreg);
goto exit_release;
}
} else { } else {
dev_info(dev, dev_info(dev,
"VID pins in output mode, CPU VID not available\n"); "VID pins in output mode, CPU VID not available\n");
...@@ -2433,151 +2403,14 @@ static int w83627ehf_probe(struct platform_device *pdev) ...@@ -2433,151 +2403,14 @@ static int w83627ehf_probe(struct platform_device *pdev)
for (i = 0; i < data->pwm_num; i++) for (i = 0; i < data->pwm_num; i++)
data->pwm_enable_orig[i] = data->pwm_enable[i]; data->pwm_enable_orig[i] = data->pwm_enable[i];
/* Register sysfs hooks */ hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) { data->name,
err = device_create_file(dev, &sda_sf3_arrays[i].dev_attr); data,
if (err) &w83627ehf_chip_info,
goto exit_remove; w83627ehf_groups);
}
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->REG_FAN_STEP_OUTPUT &&
data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff) {
err = device_create_file(dev, &attr->dev_attr);
if (err)
goto exit_remove;
}
}
/* if fan3 and fan4 are enabled create the sf3 files for them */
if ((data->has_fan & (1 << 2)) && data->pwm_num >= 3)
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++) {
err = device_create_file(dev,
&sda_sf3_arrays_fan3[i].dev_attr);
if (err)
goto exit_remove;
}
if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
err = device_create_file(dev,
&sda_sf3_arrays_fan4[i].dev_attr);
if (err)
goto exit_remove;
}
for (i = 0; i < data->in_num; i++) {
if ((i == 6) && data->in6_skip)
continue;
if ((err = device_create_file(dev, &sda_in_input[i].dev_attr))
|| (err = device_create_file(dev,
&sda_in_alarm[i].dev_attr))
|| (err = device_create_file(dev,
&sda_in_min[i].dev_attr))
|| (err = device_create_file(dev,
&sda_in_max[i].dev_attr)))
goto exit_remove;
}
for (i = 0; i < 5; i++) {
if (data->has_fan & (1 << i)) {
if ((err = device_create_file(dev,
&sda_fan_input[i].dev_attr))
|| (err = device_create_file(dev,
&sda_fan_alarm[i].dev_attr)))
goto exit_remove;
if (sio_data->kind != nct6776) {
err = device_create_file(dev,
&sda_fan_div[i].dev_attr);
if (err)
goto exit_remove;
}
if (data->has_fan_min & (1 << i)) {
err = device_create_file(dev,
&sda_fan_min[i].dev_attr);
if (err)
goto exit_remove;
}
if (i < data->pwm_num &&
((err = device_create_file(dev,
&sda_pwm[i].dev_attr))
|| (err = device_create_file(dev,
&sda_pwm_mode[i].dev_attr))
|| (err = device_create_file(dev,
&sda_pwm_enable[i].dev_attr))
|| (err = device_create_file(dev,
&sda_target_temp[i].dev_attr))
|| (err = device_create_file(dev,
&sda_tolerance[i].dev_attr))))
goto exit_remove;
}
}
for (i = 0; i < NUM_REG_TEMP; i++) {
if (!(data->have_temp & (1 << i)))
continue;
err = device_create_file(dev, &sda_temp_input[i].dev_attr);
if (err)
goto exit_remove;
if (data->temp_label) {
err = device_create_file(dev,
&sda_temp_label[i].dev_attr);
if (err)
goto exit_remove;
}
if (i == 2 && data->temp3_val_only)
continue;
if (data->reg_temp_over[i]) {
err = device_create_file(dev,
&sda_temp_max[i].dev_attr);
if (err)
goto exit_remove;
}
if (data->reg_temp_hyst[i]) {
err = device_create_file(dev,
&sda_temp_max_hyst[i].dev_attr);
if (err)
goto exit_remove;
}
if (i > 2)
continue;
if ((err = device_create_file(dev,
&sda_temp_alarm[i].dev_attr))
|| (err = device_create_file(dev,
&sda_temp_type[i].dev_attr)))
goto exit_remove;
if (data->have_temp_offset & (1 << i)) {
err = device_create_file(dev,
&sda_temp_offset[i].dev_attr);
if (err)
goto exit_remove;
}
}
err = device_create_file(dev, &sda_caseopen[0].dev_attr); return PTR_ERR_OR_ZERO(hwmon_dev);
if (err)
goto exit_remove;
if (sio_data->kind == nct6776) {
err = device_create_file(dev, &sda_caseopen[1].dev_attr);
if (err)
goto exit_remove;
}
err = device_create_file(dev, &dev_attr_name);
if (err)
goto exit_remove;
data->hwmon_dev = hwmon_device_register(dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
w83627ehf_device_remove_files(dev);
exit_release: exit_release:
release_region(res->start, IOREGION_LENGTH); release_region(res->start, IOREGION_LENGTH);
exit: exit:
...@@ -2588,8 +2421,6 @@ static int w83627ehf_remove(struct platform_device *pdev) ...@@ -2588,8 +2421,6 @@ static int w83627ehf_remove(struct platform_device *pdev)
{ {
struct w83627ehf_data *data = platform_get_drvdata(pdev); struct w83627ehf_data *data = platform_get_drvdata(pdev);
hwmon_device_unregister(data->hwmon_dev);
w83627ehf_device_remove_files(&pdev->dev);
release_region(data->addr, IOREGION_LENGTH); release_region(data->addr, IOREGION_LENGTH);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment