Commit 5c25d954d37b7c18606d7ef99122424552b86ef2
1 parent
1c65dc365e
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
hwmon: (nct6775) Add support for fanX_pulses sysfs attribute
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Showing 1 changed file with 64 additions and 0 deletions Side-by-side Diff
drivers/hwmon/nct6775.c
... | ... | @@ -205,6 +205,7 @@ |
205 | 205 | |
206 | 206 | static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; |
207 | 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 | 210 | static const u16 NCT6775_REG_TEMP[] = { |
210 | 211 | 0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d }; |
... | ... | @@ -264,6 +265,7 @@ |
264 | 265 | 12, 9 }; /* intrusion0, intrusion1 */ |
265 | 266 | |
266 | 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 | 270 | static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { |
269 | 271 | 0x18, 0x152, 0x252, 0x628, 0x629, 0x62A }; |
... | ... | @@ -319,6 +321,8 @@ |
319 | 321 | 12, 9 }; /* intrusion0, intrusion1 */ |
320 | 322 | |
321 | 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 | 327 | static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; |
324 | 328 | static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = { |
... | ... | @@ -462,6 +466,7 @@ |
462 | 466 | |
463 | 467 | const u16 *REG_FAN; |
464 | 468 | const u16 *REG_FAN_MIN; |
469 | + const u16 *REG_FAN_PULSES; | |
465 | 470 | |
466 | 471 | const u16 *REG_TEMP_SOURCE; /* temp register sources */ |
467 | 472 | const u16 *REG_TEMP_OFFSET; |
... | ... | @@ -481,6 +486,7 @@ |
481 | 486 | u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ |
482 | 487 | unsigned int rpm[5]; |
483 | 488 | u16 fan_min[5]; |
489 | + u8 fan_pulses[5]; | |
484 | 490 | u8 fan_div[5]; |
485 | 491 | u8 has_fan; /* some fan inputs can be disabled */ |
486 | 492 | u8 has_fan_min; /* some fans don't have min register */ |
... | ... | @@ -802,6 +808,8 @@ |
802 | 808 | if (data->has_fan_min & (1 << i)) |
803 | 809 | data->fan_min[i] = nct6775_read_value(data, |
804 | 810 | data->REG_FAN_MIN[i]); |
811 | + data->fan_pulses[i] = | |
812 | + nct6775_read_value(data, data->REG_FAN_PULSES[i]); | |
805 | 813 | |
806 | 814 | nct6775_select_fan_div(dev, data, i, reg); |
807 | 815 | } |
... | ... | @@ -1225,6 +1233,41 @@ |
1225 | 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 | 1271 | static struct sensor_device_attribute sda_fan_input[] = { |
1229 | 1272 | SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), |
1230 | 1273 | SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), |
... | ... | @@ -1254,6 +1297,19 @@ |
1254 | 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 | 1313 | static struct sensor_device_attribute sda_fan_div[] = { |
1258 | 1314 | SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), |
1259 | 1315 | SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1), |
... | ... | @@ -1621,6 +1677,7 @@ |
1621 | 1677 | device_remove_file(dev, &sda_fan_alarm[i].dev_attr); |
1622 | 1678 | device_remove_file(dev, &sda_fan_div[i].dev_attr); |
1623 | 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 | 1682 | for (i = 0; i < NUM_TEMP; i++) { |
1626 | 1683 | if (!(data->have_temp & (1 << i))) |
... | ... | @@ -1809,6 +1866,7 @@ |
1809 | 1866 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; |
1810 | 1867 | data->REG_FAN = NCT6775_REG_FAN; |
1811 | 1868 | data->REG_FAN_MIN = NCT6775_REG_FAN_MIN; |
1869 | + data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES; | |
1812 | 1870 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; |
1813 | 1871 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; |
1814 | 1872 | data->REG_ALARM = NCT6775_REG_ALARM; |
... | ... | @@ -1843,6 +1901,7 @@ |
1843 | 1901 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; |
1844 | 1902 | data->REG_FAN = NCT6775_REG_FAN; |
1845 | 1903 | data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; |
1904 | + data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES; | |
1846 | 1905 | data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET; |
1847 | 1906 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; |
1848 | 1907 | data->REG_ALARM = NCT6775_REG_ALARM; |
... | ... | @@ -1877,6 +1936,7 @@ |
1877 | 1936 | data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX; |
1878 | 1937 | data->REG_FAN = NCT6779_REG_FAN; |
1879 | 1938 | data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; |
1939 | + data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES; | |
1880 | 1940 | data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET; |
1881 | 1941 | data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE; |
1882 | 1942 | data->REG_ALARM = NCT6779_REG_ALARM; |
... | ... | @@ -2094,6 +2154,10 @@ |
2094 | 2154 | if (err) |
2095 | 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 |