diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwmon/nct6775.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index bafcae55e255..fea6ed7a0044 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -205,6 +205,7 @@ static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 }; | |||
205 | 205 | ||
206 | static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; | 206 | static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; |
207 | static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d }; | 207 | static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d }; |
208 | static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 }; | ||
208 | 209 | ||
209 | static const u16 NCT6775_REG_TEMP[] = { | 210 | static const u16 NCT6775_REG_TEMP[] = { |
210 | 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d }; | 211 | 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d }; |
@@ -264,6 +265,7 @@ static const s8 NCT6776_ALARM_BITS[] = { | |||
264 | 12, 9 }; /* intrusion0, intrusion1 */ | 265 | 12, 9 }; /* intrusion0, intrusion1 */ |
265 | 266 | ||
266 | static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 }; | 267 | static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 }; |
268 | static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 }; | ||
267 | 269 | ||
268 | static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { | 270 | static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { |
269 | 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A }; | 271 | 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A }; |
@@ -319,6 +321,8 @@ static const s8 NCT6779_ALARM_BITS[] = { | |||
319 | 12, 9 }; /* intrusion0, intrusion1 */ | 321 | 12, 9 }; /* intrusion0, intrusion1 */ |
320 | 322 | ||
321 | static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 }; | 323 | static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 }; |
324 | static const u16 NCT6779_REG_FAN_PULSES[] = { | ||
325 | 0x644, 0x645, 0x646, 0x647, 0x648 }; | ||
322 | 326 | ||
323 | static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; | 327 | static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; |
324 | static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = { | 328 | static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = { |
@@ -462,6 +466,7 @@ struct nct6775_data { | |||
462 | 466 | ||
463 | const u16 *REG_FAN; | 467 | const u16 *REG_FAN; |
464 | const u16 *REG_FAN_MIN; | 468 | const u16 *REG_FAN_MIN; |
469 | const u16 *REG_FAN_PULSES; | ||
465 | 470 | ||
466 | const u16 *REG_TEMP_SOURCE; /* temp register sources */ | 471 | const u16 *REG_TEMP_SOURCE; /* temp register sources */ |
467 | const u16 *REG_TEMP_OFFSET; | 472 | const u16 *REG_TEMP_OFFSET; |
@@ -481,6 +486,7 @@ struct nct6775_data { | |||
481 | u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ | 486 | u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ |
482 | unsigned int rpm[5]; | 487 | unsigned int rpm[5]; |
483 | u16 fan_min[5]; | 488 | u16 fan_min[5]; |
489 | u8 fan_pulses[5]; | ||
484 | u8 fan_div[5]; | 490 | u8 fan_div[5]; |
485 | u8 has_fan; /* some fan inputs can be disabled */ | 491 | u8 has_fan; /* some fan inputs can be disabled */ |
486 | u8 has_fan_min; /* some fans don't have min register */ | 492 | u8 has_fan_min; /* some fans don't have min register */ |
@@ -802,6 +808,8 @@ static struct nct6775_data *nct6775_update_device(struct device *dev) | |||
802 | if (data->has_fan_min & (1 << i)) | 808 | if (data->has_fan_min & (1 << i)) |
803 | data->fan_min[i] = nct6775_read_value(data, | 809 | data->fan_min[i] = nct6775_read_value(data, |
804 | data->REG_FAN_MIN[i]); | 810 | data->REG_FAN_MIN[i]); |
811 | data->fan_pulses[i] = | ||
812 | nct6775_read_value(data, data->REG_FAN_PULSES[i]); | ||
805 | 813 | ||
806 | nct6775_select_fan_div(dev, data, i, reg); | 814 | nct6775_select_fan_div(dev, data, i, reg); |
807 | } | 815 | } |
@@ -1225,6 +1233,41 @@ write_min: | |||
1225 | return count; | 1233 | return count; |
1226 | } | 1234 | } |
1227 | 1235 | ||
1236 | static ssize_t | ||
1237 | show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf) | ||
1238 | { | ||
1239 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1240 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1241 | int p = data->fan_pulses[sattr->index]; | ||
1242 | |||
1243 | return sprintf(buf, "%d\n", p ? : 4); | ||
1244 | } | ||
1245 | |||
1246 | static ssize_t | ||
1247 | store_fan_pulses(struct device *dev, struct device_attribute *attr, | ||
1248 | const char *buf, size_t count) | ||
1249 | { | ||
1250 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1251 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1252 | int nr = sattr->index; | ||
1253 | unsigned long val; | ||
1254 | int err; | ||
1255 | |||
1256 | err = kstrtoul(buf, 10, &val); | ||
1257 | if (err < 0) | ||
1258 | return err; | ||
1259 | |||
1260 | if (val > 4) | ||
1261 | return -EINVAL; | ||
1262 | |||
1263 | mutex_lock(&data->update_lock); | ||
1264 | data->fan_pulses[nr] = val & 3; | ||
1265 | nct6775_write_value(data, data->REG_FAN_PULSES[nr], val & 3); | ||
1266 | mutex_unlock(&data->update_lock); | ||
1267 | |||
1268 | return count; | ||
1269 | } | ||
1270 | |||
1228 | static struct sensor_device_attribute sda_fan_input[] = { | 1271 | static struct sensor_device_attribute sda_fan_input[] = { |
1229 | SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), | 1272 | SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), |
1230 | SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), | 1273 | SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), |
@@ -1254,6 +1297,19 @@ static struct sensor_device_attribute sda_fan_min[] = { | |||
1254 | store_fan_min, 4), | 1297 | store_fan_min, 4), |
1255 | }; | 1298 | }; |
1256 | 1299 | ||
1300 | static struct sensor_device_attribute sda_fan_pulses[] = { | ||
1301 | SENSOR_ATTR(fan1_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1302 | store_fan_pulses, 0), | ||
1303 | SENSOR_ATTR(fan2_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1304 | store_fan_pulses, 1), | ||
1305 | SENSOR_ATTR(fan3_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1306 | store_fan_pulses, 2), | ||
1307 | SENSOR_ATTR(fan4_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1308 | store_fan_pulses, 3), | ||
1309 | SENSOR_ATTR(fan5_pulses, S_IWUSR | S_IRUGO, show_fan_pulses, | ||
1310 | store_fan_pulses, 4), | ||
1311 | }; | ||
1312 | |||
1257 | static struct sensor_device_attribute sda_fan_div[] = { | 1313 | static struct sensor_device_attribute sda_fan_div[] = { |
1258 | SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), | 1314 | SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), |
1259 | SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1), | 1315 | SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1), |
@@ -1621,6 +1677,7 @@ static void nct6775_device_remove_files(struct device *dev) | |||
1621 | device_remove_file(dev, &sda_fan_alarm[i].dev_attr); | 1677 | device_remove_file(dev, &sda_fan_alarm[i].dev_attr); |
1622 | device_remove_file(dev, &sda_fan_div[i].dev_attr); | 1678 | device_remove_file(dev, &sda_fan_div[i].dev_attr); |
1623 | device_remove_file(dev, &sda_fan_min[i].dev_attr); | 1679 | device_remove_file(dev, &sda_fan_min[i].dev_attr); |
1680 | device_remove_file(dev, &sda_fan_pulses[i].dev_attr); | ||
1624 | } | 1681 | } |
1625 | for (i = 0; i < NUM_TEMP; i++) { | 1682 | for (i = 0; i < NUM_TEMP; i++) { |
1626 | if (!(data->have_temp & (1 << i))) | 1683 | if (!(data->have_temp & (1 << i))) |
@@ -1809,6 +1866,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
1809 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; | 1866 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; |
1810 | data->REG_FAN = NCT6775_REG_FAN; | 1867 | data->REG_FAN = NCT6775_REG_FAN; |
1811 | data->REG_FAN_MIN = NCT6775_REG_FAN_MIN; | 1868 | data->REG_FAN_MIN = NCT6775_REG_FAN_MIN; |
1869 | data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES; | ||
1812 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; | 1870 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; |
1813 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; | 1871 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; |
1814 | data->REG_ALARM = NCT6775_REG_ALARM; | 1872 | data->REG_ALARM = NCT6775_REG_ALARM; |
@@ -1843,6 +1901,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
1843 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; | 1901 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; |
1844 | data->REG_FAN = NCT6775_REG_FAN; | 1902 | data->REG_FAN = NCT6775_REG_FAN; |
1845 | data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; | 1903 | data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; |
1904 | data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES; | ||
1846 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; | 1905 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; |
1847 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; | 1906 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; |
1848 | data->REG_ALARM = NCT6775_REG_ALARM; | 1907 | data->REG_ALARM = NCT6775_REG_ALARM; |
@@ -1877,6 +1936,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
1877 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; | 1936 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; |
1878 | data->REG_FAN = NCT6779_REG_FAN; | 1937 | data->REG_FAN = NCT6779_REG_FAN; |
1879 | data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; | 1938 | data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; |
1939 | data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES; | ||
1880 | data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; | 1940 | data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; |
1881 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; | 1941 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; |
1882 | data->REG_ALARM = NCT6779_REG_ALARM; | 1942 | data->REG_ALARM = NCT6779_REG_ALARM; |
@@ -2094,6 +2154,10 @@ static int nct6775_probe(struct platform_device *pdev) | |||
2094 | if (err) | 2154 | if (err) |
2095 | goto exit_remove; | 2155 | goto exit_remove; |
2096 | } | 2156 | } |
2157 | err = device_create_file(dev, | ||
2158 | &sda_fan_pulses[i].dev_attr); | ||
2159 | if (err) | ||
2160 | goto exit_remove; | ||
2097 | } | 2161 | } |
2098 | } | 2162 | } |
2099 | 2163 | ||