aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2011-03-09 14:57:14 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-03-15 01:39:25 -0400
commit3cad402281607d4db0d99d88fbd67cabb7c5b9f1 (patch)
tree81147d3ef8f5a8d6230ae531d00e929a887a77fa /drivers/hwmon
parente48a7f1a719b258ee8bd2e809205d6d0f9d66aed (diff)
hwmon/f71882fg: Add support for f71889ed
Note that this patch also makes 2 changes to the code paths for the f71889fg to keep the code unified between the 2 (for simplicities sake). Both of these are harmless for then f71889fg: 1) The first change is to always set the FAN_PROG_SEL bit to 0. This influences accesses to some banked fan / pwm registers. On the f71889fg no registers which we use are banked. On the f71889ed however some more fan registers have been banked including one which we use, by making the FAN_PROG_SEL bit 0, address 0x96 will point to the right register. 2) The second change is to see a FANx_TEMP_SEL value of 0 as pointing to a PECI / AMDSI value, and thus disable our pwm related sysfs attr. This is correct for the f71889ed and on the f71889fg 0 is a reserved value, so we should never see it and if we do, disabling the pwm related sysfs attr is a sane thing to do. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Tested-by: Thomas Greve <tg42@gmx.net> Tested-by: Sander Eikelenboom <linux@eikelenboom.it> Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/f71882fg.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 4c17f12054a2..49cf19621c0c 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -51,16 +51,17 @@
51#define SIO_F71862_ID 0x0601 /* Chipset ID */ 51#define SIO_F71862_ID 0x0601 /* Chipset ID */
52#define SIO_F71882_ID 0x0541 /* Chipset ID */ 52#define SIO_F71882_ID 0x0541 /* Chipset ID */
53#define SIO_F71889_ID 0x0723 /* Chipset ID */ 53#define SIO_F71889_ID 0x0723 /* Chipset ID */
54#define SIO_F71889E_ID 0x0909 /* Chipset ID */
54#define SIO_F8000_ID 0x0581 /* Chipset ID */ 55#define SIO_F8000_ID 0x0581 /* Chipset ID */
55 56
56#define REGION_LENGTH 8 57#define REGION_LENGTH 8
57#define ADDR_REG_OFFSET 5 58#define ADDR_REG_OFFSET 5
58#define DATA_REG_OFFSET 6 59#define DATA_REG_OFFSET 6
59 60
60#define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */ 61#define F71882FG_REG_IN_STATUS 0x12 /* f7188x only */
61#define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */ 62#define F71882FG_REG_IN_BEEP 0x13 /* f7188x only */
62#define F71882FG_REG_IN(nr) (0x20 + (nr)) 63#define F71882FG_REG_IN(nr) (0x20 + (nr))
63#define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */ 64#define F71882FG_REG_IN1_HIGH 0x32 /* f7188x only */
64 65
65#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) 66#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
66#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr))) 67#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
@@ -86,6 +87,7 @@
86 87
87#define F71882FG_REG_FAN_FAULT_T 0x9F 88#define F71882FG_REG_FAN_FAULT_T 0x9F
88#define F71882FG_FAN_NEG_TEMP_EN 0x20 89#define F71882FG_FAN_NEG_TEMP_EN 0x20
90#define F71882FG_FAN_PROG_SEL 0x80
89 91
90#define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm))) 92#define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
91#define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm))) 93#define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
@@ -101,37 +103,41 @@ static unsigned short force_id;
101module_param(force_id, ushort, 0); 103module_param(force_id, ushort, 0);
102MODULE_PARM_DESC(force_id, "Override the detected device ID"); 104MODULE_PARM_DESC(force_id, "Override the detected device ID");
103 105
104enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 }; 106enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f71889ed, f8000 };
105 107
106static const char *f71882fg_names[] = { 108static const char *f71882fg_names[] = {
107 "f71858fg", 109 "f71858fg",
108 "f71862fg", 110 "f71862fg",
109 "f71882fg", 111 "f71882fg",
110 "f71889fg", 112 "f71889fg",
113 "f71889ed",
111 "f8000", 114 "f8000",
112}; 115};
113 116
114static const char f71882fg_has_in[5][F71882FG_MAX_INS] = { 117static const char f71882fg_has_in[6][F71882FG_MAX_INS] = {
115 { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f71858fg */ 118 { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f71858fg */
116 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71862fg */ 119 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71862fg */
117 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71882fg */ 120 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71882fg */
118 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889fg */ 121 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889fg */
122 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889ed */
119 { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f8000 */ 123 { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f8000 */
120}; 124};
121 125
122static const char f71882fg_has_in1_alarm[5] = { 126static const char f71882fg_has_in1_alarm[6] = {
123 0, /* f71858fg */ 127 0, /* f71858fg */
124 0, /* f71862fg */ 128 0, /* f71862fg */
125 1, /* f71882fg */ 129 1, /* f71882fg */
126 1, /* f71889fg */ 130 1, /* f71889fg */
131 1, /* f71889ed */
127 0, /* f8000 */ 132 0, /* f8000 */
128}; 133};
129 134
130static const char f71882fg_has_beep[5] = { 135static const char f71882fg_has_beep[6] = {
131 0, /* f71858fg */ 136 0, /* f71858fg */
132 1, /* f71862fg */ 137 1, /* f71862fg */
133 1, /* f71882fg */ 138 1, /* f71882fg */
134 1, /* f71889fg */ 139 1, /* f71889fg */
140 1, /* f71889ed */
135 0, /* f8000 */ 141 0, /* f8000 */
136}; 142};
137 143
@@ -510,7 +516,7 @@ static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
510}; 516};
511 517
512/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the 518/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
513 f71858fg / f71882fg / f71889fg */ 519 standard models */
514static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { 520static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
515 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 521 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
516 show_pwm_auto_point_channel, 522 show_pwm_auto_point_channel,
@@ -579,7 +585,7 @@ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
579 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 585 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
580}; 586};
581 587
582/* PWM attr common to the f71858fg, f71882fg and f71889fg */ 588/* PWM attr for the standard models */
583static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { { 589static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
584 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 590 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
585 show_pwm_auto_point_channel, 591 show_pwm_auto_point_channel,
@@ -2024,9 +2030,13 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2024 if (start_reg & 0x02) { 2030 if (start_reg & 0x02) {
2025 switch (data->type) { 2031 switch (data->type) {
2026 case f71889fg: 2032 case f71889fg:
2033 case f71889ed:
2027 reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T); 2034 reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T);
2028 if (reg & F71882FG_FAN_NEG_TEMP_EN) 2035 if (reg & F71882FG_FAN_NEG_TEMP_EN)
2029 data->auto_point_temp_signed = 1; 2036 data->auto_point_temp_signed = 1;
2037 /* Ensure banked pwm registers point to right bank */
2038 reg &= ~F71882FG_FAN_PROG_SEL;
2039 f71882fg_write8(data, F71882FG_REG_FAN_FAULT_T, reg);
2030 break; 2040 break;
2031 default: 2041 default:
2032 break; 2042 break;
@@ -2048,6 +2058,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2048 break; 2058 break;
2049 case f71882fg: 2059 case f71882fg:
2050 case f71889fg: 2060 case f71889fg:
2061 case f71889ed:
2051 err = 0; 2062 err = 0;
2052 break; 2063 break;
2053 case f8000: 2064 case f8000:
@@ -2076,11 +2087,13 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2076 2087
2077 switch (data->type) { 2088 switch (data->type) {
2078 case f71889fg: 2089 case f71889fg:
2090 case f71889ed:
2079 for (i = 0; i < nr_fans; i++) { 2091 for (i = 0; i < nr_fans; i++) {
2080 data->pwm_auto_point_mapping[i] = 2092 data->pwm_auto_point_mapping[i] =
2081 f71882fg_read8(data, 2093 f71882fg_read8(data,
2082 F71882FG_REG_POINT_MAPPING(i)); 2094 F71882FG_REG_POINT_MAPPING(i));
2083 if (data->pwm_auto_point_mapping[i] & 0x80) 2095 if ((data->pwm_auto_point_mapping[i] & 0x80) ||
2096 (data->pwm_auto_point_mapping[i] & 3) == 0)
2084 break; 2097 break;
2085 } 2098 }
2086 if (i != nr_fans) { 2099 if (i != nr_fans) {
@@ -2219,7 +2232,7 @@ static int f71882fg_remove(struct platform_device *pdev)
2219 f8000_auto_pwm_attr, 2232 f8000_auto_pwm_attr,
2220 ARRAY_SIZE(f8000_auto_pwm_attr)); 2233 ARRAY_SIZE(f8000_auto_pwm_attr));
2221 break; 2234 break;
2222 default: /* f71858fg / f71882fg / f71889fg */ 2235 default:
2223 f71882fg_remove_sysfs_files(pdev, 2236 f71882fg_remove_sysfs_files(pdev,
2224 &fxxxx_auto_pwm_attr[0][0], 2237 &fxxxx_auto_pwm_attr[0][0],
2225 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); 2238 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
@@ -2261,6 +2274,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
2261 case SIO_F71889_ID: 2274 case SIO_F71889_ID:
2262 sio_data->type = f71889fg; 2275 sio_data->type = f71889fg;
2263 break; 2276 break;
2277 case SIO_F71889E_ID:
2278 sio_data->type = f71889ed;
2279 break;
2264 case SIO_F8000_ID: 2280 case SIO_F8000_ID:
2265 sio_data->type = f8000; 2281 sio_data->type = f8000;
2266 break; 2282 break;