mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 23:34:05 +08:00
hwmon: (nct6775) Add support for pwm, pwm_mode, and pwm_enable
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
84d19d92f7
commit
77eb5b3703
@ -69,6 +69,24 @@ is driven slower/faster to reach the predefined range again.
|
||||
|
||||
The mode works for fan1-fan5.
|
||||
|
||||
sysfs attributes
|
||||
----------------
|
||||
|
||||
pwm[1-5] - this file stores PWM duty cycle or DC value (fan speed) in range:
|
||||
0 (lowest speed) to 255 (full)
|
||||
|
||||
pwm[1-5]_enable - this file controls mode of fan/temperature control:
|
||||
* 0 Fan control disabled (fans set to maximum speed)
|
||||
* 1 Manual mode, write to pwm[0-5] any value 0-255
|
||||
* 2 "Thermal Cruise" mode
|
||||
* 3 "Fan Speed Cruise" mode
|
||||
* 4 "Smart Fan III" mode (NCT6775F only)
|
||||
* 5 "Smart Fan IV" mode
|
||||
|
||||
pwm[1-5]_mode - controls if output is PWM or DC level
|
||||
* 0 DC output
|
||||
* 1 PWM output
|
||||
|
||||
Usage Notes
|
||||
-----------
|
||||
|
||||
|
@ -96,6 +96,8 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
|
||||
#define SIO_NCT6779_ID 0xc560
|
||||
#define SIO_ID_MASK 0xFFF0
|
||||
|
||||
enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
|
||||
|
||||
static inline void
|
||||
superio_outb(int ioreg, int reg, int val)
|
||||
{
|
||||
@ -209,6 +211,15 @@ static const s8 NCT6775_ALARM_BITS[] = {
|
||||
static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
|
||||
static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
|
||||
|
||||
/* DC or PWM output fan configuration */
|
||||
static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 };
|
||||
static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
|
||||
|
||||
static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302, 0x802, 0x902 };
|
||||
|
||||
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[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
|
||||
static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
|
||||
static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 };
|
||||
@ -270,6 +281,9 @@ static const s8 NCT6776_ALARM_BITS[] = {
|
||||
4, 5, 13, -1, -1, -1, /* temp1..temp6 */
|
||||
12, 9 }; /* intrusion0, intrusion1 */
|
||||
|
||||
static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0 };
|
||||
static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0 };
|
||||
|
||||
static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 };
|
||||
static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 };
|
||||
|
||||
@ -380,6 +394,20 @@ static const u16 NCT6779_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6779_temp_label) - 1]
|
||||
static const u16 NCT6779_REG_TEMP_CRIT[ARRAY_SIZE(nct6779_temp_label) - 1]
|
||||
= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x709, 0x70a };
|
||||
|
||||
static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
|
||||
{
|
||||
if (mode == 0 && pwm == 255)
|
||||
return off;
|
||||
return mode + 1;
|
||||
}
|
||||
|
||||
static int pwm_enable_to_reg(enum pwm_enable mode)
|
||||
{
|
||||
if (mode == off)
|
||||
return 0;
|
||||
return mode - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Conversions
|
||||
*/
|
||||
@ -471,9 +499,16 @@ struct nct6775_data {
|
||||
const u16 *REG_IN_MINMAX[2];
|
||||
|
||||
const u16 *REG_FAN;
|
||||
const u16 *REG_FAN_MODE;
|
||||
const u16 *REG_FAN_MIN;
|
||||
const u16 *REG_FAN_PULSES;
|
||||
|
||||
const u8 *REG_PWM_MODE;
|
||||
const u8 *PWM_MODE_MASK;
|
||||
|
||||
const u16 *REG_PWM[1]; /* [0]=pwm */
|
||||
const u16 *REG_PWM_READ;
|
||||
|
||||
const u16 *REG_TEMP_SOURCE; /* temp register sources */
|
||||
const u16 *REG_TEMP_OFFSET;
|
||||
|
||||
@ -494,6 +529,7 @@ struct nct6775_data {
|
||||
u16 fan_min[5];
|
||||
u8 fan_pulses[5];
|
||||
u8 fan_div[5];
|
||||
u8 has_pwm;
|
||||
u8 has_fan; /* some fan inputs can be disabled */
|
||||
u8 has_fan_min; /* some fans don't have min register */
|
||||
bool has_fan_div;
|
||||
@ -505,6 +541,18 @@ struct nct6775_data {
|
||||
* 3=temp_crit */
|
||||
u64 alarms;
|
||||
|
||||
u8 pwm_num; /* number of pwm */
|
||||
u8 pwm_mode[5]; /* 1->DC variable voltage, 0->PWM variable duty cycle */
|
||||
enum pwm_enable pwm_enable[5];
|
||||
/* 0->off
|
||||
* 1->manual
|
||||
* 2->thermal cruise mode (also called SmartFan I)
|
||||
* 3->fan speed cruise mode
|
||||
* 4->SmartFan III
|
||||
* 5->enhanced variable thermal cruise (SmartFan IV)
|
||||
*/
|
||||
u8 pwm[1][5]; /* [0]=pwm */
|
||||
|
||||
u8 vid;
|
||||
u8 vrm;
|
||||
|
||||
@ -781,6 +829,36 @@ static void nct6775_select_fan_div(struct device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
static void nct6775_update_pwm(struct device *dev)
|
||||
{
|
||||
struct nct6775_data *data = dev_get_drvdata(dev);
|
||||
int i, j;
|
||||
int fanmodecfg;
|
||||
bool duty_is_dc;
|
||||
|
||||
for (i = 0; i < data->pwm_num; i++) {
|
||||
if (!(data->has_pwm & (1 << i)))
|
||||
continue;
|
||||
|
||||
duty_is_dc = data->REG_PWM_MODE[i] &&
|
||||
(nct6775_read_value(data, data->REG_PWM_MODE[i])
|
||||
& data->PWM_MODE_MASK[i]);
|
||||
data->pwm_mode[i] = duty_is_dc;
|
||||
|
||||
fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
|
||||
for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
|
||||
if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
|
||||
data->pwm[j][i]
|
||||
= nct6775_read_value(data,
|
||||
data->REG_PWM[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
|
||||
(fanmodecfg >> 4) & 7);
|
||||
}
|
||||
}
|
||||
|
||||
static struct nct6775_data *nct6775_update_device(struct device *dev)
|
||||
{
|
||||
struct nct6775_data *data = dev_get_drvdata(dev);
|
||||
@ -826,6 +904,8 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
|
||||
nct6775_select_fan_div(dev, data, i, reg);
|
||||
}
|
||||
|
||||
nct6775_update_pwm(dev);
|
||||
|
||||
/* Measured temperatures and limits */
|
||||
for (i = 0; i < NUM_TEMP; i++) {
|
||||
if (!(data->have_temp & (1 << i)))
|
||||
@ -1599,6 +1679,170 @@ static struct sensor_device_attribute sda_temp_alarm[] = {
|
||||
|
||||
#define NUM_TEMP_ALARM ARRAY_SIZE(sda_temp_alarm)
|
||||
|
||||
static ssize_t
|
||||
show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct nct6775_data *data = nct6775_update_device(dev);
|
||||
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
||||
|
||||
return sprintf(buf, "%d\n", !data->pwm_mode[sattr->index]);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
store_pwm_mode(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 *sattr = to_sensor_dev_attr(attr);
|
||||
int nr = sattr->index;
|
||||
unsigned long val;
|
||||
int err;
|
||||
u8 reg;
|
||||
|
||||
err = kstrtoul(buf, 10, &val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (val > 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Setting DC mode is not supported for all chips/channels */
|
||||
if (data->REG_PWM_MODE[nr] == 0) {
|
||||
if (val)
|
||||
return -EINVAL;
|
||||
return count;
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
data->pwm_mode[nr] = val;
|
||||
reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
|
||||
reg &= ~data->PWM_MODE_MASK[nr];
|
||||
if (val)
|
||||
reg |= data->PWM_MODE_MASK[nr];
|
||||
nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
|
||||
mutex_unlock(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
show_pwm(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;
|
||||
int pwm;
|
||||
|
||||
/*
|
||||
* For automatic fan control modes, show current pwm readings.
|
||||
* Otherwise, show the configured value.
|
||||
*/
|
||||
if (index == 0 && data->pwm_enable[nr] > manual)
|
||||
pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
|
||||
else
|
||||
pwm = data->pwm[index][nr];
|
||||
|
||||
return sprintf(buf, "%d\n", pwm);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
store_pwm(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 = clamp_val(val, 0, 255);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
data->pwm[index][nr] = val;
|
||||
nct6775_write_value(data, data->REG_PWM[index][nr], val);
|
||||
mutex_unlock(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct nct6775_data *data = nct6775_update_device(dev);
|
||||
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
||||
|
||||
return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
store_pwm_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 *sattr = to_sensor_dev_attr(attr);
|
||||
int nr = sattr->index;
|
||||
unsigned long val;
|
||||
int err;
|
||||
u16 reg;
|
||||
|
||||
err = kstrtoul(buf, 10, &val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (val > sf4)
|
||||
return -EINVAL;
|
||||
|
||||
if (val == sf3 && data->kind != nct6775)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
data->pwm_enable[nr] = val;
|
||||
if (val == off) {
|
||||
/*
|
||||
* turn off pwm control: select manual mode, set pwm to maximum
|
||||
*/
|
||||
data->pwm[0][nr] = 255;
|
||||
nct6775_write_value(data, data->REG_PWM[0][nr], 255);
|
||||
}
|
||||
reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
|
||||
reg &= 0x0f;
|
||||
reg |= pwm_enable_to_reg(val) << 4;
|
||||
nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
|
||||
mutex_unlock(&data->update_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
static SENSOR_DEVICE_ATTR_2(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0);
|
||||
static SENSOR_DEVICE_ATTR_2(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1, 0);
|
||||
static SENSOR_DEVICE_ATTR_2(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2, 0);
|
||||
static SENSOR_DEVICE_ATTR_2(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3, 0);
|
||||
static SENSOR_DEVICE_ATTR_2(pwm5, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 4, 0);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
|
||||
store_pwm_mode, 0);
|
||||
static SENSOR_DEVICE_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
|
||||
store_pwm_mode, 1);
|
||||
static SENSOR_DEVICE_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
|
||||
store_pwm_mode, 2);
|
||||
static SENSOR_DEVICE_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
|
||||
store_pwm_mode, 3);
|
||||
static SENSOR_DEVICE_ATTR(pwm5_mode, S_IWUSR | S_IRUGO, show_pwm_mode,
|
||||
store_pwm_mode, 4);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
|
||||
store_pwm_enable, 0);
|
||||
static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
|
||||
store_pwm_enable, 1);
|
||||
static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
|
||||
store_pwm_enable, 2);
|
||||
static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
|
||||
store_pwm_enable, 3);
|
||||
static SENSOR_DEVICE_ATTR(pwm5_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
|
||||
store_pwm_enable, 4);
|
||||
|
||||
static ssize_t
|
||||
show_name(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -1609,6 +1853,47 @@ show_name(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
|
||||
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
|
||||
|
||||
static struct attribute *nct6775_attributes_pwm[5][4] = {
|
||||
{
|
||||
&sensor_dev_attr_pwm1.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm1_mode.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
&sensor_dev_attr_pwm2.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm2_mode.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm2_enable.dev_attr.attr,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
&sensor_dev_attr_pwm3.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm3_mode.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm3_enable.dev_attr.attr,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
&sensor_dev_attr_pwm4.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm4_mode.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm4_enable.dev_attr.attr,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
&sensor_dev_attr_pwm5.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm5_mode.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm5_enable.dev_attr.attr,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
|
||||
static const struct attribute_group nct6775_group_pwm[5] = {
|
||||
{ .attrs = nct6775_attributes_pwm[0] },
|
||||
{ .attrs = nct6775_attributes_pwm[1] },
|
||||
{ .attrs = nct6775_attributes_pwm[2] },
|
||||
{ .attrs = nct6775_attributes_pwm[3] },
|
||||
{ .attrs = nct6775_attributes_pwm[4] },
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
show_vid(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -1681,6 +1966,9 @@ static void nct6775_device_remove_files(struct device *dev)
|
||||
int i;
|
||||
struct nct6775_data *data = dev_get_drvdata(dev);
|
||||
|
||||
for (i = 0; i < data->pwm_num; i++)
|
||||
sysfs_remove_group(&dev->kobj, &nct6775_group_pwm[i]);
|
||||
|
||||
for (i = 0; i < data->in_num; i++)
|
||||
sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
|
||||
|
||||
@ -1763,6 +2051,7 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
|
||||
{
|
||||
int regval;
|
||||
bool fan3pin, fan3min, fan4pin, fan4min, fan5pin;
|
||||
bool pwm3pin, pwm4pin, pwm5pin;
|
||||
int ret;
|
||||
|
||||
ret = superio_enter(sio_data->sioreg);
|
||||
@ -1775,11 +2064,14 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
|
||||
|
||||
fan3pin = regval & (1 << 6);
|
||||
fan3min = fan3pin;
|
||||
pwm3pin = regval & (1 << 7);
|
||||
|
||||
/* On NCT6775, fan4 shares pins with the fdc interface */
|
||||
fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80);
|
||||
fan4min = 0;
|
||||
fan5pin = 0;
|
||||
pwm4pin = 0;
|
||||
pwm5pin = 0;
|
||||
} else if (data->kind == nct6776) {
|
||||
bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
|
||||
|
||||
@ -1803,6 +2095,9 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
|
||||
|
||||
fan4min = fan4pin;
|
||||
fan3min = fan3pin;
|
||||
pwm3pin = fan3pin;
|
||||
pwm4pin = 0;
|
||||
pwm5pin = 0;
|
||||
} else { /* NCT6779D */
|
||||
regval = superio_inb(sio_data->sioreg, 0x1c);
|
||||
|
||||
@ -1810,6 +2105,10 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
|
||||
fan4pin = !(regval & (1 << 6));
|
||||
fan5pin = !(regval & (1 << 7));
|
||||
|
||||
pwm3pin = !(regval & (1 << 0));
|
||||
pwm4pin = !(regval & (1 << 1));
|
||||
pwm5pin = !(regval & (1 << 2));
|
||||
|
||||
fan3min = fan3pin;
|
||||
fan4min = fan4pin;
|
||||
}
|
||||
@ -1823,6 +2122,8 @@ nct6775_check_fan_inputs(const struct nct6775_sio_data *sio_data,
|
||||
data->has_fan |= (fan4pin << 3) | (fan5pin << 4);
|
||||
data->has_fan_min |= (fan4min << 3) | (fan5pin << 4);
|
||||
|
||||
data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) | (pwm5pin << 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1859,6 +2160,7 @@ static int nct6775_probe(struct platform_device *pdev)
|
||||
switch (data->kind) {
|
||||
case nct6775:
|
||||
data->in_num = 9;
|
||||
data->pwm_num = 3;
|
||||
data->has_fan_div = true;
|
||||
data->temp_fixed_num = 3;
|
||||
|
||||
@ -1877,8 +2179,13 @@ static int nct6775_probe(struct platform_device *pdev)
|
||||
data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
|
||||
data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
|
||||
data->REG_FAN = NCT6775_REG_FAN;
|
||||
data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
|
||||
data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
|
||||
data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
|
||||
data->REG_PWM[0] = NCT6775_REG_PWM;
|
||||
data->REG_PWM_READ = NCT6775_REG_PWM_READ;
|
||||
data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
|
||||
data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
|
||||
data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
|
||||
data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
|
||||
data->REG_ALARM = NCT6775_REG_ALARM;
|
||||
@ -1894,6 +2201,7 @@ static int nct6775_probe(struct platform_device *pdev)
|
||||
break;
|
||||
case nct6776:
|
||||
data->in_num = 9;
|
||||
data->pwm_num = 3;
|
||||
data->has_fan_div = false;
|
||||
data->temp_fixed_num = 3;
|
||||
|
||||
@ -1912,8 +2220,13 @@ static int nct6775_probe(struct platform_device *pdev)
|
||||
data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
|
||||
data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
|
||||
data->REG_FAN = NCT6775_REG_FAN;
|
||||
data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
|
||||
data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
|
||||
data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
|
||||
data->REG_PWM[0] = NCT6775_REG_PWM;
|
||||
data->REG_PWM_READ = NCT6775_REG_PWM_READ;
|
||||
data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
|
||||
data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
|
||||
data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
|
||||
data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
|
||||
data->REG_ALARM = NCT6775_REG_ALARM;
|
||||
@ -1929,6 +2242,7 @@ static int nct6775_probe(struct platform_device *pdev)
|
||||
break;
|
||||
case nct6779:
|
||||
data->in_num = 15;
|
||||
data->pwm_num = 5;
|
||||
data->has_fan_div = false;
|
||||
data->temp_fixed_num = 6;
|
||||
|
||||
@ -1947,8 +2261,13 @@ static int nct6775_probe(struct platform_device *pdev)
|
||||
data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
|
||||
data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
|
||||
data->REG_FAN = NCT6779_REG_FAN;
|
||||
data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
|
||||
data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
|
||||
data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
|
||||
data->REG_PWM[0] = NCT6775_REG_PWM;
|
||||
data->REG_PWM_READ = NCT6775_REG_PWM_READ;
|
||||
data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
|
||||
data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
|
||||
data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
|
||||
data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
|
||||
data->REG_ALARM = NCT6779_REG_ALARM;
|
||||
@ -2157,6 +2476,16 @@ static int nct6775_probe(struct platform_device *pdev)
|
||||
/* Read fan clock dividers immediately */
|
||||
nct6775_init_fan_common(dev, data);
|
||||
|
||||
/* Register sysfs hooks */
|
||||
for (i = 0; i < data->pwm_num; i++) {
|
||||
if (!(data->has_pwm & (1 << i)))
|
||||
continue;
|
||||
|
||||
err = sysfs_create_group(&dev->kobj, &nct6775_group_pwm[i]);
|
||||
if (err)
|
||||
goto exit_remove;
|
||||
}
|
||||
|
||||
for (i = 0; i < data->in_num; i++) {
|
||||
if (!(data->have_in & (1 << i)))
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user