diff options
| author | Juerg Haefliger <juergh@gmail.com> | 2010-05-27 13:59:01 -0400 |
|---|---|---|
| committer | Jean Delvare <khali@linux-fr.org> | 2010-05-27 13:59:01 -0400 |
| commit | ea694431f9c862bd409c90ba1cb3bdc6fdde8635 (patch) | |
| tree | 702ee926abff58b9896220ce02e4592b13978005 | |
| parent | 38806bda6b7c8473c47a967a514260c1a1c32c2e (diff) | |
hwmon: (dme1737) Add SCH5127 support
Add support for the hardware monitoring capabilities of the SCH5127
chip to the dme1737 driver.
Signed-off-by: Juerg Haefliger <juergh@gmail.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Tested-by: Jeff Rickman <jrickman@myamigos.us>
| -rw-r--r-- | Documentation/hwmon/dme1737 | 51 | ||||
| -rw-r--r-- | drivers/hwmon/dme1737.c | 328 |
2 files changed, 266 insertions, 113 deletions
diff --git a/Documentation/hwmon/dme1737 b/Documentation/hwmon/dme1737 index 001d2e70bc11..fc5df7654d63 100644 --- a/Documentation/hwmon/dme1737 +++ b/Documentation/hwmon/dme1737 | |||
| @@ -9,11 +9,15 @@ Supported chips: | |||
| 9 | * SMSC SCH3112, SCH3114, SCH3116 | 9 | * SMSC SCH3112, SCH3114, SCH3116 |
| 10 | Prefix: 'sch311x' | 10 | Prefix: 'sch311x' |
| 11 | Addresses scanned: none, address read from Super-I/O config space | 11 | Addresses scanned: none, address read from Super-I/O config space |
| 12 | Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf | 12 | Datasheet: Available on the Internet |
| 13 | * SMSC SCH5027 | 13 | * SMSC SCH5027 |
| 14 | Prefix: 'sch5027' | 14 | Prefix: 'sch5027' |
| 15 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e | 15 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e |
| 16 | Datasheet: Provided by SMSC upon request and under NDA | 16 | Datasheet: Provided by SMSC upon request and under NDA |
| 17 | * SMSC SCH5127 | ||
| 18 | Prefix: 'sch5127' | ||
| 19 | Addresses scanned: none, address read from Super-I/O config space | ||
| 20 | Datasheet: Provided by SMSC upon request and under NDA | ||
| 17 | 21 | ||
| 18 | Authors: | 22 | Authors: |
| 19 | Juerg Haefliger <juergh@gmail.com> | 23 | Juerg Haefliger <juergh@gmail.com> |
| @@ -36,8 +40,8 @@ Description | |||
| 36 | ----------- | 40 | ----------- |
| 37 | 41 | ||
| 38 | This driver implements support for the hardware monitoring capabilities of the | 42 | This driver implements support for the hardware monitoring capabilities of the |
| 39 | SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, and SMSC | 43 | SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, SCH311x, |
| 40 | SCH311x Super-I/O chips. These chips feature monitoring of 3 temp sensors | 44 | and SCH5127 Super-I/O chips. These chips feature monitoring of 3 temp sensors |
| 41 | temp[1-3] (2 remote diodes and 1 internal), 7 voltages in[0-6] (6 external and | 45 | temp[1-3] (2 remote diodes and 1 internal), 7 voltages in[0-6] (6 external and |
| 42 | 1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement | 46 | 1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement |
| 43 | up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and | 47 | up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and |
| @@ -48,14 +52,14 @@ Fan[3-6] and pwm[3,5-6] are optional features and their availability depends on | |||
| 48 | the configuration of the chip. The driver will detect which features are | 52 | the configuration of the chip. The driver will detect which features are |
| 49 | present during initialization and create the sysfs attributes accordingly. | 53 | present during initialization and create the sysfs attributes accordingly. |
| 50 | 54 | ||
| 51 | For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and | 55 | For the SCH311x and SCH5127, fan[1-3] and pwm[1-3] are always present and |
| 52 | pwm[5-6] don't exist. | 56 | fan[4-6] and pwm[5-6] don't exist. |
| 53 | 57 | ||
| 54 | The hardware monitoring features of the DME1737, A8000, and SCH5027 are only | 58 | The hardware monitoring features of the DME1737, A8000, and SCH5027 are only |
| 55 | accessible via SMBus, while the SCH311x only provides access via the ISA bus. | 59 | accessible via SMBus, while the SCH311x and SCH5127 only provide access via |
| 56 | The driver will therefore register itself as an I2C client driver if it detects | 60 | the ISA bus. The driver will therefore register itself as an I2C client driver |
| 57 | a DME1737, A8000, or SCH5027 and as a platform driver if it detects a SCH311x | 61 | if it detects a DME1737, A8000, or SCH5027 and as a platform driver if it |
| 58 | chip. | 62 | detects a SCH311x or SCH5127 chip. |
| 59 | 63 | ||
| 60 | 64 | ||
| 61 | Voltage Monitoring | 65 | Voltage Monitoring |
| @@ -76,7 +80,7 @@ DME1737, A8000: | |||
| 76 | in6: Vbat (+3.0V) 0V - 4.38V | 80 | in6: Vbat (+3.0V) 0V - 4.38V |
| 77 | 81 | ||
| 78 | SCH311x: | 82 | SCH311x: |
| 79 | in0: +2.5V 0V - 6.64V | 83 | in0: +2.5V 0V - 3.32V |
| 80 | in1: Vccp (processor core) 0V - 2V | 84 | in1: Vccp (processor core) 0V - 2V |
| 81 | in2: VCC (internal +3.3V) 0V - 4.38V | 85 | in2: VCC (internal +3.3V) 0V - 4.38V |
| 82 | in3: +5V 0V - 6.64V | 86 | in3: +5V 0V - 6.64V |
| @@ -93,6 +97,15 @@ SCH5027: | |||
| 93 | in5: VTR (+3.3V standby) 0V - 4.38V | 97 | in5: VTR (+3.3V standby) 0V - 4.38V |
| 94 | in6: Vbat (+3.0V) 0V - 4.38V | 98 | in6: Vbat (+3.0V) 0V - 4.38V |
| 95 | 99 | ||
| 100 | SCH5127: | ||
| 101 | in0: +2.5 0V - 3.32V | ||
| 102 | in1: Vccp (processor core) 0V - 3V | ||
| 103 | in2: VCC (internal +3.3V) 0V - 4.38V | ||
| 104 | in3: V2_IN 0V - 1.5V | ||
| 105 | in4: V1_IN 0V - 1.5V | ||
| 106 | in5: VTR (+3.3V standby) 0V - 4.38V | ||
| 107 | in6: Vbat (+3.0V) 0V - 4.38V | ||
| 108 | |||
| 96 | Each voltage input has associated min and max limits which trigger an alarm | 109 | Each voltage input has associated min and max limits which trigger an alarm |
| 97 | when crossed. | 110 | when crossed. |
| 98 | 111 | ||
| @@ -293,3 +306,21 @@ pwm[1-3]_auto_point1_pwm RW Auto PWM pwm point. Auto_point1 is the | |||
| 293 | pwm[1-3]_auto_point2_pwm RO Auto PWM pwm point. Auto_point2 is the | 306 | pwm[1-3]_auto_point2_pwm RO Auto PWM pwm point. Auto_point2 is the |
| 294 | full-speed duty-cycle which is hard- | 307 | full-speed duty-cycle which is hard- |
| 295 | wired to 255 (100% duty-cycle). | 308 | wired to 255 (100% duty-cycle). |
| 309 | |||
| 310 | Chip Differences | ||
| 311 | ---------------- | ||
| 312 | |||
| 313 | Feature dme1737 sch311x sch5027 sch5127 | ||
| 314 | ------------------------------------------------------- | ||
| 315 | temp[1-3]_offset yes yes | ||
| 316 | vid yes | ||
| 317 | zone3 yes yes yes | ||
| 318 | zone[1-3]_hyst yes yes | ||
| 319 | pwm min/off yes yes | ||
| 320 | fan3 opt yes opt yes | ||
| 321 | pwm3 opt yes opt yes | ||
| 322 | fan4 opt opt | ||
| 323 | fan5 opt opt | ||
| 324 | pwm5 opt opt | ||
| 325 | fan6 opt opt | ||
| 326 | pwm6 opt opt | ||
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 823dd28a902c..980c17d5eeae 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
| @@ -1,12 +1,14 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x and | 2 | * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x, SCH5027, |
| 3 | * SCH5027 Super-I/O chips integrated hardware monitoring features. | 3 | * and SCH5127 Super-I/O chips integrated hardware monitoring |
| 4 | * Copyright (c) 2007, 2008 Juerg Haefliger <juergh@gmail.com> | 4 | * features. |
| 5 | * Copyright (c) 2007, 2008, 2009, 2010 Juerg Haefliger <juergh@gmail.com> | ||
| 5 | * | 6 | * |
| 6 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access | 7 | * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access |
| 7 | * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus | 8 | * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus |
| 8 | * if a SCH311x chip is found. Both types of chips have very similar hardware | 9 | * if a SCH311x or SCH5127 chip is found. Both types of chips have very |
| 9 | * monitoring capabilities but differ in the way they can be accessed. | 10 | * similar hardware monitoring capabilities but differ in the way they can be |
| 11 | * accessed. | ||
| 10 | * | 12 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License as published by | 14 | * it under the terms of the GNU General Public License as published by |
| @@ -57,7 +59,7 @@ MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " | |||
| 57 | /* Addresses to scan */ | 59 | /* Addresses to scan */ |
| 58 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; | 60 | static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; |
| 59 | 61 | ||
| 60 | enum chips { dme1737, sch5027, sch311x }; | 62 | enum chips { dme1737, sch5027, sch311x, sch5127 }; |
| 61 | 63 | ||
| 62 | /* --------------------------------------------------------------------- | 64 | /* --------------------------------------------------------------------- |
| 63 | * Registers | 65 | * Registers |
| @@ -164,10 +166,29 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | |||
| 164 | #define DME1737_VERSTEP_MASK 0xf8 | 166 | #define DME1737_VERSTEP_MASK 0xf8 |
| 165 | #define SCH311X_DEVICE 0x8c | 167 | #define SCH311X_DEVICE 0x8c |
| 166 | #define SCH5027_VERSTEP 0x69 | 168 | #define SCH5027_VERSTEP 0x69 |
| 169 | #define SCH5127_DEVICE 0x8e | ||
| 170 | |||
| 171 | /* Device ID values (global configuration register index 0x20) */ | ||
| 172 | #define DME1737_ID_1 0x77 | ||
| 173 | #define DME1737_ID_2 0x78 | ||
| 174 | #define SCH3112_ID 0x7c | ||
| 175 | #define SCH3114_ID 0x7d | ||
| 176 | #define SCH3116_ID 0x7f | ||
| 177 | #define SCH5027_ID 0x89 | ||
| 178 | #define SCH5127_ID 0x86 | ||
| 167 | 179 | ||
| 168 | /* Length of ISA address segment */ | 180 | /* Length of ISA address segment */ |
| 169 | #define DME1737_EXTENT 2 | 181 | #define DME1737_EXTENT 2 |
| 170 | 182 | ||
| 183 | /* chip-dependent features */ | ||
| 184 | #define HAS_TEMP_OFFSET (1 << 0) /* bit 0 */ | ||
| 185 | #define HAS_VID (1 << 1) /* bit 1 */ | ||
| 186 | #define HAS_ZONE3 (1 << 2) /* bit 2 */ | ||
| 187 | #define HAS_ZONE_HYST (1 << 3) /* bit 3 */ | ||
| 188 | #define HAS_PWM_MIN (1 << 4) /* bit 4 */ | ||
| 189 | #define HAS_FAN(ix) (1 << ((ix) + 5)) /* bits 5-10 */ | ||
| 190 | #define HAS_PWM(ix) (1 << ((ix) + 11)) /* bits 11-16 */ | ||
| 191 | |||
| 171 | /* --------------------------------------------------------------------- | 192 | /* --------------------------------------------------------------------- |
| 172 | * Data structures and manipulation thereof | 193 | * Data structures and manipulation thereof |
| 173 | * --------------------------------------------------------------------- */ | 194 | * --------------------------------------------------------------------- */ |
| @@ -187,8 +208,7 @@ struct dme1737_data { | |||
| 187 | 208 | ||
| 188 | u8 vid; | 209 | u8 vid; |
| 189 | u8 pwm_rr_en; | 210 | u8 pwm_rr_en; |
| 190 | u8 has_pwm; | 211 | u32 has_features; |
| 191 | u8 has_fan; | ||
| 192 | 212 | ||
| 193 | /* Register values */ | 213 | /* Register values */ |
| 194 | u16 in[7]; | 214 | u16 in[7]; |
| @@ -224,8 +244,11 @@ static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300, | |||
| 224 | 3300}; | 244 | 3300}; |
| 225 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, | 245 | static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, |
| 226 | 3300}; | 246 | 3300}; |
| 247 | static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300, | ||
| 248 | 3300}; | ||
| 227 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ | 249 | #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ |
| 228 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ | 250 | (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ |
| 251 | (type) == sch5127 ? IN_NOMINAL_SCH5127 : \ | ||
| 229 | IN_NOMINAL_DME1737) | 252 | IN_NOMINAL_DME1737) |
| 230 | 253 | ||
| 231 | /* Voltage input | 254 | /* Voltage input |
| @@ -568,7 +591,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
| 568 | 591 | ||
| 569 | /* Sample register contents every 1 sec */ | 592 | /* Sample register contents every 1 sec */ |
| 570 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { | 593 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { |
| 571 | if (data->type == dme1737) { | 594 | if (data->has_features & HAS_VID) { |
| 572 | data->vid = dme1737_read(data, DME1737_REG_VID) & | 595 | data->vid = dme1737_read(data, DME1737_REG_VID) & |
| 573 | 0x3f; | 596 | 0x3f; |
| 574 | } | 597 | } |
| @@ -599,7 +622,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
| 599 | DME1737_REG_TEMP_MIN(ix)); | 622 | DME1737_REG_TEMP_MIN(ix)); |
| 600 | data->temp_max[ix] = dme1737_read(data, | 623 | data->temp_max[ix] = dme1737_read(data, |
| 601 | DME1737_REG_TEMP_MAX(ix)); | 624 | DME1737_REG_TEMP_MAX(ix)); |
| 602 | if (data->type != sch5027) { | 625 | if (data->has_features & HAS_TEMP_OFFSET) { |
| 603 | data->temp_offset[ix] = dme1737_read(data, | 626 | data->temp_offset[ix] = dme1737_read(data, |
| 604 | DME1737_REG_TEMP_OFFSET(ix)); | 627 | DME1737_REG_TEMP_OFFSET(ix)); |
| 605 | } | 628 | } |
| @@ -626,7 +649,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
| 626 | for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { | 649 | for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { |
| 627 | /* Skip reading registers if optional fans are not | 650 | /* Skip reading registers if optional fans are not |
| 628 | * present */ | 651 | * present */ |
| 629 | if (!(data->has_fan & (1 << ix))) { | 652 | if (!(data->has_features & HAS_FAN(ix))) { |
| 630 | continue; | 653 | continue; |
| 631 | } | 654 | } |
| 632 | data->fan[ix] = dme1737_read(data, | 655 | data->fan[ix] = dme1737_read(data, |
| @@ -650,7 +673,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
| 650 | for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { | 673 | for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { |
| 651 | /* Skip reading registers if optional PWMs are not | 674 | /* Skip reading registers if optional PWMs are not |
| 652 | * present */ | 675 | * present */ |
| 653 | if (!(data->has_pwm & (1 << ix))) { | 676 | if (!(data->has_features & HAS_PWM(ix))) { |
| 654 | continue; | 677 | continue; |
| 655 | } | 678 | } |
| 656 | data->pwm[ix] = dme1737_read(data, | 679 | data->pwm[ix] = dme1737_read(data, |
| @@ -672,12 +695,24 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) | |||
| 672 | 695 | ||
| 673 | /* Thermal zone registers */ | 696 | /* Thermal zone registers */ |
| 674 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { | 697 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { |
| 675 | data->zone_low[ix] = dme1737_read(data, | 698 | /* Skip reading registers if zone3 is not present */ |
| 676 | DME1737_REG_ZONE_LOW(ix)); | 699 | if ((ix == 2) && !(data->has_features & HAS_ZONE3)) { |
| 677 | data->zone_abs[ix] = dme1737_read(data, | 700 | continue; |
| 678 | DME1737_REG_ZONE_ABS(ix)); | 701 | } |
| 702 | /* sch5127 zone2 registers are special */ | ||
| 703 | if ((ix == 1) && (data->type == sch5127)) { | ||
| 704 | data->zone_low[1] = dme1737_read(data, | ||
| 705 | DME1737_REG_ZONE_LOW(2)); | ||
| 706 | data->zone_abs[1] = dme1737_read(data, | ||
| 707 | DME1737_REG_ZONE_ABS(2)); | ||
| 708 | } else { | ||
| 709 | data->zone_low[ix] = dme1737_read(data, | ||
| 710 | DME1737_REG_ZONE_LOW(ix)); | ||
| 711 | data->zone_abs[ix] = dme1737_read(data, | ||
| 712 | DME1737_REG_ZONE_ABS(ix)); | ||
| 713 | } | ||
| 679 | } | 714 | } |
| 680 | if (data->type != sch5027) { | 715 | if (data->has_features & HAS_ZONE_HYST) { |
| 681 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { | 716 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { |
| 682 | data->zone_hyst[ix] = dme1737_read(data, | 717 | data->zone_hyst[ix] = dme1737_read(data, |
| 683 | DME1737_REG_ZONE_HYST(ix)); | 718 | DME1737_REG_ZONE_HYST(ix)); |
| @@ -1594,10 +1629,6 @@ static struct attribute *dme1737_attr[] ={ | |||
| 1594 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, | 1629 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, |
| 1595 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, | 1630 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, |
| 1596 | &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, | 1631 | &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, |
| 1597 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | ||
| 1598 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | ||
| 1599 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | ||
| 1600 | &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, | ||
| 1601 | NULL | 1632 | NULL |
| 1602 | }; | 1633 | }; |
| 1603 | 1634 | ||
| @@ -1605,27 +1636,23 @@ static const struct attribute_group dme1737_group = { | |||
| 1605 | .attrs = dme1737_attr, | 1636 | .attrs = dme1737_attr, |
| 1606 | }; | 1637 | }; |
| 1607 | 1638 | ||
| 1608 | /* The following struct holds misc attributes, which are not available in all | 1639 | /* The following struct holds temp offset attributes, which are not available |
| 1609 | * chips. Their creation depends on the chip type which is determined during | 1640 | * in all chips. The following chips support them: |
| 1610 | * module load. */ | 1641 | * DME1737, SCH311x */ |
| 1611 | static struct attribute *dme1737_misc_attr[] = { | 1642 | static struct attribute *dme1737_temp_offset_attr[] = { |
| 1612 | /* Temperatures */ | ||
| 1613 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | 1643 | &sensor_dev_attr_temp1_offset.dev_attr.attr, |
| 1614 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 1644 | &sensor_dev_attr_temp2_offset.dev_attr.attr, |
| 1615 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | 1645 | &sensor_dev_attr_temp3_offset.dev_attr.attr, |
| 1616 | /* Zones */ | ||
| 1617 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1618 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1619 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1620 | NULL | 1646 | NULL |
| 1621 | }; | 1647 | }; |
| 1622 | 1648 | ||
| 1623 | static const struct attribute_group dme1737_misc_group = { | 1649 | static const struct attribute_group dme1737_temp_offset_group = { |
| 1624 | .attrs = dme1737_misc_attr, | 1650 | .attrs = dme1737_temp_offset_attr, |
| 1625 | }; | 1651 | }; |
| 1626 | 1652 | ||
| 1627 | /* The following struct holds VID-related attributes. Their creation | 1653 | /* The following struct holds VID related attributes, which are not available |
| 1628 | depends on the chip type which is determined during module load. */ | 1654 | * in all chips. The following chips support them: |
| 1655 | * DME1737 */ | ||
| 1629 | static struct attribute *dme1737_vid_attr[] = { | 1656 | static struct attribute *dme1737_vid_attr[] = { |
| 1630 | &dev_attr_vrm.attr, | 1657 | &dev_attr_vrm.attr, |
| 1631 | &dev_attr_cpu0_vid.attr, | 1658 | &dev_attr_cpu0_vid.attr, |
| @@ -1636,6 +1663,36 @@ static const struct attribute_group dme1737_vid_group = { | |||
| 1636 | .attrs = dme1737_vid_attr, | 1663 | .attrs = dme1737_vid_attr, |
| 1637 | }; | 1664 | }; |
| 1638 | 1665 | ||
| 1666 | /* The following struct holds temp zone 3 related attributes, which are not | ||
| 1667 | * available in all chips. The following chips support them: | ||
| 1668 | * DME1737, SCH311x, SCH5027 */ | ||
| 1669 | static struct attribute *dme1737_zone3_attr[] = { | ||
| 1670 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | ||
| 1671 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | ||
| 1672 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | ||
| 1673 | &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, | ||
| 1674 | NULL | ||
| 1675 | }; | ||
| 1676 | |||
| 1677 | static const struct attribute_group dme1737_zone3_group = { | ||
| 1678 | .attrs = dme1737_zone3_attr, | ||
| 1679 | }; | ||
| 1680 | |||
| 1681 | |||
| 1682 | /* The following struct holds temp zone hysteresis related attributes, which | ||
| 1683 | * are not available in all chips. The following chips support them: | ||
| 1684 | * DME1737, SCH311x */ | ||
| 1685 | static struct attribute *dme1737_zone_hyst_attr[] = { | ||
| 1686 | &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1687 | &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1688 | &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, | ||
| 1689 | NULL | ||
| 1690 | }; | ||
| 1691 | |||
| 1692 | static const struct attribute_group dme1737_zone_hyst_group = { | ||
| 1693 | .attrs = dme1737_zone_hyst_attr, | ||
| 1694 | }; | ||
| 1695 | |||
| 1639 | /* The following structs hold the PWM attributes, some of which are optional. | 1696 | /* The following structs hold the PWM attributes, some of which are optional. |
| 1640 | * Their creation depends on the chip configuration which is determined during | 1697 | * Their creation depends on the chip configuration which is determined during |
| 1641 | * module load. */ | 1698 | * module load. */ |
| @@ -1691,10 +1748,10 @@ static const struct attribute_group dme1737_pwm_group[] = { | |||
| 1691 | { .attrs = dme1737_pwm6_attr }, | 1748 | { .attrs = dme1737_pwm6_attr }, |
| 1692 | }; | 1749 | }; |
| 1693 | 1750 | ||
| 1694 | /* The following struct holds misc PWM attributes, which are not available in | 1751 | /* The following struct holds auto PWM min attributes, which are not available |
| 1695 | * all chips. Their creation depends on the chip type which is determined | 1752 | * in all chips. Their creation depends on the chip type which is determined |
| 1696 | * during module load. */ | 1753 | * during module load. */ |
| 1697 | static struct attribute *dme1737_pwm_misc_attr[] = { | 1754 | static struct attribute *dme1737_auto_pwm_min_attr[] = { |
| 1698 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | 1755 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, |
| 1699 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | 1756 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, |
| 1700 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | 1757 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, |
| @@ -1764,14 +1821,25 @@ static struct attribute *dme1737_zone_chmod_attr[] = { | |||
| 1764 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, | 1821 | &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, |
| 1765 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, | 1822 | &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, |
| 1766 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, | 1823 | &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, |
| 1824 | NULL | ||
| 1825 | }; | ||
| 1826 | |||
| 1827 | static const struct attribute_group dme1737_zone_chmod_group = { | ||
| 1828 | .attrs = dme1737_zone_chmod_attr, | ||
| 1829 | }; | ||
| 1830 | |||
| 1831 | |||
| 1832 | /* The permissions of the following zone 3 attributes are changed to read- | ||
| 1833 | * writeable if the chip is *not* locked. Otherwise they stay read-only. */ | ||
| 1834 | static struct attribute *dme1737_zone3_chmod_attr[] = { | ||
| 1767 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, | 1835 | &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, |
| 1768 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, | 1836 | &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, |
| 1769 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, | 1837 | &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, |
| 1770 | NULL | 1838 | NULL |
| 1771 | }; | 1839 | }; |
| 1772 | 1840 | ||
| 1773 | static const struct attribute_group dme1737_zone_chmod_group = { | 1841 | static const struct attribute_group dme1737_zone3_chmod_group = { |
| 1774 | .attrs = dme1737_zone_chmod_attr, | 1842 | .attrs = dme1737_zone3_chmod_attr, |
| 1775 | }; | 1843 | }; |
| 1776 | 1844 | ||
| 1777 | /* The permissions of the following PWM attributes are changed to read- | 1845 | /* The permissions of the following PWM attributes are changed to read- |
| @@ -1887,30 +1955,35 @@ static void dme1737_remove_files(struct device *dev) | |||
| 1887 | int ix; | 1955 | int ix; |
| 1888 | 1956 | ||
| 1889 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 1957 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
| 1890 | if (data->has_fan & (1 << ix)) { | 1958 | if (data->has_features & HAS_FAN(ix)) { |
| 1891 | sysfs_remove_group(&dev->kobj, | 1959 | sysfs_remove_group(&dev->kobj, |
| 1892 | &dme1737_fan_group[ix]); | 1960 | &dme1737_fan_group[ix]); |
| 1893 | } | 1961 | } |
| 1894 | } | 1962 | } |
| 1895 | 1963 | ||
| 1896 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | 1964 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { |
| 1897 | if (data->has_pwm & (1 << ix)) { | 1965 | if (data->has_features & HAS_PWM(ix)) { |
| 1898 | sysfs_remove_group(&dev->kobj, | 1966 | sysfs_remove_group(&dev->kobj, |
| 1899 | &dme1737_pwm_group[ix]); | 1967 | &dme1737_pwm_group[ix]); |
| 1900 | if (data->type != sch5027 && ix < 3) { | 1968 | if ((data->has_features & HAS_PWM_MIN) && ix < 3) { |
| 1901 | sysfs_remove_file(&dev->kobj, | 1969 | sysfs_remove_file(&dev->kobj, |
| 1902 | dme1737_pwm_misc_attr[ix]); | 1970 | dme1737_auto_pwm_min_attr[ix]); |
| 1903 | } | 1971 | } |
| 1904 | } | 1972 | } |
| 1905 | } | 1973 | } |
| 1906 | 1974 | ||
| 1907 | if (data->type != sch5027) { | 1975 | if (data->has_features & HAS_TEMP_OFFSET) { |
| 1908 | sysfs_remove_group(&dev->kobj, &dme1737_misc_group); | 1976 | sysfs_remove_group(&dev->kobj, &dme1737_temp_offset_group); |
| 1909 | } | 1977 | } |
| 1910 | if (data->type == dme1737) { | 1978 | if (data->has_features & HAS_VID) { |
| 1911 | sysfs_remove_group(&dev->kobj, &dme1737_vid_group); | 1979 | sysfs_remove_group(&dev->kobj, &dme1737_vid_group); |
| 1912 | } | 1980 | } |
| 1913 | 1981 | if (data->has_features & HAS_ZONE3) { | |
| 1982 | sysfs_remove_group(&dev->kobj, &dme1737_zone3_group); | ||
| 1983 | } | ||
| 1984 | if (data->has_features & HAS_ZONE_HYST) { | ||
| 1985 | sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group); | ||
| 1986 | } | ||
| 1914 | sysfs_remove_group(&dev->kobj, &dme1737_group); | 1987 | sysfs_remove_group(&dev->kobj, &dme1737_group); |
| 1915 | 1988 | ||
| 1916 | if (!data->client) { | 1989 | if (!data->client) { |
| @@ -1934,23 +2007,31 @@ static int dme1737_create_files(struct device *dev) | |||
| 1934 | goto exit_remove; | 2007 | goto exit_remove; |
| 1935 | } | 2008 | } |
| 1936 | 2009 | ||
| 1937 | /* Create misc sysfs attributes */ | 2010 | /* Create chip-dependent sysfs attributes */ |
| 1938 | if ((data->type != sch5027) && | 2011 | if ((data->has_features & HAS_TEMP_OFFSET) && |
| 1939 | (err = sysfs_create_group(&dev->kobj, | 2012 | (err = sysfs_create_group(&dev->kobj, |
| 1940 | &dme1737_misc_group))) { | 2013 | &dme1737_temp_offset_group))) { |
| 1941 | goto exit_remove; | 2014 | goto exit_remove; |
| 1942 | } | 2015 | } |
| 1943 | 2016 | if ((data->has_features & HAS_VID) && | |
| 1944 | /* Create VID-related sysfs attributes */ | ||
| 1945 | if ((data->type == dme1737) && | ||
| 1946 | (err = sysfs_create_group(&dev->kobj, | 2017 | (err = sysfs_create_group(&dev->kobj, |
| 1947 | &dme1737_vid_group))) { | 2018 | &dme1737_vid_group))) { |
| 1948 | goto exit_remove; | 2019 | goto exit_remove; |
| 1949 | } | 2020 | } |
| 2021 | if ((data->has_features & HAS_ZONE3) && | ||
| 2022 | (err = sysfs_create_group(&dev->kobj, | ||
| 2023 | &dme1737_zone3_group))) { | ||
| 2024 | goto exit_remove; | ||
| 2025 | } | ||
| 2026 | if ((data->has_features & HAS_ZONE_HYST) && | ||
| 2027 | (err = sysfs_create_group(&dev->kobj, | ||
| 2028 | &dme1737_zone_hyst_group))) { | ||
| 2029 | goto exit_remove; | ||
| 2030 | } | ||
| 1950 | 2031 | ||
| 1951 | /* Create fan sysfs attributes */ | 2032 | /* Create fan sysfs attributes */ |
| 1952 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | 2033 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { |
| 1953 | if (data->has_fan & (1 << ix)) { | 2034 | if (data->has_features & HAS_FAN(ix)) { |
| 1954 | if ((err = sysfs_create_group(&dev->kobj, | 2035 | if ((err = sysfs_create_group(&dev->kobj, |
| 1955 | &dme1737_fan_group[ix]))) { | 2036 | &dme1737_fan_group[ix]))) { |
| 1956 | goto exit_remove; | 2037 | goto exit_remove; |
| @@ -1960,14 +2041,14 @@ static int dme1737_create_files(struct device *dev) | |||
| 1960 | 2041 | ||
| 1961 | /* Create PWM sysfs attributes */ | 2042 | /* Create PWM sysfs attributes */ |
| 1962 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | 2043 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { |
| 1963 | if (data->has_pwm & (1 << ix)) { | 2044 | if (data->has_features & HAS_PWM(ix)) { |
| 1964 | if ((err = sysfs_create_group(&dev->kobj, | 2045 | if ((err = sysfs_create_group(&dev->kobj, |
| 1965 | &dme1737_pwm_group[ix]))) { | 2046 | &dme1737_pwm_group[ix]))) { |
| 1966 | goto exit_remove; | 2047 | goto exit_remove; |
| 1967 | } | 2048 | } |
| 1968 | if (data->type != sch5027 && ix < 3 && | 2049 | if ((data->has_features & HAS_PWM_MIN) && ix < 3 && |
| 1969 | (err = sysfs_create_file(&dev->kobj, | 2050 | (err = sysfs_create_file(&dev->kobj, |
| 1970 | dme1737_pwm_misc_attr[ix]))) { | 2051 | dme1737_auto_pwm_min_attr[ix]))) { |
| 1971 | goto exit_remove; | 2052 | goto exit_remove; |
| 1972 | } | 2053 | } |
| 1973 | } | 2054 | } |
| @@ -1983,21 +2064,30 @@ static int dme1737_create_files(struct device *dev) | |||
| 1983 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, | 2064 | dme1737_chmod_group(dev, &dme1737_zone_chmod_group, |
| 1984 | S_IRUGO | S_IWUSR); | 2065 | S_IRUGO | S_IWUSR); |
| 1985 | 2066 | ||
| 1986 | /* Change permissions of misc sysfs attributes */ | 2067 | /* Change permissions of chip-dependent sysfs attributes */ |
| 1987 | if (data->type != sch5027) { | 2068 | if (data->has_features & HAS_TEMP_OFFSET) { |
| 1988 | dme1737_chmod_group(dev, &dme1737_misc_group, | 2069 | dme1737_chmod_group(dev, &dme1737_temp_offset_group, |
| 2070 | S_IRUGO | S_IWUSR); | ||
| 2071 | } | ||
| 2072 | if (data->has_features & HAS_ZONE3) { | ||
| 2073 | dme1737_chmod_group(dev, &dme1737_zone3_chmod_group, | ||
| 2074 | S_IRUGO | S_IWUSR); | ||
| 2075 | } | ||
| 2076 | if (data->has_features & HAS_ZONE_HYST) { | ||
| 2077 | dme1737_chmod_group(dev, &dme1737_zone_hyst_group, | ||
| 1989 | S_IRUGO | S_IWUSR); | 2078 | S_IRUGO | S_IWUSR); |
| 1990 | } | 2079 | } |
| 1991 | 2080 | ||
| 1992 | /* Change permissions of PWM sysfs attributes */ | 2081 | /* Change permissions of PWM sysfs attributes */ |
| 1993 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) { | 2082 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) { |
| 1994 | if (data->has_pwm & (1 << ix)) { | 2083 | if (data->has_features & HAS_PWM(ix)) { |
| 1995 | dme1737_chmod_group(dev, | 2084 | dme1737_chmod_group(dev, |
| 1996 | &dme1737_pwm_chmod_group[ix], | 2085 | &dme1737_pwm_chmod_group[ix], |
| 1997 | S_IRUGO | S_IWUSR); | 2086 | S_IRUGO | S_IWUSR); |
| 1998 | if (data->type != sch5027 && ix < 3) { | 2087 | if ((data->has_features & HAS_PWM_MIN) && |
| 2088 | ix < 3) { | ||
| 1999 | dme1737_chmod_file(dev, | 2089 | dme1737_chmod_file(dev, |
| 2000 | dme1737_pwm_misc_attr[ix], | 2090 | dme1737_auto_pwm_min_attr[ix], |
| 2001 | S_IRUGO | S_IWUSR); | 2091 | S_IRUGO | S_IWUSR); |
| 2002 | } | 2092 | } |
| 2003 | } | 2093 | } |
| @@ -2005,7 +2095,7 @@ static int dme1737_create_files(struct device *dev) | |||
| 2005 | 2095 | ||
| 2006 | /* Change permissions of pwm[1-3] if in manual mode */ | 2096 | /* Change permissions of pwm[1-3] if in manual mode */ |
| 2007 | for (ix = 0; ix < 3; ix++) { | 2097 | for (ix = 0; ix < 3; ix++) { |
| 2008 | if ((data->has_pwm & (1 << ix)) && | 2098 | if ((data->has_features & HAS_PWM(ix)) && |
| 2009 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { | 2099 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { |
| 2010 | dme1737_chmod_file(dev, | 2100 | dme1737_chmod_file(dev, |
| 2011 | dme1737_pwm_chmod_attr[ix], | 2101 | dme1737_pwm_chmod_attr[ix], |
| @@ -2052,20 +2142,20 @@ static int dme1737_init_device(struct device *dev) | |||
| 2052 | return -EFAULT; | 2142 | return -EFAULT; |
| 2053 | } | 2143 | } |
| 2054 | 2144 | ||
| 2055 | /* Determine which optional fan and pwm features are enabled/present */ | 2145 | /* Determine which optional fan and pwm features are enabled (only |
| 2146 | * valid for I2C devices) */ | ||
| 2056 | if (client) { /* I2C chip */ | 2147 | if (client) { /* I2C chip */ |
| 2057 | data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); | 2148 | data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); |
| 2058 | /* Check if optional fan3 input is enabled */ | 2149 | /* Check if optional fan3 input is enabled */ |
| 2059 | if (data->config2 & 0x04) { | 2150 | if (data->config2 & 0x04) { |
| 2060 | data->has_fan |= (1 << 2); | 2151 | data->has_features |= HAS_FAN(2); |
| 2061 | } | 2152 | } |
| 2062 | 2153 | ||
| 2063 | /* Fan4 and pwm3 are only available if the client's I2C address | 2154 | /* Fan4 and pwm3 are only available if the client's I2C address |
| 2064 | * is the default 0x2e. Otherwise the I/Os associated with | 2155 | * is the default 0x2e. Otherwise the I/Os associated with |
| 2065 | * these functions are used for addr enable/select. */ | 2156 | * these functions are used for addr enable/select. */ |
| 2066 | if (client->addr == 0x2e) { | 2157 | if (client->addr == 0x2e) { |
| 2067 | data->has_fan |= (1 << 3); | 2158 | data->has_features |= HAS_FAN(3) | HAS_PWM(2); |
| 2068 | data->has_pwm |= (1 << 2); | ||
| 2069 | } | 2159 | } |
| 2070 | 2160 | ||
| 2071 | /* Determine which of the optional fan[5-6] and pwm[5-6] | 2161 | /* Determine which of the optional fan[5-6] and pwm[5-6] |
| @@ -2077,26 +2167,40 @@ static int dme1737_init_device(struct device *dev) | |||
| 2077 | dev_warn(dev, "Failed to query Super-IO for optional " | 2167 | dev_warn(dev, "Failed to query Super-IO for optional " |
| 2078 | "features.\n"); | 2168 | "features.\n"); |
| 2079 | } | 2169 | } |
| 2080 | } else { /* ISA chip */ | ||
| 2081 | /* Fan3 and pwm3 are always available. Fan[4-5] and pwm[5-6] | ||
| 2082 | * don't exist in the ISA chip. */ | ||
| 2083 | data->has_fan |= (1 << 2); | ||
| 2084 | data->has_pwm |= (1 << 2); | ||
| 2085 | } | 2170 | } |
| 2086 | 2171 | ||
| 2087 | /* Fan1, fan2, pwm1, and pwm2 are always present */ | 2172 | /* Fan[1-2] and pwm[1-2] are present in all chips */ |
| 2088 | data->has_fan |= 0x03; | 2173 | data->has_features |= HAS_FAN(0) | HAS_FAN(1) | HAS_PWM(0) | HAS_PWM(1); |
| 2089 | data->has_pwm |= 0x03; | 2174 | |
| 2175 | /* Chip-dependent features */ | ||
| 2176 | switch (data->type) { | ||
| 2177 | case dme1737: | ||
| 2178 | data->has_features |= HAS_TEMP_OFFSET | HAS_VID | HAS_ZONE3 | | ||
| 2179 | HAS_ZONE_HYST | HAS_PWM_MIN; | ||
| 2180 | break; | ||
| 2181 | case sch311x: | ||
| 2182 | data->has_features |= HAS_TEMP_OFFSET | HAS_ZONE3 | | ||
| 2183 | HAS_ZONE_HYST | HAS_PWM_MIN | HAS_FAN(2) | HAS_PWM(2); | ||
| 2184 | break; | ||
| 2185 | case sch5027: | ||
| 2186 | data->has_features |= HAS_ZONE3; | ||
| 2187 | break; | ||
| 2188 | case sch5127: | ||
| 2189 | data->has_features |= HAS_FAN(2) | HAS_PWM(2); | ||
| 2190 | break; | ||
| 2191 | default: | ||
| 2192 | break; | ||
| 2193 | } | ||
| 2090 | 2194 | ||
| 2091 | dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " | 2195 | dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " |
| 2092 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", | 2196 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", |
| 2093 | (data->has_pwm & (1 << 2)) ? "yes" : "no", | 2197 | (data->has_features & HAS_PWM(2)) ? "yes" : "no", |
| 2094 | (data->has_pwm & (1 << 4)) ? "yes" : "no", | 2198 | (data->has_features & HAS_PWM(4)) ? "yes" : "no", |
| 2095 | (data->has_pwm & (1 << 5)) ? "yes" : "no", | 2199 | (data->has_features & HAS_PWM(5)) ? "yes" : "no", |
| 2096 | (data->has_fan & (1 << 2)) ? "yes" : "no", | 2200 | (data->has_features & HAS_FAN(2)) ? "yes" : "no", |
| 2097 | (data->has_fan & (1 << 3)) ? "yes" : "no", | 2201 | (data->has_features & HAS_FAN(3)) ? "yes" : "no", |
| 2098 | (data->has_fan & (1 << 4)) ? "yes" : "no", | 2202 | (data->has_features & HAS_FAN(4)) ? "yes" : "no", |
| 2099 | (data->has_fan & (1 << 5)) ? "yes" : "no"); | 2203 | (data->has_features & HAS_FAN(5)) ? "yes" : "no"); |
| 2100 | 2204 | ||
| 2101 | reg = dme1737_read(data, DME1737_REG_TACH_PWM); | 2205 | reg = dme1737_read(data, DME1737_REG_TACH_PWM); |
| 2102 | /* Inform if fan-to-pwm mapping differs from the default */ | 2206 | /* Inform if fan-to-pwm mapping differs from the default */ |
| @@ -2122,7 +2226,7 @@ static int dme1737_init_device(struct device *dev) | |||
| 2122 | for (ix = 0; ix < 3; ix++) { | 2226 | for (ix = 0; ix < 3; ix++) { |
| 2123 | data->pwm_config[ix] = dme1737_read(data, | 2227 | data->pwm_config[ix] = dme1737_read(data, |
| 2124 | DME1737_REG_PWM_CONFIG(ix)); | 2228 | DME1737_REG_PWM_CONFIG(ix)); |
| 2125 | if ((data->has_pwm & (1 << ix)) && | 2229 | if ((data->has_features & HAS_PWM(ix)) && |
| 2126 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { | 2230 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { |
| 2127 | dev_info(dev, "Switching pwm%d to " | 2231 | dev_info(dev, "Switching pwm%d to " |
| 2128 | "manual mode.\n", ix + 1); | 2232 | "manual mode.\n", ix + 1); |
| @@ -2142,7 +2246,7 @@ static int dme1737_init_device(struct device *dev) | |||
| 2142 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ | 2246 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ |
| 2143 | 2247 | ||
| 2144 | /* Set VRM */ | 2248 | /* Set VRM */ |
| 2145 | if (data->type == dme1737) { | 2249 | if (data->has_features & HAS_VID) { |
| 2146 | data->vrm = vid_which_vrm(); | 2250 | data->vrm = vid_which_vrm(); |
| 2147 | } | 2251 | } |
| 2148 | 2252 | ||
| @@ -2163,10 +2267,10 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | |||
| 2163 | dme1737_sio_enter(sio_cip); | 2267 | dme1737_sio_enter(sio_cip); |
| 2164 | 2268 | ||
| 2165 | /* Check device ID | 2269 | /* Check device ID |
| 2166 | * The DME1737 can return either 0x78 or 0x77 as its device ID. | 2270 | * We currently know about two kinds of DME1737 and SCH5027. */ |
| 2167 | * The SCH5027 returns 0x89 as its device ID. */ | ||
| 2168 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); | 2271 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); |
| 2169 | if (!(reg == 0x77 || reg == 0x78 || reg == 0x89)) { | 2272 | if (!(reg == DME1737_ID_1 || reg == DME1737_ID_2 || |
| 2273 | reg == SCH5027_ID)) { | ||
| 2170 | err = -ENODEV; | 2274 | err = -ENODEV; |
| 2171 | goto exit; | 2275 | goto exit; |
| 2172 | } | 2276 | } |
| @@ -2185,16 +2289,16 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) | |||
| 2185 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set | 2289 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set |
| 2186 | * to '10' if the respective feature is enabled. */ | 2290 | * to '10' if the respective feature is enabled. */ |
| 2187 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ | 2291 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ |
| 2188 | data->has_fan |= (1 << 5); | 2292 | data->has_features |= HAS_FAN(5); |
| 2189 | } | 2293 | } |
| 2190 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ | 2294 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ |
| 2191 | data->has_pwm |= (1 << 5); | 2295 | data->has_features |= HAS_PWM(5); |
| 2192 | } | 2296 | } |
| 2193 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ | 2297 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ |
| 2194 | data->has_fan |= (1 << 4); | 2298 | data->has_features |= HAS_FAN(4); |
| 2195 | } | 2299 | } |
| 2196 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ | 2300 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ |
| 2197 | data->has_pwm |= (1 << 4); | 2301 | data->has_features |= HAS_PWM(4); |
| 2198 | } | 2302 | } |
| 2199 | 2303 | ||
| 2200 | exit: | 2304 | exit: |
| @@ -2222,7 +2326,6 @@ static int dme1737_i2c_detect(struct i2c_client *client, | |||
| 2222 | if (company == DME1737_COMPANY_SMSC && | 2326 | if (company == DME1737_COMPANY_SMSC && |
| 2223 | verstep == SCH5027_VERSTEP) { | 2327 | verstep == SCH5027_VERSTEP) { |
| 2224 | name = "sch5027"; | 2328 | name = "sch5027"; |
| 2225 | |||
| 2226 | } else if (company == DME1737_COMPANY_SMSC && | 2329 | } else if (company == DME1737_COMPANY_SMSC && |
| 2227 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { | 2330 | (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { |
| 2228 | name = "dme1737"; | 2331 | name = "dme1737"; |
| @@ -2329,10 +2432,10 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr) | |||
| 2329 | dme1737_sio_enter(sio_cip); | 2432 | dme1737_sio_enter(sio_cip); |
| 2330 | 2433 | ||
| 2331 | /* Check device ID | 2434 | /* Check device ID |
| 2332 | * We currently know about SCH3112 (0x7c), SCH3114 (0x7d), and | 2435 | * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127 */ |
| 2333 | * SCH3116 (0x7f). */ | ||
| 2334 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); | 2436 | reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); |
| 2335 | if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) { | 2437 | if (!(reg == SCH3112_ID || reg == SCH3114_ID || reg == SCH3116_ID || |
| 2438 | reg == SCH5127_ID)) { | ||
| 2336 | err = -ENODEV; | 2439 | err = -ENODEV; |
| 2337 | goto exit; | 2440 | goto exit; |
| 2338 | } | 2441 | } |
| @@ -2424,23 +2527,42 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) | |||
| 2424 | platform_set_drvdata(pdev, data); | 2527 | platform_set_drvdata(pdev, data); |
| 2425 | 2528 | ||
| 2426 | /* Skip chip detection if module is loaded with force_id parameter */ | 2529 | /* Skip chip detection if module is loaded with force_id parameter */ |
| 2427 | if (!force_id) { | 2530 | switch (force_id) { |
| 2531 | case SCH3112_ID: | ||
| 2532 | case SCH3114_ID: | ||
| 2533 | case SCH3116_ID: | ||
| 2534 | data->type = sch311x; | ||
| 2535 | break; | ||
| 2536 | case SCH5127_ID: | ||
| 2537 | data->type = sch5127; | ||
| 2538 | break; | ||
| 2539 | default: | ||
| 2428 | company = dme1737_read(data, DME1737_REG_COMPANY); | 2540 | company = dme1737_read(data, DME1737_REG_COMPANY); |
| 2429 | device = dme1737_read(data, DME1737_REG_DEVICE); | 2541 | device = dme1737_read(data, DME1737_REG_DEVICE); |
| 2430 | 2542 | ||
| 2431 | if (!((company == DME1737_COMPANY_SMSC) && | 2543 | if ((company == DME1737_COMPANY_SMSC) && |
| 2432 | (device == SCH311X_DEVICE))) { | 2544 | (device == SCH311X_DEVICE)) { |
| 2545 | data->type = sch311x; | ||
| 2546 | } else if ((company == DME1737_COMPANY_SMSC) && | ||
| 2547 | (device == SCH5127_DEVICE)) { | ||
| 2548 | data->type = sch5127; | ||
| 2549 | } else { | ||
| 2433 | err = -ENODEV; | 2550 | err = -ENODEV; |
| 2434 | goto exit_kfree; | 2551 | goto exit_kfree; |
| 2435 | } | 2552 | } |
| 2436 | } | 2553 | } |
| 2437 | data->type = sch311x; | ||
| 2438 | 2554 | ||
| 2439 | /* Fill in the remaining client fields and initialize the mutex */ | 2555 | if (data->type == sch5127) { |
| 2440 | data->name = "sch311x"; | 2556 | data->name = "sch5127"; |
| 2557 | } else { | ||
| 2558 | data->name = "sch311x"; | ||
| 2559 | } | ||
| 2560 | |||
| 2561 | /* Initialize the mutex */ | ||
| 2441 | mutex_init(&data->update_lock); | 2562 | mutex_init(&data->update_lock); |
| 2442 | 2563 | ||
| 2443 | dev_info(dev, "Found a SCH311x chip at 0x%04x\n", data->addr); | 2564 | dev_info(dev, "Found a %s chip at 0x%04x\n", |
| 2565 | data->type == sch5127 ? "SCH5127" : "SCH311x", data->addr); | ||
| 2444 | 2566 | ||
| 2445 | /* Initialize the chip */ | 2567 | /* Initialize the chip */ |
| 2446 | if ((err = dme1737_init_device(dev))) { | 2568 | if ((err = dme1737_init_device(dev))) { |
