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>

authored by Jean Delvare and committed by Jean Delvare cf6b9ea6 2a2d27da

+20 -3
+20 -3
drivers/hwmon/w83795.c
··· 165 166 #define W83795_REG_VID_CTRL 0x6A 167 168 #define W83795_REG_ALARM(index) (0x41 + (index)) 169 - #define W83795_REG_BEEP(index) (0x50 + (index)) 170 - 171 #define W83795_REG_CLR_CHASSIS 0x4D 172 173 174 #define W83795_REG_FCMS1 0x201 ··· 586 struct i2c_client *client = to_i2c_client(dev); 587 struct w83795_data *data = i2c_get_clientdata(client); 588 u16 tmp; 589 int i; 590 591 mutex_lock(&data->update_lock); ··· 658 w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); 659 } 660 661 - /* update alarm */ 662 for (i = 0; i < ARRAY_SIZE(data->alarms); i++) 663 data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); 664 665 data->last_updated = jiffies; 666 data->valid = 1;
··· 165 166 #define W83795_REG_VID_CTRL 0x6A 167 168 + #define W83795_REG_ALARM_CTRL 0x40 169 + #define ALARM_CTRL_RTSACS (1 << 7) 170 #define W83795_REG_ALARM(index) (0x41 + (index)) 171 #define W83795_REG_CLR_CHASSIS 0x4D 172 + #define W83795_REG_BEEP(index) (0x50 + (index)) 173 174 175 #define W83795_REG_FCMS1 0x201 ··· 585 struct i2c_client *client = to_i2c_client(dev); 586 struct w83795_data *data = i2c_get_clientdata(client); 587 u16 tmp; 588 + u8 intrusion; 589 int i; 590 591 mutex_lock(&data->update_lock); ··· 656 w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); 657 } 658 659 + /* Update intrusion and alarms 660 + * It is important to read intrusion first, because reading from 661 + * register SMI STS6 clears the interrupt status temporarily. */ 662 + tmp = w83795_read(client, W83795_REG_ALARM_CTRL); 663 + /* Switch to interrupt status for intrusion if needed */ 664 + if (tmp & ALARM_CTRL_RTSACS) 665 + w83795_write(client, W83795_REG_ALARM_CTRL, 666 + tmp & ~ALARM_CTRL_RTSACS); 667 + intrusion = w83795_read(client, W83795_REG_ALARM(5)) & (1 << 6); 668 + /* Switch to real-time alarms */ 669 + w83795_write(client, W83795_REG_ALARM_CTRL, tmp | ALARM_CTRL_RTSACS); 670 for (i = 0; i < ARRAY_SIZE(data->alarms); i++) 671 data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); 672 + data->alarms[5] |= intrusion; 673 + /* Restore original configuration if needed */ 674 + if (!(tmp & ALARM_CTRL_RTSACS)) 675 + w83795_write(client, W83795_REG_ALARM_CTRL, 676 + tmp & ~ALARM_CTRL_RTSACS); 677 678 data->last_updated = jiffies; 679 data->valid = 1;