aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/nct6775.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/nct6775.c')
-rw-r--r--drivers/hwmon/nct6775.c64
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
206static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; 206static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
207static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d }; 207static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
208static const u16 NCT6775_REG_FAN_PULSES[] = { 0x641, 0x642, 0x643, 0x644, 0 };
208 209
209static const u16 NCT6775_REG_TEMP[] = { 210static 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
266static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 }; 267static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642 };
268static const u16 NCT6776_REG_FAN_PULSES[] = { 0x644, 0x645, 0x646, 0, 0 };
267 269
268static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = { 270static 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
321static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 }; 323static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 };
324static const u16 NCT6779_REG_FAN_PULSES[] = {
325 0x644, 0x645, 0x646, 0x647, 0x648 };
322 326
323static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 }; 327static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
324static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = { 328static 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
1236static ssize_t
1237show_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
1246static ssize_t
1247store_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
1228static struct sensor_device_attribute sda_fan_input[] = { 1271static 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
1300static 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
1257static struct sensor_device_attribute sda_fan_div[] = { 1313static 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