diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 188 |
1 files changed, 106 insertions, 82 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index a658d62c5e10..ec595c606ed4 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -1,50 +1,49 @@ | |||
1 | /* | 1 | /* |
2 | w83627ehf - Driver for the hardware monitoring functionality of | 2 | * w83627ehf - Driver for the hardware monitoring functionality of |
3 | the Winbond W83627EHF Super-I/O chip | 3 | * the Winbond W83627EHF Super-I/O chip |
4 | Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org> | 4 | * Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org> |
5 | Copyright (C) 2006 Yuan Mu (Winbond), | 5 | * Copyright (C) 2006 Yuan Mu (Winbond), |
6 | Rudolf Marek <r.marek@assembler.cz> | 6 | * Rudolf Marek <r.marek@assembler.cz> |
7 | David Hubbard <david.c.hubbard@gmail.com> | 7 | * David Hubbard <david.c.hubbard@gmail.com> |
8 | Daniel J Blueman <daniel.blueman@gmail.com> | 8 | * Daniel J Blueman <daniel.blueman@gmail.com> |
9 | Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00) | 9 | * Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00) |
10 | 10 | * | |
11 | Shamelessly ripped from the w83627hf driver | 11 | * Shamelessly ripped from the w83627hf driver |
12 | Copyright (C) 2003 Mark Studebaker | 12 | * Copyright (C) 2003 Mark Studebaker |
13 | 13 | * | |
14 | Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help | 14 | * Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help |
15 | in testing and debugging this driver. | 15 | * in testing and debugging this driver. |
16 | 16 | * | |
17 | This driver also supports the W83627EHG, which is the lead-free | 17 | * This driver also supports the W83627EHG, which is the lead-free |
18 | version of the W83627EHF. | 18 | * version of the W83627EHF. |
19 | 19 | * | |
20 | This program is free software; you can redistribute it and/or modify | 20 | * This program is free software; you can redistribute it and/or modify |
21 | it under the terms of the GNU General Public License as published by | 21 | * it under the terms of the GNU General Public License as published by |
22 | the Free Software Foundation; either version 2 of the License, or | 22 | * the Free Software Foundation; either version 2 of the License, or |
23 | (at your option) any later version. | 23 | * (at your option) any later version. |
24 | 24 | * | |
25 | This program is distributed in the hope that it will be useful, | 25 | * This program is distributed in the hope that it will be useful, |
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
28 | GNU General Public License for more details. | 28 | * GNU General Public License for more details. |
29 | 29 | * | |
30 | You should have received a copy of the GNU General Public License | 30 | * You should have received a copy of the GNU General Public License |
31 | along with this program; if not, write to the Free Software | 31 | * along with this program; if not, write to the Free Software |
32 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 32 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
33 | 33 | * | |
34 | 34 | * Supports the following chips: | |
35 | Supports the following chips: | 35 | * |
36 | 36 | * Chip #vin #fan #pwm #temp chip IDs man ID | |
37 | Chip #vin #fan #pwm #temp chip IDs man ID | 37 | * w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 |
38 | w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 | 38 | * 0x8860 0xa1 |
39 | 0x8860 0xa1 | 39 | * w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 |
40 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 | 40 | * w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 |
41 | w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 | 41 | * w83627uhg 8 2 2 3 0xa230 0xc1 0x5ca3 |
42 | w83627uhg 8 2 2 3 0xa230 0xc1 0x5ca3 | 42 | * w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 |
43 | w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 | 43 | * w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 |
44 | w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 | 44 | * nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 |
45 | nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 | 45 | * nct6776f 9 5 3 9 0xC330 0xc1 0x5ca3 |
46 | nct6776f 9 5 3 9 0xC330 0xc1 0x5ca3 | 46 | */ |
47 | */ | ||
48 | 47 | ||
49 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 48 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
50 | 49 | ||
@@ -164,11 +163,13 @@ superio_exit(int ioreg) | |||
164 | #define W83627EHF_REG_BANK 0x4E | 163 | #define W83627EHF_REG_BANK 0x4E |
165 | #define W83627EHF_REG_CONFIG 0x40 | 164 | #define W83627EHF_REG_CONFIG 0x40 |
166 | 165 | ||
167 | /* Not currently used: | 166 | /* |
167 | * Not currently used: | ||
168 | * REG_MAN_ID has the value 0x5ca3 for all supported chips. | 168 | * REG_MAN_ID has the value 0x5ca3 for all supported chips. |
169 | * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. | 169 | * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. |
170 | * REG_MAN_ID is at port 0x4f | 170 | * REG_MAN_ID is at port 0x4f |
171 | * REG_CHIP_ID is at port 0x58 */ | 171 | * REG_CHIP_ID is at port 0x58 |
172 | */ | ||
172 | 173 | ||
173 | static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; | 174 | static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; |
174 | static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; | 175 | static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; |
@@ -393,8 +394,10 @@ div_from_reg(u8 reg) | |||
393 | return 1 << reg; | 394 | return 1 << reg; |
394 | } | 395 | } |
395 | 396 | ||
396 | /* Some of the voltage inputs have internal scaling, the tables below | 397 | /* |
397 | * contain 8 (the ADC LSB in mV) * scaling factor * 100 */ | 398 | * Some of the voltage inputs have internal scaling, the tables below |
399 | * contain 8 (the ADC LSB in mV) * scaling factor * 100 | ||
400 | */ | ||
398 | static const u16 scale_in_common[10] = { | 401 | static const u16 scale_in_common[10] = { |
399 | 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800 | 402 | 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800 |
400 | }; | 403 | }; |
@@ -470,12 +473,13 @@ struct w83627ehf_data { | |||
470 | 473 | ||
471 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ | 474 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ |
472 | u8 pwm_enable[4]; /* 1->manual | 475 | u8 pwm_enable[4]; /* 1->manual |
473 | 2->thermal cruise mode (also called SmartFan I) | 476 | * 2->thermal cruise mode (also called SmartFan I) |
474 | 3->fan speed cruise mode | 477 | * 3->fan speed cruise mode |
475 | 4->variable thermal cruise (also called | 478 | * 4->variable thermal cruise (also called |
476 | SmartFan III) | 479 | * SmartFan III) |
477 | 5->enhanced variable thermal cruise (also called | 480 | * 5->enhanced variable thermal cruise (also called |
478 | SmartFan IV) */ | 481 | * SmartFan IV) |
482 | */ | ||
479 | u8 pwm_enable_orig[4]; /* original value of pwm_enable */ | 483 | u8 pwm_enable_orig[4]; /* original value of pwm_enable */ |
480 | u8 pwm_num; /* number of pwm */ | 484 | u8 pwm_num; /* number of pwm */ |
481 | u8 pwm[4]; | 485 | u8 pwm[4]; |
@@ -816,9 +820,11 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
816 | data->fan_min[i] = w83627ehf_read_value(data, | 820 | data->fan_min[i] = w83627ehf_read_value(data, |
817 | data->REG_FAN_MIN[i]); | 821 | data->REG_FAN_MIN[i]); |
818 | 822 | ||
819 | /* If we failed to measure the fan speed and clock | 823 | /* |
820 | divider can be increased, let's try that for next | 824 | * If we failed to measure the fan speed and clock |
821 | time */ | 825 | * divider can be increased, let's try that for next |
826 | * time | ||
827 | */ | ||
822 | if (data->has_fan_div | 828 | if (data->has_fan_div |
823 | && (reg >= 0xff || (sio_data->kind == nct6775 | 829 | && (reg >= 0xff || (sio_data->kind == nct6775 |
824 | && reg == 0x00)) | 830 | && reg == 0x00)) |
@@ -1081,25 +1087,31 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
1081 | new_div = data->fan_div[nr]; /* No change */ | 1087 | new_div = data->fan_div[nr]; /* No change */ |
1082 | dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1); | 1088 | dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1); |
1083 | } else if ((reg = 1350000U / val) >= 128 * 255) { | 1089 | } else if ((reg = 1350000U / val) >= 128 * 255) { |
1084 | /* Speed below this value cannot possibly be represented, | 1090 | /* |
1085 | even with the highest divider (128) */ | 1091 | * Speed below this value cannot possibly be represented, |
1092 | * even with the highest divider (128) | ||
1093 | */ | ||
1086 | data->fan_min[nr] = 254; | 1094 | data->fan_min[nr] = 254; |
1087 | new_div = 7; /* 128 == (1 << 7) */ | 1095 | new_div = 7; /* 128 == (1 << 7) */ |
1088 | dev_warn(dev, "fan%u low limit %lu below minimum %u, set to " | 1096 | dev_warn(dev, "fan%u low limit %lu below minimum %u, set to " |
1089 | "minimum\n", nr + 1, val, | 1097 | "minimum\n", nr + 1, val, |
1090 | data->fan_from_reg_min(254, 7)); | 1098 | data->fan_from_reg_min(254, 7)); |
1091 | } else if (!reg) { | 1099 | } else if (!reg) { |
1092 | /* Speed above this value cannot possibly be represented, | 1100 | /* |
1093 | even with the lowest divider (1) */ | 1101 | * Speed above this value cannot possibly be represented, |
1102 | * even with the lowest divider (1) | ||
1103 | */ | ||
1094 | data->fan_min[nr] = 1; | 1104 | data->fan_min[nr] = 1; |
1095 | new_div = 0; /* 1 == (1 << 0) */ | 1105 | new_div = 0; /* 1 == (1 << 0) */ |
1096 | dev_warn(dev, "fan%u low limit %lu above maximum %u, set to " | 1106 | dev_warn(dev, "fan%u low limit %lu above maximum %u, set to " |
1097 | "maximum\n", nr + 1, val, | 1107 | "maximum\n", nr + 1, val, |
1098 | data->fan_from_reg_min(1, 0)); | 1108 | data->fan_from_reg_min(1, 0)); |
1099 | } else { | 1109 | } else { |
1100 | /* Automatically pick the best divider, i.e. the one such | 1110 | /* |
1101 | that the min limit will correspond to a register value | 1111 | * Automatically pick the best divider, i.e. the one such |
1102 | in the 96..192 range */ | 1112 | * that the min limit will correspond to a register value |
1113 | * in the 96..192 range | ||
1114 | */ | ||
1103 | new_div = 0; | 1115 | new_div = 0; |
1104 | while (reg > 192 && new_div < 7) { | 1116 | while (reg > 192 && new_div < 7) { |
1105 | reg >>= 1; | 1117 | reg >>= 1; |
@@ -1108,8 +1120,10 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
1108 | data->fan_min[nr] = reg; | 1120 | data->fan_min[nr] = reg; |
1109 | } | 1121 | } |
1110 | 1122 | ||
1111 | /* Write both the fan clock divider (if it changed) and the new | 1123 | /* |
1112 | fan min (unconditionally) */ | 1124 | * Write both the fan clock divider (if it changed) and the new |
1125 | * fan min (unconditionally) | ||
1126 | */ | ||
1113 | if (new_div != data->fan_div[nr]) { | 1127 | if (new_div != data->fan_div[nr]) { |
1114 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", | 1128 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", |
1115 | nr + 1, div_from_reg(data->fan_div[nr]), | 1129 | nr + 1, div_from_reg(data->fan_div[nr]), |
@@ -1736,8 +1750,10 @@ static struct sensor_device_attribute_2 sda_caseopen[] = { | |||
1736 | 1750 | ||
1737 | static void w83627ehf_device_remove_files(struct device *dev) | 1751 | static void w83627ehf_device_remove_files(struct device *dev) |
1738 | { | 1752 | { |
1739 | /* some entries in the following arrays may not have been used in | 1753 | /* |
1740 | * device_create_file(), but device_remove_file() will ignore them */ | 1754 | * some entries in the following arrays may not have been used in |
1755 | * device_create_file(), but device_remove_file() will ignore them | ||
1756 | */ | ||
1741 | int i; | 1757 | int i; |
1742 | struct w83627ehf_data *data = dev_get_drvdata(dev); | 1758 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
1743 | 1759 | ||
@@ -2279,9 +2295,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2279 | /* Read VID value */ | 2295 | /* Read VID value */ |
2280 | if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b || | 2296 | if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b || |
2281 | sio_data->kind == nct6775 || sio_data->kind == nct6776) { | 2297 | sio_data->kind == nct6775 || sio_data->kind == nct6776) { |
2282 | /* W83667HG has different pins for VID input and output, so | 2298 | /* |
2283 | we can get the VID input values directly at logical device D | 2299 | * W83667HG has different pins for VID input and output, so |
2284 | 0xe3. */ | 2300 | * we can get the VID input values directly at logical device D |
2301 | * 0xe3. | ||
2302 | */ | ||
2285 | superio_select(sio_data->sioreg, W83667HG_LD_VID); | 2303 | superio_select(sio_data->sioreg, W83667HG_LD_VID); |
2286 | data->vid = superio_inb(sio_data->sioreg, 0xe3); | 2304 | data->vid = superio_inb(sio_data->sioreg, 0xe3); |
2287 | err = device_create_file(dev, &dev_attr_cpu0_vid); | 2305 | err = device_create_file(dev, &dev_attr_cpu0_vid); |
@@ -2290,11 +2308,13 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2290 | } else if (sio_data->kind != w83627uhg) { | 2308 | } else if (sio_data->kind != w83627uhg) { |
2291 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); | 2309 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); |
2292 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { | 2310 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { |
2293 | /* Set VID input sensibility if needed. In theory the | 2311 | /* |
2294 | BIOS should have set it, but in practice it's not | 2312 | * Set VID input sensibility if needed. In theory the |
2295 | always the case. We only do it for the W83627EHF/EHG | 2313 | * BIOS should have set it, but in practice it's not |
2296 | because the W83627DHG is more complex in this | 2314 | * always the case. We only do it for the W83627EHF/EHG |
2297 | respect. */ | 2315 | * because the W83627DHG is more complex in this |
2316 | * respect. | ||
2317 | */ | ||
2298 | if (sio_data->kind == w83627ehf) { | 2318 | if (sio_data->kind == w83627ehf) { |
2299 | en_vrm10 = superio_inb(sio_data->sioreg, | 2319 | en_vrm10 = superio_inb(sio_data->sioreg, |
2300 | SIO_REG_EN_VRM10); | 2320 | SIO_REG_EN_VRM10); |
@@ -2616,10 +2636,12 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | |||
2616 | return 0; | 2636 | return 0; |
2617 | } | 2637 | } |
2618 | 2638 | ||
2619 | /* when Super-I/O functions move to a separate file, the Super-I/O | 2639 | /* |
2640 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
2620 | * bus will manage the lifetime of the device and this module will only keep | 2641 | * bus will manage the lifetime of the device and this module will only keep |
2621 | * track of the w83627ehf driver. But since we platform_device_alloc(), we | 2642 | * track of the w83627ehf driver. But since we platform_device_alloc(), we |
2622 | * must keep track of the device */ | 2643 | * must keep track of the device |
2644 | */ | ||
2623 | static struct platform_device *pdev; | 2645 | static struct platform_device *pdev; |
2624 | 2646 | ||
2625 | static int __init sensors_w83627ehf_init(void) | 2647 | static int __init sensors_w83627ehf_init(void) |
@@ -2629,11 +2651,13 @@ static int __init sensors_w83627ehf_init(void) | |||
2629 | struct resource res; | 2651 | struct resource res; |
2630 | struct w83627ehf_sio_data sio_data; | 2652 | struct w83627ehf_sio_data sio_data; |
2631 | 2653 | ||
2632 | /* initialize sio_data->kind and sio_data->sioreg. | 2654 | /* |
2655 | * initialize sio_data->kind and sio_data->sioreg. | ||
2633 | * | 2656 | * |
2634 | * when Super-I/O functions move to a separate file, the Super-I/O | 2657 | * when Super-I/O functions move to a separate file, the Super-I/O |
2635 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a | 2658 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a |
2636 | * w83627ehf hardware monitor, and call probe() */ | 2659 | * w83627ehf hardware monitor, and call probe() |
2660 | */ | ||
2637 | if (w83627ehf_find(0x2e, &address, &sio_data) && | 2661 | if (w83627ehf_find(0x2e, &address, &sio_data) && |
2638 | w83627ehf_find(0x4e, &address, &sio_data)) | 2662 | w83627ehf_find(0x4e, &address, &sio_data)) |
2639 | return -ENODEV; | 2663 | return -ENODEV; |