diff options
author | Hans de Goede <hdegoede@redhat.com> | 2011-03-09 14:57:10 -0500 |
---|---|---|
committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-03-15 01:39:22 -0400 |
commit | 0bae640088b5bd6c7a2a691ad20543d69c2b9b2c (patch) | |
tree | 0613662e3129bdcb6d9ef9ba800096637f81ae50 /drivers/hwmon | |
parent | 98f7ba197f9ef366856b5cc9ef4f46e852f3d1c8 (diff) |
hwmon/f71882fg: Make creation of in sysfs attributes more generic
This is a preparation patch for adding support for more different models,
some of which have a sparse list of used voltage pins.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/f71882fg.c | 180 |
1 files changed, 103 insertions, 77 deletions
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 67ac85870592..ec29c611ed3e 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -93,6 +93,8 @@ | |||
93 | 93 | ||
94 | #define F71882FG_REG_START 0x01 | 94 | #define F71882FG_REG_START 0x01 |
95 | 95 | ||
96 | #define F71882FG_MAX_INS 9 | ||
97 | |||
96 | #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ | 98 | #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ |
97 | 99 | ||
98 | static unsigned short force_id; | 100 | static unsigned short force_id; |
@@ -109,6 +111,22 @@ static const char *f71882fg_names[] = { | |||
109 | "f8000", | 111 | "f8000", |
110 | }; | 112 | }; |
111 | 113 | ||
114 | static const char f71882fg_has_in[5][F71882FG_MAX_INS] = { | ||
115 | { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f71858fg */ | ||
116 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71862fg */ | ||
117 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71882fg */ | ||
118 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889fg */ | ||
119 | { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f8000 */ | ||
120 | }; | ||
121 | |||
122 | static const char f71882fg_has_in1_alarm[5] = { | ||
123 | 0, /* f71858fg */ | ||
124 | 0, /* f71862fg */ | ||
125 | 1, /* f71882fg */ | ||
126 | 1, /* f71889fg */ | ||
127 | 0, /* f8000 */ | ||
128 | }; | ||
129 | |||
112 | static struct platform_device *f71882fg_pdev; | 130 | static struct platform_device *f71882fg_pdev; |
113 | 131 | ||
114 | /* Super-I/O Function prototypes */ | 132 | /* Super-I/O Function prototypes */ |
@@ -135,7 +153,7 @@ struct f71882fg_data { | |||
135 | unsigned long last_limits; /* In jiffies */ | 153 | unsigned long last_limits; /* In jiffies */ |
136 | 154 | ||
137 | /* Register Values */ | 155 | /* Register Values */ |
138 | u8 in[9]; | 156 | u8 in[F71882FG_MAX_INS]; |
139 | u8 in1_max; | 157 | u8 in1_max; |
140 | u8 in_status; | 158 | u8 in_status; |
141 | u8 in_beep; | 159 | u8 in_beep; |
@@ -264,13 +282,9 @@ static struct platform_driver f71882fg_driver = { | |||
264 | 282 | ||
265 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 283 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
266 | 284 | ||
267 | /* Temp and in attr for the f71858fg, the f71858fg is special as it | 285 | /* Temp attr for the f71858fg, the f71858fg is special as it has its |
268 | has its temperature indexes start at 0 (the others start at 1) and | 286 | temperature indexes start at 0 (the others start at 1) */ |
269 | it only has 3 voltage inputs */ | 287 | static struct sensor_device_attribute_2 f71858fg_temp_attr[] = { |
270 | static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = { | ||
271 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | ||
272 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), | ||
273 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), | ||
274 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), | 288 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), |
275 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, | 289 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, |
276 | store_temp_max, 0, 0), | 290 | store_temp_max, 0, 0), |
@@ -310,17 +324,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = { | |||
310 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), | 324 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), |
311 | }; | 325 | }; |
312 | 326 | ||
313 | /* Temp and in attr common to the f71862fg, f71882fg and f71889fg */ | 327 | /* Temp attr for the standard models */ |
314 | static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = { | 328 | static struct sensor_device_attribute_2 fxxxx_temp_attr[] = { |
315 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | ||
316 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), | ||
317 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), | ||
318 | SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3), | ||
319 | SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4), | ||
320 | SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5), | ||
321 | SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), | ||
322 | SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), | ||
323 | SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), | ||
324 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), | 329 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), |
325 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, | 330 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, |
326 | store_temp_max, 0, 1), | 331 | store_temp_max, 0, 1), |
@@ -379,24 +384,12 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = { | |||
379 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3), | 384 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3), |
380 | }; | 385 | }; |
381 | 386 | ||
382 | /* For models with in1 alarm capability */ | 387 | /* Temp attr for the f8000 |
383 | static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = { | ||
384 | SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, | ||
385 | 0, 1), | ||
386 | SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, | ||
387 | 0, 1), | ||
388 | SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1), | ||
389 | }; | ||
390 | |||
391 | /* Temp and in attr for the f8000 | ||
392 | Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max) | 388 | Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max) |
393 | is used as hysteresis value to clear alarms | 389 | is used as hysteresis value to clear alarms |
394 | Also like the f71858fg its temperature indexes start at 0 | 390 | Also like the f71858fg its temperature indexes start at 0 |
395 | */ | 391 | */ |
396 | static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { | 392 | static struct sensor_device_attribute_2 f8000_temp_attr[] = { |
397 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | ||
398 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), | ||
399 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), | ||
400 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), | 393 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), |
401 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit, | 394 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit, |
402 | store_temp_crit, 0, 0), | 395 | store_temp_crit, 0, 0), |
@@ -421,6 +414,28 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { | |||
421 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), | 414 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), |
422 | }; | 415 | }; |
423 | 416 | ||
417 | /* in attr for all models */ | ||
418 | static struct sensor_device_attribute_2 fxxxx_in_attr[] = { | ||
419 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | ||
420 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), | ||
421 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), | ||
422 | SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3), | ||
423 | SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4), | ||
424 | SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5), | ||
425 | SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), | ||
426 | SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), | ||
427 | SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), | ||
428 | }; | ||
429 | |||
430 | /* For models with in1 alarm capability */ | ||
431 | static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = { | ||
432 | SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, | ||
433 | 0, 1), | ||
434 | SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, | ||
435 | 0, 1), | ||
436 | SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1), | ||
437 | }; | ||
438 | |||
424 | /* Fan / PWM attr common to all models */ | 439 | /* Fan / PWM attr common to all models */ |
425 | static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { { | 440 | static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { { |
426 | SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0), | 441 | SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0), |
@@ -947,14 +962,13 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
947 | struct f71882fg_data *data = dev_get_drvdata(dev); | 962 | struct f71882fg_data *data = dev_get_drvdata(dev); |
948 | int nr, reg; | 963 | int nr, reg; |
949 | int nr_fans = (data->type == f71882fg) ? 4 : 3; | 964 | int nr_fans = (data->type == f71882fg) ? 4 : 3; |
950 | int nr_ins = (data->type == f71858fg || data->type == f8000) ? 3 : 9; | ||
951 | 965 | ||
952 | mutex_lock(&data->update_lock); | 966 | mutex_lock(&data->update_lock); |
953 | 967 | ||
954 | /* Update once every 60 seconds */ | 968 | /* Update once every 60 seconds */ |
955 | if (time_after(jiffies, data->last_limits + 60 * HZ) || | 969 | if (time_after(jiffies, data->last_limits + 60 * HZ) || |
956 | !data->valid) { | 970 | !data->valid) { |
957 | if (data->type == f71882fg || data->type == f71889fg) { | 971 | if (f71882fg_has_in1_alarm[data->type]) { |
958 | data->in1_max = | 972 | data->in1_max = |
959 | f71882fg_read8(data, F71882FG_REG_IN1_HIGH); | 973 | f71882fg_read8(data, F71882FG_REG_IN1_HIGH); |
960 | data->in_beep = | 974 | data->in_beep = |
@@ -1058,17 +1072,18 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
1058 | data->pwm[nr] = | 1072 | data->pwm[nr] = |
1059 | f71882fg_read8(data, F71882FG_REG_PWM(nr)); | 1073 | f71882fg_read8(data, F71882FG_REG_PWM(nr)); |
1060 | } | 1074 | } |
1061 | |||
1062 | /* The f8000 can monitor 1 more fan, but has no pwm for it */ | 1075 | /* The f8000 can monitor 1 more fan, but has no pwm for it */ |
1063 | if (data->type == f8000) | 1076 | if (data->type == f8000) |
1064 | data->fan[3] = f71882fg_read16(data, | 1077 | data->fan[3] = f71882fg_read16(data, |
1065 | F71882FG_REG_FAN(3)); | 1078 | F71882FG_REG_FAN(3)); |
1066 | if (data->type == f71882fg || data->type == f71889fg) | 1079 | |
1080 | if (f71882fg_has_in1_alarm[data->type]) | ||
1067 | data->in_status = f71882fg_read8(data, | 1081 | data->in_status = f71882fg_read8(data, |
1068 | F71882FG_REG_IN_STATUS); | 1082 | F71882FG_REG_IN_STATUS); |
1069 | for (nr = 0; nr < nr_ins; nr++) | 1083 | for (nr = 0; nr < F71882FG_MAX_INS; nr++) |
1070 | data->in[nr] = f71882fg_read8(data, | 1084 | if (f71882fg_has_in[data->type][nr]) |
1071 | F71882FG_REG_IN(nr)); | 1085 | data->in[nr] = f71882fg_read8(data, |
1086 | F71882FG_REG_IN(nr)); | ||
1072 | 1087 | ||
1073 | data->last_updated = jiffies; | 1088 | data->last_updated = jiffies; |
1074 | data->valid = 1; | 1089 | data->valid = 1; |
@@ -1943,34 +1958,41 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
1943 | /* The f71858fg temperature alarms behave as | 1958 | /* The f71858fg temperature alarms behave as |
1944 | the f8000 alarms in this mode */ | 1959 | the f8000 alarms in this mode */ |
1945 | err = f71882fg_create_sysfs_files(pdev, | 1960 | err = f71882fg_create_sysfs_files(pdev, |
1946 | f8000_in_temp_attr, | 1961 | f8000_temp_attr, |
1947 | ARRAY_SIZE(f8000_in_temp_attr)); | 1962 | ARRAY_SIZE(f8000_temp_attr)); |
1948 | else | 1963 | else |
1949 | err = f71882fg_create_sysfs_files(pdev, | 1964 | err = f71882fg_create_sysfs_files(pdev, |
1950 | f71858fg_in_temp_attr, | 1965 | f71858fg_temp_attr, |
1951 | ARRAY_SIZE(f71858fg_in_temp_attr)); | 1966 | ARRAY_SIZE(f71858fg_temp_attr)); |
1952 | break; | ||
1953 | case f71882fg: | ||
1954 | case f71889fg: | ||
1955 | err = f71882fg_create_sysfs_files(pdev, | ||
1956 | fxxxx_in1_alarm_attr, | ||
1957 | ARRAY_SIZE(fxxxx_in1_alarm_attr)); | ||
1958 | if (err) | ||
1959 | goto exit_unregister_sysfs; | ||
1960 | /* fall through! */ | ||
1961 | case f71862fg: | ||
1962 | err = f71882fg_create_sysfs_files(pdev, | ||
1963 | fxxxx_in_temp_attr, | ||
1964 | ARRAY_SIZE(fxxxx_in_temp_attr)); | ||
1965 | break; | 1967 | break; |
1966 | case f8000: | 1968 | case f8000: |
1967 | err = f71882fg_create_sysfs_files(pdev, | 1969 | err = f71882fg_create_sysfs_files(pdev, |
1968 | f8000_in_temp_attr, | 1970 | f8000_temp_attr, |
1969 | ARRAY_SIZE(f8000_in_temp_attr)); | 1971 | ARRAY_SIZE(f8000_temp_attr)); |
1970 | break; | 1972 | break; |
1973 | default: | ||
1974 | err = f71882fg_create_sysfs_files(pdev, | ||
1975 | fxxxx_temp_attr, | ||
1976 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
1971 | } | 1977 | } |
1972 | if (err) | 1978 | if (err) |
1973 | goto exit_unregister_sysfs; | 1979 | goto exit_unregister_sysfs; |
1980 | |||
1981 | for (i = 0; i < F71882FG_MAX_INS; i++) { | ||
1982 | if (f71882fg_has_in[data->type][i]) { | ||
1983 | err = device_create_file(&pdev->dev, | ||
1984 | &fxxxx_in_attr[i].dev_attr); | ||
1985 | if (err) | ||
1986 | goto exit_unregister_sysfs; | ||
1987 | } | ||
1988 | } | ||
1989 | if (f71882fg_has_in1_alarm[data->type]) { | ||
1990 | err = f71882fg_create_sysfs_files(pdev, | ||
1991 | fxxxx_in1_alarm_attr, | ||
1992 | ARRAY_SIZE(fxxxx_in1_alarm_attr)); | ||
1993 | if (err) | ||
1994 | goto exit_unregister_sysfs; | ||
1995 | } | ||
1974 | } | 1996 | } |
1975 | 1997 | ||
1976 | if (start_reg & 0x02) { | 1998 | if (start_reg & 0x02) { |
@@ -2093,7 +2115,7 @@ exit_free: | |||
2093 | static int f71882fg_remove(struct platform_device *pdev) | 2115 | static int f71882fg_remove(struct platform_device *pdev) |
2094 | { | 2116 | { |
2095 | struct f71882fg_data *data = platform_get_drvdata(pdev); | 2117 | struct f71882fg_data *data = platform_get_drvdata(pdev); |
2096 | int nr_fans = (data->type == f71882fg) ? 4 : 3; | 2118 | int i, nr_fans = (data->type == f71882fg) ? 4 : 3; |
2097 | u8 start_reg = f71882fg_read8(data, F71882FG_REG_START); | 2119 | u8 start_reg = f71882fg_read8(data, F71882FG_REG_START); |
2098 | 2120 | ||
2099 | if (data->hwmon_dev) | 2121 | if (data->hwmon_dev) |
@@ -2106,29 +2128,33 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2106 | case f71858fg: | 2128 | case f71858fg: |
2107 | if (data->temp_config & 0x10) | 2129 | if (data->temp_config & 0x10) |
2108 | f71882fg_remove_sysfs_files(pdev, | 2130 | f71882fg_remove_sysfs_files(pdev, |
2109 | f8000_in_temp_attr, | 2131 | f8000_temp_attr, |
2110 | ARRAY_SIZE(f8000_in_temp_attr)); | 2132 | ARRAY_SIZE(f8000_temp_attr)); |
2111 | else | 2133 | else |
2112 | f71882fg_remove_sysfs_files(pdev, | 2134 | f71882fg_remove_sysfs_files(pdev, |
2113 | f71858fg_in_temp_attr, | 2135 | f71858fg_temp_attr, |
2114 | ARRAY_SIZE(f71858fg_in_temp_attr)); | 2136 | ARRAY_SIZE(f71858fg_temp_attr)); |
2115 | break; | ||
2116 | case f71882fg: | ||
2117 | case f71889fg: | ||
2118 | f71882fg_remove_sysfs_files(pdev, | ||
2119 | fxxxx_in1_alarm_attr, | ||
2120 | ARRAY_SIZE(fxxxx_in1_alarm_attr)); | ||
2121 | /* fall through! */ | ||
2122 | case f71862fg: | ||
2123 | f71882fg_remove_sysfs_files(pdev, | ||
2124 | fxxxx_in_temp_attr, | ||
2125 | ARRAY_SIZE(fxxxx_in_temp_attr)); | ||
2126 | break; | 2137 | break; |
2127 | case f8000: | 2138 | case f8000: |
2128 | f71882fg_remove_sysfs_files(pdev, | 2139 | f71882fg_remove_sysfs_files(pdev, |
2129 | f8000_in_temp_attr, | 2140 | f8000_temp_attr, |
2130 | ARRAY_SIZE(f8000_in_temp_attr)); | 2141 | ARRAY_SIZE(f8000_temp_attr)); |
2131 | break; | 2142 | break; |
2143 | default: | ||
2144 | f71882fg_remove_sysfs_files(pdev, | ||
2145 | fxxxx_temp_attr, | ||
2146 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
2147 | } | ||
2148 | for (i = 0; i < F71882FG_MAX_INS; i++) { | ||
2149 | if (f71882fg_has_in[data->type][i]) { | ||
2150 | device_remove_file(&pdev->dev, | ||
2151 | &fxxxx_in_attr[i].dev_attr); | ||
2152 | } | ||
2153 | } | ||
2154 | if (f71882fg_has_in1_alarm[data->type]) { | ||
2155 | f71882fg_remove_sysfs_files(pdev, | ||
2156 | fxxxx_in1_alarm_attr, | ||
2157 | ARRAY_SIZE(fxxxx_in1_alarm_attr)); | ||
2132 | } | 2158 | } |
2133 | } | 2159 | } |
2134 | 2160 | ||