Skip to content

Commit b1d2bff

Browse files
committed
hwmon: (nct6775) Fix temperature alarm attributes
Driver displays wrong alarms for temperature attributes. Turns out that temperature alarm bits are not fixed, but determined by temperature source mapping. To fix the problem, walk through the temperature sources to determine the correct alarm bit associated with a given attribute. Cc: [email protected] # 3.10+ Signed-off-by: Guenter Roeck <[email protected]>
1 parent 594fbe7 commit b1d2bff

File tree

1 file changed

+57
-23
lines changed

1 file changed

+57
-23
lines changed

drivers/hwmon/nct6775.c

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ struct nct6775_data {
625625
u8 has_fan_min; /* some fans don't have min register */
626626
bool has_fan_div;
627627

628+
u8 num_temp_alarms; /* 2 or 3 */
628629
u8 temp_fixed_num; /* 3 or 6 */
629630
u8 temp_type[NUM_TEMP_FIXED];
630631
s8 temp_offset[NUM_TEMP_FIXED];
@@ -1193,6 +1194,42 @@ show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
11931194
(unsigned int)((data->alarms >> nr) & 0x01));
11941195
}
11951196

1197+
static int find_temp_source(struct nct6775_data *data, int index, int count)
1198+
{
1199+
int source = data->temp_src[index];
1200+
int nr;
1201+
1202+
for (nr = 0; nr < count; nr++) {
1203+
int src;
1204+
1205+
src = nct6775_read_value(data,
1206+
data->REG_TEMP_SOURCE[nr]) & 0x1f;
1207+
if (src == source)
1208+
return nr;
1209+
}
1210+
return -1;
1211+
}
1212+
1213+
static ssize_t
1214+
show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1215+
{
1216+
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1217+
struct nct6775_data *data = nct6775_update_device(dev);
1218+
unsigned int alarm = 0;
1219+
int nr;
1220+
1221+
/*
1222+
* For temperatures, there is no fixed mapping from registers to alarm
1223+
* bits. Alarm bits are determined by the temperature source mapping.
1224+
*/
1225+
nr = find_temp_source(data, sattr->index, data->num_temp_alarms);
1226+
if (nr >= 0) {
1227+
int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE];
1228+
alarm = (data->alarms >> bit) & 0x01;
1229+
}
1230+
return sprintf(buf, "%u\n", alarm);
1231+
}
1232+
11961233
static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0);
11971234
static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0);
11981235
static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0);
@@ -1874,22 +1911,18 @@ static struct sensor_device_attribute sda_temp_type[] = {
18741911
};
18751912

18761913
static struct sensor_device_attribute sda_temp_alarm[] = {
1877-
SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL,
1878-
TEMP_ALARM_BASE),
1879-
SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL,
1880-
TEMP_ALARM_BASE + 1),
1881-
SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL,
1882-
TEMP_ALARM_BASE + 2),
1883-
SENSOR_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL,
1884-
TEMP_ALARM_BASE + 3),
1885-
SENSOR_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL,
1886-
TEMP_ALARM_BASE + 4),
1887-
SENSOR_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL,
1888-
TEMP_ALARM_BASE + 5),
1914+
SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0),
1915+
SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1),
1916+
SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2),
1917+
SENSOR_ATTR(temp4_alarm, S_IRUGO, show_temp_alarm, NULL, 3),
1918+
SENSOR_ATTR(temp5_alarm, S_IRUGO, show_temp_alarm, NULL, 4),
1919+
SENSOR_ATTR(temp6_alarm, S_IRUGO, show_temp_alarm, NULL, 5),
1920+
SENSOR_ATTR(temp7_alarm, S_IRUGO, show_temp_alarm, NULL, 6),
1921+
SENSOR_ATTR(temp8_alarm, S_IRUGO, show_temp_alarm, NULL, 7),
1922+
SENSOR_ATTR(temp9_alarm, S_IRUGO, show_temp_alarm, NULL, 8),
1923+
SENSOR_ATTR(temp10_alarm, S_IRUGO, show_temp_alarm, NULL, 9),
18891924
};
18901925

1891-
#define NUM_TEMP_ALARM ARRAY_SIZE(sda_temp_alarm)
1892-
18931926
static ssize_t
18941927
show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
18951928
{
@@ -3215,13 +3248,11 @@ static void nct6775_device_remove_files(struct device *dev)
32153248
device_remove_file(dev, &sda_temp_max[i].dev_attr);
32163249
device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
32173250
device_remove_file(dev, &sda_temp_crit[i].dev_attr);
3251+
device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
32183252
if (!(data->have_temp_fixed & (1 << i)))
32193253
continue;
32203254
device_remove_file(dev, &sda_temp_type[i].dev_attr);
32213255
device_remove_file(dev, &sda_temp_offset[i].dev_attr);
3222-
if (i >= NUM_TEMP_ALARM)
3223-
continue;
3224-
device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
32253256
}
32263257

32273258
device_remove_file(dev, &sda_caseopen[0].dev_attr);
@@ -3419,6 +3450,7 @@ static int nct6775_probe(struct platform_device *pdev)
34193450
data->auto_pwm_num = 6;
34203451
data->has_fan_div = true;
34213452
data->temp_fixed_num = 3;
3453+
data->num_temp_alarms = 3;
34223454

34233455
data->ALARM_BITS = NCT6775_ALARM_BITS;
34243456

@@ -3483,6 +3515,7 @@ static int nct6775_probe(struct platform_device *pdev)
34833515
data->auto_pwm_num = 4;
34843516
data->has_fan_div = false;
34853517
data->temp_fixed_num = 3;
3518+
data->num_temp_alarms = 3;
34863519

34873520
data->ALARM_BITS = NCT6776_ALARM_BITS;
34883521

@@ -3547,6 +3580,7 @@ static int nct6775_probe(struct platform_device *pdev)
35473580
data->auto_pwm_num = 4;
35483581
data->has_fan_div = false;
35493582
data->temp_fixed_num = 6;
3583+
data->num_temp_alarms = 2;
35503584

35513585
data->ALARM_BITS = NCT6779_ALARM_BITS;
35523586

@@ -3897,6 +3931,12 @@ static int nct6775_probe(struct platform_device *pdev)
38973931
if (err)
38983932
goto exit_remove;
38993933
}
3934+
if (find_temp_source(data, i, data->num_temp_alarms) >= 0) {
3935+
err = device_create_file(dev,
3936+
&sda_temp_alarm[i].dev_attr);
3937+
if (err)
3938+
goto exit_remove;
3939+
}
39003940
if (!(data->have_temp_fixed & (1 << i)))
39013941
continue;
39023942
err = device_create_file(dev, &sda_temp_type[i].dev_attr);
@@ -3905,12 +3945,6 @@ static int nct6775_probe(struct platform_device *pdev)
39053945
err = device_create_file(dev, &sda_temp_offset[i].dev_attr);
39063946
if (err)
39073947
goto exit_remove;
3908-
if (i >= NUM_TEMP_ALARM ||
3909-
data->ALARM_BITS[TEMP_ALARM_BASE + i] < 0)
3910-
continue;
3911-
err = device_create_file(dev, &sda_temp_alarm[i].dev_attr);
3912-
if (err)
3913-
goto exit_remove;
39143948
}
39153949

39163950
for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) {

0 commit comments

Comments
 (0)