diff options
author | Jean Delvare <khali@linux-fr.org> | 2010-11-15 15:38:57 -0500 |
---|---|---|
committer | Jean Delvare <khali@endymion.delvare> | 2010-11-15 15:38:57 -0500 |
commit | 52d159eecced3e4ead901e2a14347f5c11ea4bab (patch) | |
tree | 64b1e2f4bebba1a5580a4db5514c62535ddc2fd2 /drivers/hwmon | |
parent | 793c51d5fdfa76043f1221fdaa022f50146e8386 (diff) |
hwmon: (w83795) Check for BEEP pin availability
On the W83795ADG, there's a single pin for BEEP and OVT#, so you
can't have both. Check the configuration and don't create beep
attributes when BEEP pin is not available.
The W83795G has a dedicated BEEP pin so the functionality is always
available there.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/w83795.c | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index 90f4ffb357b7..cdbc7448491e 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c | |||
@@ -171,6 +171,9 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = { | |||
171 | #define W83795_REG_CLR_CHASSIS 0x4D | 171 | #define W83795_REG_CLR_CHASSIS 0x4D |
172 | #define W83795_REG_BEEP(index) (0x50 + (index)) | 172 | #define W83795_REG_BEEP(index) (0x50 + (index)) |
173 | 173 | ||
174 | #define W83795_REG_OVT_CFG 0x58 | ||
175 | #define OVT_CFG_SEL (1 << 7) | ||
176 | |||
174 | 177 | ||
175 | #define W83795_REG_FCMS1 0x201 | 178 | #define W83795_REG_FCMS1 0x201 |
176 | #define W83795_REG_FCMS2 0x208 | 179 | #define W83795_REG_FCMS2 0x208 |
@@ -378,6 +381,7 @@ struct w83795_data { | |||
378 | u8 setup_pwm[3]; /* Register value */ | 381 | u8 setup_pwm[3]; /* Register value */ |
379 | 382 | ||
380 | u8 alarms[6]; /* Register value */ | 383 | u8 alarms[6]; /* Register value */ |
384 | u8 enable_beep; | ||
381 | u8 beeps[6]; /* Register value */ | 385 | u8 beeps[6]; /* Register value */ |
382 | 386 | ||
383 | char valid; | 387 | char valid; |
@@ -508,8 +512,11 @@ static void w83795_update_limits(struct i2c_client *client) | |||
508 | } | 512 | } |
509 | 513 | ||
510 | /* Read beep settings */ | 514 | /* Read beep settings */ |
511 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) | 515 | if (data->enable_beep) { |
512 | data->beeps[i] = w83795_read(client, W83795_REG_BEEP(i)); | 516 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) |
517 | data->beeps[i] = | ||
518 | w83795_read(client, W83795_REG_BEEP(i)); | ||
519 | } | ||
513 | 520 | ||
514 | data->valid_limits = 1; | 521 | data->valid_limits = 1; |
515 | } | 522 | } |
@@ -1588,7 +1595,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1588 | 1595 | ||
1589 | #define NOT_USED -1 | 1596 | #define NOT_USED -1 |
1590 | 1597 | ||
1591 | /* Don't change the attribute order, _max and _min are accessed by index | 1598 | /* Don't change the attribute order, _max, _min and _beep are accessed by index |
1592 | * somewhere else in the code */ | 1599 | * somewhere else in the code */ |
1593 | #define SENSOR_ATTR_IN(index) { \ | 1600 | #define SENSOR_ATTR_IN(index) { \ |
1594 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ | 1601 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ |
@@ -1603,6 +1610,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1603 | show_alarm_beep, store_beep, BEEP_ENABLE, \ | 1610 | show_alarm_beep, store_beep, BEEP_ENABLE, \ |
1604 | index + ((index > 14) ? 1 : 0)) } | 1611 | index + ((index > 14) ? 1 : 0)) } |
1605 | 1612 | ||
1613 | /* Don't change the attribute order, _beep is accessed by index | ||
1614 | * somewhere else in the code */ | ||
1606 | #define SENSOR_ATTR_FAN(index) { \ | 1615 | #define SENSOR_ATTR_FAN(index) { \ |
1607 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ | 1616 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ |
1608 | NULL, FAN_INPUT, index - 1), \ | 1617 | NULL, FAN_INPUT, index - 1), \ |
@@ -1631,6 +1640,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1631 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ | 1640 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ |
1632 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } | 1641 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } |
1633 | 1642 | ||
1643 | /* Don't change the attribute order, _beep is accessed by index | ||
1644 | * somewhere else in the code */ | ||
1634 | #define SENSOR_ATTR_DTS(index) { \ | 1645 | #define SENSOR_ATTR_DTS(index) { \ |
1635 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ | 1646 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ |
1636 | show_dts_mode, NULL, NOT_USED, index - 7), \ | 1647 | show_dts_mode, NULL, NOT_USED, index - 7), \ |
@@ -1649,6 +1660,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1649 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ | 1660 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ |
1650 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } | 1661 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } |
1651 | 1662 | ||
1663 | /* Don't change the attribute order, _beep is accessed by index | ||
1664 | * somewhere else in the code */ | ||
1652 | #define SENSOR_ATTR_TEMP(index) { \ | 1665 | #define SENSOR_ATTR_TEMP(index) { \ |
1653 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ | 1666 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ |
1654 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ | 1667 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ |
@@ -1802,10 +1815,6 @@ static const struct sensor_device_attribute_2 w83795_tss[6] = { | |||
1802 | static const struct sensor_device_attribute_2 sda_single_files[] = { | 1815 | static const struct sensor_device_attribute_2 sda_single_files[] = { |
1803 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, | 1816 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, |
1804 | store_chassis_clear, ALARM_STATUS, 46), | 1817 | store_chassis_clear, ALARM_STATUS, 46), |
1805 | SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1806 | store_beep, BEEP_ENABLE, 46), | ||
1807 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1808 | store_beep, BEEP_ENABLE, 47), | ||
1809 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 1818 | #ifdef CONFIG_SENSORS_W83795_FANCTRL |
1810 | SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin, | 1819 | SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin, |
1811 | store_fanin, FANIN_TOL, NOT_USED), | 1820 | store_fanin, FANIN_TOL, NOT_USED), |
@@ -1818,6 +1827,13 @@ static const struct sensor_device_attribute_2 sda_single_files[] = { | |||
1818 | #endif | 1827 | #endif |
1819 | }; | 1828 | }; |
1820 | 1829 | ||
1830 | static const struct sensor_device_attribute_2 sda_beep_files[] = { | ||
1831 | SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1832 | store_beep, BEEP_ENABLE, 46), | ||
1833 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1834 | store_beep, BEEP_ENABLE, 47), | ||
1835 | }; | ||
1836 | |||
1821 | /* | 1837 | /* |
1822 | * Driver interface | 1838 | * Driver interface |
1823 | */ | 1839 | */ |
@@ -1947,6 +1963,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
1947 | if (!(data->has_in & (1 << i))) | 1963 | if (!(data->has_in & (1 << i))) |
1948 | continue; | 1964 | continue; |
1949 | for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) { | 1965 | for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) { |
1966 | if (j == 4 && !data->enable_beep) | ||
1967 | continue; | ||
1950 | err = fn(dev, &w83795_in[i][j].dev_attr); | 1968 | err = fn(dev, &w83795_in[i][j].dev_attr); |
1951 | if (err) | 1969 | if (err) |
1952 | return err; | 1970 | return err; |
@@ -1957,6 +1975,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
1957 | if (!(data->has_fan & (1 << i))) | 1975 | if (!(data->has_fan & (1 << i))) |
1958 | continue; | 1976 | continue; |
1959 | for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) { | 1977 | for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) { |
1978 | if (j == 3 && !data->enable_beep) | ||
1979 | continue; | ||
1960 | err = fn(dev, &w83795_fan[i][j].dev_attr); | 1980 | err = fn(dev, &w83795_fan[i][j].dev_attr); |
1961 | if (err) | 1981 | if (err) |
1962 | return err; | 1982 | return err; |
@@ -1978,6 +1998,14 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
1978 | return err; | 1998 | return err; |
1979 | } | 1999 | } |
1980 | 2000 | ||
2001 | if (data->enable_beep) { | ||
2002 | for (i = 0; i < ARRAY_SIZE(sda_beep_files); i++) { | ||
2003 | err = fn(dev, &sda_beep_files[i].dev_attr); | ||
2004 | if (err) | ||
2005 | return err; | ||
2006 | } | ||
2007 | } | ||
2008 | |||
1981 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 2009 | #ifdef CONFIG_SENSORS_W83795_FANCTRL |
1982 | for (i = 0; i < data->has_pwm; i++) { | 2010 | for (i = 0; i < data->has_pwm; i++) { |
1983 | for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) { | 2011 | for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) { |
@@ -1996,6 +2024,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
1996 | #else | 2024 | #else |
1997 | for (j = 0; j < 8; j++) { | 2025 | for (j = 0; j < 8; j++) { |
1998 | #endif | 2026 | #endif |
2027 | if (j == 7 && !data->enable_beep) | ||
2028 | continue; | ||
1999 | err = fn(dev, &w83795_temp[i][j].dev_attr); | 2029 | err = fn(dev, &w83795_temp[i][j].dev_attr); |
2000 | if (err) | 2030 | if (err) |
2001 | return err; | 2031 | return err; |
@@ -2007,6 +2037,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
2007 | if (!(data->has_dts & (1 << i))) | 2037 | if (!(data->has_dts & (1 << i))) |
2008 | continue; | 2038 | continue; |
2009 | for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) { | 2039 | for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) { |
2040 | if (j == 7 && !data->enable_beep) | ||
2041 | continue; | ||
2010 | err = fn(dev, &w83795_dts[i][j].dev_attr); | 2042 | err = fn(dev, &w83795_dts[i][j].dev_attr); |
2011 | if (err) | 2043 | if (err) |
2012 | return err; | 2044 | return err; |
@@ -2146,6 +2178,18 @@ static int w83795_probe(struct i2c_client *client, | |||
2146 | else | 2178 | else |
2147 | data->has_pwm = 2; | 2179 | data->has_pwm = 2; |
2148 | 2180 | ||
2181 | /* Check if BEEP pin is available */ | ||
2182 | if (data->chip_type == w83795g) { | ||
2183 | /* The W83795G has a dedicated BEEP pin */ | ||
2184 | data->enable_beep = 1; | ||
2185 | } else { | ||
2186 | /* The W83795ADG has a shared pin for OVT# and BEEP, so you | ||
2187 | * can't have both */ | ||
2188 | tmp = w83795_read(client, W83795_REG_OVT_CFG); | ||
2189 | if ((tmp & OVT_CFG_SEL) == 0) | ||
2190 | data->enable_beep = 1; | ||
2191 | } | ||
2192 | |||
2149 | err = w83795_handle_files(dev, device_create_file); | 2193 | err = w83795_handle_files(dev, device_create_file); |
2150 | if (err) | 2194 | if (err) |
2151 | goto exit_remove; | 2195 | goto exit_remove; |