aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83795.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2010-11-15 15:38:56 -0500
committerJean Delvare <khali@endymion.delvare>2010-11-15 15:38:56 -0500
commitcf6b9ea661ef4f20b4a4cba1a232a732339aae2c (patch)
treed12db9d301146d533120686d7da1bf84a3068c0a /drivers/hwmon/w83795.c
parent2a2d27da00250c9f117e35653ed5a6a3212e5d77 (diff)
hwmon: (w83795) Read the intrusion state properly
We can't read the intrusion state from the real-time alarm registers as we do for all other alarm flags, because real-time alarm bits don't stick (by definition) and the intrusion state has to stick until explicitly cleared (otherwise it has little value.) So we have to use the interrupt status register instead, which is read from the same address but with a configuration bit flipped in another register. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon/w83795.c')
-rw-r--r--drivers/hwmon/w83795.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
index 400558d97f3d..600b2adbbd49 100644
--- a/drivers/hwmon/w83795.c
+++ b/drivers/hwmon/w83795.c
@@ -165,10 +165,11 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = {
165 165
166#define W83795_REG_VID_CTRL 0x6A 166#define W83795_REG_VID_CTRL 0x6A
167 167
168#define W83795_REG_ALARM_CTRL 0x40
169#define ALARM_CTRL_RTSACS (1 << 7)
168#define W83795_REG_ALARM(index) (0x41 + (index)) 170#define W83795_REG_ALARM(index) (0x41 + (index))
169#define W83795_REG_BEEP(index) (0x50 + (index))
170
171#define W83795_REG_CLR_CHASSIS 0x4D 171#define W83795_REG_CLR_CHASSIS 0x4D
172#define W83795_REG_BEEP(index) (0x50 + (index))
172 173
173 174
174#define W83795_REG_FCMS1 0x201 175#define W83795_REG_FCMS1 0x201
@@ -585,6 +586,7 @@ static struct w83795_data *w83795_update_device(struct device *dev)
585 struct i2c_client *client = to_i2c_client(dev); 586 struct i2c_client *client = to_i2c_client(dev);
586 struct w83795_data *data = i2c_get_clientdata(client); 587 struct w83795_data *data = i2c_get_clientdata(client);
587 u16 tmp; 588 u16 tmp;
589 u8 intrusion;
588 int i; 590 int i;
589 591
590 mutex_lock(&data->update_lock); 592 mutex_lock(&data->update_lock);
@@ -656,9 +658,24 @@ static struct w83795_data *w83795_update_device(struct device *dev)
656 w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); 658 w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT));
657 } 659 }
658 660
659 /* update alarm */ 661 /* Update intrusion and alarms
662 * It is important to read intrusion first, because reading from
663 * register SMI STS6 clears the interrupt status temporarily. */
664 tmp = w83795_read(client, W83795_REG_ALARM_CTRL);
665 /* Switch to interrupt status for intrusion if needed */
666 if (tmp & ALARM_CTRL_RTSACS)
667 w83795_write(client, W83795_REG_ALARM_CTRL,
668 tmp & ~ALARM_CTRL_RTSACS);
669 intrusion = w83795_read(client, W83795_REG_ALARM(5)) & (1 << 6);
670 /* Switch to real-time alarms */
671 w83795_write(client, W83795_REG_ALARM_CTRL, tmp | ALARM_CTRL_RTSACS);
660 for (i = 0; i < ARRAY_SIZE(data->alarms); i++) 672 for (i = 0; i < ARRAY_SIZE(data->alarms); i++)
661 data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); 673 data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i));
674 data->alarms[5] |= intrusion;
675 /* Restore original configuration if needed */
676 if (!(tmp & ALARM_CTRL_RTSACS))
677 w83795_write(client, W83795_REG_ALARM_CTRL,
678 tmp & ~ALARM_CTRL_RTSACS);
662 679
663 data->last_updated = jiffies; 680 data->last_updated = jiffies;
664 data->valid = 1; 681 data->valid = 1;