diff options
| -rw-r--r-- | Documentation/hwmon/f71882fg | 4 | ||||
| -rw-r--r-- | drivers/hwmon/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/hwmon/f71882fg.c | 87 |
3 files changed, 89 insertions, 4 deletions
diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg index df02245d1419..84d2623810f3 100644 --- a/Documentation/hwmon/f71882fg +++ b/Documentation/hwmon/f71882fg | |||
| @@ -6,6 +6,10 @@ Supported chips: | |||
| 6 | Prefix: 'f71808e' | 6 | Prefix: 'f71808e' |
| 7 | Addresses scanned: none, address read from Super I/O config space | 7 | Addresses scanned: none, address read from Super I/O config space |
| 8 | Datasheet: Not public | 8 | Datasheet: Not public |
| 9 | * Fintek F71808A | ||
| 10 | Prefix: 'f71808a' | ||
| 11 | Addresses scanned: none, address read from Super I/O config space | ||
| 12 | Datasheet: Not public | ||
| 9 | * Fintek F71858FG | 13 | * Fintek F71858FG |
| 10 | Prefix: 'f71858fg' | 14 | Prefix: 'f71858fg' |
| 11 | Addresses scanned: none, address read from Super I/O config space | 15 | Addresses scanned: none, address read from Super I/O config space |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 9ebdb0da7f7c..a620a760397d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -329,7 +329,7 @@ config SENSORS_F71882FG | |||
| 329 | If you say yes here you get support for hardware monitoring | 329 | If you say yes here you get support for hardware monitoring |
| 330 | features of many Fintek Super-I/O (LPC) chips. The currently | 330 | features of many Fintek Super-I/O (LPC) chips. The currently |
| 331 | supported chips are: | 331 | supported chips are: |
| 332 | F71808E | 332 | F71808E/A |
| 333 | F71858FG | 333 | F71858FG |
| 334 | F71862FG | 334 | F71862FG |
| 335 | F71863FG | 335 | F71863FG |
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; |
