diff options
author | Guenter Roeck <linux@roeck-us.net> | 2013-06-25 01:21:59 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2013-08-12 01:10:39 -0400 |
commit | 30846993047b6611dece427a05b0135d97063153 (patch) | |
tree | 62da46912a7a61874832dab9700d2fef7d2da839 /drivers/hwmon/nct6775.c | |
parent | b7a61353484ca6d2d149cefda4982de5575895dd (diff) |
hwmon: (nct6775) Add support for beep attributes
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/nct6775.c')
-rw-r--r-- | drivers/hwmon/nct6775.c | 239 |
1 files changed, 218 insertions, 21 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 1560f2359f6a..6386d1b16a23 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -171,6 +171,7 @@ superio_exit(int ioreg) | |||
171 | #define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */ | 171 | #define NUM_TEMP_FIXED 6 /* Max number of fixed temp attribute sets */ |
172 | 172 | ||
173 | #define NUM_REG_ALARM 7 /* Max number of alarm registers */ | 173 | #define NUM_REG_ALARM 7 /* Max number of alarm registers */ |
174 | #define NUM_REG_BEEP 5 /* Max number of beep registers */ | ||
174 | 175 | ||
175 | /* Common and NCT6775 specific data */ | 176 | /* Common and NCT6775 specific data */ |
176 | 177 | ||
@@ -197,7 +198,7 @@ static const u16 NCT6775_REG_IN[] = { | |||
197 | 198 | ||
198 | static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B }; | 199 | static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B }; |
199 | 200 | ||
200 | /* 0..15 voltages, 16..23 fans, 24..31 temperatures */ | 201 | /* 0..15 voltages, 16..23 fans, 24..29 temperatures, 30..31 intrusion */ |
201 | 202 | ||
202 | static const s8 NCT6775_ALARM_BITS[] = { | 203 | static const s8 NCT6775_ALARM_BITS[] = { |
203 | 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */ | 204 | 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */ |
@@ -212,6 +213,23 @@ static const s8 NCT6775_ALARM_BITS[] = { | |||
212 | #define TEMP_ALARM_BASE 24 | 213 | #define TEMP_ALARM_BASE 24 |
213 | #define INTRUSION_ALARM_BASE 30 | 214 | #define INTRUSION_ALARM_BASE 30 |
214 | 215 | ||
216 | static const u16 NCT6775_REG_BEEP[NUM_REG_BEEP] = { 0x56, 0x57, 0x453, 0x4e }; | ||
217 | |||
218 | /* | ||
219 | * 0..14 voltages, 15 global beep enable, 16..23 fans, 24..29 temperatures, | ||
220 | * 30..31 intrusion | ||
221 | */ | ||
222 | static const s8 NCT6775_BEEP_BITS[] = { | ||
223 | 0, 1, 2, 3, 8, 9, 10, 16, /* in0.. in7 */ | ||
224 | 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */ | ||
225 | 21, /* global beep enable */ | ||
226 | 6, 7, 11, 28, -1, /* fan1..fan5 */ | ||
227 | -1, -1, -1, /* unused */ | ||
228 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ | ||
229 | 12, -1 }; /* intrusion0, intrusion1 */ | ||
230 | |||
231 | #define BEEP_ENABLE_BASE 15 | ||
232 | |||
215 | static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee }; | 233 | static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee }; |
216 | static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 }; | 234 | static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 }; |
217 | 235 | ||
@@ -330,6 +348,17 @@ static const s8 NCT6776_ALARM_BITS[] = { | |||
330 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ | 348 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ |
331 | 12, 9 }; /* intrusion0, intrusion1 */ | 349 | 12, 9 }; /* intrusion0, intrusion1 */ |
332 | 350 | ||
351 | static const u16 NCT6776_REG_BEEP[NUM_REG_BEEP] = { 0xb2, 0xb3, 0xb4, 0xb5 }; | ||
352 | |||
353 | static const s8 NCT6776_BEEP_BITS[] = { | ||
354 | 0, 1, 2, 3, 4, 5, 6, 7, /* in0.. in7 */ | ||
355 | 8, -1, -1, -1, -1, -1, -1, /* in8..in14 */ | ||
356 | 24, /* global beep enable */ | ||
357 | 25, 26, 27, 28, 29, /* fan1..fan5 */ | ||
358 | -1, -1, -1, /* unused */ | ||
359 | 16, 17, 18, 19, 20, 21, /* temp1..temp6 */ | ||
360 | 30, 31 }; /* intrusion0, intrusion1 */ | ||
361 | |||
333 | static const u16 NCT6776_REG_TOLERANCE_H[] = { | 362 | static const u16 NCT6776_REG_TOLERANCE_H[] = { |
334 | 0x10c, 0x20c, 0x30c, 0x80c, 0x90c }; | 363 | 0x10c, 0x20c, 0x30c, 0x80c, 0x90c }; |
335 | 364 | ||
@@ -395,6 +424,15 @@ static const s8 NCT6779_ALARM_BITS[] = { | |||
395 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ | 424 | 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ |
396 | 12, 9 }; /* intrusion0, intrusion1 */ | 425 | 12, 9 }; /* intrusion0, intrusion1 */ |
397 | 426 | ||
427 | static const s8 NCT6779_BEEP_BITS[] = { | ||
428 | 0, 1, 2, 3, 4, 5, 6, 7, /* in0.. in7 */ | ||
429 | 8, 9, 10, 11, 12, 13, 14, /* in8..in14 */ | ||
430 | 24, /* global beep enable */ | ||
431 | 25, 26, 27, 28, 29, /* fan1..fan5 */ | ||
432 | -1, -1, -1, /* unused */ | ||
433 | 16, 17, -1, -1, -1, -1, /* temp1..temp6 */ | ||
434 | 30, 31 }; /* intrusion0, intrusion1 */ | ||
435 | |||
398 | static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 }; | 436 | static const u16 NCT6779_REG_FAN[] = { 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8 }; |
399 | static const u16 NCT6779_REG_FAN_PULSES[] = { | 437 | static const u16 NCT6779_REG_FAN_PULSES[] = { |
400 | 0x644, 0x645, 0x646, 0x647, 0x648 }; | 438 | 0x644, 0x645, 0x646, 0x647, 0x648 }; |
@@ -535,6 +573,19 @@ static const s8 NCT6106_ALARM_BITS[] = { | |||
535 | 48, -1 /* intrusion0, intrusion1 */ | 573 | 48, -1 /* intrusion0, intrusion1 */ |
536 | }; | 574 | }; |
537 | 575 | ||
576 | static const u16 NCT6106_REG_BEEP[NUM_REG_BEEP] = { | ||
577 | 0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4 }; | ||
578 | |||
579 | static const s8 NCT6106_BEEP_BITS[] = { | ||
580 | 0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */ | ||
581 | 9, 10, 11, 12, -1, -1, -1, /* in8..in14 */ | ||
582 | 32, /* global beep enable */ | ||
583 | 24, 25, 26, 27, 28, /* fan1..fan5 */ | ||
584 | -1, -1, -1, /* unused */ | ||
585 | 16, 17, 18, 19, 20, 21, /* temp1..temp6 */ | ||
586 | 34, -1 /* intrusion0, intrusion1 */ | ||
587 | }; | ||
588 | |||
538 | static const u16 NCT6106_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1] | 589 | static const u16 NCT6106_REG_TEMP_ALTERNATE[ARRAY_SIZE(nct6776_temp_label) - 1] |
539 | = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x51, 0x52, 0x54 }; | 590 | = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x51, 0x52, 0x54 }; |
540 | 591 | ||
@@ -665,6 +716,7 @@ struct nct6775_data { | |||
665 | u8 DIODE_MASK; | 716 | u8 DIODE_MASK; |
666 | 717 | ||
667 | const s8 *ALARM_BITS; | 718 | const s8 *ALARM_BITS; |
719 | const s8 *BEEP_BITS; | ||
668 | 720 | ||
669 | const u16 *REG_VIN; | 721 | const u16 *REG_VIN; |
670 | const u16 *REG_IN_MINMAX[2]; | 722 | const u16 *REG_IN_MINMAX[2]; |
@@ -706,6 +758,7 @@ struct nct6775_data { | |||
706 | const u16 *REG_TEMP_OFFSET; | 758 | const u16 *REG_TEMP_OFFSET; |
707 | 759 | ||
708 | const u16 *REG_ALARM; | 760 | const u16 *REG_ALARM; |
761 | const u16 *REG_BEEP; | ||
709 | 762 | ||
710 | unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); | 763 | unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); |
711 | unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); | 764 | unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); |
@@ -728,12 +781,14 @@ struct nct6775_data { | |||
728 | bool has_fan_div; | 781 | bool has_fan_div; |
729 | 782 | ||
730 | u8 num_temp_alarms; /* 2, 3, or 6 */ | 783 | u8 num_temp_alarms; /* 2, 3, or 6 */ |
784 | u8 num_temp_beeps; /* 2, 3, or 6 */ | ||
731 | u8 temp_fixed_num; /* 3 or 6 */ | 785 | u8 temp_fixed_num; /* 3 or 6 */ |
732 | u8 temp_type[NUM_TEMP_FIXED]; | 786 | u8 temp_type[NUM_TEMP_FIXED]; |
733 | s8 temp_offset[NUM_TEMP_FIXED]; | 787 | s8 temp_offset[NUM_TEMP_FIXED]; |
734 | s16 temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst, | 788 | s16 temp[4][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst, |
735 | * 3=temp_crit */ | 789 | * 3=temp_crit */ |
736 | u64 alarms; | 790 | u64 alarms; |
791 | u64 beeps; | ||
737 | 792 | ||
738 | u8 pwm_num; /* number of pwm */ | 793 | u8 pwm_num; /* number of pwm */ |
739 | u8 pwm_mode[5]; /* 1->DC variable voltage, 0->PWM variable duty cycle */ | 794 | u8 pwm_mode[5]; /* 1->DC variable voltage, 0->PWM variable duty cycle */ |
@@ -1385,6 +1440,15 @@ static struct nct6775_data *nct6775_update_device(struct device *dev) | |||
1385 | data->alarms |= ((u64)alarm) << (i << 3); | 1440 | data->alarms |= ((u64)alarm) << (i << 3); |
1386 | } | 1441 | } |
1387 | 1442 | ||
1443 | data->beeps = 0; | ||
1444 | for (i = 0; i < NUM_REG_BEEP; i++) { | ||
1445 | u8 beep; | ||
1446 | if (!data->REG_BEEP[i]) | ||
1447 | continue; | ||
1448 | beep = nct6775_read_value(data, data->REG_BEEP[i]); | ||
1449 | data->beeps |= ((u64)beep) << (i << 3); | ||
1450 | } | ||
1451 | |||
1388 | data->last_updated = jiffies; | 1452 | data->last_updated = jiffies; |
1389 | data->valid = true; | 1453 | data->valid = true; |
1390 | } | 1454 | } |
@@ -1472,12 +1536,105 @@ show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf) | |||
1472 | return sprintf(buf, "%u\n", alarm); | 1536 | return sprintf(buf, "%u\n", alarm); |
1473 | } | 1537 | } |
1474 | 1538 | ||
1539 | static ssize_t | ||
1540 | show_beep(struct device *dev, struct device_attribute *attr, char *buf) | ||
1541 | { | ||
1542 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1543 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1544 | int nr = data->BEEP_BITS[sattr->index]; | ||
1545 | |||
1546 | return sprintf(buf, "%u\n", | ||
1547 | (unsigned int)((data->beeps >> nr) & 0x01)); | ||
1548 | } | ||
1549 | |||
1550 | static ssize_t | ||
1551 | store_beep(struct device *dev, struct device_attribute *attr, const char *buf, | ||
1552 | size_t count) | ||
1553 | { | ||
1554 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
1555 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1556 | int nr = data->BEEP_BITS[sattr->index]; | ||
1557 | int regindex = nr >> 3; | ||
1558 | unsigned long val; | ||
1559 | |||
1560 | int err = kstrtoul(buf, 10, &val); | ||
1561 | if (err < 0) | ||
1562 | return err; | ||
1563 | if (val > 1) | ||
1564 | return -EINVAL; | ||
1565 | |||
1566 | mutex_lock(&data->update_lock); | ||
1567 | if (val) | ||
1568 | data->beeps |= (1ULL << nr); | ||
1569 | else | ||
1570 | data->beeps &= ~(1ULL << nr); | ||
1571 | nct6775_write_value(data, data->REG_BEEP[regindex], | ||
1572 | (data->beeps >> (regindex << 3)) & 0xff); | ||
1573 | mutex_unlock(&data->update_lock); | ||
1574 | return count; | ||
1575 | } | ||
1576 | |||
1577 | static ssize_t | ||
1578 | show_temp_beep(struct device *dev, struct device_attribute *attr, char *buf) | ||
1579 | { | ||
1580 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
1581 | struct nct6775_data *data = nct6775_update_device(dev); | ||
1582 | unsigned int beep = 0; | ||
1583 | int nr; | ||
1584 | |||
1585 | /* | ||
1586 | * For temperatures, there is no fixed mapping from registers to beep | ||
1587 | * enable bits. Beep enable bits are determined by the temperature | ||
1588 | * source mapping. | ||
1589 | */ | ||
1590 | nr = find_temp_source(data, sattr->index, data->num_temp_beeps); | ||
1591 | if (nr >= 0) { | ||
1592 | int bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE]; | ||
1593 | beep = (data->beeps >> bit) & 0x01; | ||
1594 | } | ||
1595 | return sprintf(buf, "%u\n", beep); | ||
1596 | } | ||
1597 | |||
1598 | static ssize_t | ||
1599 | store_temp_beep(struct device *dev, struct device_attribute *attr, | ||
1600 | const char *buf, size_t count) | ||
1601 | { | ||
1602 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
1603 | struct nct6775_data *data = dev_get_drvdata(dev); | ||
1604 | int nr, bit, regindex; | ||
1605 | unsigned long val; | ||
1606 | |||
1607 | int err = kstrtoul(buf, 10, &val); | ||
1608 | if (err < 0) | ||
1609 | return err; | ||
1610 | if (val > 1) | ||
1611 | return -EINVAL; | ||
1612 | |||
1613 | nr = find_temp_source(data, sattr->index, data->num_temp_beeps); | ||
1614 | if (nr < 0) | ||
1615 | return -ENODEV; | ||
1616 | |||
1617 | bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE]; | ||
1618 | regindex = bit >> 3; | ||
1619 | |||
1620 | mutex_lock(&data->update_lock); | ||
1621 | if (val) | ||
1622 | data->beeps |= (1ULL << bit); | ||
1623 | else | ||
1624 | data->beeps &= ~(1ULL << bit); | ||
1625 | nct6775_write_value(data, data->REG_BEEP[regindex], | ||
1626 | (data->beeps >> (regindex << 3)) & 0xff); | ||
1627 | mutex_unlock(&data->update_lock); | ||
1628 | |||
1629 | return count; | ||
1630 | } | ||
1631 | |||
1475 | static umode_t nct6775_in_is_visible(struct kobject *kobj, | 1632 | static umode_t nct6775_in_is_visible(struct kobject *kobj, |
1476 | struct attribute *attr, int index) | 1633 | struct attribute *attr, int index) |
1477 | { | 1634 | { |
1478 | struct device *dev = container_of(kobj, struct device, kobj); | 1635 | struct device *dev = container_of(kobj, struct device, kobj); |
1479 | struct nct6775_data *data = dev_get_drvdata(dev); | 1636 | struct nct6775_data *data = dev_get_drvdata(dev); |
1480 | int in = index / 4; /* voltage index */ | 1637 | int in = index / 5; /* voltage index */ |
1481 | 1638 | ||
1482 | if (!(data->have_in & (1 << in))) | 1639 | if (!(data->have_in & (1 << in))) |
1483 | return 0; | 1640 | return 0; |
@@ -1487,6 +1644,8 @@ static umode_t nct6775_in_is_visible(struct kobject *kobj, | |||
1487 | 1644 | ||
1488 | SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0); | 1645 | SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0); |
1489 | SENSOR_TEMPLATE(in_alarm, "in%d_alarm", S_IRUGO, show_alarm, NULL, 0); | 1646 | SENSOR_TEMPLATE(in_alarm, "in%d_alarm", S_IRUGO, show_alarm, NULL, 0); |
1647 | SENSOR_TEMPLATE(in_beep, "in%d_beep", S_IWUSR | S_IRUGO, show_beep, store_beep, | ||
1648 | 0); | ||
1490 | SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IWUSR | S_IRUGO, show_in_reg, | 1649 | SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IWUSR | S_IRUGO, show_in_reg, |
1491 | store_in_reg, 0, 1); | 1650 | store_in_reg, 0, 1); |
1492 | SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IWUSR | S_IRUGO, show_in_reg, | 1651 | SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IWUSR | S_IRUGO, show_in_reg, |
@@ -1500,6 +1659,7 @@ SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IWUSR | S_IRUGO, show_in_reg, | |||
1500 | static struct sensor_device_template *nct6775_attributes_in_template[] = { | 1659 | static struct sensor_device_template *nct6775_attributes_in_template[] = { |
1501 | &sensor_dev_template_in_input, | 1660 | &sensor_dev_template_in_input, |
1502 | &sensor_dev_template_in_alarm, | 1661 | &sensor_dev_template_in_alarm, |
1662 | &sensor_dev_template_in_beep, | ||
1503 | &sensor_dev_template_in_min, | 1663 | &sensor_dev_template_in_min, |
1504 | &sensor_dev_template_in_max, | 1664 | &sensor_dev_template_in_max, |
1505 | NULL | 1665 | NULL |
@@ -1677,17 +1837,19 @@ static umode_t nct6775_fan_is_visible(struct kobject *kobj, | |||
1677 | { | 1837 | { |
1678 | struct device *dev = container_of(kobj, struct device, kobj); | 1838 | struct device *dev = container_of(kobj, struct device, kobj); |
1679 | struct nct6775_data *data = dev_get_drvdata(dev); | 1839 | struct nct6775_data *data = dev_get_drvdata(dev); |
1680 | int fan = index / 5; /* fan index */ | 1840 | int fan = index / 6; /* fan index */ |
1681 | int nr = index % 5; /* attribute index */ | 1841 | int nr = index % 6; /* attribute index */ |
1682 | 1842 | ||
1683 | if (!(data->has_fan & (1 << fan))) | 1843 | if (!(data->has_fan & (1 << fan))) |
1684 | return 0; | 1844 | return 0; |
1685 | 1845 | ||
1686 | if (nr == 1 && data->ALARM_BITS[FAN_ALARM_BASE + fan] == -1) | 1846 | if (nr == 1 && data->ALARM_BITS[FAN_ALARM_BASE + fan] == -1) |
1687 | return 0; | 1847 | return 0; |
1688 | if (nr == 3 && !(data->has_fan_min & (1 << fan))) | 1848 | if (nr == 2 && data->BEEP_BITS[FAN_ALARM_BASE + fan] == -1) |
1689 | return 0; | 1849 | return 0; |
1690 | if (nr == 4 && data->kind != nct6775) | 1850 | if (nr == 4 && !(data->has_fan_min & (1 << fan))) |
1851 | return 0; | ||
1852 | if (nr == 5 && data->kind != nct6775) | ||
1691 | return 0; | 1853 | return 0; |
1692 | 1854 | ||
1693 | return attr->mode; | 1855 | return attr->mode; |
@@ -1696,6 +1858,8 @@ static umode_t nct6775_fan_is_visible(struct kobject *kobj, | |||
1696 | SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0); | 1858 | SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0); |
1697 | SENSOR_TEMPLATE(fan_alarm, "fan%d_alarm", S_IRUGO, show_alarm, NULL, | 1859 | SENSOR_TEMPLATE(fan_alarm, "fan%d_alarm", S_IRUGO, show_alarm, NULL, |
1698 | FAN_ALARM_BASE); | 1860 | FAN_ALARM_BASE); |
1861 | SENSOR_TEMPLATE(fan_beep, "fan%d_beep", S_IWUSR | S_IRUGO, show_beep, | ||
1862 | store_beep, FAN_ALARM_BASE); | ||
1699 | SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IWUSR | S_IRUGO, show_fan_pulses, | 1863 | SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IWUSR | S_IRUGO, show_fan_pulses, |
1700 | store_fan_pulses, 0); | 1864 | store_fan_pulses, 0); |
1701 | SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IWUSR | S_IRUGO, show_fan_min, | 1865 | SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IWUSR | S_IRUGO, show_fan_min, |
@@ -1710,9 +1874,10 @@ SENSOR_TEMPLATE(fan_div, "fan%d_div", S_IRUGO, show_fan_div, NULL, 0); | |||
1710 | static struct sensor_device_template *nct6775_attributes_fan_template[] = { | 1874 | static struct sensor_device_template *nct6775_attributes_fan_template[] = { |
1711 | &sensor_dev_template_fan_input, | 1875 | &sensor_dev_template_fan_input, |
1712 | &sensor_dev_template_fan_alarm, /* 1 */ | 1876 | &sensor_dev_template_fan_alarm, /* 1 */ |
1877 | &sensor_dev_template_fan_beep, /* 2 */ | ||
1713 | &sensor_dev_template_fan_pulses, | 1878 | &sensor_dev_template_fan_pulses, |
1714 | &sensor_dev_template_fan_min, /* 3 */ | 1879 | &sensor_dev_template_fan_min, /* 4 */ |
1715 | &sensor_dev_template_fan_div, /* 4 */ | 1880 | &sensor_dev_template_fan_div, /* 5 */ |
1716 | NULL | 1881 | NULL |
1717 | }; | 1882 | }; |
1718 | 1883 | ||
@@ -1855,8 +2020,8 @@ static umode_t nct6775_temp_is_visible(struct kobject *kobj, | |||
1855 | { | 2020 | { |
1856 | struct device *dev = container_of(kobj, struct device, kobj); | 2021 | struct device *dev = container_of(kobj, struct device, kobj); |
1857 | struct nct6775_data *data = dev_get_drvdata(dev); | 2022 | struct nct6775_data *data = dev_get_drvdata(dev); |
1858 | int temp = index / 9; /* temp index */ | 2023 | int temp = index / 10; /* temp index */ |
1859 | int nr = index % 9; /* attribute index */ | 2024 | int nr = index % 10; /* attribute index */ |
1860 | 2025 | ||
1861 | if (!(data->have_temp & (1 << temp))) | 2026 | if (!(data->have_temp & (1 << temp))) |
1862 | return 0; | 2027 | return 0; |
@@ -1864,20 +2029,23 @@ static umode_t nct6775_temp_is_visible(struct kobject *kobj, | |||
1864 | if (nr == 2 && find_temp_source(data, temp, data->num_temp_alarms) < 0) | 2029 | if (nr == 2 && find_temp_source(data, temp, data->num_temp_alarms) < 0) |
1865 | return 0; /* alarm */ | 2030 | return 0; /* alarm */ |
1866 | 2031 | ||
1867 | if (nr == 3 && !data->reg_temp[1][temp]) /* max */ | 2032 | if (nr == 3 && find_temp_source(data, temp, data->num_temp_beeps) < 0) |
2033 | return 0; /* beep */ | ||
2034 | |||
2035 | if (nr == 4 && !data->reg_temp[1][temp]) /* max */ | ||
1868 | return 0; | 2036 | return 0; |
1869 | 2037 | ||
1870 | if (nr == 4 && !data->reg_temp[2][temp]) /* max_hyst */ | 2038 | if (nr == 5 && !data->reg_temp[2][temp]) /* max_hyst */ |
1871 | return 0; | 2039 | return 0; |
1872 | 2040 | ||
1873 | if (nr == 5 && !data->reg_temp[3][temp]) /* crit */ | 2041 | if (nr == 6 && !data->reg_temp[3][temp]) /* crit */ |
1874 | return 0; | 2042 | return 0; |
1875 | 2043 | ||
1876 | if (nr == 6 && !data->reg_temp[4][temp]) /* lcrit */ | 2044 | if (nr == 7 && !data->reg_temp[4][temp]) /* lcrit */ |
1877 | return 0; | 2045 | return 0; |
1878 | 2046 | ||
1879 | /* offset and type only apply to fixed sensors */ | 2047 | /* offset and type only apply to fixed sensors */ |
1880 | if (nr > 6 && !(data->have_temp_fixed & (1 << temp))) | 2048 | if (nr > 7 && !(data->have_temp_fixed & (1 << temp))) |
1881 | return 0; | 2049 | return 0; |
1882 | 2050 | ||
1883 | return attr->mode; | 2051 | return attr->mode; |
@@ -1898,6 +2066,8 @@ SENSOR_TEMPLATE(temp_offset, "temp%d_offset", S_IRUGO | S_IWUSR, | |||
1898 | SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO | S_IWUSR, show_temp_type, | 2066 | SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO | S_IWUSR, show_temp_type, |
1899 | store_temp_type, 0); | 2067 | store_temp_type, 0); |
1900 | SENSOR_TEMPLATE(temp_alarm, "temp%d_alarm", S_IRUGO, show_temp_alarm, NULL, 0); | 2068 | SENSOR_TEMPLATE(temp_alarm, "temp%d_alarm", S_IRUGO, show_temp_alarm, NULL, 0); |
2069 | SENSOR_TEMPLATE(temp_beep, "temp%d_beep", S_IRUGO | S_IWUSR, show_temp_beep, | ||
2070 | store_temp_beep, 0); | ||
1901 | 2071 | ||
1902 | /* | 2072 | /* |
1903 | * nct6775_temp_is_visible uses the index into the following array | 2073 | * nct6775_temp_is_visible uses the index into the following array |
@@ -1908,12 +2078,13 @@ static struct sensor_device_template *nct6775_attributes_temp_template[] = { | |||
1908 | &sensor_dev_template_temp_input, | 2078 | &sensor_dev_template_temp_input, |
1909 | &sensor_dev_template_temp_label, | 2079 | &sensor_dev_template_temp_label, |
1910 | &sensor_dev_template_temp_alarm, /* 2 */ | 2080 | &sensor_dev_template_temp_alarm, /* 2 */ |
1911 | &sensor_dev_template_temp_max, /* 3 */ | 2081 | &sensor_dev_template_temp_beep, /* 3 */ |
1912 | &sensor_dev_template_temp_max_hyst, /* 4 */ | 2082 | &sensor_dev_template_temp_max, /* 4 */ |
1913 | &sensor_dev_template_temp_crit, /* 5 */ | 2083 | &sensor_dev_template_temp_max_hyst, /* 5 */ |
1914 | &sensor_dev_template_temp_lcrit, /* 6 */ | 2084 | &sensor_dev_template_temp_crit, /* 6 */ |
1915 | &sensor_dev_template_temp_offset, /* 7 */ | 2085 | &sensor_dev_template_temp_lcrit, /* 7 */ |
1916 | &sensor_dev_template_temp_type, /* 8 */ | 2086 | &sensor_dev_template_temp_offset, /* 8 */ |
2087 | &sensor_dev_template_temp_type, /* 9 */ | ||
1917 | NULL | 2088 | NULL |
1918 | }; | 2089 | }; |
1919 | 2090 | ||
@@ -2845,6 +3016,12 @@ static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm, | |||
2845 | clear_caseopen, INTRUSION_ALARM_BASE); | 3016 | clear_caseopen, INTRUSION_ALARM_BASE); |
2846 | static SENSOR_DEVICE_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm, | 3017 | static SENSOR_DEVICE_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm, |
2847 | clear_caseopen, INTRUSION_ALARM_BASE + 1); | 3018 | clear_caseopen, INTRUSION_ALARM_BASE + 1); |
3019 | static SENSOR_DEVICE_ATTR(intrusion0_beep, S_IWUSR | S_IRUGO, show_beep, | ||
3020 | store_beep, INTRUSION_ALARM_BASE); | ||
3021 | static SENSOR_DEVICE_ATTR(intrusion1_beep, S_IWUSR | S_IRUGO, show_beep, | ||
3022 | store_beep, INTRUSION_ALARM_BASE + 1); | ||
3023 | static SENSOR_DEVICE_ATTR(beep_enable, S_IWUSR | S_IRUGO, show_beep, | ||
3024 | store_beep, BEEP_ENABLE_BASE); | ||
2848 | 3025 | ||
2849 | static umode_t nct6775_other_is_visible(struct kobject *kobj, | 3026 | static umode_t nct6775_other_is_visible(struct kobject *kobj, |
2850 | struct attribute *attr, int index) | 3027 | struct attribute *attr, int index) |
@@ -2860,6 +3037,11 @@ static umode_t nct6775_other_is_visible(struct kobject *kobj, | |||
2860 | return 0; | 3037 | return 0; |
2861 | } | 3038 | } |
2862 | 3039 | ||
3040 | if (index == 4 || index == 5) { | ||
3041 | if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 4] < 0) | ||
3042 | return 0; | ||
3043 | } | ||
3044 | |||
2863 | return attr->mode; | 3045 | return attr->mode; |
2864 | } | 3046 | } |
2865 | 3047 | ||
@@ -2873,6 +3055,9 @@ static struct attribute *nct6775_attributes_other[] = { | |||
2873 | &dev_attr_cpu0_vid.attr, /* 1 */ | 3055 | &dev_attr_cpu0_vid.attr, /* 1 */ |
2874 | &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, /* 2 */ | 3056 | &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, /* 2 */ |
2875 | &sensor_dev_attr_intrusion1_alarm.dev_attr.attr, /* 3 */ | 3057 | &sensor_dev_attr_intrusion1_alarm.dev_attr.attr, /* 3 */ |
3058 | &sensor_dev_attr_intrusion0_beep.dev_attr.attr, /* 4 */ | ||
3059 | &sensor_dev_attr_intrusion1_beep.dev_attr.attr, /* 5 */ | ||
3060 | &sensor_dev_attr_beep_enable.dev_attr.attr, /* 6 */ | ||
2876 | 3061 | ||
2877 | NULL | 3062 | NULL |
2878 | }; | 3063 | }; |
@@ -3094,6 +3279,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3094 | data->auto_pwm_num = 4; | 3279 | data->auto_pwm_num = 4; |
3095 | data->temp_fixed_num = 3; | 3280 | data->temp_fixed_num = 3; |
3096 | data->num_temp_alarms = 6; | 3281 | data->num_temp_alarms = 6; |
3282 | data->num_temp_beeps = 6; | ||
3097 | 3283 | ||
3098 | data->fan_from_reg = fan_from_reg13; | 3284 | data->fan_from_reg = fan_from_reg13; |
3099 | data->fan_from_reg_min = fan_from_reg13; | 3285 | data->fan_from_reg_min = fan_from_reg13; |
@@ -3142,6 +3328,8 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3142 | data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE; | 3328 | data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE; |
3143 | data->REG_ALARM = NCT6106_REG_ALARM; | 3329 | data->REG_ALARM = NCT6106_REG_ALARM; |
3144 | data->ALARM_BITS = NCT6106_ALARM_BITS; | 3330 | data->ALARM_BITS = NCT6106_ALARM_BITS; |
3331 | data->REG_BEEP = NCT6106_REG_BEEP; | ||
3332 | data->BEEP_BITS = NCT6106_BEEP_BITS; | ||
3145 | 3333 | ||
3146 | reg_temp = NCT6106_REG_TEMP; | 3334 | reg_temp = NCT6106_REG_TEMP; |
3147 | num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP); | 3335 | num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP); |
@@ -3161,8 +3349,10 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3161 | data->has_fan_div = true; | 3349 | data->has_fan_div = true; |
3162 | data->temp_fixed_num = 3; | 3350 | data->temp_fixed_num = 3; |
3163 | data->num_temp_alarms = 3; | 3351 | data->num_temp_alarms = 3; |
3352 | data->num_temp_beeps = 3; | ||
3164 | 3353 | ||
3165 | data->ALARM_BITS = NCT6775_ALARM_BITS; | 3354 | data->ALARM_BITS = NCT6775_ALARM_BITS; |
3355 | data->BEEP_BITS = NCT6775_BEEP_BITS; | ||
3166 | 3356 | ||
3167 | data->fan_from_reg = fan_from_reg16; | 3357 | data->fan_from_reg = fan_from_reg16; |
3168 | data->fan_from_reg_min = fan_from_reg8; | 3358 | data->fan_from_reg_min = fan_from_reg8; |
@@ -3211,6 +3401,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3211 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; | 3401 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; |
3212 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; | 3402 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; |
3213 | data->REG_ALARM = NCT6775_REG_ALARM; | 3403 | data->REG_ALARM = NCT6775_REG_ALARM; |
3404 | data->REG_BEEP = NCT6775_REG_BEEP; | ||
3214 | 3405 | ||
3215 | reg_temp = NCT6775_REG_TEMP; | 3406 | reg_temp = NCT6775_REG_TEMP; |
3216 | num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP); | 3407 | num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP); |
@@ -3228,8 +3419,10 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3228 | data->has_fan_div = false; | 3419 | data->has_fan_div = false; |
3229 | data->temp_fixed_num = 3; | 3420 | data->temp_fixed_num = 3; |
3230 | data->num_temp_alarms = 3; | 3421 | data->num_temp_alarms = 3; |
3422 | data->num_temp_beeps = 6; | ||
3231 | 3423 | ||
3232 | data->ALARM_BITS = NCT6776_ALARM_BITS; | 3424 | data->ALARM_BITS = NCT6776_ALARM_BITS; |
3425 | data->BEEP_BITS = NCT6776_BEEP_BITS; | ||
3233 | 3426 | ||
3234 | data->fan_from_reg = fan_from_reg13; | 3427 | data->fan_from_reg = fan_from_reg13; |
3235 | data->fan_from_reg_min = fan_from_reg13; | 3428 | data->fan_from_reg_min = fan_from_reg13; |
@@ -3278,6 +3471,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3278 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; | 3471 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; |
3279 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; | 3472 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; |
3280 | data->REG_ALARM = NCT6775_REG_ALARM; | 3473 | data->REG_ALARM = NCT6775_REG_ALARM; |
3474 | data->REG_BEEP = NCT6776_REG_BEEP; | ||
3281 | 3475 | ||
3282 | reg_temp = NCT6775_REG_TEMP; | 3476 | reg_temp = NCT6775_REG_TEMP; |
3283 | num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP); | 3477 | num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP); |
@@ -3295,8 +3489,10 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3295 | data->has_fan_div = false; | 3489 | data->has_fan_div = false; |
3296 | data->temp_fixed_num = 6; | 3490 | data->temp_fixed_num = 6; |
3297 | data->num_temp_alarms = 2; | 3491 | data->num_temp_alarms = 2; |
3492 | data->num_temp_beeps = 2; | ||
3298 | 3493 | ||
3299 | data->ALARM_BITS = NCT6779_ALARM_BITS; | 3494 | data->ALARM_BITS = NCT6779_ALARM_BITS; |
3495 | data->BEEP_BITS = NCT6779_BEEP_BITS; | ||
3300 | 3496 | ||
3301 | data->fan_from_reg = fan_from_reg13; | 3497 | data->fan_from_reg = fan_from_reg13; |
3302 | data->fan_from_reg_min = fan_from_reg13; | 3498 | data->fan_from_reg_min = fan_from_reg13; |
@@ -3349,6 +3545,7 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3349 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; | 3545 | data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL; |
3350 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; | 3546 | data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE; |
3351 | data->REG_ALARM = NCT6779_REG_ALARM; | 3547 | data->REG_ALARM = NCT6779_REG_ALARM; |
3548 | data->REG_BEEP = NCT6776_REG_BEEP; | ||
3352 | 3549 | ||
3353 | reg_temp = NCT6779_REG_TEMP; | 3550 | reg_temp = NCT6779_REG_TEMP; |
3354 | num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); | 3551 | num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); |