diff options
Diffstat (limited to 'drivers/hwmon/f71882fg.c')
-rw-r--r-- | drivers/hwmon/f71882fg.c | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 16330db2bcdc..a4a94a096c90 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -48,6 +48,7 @@ | |||
48 | 48 | ||
49 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ | 49 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ |
50 | #define SIO_F71808E_ID 0x0901 /* Chipset ID */ | 50 | #define SIO_F71808E_ID 0x0901 /* Chipset ID */ |
51 | #define SIO_F71808A_ID 0x1001 /* Chipset ID */ | ||
51 | #define SIO_F71858_ID 0x0507 /* Chipset ID */ | 52 | #define SIO_F71858_ID 0x0507 /* Chipset ID */ |
52 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ | 53 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ |
53 | #define SIO_F71869_ID 0x0814 /* Chipset ID */ | 54 | #define SIO_F71869_ID 0x0814 /* Chipset ID */ |
@@ -107,11 +108,12 @@ static unsigned short force_id; | |||
107 | module_param(force_id, ushort, 0); | 108 | module_param(force_id, ushort, 0); |
108 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 109 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
109 | 110 | ||
110 | enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg, | 111 | enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71882fg, f71889fg, |
111 | f71889ed, f71889a, f8000, f81865f }; | 112 | f71889ed, f71889a, f8000, f81865f }; |
112 | 113 | ||
113 | static const char *f71882fg_names[] = { | 114 | static const char *f71882fg_names[] = { |
114 | "f71808e", | 115 | "f71808e", |
116 | "f71808a", | ||
115 | "f71858fg", | 117 | "f71858fg", |
116 | "f71862fg", | 118 | "f71862fg", |
117 | "f71869", /* Both f71869f and f71869e, reg. compatible and same id */ | 119 | "f71869", /* Both f71869f and f71869e, reg. compatible and same id */ |
@@ -125,6 +127,7 @@ static const char *f71882fg_names[] = { | |||
125 | 127 | ||
126 | static const char f71882fg_has_in[][F71882FG_MAX_INS] = { | 128 | static const char f71882fg_has_in[][F71882FG_MAX_INS] = { |
127 | [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 }, | 129 | [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 }, |
130 | [f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1 }, | ||
128 | [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, | 131 | [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, |
129 | [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 132 | [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
130 | [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 133 | [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
@@ -138,6 +141,7 @@ static const char f71882fg_has_in[][F71882FG_MAX_INS] = { | |||
138 | 141 | ||
139 | static const char f71882fg_has_in1_alarm[] = { | 142 | static const char f71882fg_has_in1_alarm[] = { |
140 | [f71808e] = 0, | 143 | [f71808e] = 0, |
144 | [f71808a] = 0, | ||
141 | [f71858fg] = 0, | 145 | [f71858fg] = 0, |
142 | [f71862fg] = 0, | 146 | [f71862fg] = 0, |
143 | [f71869] = 0, | 147 | [f71869] = 0, |
@@ -151,6 +155,7 @@ static const char f71882fg_has_in1_alarm[] = { | |||
151 | 155 | ||
152 | static const char f71882fg_fan_has_beep[] = { | 156 | static const char f71882fg_fan_has_beep[] = { |
153 | [f71808e] = 0, | 157 | [f71808e] = 0, |
158 | [f71808a] = 0, | ||
154 | [f71858fg] = 0, | 159 | [f71858fg] = 0, |
155 | [f71862fg] = 1, | 160 | [f71862fg] = 1, |
156 | [f71869] = 1, | 161 | [f71869] = 1, |
@@ -164,6 +169,7 @@ static const char f71882fg_fan_has_beep[] = { | |||
164 | 169 | ||
165 | static const char f71882fg_nr_fans[] = { | 170 | static const char f71882fg_nr_fans[] = { |
166 | [f71808e] = 3, | 171 | [f71808e] = 3, |
172 | [f71808a] = 2, /* +1 fan which is monitor + simple pwm only */ | ||
167 | [f71858fg] = 3, | 173 | [f71858fg] = 3, |
168 | [f71862fg] = 3, | 174 | [f71862fg] = 3, |
169 | [f71869] = 3, | 175 | [f71869] = 3, |
@@ -171,12 +177,13 @@ static const char f71882fg_nr_fans[] = { | |||
171 | [f71889fg] = 3, | 177 | [f71889fg] = 3, |
172 | [f71889ed] = 3, | 178 | [f71889ed] = 3, |
173 | [f71889a] = 3, | 179 | [f71889a] = 3, |
174 | [f8000] = 3, | 180 | [f8000] = 3, /* +1 fan which is monitor only */ |
175 | [f81865f] = 2, | 181 | [f81865f] = 2, |
176 | }; | 182 | }; |
177 | 183 | ||
178 | static const char f71882fg_temp_has_beep[] = { | 184 | static const char f71882fg_temp_has_beep[] = { |
179 | [f71808e] = 0, | 185 | [f71808e] = 0, |
186 | [f71808a] = 1, | ||
180 | [f71858fg] = 0, | 187 | [f71858fg] = 0, |
181 | [f71862fg] = 1, | 188 | [f71862fg] = 1, |
182 | [f71869] = 1, | 189 | [f71869] = 1, |
@@ -190,6 +197,7 @@ static const char f71882fg_temp_has_beep[] = { | |||
190 | 197 | ||
191 | static const char f71882fg_nr_temps[] = { | 198 | static const char f71882fg_nr_temps[] = { |
192 | [f71808e] = 2, | 199 | [f71808e] = 2, |
200 | [f71808a] = 2, | ||
193 | [f71858fg] = 3, | 201 | [f71858fg] = 3, |
194 | [f71862fg] = 3, | 202 | [f71862fg] = 3, |
195 | [f71869] = 3, | 203 | [f71869] = 3, |
@@ -314,6 +322,10 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, | |||
314 | char *buf); | 322 | char *buf); |
315 | static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, | 323 | static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, |
316 | const char *buf, size_t count); | 324 | const char *buf, size_t count); |
325 | static ssize_t show_simple_pwm(struct device *dev, | ||
326 | struct device_attribute *devattr, char *buf); | ||
327 | static ssize_t store_simple_pwm(struct device *dev, | ||
328 | struct device_attribute *devattr, const char *buf, size_t count); | ||
317 | static ssize_t show_pwm_enable(struct device *dev, | 329 | static ssize_t show_pwm_enable(struct device *dev, |
318 | struct device_attribute *devattr, char *buf); | 330 | struct device_attribute *devattr, char *buf); |
319 | static ssize_t store_pwm_enable(struct device *dev, | 331 | static ssize_t store_pwm_enable(struct device *dev, |
@@ -563,6 +575,14 @@ static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { { | |||
563 | show_pwm_interpolate, store_pwm_interpolate, 0, 3), | 575 | show_pwm_interpolate, store_pwm_interpolate, 0, 3), |
564 | } }; | 576 | } }; |
565 | 577 | ||
578 | /* Attr for the third fan of the f71808a, which only has manual pwm */ | ||
579 | static struct sensor_device_attribute_2 f71808a_fan3_attr[] = { | ||
580 | SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2), | ||
581 | SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2), | ||
582 | SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, | ||
583 | show_simple_pwm, store_simple_pwm, 0, 2), | ||
584 | }; | ||
585 | |||
566 | /* Attr for models which can beep on Fan alarm */ | 586 | /* Attr for models which can beep on Fan alarm */ |
567 | static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = { | 587 | static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = { |
568 | SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, | 588 | SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, |
@@ -1246,7 +1266,13 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
1246 | data->pwm[nr] = | 1266 | data->pwm[nr] = |
1247 | f71882fg_read8(data, F71882FG_REG_PWM(nr)); | 1267 | f71882fg_read8(data, F71882FG_REG_PWM(nr)); |
1248 | } | 1268 | } |
1249 | /* The f8000 can monitor 1 more fan, but has no pwm for it */ | 1269 | /* Some models have 1 more fan with limited capabilities */ |
1270 | if (data->type == f71808a) { | ||
1271 | data->fan[2] = f71882fg_read16(data, | ||
1272 | F71882FG_REG_FAN(2)); | ||
1273 | data->pwm[2] = f71882fg_read8(data, | ||
1274 | F71882FG_REG_PWM(2)); | ||
1275 | } | ||
1250 | if (data->type == f8000) | 1276 | if (data->type == f8000) |
1251 | data->fan[3] = f71882fg_read16(data, | 1277 | data->fan[3] = f71882fg_read16(data, |
1252 | F71882FG_REG_FAN(3)); | 1278 | F71882FG_REG_FAN(3)); |
@@ -1736,6 +1762,38 @@ leave: | |||
1736 | return count; | 1762 | return count; |
1737 | } | 1763 | } |
1738 | 1764 | ||
1765 | static ssize_t show_simple_pwm(struct device *dev, | ||
1766 | struct device_attribute *devattr, char *buf) | ||
1767 | { | ||
1768 | struct f71882fg_data *data = f71882fg_update_device(dev); | ||
1769 | int val, nr = to_sensor_dev_attr_2(devattr)->index; | ||
1770 | |||
1771 | val = data->pwm[nr]; | ||
1772 | return sprintf(buf, "%d\n", val); | ||
1773 | } | ||
1774 | |||
1775 | static ssize_t store_simple_pwm(struct device *dev, | ||
1776 | struct device_attribute *devattr, | ||
1777 | const char *buf, size_t count) | ||
1778 | { | ||
1779 | struct f71882fg_data *data = dev_get_drvdata(dev); | ||
1780 | int err, nr = to_sensor_dev_attr_2(devattr)->index; | ||
1781 | long val; | ||
1782 | |||
1783 | err = strict_strtol(buf, 10, &val); | ||
1784 | if (err) | ||
1785 | return err; | ||
1786 | |||
1787 | val = SENSORS_LIMIT(val, 0, 255); | ||
1788 | |||
1789 | mutex_lock(&data->update_lock); | ||
1790 | f71882fg_write8(data, F71882FG_REG_PWM(nr), val); | ||
1791 | data->pwm[nr] = val; | ||
1792 | mutex_unlock(&data->update_lock); | ||
1793 | |||
1794 | return count; | ||
1795 | } | ||
1796 | |||
1739 | static ssize_t show_pwm_enable(struct device *dev, | 1797 | static ssize_t show_pwm_enable(struct device *dev, |
1740 | struct device_attribute *devattr, char *buf) | 1798 | struct device_attribute *devattr, char *buf) |
1741 | { | 1799 | { |
@@ -2183,6 +2241,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2183 | if (start_reg & 0x02) { | 2241 | if (start_reg & 0x02) { |
2184 | switch (data->type) { | 2242 | switch (data->type) { |
2185 | case f71808e: | 2243 | case f71808e: |
2244 | case f71808a: | ||
2186 | case f71869: | 2245 | case f71869: |
2187 | /* These always have signed auto point temps */ | 2246 | /* These always have signed auto point temps */ |
2188 | data->auto_point_temp_signed = 1; | 2247 | data->auto_point_temp_signed = 1; |
@@ -2244,6 +2303,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2244 | 2303 | ||
2245 | switch (data->type) { | 2304 | switch (data->type) { |
2246 | case f71808e: | 2305 | case f71808e: |
2306 | case f71808a: | ||
2247 | case f71869: | 2307 | case f71869: |
2248 | case f71889fg: | 2308 | case f71889fg: |
2249 | case f71889ed: | 2309 | case f71889ed: |
@@ -2269,6 +2329,16 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2269 | } | 2329 | } |
2270 | 2330 | ||
2271 | switch (data->type) { | 2331 | switch (data->type) { |
2332 | case f71808a: | ||
2333 | err = f71882fg_create_sysfs_files(pdev, | ||
2334 | &fxxxx_auto_pwm_attr[0][0], | ||
2335 | ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); | ||
2336 | if (err) | ||
2337 | goto exit_unregister_sysfs; | ||
2338 | err = f71882fg_create_sysfs_files(pdev, | ||
2339 | f71808a_fan3_attr, | ||
2340 | ARRAY_SIZE(f71808a_fan3_attr)); | ||
2341 | break; | ||
2272 | case f71862fg: | 2342 | case f71862fg: |
2273 | err = f71882fg_create_sysfs_files(pdev, | 2343 | err = f71882fg_create_sysfs_files(pdev, |
2274 | f71862fg_auto_pwm_attr, | 2344 | f71862fg_auto_pwm_attr, |
@@ -2386,6 +2456,14 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2386 | } | 2456 | } |
2387 | 2457 | ||
2388 | switch (data->type) { | 2458 | switch (data->type) { |
2459 | case f71808a: | ||
2460 | f71882fg_remove_sysfs_files(pdev, | ||
2461 | &fxxxx_auto_pwm_attr[0][0], | ||
2462 | ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); | ||
2463 | f71882fg_remove_sysfs_files(pdev, | ||
2464 | f71808a_fan3_attr, | ||
2465 | ARRAY_SIZE(f71808a_fan3_attr)); | ||
2466 | break; | ||
2389 | case f71862fg: | 2467 | case f71862fg: |
2390 | f71882fg_remove_sysfs_files(pdev, | 2468 | f71882fg_remove_sysfs_files(pdev, |
2391 | f71862fg_auto_pwm_attr, | 2469 | f71862fg_auto_pwm_attr, |
@@ -2438,6 +2516,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2438 | case SIO_F71808E_ID: | 2516 | case SIO_F71808E_ID: |
2439 | sio_data->type = f71808e; | 2517 | sio_data->type = f71808e; |
2440 | break; | 2518 | break; |
2519 | case SIO_F71808A_ID: | ||
2520 | sio_data->type = f71808a; | ||
2521 | break; | ||
2441 | case SIO_F71858_ID: | 2522 | case SIO_F71858_ID: |
2442 | sio_data->type = f71858fg; | 2523 | sio_data->type = f71858fg; |
2443 | break; | 2524 | break; |