diff options
Diffstat (limited to 'drivers/hwmon/w83627hf.c')
-rw-r--r-- | drivers/hwmon/w83627hf.c | 101 |
1 files changed, 74 insertions, 27 deletions
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 9564fb069957..b30e5796cb26 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -67,10 +67,6 @@ module_param(force_i2c, byte, 0); | |||
67 | MODULE_PARM_DESC(force_i2c, | 67 | MODULE_PARM_DESC(force_i2c, |
68 | "Initialize the i2c address of the sensors"); | 68 | "Initialize the i2c address of the sensors"); |
69 | 69 | ||
70 | static int reset; | ||
71 | module_param(reset, bool, 0); | ||
72 | MODULE_PARM_DESC(reset, "Set to one to reset chip on load"); | ||
73 | |||
74 | static int init = 1; | 70 | static int init = 1; |
75 | module_param(init, bool, 0); | 71 | module_param(init, bool, 0); |
76 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); | 72 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); |
@@ -209,6 +205,13 @@ static const u16 w83627hf_reg_temp_over[] = { 0x39, 0x155, 0x255 }; | |||
209 | #define W83627HF_REG_PWM1 0x5A | 205 | #define W83627HF_REG_PWM1 0x5A |
210 | #define W83627HF_REG_PWM2 0x5B | 206 | #define W83627HF_REG_PWM2 0x5B |
211 | 207 | ||
208 | static const u8 W83627THF_REG_PWM_ENABLE[] = { | ||
209 | 0x04, /* FAN 1 mode */ | ||
210 | 0x04, /* FAN 2 mode */ | ||
211 | 0x12, /* FAN AUX mode */ | ||
212 | }; | ||
213 | static const u8 W83627THF_PWM_ENABLE_SHIFT[] = { 2, 4, 1 }; | ||
214 | |||
212 | #define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ | 215 | #define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ |
213 | #define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ | 216 | #define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ |
214 | #define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ | 217 | #define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ |
@@ -366,6 +369,9 @@ struct w83627hf_data { | |||
366 | u32 alarms; /* Register encoding, combined */ | 369 | u32 alarms; /* Register encoding, combined */ |
367 | u32 beep_mask; /* Register encoding, combined */ | 370 | u32 beep_mask; /* Register encoding, combined */ |
368 | u8 pwm[3]; /* Register value */ | 371 | u8 pwm[3]; /* Register value */ |
372 | u8 pwm_enable[3]; /* 1 = manual | ||
373 | 2 = thermal cruise (also called SmartFan I) | ||
374 | 3 = fan speed cruise */ | ||
369 | u8 pwm_freq[3]; /* Register value */ | 375 | u8 pwm_freq[3]; /* Register value */ |
370 | u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; | 376 | u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; |
371 | 4 = thermistor */ | 377 | 4 = thermistor */ |
@@ -957,6 +963,42 @@ static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 1); | |||
957 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); | 963 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); |
958 | 964 | ||
959 | static ssize_t | 965 | static ssize_t |
966 | show_pwm_enable(struct device *dev, struct device_attribute *devattr, char *buf) | ||
967 | { | ||
968 | int nr = to_sensor_dev_attr(devattr)->index; | ||
969 | struct w83627hf_data *data = w83627hf_update_device(dev); | ||
970 | return sprintf(buf, "%d\n", data->pwm_enable[nr]); | ||
971 | } | ||
972 | |||
973 | static ssize_t | ||
974 | store_pwm_enable(struct device *dev, struct device_attribute *devattr, | ||
975 | const char *buf, size_t count) | ||
976 | { | ||
977 | int nr = to_sensor_dev_attr(devattr)->index; | ||
978 | struct w83627hf_data *data = dev_get_drvdata(dev); | ||
979 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
980 | u8 reg; | ||
981 | |||
982 | if (!val || (val > 3)) /* modes 1, 2 and 3 are supported */ | ||
983 | return -EINVAL; | ||
984 | mutex_lock(&data->update_lock); | ||
985 | data->pwm_enable[nr] = val; | ||
986 | reg = w83627hf_read_value(data, W83627THF_REG_PWM_ENABLE[nr]); | ||
987 | reg &= ~(0x03 << W83627THF_PWM_ENABLE_SHIFT[nr]); | ||
988 | reg |= (val - 1) << W83627THF_PWM_ENABLE_SHIFT[nr]; | ||
989 | w83627hf_write_value(data, W83627THF_REG_PWM_ENABLE[nr], reg); | ||
990 | mutex_unlock(&data->update_lock); | ||
991 | return count; | ||
992 | } | ||
993 | |||
994 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
995 | store_pwm_enable, 0); | ||
996 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
997 | store_pwm_enable, 1); | ||
998 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, | ||
999 | store_pwm_enable, 2); | ||
1000 | |||
1001 | static ssize_t | ||
960 | show_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) | 1002 | show_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) |
961 | { | 1003 | { |
962 | int nr = to_sensor_dev_attr(devattr)->index; | 1004 | int nr = to_sensor_dev_attr(devattr)->index; |
@@ -1223,6 +1265,11 @@ static struct attribute *w83627hf_attributes_opt[] = { | |||
1223 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, | 1265 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, |
1224 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | 1266 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, |
1225 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, | 1267 | &sensor_dev_attr_pwm3_freq.dev_attr.attr, |
1268 | |||
1269 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
1270 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
1271 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
1272 | |||
1226 | NULL | 1273 | NULL |
1227 | }; | 1274 | }; |
1228 | 1275 | ||
@@ -1366,6 +1413,19 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1366 | &sensor_dev_attr_pwm3_freq.dev_attr))) | 1413 | &sensor_dev_attr_pwm3_freq.dev_attr))) |
1367 | goto ERROR4; | 1414 | goto ERROR4; |
1368 | 1415 | ||
1416 | if (data->type != w83627hf) | ||
1417 | if ((err = device_create_file(dev, | ||
1418 | &sensor_dev_attr_pwm1_enable.dev_attr)) | ||
1419 | || (err = device_create_file(dev, | ||
1420 | &sensor_dev_attr_pwm2_enable.dev_attr))) | ||
1421 | goto ERROR4; | ||
1422 | |||
1423 | if (data->type == w83627thf || data->type == w83637hf | ||
1424 | || data->type == w83687thf) | ||
1425 | if ((err = device_create_file(dev, | ||
1426 | &sensor_dev_attr_pwm3_enable.dev_attr))) | ||
1427 | goto ERROR4; | ||
1428 | |||
1369 | data->hwmon_dev = hwmon_device_register(dev); | 1429 | data->hwmon_dev = hwmon_device_register(dev); |
1370 | if (IS_ERR(data->hwmon_dev)) { | 1430 | if (IS_ERR(data->hwmon_dev)) { |
1371 | err = PTR_ERR(data->hwmon_dev); | 1431 | err = PTR_ERR(data->hwmon_dev); |
@@ -1536,29 +1596,6 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev) | |||
1536 | enum chips type = data->type; | 1596 | enum chips type = data->type; |
1537 | u8 tmp; | 1597 | u8 tmp; |
1538 | 1598 | ||
1539 | if (reset) { | ||
1540 | /* Resetting the chip has been the default for a long time, | ||
1541 | but repeatedly caused problems (fans going to full | ||
1542 | speed...) so it is now optional. It might even go away if | ||
1543 | nobody reports it as being useful, as I see very little | ||
1544 | reason why this would be needed at all. */ | ||
1545 | dev_info(&pdev->dev, "If reset=1 solved a problem you were " | ||
1546 | "having, please report!\n"); | ||
1547 | |||
1548 | /* save this register */ | ||
1549 | i = w83627hf_read_value(data, W83781D_REG_BEEP_CONFIG); | ||
1550 | /* Reset all except Watchdog values and last conversion values | ||
1551 | This sets fan-divs to 2, among others */ | ||
1552 | w83627hf_write_value(data, W83781D_REG_CONFIG, 0x80); | ||
1553 | /* Restore the register and disable power-on abnormal beep. | ||
1554 | This saves FAN 1/2/3 input/output values set by BIOS. */ | ||
1555 | w83627hf_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); | ||
1556 | /* Disable master beep-enable (reset turns it on). | ||
1557 | Individual beeps should be reset to off but for some reason | ||
1558 | disabling this bit helps some people not get beeped */ | ||
1559 | w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 0); | ||
1560 | } | ||
1561 | |||
1562 | /* Minimize conflicts with other winbond i2c-only clients... */ | 1599 | /* Minimize conflicts with other winbond i2c-only clients... */ |
1563 | /* disable i2c subclients... how to disable main i2c client?? */ | 1600 | /* disable i2c subclients... how to disable main i2c client?? */ |
1564 | /* force i2c address to relatively uncommon address */ | 1601 | /* force i2c address to relatively uncommon address */ |
@@ -1655,6 +1692,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1655 | { | 1692 | { |
1656 | struct w83627hf_data *data = dev_get_drvdata(dev); | 1693 | struct w83627hf_data *data = dev_get_drvdata(dev); |
1657 | int i, num_temps = (data->type == w83697hf) ? 2 : 3; | 1694 | int i, num_temps = (data->type == w83697hf) ? 2 : 3; |
1695 | int num_pwms = (data->type == w83697hf) ? 2 : 3; | ||
1658 | 1696 | ||
1659 | mutex_lock(&data->update_lock); | 1697 | mutex_lock(&data->update_lock); |
1660 | 1698 | ||
@@ -1707,6 +1745,15 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1707 | break; | 1745 | break; |
1708 | } | 1746 | } |
1709 | } | 1747 | } |
1748 | if (data->type != w83627hf) { | ||
1749 | for (i = 0; i < num_pwms; i++) { | ||
1750 | u8 tmp = w83627hf_read_value(data, | ||
1751 | W83627THF_REG_PWM_ENABLE[i]); | ||
1752 | data->pwm_enable[i] = | ||
1753 | ((tmp >> W83627THF_PWM_ENABLE_SHIFT[i]) | ||
1754 | & 0x03) + 1; | ||
1755 | } | ||
1756 | } | ||
1710 | for (i = 0; i < num_temps; i++) { | 1757 | for (i = 0; i < num_temps; i++) { |
1711 | data->temp[i] = w83627hf_read_value( | 1758 | data->temp[i] = w83627hf_read_value( |
1712 | data, w83627hf_reg_temp[i]); | 1759 | data, w83627hf_reg_temp[i]); |