diff options
57 files changed, 8809 insertions, 1721 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index a9941544ed8e..a5cb7839a679 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
| @@ -164,15 +164,6 @@ Who: Kay Sievers <kay.sievers@suse.de> | |||
| 164 | 164 | ||
| 165 | --------------------------- | 165 | --------------------------- |
| 166 | 166 | ||
| 167 | What: i2c-isa | ||
| 168 | When: December 2006 | ||
| 169 | Why: i2c-isa is a non-sense and doesn't fit in the device driver | ||
| 170 | model. Drivers relying on it are better implemented as platform | ||
| 171 | drivers. | ||
| 172 | Who: Jean Delvare <khali@linux-fr.org> | ||
| 173 | |||
| 174 | --------------------------- | ||
| 175 | |||
| 176 | What: i2c_adapter.list | 167 | What: i2c_adapter.list |
| 177 | When: July 2007 | 168 | When: July 2007 |
| 178 | Why: Superfluous, this list duplicates the one maintained by the driver | 169 | Why: Superfluous, this list duplicates the one maintained by the driver |
diff --git a/Documentation/hwmon/abituguru b/Documentation/hwmon/abituguru index b2c0d61b39a2..87ffa0f5ec70 100644 --- a/Documentation/hwmon/abituguru +++ b/Documentation/hwmon/abituguru | |||
| @@ -2,7 +2,7 @@ Kernel driver abituguru | |||
| 2 | ======================= | 2 | ======================= |
| 3 | 3 | ||
| 4 | Supported chips: | 4 | Supported chips: |
| 5 | * Abit uGuru revision 1-3 (Hardware Monitor part only) | 5 | * Abit uGuru revision 1 & 2 (Hardware Monitor part only) |
| 6 | Prefix: 'abituguru' | 6 | Prefix: 'abituguru' |
| 7 | Addresses scanned: ISA 0x0E0 | 7 | Addresses scanned: ISA 0x0E0 |
| 8 | Datasheet: Not available, this driver is based on reverse engineering. | 8 | Datasheet: Not available, this driver is based on reverse engineering. |
| @@ -20,8 +20,8 @@ Supported chips: | |||
| 20 | uGuru 2.1.0.0 ~ 2.1.2.8 (AS8, AV8, AA8, AG8, AA8XE, AX8) | 20 | uGuru 2.1.0.0 ~ 2.1.2.8 (AS8, AV8, AA8, AG8, AA8XE, AX8) |
| 21 | uGuru 2.2.0.0 ~ 2.2.0.6 (AA8 Fatal1ty) | 21 | uGuru 2.2.0.0 ~ 2.2.0.6 (AA8 Fatal1ty) |
| 22 | uGuru 2.3.0.0 ~ 2.3.0.9 (AN8) | 22 | uGuru 2.3.0.0 ~ 2.3.0.9 (AN8) |
| 23 | uGuru 3.0.0.0 ~ 3.0.1.2 (AW8, AL8, NI8) | 23 | uGuru 3.0.0.0 ~ 3.0.x.x (AW8, AL8, AT8, NI8 SLI, AT8 32X, AN8 32X, |
| 24 | uGuru 4.xxxxx? (AT8 32X) (2) | 24 | AW9D-MAX) (2) |
| 25 | 1) For revisions 2 and 3 uGuru's the driver can autodetect the | 25 | 1) For revisions 2 and 3 uGuru's the driver can autodetect the |
| 26 | sensortype (Volt or Temp) for bank1 sensors, for revision 1 uGuru's | 26 | sensortype (Volt or Temp) for bank1 sensors, for revision 1 uGuru's |
| 27 | this doesnot always work. For these uGuru's the autodection can | 27 | this doesnot always work. For these uGuru's the autodection can |
| @@ -30,8 +30,9 @@ Supported chips: | |||
| 30 | bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1 | 30 | bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1 |
| 31 | You may also need to specify the fan_sensors option for these boards | 31 | You may also need to specify the fan_sensors option for these boards |
| 32 | fan_sensors=5 | 32 | fan_sensors=5 |
| 33 | 2) The current version of the abituguru driver is known to NOT work | 33 | 2) There is a seperate abituguru3 driver for these motherboards, |
| 34 | on these Motherboards | 34 | the abituguru (without the 3 !) driver will not work on these |
| 35 | motherboards (and visa versa)! | ||
| 35 | 36 | ||
| 36 | Authors: | 37 | Authors: |
| 37 | Hans de Goede <j.w.r.degoede@hhs.nl>, | 38 | Hans de Goede <j.w.r.degoede@hhs.nl>, |
| @@ -43,8 +44,10 @@ Module Parameters | |||
| 43 | ----------------- | 44 | ----------------- |
| 44 | 45 | ||
| 45 | * force: bool Force detection. Note this parameter only causes the | 46 | * force: bool Force detection. Note this parameter only causes the |
| 46 | detection to be skipped, if the uGuru can't be read | 47 | detection to be skipped, and thus the insmod to |
| 47 | the module initialization (insmod) will still fail. | 48 | succeed. If the uGuru can't be read the actual hwmon |
| 49 | driver will not load and thus no hwmon device will get | ||
| 50 | registered. | ||
| 48 | * bank1_types: int[] Bank1 sensortype autodetection override: | 51 | * bank1_types: int[] Bank1 sensortype autodetection override: |
| 49 | -1 autodetect (default) | 52 | -1 autodetect (default) |
| 50 | 0 volt sensor | 53 | 0 volt sensor |
| @@ -69,13 +72,15 @@ dmesg | grep abituguru | |||
| 69 | Description | 72 | Description |
| 70 | ----------- | 73 | ----------- |
| 71 | 74 | ||
| 72 | This driver supports the hardware monitoring features of the Abit uGuru chip | 75 | This driver supports the hardware monitoring features of the first and |
| 73 | found on Abit uGuru featuring motherboards (most modern Abit motherboards). | 76 | second revision of the Abit uGuru chip found on Abit uGuru featuring |
| 77 | motherboards (most modern Abit motherboards). | ||
| 74 | 78 | ||
| 75 | The uGuru chip in reality is a Winbond W83L950D in disguise (despite Abit | 79 | The first and second revision of the uGuru chip in reality is a Winbond |
| 76 | claiming it is "a new microprocessor designed by the ABIT Engineers"). | 80 | W83L950D in disguise (despite Abit claiming it is "a new microprocessor |
| 77 | Unfortunatly this doesn't help since the W83L950D is a generic | 81 | designed by the ABIT Engineers"). Unfortunatly this doesn't help since the |
| 78 | microcontroller with a custom Abit application running on it. | 82 | W83L950D is a generic microcontroller with a custom Abit application running |
| 83 | on it. | ||
| 79 | 84 | ||
| 80 | Despite Abit not releasing any information regarding the uGuru, Olle | 85 | Despite Abit not releasing any information regarding the uGuru, Olle |
| 81 | Sandberg <ollebull@gmail.com> has managed to reverse engineer the sensor part | 86 | Sandberg <ollebull@gmail.com> has managed to reverse engineer the sensor part |
diff --git a/Documentation/hwmon/abituguru3 b/Documentation/hwmon/abituguru3 new file mode 100644 index 000000000000..fa598aac22fa --- /dev/null +++ b/Documentation/hwmon/abituguru3 | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | Kernel driver abituguru3 | ||
| 2 | ======================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * Abit uGuru revision 3 (Hardware Monitor part, reading only) | ||
| 6 | Prefix: 'abituguru3' | ||
| 7 | Addresses scanned: ISA 0x0E0 | ||
| 8 | Datasheet: Not available, this driver is based on reverse engineering. | ||
| 9 | Note: | ||
| 10 | The uGuru is a microcontroller with onboard firmware which programs | ||
| 11 | it to behave as a hwmon IC. There are many different revisions of the | ||
| 12 | firmware and thus effectivly many different revisions of the uGuru. | ||
| 13 | Below is an incomplete list with which revisions are used for which | ||
| 14 | Motherboards: | ||
| 15 | uGuru 1.00 ~ 1.24 (AI7, KV8-MAX3, AN7) | ||
| 16 | uGuru 2.0.0.0 ~ 2.0.4.2 (KV8-PRO) | ||
| 17 | uGuru 2.1.0.0 ~ 2.1.2.8 (AS8, AV8, AA8, AG8, AA8XE, AX8) | ||
| 18 | uGuru 2.3.0.0 ~ 2.3.0.9 (AN8) | ||
| 19 | uGuru 3.0.0.0 ~ 3.0.x.x (AW8, AL8, AT8, NI8 SLI, AT8 32X, AN8 32X, | ||
| 20 | AW9D-MAX) | ||
| 21 | The abituguru3 driver is only for revison 3.0.x.x motherboards, | ||
| 22 | this driver will not work on older motherboards. For older | ||
| 23 | motherboards use the abituguru (without the 3 !) driver. | ||
| 24 | |||
| 25 | Authors: | ||
| 26 | Hans de Goede <j.w.r.degoede@hhs.nl>, | ||
| 27 | (Initial reverse engineering done by Louis Kruger) | ||
| 28 | |||
| 29 | |||
| 30 | Module Parameters | ||
| 31 | ----------------- | ||
| 32 | |||
| 33 | * force: bool Force detection. Note this parameter only causes the | ||
| 34 | detection to be skipped, and thus the insmod to | ||
| 35 | succeed. If the uGuru can't be read the actual hwmon | ||
| 36 | driver will not load and thus no hwmon device will get | ||
| 37 | registered. | ||
| 38 | * verbose: bool Should the driver be verbose? | ||
| 39 | 0/off/false normal output | ||
| 40 | 1/on/true + verbose error reporting (default) | ||
| 41 | Default: 1 (the driver is still in the testing phase) | ||
| 42 | |||
| 43 | Description | ||
| 44 | ----------- | ||
| 45 | |||
| 46 | This driver supports the hardware monitoring features of the third revision of | ||
| 47 | the Abit uGuru chip, found on recent Abit uGuru featuring motherboards. | ||
| 48 | |||
| 49 | The 3rd revision of the uGuru chip in reality is a Winbond W83L951G. | ||
| 50 | Unfortunatly this doesn't help since the W83L951G is a generic microcontroller | ||
| 51 | with a custom Abit application running on it. | ||
| 52 | |||
| 53 | Despite Abit not releasing any information regarding the uGuru revision 3, | ||
| 54 | Louis Kruger has managed to reverse engineer the sensor part of the uGuru. | ||
| 55 | Without his work this driver would not have been possible. | ||
| 56 | |||
| 57 | Known Issues | ||
| 58 | ------------ | ||
| 59 | |||
| 60 | The voltage and frequency control parts of the Abit uGuru are not supported, | ||
| 61 | neither is writing any of the sensor settings and writing / reading the | ||
| 62 | fanspeed control registers (FanEQ) | ||
| 63 | |||
| 64 | If you encounter any problems please mail me <j.w.r.degoede@hhs.nl> and | ||
| 65 | include the output of: "dmesg | grep abituguru" | ||
diff --git a/Documentation/hwmon/dme1737 b/Documentation/hwmon/dme1737 new file mode 100644 index 000000000000..1a0f3d64ab80 --- /dev/null +++ b/Documentation/hwmon/dme1737 | |||
| @@ -0,0 +1,257 @@ | |||
| 1 | Kernel driver dme1737 | ||
| 2 | ===================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * SMSC DME1737 and compatibles (like Asus A8000) | ||
| 6 | Prefix: 'dme1737' | ||
| 7 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e | ||
| 8 | Datasheet: Provided by SMSC upon request and under NDA | ||
| 9 | |||
| 10 | Authors: | ||
| 11 | Juerg Haefliger <juergh@gmail.com> | ||
| 12 | |||
| 13 | |||
| 14 | Module Parameters | ||
| 15 | ----------------- | ||
| 16 | |||
| 17 | * force_start: bool Enables the monitoring of voltage, fan and temp inputs | ||
| 18 | and PWM output control functions. Using this parameter | ||
| 19 | shouldn't be required since the BIOS usually takes care | ||
| 20 | of this. | ||
| 21 | |||
| 22 | Note that there is no need to use this parameter if the driver loads without | ||
| 23 | complaining. The driver will say so if it is necessary. | ||
| 24 | |||
| 25 | |||
| 26 | Description | ||
| 27 | ----------- | ||
| 28 | |||
| 29 | This driver implements support for the hardware monitoring capabilities of the | ||
| 30 | SMSC DME1737 and Asus A8000 (which are the same) Super-I/O chips. This chip | ||
| 31 | features monitoring of 3 temp sensors temp[1-3] (2 remote diodes and 1 | ||
| 32 | internal), 7 voltages in[0-6] (6 external and 1 internal) and 6 fan speeds | ||
| 33 | fan[1-6]. Additionally, the chip implements 5 PWM outputs pwm[1-3,5-6] for | ||
| 34 | controlling fan speeds both manually and automatically. | ||
| 35 | |||
| 36 | Fan[3-6] and pwm[3,5-6] are optional features and their availability is | ||
| 37 | dependent on the configuration of the chip. The driver will detect which | ||
| 38 | features are present during initialization and create the sysfs attributes | ||
| 39 | accordingly. | ||
| 40 | |||
| 41 | |||
| 42 | Voltage Monitoring | ||
| 43 | ------------------ | ||
| 44 | |||
| 45 | The voltage inputs are sampled with 12-bit resolution and have internal | ||
| 46 | scaling resistors. The values returned by the driver therefore reflect true | ||
| 47 | millivolts and don't need scaling. The voltage inputs are mapped as follows | ||
| 48 | (the last column indicates the input ranges): | ||
| 49 | |||
| 50 | in0: +5VTR (+5V standby) 0V - 6.64V | ||
| 51 | in1: Vccp (processor core) 0V - 3V | ||
| 52 | in2: VCC (internal +3.3V) 0V - 4.38V | ||
| 53 | in3: +5V 0V - 6.64V | ||
| 54 | in4: +12V 0V - 16V | ||
| 55 | in5: VTR (+3.3V standby) 0V - 4.38V | ||
| 56 | in6: Vbat (+3.0V) 0V - 4.38V | ||
| 57 | |||
| 58 | Each voltage input has associated min and max limits which trigger an alarm | ||
| 59 | when crossed. | ||
| 60 | |||
| 61 | |||
| 62 | Temperature Monitoring | ||
| 63 | ---------------------- | ||
| 64 | |||
| 65 | Temperatures are measured with 12-bit resolution and reported in millidegree | ||
| 66 | Celsius. The chip also features offsets for all 3 temperature inputs which - | ||
| 67 | when programmed - get added to the input readings. The chip does all the | ||
| 68 | scaling by itself and the driver therefore reports true temperatures that don't | ||
| 69 | need any user-space adjustments. The temperature inputs are mapped as follows | ||
| 70 | (the last column indicates the input ranges): | ||
| 71 | |||
| 72 | temp1: Remote diode 1 (3904 type) temperature -127C - +127C | ||
| 73 | temp2: DME1737 internal temperature -127C - +127C | ||
| 74 | temp3: Remote diode 2 (3904 type) temperature -127C - +127C | ||
| 75 | |||
| 76 | Each temperature input has associated min and max limits which trigger an alarm | ||
| 77 | when crossed. Additionally, each temperature input has a fault attribute that | ||
| 78 | returns 1 when a faulty diode or an unconnected input is detected and 0 | ||
| 79 | otherwise. | ||
| 80 | |||
| 81 | |||
| 82 | Fan Monitoring | ||
| 83 | -------------- | ||
| 84 | |||
| 85 | Fan RPMs are measured with 16-bit resolution. The chip provides inputs for 6 | ||
| 86 | fan tachometers. All 6 inputs have an associated min limit which triggers an | ||
| 87 | alarm when crossed. Fan inputs 1-4 provide type attributes that need to be set | ||
| 88 | to the number of pulses per fan revolution that the connected tachometer | ||
| 89 | generates. Supported values are 1, 2, and 4. Fan inputs 5-6 only support fans | ||
| 90 | that generate 2 pulses per revolution. Fan inputs 5-6 also provide a max | ||
| 91 | attribute that needs to be set to the maximum attainable RPM (fan at 100% duty- | ||
| 92 | cycle) of the input. The chip adjusts the sampling rate based on this value. | ||
| 93 | |||
| 94 | |||
| 95 | PWM Output Control | ||
| 96 | ------------------ | ||
| 97 | |||
| 98 | This chip features 5 PWM outputs. PWM outputs 1-3 are associated with fan | ||
| 99 | inputs 1-3 and PWM outputs 5-6 are associated with fan inputs 5-6. PWM outputs | ||
| 100 | 1-3 can be configured to operate either in manual or automatic mode by setting | ||
| 101 | the appropriate enable attribute accordingly. PWM outputs 5-6 can only operate | ||
| 102 | in manual mode, their enable attributes are therefore read-only. When set to | ||
| 103 | manual mode, the fan speed is set by writing the duty-cycle value to the | ||
| 104 | appropriate PWM attribute. In automatic mode, the PWM attribute returns the | ||
| 105 | current duty-cycle as set by the fan controller in the chip. All PWM outputs | ||
| 106 | support the setting of the output frequency via the freq attribute. | ||
| 107 | |||
| 108 | In automatic mode, the chip supports the setting of the PWM ramp rate which | ||
| 109 | defines how fast the PWM output is adjusting to changes of the associated | ||
| 110 | temperature input. Associating PWM outputs to temperature inputs is done via | ||
| 111 | temperature zones. The chip features 3 zones whose assignments to temperature | ||
| 112 | inputs is static and determined during initialization. These assignments can | ||
| 113 | be retrieved via the zone[1-3]_auto_channels_temp attributes. Each PWM output | ||
| 114 | is assigned to one (or hottest of multiple) temperature zone(s) through the | ||
| 115 | pwm[1-3]_auto_channels_zone attributes. Each PWM output has 3 distinct output | ||
| 116 | duty-cycles: full, low, and min. Full is internally hard-wired to 255 (100%) | ||
| 117 | and low and min can be programmed via pwm[1-3]_auto_point1_pwm and | ||
| 118 | pwm[1-3]_auto_pwm_min, respectively. The thermal thresholds of the zones are | ||
| 119 | programmed via zone[1-3]_auto_point[1-3]_temp and | ||
| 120 | zone[1-3]_auto_point1_temp_hyst: | ||
| 121 | |||
| 122 | pwm[1-3]_auto_point2_pwm full-speed duty-cycle (255, i.e., 100%) | ||
| 123 | pwm[1-3]_auto_point1_pwm low-speed duty-cycle | ||
| 124 | pwm[1-3]_auto_pwm_min min-speed duty-cycle | ||
| 125 | |||
| 126 | zone[1-3]_auto_point3_temp full-speed temp (all outputs) | ||
| 127 | zone[1-3]_auto_point2_temp full-speed temp | ||
| 128 | zone[1-3]_auto_point1_temp low-speed temp | ||
| 129 | zone[1-3]_auto_point1_temp_hyst min-speed temp | ||
| 130 | |||
| 131 | The chip adjusts the output duty-cycle linearly in the range of auto_point1_pwm | ||
| 132 | to auto_point2_pwm if the temperature of the associated zone is between | ||
| 133 | auto_point1_temp and auto_point2_temp. If the temperature drops below the | ||
| 134 | auto_point1_temp_hyst value, the output duty-cycle is set to the auto_pwm_min | ||
| 135 | value which only supports two values: 0 or auto_point1_pwm. That means that the | ||
| 136 | fan either turns completely off or keeps spinning with the low-speed | ||
| 137 | duty-cycle. If any of the temperatures rise above the auto_point3_temp value, | ||
| 138 | all PWM outputs are set to 100% duty-cycle. | ||
| 139 | |||
| 140 | Following is another representation of how the chip sets the output duty-cycle | ||
| 141 | based on the temperature of the associated thermal zone: | ||
| 142 | |||
| 143 | Duty-Cycle Duty-Cycle | ||
| 144 | Temperature Rising Temp Falling Temp | ||
| 145 | ----------- ----------- ------------ | ||
| 146 | full-speed full-speed full-speed | ||
| 147 | |||
| 148 | < linearly adjusted duty-cycle > | ||
| 149 | |||
| 150 | low-speed low-speed low-speed | ||
| 151 | min-speed low-speed | ||
| 152 | min-speed min-speed min-speed | ||
| 153 | min-speed min-speed | ||
| 154 | |||
| 155 | |||
| 156 | Sysfs Attributes | ||
| 157 | ---------------- | ||
| 158 | |||
| 159 | Following is a list of all sysfs attributes that the driver provides, their | ||
| 160 | permissions and a short description: | ||
| 161 | |||
| 162 | Name Perm Description | ||
| 163 | ---- ---- ----------- | ||
| 164 | cpu0_vid RO CPU core reference voltage in | ||
| 165 | millivolts. | ||
| 166 | vrm RW Voltage regulator module version | ||
| 167 | number. | ||
| 168 | |||
| 169 | in[0-6]_input RO Measured voltage in millivolts. | ||
| 170 | in[0-6]_min RW Low limit for voltage input. | ||
| 171 | in[0-6]_max RW High limit for voltage input. | ||
| 172 | in[0-6]_alarm RO Voltage input alarm. Returns 1 if | ||
| 173 | voltage input is or went outside the | ||
| 174 | associated min-max range, 0 otherwise. | ||
| 175 | |||
| 176 | temp[1-3]_input RO Measured temperature in millidegree | ||
| 177 | Celsius. | ||
| 178 | temp[1-3]_min RW Low limit for temp input. | ||
| 179 | temp[1-3]_max RW High limit for temp input. | ||
| 180 | temp[1-3]_offset RW Offset for temp input. This value will | ||
| 181 | be added by the chip to the measured | ||
| 182 | temperature. | ||
| 183 | temp[1-3]_alarm RO Alarm for temp input. Returns 1 if temp | ||
| 184 | input is or went outside the associated | ||
| 185 | min-max range, 0 otherwise. | ||
| 186 | temp[1-3]_fault RO Temp input fault. Returns 1 if the chip | ||
| 187 | detects a faulty thermal diode or an | ||
| 188 | unconnected temp input, 0 otherwise. | ||
| 189 | |||
| 190 | zone[1-3]_auto_channels_temp RO Temperature zone to temperature input | ||
| 191 | mapping. This attribute is a bitfield | ||
| 192 | and supports the following values: | ||
| 193 | 1: temp1 | ||
| 194 | 2: temp2 | ||
| 195 | 4: temp3 | ||
| 196 | zone[1-3]_auto_point1_temp_hyst RW Auto PWM temp point1 hysteresis. The | ||
| 197 | output of the corresponding PWM is set | ||
| 198 | to the pwm_auto_min value if the temp | ||
| 199 | falls below the auto_point1_temp_hyst | ||
| 200 | value. | ||
| 201 | zone[1-3]_auto_point[1-3]_temp RW Auto PWM temp points. Auto_point1 is | ||
| 202 | the low-speed temp, auto_point2 is the | ||
| 203 | full-speed temp, and auto_point3 is the | ||
| 204 | temp at which all PWM outputs are set | ||
| 205 | to full-speed (100% duty-cycle). | ||
| 206 | |||
| 207 | fan[1-6]_input RO Measured fan speed in RPM. | ||
| 208 | fan[1-6]_min RW Low limit for fan input. | ||
| 209 | fan[1-6]_alarm RO Alarm for fan input. Returns 1 if fan | ||
| 210 | input is or went below the associated | ||
| 211 | min value, 0 otherwise. | ||
| 212 | fan[1-4]_type RW Type of attached fan. Expressed in | ||
| 213 | number of pulses per revolution that | ||
| 214 | the fan generates. Supported values are | ||
| 215 | 1, 2, and 4. | ||
| 216 | fan[5-6]_max RW Max attainable RPM at 100% duty-cycle. | ||
| 217 | Required for chip to adjust the | ||
| 218 | sampling rate accordingly. | ||
| 219 | |||
| 220 | pmw[1-3,5-6] RO/RW Duty-cycle of PWM output. Supported | ||
| 221 | values are 0-255 (0%-100%). Only | ||
| 222 | writeable if the associated PWM is in | ||
| 223 | manual mode. | ||
| 224 | pwm[1-3]_enable RW Enable of PWM outputs 1-3. Supported | ||
| 225 | values are: | ||
| 226 | 0: turned off (output @ 100%) | ||
| 227 | 1: manual mode | ||
| 228 | 2: automatic mode | ||
| 229 | pwm[5-6]_enable RO Enable of PWM outputs 5-6. Always | ||
| 230 | returns 1 since these 2 outputs are | ||
| 231 | hard-wired to manual mode. | ||
| 232 | pmw[1-3,5-6]_freq RW Frequency of PWM output. Supported | ||
| 233 | values are in the range 11Hz-30000Hz | ||
| 234 | (default is 25000Hz). | ||
| 235 | pmw[1-3]_ramp_rate RW Ramp rate of PWM output. Determines how | ||
| 236 | fast the PWM duty-cycle will change | ||
| 237 | when the PWM is in automatic mode. | ||
| 238 | Expressed in ms per PWM step. Supported | ||
| 239 | values are in the range 0ms-206ms | ||
| 240 | (default is 0, which means the duty- | ||
| 241 | cycle changes instantly). | ||
| 242 | pwm[1-3]_auto_channels_zone RW PWM output to temperature zone mapping. | ||
| 243 | This attribute is a bitfield and | ||
| 244 | supports the following values: | ||
| 245 | 1: zone1 | ||
| 246 | 2: zone2 | ||
| 247 | 4: zone3 | ||
| 248 | 6: highest of zone[2-3] | ||
| 249 | 7: highest of zone[1-3] | ||
| 250 | pwm[1-3]_auto_pwm_min RW Auto PWM min pwm. Minimum PWM duty- | ||
| 251 | cycle. Supported values are 0 or | ||
| 252 | auto_point1_pwm. | ||
| 253 | pwm[1-3]_auto_point1_pwm RW Auto PWM pwm point. Auto_point1 is the | ||
| 254 | low-speed duty-cycle. | ||
| 255 | pwm[1-3]_auto_point2_pwm RO Auto PWM pwm point. Auto_point2 is the | ||
| 256 | full-speed duty-cycle which is hard- | ||
| 257 | wired to 255 (100% duty-cycle). | ||
diff --git a/Documentation/hwmon/f71805f b/Documentation/hwmon/f71805f index bfd0f154959c..94e0d2cbd3d2 100644 --- a/Documentation/hwmon/f71805f +++ b/Documentation/hwmon/f71805f | |||
| @@ -5,11 +5,11 @@ Supported chips: | |||
| 5 | * Fintek F71805F/FG | 5 | * Fintek F71805F/FG |
| 6 | Prefix: 'f71805f' | 6 | Prefix: 'f71805f' |
| 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: Provided by Fintek on request | 8 | Datasheet: Available from the Fintek website |
| 9 | * Fintek F71872F/FG | 9 | * Fintek F71872F/FG |
| 10 | Prefix: 'f71872f' | 10 | Prefix: 'f71872f' |
| 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: Provided by Fintek on request | 12 | Datasheet: Available from the Fintek website |
| 13 | 13 | ||
| 14 | Author: Jean Delvare <khali@linux-fr.org> | 14 | Author: Jean Delvare <khali@linux-fr.org> |
| 15 | 15 | ||
| @@ -128,7 +128,9 @@ it. | |||
| 128 | When the PWM method is used, you can select the operating frequency, | 128 | When the PWM method is used, you can select the operating frequency, |
| 129 | from 187.5 kHz (default) to 31 Hz. The best frequency depends on the | 129 | from 187.5 kHz (default) to 31 Hz. The best frequency depends on the |
| 130 | fan model. As a rule of thumb, lower frequencies seem to give better | 130 | fan model. As a rule of thumb, lower frequencies seem to give better |
| 131 | control, but may generate annoying high-pitch noise. Fintek recommends | 131 | control, but may generate annoying high-pitch noise. So a frequency just |
| 132 | above the audible range, such as 25 kHz, may be a good choice; if this | ||
| 133 | doesn't give you good linear control, try reducing it. Fintek recommends | ||
| 132 | not going below 1 kHz, as the fan tachometers get confused by lower | 134 | not going below 1 kHz, as the fan tachometers get confused by lower |
| 133 | frequencies as well. | 135 | frequencies as well. |
| 134 | 136 | ||
| @@ -136,16 +138,23 @@ When the DC method is used, Fintek recommends not going below 5 V, which | |||
| 136 | corresponds to a pwm value of 106 for the driver. The driver doesn't | 138 | corresponds to a pwm value of 106 for the driver. The driver doesn't |
| 137 | enforce this limit though. | 139 | enforce this limit though. |
| 138 | 140 | ||
| 139 | Three different fan control modes are supported: | 141 | Three different fan control modes are supported; the mode number is written |
| 142 | to the pwm<n>_enable file. | ||
| 140 | 143 | ||
| 141 | * Manual mode | 144 | * 1: Manual mode |
| 142 | You ask for a specific PWM duty cycle or DC voltage. | 145 | You ask for a specific PWM duty cycle or DC voltage by writing to the |
| 146 | pwm<n> file. | ||
| 143 | 147 | ||
| 144 | * Fan speed mode | 148 | * 2: Temperature mode |
| 145 | You ask for a specific fan speed. This mode assumes that pwm1 | 149 | You define 3 temperature/fan speed trip points using the |
| 146 | corresponds to fan1, pwm2 to fan2 and pwm3 to fan3. | 150 | pwm<n>_auto_point<m>_temp and _fan files. These define a staircase |
| 151 | relationship between temperature and fan speed with two additional points | ||
| 152 | interpolated between the values that you define. When the temperature | ||
| 153 | is below auto_point1_temp the fan is switched off. | ||
| 147 | 154 | ||
| 148 | * Temperature mode | 155 | * 3: Fan speed mode |
| 149 | You define 3 temperature/fan speed trip points, and the fan speed is | 156 | You ask for a specific fan speed by writing to the fan<n>_target file. |
| 150 | adjusted depending on the measured temperature, using interpolation. | 157 | |
| 151 | This mode is not yet supported by the driver. | 158 | Both of the automatic modes require that pwm1 corresponds to fan1, pwm2 to |
| 159 | fan2 and pwm3 to fan3. Temperature mode also requires that temp1 corresponds | ||
| 160 | to pwm1 and fan1, etc. | ||
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index c0528d6f9ace..81ecc7e41c50 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
| @@ -12,11 +12,12 @@ Supported chips: | |||
| 12 | Addresses scanned: from Super I/O config space (8 I/O ports) | 12 | Addresses scanned: from Super I/O config space (8 I/O ports) |
| 13 | Datasheet: Publicly available at the ITE website | 13 | Datasheet: Publicly available at the ITE website |
| 14 | http://www.ite.com.tw/ | 14 | http://www.ite.com.tw/ |
| 15 | * IT8716F | 15 | * IT8716F/IT8726F |
| 16 | Prefix: 'it8716' | 16 | Prefix: 'it8716' |
| 17 | Addresses scanned: from Super I/O config space (8 I/O ports) | 17 | Addresses scanned: from Super I/O config space (8 I/O ports) |
| 18 | Datasheet: Publicly available at the ITE website | 18 | Datasheet: Publicly available at the ITE website |
| 19 | http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP | 19 | http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP |
| 20 | http://www.ite.com.tw/product_info/file/pc/IT8726F_V0.3.pdf | ||
| 20 | * IT8718F | 21 | * IT8718F |
| 21 | Prefix: 'it8718' | 22 | Prefix: 'it8718' |
| 22 | Addresses scanned: from Super I/O config space (8 I/O ports) | 23 | Addresses scanned: from Super I/O config space (8 I/O ports) |
| @@ -68,7 +69,7 @@ Description | |||
| 68 | ----------- | 69 | ----------- |
| 69 | 70 | ||
| 70 | This driver implements support for the IT8705F, IT8712F, IT8716F, | 71 | This driver implements support for the IT8705F, IT8712F, IT8716F, |
| 71 | IT8718F and SiS950 chips. | 72 | IT8718F, IT8726F and SiS950 chips. |
| 72 | 73 | ||
| 73 | These chips are 'Super I/O chips', supporting floppy disks, infrared ports, | 74 | These chips are 'Super I/O chips', supporting floppy disks, infrared ports, |
| 74 | joysticks and other miscellaneous stuff. For hardware monitoring, they | 75 | joysticks and other miscellaneous stuff. For hardware monitoring, they |
| @@ -97,6 +98,10 @@ clock divider mess) but not compatible with the older chips and | |||
| 97 | revisions. For now, the driver only uses the 16-bit mode on the | 98 | revisions. For now, the driver only uses the 16-bit mode on the |
| 98 | IT8716F and IT8718F. | 99 | IT8716F and IT8718F. |
| 99 | 100 | ||
| 101 | The IT8726F is just bit enhanced IT8716F with additional hardware | ||
| 102 | for AMD power sequencing. Therefore the chip will appear as IT8716F | ||
| 103 | to userspace applications. | ||
| 104 | |||
| 100 | Temperatures are measured in degrees Celsius. An alarm is triggered once | 105 | Temperatures are measured in degrees Celsius. An alarm is triggered once |
| 101 | when the Overtemperature Shutdown limit is crossed. | 106 | when the Overtemperature Shutdown limit is crossed. |
| 102 | 107 | ||
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90 index 438cb24cee5b..aa4a0ec20081 100644 --- a/Documentation/hwmon/lm90 +++ b/Documentation/hwmon/lm90 | |||
| @@ -48,6 +48,18 @@ Supported chips: | |||
| 48 | Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e) | 48 | Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e) |
| 49 | Datasheet: Publicly available at the Maxim website | 49 | Datasheet: Publicly available at the Maxim website |
| 50 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 | 50 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 |
| 51 | * Maxim MAX6680 | ||
| 52 | Prefix: 'max6680' | ||
| 53 | Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | ||
| 54 | 0x4c, 0x4d and 0x4e | ||
| 55 | Datasheet: Publicly available at the Maxim website | ||
| 56 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 | ||
| 57 | * Maxim MAX6681 | ||
| 58 | Prefix: 'max6680' | ||
| 59 | Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | ||
| 60 | 0x4c, 0x4d and 0x4e | ||
| 61 | Datasheet: Publicly available at the Maxim website | ||
| 62 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 | ||
| 51 | 63 | ||
| 52 | 64 | ||
| 53 | Author: Jean Delvare <khali@linux-fr.org> | 65 | Author: Jean Delvare <khali@linux-fr.org> |
| @@ -59,11 +71,15 @@ Description | |||
| 59 | The LM90 is a digital temperature sensor. It senses its own temperature as | 71 | The LM90 is a digital temperature sensor. It senses its own temperature as |
| 60 | well as the temperature of up to one external diode. It is compatible | 72 | well as the temperature of up to one external diode. It is compatible |
| 61 | with many other devices such as the LM86, the LM89, the LM99, the ADM1032, | 73 | with many other devices such as the LM86, the LM89, the LM99, the ADM1032, |
| 62 | the MAX6657, MAX6658 and the MAX6659 all of which are supported by this driver. | 74 | the MAX6657, MAX6658, MAX6659, MAX6680 and the MAX6681 all of which are |
| 63 | Note that there is no easy way to differentiate between the last three | 75 | supported by this driver. |
| 64 | variants. The extra address and features of the MAX6659 are not supported by | 76 | |
| 65 | this driver. Additionally, the ADT7461 is supported if found in ADM1032 | 77 | Note that there is no easy way to differentiate between the MAX6657, |
| 66 | compatibility mode. | 78 | MAX6658 and MAX6659 variants. The extra address and features of the |
| 79 | MAX6659 are not supported by this driver. The MAX6680 and MAX6681 only | ||
| 80 | differ in their pinout, therefore they obviously can't (and don't need to) | ||
| 81 | be distinguished. Additionally, the ADT7461 is supported if found in | ||
| 82 | ADM1032 compatibility mode. | ||
| 67 | 83 | ||
| 68 | The specificity of this family of chipsets over the ADM1021/LM84 | 84 | The specificity of this family of chipsets over the ADM1021/LM84 |
| 69 | family is that it features critical limits with hysteresis, and an | 85 | family is that it features critical limits with hysteresis, and an |
| @@ -93,18 +109,22 @@ ADM1032: | |||
| 93 | * ALERT is triggered by open remote sensor. | 109 | * ALERT is triggered by open remote sensor. |
| 94 | * SMBus PEC support for Write Byte and Receive Byte transactions. | 110 | * SMBus PEC support for Write Byte and Receive Byte transactions. |
| 95 | 111 | ||
| 96 | ADT7461 | 112 | ADT7461: |
| 97 | * Extended temperature range (breaks compatibility) | 113 | * Extended temperature range (breaks compatibility) |
| 98 | * Lower resolution for remote temperature | 114 | * Lower resolution for remote temperature |
| 99 | 115 | ||
| 100 | MAX6657 and MAX6658: | 116 | MAX6657 and MAX6658: |
| 101 | * Remote sensor type selection | 117 | * Remote sensor type selection |
| 102 | 118 | ||
| 103 | MAX6659 | 119 | MAX6659: |
| 104 | * Selectable address | 120 | * Selectable address |
| 105 | * Second critical temperature limit | 121 | * Second critical temperature limit |
| 106 | * Remote sensor type selection | 122 | * Remote sensor type selection |
| 107 | 123 | ||
| 124 | MAX6680 and MAX6681: | ||
| 125 | * Selectable address | ||
| 126 | * Remote sensor type selection | ||
| 127 | |||
| 108 | All temperature values are given in degrees Celsius. Resolution | 128 | All temperature values are given in degrees Celsius. Resolution |
| 109 | is 1.0 degree for the local temperature, 0.125 degree for the remote | 129 | is 1.0 degree for the local temperature, 0.125 degree for the remote |
| 110 | temperature. | 130 | temperature. |
| @@ -141,7 +161,7 @@ SMBus Read Byte, and PEC will work properly. | |||
| 141 | Additionally, the ADM1032 doesn't support SMBus Send Byte with PEC. | 161 | Additionally, the ADM1032 doesn't support SMBus Send Byte with PEC. |
| 142 | Instead, it will try to write the PEC value to the register (because the | 162 | Instead, it will try to write the PEC value to the register (because the |
| 143 | SMBus Send Byte transaction with PEC is similar to a Write Byte transaction | 163 | SMBus Send Byte transaction with PEC is similar to a Write Byte transaction |
| 144 | without PEC), which is not what we want. Thus, PEC is explicitely disabled | 164 | without PEC), which is not what we want. Thus, PEC is explicitly disabled |
| 145 | on SMBus Send Byte transactions in the lm90 driver. | 165 | on SMBus Send Byte transactions in the lm90 driver. |
| 146 | 166 | ||
| 147 | PEC on byte data transactions represents a significant increase in bandwidth | 167 | PEC on byte data transactions represents a significant increase in bandwidth |
diff --git a/Documentation/hwmon/lm93 b/Documentation/hwmon/lm93 new file mode 100644 index 000000000000..4e4a1dc1d2da --- /dev/null +++ b/Documentation/hwmon/lm93 | |||
| @@ -0,0 +1,412 @@ | |||
| 1 | Kernel driver lm93 | ||
| 2 | ================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * National Semiconductor LM93 | ||
| 6 | Prefix 'lm93' | ||
| 7 | Addresses scanned: I2C 0x2c-0x2e | ||
| 8 | Datasheet: http://www.national.com/ds.cgi/LM/LM93.pdf | ||
| 9 | |||
| 10 | Author: | ||
| 11 | Mark M. Hoffman <mhoffman@lightlink.com> | ||
| 12 | Ported to 2.6 by Eric J. Bowersox <ericb@aspsys.com> | ||
| 13 | Adapted to 2.6.20 by Carsten Emde <ce@osadl.org> | ||
| 14 | Modified for mainline integration by Hans J. Koch <hjk@linutronix.de> | ||
| 15 | |||
| 16 | Module Parameters | ||
| 17 | ----------------- | ||
| 18 | |||
| 19 | (specific to LM93) | ||
| 20 | * init: integer | ||
| 21 | Set to non-zero to force some initializations (default is 0). | ||
| 22 | * disable_block: integer | ||
| 23 | A "0" allows SMBus block data transactions if the host supports them. A "1" | ||
| 24 | disables SMBus block data transactions. The default is 0. | ||
| 25 | * vccp_limit_type: integer array (2) | ||
| 26 | Configures in7 and in8 limit type, where 0 means absolute and non-zero | ||
| 27 | means relative. "Relative" here refers to "Dynamic Vccp Monitoring using | ||
| 28 | VID" from the datasheet. It greatly simplifies the interface to allow | ||
| 29 | only one set of limits (absolute or relative) to be in operation at a | ||
| 30 | time (even though the hardware is capable of enabling both). There's | ||
| 31 | not a compelling use case for enabling both at once, anyway. The default | ||
| 32 | is "0,0". | ||
| 33 | * vid_agtl: integer | ||
| 34 | A "0" configures the VID pins for V(ih) = 2.1V min, V(il) = 0.8V max. | ||
| 35 | A "1" configures the VID pins for V(ih) = 0.8V min, V(il) = 0.4V max. | ||
| 36 | (The latter setting is referred to as AGTL+ Compatible in the datasheet.) | ||
| 37 | I.e. this parameter controls the VID pin input thresholds; if your VID | ||
| 38 | inputs are not working, try changing this. The default value is "0". | ||
| 39 | |||
| 40 | (common among sensor drivers) | ||
| 41 | * force: short array (min = 1, max = 48) | ||
| 42 | List of adapter,address pairs to assume to be present. Autodetection | ||
| 43 | of the target device will still be attempted. Use one of the more | ||
| 44 | specific force directives below if this doesn't detect the device. | ||
| 45 | * force_lm93: short array (min = 1, max = 48) | ||
| 46 | List of adapter,address pairs which are unquestionably assumed to contain | ||
| 47 | a 'lm93' chip | ||
| 48 | * ignore: short array (min = 1, max = 48) | ||
| 49 | List of adapter,address pairs not to scan | ||
| 50 | * ignore_range: short array (min = 1, max = 48) | ||
| 51 | List of adapter,start-addr,end-addr triples not to scan | ||
| 52 | * probe: short array (min = 1, max = 48) | ||
| 53 | List of adapter,address pairs to scan additionally | ||
| 54 | * probe_range: short array (min = 1, max = 48) | ||
| 55 | List of adapter,start-addr,end-addr triples to scan additionally | ||
| 56 | |||
| 57 | |||
| 58 | Hardware Description | ||
| 59 | -------------------- | ||
| 60 | |||
| 61 | (from the datasheet) | ||
| 62 | |||
| 63 | The LM93, hardware monitor, has a two wire digital interface compatible with | ||
| 64 | SMBus 2.0. Using an 8-bit ADC, the LM93 measures the temperature of two remote | ||
| 65 | diode connected transistors as well as its own die and 16 power supply | ||
| 66 | voltages. To set fan speed, the LM93 has two PWM outputs that are each | ||
| 67 | controlled by up to four temperature zones. The fancontrol algorithm is lookup | ||
| 68 | table based. The LM93 includes a digital filter that can be invoked to smooth | ||
| 69 | temperature readings for better control of fan speed. The LM93 has four | ||
| 70 | tachometer inputs to measure fan speed. Limit and status registers for all | ||
| 71 | measured values are included. The LM93 builds upon the functionality of | ||
| 72 | previous motherboard management ASICs and uses some of the LM85 s features | ||
| 73 | (i.e. smart tachometer mode). It also adds measurement and control support | ||
| 74 | for dynamic Vccp monitoring and PROCHOT. It is designed to monitor a dual | ||
| 75 | processor Xeon class motherboard with a minimum of external components. | ||
| 76 | |||
| 77 | |||
| 78 | Driver Description | ||
| 79 | ------------------ | ||
| 80 | |||
| 81 | This driver implements support for the National Semiconductor LM93. | ||
| 82 | |||
| 83 | |||
| 84 | User Interface | ||
| 85 | -------------- | ||
| 86 | |||
| 87 | #PROCHOT: | ||
| 88 | |||
| 89 | The LM93 can monitor two #PROCHOT signals. The results are found in the | ||
| 90 | sysfs files prochot1, prochot2, prochot1_avg, prochot2_avg, prochot1_max, | ||
| 91 | and prochot2_max. prochot1_max and prochot2_max contain the user limits | ||
| 92 | for #PROCHOT1 and #PROCHOT2, respectively. prochot1 and prochot2 contain | ||
| 93 | the current readings for the most recent complete time interval. The | ||
| 94 | value of prochot1_avg and prochot2_avg is something like a 2 period | ||
| 95 | exponential moving average (but not quite - check the datasheet). Note | ||
| 96 | that this third value is calculated by the chip itself. All values range | ||
| 97 | from 0-255 where 0 indicates no throttling, and 255 indicates > 99.6%. | ||
| 98 | |||
| 99 | The monitoring intervals for the two #PROCHOT signals is also configurable. | ||
| 100 | These intervals can be found in the sysfs files prochot1_interval and | ||
| 101 | prochot2_interval. The values in these files specify the intervals for | ||
| 102 | #P1_PROCHOT and #P2_PROCHOT, respectively. Selecting a value not in this | ||
| 103 | list will cause the driver to use the next largest interval. The available | ||
| 104 | intervals are: | ||
| 105 | |||
| 106 | #PROCHOT intervals: 0.73, 1.46, 2.9, 5.8, 11.7, 23.3, 46.6, 93.2, 186, 372 | ||
| 107 | |||
| 108 | It is possible to configure the LM93 to logically short the two #PROCHOT | ||
| 109 | signals. I.e. when #P1_PROCHOT is asserted, the LM93 will automatically | ||
| 110 | assert #P2_PROCHOT, and vice-versa. This mode is enabled by writing a | ||
| 111 | non-zero integer to the sysfs file prochot_short. | ||
| 112 | |||
| 113 | The LM93 can also override the #PROCHOT pins by driving a PWM signal onto | ||
| 114 | one or both of them. When overridden, the signal has a period of 3.56 mS, | ||
| 115 | a minimum pulse width of 5 clocks (at 22.5kHz => 6.25% duty cycle), and | ||
| 116 | a maximum pulse width of 80 clocks (at 22.5kHz => 99.88% duty cycle). | ||
| 117 | |||
| 118 | The sysfs files prochot1_override and prochot2_override contain boolean | ||
| 119 | intgers which enable or disable the override function for #P1_PROCHOT and | ||
| 120 | #P2_PROCHOT, respectively. The sysfs file prochot_override_duty_cycle | ||
| 121 | contains a value controlling the duty cycle for the PWM signal used when | ||
| 122 | the override function is enabled. This value ranges from 0 to 15, with 0 | ||
| 123 | indicating minimum duty cycle and 15 indicating maximum. | ||
| 124 | |||
| 125 | #VRD_HOT: | ||
| 126 | |||
| 127 | The LM93 can monitor two #VRD_HOT signals. The results are found in the | ||
| 128 | sysfs files vrdhot1 and vrdhot2. There is one value per file: a boolean for | ||
| 129 | which 1 indicates #VRD_HOT is asserted and 0 indicates it is negated. These | ||
| 130 | files are read-only. | ||
| 131 | |||
| 132 | Smart Tach Mode: | ||
| 133 | |||
| 134 | (from the datasheet) | ||
| 135 | |||
| 136 | If a fan is driven using a low-side drive PWM, the tachometer | ||
| 137 | output of the fan is corrupted. The LM93 includes smart tachometer | ||
| 138 | circuitry that allows an accurate tachometer reading to be | ||
| 139 | achieved despite the signal corruption. In smart tach mode all | ||
| 140 | four signals are measured within 4 seconds. | ||
| 141 | |||
| 142 | Smart tach mode is enabled by the driver by writing 1 or 2 (associating the | ||
| 143 | the fan tachometer with a pwm) to the sysfs file fan<n>_smart_tach. A zero | ||
| 144 | will disable the function for that fan. Note that Smart tach mode cannot be | ||
| 145 | enabled if the PWM output frequency is 22500 Hz (see below). | ||
| 146 | |||
| 147 | Manual PWM: | ||
| 148 | |||
| 149 | The LM93 has a fixed or override mode for the two PWM outputs (although, there | ||
| 150 | are still some conditions that will override even this mode - see section | ||
| 151 | 15.10.6 of the datasheet for details.) The sysfs files pwm1_override | ||
| 152 | and pwm2_override are used to enable this mode; each is a boolean integer | ||
| 153 | where 0 disables and 1 enables the manual control mode. The sysfs files pwm1 | ||
| 154 | and pwm2 are used to set the manual duty cycle; each is an integer (0-255) | ||
| 155 | where 0 is 0% duty cycle, and 255 is 100%. Note that the duty cycle values | ||
| 156 | are constrained by the hardware. Selecting a value which is not available | ||
| 157 | will cause the driver to use the next largest value. Also note: when manual | ||
| 158 | PWM mode is disabled, the value of pwm1 and pwm2 indicates the current duty | ||
| 159 | cycle chosen by the h/w. | ||
| 160 | |||
| 161 | PWM Output Frequency: | ||
| 162 | |||
| 163 | The LM93 supports several different frequencies for the PWM output channels. | ||
| 164 | The sysfs files pwm1_freq and pwm2_freq are used to select the frequency. The | ||
| 165 | frequency values are constrained by the hardware. Selecting a value which is | ||
| 166 | not available will cause the driver to use the next largest value. Also note | ||
| 167 | that this parameter has implications for the Smart Tach Mode (see above). | ||
| 168 | |||
| 169 | PWM Output Frequencies: 12, 36, 48, 60, 72, 84, 96, 22500 (h/w default) | ||
| 170 | |||
| 171 | Automatic PWM: | ||
| 172 | |||
| 173 | The LM93 is capable of complex automatic fan control, with many different | ||
| 174 | points of configuration. To start, each PWM output can be bound to any | ||
| 175 | combination of eight control sources. The final PWM is the largest of all | ||
| 176 | individual control sources to which the PWM output is bound. | ||
| 177 | |||
| 178 | The eight control sources are: temp1-temp4 (aka "zones" in the datasheet), | ||
| 179 | #PROCHOT 1 & 2, and #VRDHOT 1 & 2. The bindings are expressed as a bitmask | ||
| 180 | in the sysfs files pwm<n>_auto_channels, where a "1" enables the binding, and | ||
| 181 | a "0" disables it. The h/w default is 0x0f (all temperatures bound). | ||
| 182 | |||
| 183 | 0x01 - Temp 1 | ||
| 184 | 0x02 - Temp 2 | ||
| 185 | 0x04 - Temp 3 | ||
| 186 | 0x08 - Temp 4 | ||
| 187 | 0x10 - #PROCHOT 1 | ||
| 188 | 0x20 - #PROCHOT 2 | ||
| 189 | 0x40 - #VRDHOT 1 | ||
| 190 | 0x80 - #VRDHOT 2 | ||
| 191 | |||
| 192 | The function y = f(x) takes a source temperature x to a PWM output y. This | ||
| 193 | function of the LM93 is derived from a base temperature and a table of 12 | ||
| 194 | temperature offsets. The base temperature is expressed in degrees C in the | ||
| 195 | sysfs files temp<n>_auto_base. The offsets are expressed in cumulative | ||
| 196 | degrees C, with the value of offset <i> for temperature value <n> being | ||
| 197 | contained in the file temp<n>_auto_offset<i>. E.g. if the base temperature | ||
| 198 | is 40C: | ||
| 199 | |||
| 200 | offset # temp<n>_auto_offset<i> range pwm | ||
| 201 | 1 0 - 25.00% | ||
| 202 | 2 0 - 28.57% | ||
| 203 | 3 1 40C - 41C 32.14% | ||
| 204 | 4 1 41C - 42C 35.71% | ||
| 205 | 5 2 42C - 44C 39.29% | ||
| 206 | 6 2 44C - 46C 42.86% | ||
| 207 | 7 2 48C - 50C 46.43% | ||
| 208 | 8 2 50C - 52C 50.00% | ||
| 209 | 9 2 52C - 54C 53.57% | ||
| 210 | 10 2 54C - 56C 57.14% | ||
| 211 | 11 2 56C - 58C 71.43% | ||
| 212 | 12 2 58C - 60C 85.71% | ||
| 213 | > 60C 100.00% | ||
| 214 | |||
| 215 | Valid offsets are in the range 0C <= x <= 7.5C in 0.5C increments. | ||
| 216 | |||
| 217 | There is an independent base temperature for each temperature channel. Note, | ||
| 218 | however, there are only two tables of offsets: one each for temp[12] and | ||
| 219 | temp[34]. Therefore, any change to e.g. temp1_auto_offset<i> will also | ||
| 220 | affect temp2_auto_offset<i>. | ||
| 221 | |||
| 222 | The LM93 can also apply hysteresis to the offset table, to prevent unwanted | ||
| 223 | oscillation between two steps in the offsets table. These values are found in | ||
| 224 | the sysfs files temp<n>_auto_offset_hyst. The value in this file has the | ||
| 225 | same representation as in temp<n>_auto_offset<i>. | ||
| 226 | |||
| 227 | If a temperature reading falls below the base value for that channel, the LM93 | ||
| 228 | will use the minimum PWM value. These values are found in the sysfs files | ||
| 229 | temp<n>_auto_pwm_min. Note, there are only two minimums: one each for temp[12] | ||
| 230 | and temp[34]. Therefore, any change to e.g. temp1_auto_pwm_min will also | ||
| 231 | affect temp2_auto_pwm_min. | ||
| 232 | |||
| 233 | PWM Spin-Up Cycle: | ||
| 234 | |||
| 235 | A spin-up cycle occurs when a PWM output is commanded from 0% duty cycle to | ||
| 236 | some value > 0%. The LM93 supports a minimum duty cycle during spin-up. These | ||
| 237 | values are found in the sysfs files pwm<n>_auto_spinup_min. The value in this | ||
| 238 | file has the same representation as other PWM duty cycle values. The | ||
| 239 | duration of the spin-up cycle is also configurable. These values are found in | ||
| 240 | the sysfs files pwm<n>_auto_spinup_time. The value in this file is | ||
| 241 | the spin-up time in seconds. The available spin-up times are constrained by | ||
| 242 | the hardware. Selecting a value which is not available will cause the driver | ||
| 243 | to use the next largest value. | ||
| 244 | |||
| 245 | Spin-up Durations: 0 (disabled, h/w default), 0.1, 0.25, 0.4, 0.7, 1.0, | ||
| 246 | 2.0, 4.0 | ||
| 247 | |||
| 248 | #PROCHOT and #VRDHOT PWM Ramping: | ||
| 249 | |||
| 250 | If the #PROCHOT or #VRDHOT signals are asserted while bound to a PWM output | ||
| 251 | channel, the LM93 will ramp the PWM output up to 100% duty cycle in discrete | ||
| 252 | steps. The duration of each step is configurable. There are two files, with | ||
| 253 | one value each in seconds: pwm_auto_prochot_ramp and pwm_auto_vrdhot_ramp. | ||
| 254 | The available ramp times are constrained by the hardware. Selecting a value | ||
| 255 | which is not available will cause the driver to use the next largest value. | ||
| 256 | |||
| 257 | Ramp Times: 0 (disabled, h/w default) to 0.75 in 0.05 second intervals | ||
| 258 | |||
| 259 | Fan Boost: | ||
| 260 | |||
| 261 | For each temperature channel, there is a boost temperature: if the channel | ||
| 262 | exceeds this limit, the LM93 will immediately drive both PWM outputs to 100%. | ||
| 263 | This limit is expressed in degrees C in the sysfs files temp<n>_auto_boost. | ||
| 264 | There is also a hysteresis temperature for this function: after the boost | ||
| 265 | limit is reached, the temperature channel must drop below this value before | ||
| 266 | the boost function is disabled. This temperature is also expressed in degrees | ||
| 267 | C in the sysfs files temp<n>_auto_boost_hyst. | ||
| 268 | |||
| 269 | GPIO Pins: | ||
| 270 | |||
| 271 | The LM93 can monitor the logic level of four dedicated GPIO pins as well as the | ||
| 272 | four tach input pins. GPIO0-GPIO3 correspond to (fan) tach 1-4, respectively. | ||
| 273 | All eight GPIOs are read by reading the bitmask in the sysfs file gpio. The | ||
| 274 | LSB is GPIO0, and the MSB is GPIO7. | ||
| 275 | |||
| 276 | |||
| 277 | LM93 Unique sysfs Files | ||
| 278 | ----------------------- | ||
| 279 | |||
| 280 | file description | ||
| 281 | ------------------------------------------------------------- | ||
| 282 | |||
| 283 | prochot<n> current #PROCHOT % | ||
| 284 | |||
| 285 | prochot<n>_avg moving average #PROCHOT % | ||
| 286 | |||
| 287 | prochot<n>_max limit #PROCHOT % | ||
| 288 | |||
| 289 | prochot_short enable or disable logical #PROCHOT pin short | ||
| 290 | |||
| 291 | prochot<n>_override force #PROCHOT assertion as PWM | ||
| 292 | |||
| 293 | prochot_override_duty_cycle | ||
| 294 | duty cycle for the PWM signal used when | ||
| 295 | #PROCHOT is overridden | ||
| 296 | |||
| 297 | prochot<n>_interval #PROCHOT PWM sampling interval | ||
| 298 | |||
| 299 | vrdhot<n> 0 means negated, 1 means asserted | ||
| 300 | |||
| 301 | fan<n>_smart_tach enable or disable smart tach mode | ||
| 302 | |||
| 303 | pwm<n>_auto_channels select control sources for PWM outputs | ||
| 304 | |||
| 305 | pwm<n>_auto_spinup_min minimum duty cycle during spin-up | ||
| 306 | |||
| 307 | pwm<n>_auto_spinup_time duration of spin-up | ||
| 308 | |||
| 309 | pwm_auto_prochot_ramp ramp time per step when #PROCHOT asserted | ||
| 310 | |||
| 311 | pwm_auto_vrdhot_ramp ramp time per step when #VRDHOT asserted | ||
| 312 | |||
| 313 | temp<n>_auto_base temperature channel base | ||
| 314 | |||
| 315 | temp<n>_auto_offset[1-12] | ||
| 316 | temperature channel offsets | ||
| 317 | |||
| 318 | temp<n>_auto_offset_hyst | ||
| 319 | temperature channel offset hysteresis | ||
| 320 | |||
| 321 | temp<n>_auto_boost temperature channel boost (PWMs to 100%) limit | ||
| 322 | |||
| 323 | temp<n>_auto_boost_hyst temperature channel boost hysteresis | ||
| 324 | |||
| 325 | gpio input state of 8 GPIO pins; read-only | ||
| 326 | |||
| 327 | |||
| 328 | Sample Configuration File | ||
| 329 | ------------------------- | ||
| 330 | |||
| 331 | Here is a sample LM93 chip config for sensors.conf: | ||
| 332 | |||
| 333 | ---------- cut here ---------- | ||
| 334 | chip "lm93-*" | ||
| 335 | |||
| 336 | # VOLTAGE INPUTS | ||
| 337 | |||
| 338 | # labels and scaling based on datasheet recommendations | ||
| 339 | label in1 "+12V1" | ||
| 340 | compute in1 @ * 12.945, @ / 12.945 | ||
| 341 | set in1_min 12 * 0.90 | ||
| 342 | set in1_max 12 * 1.10 | ||
| 343 | |||
| 344 | label in2 "+12V2" | ||
| 345 | compute in2 @ * 12.945, @ / 12.945 | ||
| 346 | set in2_min 12 * 0.90 | ||
| 347 | set in2_max 12 * 1.10 | ||
| 348 | |||
| 349 | label in3 "+12V3" | ||
| 350 | compute in3 @ * 12.945, @ / 12.945 | ||
| 351 | set in3_min 12 * 0.90 | ||
| 352 | set in3_max 12 * 1.10 | ||
| 353 | |||
| 354 | label in4 "FSB_Vtt" | ||
| 355 | |||
| 356 | label in5 "3GIO" | ||
| 357 | |||
| 358 | label in6 "ICH_Core" | ||
| 359 | |||
| 360 | label in7 "Vccp1" | ||
| 361 | |||
| 362 | label in8 "Vccp2" | ||
| 363 | |||
| 364 | label in9 "+3.3V" | ||
| 365 | set in9_min 3.3 * 0.90 | ||
| 366 | set in9_max 3.3 * 1.10 | ||
| 367 | |||
| 368 | label in10 "+5V" | ||
| 369 | set in10_min 5.0 * 0.90 | ||
| 370 | set in10_max 5.0 * 1.10 | ||
| 371 | |||
| 372 | label in11 "SCSI_Core" | ||
| 373 | |||
| 374 | label in12 "Mem_Core" | ||
| 375 | |||
| 376 | label in13 "Mem_Vtt" | ||
| 377 | |||
| 378 | label in14 "Gbit_Core" | ||
| 379 | |||
| 380 | # Assuming R1/R2 = 4.1143, and 3.3V reference | ||
| 381 | # -12V = (4.1143 + 1) * (@ - 3.3) + 3.3 | ||
| 382 | label in15 "-12V" | ||
| 383 | compute in15 @ * 5.1143 - 13.57719, (@ + 13.57719) / 5.1143 | ||
| 384 | set in15_min -12 * 0.90 | ||
| 385 | set in15_max -12 * 1.10 | ||
| 386 | |||
| 387 | label in16 "+3.3VSB" | ||
| 388 | set in16_min 3.3 * 0.90 | ||
| 389 | set in16_max 3.3 * 1.10 | ||
| 390 | |||
| 391 | # TEMPERATURE INPUTS | ||
| 392 | |||
| 393 | label temp1 "CPU1" | ||
| 394 | label temp2 "CPU2" | ||
| 395 | label temp3 "LM93" | ||
| 396 | |||
| 397 | # TACHOMETER INPUTS | ||
| 398 | |||
| 399 | label fan1 "Fan1" | ||
| 400 | set fan1_min 3000 | ||
| 401 | label fan2 "Fan2" | ||
| 402 | set fan2_min 3000 | ||
| 403 | label fan3 "Fan3" | ||
| 404 | set fan3_min 3000 | ||
| 405 | label fan4 "Fan4" | ||
| 406 | set fan4_min 3000 | ||
| 407 | |||
| 408 | # PWM OUTPUTS | ||
| 409 | |||
| 410 | label pwm1 "CPU1" | ||
| 411 | label pwm2 "CPU2" | ||
| 412 | |||
diff --git a/Documentation/hwmon/smsc47b397 b/Documentation/hwmon/smsc47b397 index 20682f15ae41..3a43b6948924 100644 --- a/Documentation/hwmon/smsc47b397 +++ b/Documentation/hwmon/smsc47b397 | |||
| @@ -4,6 +4,7 @@ Kernel driver smsc47b397 | |||
| 4 | Supported chips: | 4 | Supported chips: |
| 5 | * SMSC LPC47B397-NC | 5 | * SMSC LPC47B397-NC |
| 6 | * SMSC SCH5307-NS | 6 | * SMSC SCH5307-NS |
| 7 | * SMSC SCH5317 | ||
| 7 | Prefix: 'smsc47b397' | 8 | Prefix: 'smsc47b397' |
| 8 | Addresses scanned: none, address read from Super I/O config space | 9 | Addresses scanned: none, address read from Super I/O config space |
| 9 | Datasheet: In this file | 10 | Datasheet: In this file |
| @@ -18,8 +19,8 @@ The following specification describes the SMSC LPC47B397-NC[1] sensor chip | |||
| 18 | provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected | 19 | provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected |
| 19 | by Mark M. Hoffman <mhoffman@lightlink.com>. | 20 | by Mark M. Hoffman <mhoffman@lightlink.com>. |
| 20 | 21 | ||
| 21 | [1] And SMSC SCH5307-NS, which has a different device ID but is otherwise | 22 | [1] And SMSC SCH5307-NS and SCH5317, which have different device IDs but are |
| 22 | compatible. | 23 | otherwise compatible. |
| 23 | 24 | ||
| 24 | * * * * * | 25 | * * * * * |
| 25 | 26 | ||
| @@ -131,7 +132,7 @@ OUT DX,AL | |||
| 131 | The registers of interest for identifying the SIO on the dc7100 are Device ID | 132 | The registers of interest for identifying the SIO on the dc7100 are Device ID |
| 132 | (0x20) and Device Rev (0x21). | 133 | (0x20) and Device Rev (0x21). |
| 133 | 134 | ||
| 134 | The Device ID will read 0x6F (for SCH5307-NS, 0x81) | 135 | The Device ID will read 0x6F (0x81 for SCH5307-NS, and 0x85 for SCH5317) |
| 135 | The Device Rev currently reads 0x01 | 136 | The Device Rev currently reads 0x01 |
| 136 | 137 | ||
| 137 | Obtaining the HWM Base Address. | 138 | Obtaining the HWM Base Address. |
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index a9a18ad0d17a..b3a9e1b9dbda 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface | |||
| @@ -172,11 +172,10 @@ pwm[1-*] Pulse width modulation fan control. | |||
| 172 | 255 is max or 100%. | 172 | 255 is max or 100%. |
| 173 | 173 | ||
| 174 | pwm[1-*]_enable | 174 | pwm[1-*]_enable |
| 175 | Switch PWM on and off. | 175 | Fan speed control method: |
| 176 | Not always present even if pwmN is. | 176 | 0: no fan speed control (i.e. fan at full speed) |
| 177 | 0: turn off | 177 | 1: manual fan speed control enabled (using pwm[1-*]) |
| 178 | 1: turn on in manual mode | 178 | 2+: automatic fan speed control enabled |
| 179 | 2+: turn on in automatic mode | ||
| 180 | Check individual chip documentation files for automatic mode | 179 | Check individual chip documentation files for automatic mode |
| 181 | details. | 180 | details. |
| 182 | RW | 181 | RW |
| @@ -343,9 +342,9 @@ to notify open diodes, unconnected fans etc. where the hardware | |||
| 343 | supports it. When this boolean has value 1, the measurement for that | 342 | supports it. When this boolean has value 1, the measurement for that |
| 344 | channel should not be trusted. | 343 | channel should not be trusted. |
| 345 | 344 | ||
| 346 | in[0-*]_input_fault | 345 | in[0-*]_fault |
| 347 | fan[1-*]_input_fault | 346 | fan[1-*]_fault |
| 348 | temp[1-*]_input_fault | 347 | temp[1-*]_fault |
| 349 | Input fault condition | 348 | Input fault condition |
| 350 | 0: no fault occured | 349 | 0: no fault occured |
| 351 | 1: fault condition | 350 | 1: fault condition |
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf index 030fac6cec7a..ccc2bcb61068 100644 --- a/Documentation/hwmon/w83627ehf +++ b/Documentation/hwmon/w83627ehf | |||
| @@ -22,9 +22,9 @@ This driver implements support for the Winbond W83627EHF, W83627EHG, and | |||
| 22 | W83627DHG super I/O chips. We will refer to them collectively as Winbond chips. | 22 | W83627DHG super I/O chips. We will refer to them collectively as Winbond chips. |
| 23 | 23 | ||
| 24 | The chips implement three temperature sensors, five fan rotation | 24 | The chips implement three temperature sensors, five fan rotation |
| 25 | speed sensors, ten analog voltage sensors (only nine for the 627DHG), alarms | 25 | speed sensors, ten analog voltage sensors (only nine for the 627DHG), one |
| 26 | with beep warnings (control unimplemented), and some automatic fan regulation | 26 | VID (6 pins), alarms with beep warnings (control unimplemented), and |
| 27 | strategies (plus manual fan control mode). | 27 | some automatic fan regulation strategies (plus manual fan control mode). |
| 28 | 28 | ||
| 29 | Temperatures are measured in degrees Celsius and measurement resolution is 1 | 29 | Temperatures are measured in degrees Celsius and measurement resolution is 1 |
| 30 | degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when | 30 | degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when |
diff --git a/MAINTAINERS b/MAINTAINERS index 0c83823f14c3..fbe0dca1c0ed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -607,6 +607,12 @@ W: http://sourceforge.net/projects/acpi4asus | |||
| 607 | W: http://xf.iksaif.net/acpi4asus | 607 | W: http://xf.iksaif.net/acpi4asus |
| 608 | S: Maintained | 608 | S: Maintained |
| 609 | 609 | ||
| 610 | ASUS ASB100 HARDWARE MONITOR DRIVER | ||
| 611 | P: Mark M. Hoffman | ||
| 612 | M: mhoffman@lightlink.com | ||
| 613 | L: lm-sensors@lm-sensors.org | ||
| 614 | S: Maintained | ||
| 615 | |||
| 610 | ASUS LAPTOP EXTRAS DRIVER | 616 | ASUS LAPTOP EXTRAS DRIVER |
| 611 | P: Corentin Chary | 617 | P: Corentin Chary |
| 612 | M: corentincj@iksaif.net | 618 | M: corentincj@iksaif.net |
| @@ -1273,6 +1279,12 @@ M: shannon.nelson@intel.com | |||
| 1273 | L: linux-kernel@vger.kernel.org | 1279 | L: linux-kernel@vger.kernel.org |
| 1274 | S: Maintained | 1280 | S: Maintained |
| 1275 | 1281 | ||
| 1282 | DME1737 HARDWARE MONITOR DRIVER | ||
| 1283 | P: Juerg Haefliger | ||
| 1284 | M: juergh@gmail.com | ||
| 1285 | L: lm-sensors@lm-sensors.org | ||
| 1286 | S: Maintained | ||
| 1287 | |||
| 1276 | DOCBOOK FOR DOCUMENTATION | 1288 | DOCBOOK FOR DOCUMENTATION |
| 1277 | P: Randy Dunlap | 1289 | P: Randy Dunlap |
| 1278 | M: rdunlap@xenotime.net | 1290 | M: rdunlap@xenotime.net |
| @@ -1623,11 +1635,11 @@ W: http://gigaset307x.sourceforge.net/ | |||
| 1623 | S: Maintained | 1635 | S: Maintained |
| 1624 | 1636 | ||
| 1625 | HARDWARE MONITORING | 1637 | HARDWARE MONITORING |
| 1626 | P: Jean Delvare | 1638 | P: Mark M. Hoffman |
| 1627 | M: khali@linux-fr.org | 1639 | M: mhoffman@lightlink.com |
| 1628 | L: lm-sensors@lm-sensors.org | 1640 | L: lm-sensors@lm-sensors.org |
| 1629 | W: http://www.lm-sensors.org/ | 1641 | W: http://www.lm-sensors.org/ |
| 1630 | T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-hwmon/ | 1642 | T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git |
| 1631 | S: Maintained | 1643 | S: Maintained |
| 1632 | 1644 | ||
| 1633 | HARDWARE RANDOM NUMBER GENERATOR CORE | 1645 | HARDWARE RANDOM NUMBER GENERATOR CORE |
| @@ -1763,6 +1775,12 @@ P: William Irwin | |||
| 1763 | M: wli@holomorphy.com | 1775 | M: wli@holomorphy.com |
| 1764 | S: Maintained | 1776 | S: Maintained |
| 1765 | 1777 | ||
| 1778 | I2C/SMBUS STUB DRIVER | ||
| 1779 | P: Mark M. Hoffman | ||
| 1780 | M: mhoffman@lightlink.com | ||
| 1781 | L: lm-sensors@lm-sensors.org | ||
| 1782 | S: Maintained | ||
| 1783 | |||
| 1766 | I2C SUBSYSTEM | 1784 | I2C SUBSYSTEM |
| 1767 | P: Jean Delvare | 1785 | P: Jean Delvare |
| 1768 | M: khali@linux-fr.org | 1786 | M: khali@linux-fr.org |
| @@ -3292,6 +3310,12 @@ W: http://www.brownhat.org/sis900.html | |||
| 3292 | L: netdev@vger.kernel.org | 3310 | L: netdev@vger.kernel.org |
| 3293 | S: Maintained | 3311 | S: Maintained |
| 3294 | 3312 | ||
| 3313 | SIS 96X I2C/SMBUS DRIVER | ||
| 3314 | P: Mark M. Hoffman | ||
| 3315 | M: mhoffman@lightlink.com | ||
| 3316 | L: lm-sensors@lm-sensors.org | ||
| 3317 | S: Maintained | ||
| 3318 | |||
| 3295 | SIS FRAMEBUFFER DRIVER | 3319 | SIS FRAMEBUFFER DRIVER |
| 3296 | P: Thomas Winischhofer | 3320 | P: Thomas Winischhofer |
| 3297 | M: thomas@winischhofer.net | 3321 | M: thomas@winischhofer.net |
| @@ -3309,6 +3333,12 @@ P: Nicolas Pitre | |||
| 3309 | M: nico@cam.org | 3333 | M: nico@cam.org |
| 3310 | S: Maintained | 3334 | S: Maintained |
| 3311 | 3335 | ||
| 3336 | SMSC47B397 HARDWARE MONITOR DRIVER | ||
| 3337 | P: Mark M. Hoffman | ||
| 3338 | M: mhoffman@lightlink.com | ||
| 3339 | L: lm-sensors@lm-sensors.org | ||
| 3340 | S: Maintained | ||
| 3341 | |||
| 3312 | SOFTMAC LAYER (IEEE 802.11) | 3342 | SOFTMAC LAYER (IEEE 802.11) |
| 3313 | P: Johannes Berg | 3343 | P: Johannes Berg |
| 3314 | M: johannes@sipsolutions.net | 3344 | M: johannes@sipsolutions.net |
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig index 821865f75605..b2bbf217c707 100644 --- a/arch/arm/configs/badge4_defconfig +++ b/arch/arm/configs/badge4_defconfig | |||
| @@ -708,7 +708,6 @@ CONFIG_I2C_ALGOPCF=m | |||
| 708 | # I2C Hardware Bus support | 708 | # I2C Hardware Bus support |
| 709 | # | 709 | # |
| 710 | CONFIG_I2C_ELEKTOR=m | 710 | CONFIG_I2C_ELEKTOR=m |
| 711 | # CONFIG_I2C_ISA is not set | ||
| 712 | # CONFIG_I2C_PARPORT is not set | 711 | # CONFIG_I2C_PARPORT is not set |
| 713 | # CONFIG_I2C_PARPORT_LIGHT is not set | 712 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| 714 | # CONFIG_I2C_STUB is not set | 713 | # CONFIG_I2C_STUB is not set |
diff --git a/arch/arm/configs/clps7500_defconfig b/arch/arm/configs/clps7500_defconfig index af9ae5389131..49e9f9d8b3d1 100644 --- a/arch/arm/configs/clps7500_defconfig +++ b/arch/arm/configs/clps7500_defconfig | |||
| @@ -536,7 +536,6 @@ CONFIG_I2C_ALGOBIT=y | |||
| 536 | # I2C Hardware Bus support | 536 | # I2C Hardware Bus support |
| 537 | # | 537 | # |
| 538 | # CONFIG_I2C_ELEKTOR is not set | 538 | # CONFIG_I2C_ELEKTOR is not set |
| 539 | # CONFIG_I2C_ISA is not set | ||
| 540 | # CONFIG_I2C_PARPORT is not set | 539 | # CONFIG_I2C_PARPORT is not set |
| 541 | # CONFIG_I2C_PARPORT_LIGHT is not set | 540 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| 542 | # CONFIG_I2C_PCA_ISA is not set | 541 | # CONFIG_I2C_PCA_ISA is not set |
diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig index 2a612d23120b..299dc22294a0 100644 --- a/arch/arm/configs/footbridge_defconfig +++ b/arch/arm/configs/footbridge_defconfig | |||
| @@ -748,7 +748,6 @@ CONFIG_I2C=m | |||
| 748 | # CONFIG_I2C_ELEKTOR is not set | 748 | # CONFIG_I2C_ELEKTOR is not set |
| 749 | # CONFIG_I2C_I801 is not set | 749 | # CONFIG_I2C_I801 is not set |
| 750 | # CONFIG_I2C_I810 is not set | 750 | # CONFIG_I2C_I810 is not set |
| 751 | # CONFIG_I2C_ISA is not set | ||
| 752 | # CONFIG_I2C_NFORCE2 is not set | 751 | # CONFIG_I2C_NFORCE2 is not set |
| 753 | # CONFIG_I2C_PARPORT is not set | 752 | # CONFIG_I2C_PARPORT is not set |
| 754 | # CONFIG_I2C_PARPORT_LIGHT is not set | 753 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig index e86794a10fc0..92ccdc6492f7 100644 --- a/arch/arm/configs/neponset_defconfig +++ b/arch/arm/configs/neponset_defconfig | |||
| @@ -698,7 +698,6 @@ CONFIG_I2C_ALGOBIT=y | |||
| 698 | # I2C Hardware Bus support | 698 | # I2C Hardware Bus support |
| 699 | # | 699 | # |
| 700 | # CONFIG_I2C_ELEKTOR is not set | 700 | # CONFIG_I2C_ELEKTOR is not set |
| 701 | # CONFIG_I2C_ISA is not set | ||
| 702 | # CONFIG_I2C_PARPORT_LIGHT is not set | 701 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| 703 | # CONFIG_I2C_STUB is not set | 702 | # CONFIG_I2C_STUB is not set |
| 704 | # CONFIG_I2C_PCA_ISA is not set | 703 | # CONFIG_I2C_PCA_ISA is not set |
diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig index 339c48953a62..3c0c4f192dc1 100644 --- a/arch/arm/configs/picotux200_defconfig +++ b/arch/arm/configs/picotux200_defconfig | |||
| @@ -735,7 +735,6 @@ CONFIG_I2C_CHARDEV=m | |||
| 735 | # I2C Hardware Bus support | 735 | # I2C Hardware Bus support |
| 736 | # | 736 | # |
| 737 | CONFIG_I2C_AT91=m | 737 | CONFIG_I2C_AT91=m |
| 738 | CONFIG_I2C_ISA=m | ||
| 739 | # CONFIG_I2C_OCORES is not set | 738 | # CONFIG_I2C_OCORES is not set |
| 740 | # CONFIG_I2C_PARPORT_LIGHT is not set | 739 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| 741 | # CONFIG_I2C_STUB is not set | 740 | # CONFIG_I2C_STUB is not set |
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig index bc091264d354..8452dc8c7cc3 100644 --- a/arch/arm/configs/rpc_defconfig +++ b/arch/arm/configs/rpc_defconfig | |||
| @@ -558,7 +558,6 @@ CONFIG_I2C_ALGOBIT=y | |||
| 558 | # | 558 | # |
| 559 | # I2C Hardware Bus support | 559 | # I2C Hardware Bus support |
| 560 | # | 560 | # |
| 561 | # CONFIG_I2C_ISA is not set | ||
| 562 | # CONFIG_I2C_PARPORT is not set | 561 | # CONFIG_I2C_PARPORT is not set |
| 563 | # CONFIG_I2C_PARPORT_LIGHT is not set | 562 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| 564 | # CONFIG_I2C_STUB is not set | 563 | # CONFIG_I2C_STUB is not set |
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index a850da377a29..1d5150e4d6b3 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig | |||
| @@ -826,7 +826,6 @@ CONFIG_I2C_ALGOBIT=m | |||
| 826 | # I2C Hardware Bus support | 826 | # I2C Hardware Bus support |
| 827 | # | 827 | # |
| 828 | # CONFIG_I2C_ELEKTOR is not set | 828 | # CONFIG_I2C_ELEKTOR is not set |
| 829 | CONFIG_I2C_ISA=m | ||
| 830 | # CONFIG_I2C_OCORES is not set | 829 | # CONFIG_I2C_OCORES is not set |
| 831 | # CONFIG_I2C_PARPORT is not set | 830 | # CONFIG_I2C_PARPORT is not set |
| 832 | # CONFIG_I2C_PARPORT_LIGHT is not set | 831 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/m32r/m32104ut/defconfig.m32104ut b/arch/m32r/m32104ut/defconfig.m32104ut index 7b68fe8d921e..1f88f493a9e2 100644 --- a/arch/m32r/m32104ut/defconfig.m32104ut +++ b/arch/m32r/m32104ut/defconfig.m32104ut | |||
| @@ -699,7 +699,6 @@ CONFIG_I2C_ALGOPCF=m | |||
| 699 | # I2C Hardware Bus support | 699 | # I2C Hardware Bus support |
| 700 | # | 700 | # |
| 701 | CONFIG_I2C_ELEKTOR=m | 701 | CONFIG_I2C_ELEKTOR=m |
| 702 | CONFIG_I2C_ISA=m | ||
| 703 | # CONFIG_I2C_OCORES is not set | 702 | # CONFIG_I2C_OCORES is not set |
| 704 | # CONFIG_I2C_PARPORT is not set | 703 | # CONFIG_I2C_PARPORT is not set |
| 705 | # CONFIG_I2C_PARPORT_LIGHT is not set | 704 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/ev64260_defconfig b/arch/ppc/configs/ev64260_defconfig index 84cc142a67bb..587e9a3b9491 100644 --- a/arch/ppc/configs/ev64260_defconfig +++ b/arch/ppc/configs/ev64260_defconfig | |||
| @@ -531,7 +531,6 @@ CONFIG_I2C_CHARDEV=m | |||
| 531 | # CONFIG_I2C_AMD8111 is not set | 531 | # CONFIG_I2C_AMD8111 is not set |
| 532 | # CONFIG_I2C_I801 is not set | 532 | # CONFIG_I2C_I801 is not set |
| 533 | # CONFIG_I2C_I810 is not set | 533 | # CONFIG_I2C_I810 is not set |
| 534 | # CONFIG_I2C_ISA is not set | ||
| 535 | # CONFIG_I2C_NFORCE2 is not set | 534 | # CONFIG_I2C_NFORCE2 is not set |
| 536 | # CONFIG_I2C_PARPORT_LIGHT is not set | 535 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| 537 | # CONFIG_I2C_PIIX4 is not set | 536 | # CONFIG_I2C_PIIX4 is not set |
diff --git a/arch/ppc/configs/mpc8540_ads_defconfig b/arch/ppc/configs/mpc8540_ads_defconfig index c5c86025e261..bf676ebd99ab 100644 --- a/arch/ppc/configs/mpc8540_ads_defconfig +++ b/arch/ppc/configs/mpc8540_ads_defconfig | |||
| @@ -452,7 +452,6 @@ CONFIG_I2C_CHARDEV=y | |||
| 452 | # CONFIG_I2C_AMD8111 is not set | 452 | # CONFIG_I2C_AMD8111 is not set |
| 453 | # CONFIG_I2C_I801 is not set | 453 | # CONFIG_I2C_I801 is not set |
| 454 | # CONFIG_I2C_I810 is not set | 454 | # CONFIG_I2C_I810 is not set |
| 455 | # CONFIG_I2C_ISA is not set | ||
| 456 | CONFIG_I2C_MPC=y | 455 | CONFIG_I2C_MPC=y |
| 457 | # CONFIG_I2C_NFORCE2 is not set | 456 | # CONFIG_I2C_NFORCE2 is not set |
| 458 | # CONFIG_I2C_PARPORT_LIGHT is not set | 457 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/mpc8548_cds_defconfig b/arch/ppc/configs/mpc8548_cds_defconfig index abe034f24b83..f36fc5db540b 100644 --- a/arch/ppc/configs/mpc8548_cds_defconfig +++ b/arch/ppc/configs/mpc8548_cds_defconfig | |||
| @@ -413,7 +413,6 @@ CONFIG_I2C_CHARDEV=y | |||
| 413 | # | 413 | # |
| 414 | # I2C Hardware Bus support | 414 | # I2C Hardware Bus support |
| 415 | # | 415 | # |
| 416 | # CONFIG_I2C_ISA is not set | ||
| 417 | CONFIG_I2C_MPC=y | 416 | CONFIG_I2C_MPC=y |
| 418 | # CONFIG_I2C_PARPORT_LIGHT is not set | 417 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| 419 | # CONFIG_I2C_PCA_ISA is not set | 418 | # CONFIG_I2C_PCA_ISA is not set |
diff --git a/arch/ppc/configs/mpc8555_cds_defconfig b/arch/ppc/configs/mpc8555_cds_defconfig index 15abebf46b96..4f1e320acfbe 100644 --- a/arch/ppc/configs/mpc8555_cds_defconfig +++ b/arch/ppc/configs/mpc8555_cds_defconfig | |||
| @@ -518,7 +518,6 @@ CONFIG_I2C_CHARDEV=y | |||
| 518 | # CONFIG_I2C_I801 is not set | 518 | # CONFIG_I2C_I801 is not set |
| 519 | # CONFIG_I2C_I810 is not set | 519 | # CONFIG_I2C_I810 is not set |
| 520 | # CONFIG_I2C_PIIX4 is not set | 520 | # CONFIG_I2C_PIIX4 is not set |
| 521 | # CONFIG_I2C_ISA is not set | ||
| 522 | CONFIG_I2C_MPC=y | 521 | CONFIG_I2C_MPC=y |
| 523 | # CONFIG_I2C_NFORCE2 is not set | 522 | # CONFIG_I2C_NFORCE2 is not set |
| 524 | # CONFIG_I2C_PARPORT_LIGHT is not set | 523 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/mpc8560_ads_defconfig b/arch/ppc/configs/mpc8560_ads_defconfig index f834fb541ad5..f12d48fcbba7 100644 --- a/arch/ppc/configs/mpc8560_ads_defconfig +++ b/arch/ppc/configs/mpc8560_ads_defconfig | |||
| @@ -489,7 +489,6 @@ CONFIG_I2C_CHARDEV=y | |||
| 489 | # CONFIG_I2C_I801 is not set | 489 | # CONFIG_I2C_I801 is not set |
| 490 | # CONFIG_I2C_I810 is not set | 490 | # CONFIG_I2C_I810 is not set |
| 491 | # CONFIG_I2C_PIIX4 is not set | 491 | # CONFIG_I2C_PIIX4 is not set |
| 492 | # CONFIG_I2C_ISA is not set | ||
| 493 | CONFIG_I2C_MPC=y | 492 | CONFIG_I2C_MPC=y |
| 494 | # CONFIG_I2C_NFORCE2 is not set | 493 | # CONFIG_I2C_NFORCE2 is not set |
| 495 | # CONFIG_I2C_PARPORT_LIGHT is not set | 494 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/radstone_ppc7d_defconfig b/arch/ppc/configs/radstone_ppc7d_defconfig index ca4d1fd0ca05..9f64532f2a81 100644 --- a/arch/ppc/configs/radstone_ppc7d_defconfig +++ b/arch/ppc/configs/radstone_ppc7d_defconfig | |||
| @@ -710,7 +710,6 @@ CONFIG_I2C_CHARDEV=y | |||
| 710 | # CONFIG_I2C_I801 is not set | 710 | # CONFIG_I2C_I801 is not set |
| 711 | # CONFIG_I2C_I810 is not set | 711 | # CONFIG_I2C_I810 is not set |
| 712 | # CONFIG_I2C_PIIX4 is not set | 712 | # CONFIG_I2C_PIIX4 is not set |
| 713 | # CONFIG_I2C_ISA is not set | ||
| 714 | # CONFIG_I2C_MPC is not set | 713 | # CONFIG_I2C_MPC is not set |
| 715 | # CONFIG_I2C_NFORCE2 is not set | 714 | # CONFIG_I2C_NFORCE2 is not set |
| 716 | # CONFIG_I2C_PARPORT_LIGHT is not set | 715 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/ppc/configs/stx_gp3_defconfig b/arch/ppc/configs/stx_gp3_defconfig index 3fedc43e44ad..70d6f842aa9b 100644 --- a/arch/ppc/configs/stx_gp3_defconfig +++ b/arch/ppc/configs/stx_gp3_defconfig | |||
| @@ -661,7 +661,6 @@ CONFIG_I2C_ALGOBIT=m | |||
| 661 | # CONFIG_I2C_I801 is not set | 661 | # CONFIG_I2C_I801 is not set |
| 662 | # CONFIG_I2C_I810 is not set | 662 | # CONFIG_I2C_I810 is not set |
| 663 | # CONFIG_I2C_PIIX4 is not set | 663 | # CONFIG_I2C_PIIX4 is not set |
| 664 | # CONFIG_I2C_ISA is not set | ||
| 665 | # CONFIG_I2C_MPC is not set | 664 | # CONFIG_I2C_MPC is not set |
| 666 | # CONFIG_I2C_NFORCE2 is not set | 665 | # CONFIG_I2C_NFORCE2 is not set |
| 667 | # CONFIG_I2C_PARPORT is not set | 666 | # CONFIG_I2C_PARPORT is not set |
diff --git a/arch/ppc/configs/sycamore_defconfig b/arch/ppc/configs/sycamore_defconfig index 758114cfea5c..6996cca18f3e 100644 --- a/arch/ppc/configs/sycamore_defconfig +++ b/arch/ppc/configs/sycamore_defconfig | |||
| @@ -461,7 +461,6 @@ CONFIG_I2C_CHARDEV=y | |||
| 461 | # CONFIG_I2C_I801 is not set | 461 | # CONFIG_I2C_I801 is not set |
| 462 | # CONFIG_I2C_I810 is not set | 462 | # CONFIG_I2C_I810 is not set |
| 463 | # CONFIG_I2C_IBM_IIC is not set | 463 | # CONFIG_I2C_IBM_IIC is not set |
| 464 | # CONFIG_I2C_ISA is not set | ||
| 465 | # CONFIG_I2C_NFORCE2 is not set | 464 | # CONFIG_I2C_NFORCE2 is not set |
| 466 | # CONFIG_I2C_PARPORT_LIGHT is not set | 465 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| 467 | # CONFIG_I2C_PIIX4 is not set | 466 | # CONFIG_I2C_PIIX4 is not set |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 13eea47dceb3..dbdca6f10e46 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -29,17 +29,34 @@ config HWMON_VID | |||
| 29 | default n | 29 | default n |
| 30 | 30 | ||
| 31 | config SENSORS_ABITUGURU | 31 | config SENSORS_ABITUGURU |
| 32 | tristate "Abit uGuru" | 32 | tristate "Abit uGuru (rev 1 & 2)" |
| 33 | depends on EXPERIMENTAL | 33 | depends on EXPERIMENTAL |
| 34 | help | 34 | help |
| 35 | If you say yes here you get support for the Abit uGuru chips | 35 | If you say yes here you get support for the sensor part of the first |
| 36 | sensor part. The voltage and frequency control parts of the Abit | 36 | and second revision of the Abit uGuru chip. The voltage and frequency |
| 37 | uGuru are not supported. The Abit uGuru chip can be found on Abit | 37 | control parts of the Abit uGuru are not supported. The Abit uGuru |
| 38 | uGuru featuring motherboards (most modern Abit motherboards). | 38 | chip can be found on Abit uGuru featuring motherboards (most modern |
| 39 | Abit motherboards from before end 2005). For more info and a list | ||
| 40 | of which motherboards have which revision see | ||
| 41 | Documentation/hwmon/abituguru | ||
| 39 | 42 | ||
| 40 | This driver can also be built as a module. If so, the module | 43 | This driver can also be built as a module. If so, the module |
| 41 | will be called abituguru. | 44 | will be called abituguru. |
| 42 | 45 | ||
| 46 | config SENSORS_ABITUGURU3 | ||
| 47 | tristate "Abit uGuru (rev 3)" | ||
| 48 | depends on HWMON && EXPERIMENTAL | ||
| 49 | help | ||
| 50 | If you say yes here you get support for the sensor part of the | ||
| 51 | third revision of the Abit uGuru chip. Only reading the sensors | ||
| 52 | and their settings is supported. The third revision of the Abit | ||
| 53 | uGuru chip can be found on recent Abit motherboards (since end | ||
| 54 | 2005). For more info and a list of which motherboards have which | ||
| 55 | revision see Documentation/hwmon/abituguru3 | ||
| 56 | |||
| 57 | This driver can also be built as a module. If so, the module | ||
| 58 | will be called abituguru3. | ||
| 59 | |||
| 43 | config SENSORS_AD7418 | 60 | config SENSORS_AD7418 |
| 44 | tristate "Analog Devices AD7416, AD7417 and AD7418" | 61 | tristate "Analog Devices AD7416, AD7417 and AD7418" |
| 45 | depends on I2C && EXPERIMENTAL | 62 | depends on I2C && EXPERIMENTAL |
| @@ -250,12 +267,10 @@ config SENSORS_CORETEMP | |||
| 250 | 267 | ||
| 251 | config SENSORS_IT87 | 268 | config SENSORS_IT87 |
| 252 | tristate "ITE IT87xx and compatibles" | 269 | tristate "ITE IT87xx and compatibles" |
| 253 | depends on I2C | ||
| 254 | select I2C_ISA | ||
| 255 | select HWMON_VID | 270 | select HWMON_VID |
| 256 | help | 271 | help |
| 257 | If you say yes here you get support for ITE IT8705F, IT8712F, | 272 | If you say yes here you get support for ITE IT8705F, IT8712F, |
| 258 | IT8716F and IT8718F sensor chips, and the SiS960 clone. | 273 | IT8716F, IT8718F and IT8726F sensor chips, and the SiS960 clone. |
| 259 | 274 | ||
| 260 | This driver can also be built as a module. If so, the module | 275 | This driver can also be built as a module. If so, the module |
| 261 | will be called it87. | 276 | will be called it87. |
| @@ -365,8 +380,8 @@ config SENSORS_LM90 | |||
| 365 | depends on I2C | 380 | depends on I2C |
| 366 | help | 381 | help |
| 367 | If you say yes here you get support for National Semiconductor LM90, | 382 | If you say yes here you get support for National Semiconductor LM90, |
| 368 | LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and | 383 | LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657, |
| 369 | MAX6658 sensor chips. | 384 | MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips. |
| 370 | 385 | ||
| 371 | The Analog Devices ADT7461 sensor chip is also supported, but only | 386 | The Analog Devices ADT7461 sensor chip is also supported, but only |
| 372 | if found in ADM1032 compatibility mode. | 387 | if found in ADM1032 compatibility mode. |
| @@ -384,6 +399,17 @@ config SENSORS_LM92 | |||
| 384 | This driver can also be built as a module. If so, the module | 399 | This driver can also be built as a module. If so, the module |
| 385 | will be called lm92. | 400 | will be called lm92. |
| 386 | 401 | ||
| 402 | config SENSORS_LM93 | ||
| 403 | tristate "National Semiconductor LM93 and compatibles" | ||
| 404 | depends on HWMON && I2C | ||
| 405 | select HWMON_VID | ||
| 406 | help | ||
| 407 | If you say yes here you get support for National Semiconductor LM93 | ||
| 408 | sensor chips. | ||
| 409 | |||
| 410 | This driver can also be built as a module. If so, the module | ||
| 411 | will be called lm93. | ||
| 412 | |||
| 387 | config SENSORS_MAX1619 | 413 | config SENSORS_MAX1619 |
| 388 | tristate "Maxim MAX1619 sensor chip" | 414 | tristate "Maxim MAX1619 sensor chip" |
| 389 | depends on I2C | 415 | depends on I2C |
| @@ -405,8 +431,6 @@ config SENSORS_MAX6650 | |||
| 405 | 431 | ||
| 406 | config SENSORS_PC87360 | 432 | config SENSORS_PC87360 |
| 407 | tristate "National Semiconductor PC87360 family" | 433 | tristate "National Semiconductor PC87360 family" |
| 408 | depends on I2C && EXPERIMENTAL | ||
| 409 | select I2C_ISA | ||
| 410 | select HWMON_VID | 434 | select HWMON_VID |
| 411 | help | 435 | help |
| 412 | If you say yes here you get access to the hardware monitoring | 436 | If you say yes here you get access to the hardware monitoring |
| @@ -433,8 +457,7 @@ config SENSORS_PC87427 | |||
| 433 | 457 | ||
| 434 | config SENSORS_SIS5595 | 458 | config SENSORS_SIS5595 |
| 435 | tristate "Silicon Integrated Systems Corp. SiS5595" | 459 | tristate "Silicon Integrated Systems Corp. SiS5595" |
| 436 | depends on I2C && PCI && EXPERIMENTAL | 460 | depends on PCI |
| 437 | select I2C_ISA | ||
| 438 | help | 461 | help |
| 439 | If you say yes here you get support for the integrated sensors in | 462 | If you say yes here you get support for the integrated sensors in |
| 440 | SiS5595 South Bridges. | 463 | SiS5595 South Bridges. |
| @@ -442,6 +465,18 @@ config SENSORS_SIS5595 | |||
| 442 | This driver can also be built as a module. If so, the module | 465 | This driver can also be built as a module. If so, the module |
| 443 | will be called sis5595. | 466 | will be called sis5595. |
| 444 | 467 | ||
| 468 | config SENSORS_DME1737 | ||
| 469 | tristate "SMSC DME1737 and compatibles" | ||
| 470 | depends on I2C && EXPERIMENTAL | ||
| 471 | select HWMON_VID | ||
| 472 | help | ||
| 473 | If you say yes here you get support for the hardware monitoring | ||
| 474 | and fan control features of the SMSC DME1737 (and compatibles | ||
| 475 | like the Asus A8000) Super-I/O chip. | ||
| 476 | |||
| 477 | This driver can also be built as a module. If so, the module | ||
| 478 | will be called dme1737. | ||
| 479 | |||
| 445 | config SENSORS_SMSC47M1 | 480 | config SENSORS_SMSC47M1 |
| 446 | tristate "SMSC LPC47M10x and compatibles" | 481 | tristate "SMSC LPC47M10x and compatibles" |
| 447 | help | 482 | help |
| @@ -487,8 +522,7 @@ config SENSORS_SMSC47B397 | |||
| 487 | 522 | ||
| 488 | config SENSORS_VIA686A | 523 | config SENSORS_VIA686A |
| 489 | tristate "VIA686A" | 524 | tristate "VIA686A" |
| 490 | depends on I2C && PCI | 525 | depends on PCI |
| 491 | select I2C_ISA | ||
| 492 | help | 526 | help |
| 493 | If you say yes here you get support for the integrated sensors in | 527 | If you say yes here you get support for the integrated sensors in |
| 494 | Via 686A/B South Bridges. | 528 | Via 686A/B South Bridges. |
| @@ -509,9 +543,8 @@ config SENSORS_VT1211 | |||
| 509 | 543 | ||
| 510 | config SENSORS_VT8231 | 544 | config SENSORS_VT8231 |
| 511 | tristate "VIA VT8231" | 545 | tristate "VIA VT8231" |
| 512 | depends on I2C && PCI && EXPERIMENTAL | 546 | depends on PCI |
| 513 | select HWMON_VID | 547 | select HWMON_VID |
| 514 | select I2C_ISA | ||
| 515 | help | 548 | help |
| 516 | If you say yes here then you get support for the integrated sensors | 549 | If you say yes here then you get support for the integrated sensors |
| 517 | in the VIA VT8231 device. | 550 | in the VIA VT8231 device. |
| @@ -584,17 +617,16 @@ config SENSORS_W83627HF | |||
| 584 | will be called w83627hf. | 617 | will be called w83627hf. |
| 585 | 618 | ||
| 586 | config SENSORS_W83627EHF | 619 | config SENSORS_W83627EHF |
| 587 | tristate "Winbond W83627EHF" | 620 | tristate "Winbond W83627EHF/DHG" |
| 588 | depends on I2C && EXPERIMENTAL | 621 | select HWMON_VID |
| 589 | select I2C_ISA | ||
| 590 | help | 622 | help |
| 591 | If you say yes here you get preliminary support for the hardware | 623 | If you say yes here you get support for the hardware |
| 592 | monitoring functionality of the Winbond W83627EHF Super-I/O chip. | 624 | monitoring functionality of the Winbond W83627EHF Super-I/O chip. |
| 593 | Only fan and temperature inputs are supported at the moment, while | ||
| 594 | the chip does much more than that. | ||
| 595 | 625 | ||
| 596 | This driver also supports the W83627EHG, which is the lead-free | 626 | This driver also supports the W83627EHG, which is the lead-free |
| 597 | version of the W83627EHF. | 627 | version of the W83627EHF, and the W83627DHG, which is a similar |
| 628 | chip suited for specific Intel processors that use PECI such as | ||
| 629 | the Core 2 Duo. | ||
| 598 | 630 | ||
| 599 | This driver can also be built as a module. If so, the module | 631 | This driver can also be built as a module. If so, the module |
| 600 | will be called w83627ehf. | 632 | will be called w83627ehf. |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index cfaf338919dd..59f81fae40a0 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
| @@ -14,6 +14,7 @@ obj-$(CONFIG_SENSORS_W83781D) += w83781d.o | |||
| 14 | obj-$(CONFIG_SENSORS_W83791D) += w83791d.o | 14 | obj-$(CONFIG_SENSORS_W83791D) += w83791d.o |
| 15 | 15 | ||
| 16 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o | 16 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o |
| 17 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o | ||
| 17 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o | 18 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o |
| 18 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o | 19 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o |
| 19 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o | 20 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o |
| @@ -25,6 +26,7 @@ obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o | |||
| 25 | obj-$(CONFIG_SENSORS_AMS) += ams/ | 26 | obj-$(CONFIG_SENSORS_AMS) += ams/ |
| 26 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 27 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
| 27 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o | 28 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o |
| 29 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o | ||
| 28 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 30 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
| 29 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | 31 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o |
| 30 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o | 32 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o |
| @@ -45,6 +47,7 @@ obj-$(CONFIG_SENSORS_LM85) += lm85.o | |||
| 45 | obj-$(CONFIG_SENSORS_LM87) += lm87.o | 47 | obj-$(CONFIG_SENSORS_LM87) += lm87.o |
| 46 | obj-$(CONFIG_SENSORS_LM90) += lm90.o | 48 | obj-$(CONFIG_SENSORS_LM90) += lm90.o |
| 47 | obj-$(CONFIG_SENSORS_LM92) += lm92.o | 49 | obj-$(CONFIG_SENSORS_LM92) += lm92.o |
| 50 | obj-$(CONFIG_SENSORS_LM93) += lm93.o | ||
| 48 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o | 51 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o |
| 49 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | 52 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o |
| 50 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 53 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index bede4d990ea6..d575ee958de5 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c | |||
| @@ -16,9 +16,9 @@ | |||
| 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 17 | */ | 17 | */ |
| 18 | /* | 18 | /* |
| 19 | This driver supports the sensor part of the custom Abit uGuru chip found | 19 | This driver supports the sensor part of the first and second revision of |
| 20 | on Abit uGuru motherboards. Note: because of lack of specs the CPU / RAM / | 20 | the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because |
| 21 | etc voltage & frequency control is not supported! | 21 | of lack of specs the CPU/RAM voltage & frequency control is not supported! |
| 22 | */ | 22 | */ |
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
| 32 | #include <linux/hwmon.h> | 32 | #include <linux/hwmon.h> |
| 33 | #include <linux/hwmon-sysfs.h> | 33 | #include <linux/hwmon-sysfs.h> |
| 34 | #include <linux/dmi.h> | ||
| 34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
| 35 | 36 | ||
| 36 | /* Banks */ | 37 | /* Banks */ |
| @@ -418,7 +419,7 @@ static int __devinit | |||
| 418 | abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | 419 | abituguru_detect_bank1_sensor_type(struct abituguru_data *data, |
| 419 | u8 sensor_addr) | 420 | u8 sensor_addr) |
| 420 | { | 421 | { |
| 421 | u8 val, buf[3]; | 422 | u8 val, test_flag, buf[3]; |
| 422 | int i, ret = -ENODEV; /* error is the most common used retval :| */ | 423 | int i, ret = -ENODEV; /* error is the most common used retval :| */ |
| 423 | 424 | ||
| 424 | /* If overriden by the user return the user selected type */ | 425 | /* If overriden by the user return the user selected type */ |
| @@ -436,7 +437,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | |||
| 436 | return -ENODEV; | 437 | return -ENODEV; |
| 437 | 438 | ||
| 438 | /* Test val is sane / usable for sensor type detection. */ | 439 | /* Test val is sane / usable for sensor type detection. */ |
| 439 | if ((val < 10u) || (val > 240u)) { | 440 | if ((val < 10u) || (val > 250u)) { |
| 440 | printk(KERN_WARNING ABIT_UGURU_NAME | 441 | printk(KERN_WARNING ABIT_UGURU_NAME |
| 441 | ": bank1-sensor: %d reading (%d) too close to limits, " | 442 | ": bank1-sensor: %d reading (%d) too close to limits, " |
| 442 | "unable to determine sensor type, skipping sensor\n", | 443 | "unable to determine sensor type, skipping sensor\n", |
| @@ -449,10 +450,20 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | |||
| 449 | 450 | ||
| 450 | ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); | 451 | ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); |
| 451 | /* Volt sensor test, enable volt low alarm, set min value ridicously | 452 | /* Volt sensor test, enable volt low alarm, set min value ridicously |
| 452 | high. If its a volt sensor this should always give us an alarm. */ | 453 | high, or vica versa if the reading is very high. If its a volt |
| 453 | buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; | 454 | sensor this should always give us an alarm. */ |
| 454 | buf[1] = 245; | 455 | if (val <= 240u) { |
| 455 | buf[2] = 250; | 456 | buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; |
| 457 | buf[1] = 245; | ||
| 458 | buf[2] = 250; | ||
| 459 | test_flag = ABIT_UGURU_VOLT_LOW_ALARM_FLAG; | ||
| 460 | } else { | ||
| 461 | buf[0] = ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE; | ||
| 462 | buf[1] = 5; | ||
| 463 | buf[2] = 10; | ||
| 464 | test_flag = ABIT_UGURU_VOLT_HIGH_ALARM_FLAG; | ||
| 465 | } | ||
| 466 | |||
| 456 | if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, | 467 | if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, |
| 457 | buf, 3) != 3) | 468 | buf, 3) != 3) |
| 458 | goto abituguru_detect_bank1_sensor_type_exit; | 469 | goto abituguru_detect_bank1_sensor_type_exit; |
| @@ -469,13 +480,13 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | |||
| 469 | sensor_addr, buf, 3, | 480 | sensor_addr, buf, 3, |
| 470 | ABIT_UGURU_MAX_RETRIES) != 3) | 481 | ABIT_UGURU_MAX_RETRIES) != 3) |
| 471 | goto abituguru_detect_bank1_sensor_type_exit; | 482 | goto abituguru_detect_bank1_sensor_type_exit; |
| 472 | if (buf[0] & ABIT_UGURU_VOLT_LOW_ALARM_FLAG) { | 483 | if (buf[0] & test_flag) { |
| 473 | ABIT_UGURU_DEBUG(2, " found volt sensor\n"); | 484 | ABIT_UGURU_DEBUG(2, " found volt sensor\n"); |
| 474 | ret = ABIT_UGURU_IN_SENSOR; | 485 | ret = ABIT_UGURU_IN_SENSOR; |
| 475 | goto abituguru_detect_bank1_sensor_type_exit; | 486 | goto abituguru_detect_bank1_sensor_type_exit; |
| 476 | } else | 487 | } else |
| 477 | ABIT_UGURU_DEBUG(2, " alarm raised during volt " | 488 | ABIT_UGURU_DEBUG(2, " alarm raised during volt " |
| 478 | "sensor test, but volt low flag not set\n"); | 489 | "sensor test, but volt range flag not set\n"); |
| 479 | } else | 490 | } else |
| 480 | ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " | 491 | ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " |
| 481 | "test\n"); | 492 | "test\n"); |
| @@ -1287,6 +1298,7 @@ abituguru_probe_error: | |||
| 1287 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) | 1298 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) |
| 1288 | device_remove_file(&pdev->dev, | 1299 | device_remove_file(&pdev->dev, |
| 1289 | &abituguru_sysfs_attr[i].dev_attr); | 1300 | &abituguru_sysfs_attr[i].dev_attr); |
| 1301 | platform_set_drvdata(pdev, NULL); | ||
| 1290 | kfree(data); | 1302 | kfree(data); |
| 1291 | return res; | 1303 | return res; |
| 1292 | } | 1304 | } |
| @@ -1296,13 +1308,13 @@ static int __devexit abituguru_remove(struct platform_device *pdev) | |||
| 1296 | int i; | 1308 | int i; |
| 1297 | struct abituguru_data *data = platform_get_drvdata(pdev); | 1309 | struct abituguru_data *data = platform_get_drvdata(pdev); |
| 1298 | 1310 | ||
| 1299 | platform_set_drvdata(pdev, NULL); | ||
| 1300 | hwmon_device_unregister(data->class_dev); | 1311 | hwmon_device_unregister(data->class_dev); |
| 1301 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | 1312 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) |
| 1302 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | 1313 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); |
| 1303 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) | 1314 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) |
| 1304 | device_remove_file(&pdev->dev, | 1315 | device_remove_file(&pdev->dev, |
| 1305 | &abituguru_sysfs_attr[i].dev_attr); | 1316 | &abituguru_sysfs_attr[i].dev_attr); |
| 1317 | platform_set_drvdata(pdev, NULL); | ||
| 1306 | kfree(data); | 1318 | kfree(data); |
| 1307 | 1319 | ||
| 1308 | return 0; | 1320 | return 0; |
| @@ -1436,6 +1448,15 @@ static int __init abituguru_init(void) | |||
| 1436 | int address, err; | 1448 | int address, err; |
| 1437 | struct resource res = { .flags = IORESOURCE_IO }; | 1449 | struct resource res = { .flags = IORESOURCE_IO }; |
| 1438 | 1450 | ||
| 1451 | #ifdef CONFIG_DMI | ||
| 1452 | char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | ||
| 1453 | |||
| 1454 | /* safety check, refuse to load on non Abit motherboards */ | ||
| 1455 | if (!force && (!board_vendor || | ||
| 1456 | strcmp(board_vendor, "http://www.abit.com.tw/"))) | ||
| 1457 | return -ENODEV; | ||
| 1458 | #endif | ||
| 1459 | |||
| 1439 | address = abituguru_detect(); | 1460 | address = abituguru_detect(); |
| 1440 | if (address < 0) | 1461 | if (address < 0) |
| 1441 | return address; | 1462 | return address; |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c new file mode 100644 index 000000000000..a003d104ca45 --- /dev/null +++ b/drivers/hwmon/abituguru3.c | |||
| @@ -0,0 +1,1140 @@ | |||
| 1 | /* | ||
| 2 | abituguru3.c Copyright (c) 2006 Hans de Goede <j.w.r.degoede@hhs.nl> | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 17 | */ | ||
| 18 | /* | ||
| 19 | This driver supports the sensor part of revision 3 of the custom Abit uGuru | ||
| 20 | chip found on newer Abit uGuru motherboards. Note: because of lack of specs | ||
| 21 | only reading the sensors and their settings is supported. | ||
| 22 | */ | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <linux/jiffies.h> | ||
| 27 | #include <linux/mutex.h> | ||
| 28 | #include <linux/err.h> | ||
| 29 | #include <linux/delay.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/hwmon.h> | ||
| 32 | #include <linux/hwmon-sysfs.h> | ||
| 33 | #include <asm/io.h> | ||
| 34 | |||
| 35 | /* uGuru3 bank addresses */ | ||
| 36 | #define ABIT_UGURU3_SETTINGS_BANK 0x01 | ||
| 37 | #define ABIT_UGURU3_SENSORS_BANK 0x08 | ||
| 38 | #define ABIT_UGURU3_MISC_BANK 0x09 | ||
| 39 | #define ABIT_UGURU3_ALARMS_START 0x1E | ||
| 40 | #define ABIT_UGURU3_SETTINGS_START 0x24 | ||
| 41 | #define ABIT_UGURU3_VALUES_START 0x80 | ||
| 42 | #define ABIT_UGURU3_BOARD_ID 0x0A | ||
| 43 | /* uGuru3 sensor bank flags */ /* Alarm if: */ | ||
| 44 | #define ABIT_UGURU3_TEMP_HIGH_ALARM_ENABLE 0x01 /* temp over warn */ | ||
| 45 | #define ABIT_UGURU3_VOLT_HIGH_ALARM_ENABLE 0x02 /* volt over max */ | ||
| 46 | #define ABIT_UGURU3_VOLT_LOW_ALARM_ENABLE 0x04 /* volt under min */ | ||
| 47 | #define ABIT_UGURU3_TEMP_HIGH_ALARM_FLAG 0x10 /* temp is over warn */ | ||
| 48 | #define ABIT_UGURU3_VOLT_HIGH_ALARM_FLAG 0x20 /* volt is over max */ | ||
| 49 | #define ABIT_UGURU3_VOLT_LOW_ALARM_FLAG 0x40 /* volt is under min */ | ||
| 50 | #define ABIT_UGURU3_FAN_LOW_ALARM_ENABLE 0x01 /* fan under min */ | ||
| 51 | #define ABIT_UGURU3_BEEP_ENABLE 0x08 /* beep if alarm */ | ||
| 52 | #define ABIT_UGURU3_SHUTDOWN_ENABLE 0x80 /* shutdown if alarm */ | ||
| 53 | /* sensor types */ | ||
| 54 | #define ABIT_UGURU3_IN_SENSOR 0 | ||
| 55 | #define ABIT_UGURU3_TEMP_SENSOR 1 | ||
| 56 | #define ABIT_UGURU3_FAN_SENSOR 2 | ||
| 57 | |||
| 58 | /* Timeouts / Retries, if these turn out to need a lot of fiddling we could | ||
| 59 | convert them to params. Determined by trial and error. I assume this is | ||
| 60 | cpu-speed independent, since the ISA-bus and not the CPU should be the | ||
| 61 | bottleneck. */ | ||
| 62 | #define ABIT_UGURU3_WAIT_TIMEOUT 250 | ||
| 63 | /* Normally the 0xAC at the end of synchronize() is reported after the | ||
| 64 | first read, but sometimes not and we need to poll */ | ||
| 65 | #define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT 5 | ||
| 66 | /* utility macros */ | ||
| 67 | #define ABIT_UGURU3_NAME "abituguru3" | ||
| 68 | #define ABIT_UGURU3_DEBUG(format, arg...) \ | ||
| 69 | if (verbose) \ | ||
| 70 | printk(KERN_DEBUG ABIT_UGURU3_NAME ": " format , ## arg) | ||
| 71 | |||
| 72 | /* Macros to help calculate the sysfs_names array length */ | ||
| 73 | #define ABIT_UGURU3_MAX_NO_SENSORS 26 | ||
| 74 | /* sum of strlen +1 of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, | ||
| 75 | in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0, in??_label\0 */ | ||
| 76 | #define ABIT_UGURU3_IN_NAMES_LENGTH (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14 + 11) | ||
| 77 | /* sum of strlen +1 of: temp??_input\0, temp??_max\0, temp??_crit\0, | ||
| 78 | temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0, | ||
| 79 | temp??_label\0 */ | ||
| 80 | #define ABIT_UGURU3_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16 + 13) | ||
| 81 | /* sum of strlen +1 of: fan??_input\0, fan??_min\0, fan??_alarm\0, | ||
| 82 | fan??_alarm_enable\0, fan??_beep\0, fan??_shutdown\0, fan??_label\0 */ | ||
| 83 | #define ABIT_UGURU3_FAN_NAMES_LENGTH (12 + 10 + 12 + 19 + 11 + 15 + 12) | ||
| 84 | /* Worst case scenario 16 in sensors (longest names_length) and the rest | ||
| 85 | temp sensors (second longest names_length). */ | ||
| 86 | #define ABIT_UGURU3_SYSFS_NAMES_LENGTH (16 * ABIT_UGURU3_IN_NAMES_LENGTH + \ | ||
| 87 | (ABIT_UGURU3_MAX_NO_SENSORS - 16) * ABIT_UGURU3_TEMP_NAMES_LENGTH) | ||
| 88 | |||
| 89 | /* All the macros below are named identical to the openguru2 program | ||
| 90 | reverse engineered by Louis Kruger, hence the names might not be 100% | ||
| 91 | logical. I could come up with better names, but I prefer keeping the names | ||
| 92 | identical so that this driver can be compared with his work more easily. */ | ||
| 93 | /* Two i/o-ports are used by uGuru */ | ||
| 94 | #define ABIT_UGURU3_BASE 0x00E0 | ||
| 95 | #define ABIT_UGURU3_CMD 0x00 | ||
| 96 | #define ABIT_UGURU3_DATA 0x04 | ||
| 97 | #define ABIT_UGURU3_REGION_LENGTH 5 | ||
| 98 | /* The wait_xxx functions return this on success and the last contents | ||
| 99 | of the DATA register (0-255) on failure. */ | ||
| 100 | #define ABIT_UGURU3_SUCCESS -1 | ||
| 101 | /* uGuru status flags */ | ||
| 102 | #define ABIT_UGURU3_STATUS_READY_FOR_READ 0x01 | ||
| 103 | #define ABIT_UGURU3_STATUS_BUSY 0x02 | ||
| 104 | |||
| 105 | |||
| 106 | /* Structures */ | ||
| 107 | struct abituguru3_sensor_info { | ||
| 108 | const char* name; | ||
| 109 | int port; | ||
| 110 | int type; | ||
| 111 | int multiplier; | ||
| 112 | int divisor; | ||
| 113 | int offset; | ||
| 114 | }; | ||
| 115 | |||
| 116 | struct abituguru3_motherboard_info { | ||
| 117 | u16 id; | ||
| 118 | const char *name; | ||
| 119 | /* + 1 -> end of sensors indicated by a sensor with name == NULL */ | ||
| 120 | struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; | ||
| 121 | }; | ||
| 122 | |||
| 123 | /* For the Abit uGuru, we need to keep some data in memory. | ||
| 124 | The structure is dynamically allocated, at the same time when a new | ||
| 125 | abituguru3 device is allocated. */ | ||
| 126 | struct abituguru3_data { | ||
| 127 | struct class_device *class_dev; /* hwmon registered device */ | ||
| 128 | struct mutex update_lock; /* protect access to data and uGuru */ | ||
| 129 | unsigned short addr; /* uguru base address */ | ||
| 130 | char valid; /* !=0 if following fields are valid */ | ||
| 131 | unsigned long last_updated; /* In jiffies */ | ||
| 132 | |||
| 133 | /* For convenience the sysfs attr and their names are generated | ||
| 134 | automatically. We have max 10 entries per sensor (for in sensors) */ | ||
| 135 | struct sensor_device_attribute_2 sysfs_attr[ABIT_UGURU3_MAX_NO_SENSORS | ||
| 136 | * 10]; | ||
| 137 | |||
| 138 | /* Buffer to store the dynamically generated sysfs names */ | ||
| 139 | char sysfs_names[ABIT_UGURU3_SYSFS_NAMES_LENGTH]; | ||
| 140 | |||
| 141 | /* Pointer to the sensors info for the detected motherboard */ | ||
| 142 | const struct abituguru3_sensor_info *sensors; | ||
| 143 | |||
| 144 | /* The abituguru3 supports upto 48 sensors, and thus has registers | ||
| 145 | sets for 48 sensors, for convienence reasons / simplicity of the | ||
| 146 | code we always read and store all registers for all 48 sensors */ | ||
| 147 | |||
| 148 | /* Alarms for all 48 sensors (1 bit per sensor) */ | ||
| 149 | u8 alarms[48/8]; | ||
| 150 | |||
| 151 | /* Value of all 48 sensors */ | ||
| 152 | u8 value[48]; | ||
| 153 | |||
| 154 | /* Settings of all 48 sensors, note in and temp sensors (the first 32 | ||
| 155 | sensors) have 3 bytes of settings, while fans only have 2 bytes, | ||
| 156 | for convenience we use 3 bytes for all sensors */ | ||
| 157 | u8 settings[48][3]; | ||
| 158 | }; | ||
| 159 | |||
| 160 | |||
| 161 | /* Constants */ | ||
| 162 | static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | ||
| 163 | { 0x000C, "unknown", { | ||
| 164 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 165 | { "DDR", 1, 0, 10, 1, 0 }, | ||
| 166 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 167 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
| 168 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
| 169 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
| 170 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
| 171 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 172 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 173 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 174 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 175 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 176 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 177 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 178 | { "PWM", 26, 1, 1, 1, 0 }, | ||
| 179 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 180 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 181 | { "SYS FAN", 34, 2, 60, 1, 0 }, | ||
| 182 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
| 183 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 184 | }, | ||
| 185 | { 0x000D, "Abit AW8", { | ||
| 186 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 187 | { "DDR", 1, 0, 10, 1, 0 }, | ||
| 188 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 189 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
| 190 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
| 191 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
| 192 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
| 193 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 194 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 195 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 196 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 197 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 198 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 199 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 200 | { "PWM1", 26, 1, 1, 1, 0 }, | ||
| 201 | { "PWM2", 27, 1, 1, 1, 0 }, | ||
| 202 | { "PWM3", 28, 1, 1, 1, 0 }, | ||
| 203 | { "PWM4", 29, 1, 1, 1, 0 }, | ||
| 204 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 205 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 206 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 207 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
| 208 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | ||
| 209 | { "AUX3 Fan", 37, 2, 60, 1, 0 }, | ||
| 210 | { "AUX4 Fan", 38, 2, 60, 1, 0 }, | ||
| 211 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | ||
| 212 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 213 | }, | ||
| 214 | { 0x000E, "AL-8", { | ||
| 215 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 216 | { "DDR", 1, 0, 10, 1, 0 }, | ||
| 217 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 218 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
| 219 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
| 220 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
| 221 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
| 222 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 223 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 224 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 225 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 226 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 227 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 228 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 229 | { "PWM", 26, 1, 1, 1, 0 }, | ||
| 230 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 231 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 232 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 233 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 234 | }, | ||
| 235 | { 0x000F, "unknown", { | ||
| 236 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 237 | { "DDR", 1, 0, 10, 1, 0 }, | ||
| 238 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 239 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
| 240 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
| 241 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
| 242 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
| 243 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 244 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 245 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 246 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 247 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 248 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 249 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 250 | { "PWM", 26, 1, 1, 1, 0 }, | ||
| 251 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 252 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 253 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 254 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 255 | }, | ||
| 256 | { 0x0010, "Abit NI8 SLI GR", { | ||
| 257 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 258 | { "DDR", 1, 0, 10, 1, 0 }, | ||
| 259 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 260 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
| 261 | { "NB 1.4V", 4, 0, 10, 1, 0 }, | ||
| 262 | { "SB 1.5V", 6, 0, 10, 1, 0 }, | ||
| 263 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 264 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 265 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 266 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 267 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 268 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 269 | { "SYS", 25, 1, 1, 1, 0 }, | ||
| 270 | { "PWM", 26, 1, 1, 1, 0 }, | ||
| 271 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 272 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 273 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 274 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
| 275 | { "OTES1 Fan", 36, 2, 60, 1, 0 }, | ||
| 276 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 277 | }, | ||
| 278 | { 0x0011, "Abit AT8 32X", { | ||
| 279 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 280 | { "DDR", 1, 0, 20, 1, 0 }, | ||
| 281 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 282 | { "CPU VDDA 2.5V", 6, 0, 20, 1, 0 }, | ||
| 283 | { "NB 1.8V", 4, 0, 10, 1, 0 }, | ||
| 284 | { "NB 1.8V Dual", 5, 0, 10, 1, 0 }, | ||
| 285 | { "HTV 1.2", 3, 0, 10, 1, 0 }, | ||
| 286 | { "PCIE 1.2V", 12, 0, 10, 1, 0 }, | ||
| 287 | { "NB 1.2V", 13, 0, 10, 1, 0 }, | ||
| 288 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 289 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 290 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 291 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 292 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 293 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 294 | { "NB", 25, 1, 1, 1, 0 }, | ||
| 295 | { "System", 26, 1, 1, 1, 0 }, | ||
| 296 | { "PWM", 27, 1, 1, 1, 0 }, | ||
| 297 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 298 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 299 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 300 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
| 301 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | ||
| 302 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 303 | }, | ||
| 304 | { 0x0012, "Abit AN8 32X", { | ||
| 305 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 306 | { "DDR", 1, 0, 20, 1, 0 }, | ||
| 307 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 308 | { "HyperTransport", 3, 0, 10, 1, 0 }, | ||
| 309 | { "CPU VDDA 2.5V", 5, 0, 20, 1, 0 }, | ||
| 310 | { "NB", 4, 0, 10, 1, 0 }, | ||
| 311 | { "SB", 6, 0, 10, 1, 0 }, | ||
| 312 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 313 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 314 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 315 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 316 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 317 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 318 | { "SYS", 25, 1, 1, 1, 0 }, | ||
| 319 | { "PWM", 26, 1, 1, 1, 0 }, | ||
| 320 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 321 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 322 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 323 | { "AUX1 Fan", 36, 2, 60, 1, 0 }, | ||
| 324 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 325 | }, | ||
| 326 | { 0x0013, "unknown", { | ||
| 327 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 328 | { "DDR", 1, 0, 10, 1, 0 }, | ||
| 329 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 330 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
| 331 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
| 332 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
| 333 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
| 334 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 335 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 336 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 337 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 338 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 339 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 340 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 341 | { "PWM1", 26, 1, 1, 1, 0 }, | ||
| 342 | { "PWM2", 27, 1, 1, 1, 0 }, | ||
| 343 | { "PWM3", 28, 1, 1, 1, 0 }, | ||
| 344 | { "PWM4", 29, 1, 1, 1, 0 }, | ||
| 345 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 346 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 347 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 348 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
| 349 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | ||
| 350 | { "AUX3 Fan", 37, 2, 60, 1, 0 }, | ||
| 351 | { "AUX4 Fan", 38, 2, 60, 1, 0 }, | ||
| 352 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 353 | }, | ||
| 354 | { 0x0014, "Abit AB9 Pro", { | ||
| 355 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 356 | { "DDR", 1, 0, 10, 1, 0 }, | ||
| 357 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 358 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
| 359 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
| 360 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
| 361 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
| 362 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 363 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 364 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 365 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 366 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 367 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 368 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 369 | { "PWM", 26, 1, 1, 1, 0 }, | ||
| 370 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 371 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 372 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 373 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 374 | }, | ||
| 375 | { 0x0015, "unknown", { | ||
| 376 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 377 | { "DDR", 1, 0, 20, 1, 0 }, | ||
| 378 | { "DDR VTT", 2, 0, 10, 1, 0 }, | ||
| 379 | { "HyperTransport", 3, 0, 10, 1, 0 }, | ||
| 380 | { "CPU VDDA 2.5V", 5, 0, 20, 1, 0 }, | ||
| 381 | { "NB", 4, 0, 10, 1, 0 }, | ||
| 382 | { "SB", 6, 0, 10, 1, 0 }, | ||
| 383 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 384 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 385 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 386 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 387 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 388 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 389 | { "SYS", 25, 1, 1, 1, 0 }, | ||
| 390 | { "PWM", 26, 1, 1, 1, 0 }, | ||
| 391 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 392 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 393 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 394 | { "AUX1 Fan", 33, 2, 60, 1, 0 }, | ||
| 395 | { "AUX2 Fan", 35, 2, 60, 1, 0 }, | ||
| 396 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | ||
| 397 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 398 | }, | ||
| 399 | { 0x0016, "AW9D-MAX", { | ||
| 400 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 401 | { "DDR2", 1, 0, 20, 1, 0 }, | ||
| 402 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | ||
| 403 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
| 404 | { "MCH & PCIE 1.5V", 4, 0, 10, 1, 0 }, | ||
| 405 | { "MCH 2.5V", 5, 0, 20, 1, 0 }, | ||
| 406 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
| 407 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 408 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 409 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 410 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 411 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 412 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 413 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 414 | { "PWM1", 26, 1, 1, 1, 0 }, | ||
| 415 | { "PWM2", 27, 1, 1, 1, 0 }, | ||
| 416 | { "PWM3", 28, 1, 1, 1, 0 }, | ||
| 417 | { "PWM4", 29, 1, 1, 1, 0 }, | ||
| 418 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 419 | { "NB Fan", 33, 2, 60, 1, 0 }, | ||
| 420 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 421 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | ||
| 422 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | ||
| 423 | { "AUX3 Fan", 37, 2, 60, 1, 0 }, | ||
| 424 | { "OTES1 Fan", 38, 2, 60, 1, 0 }, | ||
| 425 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 426 | }, | ||
| 427 | { 0x0017, "unknown", { | ||
| 428 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 429 | { "DDR2", 1, 0, 20, 1, 0 }, | ||
| 430 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | ||
| 431 | { "HyperTransport", 3, 0, 10, 1, 0 }, | ||
| 432 | { "CPU VDDA 2.5V", 6, 0, 20, 1, 0 }, | ||
| 433 | { "NB 1.8V", 4, 0, 10, 1, 0 }, | ||
| 434 | { "NB 1.2V ", 13, 0, 10, 1, 0 }, | ||
| 435 | { "SB 1.2V", 5, 0, 10, 1, 0 }, | ||
| 436 | { "PCIE 1.2V", 12, 0, 10, 1, 0 }, | ||
| 437 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 438 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 439 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 440 | { "ATX +3.3V", 10, 0, 20, 1, 0 }, | ||
| 441 | { "ATX 5VSB", 11, 0, 30, 1, 0 }, | ||
| 442 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 443 | { "System ", 26, 1, 1, 1, 0 }, | ||
| 444 | { "PWM", 27, 1, 1, 1, 0 }, | ||
| 445 | { "CPU FAN", 32, 2, 60, 1, 0 }, | ||
| 446 | { "SYS FAN", 34, 2, 60, 1, 0 }, | ||
| 447 | { "AUX1 FAN", 35, 2, 60, 1, 0 }, | ||
| 448 | { "AUX2 FAN", 36, 2, 60, 1, 0 }, | ||
| 449 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, | ||
| 450 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 451 | }, | ||
| 452 | { 0x0018, "unknown", { | ||
| 453 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 454 | { "DDR2", 1, 0, 20, 1, 0 }, | ||
| 455 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | ||
| 456 | { "CPU VTT", 3, 0, 10, 1, 0 }, | ||
| 457 | { "MCH 1.25V", 4, 0, 10, 1, 0 }, | ||
| 458 | { "ICHIO 1.5V", 5, 0, 10, 1, 0 }, | ||
| 459 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
| 460 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 461 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 462 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 463 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 464 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 465 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 466 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 467 | { "PWM Phase1", 26, 1, 1, 1, 0 }, | ||
| 468 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | ||
| 469 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | ||
| 470 | { "PWM Phase4", 29, 1, 1, 1, 0 }, | ||
| 471 | { "PWM Phase5", 30, 1, 1, 1, 0 }, | ||
| 472 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 473 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 474 | { "AUX1 Fan", 33, 2, 60, 1, 0 }, | ||
| 475 | { "AUX2 Fan", 35, 2, 60, 1, 0 }, | ||
| 476 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | ||
| 477 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 478 | }, | ||
| 479 | { 0x0019, "unknown", { | ||
| 480 | { "CPU Core", 7, 0, 10, 1, 0 }, | ||
| 481 | { "DDR2", 13, 0, 20, 1, 0 }, | ||
| 482 | { "DDR2 VTT", 14, 0, 10, 1, 0 }, | ||
| 483 | { "CPU VTT", 3, 0, 20, 1, 0 }, | ||
| 484 | { "NB 1.2V ", 4, 0, 10, 1, 0 }, | ||
| 485 | { "SB 1.5V", 6, 0, 10, 1, 0 }, | ||
| 486 | { "HyperTransport", 5, 0, 10, 1, 0 }, | ||
| 487 | { "ATX +12V (24-Pin)", 12, 0, 60, 1, 0 }, | ||
| 488 | { "ATX +12V (4-pin)", 8, 0, 60, 1, 0 }, | ||
| 489 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 490 | { "ATX +3.3V", 10, 0, 20, 1, 0 }, | ||
| 491 | { "ATX 5VSB", 11, 0, 30, 1, 0 }, | ||
| 492 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 493 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 494 | { "PWM Phase1", 26, 1, 1, 1, 0 }, | ||
| 495 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | ||
| 496 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | ||
| 497 | { "PWM Phase4", 29, 1, 1, 1, 0 }, | ||
| 498 | { "PWM Phase5", 30, 1, 1, 1, 0 }, | ||
| 499 | { "CPU FAN", 32, 2, 60, 1, 0 }, | ||
| 500 | { "SYS FAN", 34, 2, 60, 1, 0 }, | ||
| 501 | { "AUX1 FAN", 33, 2, 60, 1, 0 }, | ||
| 502 | { "AUX2 FAN", 35, 2, 60, 1, 0 }, | ||
| 503 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, | ||
| 504 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 505 | }, | ||
| 506 | { 0x001A, "unknown", { | ||
| 507 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
| 508 | { "DDR2", 1, 0, 20, 1, 0 }, | ||
| 509 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | ||
| 510 | { "CPU VTT 1.2V", 3, 0, 10, 1, 0 }, | ||
| 511 | { "MCH 1.25V", 4, 0, 10, 1, 0 }, | ||
| 512 | { "ICHIO 1.5V", 5, 0, 10, 1, 0 }, | ||
| 513 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
| 514 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
| 515 | { "ATX +12V (8-pin)", 8, 0, 60, 1, 0 }, | ||
| 516 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
| 517 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
| 518 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
| 519 | { "CPU", 24, 1, 1, 1, 0 }, | ||
| 520 | { "System ", 25, 1, 1, 1, 0 }, | ||
| 521 | { "PWM ", 26, 1, 1, 1, 0 }, | ||
| 522 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | ||
| 523 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | ||
| 524 | { "PWM Phase4", 29, 1, 1, 1, 0 }, | ||
| 525 | { "PWM Phase5", 30, 1, 1, 1, 0 }, | ||
| 526 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
| 527 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
| 528 | { "AUX1 Fan", 33, 2, 60, 1, 0 }, | ||
| 529 | { "AUX2 Fan", 35, 2, 60, 1, 0 }, | ||
| 530 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | ||
| 531 | { NULL, 0, 0, 0, 0, 0 } } | ||
| 532 | }, | ||
| 533 | { 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } } | ||
| 534 | }; | ||
| 535 | |||
| 536 | |||
| 537 | /* Insmod parameters */ | ||
| 538 | static int force; | ||
| 539 | module_param(force, bool, 0); | ||
| 540 | MODULE_PARM_DESC(force, "Set to one to force detection."); | ||
| 541 | /* Default verbose is 1, since this driver is still in the testing phase */ | ||
| 542 | static int verbose = 1; | ||
| 543 | module_param(verbose, bool, 0644); | ||
| 544 | MODULE_PARM_DESC(verbose, "Enable/disable verbose error reporting"); | ||
| 545 | |||
| 546 | |||
| 547 | /* wait while the uguru is busy (usually after a write) */ | ||
| 548 | static int abituguru3_wait_while_busy(struct abituguru3_data *data) | ||
| 549 | { | ||
| 550 | u8 x; | ||
| 551 | int timeout = ABIT_UGURU3_WAIT_TIMEOUT; | ||
| 552 | |||
| 553 | while ((x = inb_p(data->addr + ABIT_UGURU3_DATA)) & | ||
| 554 | ABIT_UGURU3_STATUS_BUSY) { | ||
| 555 | timeout--; | ||
| 556 | if (timeout == 0) | ||
| 557 | return x; | ||
| 558 | /* sleep a bit before our last try, to give the uGuru3 one | ||
| 559 | last chance to respond. */ | ||
| 560 | if (timeout == 1) | ||
| 561 | msleep(1); | ||
| 562 | } | ||
| 563 | return ABIT_UGURU3_SUCCESS; | ||
| 564 | } | ||
| 565 | |||
| 566 | /* wait till uguru is ready to be read */ | ||
| 567 | static int abituguru3_wait_for_read(struct abituguru3_data *data) | ||
| 568 | { | ||
| 569 | u8 x; | ||
| 570 | int timeout = ABIT_UGURU3_WAIT_TIMEOUT; | ||
| 571 | |||
| 572 | while (!((x = inb_p(data->addr + ABIT_UGURU3_DATA)) & | ||
| 573 | ABIT_UGURU3_STATUS_READY_FOR_READ)) { | ||
| 574 | timeout--; | ||
| 575 | if (timeout == 0) | ||
| 576 | return x; | ||
| 577 | /* sleep a bit before our last try, to give the uGuru3 one | ||
| 578 | last chance to respond. */ | ||
| 579 | if (timeout == 1) | ||
| 580 | msleep(1); | ||
| 581 | } | ||
| 582 | return ABIT_UGURU3_SUCCESS; | ||
| 583 | } | ||
| 584 | |||
| 585 | /* This synchronizes us with the uGuru3's protocol state machine, this | ||
| 586 | must be done before each command. */ | ||
| 587 | static int abituguru3_synchronize(struct abituguru3_data *data) | ||
| 588 | { | ||
| 589 | int x, timeout = ABIT_UGURU3_SYNCHRONIZE_TIMEOUT; | ||
| 590 | |||
| 591 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
| 592 | ABIT_UGURU3_DEBUG("synchronize timeout during initial busy " | ||
| 593 | "wait, status: 0x%02x\n", x); | ||
| 594 | return -EIO; | ||
| 595 | } | ||
| 596 | |||
| 597 | outb(0x20, data->addr + ABIT_UGURU3_DATA); | ||
| 598 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
| 599 | ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x20, " | ||
| 600 | "status: 0x%02x\n", x); | ||
| 601 | return -EIO; | ||
| 602 | } | ||
| 603 | |||
| 604 | outb(0x10, data->addr + ABIT_UGURU3_CMD); | ||
| 605 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
| 606 | ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x10, " | ||
| 607 | "status: 0x%02x\n", x); | ||
| 608 | return -EIO; | ||
| 609 | } | ||
| 610 | |||
| 611 | outb(0x00, data->addr + ABIT_UGURU3_CMD); | ||
| 612 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
| 613 | ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x00, " | ||
| 614 | "status: 0x%02x\n", x); | ||
| 615 | return -EIO; | ||
| 616 | } | ||
| 617 | |||
| 618 | if ((x = abituguru3_wait_for_read(data)) != ABIT_UGURU3_SUCCESS) { | ||
| 619 | ABIT_UGURU3_DEBUG("synchronize timeout waiting for read, " | ||
| 620 | "status: 0x%02x\n", x); | ||
| 621 | return -EIO; | ||
| 622 | } | ||
| 623 | |||
| 624 | while ((x = inb(data->addr + ABIT_UGURU3_CMD)) != 0xAC) { | ||
| 625 | timeout--; | ||
| 626 | if (timeout == 0) { | ||
| 627 | ABIT_UGURU3_DEBUG("synchronize timeout cmd does not " | ||
| 628 | "hold 0xAC after synchronize, cmd: 0x%02x\n", | ||
| 629 | x); | ||
| 630 | return -EIO; | ||
| 631 | } | ||
| 632 | msleep(1); | ||
| 633 | } | ||
| 634 | return 0; | ||
| 635 | } | ||
| 636 | |||
| 637 | /* Read count bytes from sensor sensor_addr in bank bank_addr and store the | ||
| 638 | result in buf */ | ||
| 639 | static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset, | ||
| 640 | u8 count, u8 *buf) | ||
| 641 | { | ||
| 642 | int i, x; | ||
| 643 | |||
| 644 | if ((x = abituguru3_synchronize(data))) | ||
| 645 | return x; | ||
| 646 | |||
| 647 | outb(0x1A, data->addr + ABIT_UGURU3_DATA); | ||
| 648 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
| 649 | ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " | ||
| 650 | "sending 0x1A, status: 0x%02x\n", (unsigned int)bank, | ||
| 651 | (unsigned int)offset, x); | ||
| 652 | return -EIO; | ||
| 653 | } | ||
| 654 | |||
| 655 | outb(bank, data->addr + ABIT_UGURU3_CMD); | ||
| 656 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
| 657 | ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " | ||
| 658 | "sending the bank, status: 0x%02x\n", | ||
| 659 | (unsigned int)bank, (unsigned int)offset, x); | ||
| 660 | return -EIO; | ||
| 661 | } | ||
| 662 | |||
| 663 | outb(offset, data->addr + ABIT_UGURU3_CMD); | ||
| 664 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
| 665 | ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " | ||
| 666 | "sending the offset, status: 0x%02x\n", | ||
| 667 | (unsigned int)bank, (unsigned int)offset, x); | ||
| 668 | return -EIO; | ||
| 669 | } | ||
| 670 | |||
| 671 | outb(count, data->addr + ABIT_UGURU3_CMD); | ||
| 672 | if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) { | ||
| 673 | ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after " | ||
| 674 | "sending the count, status: 0x%02x\n", | ||
| 675 | (unsigned int)bank, (unsigned int)offset, x); | ||
| 676 | return -EIO; | ||
| 677 | } | ||
| 678 | |||
| 679 | for (i = 0; i < count; i++) { | ||
| 680 | if ((x = abituguru3_wait_for_read(data)) != | ||
| 681 | ABIT_UGURU3_SUCCESS) { | ||
| 682 | ABIT_UGURU3_DEBUG("timeout reading byte %d from " | ||
| 683 | "0x%02x:0x%02x, status: 0x%02x\n", i, | ||
| 684 | (unsigned int)bank, (unsigned int)offset, x); | ||
| 685 | break; | ||
| 686 | } | ||
| 687 | buf[i] = inb(data->addr + ABIT_UGURU3_CMD); | ||
| 688 | } | ||
| 689 | return i; | ||
| 690 | } | ||
| 691 | |||
| 692 | /* Sensor settings are stored 1 byte per offset with the bytes | ||
| 693 | placed add consecutive offsets. */ | ||
| 694 | int abituguru3_read_increment_offset(struct abituguru3_data *data, u8 bank, | ||
| 695 | u8 offset, u8 count, u8 *buf, int offset_count) | ||
| 696 | { | ||
| 697 | int i, x; | ||
| 698 | |||
| 699 | for (i = 0; i < offset_count; i++) | ||
| 700 | if ((x = abituguru3_read(data, bank, offset + i, count, | ||
| 701 | buf + i * count)) != count) | ||
| 702 | return i * count + (i && (x < 0)) ? 0 : x; | ||
| 703 | |||
| 704 | return i * count; | ||
| 705 | } | ||
| 706 | |||
| 707 | /* Following are the sysfs callback functions. These functions expect: | ||
| 708 | sensor_device_attribute_2->index: index into the data->sensors array | ||
| 709 | sensor_device_attribute_2->nr: register offset, bitmask or NA. */ | ||
| 710 | static struct abituguru3_data *abituguru3_update_device(struct device *dev); | ||
| 711 | |||
| 712 | static ssize_t show_value(struct device *dev, | ||
| 713 | struct device_attribute *devattr, char *buf) | ||
| 714 | { | ||
| 715 | int value; | ||
| 716 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
| 717 | struct abituguru3_data *data = abituguru3_update_device(dev); | ||
| 718 | const struct abituguru3_sensor_info *sensor; | ||
| 719 | |||
| 720 | if (!data) | ||
| 721 | return -EIO; | ||
| 722 | |||
| 723 | sensor = &data->sensors[attr->index]; | ||
| 724 | |||
| 725 | /* are we reading a setting, or is this a normal read? */ | ||
| 726 | if (attr->nr) | ||
| 727 | value = data->settings[sensor->port][attr->nr]; | ||
| 728 | else | ||
| 729 | value = data->value[sensor->port]; | ||
| 730 | |||
| 731 | /* convert the value */ | ||
| 732 | value = (value * sensor->multiplier) / sensor->divisor + | ||
| 733 | sensor->offset; | ||
| 734 | |||
| 735 | /* alternatively we could update the sensors settings struct for this, | ||
| 736 | but then its contents would differ from the windows sw ini files */ | ||
| 737 | if (sensor->type == ABIT_UGURU3_TEMP_SENSOR) | ||
| 738 | value *= 1000; | ||
| 739 | |||
| 740 | return sprintf(buf, "%d\n", value); | ||
| 741 | } | ||
| 742 | |||
| 743 | static ssize_t show_alarm(struct device *dev, | ||
| 744 | struct device_attribute *devattr, char *buf) | ||
| 745 | { | ||
| 746 | int port; | ||
| 747 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
| 748 | struct abituguru3_data *data = abituguru3_update_device(dev); | ||
| 749 | |||
| 750 | if (!data) | ||
| 751 | return -EIO; | ||
| 752 | |||
| 753 | port = data->sensors[attr->index].port; | ||
| 754 | |||
| 755 | /* See if the alarm bit for this sensor is set and if a bitmask is | ||
| 756 | given in attr->nr also check if the alarm matches the type of alarm | ||
| 757 | we're looking for (for volt it can be either low or high). The type | ||
| 758 | is stored in a few readonly bits in the settings of the sensor. */ | ||
| 759 | if ((data->alarms[port / 8] & (0x01 << (port % 8))) && | ||
| 760 | (!attr->nr || (data->settings[port][0] & attr->nr))) | ||
| 761 | return sprintf(buf, "1\n"); | ||
| 762 | else | ||
| 763 | return sprintf(buf, "0\n"); | ||
| 764 | } | ||
| 765 | |||
| 766 | static ssize_t show_mask(struct device *dev, | ||
| 767 | struct device_attribute *devattr, char *buf) | ||
| 768 | { | ||
| 769 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
| 770 | struct abituguru3_data *data = dev_get_drvdata(dev); | ||
| 771 | |||
| 772 | if (data->settings[data->sensors[attr->index].port][0] & attr->nr) | ||
| 773 | return sprintf(buf, "1\n"); | ||
| 774 | else | ||
| 775 | return sprintf(buf, "0\n"); | ||
| 776 | } | ||
| 777 | |||
| 778 | static ssize_t show_label(struct device *dev, | ||
| 779 | struct device_attribute *devattr, char *buf) | ||
| 780 | { | ||
| 781 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
| 782 | struct abituguru3_data *data = dev_get_drvdata(dev); | ||
| 783 | |||
| 784 | return sprintf(buf, "%s\n", data->sensors[attr->index].name); | ||
| 785 | } | ||
| 786 | |||
| 787 | static ssize_t show_name(struct device *dev, | ||
| 788 | struct device_attribute *devattr, char *buf) | ||
| 789 | { | ||
| 790 | return sprintf(buf, "%s\n", ABIT_UGURU3_NAME); | ||
| 791 | } | ||
| 792 | |||
| 793 | /* Sysfs attr templates, the real entries are generated automatically. */ | ||
| 794 | static const | ||
| 795 | struct sensor_device_attribute_2 abituguru3_sysfs_templ[3][10] = { { | ||
| 796 | SENSOR_ATTR_2(in%d_input, 0444, show_value, NULL, 0, 0), | ||
| 797 | SENSOR_ATTR_2(in%d_min, 0444, show_value, NULL, 1, 0), | ||
| 798 | SENSOR_ATTR_2(in%d_max, 0444, show_value, NULL, 2, 0), | ||
| 799 | SENSOR_ATTR_2(in%d_min_alarm, 0444, show_alarm, NULL, | ||
| 800 | ABIT_UGURU3_VOLT_LOW_ALARM_FLAG, 0), | ||
| 801 | SENSOR_ATTR_2(in%d_max_alarm, 0444, show_alarm, NULL, | ||
| 802 | ABIT_UGURU3_VOLT_HIGH_ALARM_FLAG, 0), | ||
| 803 | SENSOR_ATTR_2(in%d_beep, 0444, show_mask, NULL, | ||
| 804 | ABIT_UGURU3_BEEP_ENABLE, 0), | ||
| 805 | SENSOR_ATTR_2(in%d_shutdown, 0444, show_mask, NULL, | ||
| 806 | ABIT_UGURU3_SHUTDOWN_ENABLE, 0), | ||
| 807 | SENSOR_ATTR_2(in%d_min_alarm_enable, 0444, show_mask, NULL, | ||
| 808 | ABIT_UGURU3_VOLT_LOW_ALARM_ENABLE, 0), | ||
| 809 | SENSOR_ATTR_2(in%d_max_alarm_enable, 0444, show_mask, NULL, | ||
| 810 | ABIT_UGURU3_VOLT_HIGH_ALARM_ENABLE, 0), | ||
| 811 | SENSOR_ATTR_2(in%d_label, 0444, show_label, NULL, 0, 0) | ||
| 812 | }, { | ||
| 813 | SENSOR_ATTR_2(temp%d_input, 0444, show_value, NULL, 0, 0), | ||
| 814 | SENSOR_ATTR_2(temp%d_max, 0444, show_value, NULL, 1, 0), | ||
| 815 | SENSOR_ATTR_2(temp%d_crit, 0444, show_value, NULL, 2, 0), | ||
| 816 | SENSOR_ATTR_2(temp%d_alarm, 0444, show_alarm, NULL, 0, 0), | ||
| 817 | SENSOR_ATTR_2(temp%d_beep, 0444, show_mask, NULL, | ||
| 818 | ABIT_UGURU3_BEEP_ENABLE, 0), | ||
| 819 | SENSOR_ATTR_2(temp%d_shutdown, 0444, show_mask, NULL, | ||
| 820 | ABIT_UGURU3_SHUTDOWN_ENABLE, 0), | ||
| 821 | SENSOR_ATTR_2(temp%d_alarm_enable, 0444, show_mask, NULL, | ||
| 822 | ABIT_UGURU3_TEMP_HIGH_ALARM_ENABLE, 0), | ||
| 823 | SENSOR_ATTR_2(temp%d_label, 0444, show_label, NULL, 0, 0) | ||
| 824 | }, { | ||
| 825 | SENSOR_ATTR_2(fan%d_input, 0444, show_value, NULL, 0, 0), | ||
| 826 | SENSOR_ATTR_2(fan%d_min, 0444, show_value, NULL, 1, 0), | ||
| 827 | SENSOR_ATTR_2(fan%d_alarm, 0444, show_alarm, NULL, 0, 0), | ||
| 828 | SENSOR_ATTR_2(fan%d_beep, 0444, show_mask, NULL, | ||
| 829 | ABIT_UGURU3_BEEP_ENABLE, 0), | ||
| 830 | SENSOR_ATTR_2(fan%d_shutdown, 0444, show_mask, NULL, | ||
| 831 | ABIT_UGURU3_SHUTDOWN_ENABLE, 0), | ||
| 832 | SENSOR_ATTR_2(fan%d_alarm_enable, 0444, show_mask, NULL, | ||
| 833 | ABIT_UGURU3_FAN_LOW_ALARM_ENABLE, 0), | ||
| 834 | SENSOR_ATTR_2(fan%d_label, 0444, show_label, NULL, 0, 0) | ||
| 835 | } }; | ||
| 836 | |||
| 837 | static struct sensor_device_attribute_2 abituguru3_sysfs_attr[] = { | ||
| 838 | SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0), | ||
| 839 | }; | ||
| 840 | |||
| 841 | static int __devinit abituguru3_probe(struct platform_device *pdev) | ||
| 842 | { | ||
| 843 | const int no_sysfs_attr[3] = { 10, 8, 7 }; | ||
| 844 | int sensor_index[3] = { 0, 1, 1 }; | ||
| 845 | struct abituguru3_data *data; | ||
| 846 | int i, j, type, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV; | ||
| 847 | char *sysfs_filename; | ||
| 848 | u8 buf[2]; | ||
| 849 | u16 id; | ||
| 850 | |||
| 851 | if (!(data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL))) | ||
| 852 | return -ENOMEM; | ||
| 853 | |||
| 854 | data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; | ||
| 855 | mutex_init(&data->update_lock); | ||
| 856 | platform_set_drvdata(pdev, data); | ||
| 857 | |||
| 858 | /* Read the motherboard ID */ | ||
| 859 | if ((i = abituguru3_read(data, ABIT_UGURU3_MISC_BANK, | ||
| 860 | ABIT_UGURU3_BOARD_ID, 2, buf)) != 2) { | ||
| 861 | goto abituguru3_probe_error; | ||
| 862 | } | ||
| 863 | |||
| 864 | /* Completely read the uGuru to see if one really is there */ | ||
| 865 | if (!abituguru3_update_device(&pdev->dev)) | ||
| 866 | goto abituguru3_probe_error; | ||
| 867 | |||
| 868 | /* lookup the ID in our motherboard table */ | ||
| 869 | id = ((u16)buf[0] << 8) | (u16)buf[1]; | ||
| 870 | for (i = 0; abituguru3_motherboards[i].id; i++) | ||
| 871 | if (abituguru3_motherboards[i].id == id) | ||
| 872 | break; | ||
| 873 | if (!abituguru3_motherboards[i].id) { | ||
| 874 | printk(KERN_ERR ABIT_UGURU3_NAME ": error unknown motherboard " | ||
| 875 | "ID: %04X. Please report this to the abituguru3 " | ||
| 876 | "maintainer (see MAINTAINERS)\n", (unsigned int)id); | ||
| 877 | goto abituguru3_probe_error; | ||
| 878 | } | ||
| 879 | data->sensors = abituguru3_motherboards[i].sensors; | ||
| 880 | printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " | ||
| 881 | "ID: %04X (%s)\n", (unsigned int)id, | ||
| 882 | abituguru3_motherboards[i].name); | ||
| 883 | |||
| 884 | /* Fill the sysfs attr array */ | ||
| 885 | sysfs_attr_i = 0; | ||
| 886 | sysfs_filename = data->sysfs_names; | ||
| 887 | sysfs_names_free = ABIT_UGURU3_SYSFS_NAMES_LENGTH; | ||
| 888 | for (i = 0; data->sensors[i].name; i++) { | ||
| 889 | /* Fail safe check, this should never happen! */ | ||
| 890 | if (i >= ABIT_UGURU3_MAX_NO_SENSORS) { | ||
| 891 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
| 892 | ": Fatal error motherboard has more sensors " | ||
| 893 | "then ABIT_UGURU3_MAX_NO_SENSORS. This should " | ||
| 894 | "never happen please report to the abituguru3 " | ||
| 895 | "maintainer (see MAINTAINERS)\n"); | ||
| 896 | res = -ENAMETOOLONG; | ||
| 897 | goto abituguru3_probe_error; | ||
| 898 | } | ||
| 899 | type = data->sensors[i].type; | ||
| 900 | for (j = 0; j < no_sysfs_attr[type]; j++) { | ||
| 901 | used = snprintf(sysfs_filename, sysfs_names_free, | ||
| 902 | abituguru3_sysfs_templ[type][j].dev_attr.attr. | ||
| 903 | name, sensor_index[type]) + 1; | ||
| 904 | data->sysfs_attr[sysfs_attr_i] = | ||
| 905 | abituguru3_sysfs_templ[type][j]; | ||
| 906 | data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = | ||
| 907 | sysfs_filename; | ||
| 908 | data->sysfs_attr[sysfs_attr_i].index = i; | ||
| 909 | sysfs_filename += used; | ||
| 910 | sysfs_names_free -= used; | ||
| 911 | sysfs_attr_i++; | ||
| 912 | } | ||
| 913 | sensor_index[type]++; | ||
| 914 | } | ||
| 915 | /* Fail safe check, this should never happen! */ | ||
| 916 | if (sysfs_names_free < 0) { | ||
| 917 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
| 918 | ": Fatal error ran out of space for sysfs attr names. " | ||
| 919 | "This should never happen please report to the " | ||
| 920 | "abituguru3 maintainer (see MAINTAINERS)\n"); | ||
| 921 | res = -ENAMETOOLONG; | ||
| 922 | goto abituguru3_probe_error; | ||
| 923 | } | ||
| 924 | |||
| 925 | /* Register sysfs hooks */ | ||
| 926 | for (i = 0; i < sysfs_attr_i; i++) | ||
| 927 | if (device_create_file(&pdev->dev, | ||
| 928 | &data->sysfs_attr[i].dev_attr)) | ||
| 929 | goto abituguru3_probe_error; | ||
| 930 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) | ||
| 931 | if (device_create_file(&pdev->dev, | ||
| 932 | &abituguru3_sysfs_attr[i].dev_attr)) | ||
| 933 | goto abituguru3_probe_error; | ||
| 934 | |||
| 935 | data->class_dev = hwmon_device_register(&pdev->dev); | ||
| 936 | if (IS_ERR(data->class_dev)) { | ||
| 937 | res = PTR_ERR(data->class_dev); | ||
| 938 | goto abituguru3_probe_error; | ||
| 939 | } | ||
| 940 | |||
| 941 | return 0; /* success */ | ||
| 942 | |||
| 943 | abituguru3_probe_error: | ||
| 944 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | ||
| 945 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | ||
| 946 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) | ||
| 947 | device_remove_file(&pdev->dev, | ||
| 948 | &abituguru3_sysfs_attr[i].dev_attr); | ||
| 949 | kfree(data); | ||
| 950 | return res; | ||
| 951 | } | ||
| 952 | |||
| 953 | static int __devexit abituguru3_remove(struct platform_device *pdev) | ||
| 954 | { | ||
| 955 | int i; | ||
| 956 | struct abituguru3_data *data = platform_get_drvdata(pdev); | ||
| 957 | |||
| 958 | platform_set_drvdata(pdev, NULL); | ||
| 959 | hwmon_device_unregister(data->class_dev); | ||
| 960 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | ||
| 961 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | ||
| 962 | for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++) | ||
| 963 | device_remove_file(&pdev->dev, | ||
| 964 | &abituguru3_sysfs_attr[i].dev_attr); | ||
| 965 | kfree(data); | ||
| 966 | |||
| 967 | return 0; | ||
| 968 | } | ||
| 969 | |||
| 970 | static struct abituguru3_data *abituguru3_update_device(struct device *dev) | ||
| 971 | { | ||
| 972 | int i; | ||
| 973 | struct abituguru3_data *data = dev_get_drvdata(dev); | ||
| 974 | |||
| 975 | mutex_lock(&data->update_lock); | ||
| 976 | if (!data->valid || time_after(jiffies, data->last_updated + HZ)) { | ||
| 977 | /* Clear data->valid while updating */ | ||
| 978 | data->valid = 0; | ||
| 979 | /* Read alarms */ | ||
| 980 | if (abituguru3_read_increment_offset(data, | ||
| 981 | ABIT_UGURU3_SETTINGS_BANK, | ||
| 982 | ABIT_UGURU3_ALARMS_START, | ||
| 983 | 1, data->alarms, 48/8) != (48/8)) | ||
| 984 | goto LEAVE_UPDATE; | ||
| 985 | /* Read in and temp sensors (3 byte settings / sensor) */ | ||
| 986 | for (i = 0; i < 32; i++) { | ||
| 987 | if (abituguru3_read(data, ABIT_UGURU3_SENSORS_BANK, | ||
| 988 | ABIT_UGURU3_VALUES_START + i, | ||
| 989 | 1, &data->value[i]) != 1) | ||
| 990 | goto LEAVE_UPDATE; | ||
| 991 | if (abituguru3_read_increment_offset(data, | ||
| 992 | ABIT_UGURU3_SETTINGS_BANK, | ||
| 993 | ABIT_UGURU3_SETTINGS_START + i * 3, | ||
| 994 | 1, | ||
| 995 | data->settings[i], 3) != 3) | ||
| 996 | goto LEAVE_UPDATE; | ||
| 997 | } | ||
| 998 | /* Read temp sensors (2 byte settings / sensor) */ | ||
| 999 | for (i = 0; i < 16; i++) { | ||
| 1000 | if (abituguru3_read(data, ABIT_UGURU3_SENSORS_BANK, | ||
| 1001 | ABIT_UGURU3_VALUES_START + 32 + i, | ||
| 1002 | 1, &data->value[32 + i]) != 1) | ||
| 1003 | goto LEAVE_UPDATE; | ||
| 1004 | if (abituguru3_read_increment_offset(data, | ||
| 1005 | ABIT_UGURU3_SETTINGS_BANK, | ||
| 1006 | ABIT_UGURU3_SETTINGS_START + 32 * 3 + | ||
| 1007 | i * 2, 1, | ||
| 1008 | data->settings[32 + i], 2) != 2) | ||
| 1009 | goto LEAVE_UPDATE; | ||
| 1010 | } | ||
| 1011 | data->last_updated = jiffies; | ||
| 1012 | data->valid = 1; | ||
| 1013 | } | ||
| 1014 | LEAVE_UPDATE: | ||
| 1015 | mutex_unlock(&data->update_lock); | ||
| 1016 | if (data->valid) | ||
| 1017 | return data; | ||
| 1018 | else | ||
| 1019 | return NULL; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | #ifdef CONFIG_PM | ||
| 1023 | static int abituguru3_suspend(struct platform_device *pdev, pm_message_t state) | ||
| 1024 | { | ||
| 1025 | struct abituguru3_data *data = platform_get_drvdata(pdev); | ||
| 1026 | /* make sure all communications with the uguru3 are done and no new | ||
| 1027 | ones are started */ | ||
| 1028 | mutex_lock(&data->update_lock); | ||
| 1029 | return 0; | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | static int abituguru3_resume(struct platform_device *pdev) | ||
| 1033 | { | ||
| 1034 | struct abituguru3_data *data = platform_get_drvdata(pdev); | ||
| 1035 | mutex_unlock(&data->update_lock); | ||
| 1036 | return 0; | ||
| 1037 | } | ||
| 1038 | #else | ||
| 1039 | #define abituguru3_suspend NULL | ||
| 1040 | #define abituguru3_resume NULL | ||
| 1041 | #endif /* CONFIG_PM */ | ||
| 1042 | |||
| 1043 | static struct platform_driver abituguru3_driver = { | ||
| 1044 | .driver = { | ||
| 1045 | .owner = THIS_MODULE, | ||
| 1046 | .name = ABIT_UGURU3_NAME, | ||
| 1047 | }, | ||
| 1048 | .probe = abituguru3_probe, | ||
| 1049 | .remove = __devexit_p(abituguru3_remove), | ||
| 1050 | .suspend = abituguru3_suspend, | ||
| 1051 | .resume = abituguru3_resume | ||
| 1052 | }; | ||
| 1053 | |||
| 1054 | static int __init abituguru3_detect(void) | ||
| 1055 | { | ||
| 1056 | /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or | ||
| 1057 | 0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05 | ||
| 1058 | at CMD instead, why is unknown. So we test for 0x05 too. */ | ||
| 1059 | u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA); | ||
| 1060 | u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD); | ||
| 1061 | if (((data_val == 0x00) || (data_val == 0x08)) && | ||
| 1062 | ((cmd_val == 0xAC) || (cmd_val == 0x05))) | ||
| 1063 | return ABIT_UGURU3_BASE; | ||
| 1064 | |||
| 1065 | ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = " | ||
| 1066 | "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); | ||
| 1067 | |||
| 1068 | if (force) { | ||
| 1069 | printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is " | ||
| 1070 | "present because of \"force\" parameter\n"); | ||
| 1071 | return ABIT_UGURU3_BASE; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | /* No uGuru3 found */ | ||
| 1075 | return -ENODEV; | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | static struct platform_device *abituguru3_pdev; | ||
| 1079 | |||
| 1080 | static int __init abituguru3_init(void) | ||
| 1081 | { | ||
| 1082 | int address, err; | ||
| 1083 | struct resource res = { .flags = IORESOURCE_IO }; | ||
| 1084 | |||
| 1085 | address = abituguru3_detect(); | ||
| 1086 | if (address < 0) | ||
| 1087 | return address; | ||
| 1088 | |||
| 1089 | err = platform_driver_register(&abituguru3_driver); | ||
| 1090 | if (err) | ||
| 1091 | goto exit; | ||
| 1092 | |||
| 1093 | abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME, address); | ||
| 1094 | if (!abituguru3_pdev) { | ||
| 1095 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
| 1096 | ": Device allocation failed\n"); | ||
| 1097 | err = -ENOMEM; | ||
| 1098 | goto exit_driver_unregister; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | res.start = address; | ||
| 1102 | res.end = address + ABIT_UGURU3_REGION_LENGTH - 1; | ||
| 1103 | res.name = ABIT_UGURU3_NAME; | ||
| 1104 | |||
| 1105 | err = platform_device_add_resources(abituguru3_pdev, &res, 1); | ||
| 1106 | if (err) { | ||
| 1107 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
| 1108 | ": Device resource addition failed (%d)\n", err); | ||
| 1109 | goto exit_device_put; | ||
| 1110 | } | ||
| 1111 | |||
| 1112 | err = platform_device_add(abituguru3_pdev); | ||
| 1113 | if (err) { | ||
| 1114 | printk(KERN_ERR ABIT_UGURU3_NAME | ||
| 1115 | ": Device addition failed (%d)\n", err); | ||
| 1116 | goto exit_device_put; | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | return 0; | ||
| 1120 | |||
| 1121 | exit_device_put: | ||
| 1122 | platform_device_put(abituguru3_pdev); | ||
| 1123 | exit_driver_unregister: | ||
| 1124 | platform_driver_unregister(&abituguru3_driver); | ||
| 1125 | exit: | ||
| 1126 | return err; | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | static void __exit abituguru3_exit(void) | ||
| 1130 | { | ||
| 1131 | platform_device_unregister(abituguru3_pdev); | ||
| 1132 | platform_driver_unregister(&abituguru3_driver); | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); | ||
| 1136 | MODULE_DESCRIPTION("Abit uGuru3 Sensor device"); | ||
| 1137 | MODULE_LICENSE("GPL"); | ||
| 1138 | |||
| 1139 | module_init(abituguru3_init); | ||
| 1140 | module_exit(abituguru3_exit); | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 6d54c8caed79..7c1795225b06 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
| @@ -318,7 +318,7 @@ exit: | |||
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | #ifdef CONFIG_HOTPLUG_CPU | 320 | #ifdef CONFIG_HOTPLUG_CPU |
| 321 | void coretemp_device_remove(unsigned int cpu) | 321 | static void coretemp_device_remove(unsigned int cpu) |
| 322 | { | 322 | { |
| 323 | struct pdev_entry *p, *n; | 323 | struct pdev_entry *p, *n; |
| 324 | mutex_lock(&pdev_list_mutex); | 324 | mutex_lock(&pdev_list_mutex); |
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c new file mode 100644 index 000000000000..be3aaa5d0b91 --- /dev/null +++ b/drivers/hwmon/dme1737.c | |||
| @@ -0,0 +1,2080 @@ | |||
| 1 | /* | ||
| 2 | * dme1737.c - driver for the SMSC DME1737 and Asus A8000 Super-I/O chips | ||
| 3 | * integrated hardware monitoring features. | ||
| 4 | * Copyright (c) 2007 Juerg Haefliger <juergh@gmail.com> | ||
| 5 | * | ||
| 6 | * This driver is based on the LM85 driver. The hardware monitoring | ||
| 7 | * capabilities of the DME1737 are very similar to the LM85 with some | ||
| 8 | * additional features. Even though the DME1737 is a Super-I/O chip, the | ||
| 9 | * hardware monitoring registers are only accessible via SMBus. | ||
| 10 | * | ||
| 11 | * 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 | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/slab.h> | ||
| 29 | #include <linux/jiffies.h> | ||
| 30 | #include <linux/i2c.h> | ||
| 31 | #include <linux/hwmon.h> | ||
| 32 | #include <linux/hwmon-sysfs.h> | ||
| 33 | #include <linux/hwmon-vid.h> | ||
| 34 | #include <linux/err.h> | ||
| 35 | #include <linux/mutex.h> | ||
| 36 | #include <asm/io.h> | ||
| 37 | |||
| 38 | /* Module load parameters */ | ||
| 39 | static int force_start; | ||
| 40 | module_param(force_start, bool, 0); | ||
| 41 | MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs"); | ||
| 42 | |||
| 43 | /* Addresses to scan */ | ||
| 44 | static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; | ||
| 45 | |||
| 46 | /* Insmod parameters */ | ||
| 47 | I2C_CLIENT_INSMOD_1(dme1737); | ||
| 48 | |||
| 49 | /* --------------------------------------------------------------------- | ||
| 50 | * Registers | ||
| 51 | * | ||
| 52 | * The sensors are defined as follows: | ||
| 53 | * | ||
| 54 | * Voltages Temperatures | ||
| 55 | * -------- ------------ | ||
| 56 | * in0 +5VTR (+5V stdby) temp1 Remote diode 1 | ||
| 57 | * in1 Vccp (proc core) temp2 Internal temp | ||
| 58 | * in2 VCC (internal +3.3V) temp3 Remote diode 2 | ||
| 59 | * in3 +5V | ||
| 60 | * in4 +12V | ||
| 61 | * in5 VTR (+3.3V stby) | ||
| 62 | * in6 Vbat | ||
| 63 | * | ||
| 64 | * --------------------------------------------------------------------- */ | ||
| 65 | |||
| 66 | /* Voltages (in) numbered 0-6 (ix) */ | ||
| 67 | #define DME1737_REG_IN(ix) ((ix) < 5 ? 0x20 + (ix) \ | ||
| 68 | : 0x94 + (ix)) | ||
| 69 | #define DME1737_REG_IN_MIN(ix) ((ix) < 5 ? 0x44 + (ix) * 2 \ | ||
| 70 | : 0x91 + (ix) * 2) | ||
| 71 | #define DME1737_REG_IN_MAX(ix) ((ix) < 5 ? 0x45 + (ix) * 2 \ | ||
| 72 | : 0x92 + (ix) * 2) | ||
| 73 | |||
| 74 | /* Temperatures (temp) numbered 0-2 (ix) */ | ||
| 75 | #define DME1737_REG_TEMP(ix) (0x25 + (ix)) | ||
| 76 | #define DME1737_REG_TEMP_MIN(ix) (0x4e + (ix) * 2) | ||
| 77 | #define DME1737_REG_TEMP_MAX(ix) (0x4f + (ix) * 2) | ||
| 78 | #define DME1737_REG_TEMP_OFFSET(ix) ((ix) == 0 ? 0x1f \ | ||
| 79 | : 0x1c + (ix)) | ||
| 80 | |||
| 81 | /* Voltage and temperature LSBs | ||
| 82 | * The LSBs (4 bits each) are stored in 5 registers with the following layouts: | ||
| 83 | * IN_TEMP_LSB(0) = [in5, in6] | ||
| 84 | * IN_TEMP_LSB(1) = [temp3, temp1] | ||
| 85 | * IN_TEMP_LSB(2) = [in4, temp2] | ||
| 86 | * IN_TEMP_LSB(3) = [in3, in0] | ||
| 87 | * IN_TEMP_LSB(4) = [in2, in1] */ | ||
| 88 | #define DME1737_REG_IN_TEMP_LSB(ix) (0x84 + (ix)) | ||
| 89 | static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0}; | ||
| 90 | static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4}; | ||
| 91 | static const u8 DME1737_REG_TEMP_LSB[] = {1, 2, 1}; | ||
| 92 | static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0}; | ||
| 93 | |||
| 94 | /* Fans numbered 0-5 (ix) */ | ||
| 95 | #define DME1737_REG_FAN(ix) ((ix) < 4 ? 0x28 + (ix) * 2 \ | ||
| 96 | : 0xa1 + (ix) * 2) | ||
| 97 | #define DME1737_REG_FAN_MIN(ix) ((ix) < 4 ? 0x54 + (ix) * 2 \ | ||
| 98 | : 0xa5 + (ix) * 2) | ||
| 99 | #define DME1737_REG_FAN_OPT(ix) ((ix) < 4 ? 0x90 + (ix) \ | ||
| 100 | : 0xb2 + (ix)) | ||
| 101 | #define DME1737_REG_FAN_MAX(ix) (0xb4 + (ix)) /* only for fan[4-5] */ | ||
| 102 | |||
| 103 | /* PWMs numbered 0-2, 4-5 (ix) */ | ||
| 104 | #define DME1737_REG_PWM(ix) ((ix) < 3 ? 0x30 + (ix) \ | ||
| 105 | : 0xa1 + (ix)) | ||
| 106 | #define DME1737_REG_PWM_CONFIG(ix) (0x5c + (ix)) /* only for pwm[0-2] */ | ||
| 107 | #define DME1737_REG_PWM_MIN(ix) (0x64 + (ix)) /* only for pwm[0-2] */ | ||
| 108 | #define DME1737_REG_PWM_FREQ(ix) ((ix) < 3 ? 0x5f + (ix) \ | ||
| 109 | : 0xa3 + (ix)) | ||
| 110 | /* The layout of the ramp rate registers is different from the other pwm | ||
| 111 | * registers. The bits for the 3 PWMs are stored in 2 registers: | ||
| 112 | * PWM_RR(0) = [OFF3, OFF2, OFF1, RES, RR1E, RR1-2, RR1-1, RR1-0] | ||
| 113 | * PWM_RR(1) = [RR2E, RR2-2, RR2-1, RR2-0, RR3E, RR3-2, RR3-1, RR3-0] */ | ||
| 114 | #define DME1737_REG_PWM_RR(ix) (0x62 + (ix)) /* only for pwm[0-2] */ | ||
| 115 | |||
| 116 | /* Thermal zones 0-2 */ | ||
| 117 | #define DME1737_REG_ZONE_LOW(ix) (0x67 + (ix)) | ||
| 118 | #define DME1737_REG_ZONE_ABS(ix) (0x6a + (ix)) | ||
| 119 | /* The layout of the hysteresis registers is different from the other zone | ||
| 120 | * registers. The bits for the 3 zones are stored in 2 registers: | ||
| 121 | * ZONE_HYST(0) = [H1-3, H1-2, H1-1, H1-0, H2-3, H2-2, H2-1, H2-0] | ||
| 122 | * ZONE_HYST(1) = [H3-3, H3-2, H3-1, H3-0, RES, RES, RES, RES] */ | ||
| 123 | #define DME1737_REG_ZONE_HYST(ix) (0x6d + (ix)) | ||
| 124 | |||
| 125 | /* Alarm registers and bit mapping | ||
| 126 | * The 3 8-bit alarm registers will be concatenated to a single 32-bit | ||
| 127 | * alarm value [0, ALARM3, ALARM2, ALARM1]. */ | ||
| 128 | #define DME1737_REG_ALARM1 0x41 | ||
| 129 | #define DME1737_REG_ALARM2 0x42 | ||
| 130 | #define DME1737_REG_ALARM3 0x83 | ||
| 131 | static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17}; | ||
| 132 | static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6}; | ||
| 133 | static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; | ||
| 134 | |||
| 135 | /* Miscellaneous registers */ | ||
| 136 | #define DME1737_REG_COMPANY 0x3e | ||
| 137 | #define DME1737_REG_VERSTEP 0x3f | ||
| 138 | #define DME1737_REG_CONFIG 0x40 | ||
| 139 | #define DME1737_REG_CONFIG2 0x7f | ||
| 140 | #define DME1737_REG_VID 0x43 | ||
| 141 | #define DME1737_REG_TACH_PWM 0x81 | ||
| 142 | |||
| 143 | /* --------------------------------------------------------------------- | ||
| 144 | * Misc defines | ||
| 145 | * --------------------------------------------------------------------- */ | ||
| 146 | |||
| 147 | /* Chip identification */ | ||
| 148 | #define DME1737_COMPANY_SMSC 0x5c | ||
| 149 | #define DME1737_VERSTEP 0x88 | ||
| 150 | #define DME1737_VERSTEP_MASK 0xf8 | ||
| 151 | |||
| 152 | /* --------------------------------------------------------------------- | ||
| 153 | * Data structures and manipulation thereof | ||
| 154 | * --------------------------------------------------------------------- */ | ||
| 155 | |||
| 156 | struct dme1737_data { | ||
| 157 | struct i2c_client client; | ||
| 158 | struct class_device *class_dev; | ||
| 159 | |||
| 160 | struct mutex update_lock; | ||
| 161 | int valid; /* !=0 if following fields are valid */ | ||
| 162 | unsigned long last_update; /* in jiffies */ | ||
| 163 | unsigned long last_vbat; /* in jiffies */ | ||
| 164 | |||
| 165 | u8 vid; | ||
| 166 | u8 pwm_rr_en; | ||
| 167 | u8 has_pwm; | ||
| 168 | u8 has_fan; | ||
| 169 | |||
| 170 | /* Register values */ | ||
| 171 | u16 in[7]; | ||
| 172 | u8 in_min[7]; | ||
| 173 | u8 in_max[7]; | ||
| 174 | s16 temp[3]; | ||
| 175 | s8 temp_min[3]; | ||
| 176 | s8 temp_max[3]; | ||
| 177 | s8 temp_offset[3]; | ||
| 178 | u8 config; | ||
| 179 | u8 config2; | ||
| 180 | u8 vrm; | ||
| 181 | u16 fan[6]; | ||
| 182 | u16 fan_min[6]; | ||
| 183 | u8 fan_max[2]; | ||
| 184 | u8 fan_opt[6]; | ||
| 185 | u8 pwm[6]; | ||
| 186 | u8 pwm_min[3]; | ||
| 187 | u8 pwm_config[3]; | ||
| 188 | u8 pwm_acz[3]; | ||
| 189 | u8 pwm_freq[6]; | ||
| 190 | u8 pwm_rr[2]; | ||
| 191 | u8 zone_low[3]; | ||
| 192 | u8 zone_abs[3]; | ||
| 193 | u8 zone_hyst[2]; | ||
| 194 | u32 alarms; | ||
| 195 | }; | ||
| 196 | |||
| 197 | /* Nominal voltage values */ | ||
| 198 | static const int IN_NOMINAL[] = {5000, 2250, 3300, 5000, 12000, 3300, 3300}; | ||
| 199 | |||
| 200 | /* Voltage input | ||
| 201 | * Voltage inputs have 16 bits resolution, limit values have 8 bits | ||
| 202 | * resolution. */ | ||
| 203 | static inline int IN_FROM_REG(int reg, int ix, int res) | ||
| 204 | { | ||
| 205 | return (reg * IN_NOMINAL[ix] + (3 << (res - 3))) / (3 << (res - 2)); | ||
| 206 | } | ||
| 207 | |||
| 208 | static inline int IN_TO_REG(int val, int ix) | ||
| 209 | { | ||
| 210 | return SENSORS_LIMIT((val * 192 + IN_NOMINAL[ix] / 2) / | ||
| 211 | IN_NOMINAL[ix], 0, 255); | ||
| 212 | } | ||
| 213 | |||
| 214 | /* Temperature input | ||
| 215 | * The register values represent temperatures in 2's complement notation from | ||
| 216 | * -127 degrees C to +127 degrees C. Temp inputs have 16 bits resolution, limit | ||
| 217 | * values have 8 bits resolution. */ | ||
| 218 | static inline int TEMP_FROM_REG(int reg, int res) | ||
| 219 | { | ||
| 220 | return (reg * 1000) >> (res - 8); | ||
| 221 | } | ||
| 222 | |||
| 223 | static inline int TEMP_TO_REG(int val) | ||
| 224 | { | ||
| 225 | return SENSORS_LIMIT((val < 0 ? val - 500 : val + 500) / 1000, | ||
| 226 | -128, 127); | ||
| 227 | } | ||
| 228 | |||
| 229 | /* Temperature range */ | ||
| 230 | static const int TEMP_RANGE[] = {2000, 2500, 3333, 4000, 5000, 6666, 8000, | ||
| 231 | 10000, 13333, 16000, 20000, 26666, 32000, | ||
| 232 | 40000, 53333, 80000}; | ||
| 233 | |||
| 234 | static inline int TEMP_RANGE_FROM_REG(int reg) | ||
| 235 | { | ||
| 236 | return TEMP_RANGE[(reg >> 4) & 0x0f]; | ||
| 237 | } | ||
| 238 | |||
| 239 | static int TEMP_RANGE_TO_REG(int val, int reg) | ||
| 240 | { | ||
| 241 | int i; | ||
| 242 | |||
| 243 | for (i = 15; i > 0; i--) { | ||
| 244 | if (val > (TEMP_RANGE[i] + TEMP_RANGE[i - 1] + 1) / 2) { | ||
| 245 | break; | ||
| 246 | } | ||
| 247 | } | ||
| 248 | |||
| 249 | return (reg & 0x0f) | (i << 4); | ||
| 250 | } | ||
| 251 | |||
| 252 | /* Temperature hysteresis | ||
| 253 | * Register layout: | ||
| 254 | * reg[0] = [H1-3, H1-2, H1-1, H1-0, H2-3, H2-2, H2-1, H2-0] | ||
| 255 | * reg[1] = [H3-3, H3-2, H3-1, H3-0, xxxx, xxxx, xxxx, xxxx] */ | ||
| 256 | static inline int TEMP_HYST_FROM_REG(int reg, int ix) | ||
| 257 | { | ||
| 258 | return (((ix == 1) ? reg : reg >> 4) & 0x0f) * 1000; | ||
| 259 | } | ||
| 260 | |||
| 261 | static inline int TEMP_HYST_TO_REG(int val, int ix, int reg) | ||
| 262 | { | ||
| 263 | int hyst = SENSORS_LIMIT((val + 500) / 1000, 0, 15); | ||
| 264 | |||
| 265 | return (ix == 1) ? (reg & 0xf0) | hyst : (reg & 0x0f) | (hyst << 4); | ||
| 266 | } | ||
| 267 | |||
| 268 | /* Fan input RPM */ | ||
| 269 | static inline int FAN_FROM_REG(int reg, int tpc) | ||
| 270 | { | ||
| 271 | return (reg == 0 || reg == 0xffff) ? 0 : | ||
| 272 | (tpc == 0) ? 90000 * 60 / reg : tpc * reg; | ||
| 273 | } | ||
| 274 | |||
| 275 | static inline int FAN_TO_REG(int val, int tpc) | ||
| 276 | { | ||
| 277 | return SENSORS_LIMIT((tpc == 0) ? 90000 * 60 / val : val / tpc, | ||
| 278 | 0, 0xffff); | ||
| 279 | } | ||
| 280 | |||
| 281 | /* Fan TPC (tach pulse count) | ||
| 282 | * Converts a register value to a TPC multiplier or returns 0 if the tachometer | ||
| 283 | * is configured in legacy (non-tpc) mode */ | ||
| 284 | static inline int FAN_TPC_FROM_REG(int reg) | ||
| 285 | { | ||
| 286 | return (reg & 0x20) ? 0 : 60 >> (reg & 0x03); | ||
| 287 | } | ||
| 288 | |||
| 289 | /* Fan type | ||
| 290 | * The type of a fan is expressed in number of pulses-per-revolution that it | ||
| 291 | * emits */ | ||
| 292 | static inline int FAN_TYPE_FROM_REG(int reg) | ||
| 293 | { | ||
| 294 | int edge = (reg >> 1) & 0x03; | ||
| 295 | |||
| 296 | return (edge > 0) ? 1 << (edge - 1) : 0; | ||
| 297 | } | ||
| 298 | |||
| 299 | static inline int FAN_TYPE_TO_REG(int val, int reg) | ||
| 300 | { | ||
| 301 | int edge = (val == 4) ? 3 : val; | ||
| 302 | |||
| 303 | return (reg & 0xf9) | (edge << 1); | ||
| 304 | } | ||
| 305 | |||
| 306 | /* Fan max RPM */ | ||
| 307 | static const int FAN_MAX[] = {0x54, 0x38, 0x2a, 0x21, 0x1c, 0x18, 0x15, 0x12, | ||
| 308 | 0x11, 0x0f, 0x0e}; | ||
| 309 | |||
| 310 | static int FAN_MAX_FROM_REG(int reg) | ||
| 311 | { | ||
| 312 | int i; | ||
| 313 | |||
| 314 | for (i = 10; i > 0; i--) { | ||
| 315 | if (reg == FAN_MAX[i]) { | ||
| 316 | break; | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | return 1000 + i * 500; | ||
| 321 | } | ||
| 322 | |||
| 323 | static int FAN_MAX_TO_REG(int val) | ||
| 324 | { | ||
| 325 | int i; | ||
| 326 | |||
| 327 | for (i = 10; i > 0; i--) { | ||
| 328 | if (val > (1000 + (i - 1) * 500)) { | ||
| 329 | break; | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | return FAN_MAX[i]; | ||
| 334 | } | ||
| 335 | |||
| 336 | /* PWM enable | ||
| 337 | * Register to enable mapping: | ||
| 338 | * 000: 2 fan on zone 1 auto | ||
| 339 | * 001: 2 fan on zone 2 auto | ||
| 340 | * 010: 2 fan on zone 3 auto | ||
| 341 | * 011: 0 fan full on | ||
| 342 | * 100: -1 fan disabled | ||
| 343 | * 101: 2 fan on hottest of zones 2,3 auto | ||
| 344 | * 110: 2 fan on hottest of zones 1,2,3 auto | ||
| 345 | * 111: 1 fan in manual mode */ | ||
| 346 | static inline int PWM_EN_FROM_REG(int reg) | ||
| 347 | { | ||
| 348 | static const int en[] = {2, 2, 2, 0, -1, 2, 2, 1}; | ||
| 349 | |||
| 350 | return en[(reg >> 5) & 0x07]; | ||
| 351 | } | ||
| 352 | |||
| 353 | static inline int PWM_EN_TO_REG(int val, int reg) | ||
| 354 | { | ||
| 355 | int en = (val == 1) ? 7 : 3; | ||
| 356 | |||
| 357 | return (reg & 0x1f) | ((en & 0x07) << 5); | ||
| 358 | } | ||
| 359 | |||
| 360 | /* PWM auto channels zone | ||
| 361 | * Register to auto channels zone mapping (ACZ is a bitfield with bit x | ||
| 362 | * corresponding to zone x+1): | ||
| 363 | * 000: 001 fan on zone 1 auto | ||
| 364 | * 001: 010 fan on zone 2 auto | ||
| 365 | * 010: 100 fan on zone 3 auto | ||
| 366 | * 011: 000 fan full on | ||
| 367 | * 100: 000 fan disabled | ||
| 368 | * 101: 110 fan on hottest of zones 2,3 auto | ||
| 369 | * 110: 111 fan on hottest of zones 1,2,3 auto | ||
| 370 | * 111: 000 fan in manual mode */ | ||
| 371 | static inline int PWM_ACZ_FROM_REG(int reg) | ||
| 372 | { | ||
| 373 | static const int acz[] = {1, 2, 4, 0, 0, 6, 7, 0}; | ||
| 374 | |||
| 375 | return acz[(reg >> 5) & 0x07]; | ||
| 376 | } | ||
| 377 | |||
| 378 | static inline int PWM_ACZ_TO_REG(int val, int reg) | ||
| 379 | { | ||
| 380 | int acz = (val == 4) ? 2 : val - 1; | ||
| 381 | |||
| 382 | return (reg & 0x1f) | ((acz & 0x07) << 5); | ||
| 383 | } | ||
| 384 | |||
| 385 | /* PWM frequency */ | ||
| 386 | static const int PWM_FREQ[] = {11, 15, 22, 29, 35, 44, 59, 88, | ||
| 387 | 15000, 20000, 30000, 25000, 0, 0, 0, 0}; | ||
| 388 | |||
| 389 | static inline int PWM_FREQ_FROM_REG(int reg) | ||
| 390 | { | ||
| 391 | return PWM_FREQ[reg & 0x0f]; | ||
| 392 | } | ||
| 393 | |||
| 394 | static int PWM_FREQ_TO_REG(int val, int reg) | ||
| 395 | { | ||
| 396 | int i; | ||
| 397 | |||
| 398 | /* the first two cases are special - stupid chip design! */ | ||
| 399 | if (val > 27500) { | ||
| 400 | i = 10; | ||
| 401 | } else if (val > 22500) { | ||
| 402 | i = 11; | ||
| 403 | } else { | ||
| 404 | for (i = 9; i > 0; i--) { | ||
| 405 | if (val > (PWM_FREQ[i] + PWM_FREQ[i - 1] + 1) / 2) { | ||
| 406 | break; | ||
| 407 | } | ||
| 408 | } | ||
| 409 | } | ||
| 410 | |||
| 411 | return (reg & 0xf0) | i; | ||
| 412 | } | ||
| 413 | |||
| 414 | /* PWM ramp rate | ||
| 415 | * Register layout: | ||
| 416 | * reg[0] = [OFF3, OFF2, OFF1, RES, RR1-E, RR1-2, RR1-1, RR1-0] | ||
| 417 | * reg[1] = [RR2-E, RR2-2, RR2-1, RR2-0, RR3-E, RR3-2, RR3-1, RR3-0] */ | ||
| 418 | static const u8 PWM_RR[] = {206, 104, 69, 41, 26, 18, 10, 5}; | ||
| 419 | |||
| 420 | static inline int PWM_RR_FROM_REG(int reg, int ix) | ||
| 421 | { | ||
| 422 | int rr = (ix == 1) ? reg >> 4 : reg; | ||
| 423 | |||
| 424 | return (rr & 0x08) ? PWM_RR[rr & 0x07] : 0; | ||
| 425 | } | ||
| 426 | |||
| 427 | static int PWM_RR_TO_REG(int val, int ix, int reg) | ||
| 428 | { | ||
| 429 | int i; | ||
| 430 | |||
| 431 | for (i = 0; i < 7; i++) { | ||
| 432 | if (val > (PWM_RR[i] + PWM_RR[i + 1] + 1) / 2) { | ||
| 433 | break; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | return (ix == 1) ? (reg & 0x8f) | (i << 4) : (reg & 0xf8) | i; | ||
| 438 | } | ||
| 439 | |||
| 440 | /* PWM ramp rate enable */ | ||
| 441 | static inline int PWM_RR_EN_FROM_REG(int reg, int ix) | ||
| 442 | { | ||
| 443 | return PWM_RR_FROM_REG(reg, ix) ? 1 : 0; | ||
| 444 | } | ||
| 445 | |||
| 446 | static inline int PWM_RR_EN_TO_REG(int val, int ix, int reg) | ||
| 447 | { | ||
| 448 | int en = (ix == 1) ? 0x80 : 0x08; | ||
| 449 | |||
| 450 | return val ? reg | en : reg & ~en; | ||
| 451 | } | ||
| 452 | |||
| 453 | /* PWM min/off | ||
| 454 | * The PWM min/off bits are part of the PMW ramp rate register 0 (see above for | ||
| 455 | * the register layout). */ | ||
| 456 | static inline int PWM_OFF_FROM_REG(int reg, int ix) | ||
| 457 | { | ||
| 458 | return (reg >> (ix + 5)) & 0x01; | ||
| 459 | } | ||
| 460 | |||
| 461 | static inline int PWM_OFF_TO_REG(int val, int ix, int reg) | ||
| 462 | { | ||
| 463 | return (reg & ~(1 << (ix + 5))) | ((val & 0x01) << (ix + 5)); | ||
| 464 | } | ||
| 465 | |||
| 466 | /* --------------------------------------------------------------------- | ||
| 467 | * Device I/O access | ||
| 468 | * --------------------------------------------------------------------- */ | ||
| 469 | |||
| 470 | static u8 dme1737_read(struct i2c_client *client, u8 reg) | ||
| 471 | { | ||
| 472 | s32 val = i2c_smbus_read_byte_data(client, reg); | ||
| 473 | |||
| 474 | if (val < 0) { | ||
| 475 | dev_warn(&client->dev, "Read from register 0x%02x failed! " | ||
| 476 | "Please report to the driver maintainer.\n", reg); | ||
| 477 | } | ||
| 478 | |||
| 479 | return val; | ||
| 480 | } | ||
| 481 | |||
| 482 | static s32 dme1737_write(struct i2c_client *client, u8 reg, u8 value) | ||
| 483 | { | ||
| 484 | s32 res = i2c_smbus_write_byte_data(client, reg, value); | ||
| 485 | |||
| 486 | if (res < 0) { | ||
| 487 | dev_warn(&client->dev, "Write to register 0x%02x failed! " | ||
| 488 | "Please report to the driver maintainer.\n", reg); | ||
| 489 | } | ||
| 490 | |||
| 491 | return res; | ||
| 492 | } | ||
| 493 | |||
| 494 | static struct dme1737_data *dme1737_update_device(struct device *dev) | ||
| 495 | { | ||
| 496 | struct i2c_client *client = to_i2c_client(dev); | ||
| 497 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 498 | int ix; | ||
| 499 | u8 lsb[5]; | ||
| 500 | |||
| 501 | mutex_lock(&data->update_lock); | ||
| 502 | |||
| 503 | /* Enable a Vbat monitoring cycle every 10 mins */ | ||
| 504 | if (time_after(jiffies, data->last_vbat + 600 * HZ) || !data->valid) { | ||
| 505 | dme1737_write(client, DME1737_REG_CONFIG, dme1737_read(client, | ||
| 506 | DME1737_REG_CONFIG) | 0x10); | ||
| 507 | data->last_vbat = jiffies; | ||
| 508 | } | ||
| 509 | |||
| 510 | /* Sample register contents every 1 sec */ | ||
| 511 | if (time_after(jiffies, data->last_update + HZ) || !data->valid) { | ||
| 512 | data->vid = dme1737_read(client, DME1737_REG_VID) & 0x3f; | ||
| 513 | |||
| 514 | /* In (voltage) registers */ | ||
| 515 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { | ||
| 516 | /* Voltage inputs are stored as 16 bit values even | ||
| 517 | * though they have only 12 bits resolution. This is | ||
| 518 | * to make it consistent with the temp inputs. */ | ||
| 519 | data->in[ix] = dme1737_read(client, | ||
| 520 | DME1737_REG_IN(ix)) << 8; | ||
| 521 | data->in_min[ix] = dme1737_read(client, | ||
| 522 | DME1737_REG_IN_MIN(ix)); | ||
| 523 | data->in_max[ix] = dme1737_read(client, | ||
| 524 | DME1737_REG_IN_MAX(ix)); | ||
| 525 | } | ||
| 526 | |||
| 527 | /* Temp registers */ | ||
| 528 | for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) { | ||
| 529 | /* Temp inputs are stored as 16 bit values even | ||
| 530 | * though they have only 12 bits resolution. This is | ||
| 531 | * to take advantage of implicit conversions between | ||
| 532 | * register values (2's complement) and temp values | ||
| 533 | * (signed decimal). */ | ||
| 534 | data->temp[ix] = dme1737_read(client, | ||
| 535 | DME1737_REG_TEMP(ix)) << 8; | ||
| 536 | data->temp_min[ix] = dme1737_read(client, | ||
| 537 | DME1737_REG_TEMP_MIN(ix)); | ||
| 538 | data->temp_max[ix] = dme1737_read(client, | ||
| 539 | DME1737_REG_TEMP_MAX(ix)); | ||
| 540 | data->temp_offset[ix] = dme1737_read(client, | ||
| 541 | DME1737_REG_TEMP_OFFSET(ix)); | ||
| 542 | } | ||
| 543 | |||
| 544 | /* In and temp LSB registers | ||
| 545 | * The LSBs are latched when the MSBs are read, so the order in | ||
| 546 | * which the registers are read (MSB first, then LSB) is | ||
| 547 | * important! */ | ||
| 548 | for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) { | ||
| 549 | lsb[ix] = dme1737_read(client, | ||
| 550 | DME1737_REG_IN_TEMP_LSB(ix)); | ||
| 551 | } | ||
| 552 | for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { | ||
| 553 | data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] << | ||
| 554 | DME1737_REG_IN_LSB_SHL[ix]) & 0xf0; | ||
| 555 | } | ||
| 556 | for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) { | ||
| 557 | data->temp[ix] |= (lsb[DME1737_REG_TEMP_LSB[ix]] << | ||
| 558 | DME1737_REG_TEMP_LSB_SHL[ix]) & 0xf0; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* Fan registers */ | ||
| 562 | for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { | ||
| 563 | /* Skip reading registers if optional fans are not | ||
| 564 | * present */ | ||
| 565 | if (!(data->has_fan & (1 << ix))) { | ||
| 566 | continue; | ||
| 567 | } | ||
| 568 | data->fan[ix] = dme1737_read(client, | ||
| 569 | DME1737_REG_FAN(ix)); | ||
| 570 | data->fan[ix] |= dme1737_read(client, | ||
| 571 | DME1737_REG_FAN(ix) + 1) << 8; | ||
| 572 | data->fan_min[ix] = dme1737_read(client, | ||
| 573 | DME1737_REG_FAN_MIN(ix)); | ||
| 574 | data->fan_min[ix] |= dme1737_read(client, | ||
| 575 | DME1737_REG_FAN_MIN(ix) + 1) << 8; | ||
| 576 | data->fan_opt[ix] = dme1737_read(client, | ||
| 577 | DME1737_REG_FAN_OPT(ix)); | ||
| 578 | /* fan_max exists only for fan[5-6] */ | ||
| 579 | if (ix > 3) { | ||
| 580 | data->fan_max[ix - 4] = dme1737_read(client, | ||
| 581 | DME1737_REG_FAN_MAX(ix)); | ||
| 582 | } | ||
| 583 | } | ||
| 584 | |||
| 585 | /* PWM registers */ | ||
| 586 | for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { | ||
| 587 | /* Skip reading registers if optional PWMs are not | ||
| 588 | * present */ | ||
| 589 | if (!(data->has_pwm & (1 << ix))) { | ||
| 590 | continue; | ||
| 591 | } | ||
| 592 | data->pwm[ix] = dme1737_read(client, | ||
| 593 | DME1737_REG_PWM(ix)); | ||
| 594 | data->pwm_freq[ix] = dme1737_read(client, | ||
| 595 | DME1737_REG_PWM_FREQ(ix)); | ||
| 596 | /* pwm_config and pwm_min exist only for pwm[1-3] */ | ||
| 597 | if (ix < 3) { | ||
| 598 | data->pwm_config[ix] = dme1737_read(client, | ||
| 599 | DME1737_REG_PWM_CONFIG(ix)); | ||
| 600 | data->pwm_min[ix] = dme1737_read(client, | ||
| 601 | DME1737_REG_PWM_MIN(ix)); | ||
| 602 | } | ||
| 603 | } | ||
| 604 | for (ix = 0; ix < ARRAY_SIZE(data->pwm_rr); ix++) { | ||
| 605 | data->pwm_rr[ix] = dme1737_read(client, | ||
| 606 | DME1737_REG_PWM_RR(ix)); | ||
| 607 | } | ||
| 608 | |||
| 609 | /* Thermal zone registers */ | ||
| 610 | for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { | ||
| 611 | data->zone_low[ix] = dme1737_read(client, | ||
| 612 | DME1737_REG_ZONE_LOW(ix)); | ||
| 613 | data->zone_abs[ix] = dme1737_read(client, | ||
| 614 | DME1737_REG_ZONE_ABS(ix)); | ||
| 615 | } | ||
| 616 | for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { | ||
| 617 | data->zone_hyst[ix] = dme1737_read(client, | ||
| 618 | DME1737_REG_ZONE_HYST(ix)); | ||
| 619 | } | ||
| 620 | |||
| 621 | /* Alarm registers */ | ||
| 622 | data->alarms = dme1737_read(client, | ||
| 623 | DME1737_REG_ALARM1); | ||
| 624 | /* Bit 7 tells us if the other alarm registers are non-zero and | ||
| 625 | * therefore also need to be read */ | ||
| 626 | if (data->alarms & 0x80) { | ||
| 627 | data->alarms |= dme1737_read(client, | ||
| 628 | DME1737_REG_ALARM2) << 8; | ||
| 629 | data->alarms |= dme1737_read(client, | ||
| 630 | DME1737_REG_ALARM3) << 16; | ||
| 631 | } | ||
| 632 | |||
| 633 | data->last_update = jiffies; | ||
| 634 | data->valid = 1; | ||
| 635 | } | ||
| 636 | |||
| 637 | mutex_unlock(&data->update_lock); | ||
| 638 | |||
| 639 | return data; | ||
| 640 | } | ||
| 641 | |||
| 642 | /* --------------------------------------------------------------------- | ||
| 643 | * Voltage sysfs attributes | ||
| 644 | * ix = [0-5] | ||
| 645 | * --------------------------------------------------------------------- */ | ||
| 646 | |||
| 647 | #define SYS_IN_INPUT 0 | ||
| 648 | #define SYS_IN_MIN 1 | ||
| 649 | #define SYS_IN_MAX 2 | ||
| 650 | #define SYS_IN_ALARM 3 | ||
| 651 | |||
| 652 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | ||
| 653 | char *buf) | ||
| 654 | { | ||
| 655 | struct dme1737_data *data = dme1737_update_device(dev); | ||
| 656 | struct sensor_device_attribute_2 | ||
| 657 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 658 | int ix = sensor_attr_2->index; | ||
| 659 | int fn = sensor_attr_2->nr; | ||
| 660 | int res; | ||
| 661 | |||
| 662 | switch (fn) { | ||
| 663 | case SYS_IN_INPUT: | ||
| 664 | res = IN_FROM_REG(data->in[ix], ix, 16); | ||
| 665 | break; | ||
| 666 | case SYS_IN_MIN: | ||
| 667 | res = IN_FROM_REG(data->in_min[ix], ix, 8); | ||
| 668 | break; | ||
| 669 | case SYS_IN_MAX: | ||
| 670 | res = IN_FROM_REG(data->in_max[ix], ix, 8); | ||
| 671 | break; | ||
| 672 | case SYS_IN_ALARM: | ||
| 673 | res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01; | ||
| 674 | break; | ||
| 675 | default: | ||
| 676 | res = 0; | ||
| 677 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 678 | } | ||
| 679 | |||
| 680 | return sprintf(buf, "%d\n", res); | ||
| 681 | } | ||
| 682 | |||
| 683 | static ssize_t set_in(struct device *dev, struct device_attribute *attr, | ||
| 684 | const char *buf, size_t count) | ||
| 685 | { | ||
| 686 | struct i2c_client *client = to_i2c_client(dev); | ||
| 687 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 688 | struct sensor_device_attribute_2 | ||
| 689 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 690 | int ix = sensor_attr_2->index; | ||
| 691 | int fn = sensor_attr_2->nr; | ||
| 692 | long val = simple_strtol(buf, NULL, 10); | ||
| 693 | |||
| 694 | mutex_lock(&data->update_lock); | ||
| 695 | switch (fn) { | ||
| 696 | case SYS_IN_MIN: | ||
| 697 | data->in_min[ix] = IN_TO_REG(val, ix); | ||
| 698 | dme1737_write(client, DME1737_REG_IN_MIN(ix), | ||
| 699 | data->in_min[ix]); | ||
| 700 | break; | ||
| 701 | case SYS_IN_MAX: | ||
| 702 | data->in_max[ix] = IN_TO_REG(val, ix); | ||
| 703 | dme1737_write(client, DME1737_REG_IN_MAX(ix), | ||
| 704 | data->in_max[ix]); | ||
| 705 | break; | ||
| 706 | default: | ||
| 707 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 708 | } | ||
| 709 | mutex_unlock(&data->update_lock); | ||
| 710 | |||
| 711 | return count; | ||
| 712 | } | ||
| 713 | |||
| 714 | /* --------------------------------------------------------------------- | ||
| 715 | * Temperature sysfs attributes | ||
| 716 | * ix = [0-2] | ||
| 717 | * --------------------------------------------------------------------- */ | ||
| 718 | |||
| 719 | #define SYS_TEMP_INPUT 0 | ||
| 720 | #define SYS_TEMP_MIN 1 | ||
| 721 | #define SYS_TEMP_MAX 2 | ||
| 722 | #define SYS_TEMP_OFFSET 3 | ||
| 723 | #define SYS_TEMP_ALARM 4 | ||
| 724 | #define SYS_TEMP_FAULT 5 | ||
| 725 | |||
| 726 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | ||
| 727 | char *buf) | ||
| 728 | { | ||
| 729 | struct dme1737_data *data = dme1737_update_device(dev); | ||
| 730 | struct sensor_device_attribute_2 | ||
| 731 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 732 | int ix = sensor_attr_2->index; | ||
| 733 | int fn = sensor_attr_2->nr; | ||
| 734 | int res; | ||
| 735 | |||
| 736 | switch (fn) { | ||
| 737 | case SYS_TEMP_INPUT: | ||
| 738 | res = TEMP_FROM_REG(data->temp[ix], 16); | ||
| 739 | break; | ||
| 740 | case SYS_TEMP_MIN: | ||
| 741 | res = TEMP_FROM_REG(data->temp_min[ix], 8); | ||
| 742 | break; | ||
| 743 | case SYS_TEMP_MAX: | ||
| 744 | res = TEMP_FROM_REG(data->temp_max[ix], 8); | ||
| 745 | break; | ||
| 746 | case SYS_TEMP_OFFSET: | ||
| 747 | res = TEMP_FROM_REG(data->temp_offset[ix], 8); | ||
| 748 | break; | ||
| 749 | case SYS_TEMP_ALARM: | ||
| 750 | res = (data->alarms >> DME1737_BIT_ALARM_TEMP[ix]) & 0x01; | ||
| 751 | break; | ||
| 752 | case SYS_TEMP_FAULT: | ||
| 753 | res = (data->temp[ix] == 0x0800); | ||
| 754 | break; | ||
| 755 | default: | ||
| 756 | res = 0; | ||
| 757 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 758 | } | ||
| 759 | |||
| 760 | return sprintf(buf, "%d\n", res); | ||
| 761 | } | ||
| 762 | |||
| 763 | static ssize_t set_temp(struct device *dev, struct device_attribute *attr, | ||
| 764 | const char *buf, size_t count) | ||
| 765 | { | ||
| 766 | struct i2c_client *client = to_i2c_client(dev); | ||
| 767 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 768 | struct sensor_device_attribute_2 | ||
| 769 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 770 | int ix = sensor_attr_2->index; | ||
| 771 | int fn = sensor_attr_2->nr; | ||
| 772 | long val = simple_strtol(buf, NULL, 10); | ||
| 773 | |||
| 774 | mutex_lock(&data->update_lock); | ||
| 775 | switch (fn) { | ||
| 776 | case SYS_TEMP_MIN: | ||
| 777 | data->temp_min[ix] = TEMP_TO_REG(val); | ||
| 778 | dme1737_write(client, DME1737_REG_TEMP_MIN(ix), | ||
| 779 | data->temp_min[ix]); | ||
| 780 | break; | ||
| 781 | case SYS_TEMP_MAX: | ||
| 782 | data->temp_max[ix] = TEMP_TO_REG(val); | ||
| 783 | dme1737_write(client, DME1737_REG_TEMP_MAX(ix), | ||
| 784 | data->temp_max[ix]); | ||
| 785 | break; | ||
| 786 | case SYS_TEMP_OFFSET: | ||
| 787 | data->temp_offset[ix] = TEMP_TO_REG(val); | ||
| 788 | dme1737_write(client, DME1737_REG_TEMP_OFFSET(ix), | ||
| 789 | data->temp_offset[ix]); | ||
| 790 | break; | ||
| 791 | default: | ||
| 792 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 793 | } | ||
| 794 | mutex_unlock(&data->update_lock); | ||
| 795 | |||
| 796 | return count; | ||
| 797 | } | ||
| 798 | |||
| 799 | /* --------------------------------------------------------------------- | ||
| 800 | * Zone sysfs attributes | ||
| 801 | * ix = [0-2] | ||
| 802 | * --------------------------------------------------------------------- */ | ||
| 803 | |||
| 804 | #define SYS_ZONE_AUTO_CHANNELS_TEMP 0 | ||
| 805 | #define SYS_ZONE_AUTO_POINT1_TEMP_HYST 1 | ||
| 806 | #define SYS_ZONE_AUTO_POINT1_TEMP 2 | ||
| 807 | #define SYS_ZONE_AUTO_POINT2_TEMP 3 | ||
| 808 | #define SYS_ZONE_AUTO_POINT3_TEMP 4 | ||
| 809 | |||
| 810 | static ssize_t show_zone(struct device *dev, struct device_attribute *attr, | ||
| 811 | char *buf) | ||
| 812 | { | ||
| 813 | struct dme1737_data *data = dme1737_update_device(dev); | ||
| 814 | struct sensor_device_attribute_2 | ||
| 815 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 816 | int ix = sensor_attr_2->index; | ||
| 817 | int fn = sensor_attr_2->nr; | ||
| 818 | int res; | ||
| 819 | |||
| 820 | switch (fn) { | ||
| 821 | case SYS_ZONE_AUTO_CHANNELS_TEMP: | ||
| 822 | /* check config2 for non-standard temp-to-zone mapping */ | ||
| 823 | if ((ix == 1) && (data->config2 & 0x02)) { | ||
| 824 | res = 4; | ||
| 825 | } else { | ||
| 826 | res = 1 << ix; | ||
| 827 | } | ||
| 828 | break; | ||
| 829 | case SYS_ZONE_AUTO_POINT1_TEMP_HYST: | ||
| 830 | res = TEMP_FROM_REG(data->zone_low[ix], 8) - | ||
| 831 | TEMP_HYST_FROM_REG(data->zone_hyst[ix == 2], ix); | ||
| 832 | break; | ||
| 833 | case SYS_ZONE_AUTO_POINT1_TEMP: | ||
| 834 | res = TEMP_FROM_REG(data->zone_low[ix], 8); | ||
| 835 | break; | ||
| 836 | case SYS_ZONE_AUTO_POINT2_TEMP: | ||
| 837 | /* pwm_freq holds the temp range bits in the upper nibble */ | ||
| 838 | res = TEMP_FROM_REG(data->zone_low[ix], 8) + | ||
| 839 | TEMP_RANGE_FROM_REG(data->pwm_freq[ix]); | ||
| 840 | break; | ||
| 841 | case SYS_ZONE_AUTO_POINT3_TEMP: | ||
| 842 | res = TEMP_FROM_REG(data->zone_abs[ix], 8); | ||
| 843 | break; | ||
| 844 | default: | ||
| 845 | res = 0; | ||
| 846 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 847 | } | ||
| 848 | |||
| 849 | return sprintf(buf, "%d\n", res); | ||
| 850 | } | ||
| 851 | |||
| 852 | static ssize_t set_zone(struct device *dev, struct device_attribute *attr, | ||
| 853 | const char *buf, size_t count) | ||
| 854 | { | ||
| 855 | struct i2c_client *client = to_i2c_client(dev); | ||
| 856 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 857 | struct sensor_device_attribute_2 | ||
| 858 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 859 | int ix = sensor_attr_2->index; | ||
| 860 | int fn = sensor_attr_2->nr; | ||
| 861 | long val = simple_strtol(buf, NULL, 10); | ||
| 862 | |||
| 863 | mutex_lock(&data->update_lock); | ||
| 864 | switch (fn) { | ||
| 865 | case SYS_ZONE_AUTO_POINT1_TEMP_HYST: | ||
| 866 | /* Refresh the cache */ | ||
| 867 | data->zone_low[ix] = dme1737_read(client, | ||
| 868 | DME1737_REG_ZONE_LOW(ix)); | ||
| 869 | /* Modify the temp hyst value */ | ||
| 870 | data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG( | ||
| 871 | TEMP_FROM_REG(data->zone_low[ix], 8) - | ||
| 872 | val, ix, dme1737_read(client, | ||
| 873 | DME1737_REG_ZONE_HYST(ix == 2))); | ||
| 874 | dme1737_write(client, DME1737_REG_ZONE_HYST(ix == 2), | ||
| 875 | data->zone_hyst[ix == 2]); | ||
| 876 | break; | ||
| 877 | case SYS_ZONE_AUTO_POINT1_TEMP: | ||
| 878 | data->zone_low[ix] = TEMP_TO_REG(val); | ||
| 879 | dme1737_write(client, DME1737_REG_ZONE_LOW(ix), | ||
| 880 | data->zone_low[ix]); | ||
| 881 | break; | ||
| 882 | case SYS_ZONE_AUTO_POINT2_TEMP: | ||
| 883 | /* Refresh the cache */ | ||
| 884 | data->zone_low[ix] = dme1737_read(client, | ||
| 885 | DME1737_REG_ZONE_LOW(ix)); | ||
| 886 | /* Modify the temp range value (which is stored in the upper | ||
| 887 | * nibble of the pwm_freq register) */ | ||
| 888 | data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val - | ||
| 889 | TEMP_FROM_REG(data->zone_low[ix], 8), | ||
| 890 | dme1737_read(client, | ||
| 891 | DME1737_REG_PWM_FREQ(ix))); | ||
| 892 | dme1737_write(client, DME1737_REG_PWM_FREQ(ix), | ||
| 893 | data->pwm_freq[ix]); | ||
| 894 | break; | ||
| 895 | case SYS_ZONE_AUTO_POINT3_TEMP: | ||
| 896 | data->zone_abs[ix] = TEMP_TO_REG(val); | ||
| 897 | dme1737_write(client, DME1737_REG_ZONE_ABS(ix), | ||
| 898 | data->zone_abs[ix]); | ||
| 899 | break; | ||
| 900 | default: | ||
| 901 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 902 | } | ||
| 903 | mutex_unlock(&data->update_lock); | ||
| 904 | |||
| 905 | return count; | ||
| 906 | } | ||
| 907 | |||
| 908 | /* --------------------------------------------------------------------- | ||
| 909 | * Fan sysfs attributes | ||
| 910 | * ix = [0-5] | ||
| 911 | * --------------------------------------------------------------------- */ | ||
| 912 | |||
| 913 | #define SYS_FAN_INPUT 0 | ||
| 914 | #define SYS_FAN_MIN 1 | ||
| 915 | #define SYS_FAN_MAX 2 | ||
| 916 | #define SYS_FAN_ALARM 3 | ||
| 917 | #define SYS_FAN_TYPE 4 | ||
| 918 | |||
| 919 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | ||
| 920 | char *buf) | ||
| 921 | { | ||
| 922 | struct dme1737_data *data = dme1737_update_device(dev); | ||
| 923 | struct sensor_device_attribute_2 | ||
| 924 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 925 | int ix = sensor_attr_2->index; | ||
| 926 | int fn = sensor_attr_2->nr; | ||
| 927 | int res; | ||
| 928 | |||
| 929 | switch (fn) { | ||
| 930 | case SYS_FAN_INPUT: | ||
| 931 | res = FAN_FROM_REG(data->fan[ix], | ||
| 932 | ix < 4 ? 0 : | ||
| 933 | FAN_TPC_FROM_REG(data->fan_opt[ix])); | ||
| 934 | break; | ||
| 935 | case SYS_FAN_MIN: | ||
| 936 | res = FAN_FROM_REG(data->fan_min[ix], | ||
| 937 | ix < 4 ? 0 : | ||
| 938 | FAN_TPC_FROM_REG(data->fan_opt[ix])); | ||
| 939 | break; | ||
| 940 | case SYS_FAN_MAX: | ||
| 941 | /* only valid for fan[5-6] */ | ||
| 942 | res = FAN_MAX_FROM_REG(data->fan_max[ix - 4]); | ||
| 943 | break; | ||
| 944 | case SYS_FAN_ALARM: | ||
| 945 | res = (data->alarms >> DME1737_BIT_ALARM_FAN[ix]) & 0x01; | ||
| 946 | break; | ||
| 947 | case SYS_FAN_TYPE: | ||
| 948 | /* only valid for fan[1-4] */ | ||
| 949 | res = FAN_TYPE_FROM_REG(data->fan_opt[ix]); | ||
| 950 | break; | ||
| 951 | default: | ||
| 952 | res = 0; | ||
| 953 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 954 | } | ||
| 955 | |||
| 956 | return sprintf(buf, "%d\n", res); | ||
| 957 | } | ||
| 958 | |||
| 959 | static ssize_t set_fan(struct device *dev, struct device_attribute *attr, | ||
| 960 | const char *buf, size_t count) | ||
| 961 | { | ||
| 962 | struct i2c_client *client = to_i2c_client(dev); | ||
| 963 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 964 | struct sensor_device_attribute_2 | ||
| 965 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 966 | int ix = sensor_attr_2->index; | ||
| 967 | int fn = sensor_attr_2->nr; | ||
| 968 | long val = simple_strtol(buf, NULL, 10); | ||
| 969 | |||
| 970 | mutex_lock(&data->update_lock); | ||
| 971 | switch (fn) { | ||
| 972 | case SYS_FAN_MIN: | ||
| 973 | if (ix < 4) { | ||
| 974 | data->fan_min[ix] = FAN_TO_REG(val, 0); | ||
| 975 | } else { | ||
| 976 | /* Refresh the cache */ | ||
| 977 | data->fan_opt[ix] = dme1737_read(client, | ||
| 978 | DME1737_REG_FAN_OPT(ix)); | ||
| 979 | /* Modify the fan min value */ | ||
| 980 | data->fan_min[ix] = FAN_TO_REG(val, | ||
| 981 | FAN_TPC_FROM_REG(data->fan_opt[ix])); | ||
| 982 | } | ||
| 983 | dme1737_write(client, DME1737_REG_FAN_MIN(ix), | ||
| 984 | data->fan_min[ix] & 0xff); | ||
| 985 | dme1737_write(client, DME1737_REG_FAN_MIN(ix) + 1, | ||
| 986 | data->fan_min[ix] >> 8); | ||
| 987 | break; | ||
| 988 | case SYS_FAN_MAX: | ||
| 989 | /* Only valid for fan[5-6] */ | ||
| 990 | data->fan_max[ix - 4] = FAN_MAX_TO_REG(val); | ||
| 991 | dme1737_write(client, DME1737_REG_FAN_MAX(ix), | ||
| 992 | data->fan_max[ix - 4]); | ||
| 993 | break; | ||
| 994 | case SYS_FAN_TYPE: | ||
| 995 | /* Only valid for fan[1-4] */ | ||
| 996 | if (!(val == 1 || val == 2 || val == 4)) { | ||
| 997 | count = -EINVAL; | ||
| 998 | dev_warn(&client->dev, "Fan type value %ld not " | ||
| 999 | "supported. Choose one of 1, 2, or 4.\n", | ||
| 1000 | val); | ||
| 1001 | goto exit; | ||
| 1002 | } | ||
| 1003 | data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(client, | ||
| 1004 | DME1737_REG_FAN_OPT(ix))); | ||
| 1005 | dme1737_write(client, DME1737_REG_FAN_OPT(ix), | ||
| 1006 | data->fan_opt[ix]); | ||
| 1007 | break; | ||
| 1008 | default: | ||
| 1009 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 1010 | } | ||
| 1011 | exit: | ||
| 1012 | mutex_unlock(&data->update_lock); | ||
| 1013 | |||
| 1014 | return count; | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | /* --------------------------------------------------------------------- | ||
| 1018 | * PWM sysfs attributes | ||
| 1019 | * ix = [0-4] | ||
| 1020 | * --------------------------------------------------------------------- */ | ||
| 1021 | |||
| 1022 | #define SYS_PWM 0 | ||
| 1023 | #define SYS_PWM_FREQ 1 | ||
| 1024 | #define SYS_PWM_ENABLE 2 | ||
| 1025 | #define SYS_PWM_RAMP_RATE 3 | ||
| 1026 | #define SYS_PWM_AUTO_CHANNELS_ZONE 4 | ||
| 1027 | #define SYS_PWM_AUTO_PWM_MIN 5 | ||
| 1028 | #define SYS_PWM_AUTO_POINT1_PWM 6 | ||
| 1029 | #define SYS_PWM_AUTO_POINT2_PWM 7 | ||
| 1030 | |||
| 1031 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | ||
| 1032 | char *buf) | ||
| 1033 | { | ||
| 1034 | struct dme1737_data *data = dme1737_update_device(dev); | ||
| 1035 | struct sensor_device_attribute_2 | ||
| 1036 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 1037 | int ix = sensor_attr_2->index; | ||
| 1038 | int fn = sensor_attr_2->nr; | ||
| 1039 | int res; | ||
| 1040 | |||
| 1041 | switch (fn) { | ||
| 1042 | case SYS_PWM: | ||
| 1043 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 0) { | ||
| 1044 | res = 255; | ||
| 1045 | } else { | ||
| 1046 | res = data->pwm[ix]; | ||
| 1047 | } | ||
| 1048 | break; | ||
| 1049 | case SYS_PWM_FREQ: | ||
| 1050 | res = PWM_FREQ_FROM_REG(data->pwm_freq[ix]); | ||
| 1051 | break; | ||
| 1052 | case SYS_PWM_ENABLE: | ||
| 1053 | if (ix > 3) { | ||
| 1054 | res = 1; /* pwm[5-6] hard-wired to manual mode */ | ||
| 1055 | } else { | ||
| 1056 | res = PWM_EN_FROM_REG(data->pwm_config[ix]); | ||
| 1057 | } | ||
| 1058 | break; | ||
| 1059 | case SYS_PWM_RAMP_RATE: | ||
| 1060 | /* Only valid for pwm[1-3] */ | ||
| 1061 | res = PWM_RR_FROM_REG(data->pwm_rr[ix > 0], ix); | ||
| 1062 | break; | ||
| 1063 | case SYS_PWM_AUTO_CHANNELS_ZONE: | ||
| 1064 | /* Only valid for pwm[1-3] */ | ||
| 1065 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { | ||
| 1066 | res = PWM_ACZ_FROM_REG(data->pwm_config[ix]); | ||
| 1067 | } else { | ||
| 1068 | res = data->pwm_acz[ix]; | ||
| 1069 | } | ||
| 1070 | break; | ||
| 1071 | case SYS_PWM_AUTO_PWM_MIN: | ||
| 1072 | /* Only valid for pwm[1-3] */ | ||
| 1073 | if (PWM_OFF_FROM_REG(data->pwm_rr[0], ix)) { | ||
| 1074 | res = data->pwm_min[ix]; | ||
| 1075 | } else { | ||
| 1076 | res = 0; | ||
| 1077 | } | ||
| 1078 | break; | ||
| 1079 | case SYS_PWM_AUTO_POINT1_PWM: | ||
| 1080 | /* Only valid for pwm[1-3] */ | ||
| 1081 | res = data->pwm_min[ix]; | ||
| 1082 | break; | ||
| 1083 | case SYS_PWM_AUTO_POINT2_PWM: | ||
| 1084 | /* Only valid for pwm[1-3] */ | ||
| 1085 | res = 255; /* hard-wired */ | ||
| 1086 | break; | ||
| 1087 | default: | ||
| 1088 | res = 0; | ||
| 1089 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | return sprintf(buf, "%d\n", res); | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | static struct attribute *dme1737_attr_pwm[]; | ||
| 1096 | static void dme1737_chmod_file(struct i2c_client*, struct attribute*, mode_t); | ||
| 1097 | |||
| 1098 | static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | ||
| 1099 | const char *buf, size_t count) | ||
| 1100 | { | ||
| 1101 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1102 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 1103 | struct sensor_device_attribute_2 | ||
| 1104 | *sensor_attr_2 = to_sensor_dev_attr_2(attr); | ||
| 1105 | int ix = sensor_attr_2->index; | ||
| 1106 | int fn = sensor_attr_2->nr; | ||
| 1107 | long val = simple_strtol(buf, NULL, 10); | ||
| 1108 | |||
| 1109 | mutex_lock(&data->update_lock); | ||
| 1110 | switch (fn) { | ||
| 1111 | case SYS_PWM: | ||
| 1112 | data->pwm[ix] = SENSORS_LIMIT(val, 0, 255); | ||
| 1113 | dme1737_write(client, DME1737_REG_PWM(ix), data->pwm[ix]); | ||
| 1114 | break; | ||
| 1115 | case SYS_PWM_FREQ: | ||
| 1116 | data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(client, | ||
| 1117 | DME1737_REG_PWM_FREQ(ix))); | ||
| 1118 | dme1737_write(client, DME1737_REG_PWM_FREQ(ix), | ||
| 1119 | data->pwm_freq[ix]); | ||
| 1120 | break; | ||
| 1121 | case SYS_PWM_ENABLE: | ||
| 1122 | /* Only valid for pwm[1-3] */ | ||
| 1123 | if (val < 0 || val > 2) { | ||
| 1124 | count = -EINVAL; | ||
| 1125 | dev_warn(&client->dev, "PWM enable %ld not " | ||
| 1126 | "supported. Choose one of 0, 1, or 2.\n", | ||
| 1127 | val); | ||
| 1128 | goto exit; | ||
| 1129 | } | ||
| 1130 | /* Refresh the cache */ | ||
| 1131 | data->pwm_config[ix] = dme1737_read(client, | ||
| 1132 | DME1737_REG_PWM_CONFIG(ix)); | ||
| 1133 | if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) { | ||
| 1134 | /* Bail out if no change */ | ||
| 1135 | goto exit; | ||
| 1136 | } | ||
| 1137 | /* Do some housekeeping if we are currently in auto mode */ | ||
| 1138 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { | ||
| 1139 | /* Save the current zone channel assignment */ | ||
| 1140 | data->pwm_acz[ix] = PWM_ACZ_FROM_REG( | ||
| 1141 | data->pwm_config[ix]); | ||
| 1142 | /* Save the current ramp rate state and disable it */ | ||
| 1143 | data->pwm_rr[ix > 0] = dme1737_read(client, | ||
| 1144 | DME1737_REG_PWM_RR(ix > 0)); | ||
| 1145 | data->pwm_rr_en &= ~(1 << ix); | ||
| 1146 | if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) { | ||
| 1147 | data->pwm_rr_en |= (1 << ix); | ||
| 1148 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix, | ||
| 1149 | data->pwm_rr[ix > 0]); | ||
| 1150 | dme1737_write(client, | ||
| 1151 | DME1737_REG_PWM_RR(ix > 0), | ||
| 1152 | data->pwm_rr[ix > 0]); | ||
| 1153 | } | ||
| 1154 | } | ||
| 1155 | /* Set the new PWM mode */ | ||
| 1156 | switch (val) { | ||
| 1157 | case 0: | ||
| 1158 | /* Change permissions of pwm[ix] to read-only */ | ||
| 1159 | dme1737_chmod_file(client, dme1737_attr_pwm[ix], | ||
| 1160 | S_IRUGO); | ||
| 1161 | /* Turn fan fully on */ | ||
| 1162 | data->pwm_config[ix] = PWM_EN_TO_REG(0, | ||
| 1163 | data->pwm_config[ix]); | ||
| 1164 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | ||
| 1165 | data->pwm_config[ix]); | ||
| 1166 | break; | ||
| 1167 | case 1: | ||
| 1168 | /* Turn on manual mode */ | ||
| 1169 | data->pwm_config[ix] = PWM_EN_TO_REG(1, | ||
| 1170 | data->pwm_config[ix]); | ||
| 1171 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | ||
| 1172 | data->pwm_config[ix]); | ||
| 1173 | /* Change permissions of pwm[ix] to read-writeable */ | ||
| 1174 | dme1737_chmod_file(client, dme1737_attr_pwm[ix], | ||
| 1175 | S_IRUGO | S_IWUSR); | ||
| 1176 | break; | ||
| 1177 | case 2: | ||
| 1178 | /* Change permissions of pwm[ix] to read-only */ | ||
| 1179 | dme1737_chmod_file(client, dme1737_attr_pwm[ix], | ||
| 1180 | S_IRUGO); | ||
| 1181 | /* Turn on auto mode using the saved zone channel | ||
| 1182 | * assignment */ | ||
| 1183 | data->pwm_config[ix] = PWM_ACZ_TO_REG( | ||
| 1184 | data->pwm_acz[ix], | ||
| 1185 | data->pwm_config[ix]); | ||
| 1186 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | ||
| 1187 | data->pwm_config[ix]); | ||
| 1188 | /* Enable PWM ramp rate if previously enabled */ | ||
| 1189 | if (data->pwm_rr_en & (1 << ix)) { | ||
| 1190 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix, | ||
| 1191 | dme1737_read(client, | ||
| 1192 | DME1737_REG_PWM_RR(ix > 0))); | ||
| 1193 | dme1737_write(client, | ||
| 1194 | DME1737_REG_PWM_RR(ix > 0), | ||
| 1195 | data->pwm_rr[ix > 0]); | ||
| 1196 | } | ||
| 1197 | break; | ||
| 1198 | } | ||
| 1199 | break; | ||
| 1200 | case SYS_PWM_RAMP_RATE: | ||
| 1201 | /* Only valid for pwm[1-3] */ | ||
| 1202 | /* Refresh the cache */ | ||
| 1203 | data->pwm_config[ix] = dme1737_read(client, | ||
| 1204 | DME1737_REG_PWM_CONFIG(ix)); | ||
| 1205 | data->pwm_rr[ix > 0] = dme1737_read(client, | ||
| 1206 | DME1737_REG_PWM_RR(ix > 0)); | ||
| 1207 | /* Set the ramp rate value */ | ||
| 1208 | if (val > 0) { | ||
| 1209 | data->pwm_rr[ix > 0] = PWM_RR_TO_REG(val, ix, | ||
| 1210 | data->pwm_rr[ix > 0]); | ||
| 1211 | } | ||
| 1212 | /* Enable/disable the feature only if the associated PWM | ||
| 1213 | * output is in automatic mode. */ | ||
| 1214 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { | ||
| 1215 | data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix, | ||
| 1216 | data->pwm_rr[ix > 0]); | ||
| 1217 | } | ||
| 1218 | dme1737_write(client, DME1737_REG_PWM_RR(ix > 0), | ||
| 1219 | data->pwm_rr[ix > 0]); | ||
| 1220 | break; | ||
| 1221 | case SYS_PWM_AUTO_CHANNELS_ZONE: | ||
| 1222 | /* Only valid for pwm[1-3] */ | ||
| 1223 | if (!(val == 1 || val == 2 || val == 4 || | ||
| 1224 | val == 6 || val == 7)) { | ||
| 1225 | count = -EINVAL; | ||
| 1226 | dev_warn(&client->dev, "PWM auto channels zone %ld " | ||
| 1227 | "not supported. Choose one of 1, 2, 4, 6, " | ||
| 1228 | "or 7.\n", val); | ||
| 1229 | goto exit; | ||
| 1230 | } | ||
| 1231 | /* Refresh the cache */ | ||
| 1232 | data->pwm_config[ix] = dme1737_read(client, | ||
| 1233 | DME1737_REG_PWM_CONFIG(ix)); | ||
| 1234 | if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) { | ||
| 1235 | /* PWM is already in auto mode so update the temp | ||
| 1236 | * channel assignment */ | ||
| 1237 | data->pwm_config[ix] = PWM_ACZ_TO_REG(val, | ||
| 1238 | data->pwm_config[ix]); | ||
| 1239 | dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), | ||
| 1240 | data->pwm_config[ix]); | ||
| 1241 | } else { | ||
| 1242 | /* PWM is not in auto mode so we save the temp | ||
| 1243 | * channel assignment for later use */ | ||
| 1244 | data->pwm_acz[ix] = val; | ||
| 1245 | } | ||
| 1246 | break; | ||
| 1247 | case SYS_PWM_AUTO_PWM_MIN: | ||
| 1248 | /* Only valid for pwm[1-3] */ | ||
| 1249 | /* Refresh the cache */ | ||
| 1250 | data->pwm_min[ix] = dme1737_read(client, | ||
| 1251 | DME1737_REG_PWM_MIN(ix)); | ||
| 1252 | /* There are only 2 values supported for the auto_pwm_min | ||
| 1253 | * value: 0 or auto_point1_pwm. So if the temperature drops | ||
| 1254 | * below the auto_point1_temp_hyst value, the fan either turns | ||
| 1255 | * off or runs at auto_point1_pwm duty-cycle. */ | ||
| 1256 | if (val > ((data->pwm_min[ix] + 1) / 2)) { | ||
| 1257 | data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix, | ||
| 1258 | dme1737_read(client, | ||
| 1259 | DME1737_REG_PWM_RR(0))); | ||
| 1260 | |||
| 1261 | } else { | ||
| 1262 | data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix, | ||
| 1263 | dme1737_read(client, | ||
| 1264 | DME1737_REG_PWM_RR(0))); | ||
| 1265 | |||
| 1266 | } | ||
| 1267 | dme1737_write(client, DME1737_REG_PWM_RR(0), | ||
| 1268 | data->pwm_rr[0]); | ||
| 1269 | break; | ||
| 1270 | case SYS_PWM_AUTO_POINT1_PWM: | ||
| 1271 | /* Only valid for pwm[1-3] */ | ||
| 1272 | data->pwm_min[ix] = SENSORS_LIMIT(val, 0, 255); | ||
| 1273 | dme1737_write(client, DME1737_REG_PWM_MIN(ix), | ||
| 1274 | data->pwm_min[ix]); | ||
| 1275 | break; | ||
| 1276 | default: | ||
| 1277 | dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); | ||
| 1278 | } | ||
| 1279 | exit: | ||
| 1280 | mutex_unlock(&data->update_lock); | ||
| 1281 | |||
| 1282 | return count; | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | /* --------------------------------------------------------------------- | ||
| 1286 | * Miscellaneous sysfs attributes | ||
| 1287 | * --------------------------------------------------------------------- */ | ||
| 1288 | |||
| 1289 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, | ||
| 1290 | char *buf) | ||
| 1291 | { | ||
| 1292 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1293 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 1294 | |||
| 1295 | return sprintf(buf, "%d\n", data->vrm); | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, | ||
| 1299 | const char *buf, size_t count) | ||
| 1300 | { | ||
| 1301 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1302 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 1303 | long val = simple_strtol(buf, NULL, 10); | ||
| 1304 | |||
| 1305 | data->vrm = val; | ||
| 1306 | return count; | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | static ssize_t show_vid(struct device *dev, struct device_attribute *attr, | ||
| 1310 | char *buf) | ||
| 1311 | { | ||
| 1312 | struct dme1737_data *data = dme1737_update_device(dev); | ||
| 1313 | |||
| 1314 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | /* --------------------------------------------------------------------- | ||
| 1318 | * Sysfs device attribute defines and structs | ||
| 1319 | * --------------------------------------------------------------------- */ | ||
| 1320 | |||
| 1321 | /* Voltages 0-6 */ | ||
| 1322 | |||
| 1323 | #define SENSOR_DEVICE_ATTR_IN(ix) \ | ||
| 1324 | static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \ | ||
| 1325 | show_in, NULL, SYS_IN_INPUT, ix); \ | ||
| 1326 | static SENSOR_DEVICE_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \ | ||
| 1327 | show_in, set_in, SYS_IN_MIN, ix); \ | ||
| 1328 | static SENSOR_DEVICE_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \ | ||
| 1329 | show_in, set_in, SYS_IN_MAX, ix); \ | ||
| 1330 | static SENSOR_DEVICE_ATTR_2(in##ix##_alarm, S_IRUGO, \ | ||
| 1331 | show_in, NULL, SYS_IN_ALARM, ix) | ||
| 1332 | |||
| 1333 | SENSOR_DEVICE_ATTR_IN(0); | ||
| 1334 | SENSOR_DEVICE_ATTR_IN(1); | ||
| 1335 | SENSOR_DEVICE_ATTR_IN(2); | ||
| 1336 | SENSOR_DEVICE_ATTR_IN(3); | ||
| 1337 | SENSOR_DEVICE_ATTR_IN(4); | ||
| 1338 | SENSOR_DEVICE_ATTR_IN(5); | ||
| 1339 | SENSOR_DEVICE_ATTR_IN(6); | ||
| 1340 | |||
| 1341 | /* Temperatures 1-3 */ | ||
| 1342 | |||
| 1343 | #define SENSOR_DEVICE_ATTR_TEMP(ix) \ | ||
| 1344 | static SENSOR_DEVICE_ATTR_2(temp##ix##_input, S_IRUGO, \ | ||
| 1345 | show_temp, NULL, SYS_TEMP_INPUT, ix-1); \ | ||
| 1346 | static SENSOR_DEVICE_ATTR_2(temp##ix##_min, S_IRUGO | S_IWUSR, \ | ||
| 1347 | show_temp, set_temp, SYS_TEMP_MIN, ix-1); \ | ||
| 1348 | static SENSOR_DEVICE_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \ | ||
| 1349 | show_temp, set_temp, SYS_TEMP_MAX, ix-1); \ | ||
| 1350 | static SENSOR_DEVICE_ATTR_2(temp##ix##_offset, S_IRUGO, \ | ||
| 1351 | show_temp, set_temp, SYS_TEMP_OFFSET, ix-1); \ | ||
| 1352 | static SENSOR_DEVICE_ATTR_2(temp##ix##_alarm, S_IRUGO, \ | ||
| 1353 | show_temp, NULL, SYS_TEMP_ALARM, ix-1); \ | ||
| 1354 | static SENSOR_DEVICE_ATTR_2(temp##ix##_fault, S_IRUGO, \ | ||
| 1355 | show_temp, NULL, SYS_TEMP_FAULT, ix-1) | ||
| 1356 | |||
| 1357 | SENSOR_DEVICE_ATTR_TEMP(1); | ||
| 1358 | SENSOR_DEVICE_ATTR_TEMP(2); | ||
| 1359 | SENSOR_DEVICE_ATTR_TEMP(3); | ||
| 1360 | |||
| 1361 | /* Zones 1-3 */ | ||
| 1362 | |||
| 1363 | #define SENSOR_DEVICE_ATTR_ZONE(ix) \ | ||
| 1364 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_channels_temp, S_IRUGO, \ | ||
| 1365 | show_zone, NULL, SYS_ZONE_AUTO_CHANNELS_TEMP, ix-1); \ | ||
| 1366 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp_hyst, S_IRUGO, \ | ||
| 1367 | show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP_HYST, ix-1); \ | ||
| 1368 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point1_temp, S_IRUGO, \ | ||
| 1369 | show_zone, set_zone, SYS_ZONE_AUTO_POINT1_TEMP, ix-1); \ | ||
| 1370 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point2_temp, S_IRUGO, \ | ||
| 1371 | show_zone, set_zone, SYS_ZONE_AUTO_POINT2_TEMP, ix-1); \ | ||
| 1372 | static SENSOR_DEVICE_ATTR_2(zone##ix##_auto_point3_temp, S_IRUGO, \ | ||
| 1373 | show_zone, set_zone, SYS_ZONE_AUTO_POINT3_TEMP, ix-1) | ||
| 1374 | |||
| 1375 | SENSOR_DEVICE_ATTR_ZONE(1); | ||
| 1376 | SENSOR_DEVICE_ATTR_ZONE(2); | ||
| 1377 | SENSOR_DEVICE_ATTR_ZONE(3); | ||
| 1378 | |||
| 1379 | /* Fans 1-4 */ | ||
| 1380 | |||
| 1381 | #define SENSOR_DEVICE_ATTR_FAN_1TO4(ix) \ | ||
| 1382 | static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \ | ||
| 1383 | show_fan, NULL, SYS_FAN_INPUT, ix-1); \ | ||
| 1384 | static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \ | ||
| 1385 | show_fan, set_fan, SYS_FAN_MIN, ix-1); \ | ||
| 1386 | static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \ | ||
| 1387 | show_fan, NULL, SYS_FAN_ALARM, ix-1); \ | ||
| 1388 | static SENSOR_DEVICE_ATTR_2(fan##ix##_type, S_IRUGO | S_IWUSR, \ | ||
| 1389 | show_fan, set_fan, SYS_FAN_TYPE, ix-1) | ||
| 1390 | |||
| 1391 | SENSOR_DEVICE_ATTR_FAN_1TO4(1); | ||
| 1392 | SENSOR_DEVICE_ATTR_FAN_1TO4(2); | ||
| 1393 | SENSOR_DEVICE_ATTR_FAN_1TO4(3); | ||
| 1394 | SENSOR_DEVICE_ATTR_FAN_1TO4(4); | ||
| 1395 | |||
| 1396 | /* Fans 5-6 */ | ||
| 1397 | |||
| 1398 | #define SENSOR_DEVICE_ATTR_FAN_5TO6(ix) \ | ||
| 1399 | static SENSOR_DEVICE_ATTR_2(fan##ix##_input, S_IRUGO, \ | ||
| 1400 | show_fan, NULL, SYS_FAN_INPUT, ix-1); \ | ||
| 1401 | static SENSOR_DEVICE_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \ | ||
| 1402 | show_fan, set_fan, SYS_FAN_MIN, ix-1); \ | ||
| 1403 | static SENSOR_DEVICE_ATTR_2(fan##ix##_alarm, S_IRUGO, \ | ||
| 1404 | show_fan, NULL, SYS_FAN_ALARM, ix-1); \ | ||
| 1405 | static SENSOR_DEVICE_ATTR_2(fan##ix##_max, S_IRUGO | S_IWUSR, \ | ||
| 1406 | show_fan, set_fan, SYS_FAN_MAX, ix-1) | ||
| 1407 | |||
| 1408 | SENSOR_DEVICE_ATTR_FAN_5TO6(5); | ||
| 1409 | SENSOR_DEVICE_ATTR_FAN_5TO6(6); | ||
| 1410 | |||
| 1411 | /* PWMs 1-3 */ | ||
| 1412 | |||
| 1413 | #define SENSOR_DEVICE_ATTR_PWM_1TO3(ix) \ | ||
| 1414 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO, \ | ||
| 1415 | show_pwm, set_pwm, SYS_PWM, ix-1); \ | ||
| 1416 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO, \ | ||
| 1417 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ | ||
| 1418 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ | ||
| 1419 | show_pwm, set_pwm, SYS_PWM_ENABLE, ix-1); \ | ||
| 1420 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_ramp_rate, S_IRUGO, \ | ||
| 1421 | show_pwm, set_pwm, SYS_PWM_RAMP_RATE, ix-1); \ | ||
| 1422 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_channels_zone, S_IRUGO, \ | ||
| 1423 | show_pwm, set_pwm, SYS_PWM_AUTO_CHANNELS_ZONE, ix-1); \ | ||
| 1424 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_pwm_min, S_IRUGO, \ | ||
| 1425 | show_pwm, set_pwm, SYS_PWM_AUTO_PWM_MIN, ix-1); \ | ||
| 1426 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point1_pwm, S_IRUGO, \ | ||
| 1427 | show_pwm, set_pwm, SYS_PWM_AUTO_POINT1_PWM, ix-1); \ | ||
| 1428 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_auto_point2_pwm, S_IRUGO, \ | ||
| 1429 | show_pwm, NULL, SYS_PWM_AUTO_POINT2_PWM, ix-1) | ||
| 1430 | |||
| 1431 | SENSOR_DEVICE_ATTR_PWM_1TO3(1); | ||
| 1432 | SENSOR_DEVICE_ATTR_PWM_1TO3(2); | ||
| 1433 | SENSOR_DEVICE_ATTR_PWM_1TO3(3); | ||
| 1434 | |||
| 1435 | /* PWMs 5-6 */ | ||
| 1436 | |||
| 1437 | #define SENSOR_DEVICE_ATTR_PWM_5TO6(ix) \ | ||
| 1438 | static SENSOR_DEVICE_ATTR_2(pwm##ix, S_IRUGO | S_IWUSR, \ | ||
| 1439 | show_pwm, set_pwm, SYS_PWM, ix-1); \ | ||
| 1440 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_freq, S_IRUGO | S_IWUSR, \ | ||
| 1441 | show_pwm, set_pwm, SYS_PWM_FREQ, ix-1); \ | ||
| 1442 | static SENSOR_DEVICE_ATTR_2(pwm##ix##_enable, S_IRUGO, \ | ||
| 1443 | show_pwm, NULL, SYS_PWM_ENABLE, ix-1) | ||
| 1444 | |||
| 1445 | SENSOR_DEVICE_ATTR_PWM_5TO6(5); | ||
| 1446 | SENSOR_DEVICE_ATTR_PWM_5TO6(6); | ||
| 1447 | |||
| 1448 | /* Misc */ | ||
| 1449 | |||
| 1450 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); | ||
| 1451 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | ||
| 1452 | |||
| 1453 | #define SENSOR_DEV_ATTR_IN(ix) \ | ||
| 1454 | &sensor_dev_attr_in##ix##_input.dev_attr.attr, \ | ||
| 1455 | &sensor_dev_attr_in##ix##_min.dev_attr.attr, \ | ||
| 1456 | &sensor_dev_attr_in##ix##_max.dev_attr.attr, \ | ||
| 1457 | &sensor_dev_attr_in##ix##_alarm.dev_attr.attr | ||
| 1458 | |||
| 1459 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
| 1460 | #define SENSOR_DEV_ATTR_TEMP_LOCK(ix) \ | ||
| 1461 | &sensor_dev_attr_temp##ix##_offset.dev_attr.attr | ||
| 1462 | |||
| 1463 | #define SENSOR_DEV_ATTR_TEMP(ix) \ | ||
| 1464 | SENSOR_DEV_ATTR_TEMP_LOCK(ix), \ | ||
| 1465 | &sensor_dev_attr_temp##ix##_input.dev_attr.attr, \ | ||
| 1466 | &sensor_dev_attr_temp##ix##_min.dev_attr.attr, \ | ||
| 1467 | &sensor_dev_attr_temp##ix##_max.dev_attr.attr, \ | ||
| 1468 | &sensor_dev_attr_temp##ix##_alarm.dev_attr.attr, \ | ||
| 1469 | &sensor_dev_attr_temp##ix##_fault.dev_attr.attr | ||
| 1470 | |||
| 1471 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
| 1472 | #define SENSOR_DEV_ATTR_ZONE_LOCK(ix) \ | ||
| 1473 | &sensor_dev_attr_zone##ix##_auto_point1_temp_hyst.dev_attr.attr, \ | ||
| 1474 | &sensor_dev_attr_zone##ix##_auto_point1_temp.dev_attr.attr, \ | ||
| 1475 | &sensor_dev_attr_zone##ix##_auto_point2_temp.dev_attr.attr, \ | ||
| 1476 | &sensor_dev_attr_zone##ix##_auto_point3_temp.dev_attr.attr | ||
| 1477 | |||
| 1478 | #define SENSOR_DEV_ATTR_ZONE(ix) \ | ||
| 1479 | SENSOR_DEV_ATTR_ZONE_LOCK(ix), \ | ||
| 1480 | &sensor_dev_attr_zone##ix##_auto_channels_temp.dev_attr.attr | ||
| 1481 | |||
| 1482 | #define SENSOR_DEV_ATTR_FAN_1TO4(ix) \ | ||
| 1483 | &sensor_dev_attr_fan##ix##_input.dev_attr.attr, \ | ||
| 1484 | &sensor_dev_attr_fan##ix##_min.dev_attr.attr, \ | ||
| 1485 | &sensor_dev_attr_fan##ix##_alarm.dev_attr.attr, \ | ||
| 1486 | &sensor_dev_attr_fan##ix##_type.dev_attr.attr | ||
| 1487 | |||
| 1488 | #define SENSOR_DEV_ATTR_FAN_5TO6(ix) \ | ||
| 1489 | &sensor_dev_attr_fan##ix##_input.dev_attr.attr, \ | ||
| 1490 | &sensor_dev_attr_fan##ix##_min.dev_attr.attr, \ | ||
| 1491 | &sensor_dev_attr_fan##ix##_alarm.dev_attr.attr, \ | ||
| 1492 | &sensor_dev_attr_fan##ix##_max.dev_attr.attr | ||
| 1493 | |||
| 1494 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
| 1495 | #define SENSOR_DEV_ATTR_PWM_1TO3_LOCK(ix) \ | ||
| 1496 | &sensor_dev_attr_pwm##ix##_freq.dev_attr.attr, \ | ||
| 1497 | &sensor_dev_attr_pwm##ix##_enable.dev_attr.attr, \ | ||
| 1498 | &sensor_dev_attr_pwm##ix##_ramp_rate.dev_attr.attr, \ | ||
| 1499 | &sensor_dev_attr_pwm##ix##_auto_channels_zone.dev_attr.attr, \ | ||
| 1500 | &sensor_dev_attr_pwm##ix##_auto_pwm_min.dev_attr.attr, \ | ||
| 1501 | &sensor_dev_attr_pwm##ix##_auto_point1_pwm.dev_attr.attr | ||
| 1502 | |||
| 1503 | #define SENSOR_DEV_ATTR_PWM_1TO3(ix) \ | ||
| 1504 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(ix), \ | ||
| 1505 | &sensor_dev_attr_pwm##ix.dev_attr.attr, \ | ||
| 1506 | &sensor_dev_attr_pwm##ix##_auto_point2_pwm.dev_attr.attr | ||
| 1507 | |||
| 1508 | /* These attributes are read-writeable only if the chip is *not* locked */ | ||
| 1509 | #define SENSOR_DEV_ATTR_PWM_5TO6_LOCK(ix) \ | ||
| 1510 | &sensor_dev_attr_pwm##ix.dev_attr.attr, \ | ||
| 1511 | &sensor_dev_attr_pwm##ix##_freq.dev_attr.attr | ||
| 1512 | |||
| 1513 | #define SENSOR_DEV_ATTR_PWM_5TO6(ix) \ | ||
| 1514 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(ix), \ | ||
| 1515 | &sensor_dev_attr_pwm##ix##_enable.dev_attr.attr | ||
| 1516 | |||
| 1517 | /* This struct holds all the attributes that are always present and need to be | ||
| 1518 | * created unconditionally. The attributes that need modification of their | ||
| 1519 | * permissions are created read-only and write permissions are added or removed | ||
| 1520 | * on the fly when required */ | ||
| 1521 | static struct attribute *dme1737_attr[] ={ | ||
| 1522 | /* Voltages */ | ||
| 1523 | SENSOR_DEV_ATTR_IN(0), | ||
| 1524 | SENSOR_DEV_ATTR_IN(1), | ||
| 1525 | SENSOR_DEV_ATTR_IN(2), | ||
| 1526 | SENSOR_DEV_ATTR_IN(3), | ||
| 1527 | SENSOR_DEV_ATTR_IN(4), | ||
| 1528 | SENSOR_DEV_ATTR_IN(5), | ||
| 1529 | SENSOR_DEV_ATTR_IN(6), | ||
| 1530 | /* Temperatures */ | ||
| 1531 | SENSOR_DEV_ATTR_TEMP(1), | ||
| 1532 | SENSOR_DEV_ATTR_TEMP(2), | ||
| 1533 | SENSOR_DEV_ATTR_TEMP(3), | ||
| 1534 | /* Zones */ | ||
| 1535 | SENSOR_DEV_ATTR_ZONE(1), | ||
| 1536 | SENSOR_DEV_ATTR_ZONE(2), | ||
| 1537 | SENSOR_DEV_ATTR_ZONE(3), | ||
| 1538 | /* Misc */ | ||
| 1539 | &dev_attr_vrm.attr, | ||
| 1540 | &dev_attr_cpu0_vid.attr, | ||
| 1541 | NULL | ||
| 1542 | }; | ||
| 1543 | |||
| 1544 | static const struct attribute_group dme1737_group = { | ||
| 1545 | .attrs = dme1737_attr, | ||
| 1546 | }; | ||
| 1547 | |||
| 1548 | /* The following structs hold the PWM attributes, some of which are optional. | ||
| 1549 | * Their creation depends on the chip configuration which is determined during | ||
| 1550 | * module load. */ | ||
| 1551 | static struct attribute *dme1737_attr_pwm1[] = { | ||
| 1552 | SENSOR_DEV_ATTR_PWM_1TO3(1), | ||
| 1553 | NULL | ||
| 1554 | }; | ||
| 1555 | static struct attribute *dme1737_attr_pwm2[] = { | ||
| 1556 | SENSOR_DEV_ATTR_PWM_1TO3(2), | ||
| 1557 | NULL | ||
| 1558 | }; | ||
| 1559 | static struct attribute *dme1737_attr_pwm3[] = { | ||
| 1560 | SENSOR_DEV_ATTR_PWM_1TO3(3), | ||
| 1561 | NULL | ||
| 1562 | }; | ||
| 1563 | static struct attribute *dme1737_attr_pwm5[] = { | ||
| 1564 | SENSOR_DEV_ATTR_PWM_5TO6(5), | ||
| 1565 | NULL | ||
| 1566 | }; | ||
| 1567 | static struct attribute *dme1737_attr_pwm6[] = { | ||
| 1568 | SENSOR_DEV_ATTR_PWM_5TO6(6), | ||
| 1569 | NULL | ||
| 1570 | }; | ||
| 1571 | |||
| 1572 | static const struct attribute_group dme1737_pwm_group[] = { | ||
| 1573 | { .attrs = dme1737_attr_pwm1 }, | ||
| 1574 | { .attrs = dme1737_attr_pwm2 }, | ||
| 1575 | { .attrs = dme1737_attr_pwm3 }, | ||
| 1576 | { .attrs = NULL }, | ||
| 1577 | { .attrs = dme1737_attr_pwm5 }, | ||
| 1578 | { .attrs = dme1737_attr_pwm6 }, | ||
| 1579 | }; | ||
| 1580 | |||
| 1581 | /* The following structs hold the fan attributes, some of which are optional. | ||
| 1582 | * Their creation depends on the chip configuration which is determined during | ||
| 1583 | * module load. */ | ||
| 1584 | static struct attribute *dme1737_attr_fan1[] = { | ||
| 1585 | SENSOR_DEV_ATTR_FAN_1TO4(1), | ||
| 1586 | NULL | ||
| 1587 | }; | ||
| 1588 | static struct attribute *dme1737_attr_fan2[] = { | ||
| 1589 | SENSOR_DEV_ATTR_FAN_1TO4(2), | ||
| 1590 | NULL | ||
| 1591 | }; | ||
| 1592 | static struct attribute *dme1737_attr_fan3[] = { | ||
| 1593 | SENSOR_DEV_ATTR_FAN_1TO4(3), | ||
| 1594 | NULL | ||
| 1595 | }; | ||
| 1596 | static struct attribute *dme1737_attr_fan4[] = { | ||
| 1597 | SENSOR_DEV_ATTR_FAN_1TO4(4), | ||
| 1598 | NULL | ||
| 1599 | }; | ||
| 1600 | static struct attribute *dme1737_attr_fan5[] = { | ||
| 1601 | SENSOR_DEV_ATTR_FAN_5TO6(5), | ||
| 1602 | NULL | ||
| 1603 | }; | ||
| 1604 | static struct attribute *dme1737_attr_fan6[] = { | ||
| 1605 | SENSOR_DEV_ATTR_FAN_5TO6(6), | ||
| 1606 | NULL | ||
| 1607 | }; | ||
| 1608 | |||
| 1609 | static const struct attribute_group dme1737_fan_group[] = { | ||
| 1610 | { .attrs = dme1737_attr_fan1 }, | ||
| 1611 | { .attrs = dme1737_attr_fan2 }, | ||
| 1612 | { .attrs = dme1737_attr_fan3 }, | ||
| 1613 | { .attrs = dme1737_attr_fan4 }, | ||
| 1614 | { .attrs = dme1737_attr_fan5 }, | ||
| 1615 | { .attrs = dme1737_attr_fan6 }, | ||
| 1616 | }; | ||
| 1617 | |||
| 1618 | /* The permissions of all of the following attributes are changed to read- | ||
| 1619 | * writeable if the chip is *not* locked. Otherwise they stay read-only. */ | ||
| 1620 | static struct attribute *dme1737_attr_lock[] = { | ||
| 1621 | /* Temperatures */ | ||
| 1622 | SENSOR_DEV_ATTR_TEMP_LOCK(1), | ||
| 1623 | SENSOR_DEV_ATTR_TEMP_LOCK(2), | ||
| 1624 | SENSOR_DEV_ATTR_TEMP_LOCK(3), | ||
| 1625 | /* Zones */ | ||
| 1626 | SENSOR_DEV_ATTR_ZONE_LOCK(1), | ||
| 1627 | SENSOR_DEV_ATTR_ZONE_LOCK(2), | ||
| 1628 | SENSOR_DEV_ATTR_ZONE_LOCK(3), | ||
| 1629 | NULL | ||
| 1630 | }; | ||
| 1631 | |||
| 1632 | static const struct attribute_group dme1737_lock_group = { | ||
| 1633 | .attrs = dme1737_attr_lock, | ||
| 1634 | }; | ||
| 1635 | |||
| 1636 | /* The permissions of the following PWM attributes are changed to read- | ||
| 1637 | * writeable if the chip is *not* locked and the respective PWM is available. | ||
| 1638 | * Otherwise they stay read-only. */ | ||
| 1639 | static struct attribute *dme1737_attr_pwm1_lock[] = { | ||
| 1640 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(1), | ||
| 1641 | NULL | ||
| 1642 | }; | ||
| 1643 | static struct attribute *dme1737_attr_pwm2_lock[] = { | ||
| 1644 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(2), | ||
| 1645 | NULL | ||
| 1646 | }; | ||
| 1647 | static struct attribute *dme1737_attr_pwm3_lock[] = { | ||
| 1648 | SENSOR_DEV_ATTR_PWM_1TO3_LOCK(3), | ||
| 1649 | NULL | ||
| 1650 | }; | ||
| 1651 | static struct attribute *dme1737_attr_pwm5_lock[] = { | ||
| 1652 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(5), | ||
| 1653 | NULL | ||
| 1654 | }; | ||
| 1655 | static struct attribute *dme1737_attr_pwm6_lock[] = { | ||
| 1656 | SENSOR_DEV_ATTR_PWM_5TO6_LOCK(6), | ||
| 1657 | NULL | ||
| 1658 | }; | ||
| 1659 | |||
| 1660 | static const struct attribute_group dme1737_pwm_lock_group[] = { | ||
| 1661 | { .attrs = dme1737_attr_pwm1_lock }, | ||
| 1662 | { .attrs = dme1737_attr_pwm2_lock }, | ||
| 1663 | { .attrs = dme1737_attr_pwm3_lock }, | ||
| 1664 | { .attrs = NULL }, | ||
| 1665 | { .attrs = dme1737_attr_pwm5_lock }, | ||
| 1666 | { .attrs = dme1737_attr_pwm6_lock }, | ||
| 1667 | }; | ||
| 1668 | |||
| 1669 | /* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the | ||
| 1670 | * chip is not locked. Otherwise they are read-only. */ | ||
| 1671 | static struct attribute *dme1737_attr_pwm[] = { | ||
| 1672 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
| 1673 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
| 1674 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
| 1675 | }; | ||
| 1676 | |||
| 1677 | /* --------------------------------------------------------------------- | ||
| 1678 | * Super-IO functions | ||
| 1679 | * --------------------------------------------------------------------- */ | ||
| 1680 | |||
| 1681 | static inline int dme1737_sio_inb(int sio_cip, int reg) | ||
| 1682 | { | ||
| 1683 | outb(reg, sio_cip); | ||
| 1684 | return inb(sio_cip + 1); | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | static inline void dme1737_sio_outb(int sio_cip, int reg, int val) | ||
| 1688 | { | ||
| 1689 | outb(reg, sio_cip); | ||
| 1690 | outb(val, sio_cip + 1); | ||
| 1691 | } | ||
| 1692 | |||
| 1693 | static int dme1737_sio_get_features(int sio_cip, struct i2c_client *client) | ||
| 1694 | { | ||
| 1695 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 1696 | int err = 0, reg; | ||
| 1697 | u16 addr; | ||
| 1698 | |||
| 1699 | /* Enter configuration mode */ | ||
| 1700 | outb(0x55, sio_cip); | ||
| 1701 | |||
| 1702 | /* Check device ID | ||
| 1703 | * The DME1737 can return either 0x78 or 0x77 as its device ID. */ | ||
| 1704 | reg = dme1737_sio_inb(sio_cip, 0x20); | ||
| 1705 | if (!(reg == 0x77 || reg == 0x78)) { | ||
| 1706 | err = -ENODEV; | ||
| 1707 | goto exit; | ||
| 1708 | } | ||
| 1709 | |||
| 1710 | /* Select logical device A (runtime registers) */ | ||
| 1711 | dme1737_sio_outb(sio_cip, 0x07, 0x0a); | ||
| 1712 | |||
| 1713 | /* Get the base address of the runtime registers */ | ||
| 1714 | if (!(addr = (dme1737_sio_inb(sio_cip, 0x60) << 8) | | ||
| 1715 | dme1737_sio_inb(sio_cip, 0x61))) { | ||
| 1716 | err = -ENODEV; | ||
| 1717 | goto exit; | ||
| 1718 | } | ||
| 1719 | |||
| 1720 | /* Read the runtime registers to determine which optional features | ||
| 1721 | * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set | ||
| 1722 | * to '10' if the respective feature is enabled. */ | ||
| 1723 | if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ | ||
| 1724 | data->has_fan |= (1 << 5); | ||
| 1725 | } | ||
| 1726 | if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ | ||
| 1727 | data->has_pwm |= (1 << 5); | ||
| 1728 | } | ||
| 1729 | if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ | ||
| 1730 | data->has_fan |= (1 << 4); | ||
| 1731 | } | ||
| 1732 | if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ | ||
| 1733 | data->has_pwm |= (1 << 4); | ||
| 1734 | } | ||
| 1735 | |||
| 1736 | exit: | ||
| 1737 | /* Exit configuration mode */ | ||
| 1738 | outb(0xaa, sio_cip); | ||
| 1739 | |||
| 1740 | return err; | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | /* --------------------------------------------------------------------- | ||
| 1744 | * Device detection, registration and initialization | ||
| 1745 | * --------------------------------------------------------------------- */ | ||
| 1746 | |||
| 1747 | static struct i2c_driver dme1737_driver; | ||
| 1748 | |||
| 1749 | static void dme1737_chmod_file(struct i2c_client *client, | ||
| 1750 | struct attribute *attr, mode_t mode) | ||
| 1751 | { | ||
| 1752 | if (sysfs_chmod_file(&client->dev.kobj, attr, mode)) { | ||
| 1753 | dev_warn(&client->dev, "Failed to change permissions of %s.\n", | ||
| 1754 | attr->name); | ||
| 1755 | } | ||
| 1756 | } | ||
| 1757 | |||
| 1758 | static void dme1737_chmod_group(struct i2c_client *client, | ||
| 1759 | const struct attribute_group *group, | ||
| 1760 | mode_t mode) | ||
| 1761 | { | ||
| 1762 | struct attribute **attr; | ||
| 1763 | |||
| 1764 | for (attr = group->attrs; *attr; attr++) { | ||
| 1765 | dme1737_chmod_file(client, *attr, mode); | ||
| 1766 | } | ||
| 1767 | } | ||
| 1768 | |||
| 1769 | static int dme1737_init_client(struct i2c_client *client) | ||
| 1770 | { | ||
| 1771 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 1772 | int ix; | ||
| 1773 | u8 reg; | ||
| 1774 | |||
| 1775 | data->config = dme1737_read(client, DME1737_REG_CONFIG); | ||
| 1776 | /* Inform if part is not monitoring/started */ | ||
| 1777 | if (!(data->config & 0x01)) { | ||
| 1778 | if (!force_start) { | ||
| 1779 | dev_err(&client->dev, "Device is not monitoring. " | ||
| 1780 | "Use the force_start load parameter to " | ||
| 1781 | "override.\n"); | ||
| 1782 | return -EFAULT; | ||
| 1783 | } | ||
| 1784 | |||
| 1785 | /* Force monitoring */ | ||
| 1786 | data->config |= 0x01; | ||
| 1787 | dme1737_write(client, DME1737_REG_CONFIG, data->config); | ||
| 1788 | } | ||
| 1789 | /* Inform if part is not ready */ | ||
| 1790 | if (!(data->config & 0x04)) { | ||
| 1791 | dev_err(&client->dev, "Device is not ready.\n"); | ||
| 1792 | return -EFAULT; | ||
| 1793 | } | ||
| 1794 | |||
| 1795 | data->config2 = dme1737_read(client, DME1737_REG_CONFIG2); | ||
| 1796 | /* Check if optional fan3 input is enabled */ | ||
| 1797 | if (data->config2 & 0x04) { | ||
| 1798 | data->has_fan |= (1 << 2); | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | /* Fan4 and pwm3 are only available if the client's I2C address | ||
| 1802 | * is the default 0x2e. Otherwise the I/Os associated with these | ||
| 1803 | * functions are used for addr enable/select. */ | ||
| 1804 | if (client->addr == 0x2e) { | ||
| 1805 | data->has_fan |= (1 << 3); | ||
| 1806 | data->has_pwm |= (1 << 2); | ||
| 1807 | } | ||
| 1808 | |||
| 1809 | /* Determine if the optional fan[5-6] and/or pwm[5-6] are enabled. | ||
| 1810 | * For this, we need to query the runtime registers through the | ||
| 1811 | * Super-IO LPC interface. Try both config ports 0x2e and 0x4e. */ | ||
| 1812 | if (dme1737_sio_get_features(0x2e, client) && | ||
| 1813 | dme1737_sio_get_features(0x4e, client)) { | ||
| 1814 | dev_warn(&client->dev, "Failed to query Super-IO for optional " | ||
| 1815 | "features.\n"); | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | /* Fan1, fan2, pwm1, and pwm2 are always present */ | ||
| 1819 | data->has_fan |= 0x03; | ||
| 1820 | data->has_pwm |= 0x03; | ||
| 1821 | |||
| 1822 | dev_info(&client->dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " | ||
| 1823 | "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", | ||
| 1824 | (data->has_pwm & (1 << 2)) ? "yes" : "no", | ||
| 1825 | (data->has_pwm & (1 << 4)) ? "yes" : "no", | ||
| 1826 | (data->has_pwm & (1 << 5)) ? "yes" : "no", | ||
| 1827 | (data->has_fan & (1 << 2)) ? "yes" : "no", | ||
| 1828 | (data->has_fan & (1 << 3)) ? "yes" : "no", | ||
| 1829 | (data->has_fan & (1 << 4)) ? "yes" : "no", | ||
| 1830 | (data->has_fan & (1 << 5)) ? "yes" : "no"); | ||
| 1831 | |||
| 1832 | reg = dme1737_read(client, DME1737_REG_TACH_PWM); | ||
| 1833 | /* Inform if fan-to-pwm mapping differs from the default */ | ||
| 1834 | if (reg != 0xa4) { | ||
| 1835 | dev_warn(&client->dev, "Non-standard fan to pwm mapping: " | ||
| 1836 | "fan1->pwm%d, fan2->pwm%d, fan3->pwm%d, " | ||
| 1837 | "fan4->pwm%d. Please report to the driver " | ||
| 1838 | "maintainer.\n", | ||
| 1839 | (reg & 0x03) + 1, ((reg >> 2) & 0x03) + 1, | ||
| 1840 | ((reg >> 4) & 0x03) + 1, ((reg >> 6) & 0x03) + 1); | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | /* Switch pwm[1-3] to manual mode if they are currently disabled and | ||
| 1844 | * set the duty-cycles to 0% (which is identical to the PWMs being | ||
| 1845 | * disabled). */ | ||
| 1846 | if (!(data->config & 0x02)) { | ||
| 1847 | for (ix = 0; ix < 3; ix++) { | ||
| 1848 | data->pwm_config[ix] = dme1737_read(client, | ||
| 1849 | DME1737_REG_PWM_CONFIG(ix)); | ||
| 1850 | if ((data->has_pwm & (1 << ix)) && | ||
| 1851 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { | ||
| 1852 | dev_info(&client->dev, "Switching pwm%d to " | ||
| 1853 | "manual mode.\n", ix + 1); | ||
| 1854 | data->pwm_config[ix] = PWM_EN_TO_REG(1, | ||
| 1855 | data->pwm_config[ix]); | ||
| 1856 | dme1737_write(client, DME1737_REG_PWM(ix), 0); | ||
| 1857 | dme1737_write(client, | ||
| 1858 | DME1737_REG_PWM_CONFIG(ix), | ||
| 1859 | data->pwm_config[ix]); | ||
| 1860 | } | ||
| 1861 | } | ||
| 1862 | } | ||
| 1863 | |||
| 1864 | /* Initialize the default PWM auto channels zone (acz) assignments */ | ||
| 1865 | data->pwm_acz[0] = 1; /* pwm1 -> zone1 */ | ||
| 1866 | data->pwm_acz[1] = 2; /* pwm2 -> zone2 */ | ||
| 1867 | data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ | ||
| 1868 | |||
| 1869 | /* Set VRM */ | ||
| 1870 | data->vrm = vid_which_vrm(); | ||
| 1871 | |||
| 1872 | return 0; | ||
| 1873 | } | ||
| 1874 | |||
| 1875 | static int dme1737_detect(struct i2c_adapter *adapter, int address, | ||
| 1876 | int kind) | ||
| 1877 | { | ||
| 1878 | u8 company, verstep = 0; | ||
| 1879 | struct i2c_client *client; | ||
| 1880 | struct dme1737_data *data; | ||
| 1881 | int ix, err = 0; | ||
| 1882 | const char *name; | ||
| 1883 | |||
| 1884 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
| 1885 | goto exit; | ||
| 1886 | } | ||
| 1887 | |||
| 1888 | if (!(data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL))) { | ||
| 1889 | err = -ENOMEM; | ||
| 1890 | goto exit; | ||
| 1891 | } | ||
| 1892 | |||
| 1893 | client = &data->client; | ||
| 1894 | i2c_set_clientdata(client, data); | ||
| 1895 | client->addr = address; | ||
| 1896 | client->adapter = adapter; | ||
| 1897 | client->driver = &dme1737_driver; | ||
| 1898 | |||
| 1899 | /* A negative kind means that the driver was loaded with no force | ||
| 1900 | * parameter (default), so we must identify the chip. */ | ||
| 1901 | if (kind < 0) { | ||
| 1902 | company = dme1737_read(client, DME1737_REG_COMPANY); | ||
| 1903 | verstep = dme1737_read(client, DME1737_REG_VERSTEP); | ||
| 1904 | |||
| 1905 | if (!((company == DME1737_COMPANY_SMSC) && | ||
| 1906 | ((verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP))) { | ||
| 1907 | err = -ENODEV; | ||
| 1908 | goto exit_kfree; | ||
| 1909 | } | ||
| 1910 | } | ||
| 1911 | |||
| 1912 | kind = dme1737; | ||
| 1913 | name = "dme1737"; | ||
| 1914 | |||
| 1915 | /* Fill in the remaining client fields and put it into the global | ||
| 1916 | * list */ | ||
| 1917 | strlcpy(client->name, name, I2C_NAME_SIZE); | ||
| 1918 | mutex_init(&data->update_lock); | ||
| 1919 | |||
| 1920 | /* Tell the I2C layer a new client has arrived */ | ||
| 1921 | if ((err = i2c_attach_client(client))) { | ||
| 1922 | goto exit_kfree; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | /* Initialize the DME1737 chip */ | ||
| 1926 | if ((err = dme1737_init_client(client))) { | ||
| 1927 | goto exit_detach; | ||
| 1928 | } | ||
| 1929 | |||
| 1930 | /* Create standard sysfs attributes */ | ||
| 1931 | if ((err = sysfs_create_group(&client->dev.kobj, &dme1737_group))) { | ||
| 1932 | goto exit_detach; | ||
| 1933 | } | ||
| 1934 | |||
| 1935 | /* Create fan sysfs attributes */ | ||
| 1936 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | ||
| 1937 | if (data->has_fan & (1 << ix)) { | ||
| 1938 | if ((err = sysfs_create_group(&client->dev.kobj, | ||
| 1939 | &dme1737_fan_group[ix]))) { | ||
| 1940 | goto exit_remove; | ||
| 1941 | } | ||
| 1942 | } | ||
| 1943 | } | ||
| 1944 | |||
| 1945 | /* Create PWM sysfs attributes */ | ||
| 1946 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | ||
| 1947 | if (data->has_pwm & (1 << ix)) { | ||
| 1948 | if ((err = sysfs_create_group(&client->dev.kobj, | ||
| 1949 | &dme1737_pwm_group[ix]))) { | ||
| 1950 | goto exit_remove; | ||
| 1951 | } | ||
| 1952 | } | ||
| 1953 | } | ||
| 1954 | |||
| 1955 | /* Inform if the device is locked. Otherwise change the permissions of | ||
| 1956 | * selected attributes from read-only to read-writeable. */ | ||
| 1957 | if (data->config & 0x02) { | ||
| 1958 | dev_info(&client->dev, "Device is locked. Some attributes " | ||
| 1959 | "will be read-only.\n"); | ||
| 1960 | } else { | ||
| 1961 | /* Change permissions of standard attributes */ | ||
| 1962 | dme1737_chmod_group(client, &dme1737_lock_group, | ||
| 1963 | S_IRUGO | S_IWUSR); | ||
| 1964 | |||
| 1965 | /* Change permissions of PWM attributes */ | ||
| 1966 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_lock_group); ix++) { | ||
| 1967 | if (data->has_pwm & (1 << ix)) { | ||
| 1968 | dme1737_chmod_group(client, | ||
| 1969 | &dme1737_pwm_lock_group[ix], | ||
| 1970 | S_IRUGO | S_IWUSR); | ||
| 1971 | } | ||
| 1972 | } | ||
| 1973 | |||
| 1974 | /* Change permissions of pwm[1-3] if in manual mode */ | ||
| 1975 | for (ix = 0; ix < 3; ix++) { | ||
| 1976 | if ((data->has_pwm & (1 << ix)) && | ||
| 1977 | (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { | ||
| 1978 | dme1737_chmod_file(client, | ||
| 1979 | dme1737_attr_pwm[ix], | ||
| 1980 | S_IRUGO | S_IWUSR); | ||
| 1981 | } | ||
| 1982 | } | ||
| 1983 | } | ||
| 1984 | |||
| 1985 | /* Register device */ | ||
| 1986 | data->class_dev = hwmon_device_register(&client->dev); | ||
| 1987 | if (IS_ERR(data->class_dev)) { | ||
| 1988 | err = PTR_ERR(data->class_dev); | ||
| 1989 | goto exit_remove; | ||
| 1990 | } | ||
| 1991 | |||
| 1992 | dev_info(&adapter->dev, "Found a DME1737 chip at 0x%02x " | ||
| 1993 | "(rev 0x%02x)\n", client->addr, verstep); | ||
| 1994 | |||
| 1995 | return 0; | ||
| 1996 | |||
| 1997 | exit_remove: | ||
| 1998 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | ||
| 1999 | if (data->has_fan & (1 << ix)) { | ||
| 2000 | sysfs_remove_group(&client->dev.kobj, | ||
| 2001 | &dme1737_fan_group[ix]); | ||
| 2002 | } | ||
| 2003 | } | ||
| 2004 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | ||
| 2005 | if (data->has_pwm & (1 << ix)) { | ||
| 2006 | sysfs_remove_group(&client->dev.kobj, | ||
| 2007 | &dme1737_pwm_group[ix]); | ||
| 2008 | } | ||
| 2009 | } | ||
| 2010 | sysfs_remove_group(&client->dev.kobj, &dme1737_group); | ||
| 2011 | exit_detach: | ||
| 2012 | i2c_detach_client(client); | ||
| 2013 | exit_kfree: | ||
| 2014 | kfree(data); | ||
| 2015 | exit: | ||
| 2016 | return err; | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | static int dme1737_attach_adapter(struct i2c_adapter *adapter) | ||
| 2020 | { | ||
| 2021 | if (!(adapter->class & I2C_CLASS_HWMON)) { | ||
| 2022 | return 0; | ||
| 2023 | } | ||
| 2024 | |||
| 2025 | return i2c_probe(adapter, &addr_data, dme1737_detect); | ||
| 2026 | } | ||
| 2027 | |||
| 2028 | static int dme1737_detach_client(struct i2c_client *client) | ||
| 2029 | { | ||
| 2030 | struct dme1737_data *data = i2c_get_clientdata(client); | ||
| 2031 | int ix, err; | ||
| 2032 | |||
| 2033 | hwmon_device_unregister(data->class_dev); | ||
| 2034 | |||
| 2035 | for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { | ||
| 2036 | if (data->has_fan & (1 << ix)) { | ||
| 2037 | sysfs_remove_group(&client->dev.kobj, | ||
| 2038 | &dme1737_fan_group[ix]); | ||
| 2039 | } | ||
| 2040 | } | ||
| 2041 | for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { | ||
| 2042 | if (data->has_pwm & (1 << ix)) { | ||
| 2043 | sysfs_remove_group(&client->dev.kobj, | ||
| 2044 | &dme1737_pwm_group[ix]); | ||
| 2045 | } | ||
| 2046 | } | ||
| 2047 | sysfs_remove_group(&client->dev.kobj, &dme1737_group); | ||
| 2048 | |||
| 2049 | if ((err = i2c_detach_client(client))) { | ||
| 2050 | return err; | ||
| 2051 | } | ||
| 2052 | |||
| 2053 | kfree(data); | ||
| 2054 | return 0; | ||
| 2055 | } | ||
| 2056 | |||
| 2057 | static struct i2c_driver dme1737_driver = { | ||
| 2058 | .driver = { | ||
| 2059 | .name = "dme1737", | ||
| 2060 | }, | ||
| 2061 | .attach_adapter = dme1737_attach_adapter, | ||
| 2062 | .detach_client = dme1737_detach_client, | ||
| 2063 | }; | ||
| 2064 | |||
| 2065 | static int __init dme1737_init(void) | ||
| 2066 | { | ||
| 2067 | return i2c_add_driver(&dme1737_driver); | ||
| 2068 | } | ||
| 2069 | |||
| 2070 | static void __exit dme1737_exit(void) | ||
| 2071 | { | ||
| 2072 | i2c_del_driver(&dme1737_driver); | ||
| 2073 | } | ||
| 2074 | |||
| 2075 | MODULE_AUTHOR("Juerg Haefliger <juergh@gmail.com>"); | ||
| 2076 | MODULE_DESCRIPTION("DME1737 sensors"); | ||
| 2077 | MODULE_LICENSE("GPL"); | ||
| 2078 | |||
| 2079 | module_init(dme1737_init); | ||
| 2080 | module_exit(dme1737_exit); | ||
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index d5ac422d73b2..1212d6b7f316 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/jiffies.h> | 27 | #include <linux/jiffies.h> |
| 28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
| 29 | #include <linux/hwmon.h> | 29 | #include <linux/hwmon.h> |
| 30 | #include <linux/hwmon-sysfs.h> | ||
| 30 | #include <linux/err.h> | 31 | #include <linux/err.h> |
| 31 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
| 32 | #include <linux/sysfs.h> | 33 | #include <linux/sysfs.h> |
| @@ -52,9 +53,11 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low") | |||
| 52 | #define DS1621_REG_CONFIG_DONE 0x80 | 53 | #define DS1621_REG_CONFIG_DONE 0x80 |
| 53 | 54 | ||
| 54 | /* The DS1621 registers */ | 55 | /* The DS1621 registers */ |
| 55 | #define DS1621_REG_TEMP 0xAA /* word, RO */ | 56 | static const u8 DS1621_REG_TEMP[3] = { |
| 56 | #define DS1621_REG_TEMP_MIN 0xA2 /* word, RW */ | 57 | 0xAA, /* input, word, RO */ |
| 57 | #define DS1621_REG_TEMP_MAX 0xA1 /* word, RW */ | 58 | 0xA2, /* min, word, RW */ |
| 59 | 0xA1, /* max, word, RW */ | ||
| 60 | }; | ||
| 58 | #define DS1621_REG_CONF 0xAC /* byte, RW */ | 61 | #define DS1621_REG_CONF 0xAC /* byte, RW */ |
| 59 | #define DS1621_COM_START 0xEE /* no data */ | 62 | #define DS1621_COM_START 0xEE /* no data */ |
| 60 | #define DS1621_COM_STOP 0x22 /* no data */ | 63 | #define DS1621_COM_STOP 0x22 /* no data */ |
| @@ -63,10 +66,7 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low") | |||
| 63 | #define DS1621_ALARM_TEMP_HIGH 0x40 | 66 | #define DS1621_ALARM_TEMP_HIGH 0x40 |
| 64 | #define DS1621_ALARM_TEMP_LOW 0x20 | 67 | #define DS1621_ALARM_TEMP_LOW 0x20 |
| 65 | 68 | ||
| 66 | /* Conversions. Rounding and limit checking is only done on the TO_REG | 69 | /* Conversions */ |
| 67 | variants. Note that you should be a bit careful with which arguments | ||
| 68 | these macros are called: arguments may be evaluated more than once. | ||
| 69 | Fixing this is just not worth it. */ | ||
| 70 | #define ALARMS_FROM_REG(val) ((val) & \ | 70 | #define ALARMS_FROM_REG(val) ((val) & \ |
| 71 | (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW)) | 71 | (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW)) |
| 72 | 72 | ||
| @@ -78,7 +78,7 @@ struct ds1621_data { | |||
| 78 | char valid; /* !=0 if following fields are valid */ | 78 | char valid; /* !=0 if following fields are valid */ |
| 79 | unsigned long last_updated; /* In jiffies */ | 79 | unsigned long last_updated; /* In jiffies */ |
| 80 | 80 | ||
| 81 | u16 temp, temp_min, temp_max; /* Register values, word */ | 81 | u16 temp[3]; /* Register values, word */ |
| 82 | u8 conf; /* Register encoding, combined */ | 82 | u8 conf; /* Register encoding, combined */ |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| @@ -101,7 +101,7 @@ static struct i2c_driver ds1621_driver = { | |||
| 101 | 101 | ||
| 102 | /* All registers are word-sized, except for the configuration register. | 102 | /* All registers are word-sized, except for the configuration register. |
| 103 | DS1621 uses a high-byte first convention, which is exactly opposite to | 103 | DS1621 uses a high-byte first convention, which is exactly opposite to |
| 104 | the usual practice. */ | 104 | the SMBus standard. */ |
| 105 | static int ds1621_read_value(struct i2c_client *client, u8 reg) | 105 | static int ds1621_read_value(struct i2c_client *client, u8 reg) |
| 106 | { | 106 | { |
| 107 | if (reg == DS1621_REG_CONF) | 107 | if (reg == DS1621_REG_CONF) |
| @@ -110,9 +110,6 @@ static int ds1621_read_value(struct i2c_client *client, u8 reg) | |||
| 110 | return swab16(i2c_smbus_read_word_data(client, reg)); | 110 | return swab16(i2c_smbus_read_word_data(client, reg)); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | /* All registers are word-sized, except for the configuration register. | ||
| 114 | DS1621 uses a high-byte first convention, which is exactly opposite to | ||
| 115 | the usual practice. */ | ||
| 116 | static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) | 113 | static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) |
| 117 | { | 114 | { |
| 118 | if (reg == DS1621_REG_CONF) | 115 | if (reg == DS1621_REG_CONF) |
| @@ -139,50 +136,61 @@ static void ds1621_init_client(struct i2c_client *client) | |||
| 139 | i2c_smbus_write_byte(client, DS1621_COM_START); | 136 | i2c_smbus_write_byte(client, DS1621_COM_START); |
| 140 | } | 137 | } |
| 141 | 138 | ||
| 142 | #define show(value) \ | 139 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, |
| 143 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ | 140 | char *buf) |
| 144 | { \ | 141 | { |
| 145 | struct ds1621_data *data = ds1621_update_client(dev); \ | 142 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 146 | return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value)); \ | 143 | struct ds1621_data *data = ds1621_update_client(dev); |
| 144 | return sprintf(buf, "%d\n", | ||
| 145 | LM75_TEMP_FROM_REG(data->temp[attr->index])); | ||
| 147 | } | 146 | } |
| 148 | 147 | ||
| 149 | show(temp); | 148 | static ssize_t set_temp(struct device *dev, struct device_attribute *da, |
| 150 | show(temp_min); | 149 | const char *buf, size_t count) |
| 151 | show(temp_max); | 150 | { |
| 152 | 151 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | |
| 153 | #define set_temp(suffix, value, reg) \ | 152 | struct i2c_client *client = to_i2c_client(dev); |
| 154 | static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ | 153 | struct ds1621_data *data = ds1621_update_client(dev); |
| 155 | size_t count) \ | 154 | u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); |
| 156 | { \ | ||
| 157 | struct i2c_client *client = to_i2c_client(dev); \ | ||
| 158 | struct ds1621_data *data = ds1621_update_client(dev); \ | ||
| 159 | u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \ | ||
| 160 | \ | ||
| 161 | mutex_lock(&data->update_lock); \ | ||
| 162 | data->value = val; \ | ||
| 163 | ds1621_write_value(client, reg, data->value); \ | ||
| 164 | mutex_unlock(&data->update_lock); \ | ||
| 165 | return count; \ | ||
| 166 | } | ||
| 167 | 155 | ||
| 168 | set_temp(min, temp_min, DS1621_REG_TEMP_MIN); | 156 | mutex_lock(&data->update_lock); |
| 169 | set_temp(max, temp_max, DS1621_REG_TEMP_MAX); | 157 | data->temp[attr->index] = val; |
| 158 | ds1621_write_value(client, DS1621_REG_TEMP[attr->index], | ||
| 159 | data->temp[attr->index]); | ||
| 160 | mutex_unlock(&data->update_lock); | ||
| 161 | return count; | ||
| 162 | } | ||
| 170 | 163 | ||
| 171 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) | 164 | static ssize_t show_alarms(struct device *dev, struct device_attribute *da, |
| 165 | char *buf) | ||
| 172 | { | 166 | { |
| 173 | struct ds1621_data *data = ds1621_update_client(dev); | 167 | struct ds1621_data *data = ds1621_update_client(dev); |
| 174 | return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->conf)); | 168 | return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->conf)); |
| 175 | } | 169 | } |
| 176 | 170 | ||
| 171 | static ssize_t show_alarm(struct device *dev, struct device_attribute *da, | ||
| 172 | char *buf) | ||
| 173 | { | ||
| 174 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 175 | struct ds1621_data *data = ds1621_update_client(dev); | ||
| 176 | return sprintf(buf, "%d\n", !!(data->conf & attr->index)); | ||
| 177 | } | ||
| 178 | |||
| 177 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 179 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
| 178 | static DEVICE_ATTR(temp1_input, S_IRUGO , show_temp, NULL); | 180 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); |
| 179 | static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO , show_temp_min, set_temp_min); | 181 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp, set_temp, 1); |
| 180 | static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); | 182 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp, set_temp, 2); |
| 183 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, | ||
| 184 | DS1621_ALARM_TEMP_LOW); | ||
| 185 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, | ||
| 186 | DS1621_ALARM_TEMP_HIGH); | ||
| 181 | 187 | ||
| 182 | static struct attribute *ds1621_attributes[] = { | 188 | static struct attribute *ds1621_attributes[] = { |
| 183 | &dev_attr_temp1_input.attr, | 189 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
| 184 | &dev_attr_temp1_min.attr, | 190 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
| 185 | &dev_attr_temp1_max.attr, | 191 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
| 192 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
| 193 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
| 186 | &dev_attr_alarms.attr, | 194 | &dev_attr_alarms.attr, |
| 187 | NULL | 195 | NULL |
| 188 | }; | 196 | }; |
| @@ -204,9 +212,9 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, | |||
| 204 | int kind) | 212 | int kind) |
| 205 | { | 213 | { |
| 206 | int conf, temp; | 214 | int conf, temp; |
| 207 | struct i2c_client *new_client; | 215 | struct i2c_client *client; |
| 208 | struct ds1621_data *data; | 216 | struct ds1621_data *data; |
| 209 | int err = 0; | 217 | int i, err = 0; |
| 210 | 218 | ||
| 211 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 219 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
| 212 | | I2C_FUNC_SMBUS_WORD_DATA | 220 | | I2C_FUNC_SMBUS_WORD_DATA |
| @@ -221,55 +229,44 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, | |||
| 221 | goto exit; | 229 | goto exit; |
| 222 | } | 230 | } |
| 223 | 231 | ||
| 224 | new_client = &data->client; | 232 | client = &data->client; |
| 225 | i2c_set_clientdata(new_client, data); | 233 | i2c_set_clientdata(client, data); |
| 226 | new_client->addr = address; | 234 | client->addr = address; |
| 227 | new_client->adapter = adapter; | 235 | client->adapter = adapter; |
| 228 | new_client->driver = &ds1621_driver; | 236 | client->driver = &ds1621_driver; |
| 229 | new_client->flags = 0; | ||
| 230 | |||
| 231 | 237 | ||
| 232 | /* Now, we do the remaining detection. It is lousy. */ | 238 | /* Now, we do the remaining detection. It is lousy. */ |
| 233 | if (kind < 0) { | 239 | if (kind < 0) { |
| 234 | /* The NVB bit should be low if no EEPROM write has been | 240 | /* The NVB bit should be low if no EEPROM write has been |
| 235 | requested during the latest 10ms, which is highly | 241 | requested during the latest 10ms, which is highly |
| 236 | improbable in our case. */ | 242 | improbable in our case. */ |
| 237 | conf = ds1621_read_value(new_client, DS1621_REG_CONF); | 243 | conf = ds1621_read_value(client, DS1621_REG_CONF); |
| 238 | if (conf & DS1621_REG_CONFIG_NVB) | 244 | if (conf & DS1621_REG_CONFIG_NVB) |
| 239 | goto exit_free; | 245 | goto exit_free; |
| 240 | /* The 7 lowest bits of a temperature should always be 0. */ | 246 | /* The 7 lowest bits of a temperature should always be 0. */ |
| 241 | temp = ds1621_read_value(new_client, DS1621_REG_TEMP); | 247 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { |
| 242 | if (temp & 0x007f) | 248 | temp = ds1621_read_value(client, DS1621_REG_TEMP[i]); |
| 243 | goto exit_free; | 249 | if (temp & 0x007f) |
| 244 | temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MIN); | 250 | goto exit_free; |
| 245 | if (temp & 0x007f) | 251 | } |
| 246 | goto exit_free; | ||
| 247 | temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MAX); | ||
| 248 | if (temp & 0x007f) | ||
| 249 | goto exit_free; | ||
| 250 | } | 252 | } |
| 251 | 253 | ||
| 252 | /* Determine the chip type - only one kind supported! */ | ||
| 253 | if (kind <= 0) | ||
| 254 | kind = ds1621; | ||
| 255 | |||
| 256 | /* Fill in remaining client fields and put it into the global list */ | 254 | /* Fill in remaining client fields and put it into the global list */ |
| 257 | strlcpy(new_client->name, "ds1621", I2C_NAME_SIZE); | 255 | strlcpy(client->name, "ds1621", I2C_NAME_SIZE); |
| 258 | data->valid = 0; | ||
| 259 | mutex_init(&data->update_lock); | 256 | mutex_init(&data->update_lock); |
| 260 | 257 | ||
| 261 | /* Tell the I2C layer a new client has arrived */ | 258 | /* Tell the I2C layer a new client has arrived */ |
| 262 | if ((err = i2c_attach_client(new_client))) | 259 | if ((err = i2c_attach_client(client))) |
| 263 | goto exit_free; | 260 | goto exit_free; |
| 264 | 261 | ||
| 265 | /* Initialize the DS1621 chip */ | 262 | /* Initialize the DS1621 chip */ |
| 266 | ds1621_init_client(new_client); | 263 | ds1621_init_client(client); |
| 267 | 264 | ||
| 268 | /* Register sysfs hooks */ | 265 | /* Register sysfs hooks */ |
| 269 | if ((err = sysfs_create_group(&new_client->dev.kobj, &ds1621_group))) | 266 | if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group))) |
| 270 | goto exit_detach; | 267 | goto exit_detach; |
| 271 | 268 | ||
| 272 | data->class_dev = hwmon_device_register(&new_client->dev); | 269 | data->class_dev = hwmon_device_register(&client->dev); |
| 273 | if (IS_ERR(data->class_dev)) { | 270 | if (IS_ERR(data->class_dev)) { |
| 274 | err = PTR_ERR(data->class_dev); | 271 | err = PTR_ERR(data->class_dev); |
| 275 | goto exit_remove_files; | 272 | goto exit_remove_files; |
| @@ -278,9 +275,9 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, | |||
| 278 | return 0; | 275 | return 0; |
| 279 | 276 | ||
| 280 | exit_remove_files: | 277 | exit_remove_files: |
| 281 | sysfs_remove_group(&new_client->dev.kobj, &ds1621_group); | 278 | sysfs_remove_group(&client->dev.kobj, &ds1621_group); |
| 282 | exit_detach: | 279 | exit_detach: |
| 283 | i2c_detach_client(new_client); | 280 | i2c_detach_client(client); |
| 284 | exit_free: | 281 | exit_free: |
| 285 | kfree(data); | 282 | kfree(data); |
| 286 | exit: | 283 | exit: |
| @@ -314,23 +311,21 @@ static struct ds1621_data *ds1621_update_client(struct device *dev) | |||
| 314 | 311 | ||
| 315 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 312 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
| 316 | || !data->valid) { | 313 | || !data->valid) { |
| 314 | int i; | ||
| 317 | 315 | ||
| 318 | dev_dbg(&client->dev, "Starting ds1621 update\n"); | 316 | dev_dbg(&client->dev, "Starting ds1621 update\n"); |
| 319 | 317 | ||
| 320 | data->conf = ds1621_read_value(client, DS1621_REG_CONF); | 318 | data->conf = ds1621_read_value(client, DS1621_REG_CONF); |
| 321 | 319 | ||
| 322 | data->temp = ds1621_read_value(client, DS1621_REG_TEMP); | 320 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) |
| 323 | 321 | data->temp[i] = ds1621_read_value(client, | |
| 324 | data->temp_min = ds1621_read_value(client, | 322 | DS1621_REG_TEMP[i]); |
| 325 | DS1621_REG_TEMP_MIN); | ||
| 326 | data->temp_max = ds1621_read_value(client, | ||
| 327 | DS1621_REG_TEMP_MAX); | ||
| 328 | 323 | ||
| 329 | /* reset alarms if necessary */ | 324 | /* reset alarms if necessary */ |
| 330 | new_conf = data->conf; | 325 | new_conf = data->conf; |
| 331 | if (data->temp > data->temp_min) | 326 | if (data->temp[0] > data->temp[1]) /* input > min */ |
| 332 | new_conf &= ~DS1621_ALARM_TEMP_LOW; | 327 | new_conf &= ~DS1621_ALARM_TEMP_LOW; |
| 333 | if (data->temp < data->temp_max) | 328 | if (data->temp[0] < data->temp[2]) /* input < max */ |
| 334 | new_conf &= ~DS1621_ALARM_TEMP_HIGH; | 329 | new_conf &= ~DS1621_ALARM_TEMP_HIGH; |
| 335 | if (data->conf != new_conf) | 330 | if (data->conf != new_conf) |
| 336 | ds1621_write_value(client, DS1621_REG_CONF, | 331 | ds1621_write_value(client, DS1621_REG_CONF, |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index cdbe309b8fc4..6f60715f34f8 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c | |||
| @@ -127,6 +127,13 @@ superio_exit(int base) | |||
| 127 | #define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) | 127 | #define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) |
| 128 | #define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr)) | 128 | #define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr)) |
| 129 | #define F71805F_REG_TEMP_MODE 0x01 | 129 | #define F71805F_REG_TEMP_MODE 0x01 |
| 130 | /* pwm/fan pwmnr from 0 to 2, auto point apnr from 0 to 2 */ | ||
| 131 | /* map Fintek numbers to our numbers as follows: 9->0, 5->1, 1->2 */ | ||
| 132 | #define F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr) \ | ||
| 133 | (0xA0 + 0x10 * (pwmnr) + (2 - (apnr))) | ||
| 134 | #define F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr) \ | ||
| 135 | (0xA4 + 0x10 * (pwmnr) + \ | ||
| 136 | 2 * (2 - (apnr))) | ||
| 130 | 137 | ||
| 131 | #define F71805F_REG_START 0x00 | 138 | #define F71805F_REG_START 0x00 |
| 132 | /* status nr from 0 to 2 */ | 139 | /* status nr from 0 to 2 */ |
| @@ -144,6 +151,11 @@ superio_exit(int base) | |||
| 144 | * Data structures and manipulation thereof | 151 | * Data structures and manipulation thereof |
| 145 | */ | 152 | */ |
| 146 | 153 | ||
| 154 | struct f71805f_auto_point { | ||
| 155 | u8 temp[3]; | ||
| 156 | u16 fan[3]; | ||
| 157 | }; | ||
| 158 | |||
| 147 | struct f71805f_data { | 159 | struct f71805f_data { |
| 148 | unsigned short addr; | 160 | unsigned short addr; |
| 149 | const char *name; | 161 | const char *name; |
| @@ -170,6 +182,7 @@ struct f71805f_data { | |||
| 170 | u8 temp_hyst[3]; | 182 | u8 temp_hyst[3]; |
| 171 | u8 temp_mode; | 183 | u8 temp_mode; |
| 172 | unsigned long alarms; | 184 | unsigned long alarms; |
| 185 | struct f71805f_auto_point auto_points[3]; | ||
| 173 | }; | 186 | }; |
| 174 | 187 | ||
| 175 | struct f71805f_sio_data { | 188 | struct f71805f_sio_data { |
| @@ -312,7 +325,7 @@ static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) | |||
| 312 | static struct f71805f_data *f71805f_update_device(struct device *dev) | 325 | static struct f71805f_data *f71805f_update_device(struct device *dev) |
| 313 | { | 326 | { |
| 314 | struct f71805f_data *data = dev_get_drvdata(dev); | 327 | struct f71805f_data *data = dev_get_drvdata(dev); |
| 315 | int nr; | 328 | int nr, apnr; |
| 316 | 329 | ||
| 317 | mutex_lock(&data->update_lock); | 330 | mutex_lock(&data->update_lock); |
| 318 | 331 | ||
| @@ -342,6 +355,18 @@ static struct f71805f_data *f71805f_update_device(struct device *dev) | |||
| 342 | F71805F_REG_TEMP_HYST(nr)); | 355 | F71805F_REG_TEMP_HYST(nr)); |
| 343 | } | 356 | } |
| 344 | data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); | 357 | data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); |
| 358 | for (nr = 0; nr < 3; nr++) { | ||
| 359 | for (apnr = 0; apnr < 3; apnr++) { | ||
| 360 | data->auto_points[nr].temp[apnr] = | ||
| 361 | f71805f_read8(data, | ||
| 362 | F71805F_REG_PWM_AUTO_POINT_TEMP(nr, | ||
| 363 | apnr)); | ||
| 364 | data->auto_points[nr].fan[apnr] = | ||
| 365 | f71805f_read16(data, | ||
| 366 | F71805F_REG_PWM_AUTO_POINT_FAN(nr, | ||
| 367 | apnr)); | ||
| 368 | } | ||
| 369 | } | ||
| 345 | 370 | ||
| 346 | data->last_limits = jiffies; | 371 | data->last_limits = jiffies; |
| 347 | } | 372 | } |
| @@ -705,6 +730,70 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute | |||
| 705 | return count; | 730 | return count; |
| 706 | } | 731 | } |
| 707 | 732 | ||
| 733 | static ssize_t show_pwm_auto_point_temp(struct device *dev, | ||
| 734 | struct device_attribute *devattr, | ||
| 735 | char* buf) | ||
| 736 | { | ||
| 737 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 738 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
| 739 | int pwmnr = attr->nr; | ||
| 740 | int apnr = attr->index; | ||
| 741 | |||
| 742 | return sprintf(buf, "%ld\n", | ||
| 743 | temp_from_reg(data->auto_points[pwmnr].temp[apnr])); | ||
| 744 | } | ||
| 745 | |||
| 746 | static ssize_t set_pwm_auto_point_temp(struct device *dev, | ||
| 747 | struct device_attribute *devattr, | ||
| 748 | const char* buf, size_t count) | ||
| 749 | { | ||
| 750 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 751 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
| 752 | int pwmnr = attr->nr; | ||
| 753 | int apnr = attr->index; | ||
| 754 | unsigned long val = simple_strtol(buf, NULL, 10); | ||
| 755 | |||
| 756 | mutex_lock(&data->update_lock); | ||
| 757 | data->auto_points[pwmnr].temp[apnr] = temp_to_reg(val); | ||
| 758 | f71805f_write8(data, F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr), | ||
| 759 | data->auto_points[pwmnr].temp[apnr]); | ||
| 760 | mutex_unlock(&data->update_lock); | ||
| 761 | |||
| 762 | return count; | ||
| 763 | } | ||
| 764 | |||
| 765 | static ssize_t show_pwm_auto_point_fan(struct device *dev, | ||
| 766 | struct device_attribute *devattr, | ||
| 767 | char* buf) | ||
| 768 | { | ||
| 769 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 770 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
| 771 | int pwmnr = attr->nr; | ||
| 772 | int apnr = attr->index; | ||
| 773 | |||
| 774 | return sprintf(buf, "%ld\n", | ||
| 775 | fan_from_reg(data->auto_points[pwmnr].fan[apnr])); | ||
| 776 | } | ||
| 777 | |||
| 778 | static ssize_t set_pwm_auto_point_fan(struct device *dev, | ||
| 779 | struct device_attribute *devattr, | ||
| 780 | const char* buf, size_t count) | ||
| 781 | { | ||
| 782 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 783 | struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); | ||
| 784 | int pwmnr = attr->nr; | ||
| 785 | int apnr = attr->index; | ||
| 786 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
| 787 | |||
| 788 | mutex_lock(&data->update_lock); | ||
| 789 | data->auto_points[pwmnr].fan[apnr] = fan_to_reg(val); | ||
| 790 | f71805f_write16(data, F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr), | ||
| 791 | data->auto_points[pwmnr].fan[apnr]); | ||
| 792 | mutex_unlock(&data->update_lock); | ||
| 793 | |||
| 794 | return count; | ||
| 795 | } | ||
| 796 | |||
| 708 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | 797 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, |
| 709 | char *buf) | 798 | char *buf) |
| 710 | { | 799 | { |
| @@ -932,6 +1021,63 @@ static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO | S_IWUSR, | |||
| 932 | show_pwm_freq, set_pwm_freq, 2); | 1021 | show_pwm_freq, set_pwm_freq, 2); |
| 933 | static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2); | 1022 | static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2); |
| 934 | 1023 | ||
| 1024 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR, | ||
| 1025 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
| 1026 | 0, 0); | ||
| 1027 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_fan, S_IRUGO | S_IWUSR, | ||
| 1028 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
| 1029 | 0, 0); | ||
| 1030 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR, | ||
| 1031 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
| 1032 | 0, 1); | ||
| 1033 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_fan, S_IRUGO | S_IWUSR, | ||
| 1034 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
| 1035 | 0, 1); | ||
| 1036 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR, | ||
| 1037 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
| 1038 | 0, 2); | ||
| 1039 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_fan, S_IRUGO | S_IWUSR, | ||
| 1040 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
| 1041 | 0, 2); | ||
| 1042 | |||
| 1043 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR, | ||
| 1044 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
| 1045 | 1, 0); | ||
| 1046 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_fan, S_IRUGO | S_IWUSR, | ||
| 1047 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
| 1048 | 1, 0); | ||
| 1049 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR, | ||
| 1050 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
| 1051 | 1, 1); | ||
| 1052 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_fan, S_IRUGO | S_IWUSR, | ||
| 1053 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
| 1054 | 1, 1); | ||
| 1055 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR, | ||
| 1056 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
| 1057 | 1, 2); | ||
| 1058 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_fan, S_IRUGO | S_IWUSR, | ||
| 1059 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
| 1060 | 1, 2); | ||
| 1061 | |||
| 1062 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR, | ||
| 1063 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
| 1064 | 2, 0); | ||
| 1065 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_fan, S_IRUGO | S_IWUSR, | ||
| 1066 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
| 1067 | 2, 0); | ||
| 1068 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR, | ||
| 1069 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
| 1070 | 2, 1); | ||
| 1071 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_fan, S_IRUGO | S_IWUSR, | ||
| 1072 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
| 1073 | 2, 1); | ||
| 1074 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR, | ||
| 1075 | show_pwm_auto_point_temp, set_pwm_auto_point_temp, | ||
| 1076 | 2, 2); | ||
| 1077 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_fan, S_IRUGO | S_IWUSR, | ||
| 1078 | show_pwm_auto_point_fan, set_pwm_auto_point_fan, | ||
| 1079 | 2, 2); | ||
| 1080 | |||
| 935 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | 1081 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); |
| 936 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | 1082 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); |
| 937 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | 1083 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); |
| @@ -1014,6 +1160,25 @@ static struct attribute *f71805f_attributes[] = { | |||
| 1014 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, | 1160 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, |
| 1015 | &sensor_dev_attr_temp3_type.dev_attr.attr, | 1161 | &sensor_dev_attr_temp3_type.dev_attr.attr, |
| 1016 | 1162 | ||
| 1163 | &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, | ||
| 1164 | &sensor_dev_attr_pwm1_auto_point1_fan.dev_attr.attr, | ||
| 1165 | &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, | ||
| 1166 | &sensor_dev_attr_pwm1_auto_point2_fan.dev_attr.attr, | ||
| 1167 | &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, | ||
| 1168 | &sensor_dev_attr_pwm1_auto_point3_fan.dev_attr.attr, | ||
| 1169 | &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr, | ||
| 1170 | &sensor_dev_attr_pwm2_auto_point1_fan.dev_attr.attr, | ||
| 1171 | &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr, | ||
| 1172 | &sensor_dev_attr_pwm2_auto_point2_fan.dev_attr.attr, | ||
| 1173 | &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr, | ||
| 1174 | &sensor_dev_attr_pwm2_auto_point3_fan.dev_attr.attr, | ||
| 1175 | &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr, | ||
| 1176 | &sensor_dev_attr_pwm3_auto_point1_fan.dev_attr.attr, | ||
| 1177 | &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr, | ||
| 1178 | &sensor_dev_attr_pwm3_auto_point2_fan.dev_attr.attr, | ||
| 1179 | &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr, | ||
| 1180 | &sensor_dev_attr_pwm3_auto_point3_fan.dev_attr.attr, | ||
| 1181 | |||
| 1017 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | 1182 | &sensor_dev_attr_in0_alarm.dev_attr.attr, |
| 1018 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | 1183 | &sensor_dev_attr_in1_alarm.dev_attr.attr, |
| 1019 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | 1184 | &sensor_dev_attr_in2_alarm.dev_attr.attr, |
| @@ -1242,12 +1407,12 @@ static int __devexit f71805f_remove(struct platform_device *pdev) | |||
| 1242 | struct resource *res; | 1407 | struct resource *res; |
| 1243 | int i; | 1408 | int i; |
| 1244 | 1409 | ||
| 1245 | platform_set_drvdata(pdev, NULL); | ||
| 1246 | hwmon_device_unregister(data->class_dev); | 1410 | hwmon_device_unregister(data->class_dev); |
| 1247 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); | 1411 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); |
| 1248 | for (i = 0; i < 4; i++) | 1412 | for (i = 0; i < 4; i++) |
| 1249 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); | 1413 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); |
| 1250 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); | 1414 | sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); |
| 1415 | platform_set_drvdata(pdev, NULL); | ||
| 1251 | kfree(data); | 1416 | kfree(data); |
| 1252 | 1417 | ||
| 1253 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1418 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| @@ -1290,15 +1455,12 @@ static int __init f71805f_device_add(unsigned short address, | |||
| 1290 | goto exit_device_put; | 1455 | goto exit_device_put; |
| 1291 | } | 1456 | } |
| 1292 | 1457 | ||
| 1293 | pdev->dev.platform_data = kmalloc(sizeof(struct f71805f_sio_data), | 1458 | err = platform_device_add_data(pdev, sio_data, |
| 1294 | GFP_KERNEL); | 1459 | sizeof(struct f71805f_sio_data)); |
| 1295 | if (!pdev->dev.platform_data) { | 1460 | if (err) { |
| 1296 | err = -ENOMEM; | ||
| 1297 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | 1461 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); |
| 1298 | goto exit_device_put; | 1462 | goto exit_device_put; |
| 1299 | } | 1463 | } |
| 1300 | memcpy(pdev->dev.platform_data, sio_data, | ||
| 1301 | sizeof(struct f71805f_sio_data)); | ||
| 1302 | 1464 | ||
| 1303 | err = platform_device_add(pdev); | 1465 | err = platform_device_add(pdev); |
| 1304 | if (err) { | 1466 | if (err) { |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 62afc63708a5..eff6036e15c0 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | IT8712F Super I/O chip w/LPC interface | 6 | IT8712F Super I/O chip w/LPC interface |
| 7 | IT8716F Super I/O chip w/LPC interface | 7 | IT8716F Super I/O chip w/LPC interface |
| 8 | IT8718F Super I/O chip w/LPC interface | 8 | IT8718F Super I/O chip w/LPC interface |
| 9 | IT8726F Super I/O chip w/LPC interface | ||
| 9 | Sis950 A clone of the IT8705F | 10 | Sis950 A clone of the IT8705F |
| 10 | 11 | ||
| 11 | Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> | 12 | Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> |
| @@ -30,8 +31,7 @@ | |||
| 30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| 31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 32 | #include <linux/jiffies.h> | 33 | #include <linux/jiffies.h> |
| 33 | #include <linux/i2c.h> | 34 | #include <linux/platform_device.h> |
| 34 | #include <linux/i2c-isa.h> | ||
| 35 | #include <linux/hwmon.h> | 35 | #include <linux/hwmon.h> |
| 36 | #include <linux/hwmon-sysfs.h> | 36 | #include <linux/hwmon-sysfs.h> |
| 37 | #include <linux/hwmon-vid.h> | 37 | #include <linux/hwmon-vid.h> |
| @@ -40,10 +40,12 @@ | |||
| 40 | #include <linux/sysfs.h> | 40 | #include <linux/sysfs.h> |
| 41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
| 42 | 42 | ||
| 43 | #define DRVNAME "it87" | ||
| 43 | 44 | ||
| 44 | static unsigned short isa_address; | ||
| 45 | enum chips { it87, it8712, it8716, it8718 }; | 45 | enum chips { it87, it8712, it8716, it8718 }; |
| 46 | 46 | ||
| 47 | static struct platform_device *pdev; | ||
| 48 | |||
| 47 | #define REG 0x2e /* The register to read/write */ | 49 | #define REG 0x2e /* The register to read/write */ |
| 48 | #define DEV 0x07 /* Register: Logical device select */ | 50 | #define DEV 0x07 /* Register: Logical device select */ |
| 49 | #define VAL 0x2f /* The value to read/write */ | 51 | #define VAL 0x2f /* The value to read/write */ |
| @@ -97,6 +99,7 @@ superio_exit(void) | |||
| 97 | #define IT8705F_DEVID 0x8705 | 99 | #define IT8705F_DEVID 0x8705 |
| 98 | #define IT8716F_DEVID 0x8716 | 100 | #define IT8716F_DEVID 0x8716 |
| 99 | #define IT8718F_DEVID 0x8718 | 101 | #define IT8718F_DEVID 0x8718 |
| 102 | #define IT8726F_DEVID 0x8726 | ||
| 100 | #define IT87_ACT_REG 0x30 | 103 | #define IT87_ACT_REG 0x30 |
| 101 | #define IT87_BASE_REG 0x60 | 104 | #define IT87_BASE_REG 0x60 |
| 102 | 105 | ||
| @@ -110,10 +113,6 @@ static int update_vbat; | |||
| 110 | /* Not all BIOSes properly configure the PWM registers */ | 113 | /* Not all BIOSes properly configure the PWM registers */ |
| 111 | static int fix_pwm_polarity; | 114 | static int fix_pwm_polarity; |
| 112 | 115 | ||
| 113 | /* Values read from Super-I/O config space */ | ||
| 114 | static u16 chip_type; | ||
| 115 | static u8 vid_value; | ||
| 116 | |||
| 117 | /* Many IT87 constants specified below */ | 116 | /* Many IT87 constants specified below */ |
| 118 | 117 | ||
| 119 | /* Length of ISA address segment */ | 118 | /* Length of ISA address segment */ |
| @@ -214,13 +213,20 @@ static const unsigned int pwm_freq[8] = { | |||
| 214 | }; | 213 | }; |
| 215 | 214 | ||
| 216 | 215 | ||
| 216 | struct it87_sio_data { | ||
| 217 | enum chips type; | ||
| 218 | /* Values read from Super-I/O config space */ | ||
| 219 | u8 vid_value; | ||
| 220 | }; | ||
| 221 | |||
| 217 | /* For each registered chip, we need to keep some data in memory. | 222 | /* For each registered chip, we need to keep some data in memory. |
| 218 | The structure is dynamically allocated. */ | 223 | The structure is dynamically allocated. */ |
| 219 | struct it87_data { | 224 | struct it87_data { |
| 220 | struct i2c_client client; | ||
| 221 | struct class_device *class_dev; | 225 | struct class_device *class_dev; |
| 222 | enum chips type; | 226 | enum chips type; |
| 223 | 227 | ||
| 228 | unsigned short addr; | ||
| 229 | const char *name; | ||
| 224 | struct mutex update_lock; | 230 | struct mutex update_lock; |
| 225 | char valid; /* !=0 if following fields are valid */ | 231 | char valid; /* !=0 if following fields are valid */ |
| 226 | unsigned long last_updated; /* In jiffies */ | 232 | unsigned long last_updated; /* In jiffies */ |
| @@ -245,26 +251,25 @@ struct it87_data { | |||
| 245 | }; | 251 | }; |
| 246 | 252 | ||
| 247 | 253 | ||
| 248 | static int it87_detect(struct i2c_adapter *adapter); | 254 | static int it87_probe(struct platform_device *pdev); |
| 249 | static int it87_detach_client(struct i2c_client *client); | 255 | static int it87_remove(struct platform_device *pdev); |
| 250 | 256 | ||
| 251 | static int it87_read_value(struct i2c_client *client, u8 reg); | 257 | static int it87_read_value(struct it87_data *data, u8 reg); |
| 252 | static void it87_write_value(struct i2c_client *client, u8 reg, u8 value); | 258 | static void it87_write_value(struct it87_data *data, u8 reg, u8 value); |
| 253 | static struct it87_data *it87_update_device(struct device *dev); | 259 | static struct it87_data *it87_update_device(struct device *dev); |
| 254 | static int it87_check_pwm(struct i2c_client *client); | 260 | static int it87_check_pwm(struct device *dev); |
| 255 | static void it87_init_client(struct i2c_client *client, struct it87_data *data); | 261 | static void it87_init_device(struct platform_device *pdev); |
| 256 | 262 | ||
| 257 | 263 | ||
| 258 | static struct i2c_driver it87_isa_driver = { | 264 | static struct platform_driver it87_driver = { |
| 259 | .driver = { | 265 | .driver = { |
| 260 | .owner = THIS_MODULE, | 266 | .owner = THIS_MODULE, |
| 261 | .name = "it87-isa", | 267 | .name = DRVNAME, |
| 262 | }, | 268 | }, |
| 263 | .attach_adapter = it87_detect, | 269 | .probe = it87_probe, |
| 264 | .detach_client = it87_detach_client, | 270 | .remove = __devexit_p(it87_remove), |
| 265 | }; | 271 | }; |
| 266 | 272 | ||
| 267 | |||
| 268 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | 273 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
| 269 | char *buf) | 274 | char *buf) |
| 270 | { | 275 | { |
| @@ -301,13 +306,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | |||
| 301 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 306 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 302 | int nr = sensor_attr->index; | 307 | int nr = sensor_attr->index; |
| 303 | 308 | ||
| 304 | struct i2c_client *client = to_i2c_client(dev); | 309 | struct it87_data *data = dev_get_drvdata(dev); |
| 305 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 306 | unsigned long val = simple_strtoul(buf, NULL, 10); | 310 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 307 | 311 | ||
| 308 | mutex_lock(&data->update_lock); | 312 | mutex_lock(&data->update_lock); |
| 309 | data->in_min[nr] = IN_TO_REG(val); | 313 | data->in_min[nr] = IN_TO_REG(val); |
| 310 | it87_write_value(client, IT87_REG_VIN_MIN(nr), | 314 | it87_write_value(data, IT87_REG_VIN_MIN(nr), |
| 311 | data->in_min[nr]); | 315 | data->in_min[nr]); |
| 312 | mutex_unlock(&data->update_lock); | 316 | mutex_unlock(&data->update_lock); |
| 313 | return count; | 317 | return count; |
| @@ -318,13 +322,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | |||
| 318 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 322 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 319 | int nr = sensor_attr->index; | 323 | int nr = sensor_attr->index; |
| 320 | 324 | ||
| 321 | struct i2c_client *client = to_i2c_client(dev); | 325 | struct it87_data *data = dev_get_drvdata(dev); |
| 322 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 323 | unsigned long val = simple_strtoul(buf, NULL, 10); | 326 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 324 | 327 | ||
| 325 | mutex_lock(&data->update_lock); | 328 | mutex_lock(&data->update_lock); |
| 326 | data->in_max[nr] = IN_TO_REG(val); | 329 | data->in_max[nr] = IN_TO_REG(val); |
| 327 | it87_write_value(client, IT87_REG_VIN_MAX(nr), | 330 | it87_write_value(data, IT87_REG_VIN_MAX(nr), |
| 328 | data->in_max[nr]); | 331 | data->in_max[nr]); |
| 329 | mutex_unlock(&data->update_lock); | 332 | mutex_unlock(&data->update_lock); |
| 330 | return count; | 333 | return count; |
| @@ -392,13 +395,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
| 392 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 395 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 393 | int nr = sensor_attr->index; | 396 | int nr = sensor_attr->index; |
| 394 | 397 | ||
| 395 | struct i2c_client *client = to_i2c_client(dev); | 398 | struct it87_data *data = dev_get_drvdata(dev); |
| 396 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 397 | int val = simple_strtol(buf, NULL, 10); | 399 | int val = simple_strtol(buf, NULL, 10); |
| 398 | 400 | ||
| 399 | mutex_lock(&data->update_lock); | 401 | mutex_lock(&data->update_lock); |
| 400 | data->temp_high[nr] = TEMP_TO_REG(val); | 402 | data->temp_high[nr] = TEMP_TO_REG(val); |
| 401 | it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]); | 403 | it87_write_value(data, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]); |
| 402 | mutex_unlock(&data->update_lock); | 404 | mutex_unlock(&data->update_lock); |
| 403 | return count; | 405 | return count; |
| 404 | } | 406 | } |
| @@ -408,13 +410,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
| 408 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 410 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 409 | int nr = sensor_attr->index; | 411 | int nr = sensor_attr->index; |
| 410 | 412 | ||
| 411 | struct i2c_client *client = to_i2c_client(dev); | 413 | struct it87_data *data = dev_get_drvdata(dev); |
| 412 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 413 | int val = simple_strtol(buf, NULL, 10); | 414 | int val = simple_strtol(buf, NULL, 10); |
| 414 | 415 | ||
| 415 | mutex_lock(&data->update_lock); | 416 | mutex_lock(&data->update_lock); |
| 416 | data->temp_low[nr] = TEMP_TO_REG(val); | 417 | data->temp_low[nr] = TEMP_TO_REG(val); |
| 417 | it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]); | 418 | it87_write_value(data, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]); |
| 418 | mutex_unlock(&data->update_lock); | 419 | mutex_unlock(&data->update_lock); |
| 419 | return count; | 420 | return count; |
| 420 | } | 421 | } |
| @@ -451,8 +452,7 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | |||
| 451 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 452 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 452 | int nr = sensor_attr->index; | 453 | int nr = sensor_attr->index; |
| 453 | 454 | ||
| 454 | struct i2c_client *client = to_i2c_client(dev); | 455 | struct it87_data *data = dev_get_drvdata(dev); |
| 455 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 456 | int val = simple_strtol(buf, NULL, 10); | 456 | int val = simple_strtol(buf, NULL, 10); |
| 457 | 457 | ||
| 458 | mutex_lock(&data->update_lock); | 458 | mutex_lock(&data->update_lock); |
| @@ -468,7 +468,7 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | |||
| 468 | mutex_unlock(&data->update_lock); | 468 | mutex_unlock(&data->update_lock); |
| 469 | return -EINVAL; | 469 | return -EINVAL; |
| 470 | } | 470 | } |
| 471 | it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor); | 471 | it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); |
| 472 | mutex_unlock(&data->update_lock); | 472 | mutex_unlock(&data->update_lock); |
| 473 | return count; | 473 | return count; |
| 474 | } | 474 | } |
| @@ -542,13 +542,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
| 542 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 542 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 543 | int nr = sensor_attr->index; | 543 | int nr = sensor_attr->index; |
| 544 | 544 | ||
| 545 | struct i2c_client *client = to_i2c_client(dev); | 545 | struct it87_data *data = dev_get_drvdata(dev); |
| 546 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 547 | int val = simple_strtol(buf, NULL, 10); | 546 | int val = simple_strtol(buf, NULL, 10); |
| 548 | u8 reg; | 547 | u8 reg; |
| 549 | 548 | ||
| 550 | mutex_lock(&data->update_lock); | 549 | mutex_lock(&data->update_lock); |
| 551 | reg = it87_read_value(client, IT87_REG_FAN_DIV); | 550 | reg = it87_read_value(data, IT87_REG_FAN_DIV); |
| 552 | switch (nr) { | 551 | switch (nr) { |
| 553 | case 0: data->fan_div[nr] = reg & 0x07; break; | 552 | case 0: data->fan_div[nr] = reg & 0x07; break; |
| 554 | case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break; | 553 | case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break; |
| @@ -556,7 +555,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
| 556 | } | 555 | } |
| 557 | 556 | ||
| 558 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 557 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
| 559 | it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); | 558 | it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); |
| 560 | mutex_unlock(&data->update_lock); | 559 | mutex_unlock(&data->update_lock); |
| 561 | return count; | 560 | return count; |
| 562 | } | 561 | } |
| @@ -566,14 +565,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
| 566 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 565 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 567 | int nr = sensor_attr->index; | 566 | int nr = sensor_attr->index; |
| 568 | 567 | ||
| 569 | struct i2c_client *client = to_i2c_client(dev); | 568 | struct it87_data *data = dev_get_drvdata(dev); |
| 570 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 571 | unsigned long val = simple_strtoul(buf, NULL, 10); | 569 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 572 | int min; | 570 | int min; |
| 573 | u8 old; | 571 | u8 old; |
| 574 | 572 | ||
| 575 | mutex_lock(&data->update_lock); | 573 | mutex_lock(&data->update_lock); |
| 576 | old = it87_read_value(client, IT87_REG_FAN_DIV); | 574 | old = it87_read_value(data, IT87_REG_FAN_DIV); |
| 577 | 575 | ||
| 578 | /* Save fan min limit */ | 576 | /* Save fan min limit */ |
| 579 | min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); | 577 | min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); |
| @@ -594,11 +592,11 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
| 594 | val |= (data->fan_div[1] & 0x07) << 3; | 592 | val |= (data->fan_div[1] & 0x07) << 3; |
| 595 | if (data->fan_div[2] == 3) | 593 | if (data->fan_div[2] == 3) |
| 596 | val |= 0x1 << 6; | 594 | val |= 0x1 << 6; |
| 597 | it87_write_value(client, IT87_REG_FAN_DIV, val); | 595 | it87_write_value(data, IT87_REG_FAN_DIV, val); |
| 598 | 596 | ||
| 599 | /* Restore fan min limit */ | 597 | /* Restore fan min limit */ |
| 600 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 598 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
| 601 | it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); | 599 | it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); |
| 602 | 600 | ||
| 603 | mutex_unlock(&data->update_lock); | 601 | mutex_unlock(&data->update_lock); |
| 604 | return count; | 602 | return count; |
| @@ -609,8 +607,7 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
| 609 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 607 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 610 | int nr = sensor_attr->index; | 608 | int nr = sensor_attr->index; |
| 611 | 609 | ||
| 612 | struct i2c_client *client = to_i2c_client(dev); | 610 | struct it87_data *data = dev_get_drvdata(dev); |
| 613 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 614 | int val = simple_strtol(buf, NULL, 10); | 611 | int val = simple_strtol(buf, NULL, 10); |
| 615 | 612 | ||
| 616 | mutex_lock(&data->update_lock); | 613 | mutex_lock(&data->update_lock); |
| @@ -618,17 +615,17 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
| 618 | if (val == 0) { | 615 | if (val == 0) { |
| 619 | int tmp; | 616 | int tmp; |
| 620 | /* make sure the fan is on when in on/off mode */ | 617 | /* make sure the fan is on when in on/off mode */ |
| 621 | tmp = it87_read_value(client, IT87_REG_FAN_CTL); | 618 | tmp = it87_read_value(data, IT87_REG_FAN_CTL); |
| 622 | it87_write_value(client, IT87_REG_FAN_CTL, tmp | (1 << nr)); | 619 | it87_write_value(data, IT87_REG_FAN_CTL, tmp | (1 << nr)); |
| 623 | /* set on/off mode */ | 620 | /* set on/off mode */ |
| 624 | data->fan_main_ctrl &= ~(1 << nr); | 621 | data->fan_main_ctrl &= ~(1 << nr); |
| 625 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); | 622 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); |
| 626 | } else if (val == 1) { | 623 | } else if (val == 1) { |
| 627 | /* set SmartGuardian mode */ | 624 | /* set SmartGuardian mode */ |
| 628 | data->fan_main_ctrl |= (1 << nr); | 625 | data->fan_main_ctrl |= (1 << nr); |
| 629 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); | 626 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); |
| 630 | /* set saved pwm value, clear FAN_CTLX PWM mode bit */ | 627 | /* set saved pwm value, clear FAN_CTLX PWM mode bit */ |
| 631 | it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); | 628 | it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); |
| 632 | } else { | 629 | } else { |
| 633 | mutex_unlock(&data->update_lock); | 630 | mutex_unlock(&data->update_lock); |
| 634 | return -EINVAL; | 631 | return -EINVAL; |
| @@ -643,8 +640,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
| 643 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 640 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 644 | int nr = sensor_attr->index; | 641 | int nr = sensor_attr->index; |
| 645 | 642 | ||
| 646 | struct i2c_client *client = to_i2c_client(dev); | 643 | struct it87_data *data = dev_get_drvdata(dev); |
| 647 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 648 | int val = simple_strtol(buf, NULL, 10); | 644 | int val = simple_strtol(buf, NULL, 10); |
| 649 | 645 | ||
| 650 | if (val < 0 || val > 255) | 646 | if (val < 0 || val > 255) |
| @@ -653,15 +649,14 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
| 653 | mutex_lock(&data->update_lock); | 649 | mutex_lock(&data->update_lock); |
| 654 | data->manual_pwm_ctl[nr] = val; | 650 | data->manual_pwm_ctl[nr] = val; |
| 655 | if (data->fan_main_ctrl & (1 << nr)) | 651 | if (data->fan_main_ctrl & (1 << nr)) |
| 656 | it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); | 652 | it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); |
| 657 | mutex_unlock(&data->update_lock); | 653 | mutex_unlock(&data->update_lock); |
| 658 | return count; | 654 | return count; |
| 659 | } | 655 | } |
| 660 | static ssize_t set_pwm_freq(struct device *dev, | 656 | static ssize_t set_pwm_freq(struct device *dev, |
| 661 | struct device_attribute *attr, const char *buf, size_t count) | 657 | struct device_attribute *attr, const char *buf, size_t count) |
| 662 | { | 658 | { |
| 663 | struct i2c_client *client = to_i2c_client(dev); | 659 | struct it87_data *data = dev_get_drvdata(dev); |
| 664 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 665 | unsigned long val = simple_strtoul(buf, NULL, 10); | 660 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 666 | int i; | 661 | int i; |
| 667 | 662 | ||
| @@ -672,9 +667,9 @@ static ssize_t set_pwm_freq(struct device *dev, | |||
| 672 | } | 667 | } |
| 673 | 668 | ||
| 674 | mutex_lock(&data->update_lock); | 669 | mutex_lock(&data->update_lock); |
| 675 | data->fan_ctl = it87_read_value(client, IT87_REG_FAN_CTL) & 0x8f; | 670 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL) & 0x8f; |
| 676 | data->fan_ctl |= i << 4; | 671 | data->fan_ctl |= i << 4; |
| 677 | it87_write_value(client, IT87_REG_FAN_CTL, data->fan_ctl); | 672 | it87_write_value(data, IT87_REG_FAN_CTL, data->fan_ctl); |
| 678 | mutex_unlock(&data->update_lock); | 673 | mutex_unlock(&data->update_lock); |
| 679 | 674 | ||
| 680 | return count; | 675 | return count; |
| @@ -729,15 +724,14 @@ static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr, | |||
| 729 | { | 724 | { |
| 730 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 725 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 731 | int nr = sensor_attr->index; | 726 | int nr = sensor_attr->index; |
| 732 | struct i2c_client *client = to_i2c_client(dev); | 727 | struct it87_data *data = dev_get_drvdata(dev); |
| 733 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 734 | int val = simple_strtol(buf, NULL, 10); | 728 | int val = simple_strtol(buf, NULL, 10); |
| 735 | 729 | ||
| 736 | mutex_lock(&data->update_lock); | 730 | mutex_lock(&data->update_lock); |
| 737 | data->fan_min[nr] = FAN16_TO_REG(val); | 731 | data->fan_min[nr] = FAN16_TO_REG(val); |
| 738 | it87_write_value(client, IT87_REG_FAN_MIN(nr), | 732 | it87_write_value(data, IT87_REG_FAN_MIN(nr), |
| 739 | data->fan_min[nr] & 0xff); | 733 | data->fan_min[nr] & 0xff); |
| 740 | it87_write_value(client, IT87_REG_FANX_MIN(nr), | 734 | it87_write_value(data, IT87_REG_FANX_MIN(nr), |
| 741 | data->fan_min[nr] >> 8); | 735 | data->fan_min[nr] >> 8); |
| 742 | mutex_unlock(&data->update_lock); | 736 | mutex_unlock(&data->update_lock); |
| 743 | return count; | 737 | return count; |
| @@ -775,8 +769,7 @@ show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
| 775 | static ssize_t | 769 | static ssize_t |
| 776 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 770 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
| 777 | { | 771 | { |
| 778 | struct i2c_client *client = to_i2c_client(dev); | 772 | struct it87_data *data = dev_get_drvdata(dev); |
| 779 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 780 | u32 val; | 773 | u32 val; |
| 781 | 774 | ||
| 782 | val = simple_strtoul(buf, NULL, 10); | 775 | val = simple_strtoul(buf, NULL, 10); |
| @@ -794,6 +787,14 @@ show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
| 794 | } | 787 | } |
| 795 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 788 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
| 796 | 789 | ||
| 790 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
| 791 | *devattr, char *buf) | ||
| 792 | { | ||
| 793 | struct it87_data *data = dev_get_drvdata(dev); | ||
| 794 | return sprintf(buf, "%s\n", data->name); | ||
| 795 | } | ||
| 796 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 797 | |||
| 797 | static struct attribute *it87_attributes[] = { | 798 | static struct attribute *it87_attributes[] = { |
| 798 | &sensor_dev_attr_in0_input.dev_attr.attr, | 799 | &sensor_dev_attr_in0_input.dev_attr.attr, |
| 799 | &sensor_dev_attr_in1_input.dev_attr.attr, | 800 | &sensor_dev_attr_in1_input.dev_attr.attr, |
| @@ -835,6 +836,7 @@ static struct attribute *it87_attributes[] = { | |||
| 835 | &sensor_dev_attr_temp3_type.dev_attr.attr, | 836 | &sensor_dev_attr_temp3_type.dev_attr.attr, |
| 836 | 837 | ||
| 837 | &dev_attr_alarms.attr, | 838 | &dev_attr_alarms.attr, |
| 839 | &dev_attr_name.attr, | ||
| 838 | NULL | 840 | NULL |
| 839 | }; | 841 | }; |
| 840 | 842 | ||
| @@ -877,17 +879,36 @@ static const struct attribute_group it87_group_opt = { | |||
| 877 | }; | 879 | }; |
| 878 | 880 | ||
| 879 | /* SuperIO detection - will change isa_address if a chip is found */ | 881 | /* SuperIO detection - will change isa_address if a chip is found */ |
| 880 | static int __init it87_find(unsigned short *address) | 882 | static int __init it87_find(unsigned short *address, |
| 883 | struct it87_sio_data *sio_data) | ||
| 881 | { | 884 | { |
| 882 | int err = -ENODEV; | 885 | int err = -ENODEV; |
| 886 | u16 chip_type; | ||
| 883 | 887 | ||
| 884 | superio_enter(); | 888 | superio_enter(); |
| 885 | chip_type = superio_inw(DEVID); | 889 | chip_type = superio_inw(DEVID); |
| 886 | if (chip_type != IT8712F_DEVID | 890 | |
| 887 | && chip_type != IT8716F_DEVID | 891 | switch (chip_type) { |
| 888 | && chip_type != IT8718F_DEVID | 892 | case IT8705F_DEVID: |
| 889 | && chip_type != IT8705F_DEVID) | 893 | sio_data->type = it87; |
| 890 | goto exit; | 894 | break; |
| 895 | case IT8712F_DEVID: | ||
| 896 | sio_data->type = it8712; | ||
| 897 | break; | ||
| 898 | case IT8716F_DEVID: | ||
| 899 | case IT8726F_DEVID: | ||
| 900 | sio_data->type = it8716; | ||
| 901 | break; | ||
| 902 | case IT8718F_DEVID: | ||
| 903 | sio_data->type = it8718; | ||
| 904 | break; | ||
| 905 | case 0xffff: /* No device at all */ | ||
| 906 | goto exit; | ||
| 907 | default: | ||
| 908 | pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%x)\n", | ||
| 909 | chip_type); | ||
| 910 | goto exit; | ||
| 911 | } | ||
| 891 | 912 | ||
| 892 | superio_select(PME); | 913 | superio_select(PME); |
| 893 | if (!(superio_inb(IT87_ACT_REG) & 0x01)) { | 914 | if (!(superio_inb(IT87_ACT_REG) & 0x01)) { |
| @@ -911,7 +932,7 @@ static int __init it87_find(unsigned short *address) | |||
| 911 | 932 | ||
| 912 | superio_select(GPIO); | 933 | superio_select(GPIO); |
| 913 | if (chip_type == it8718) | 934 | if (chip_type == it8718) |
| 914 | vid_value = superio_inb(IT87_SIO_VID_REG); | 935 | sio_data->vid_value = superio_inb(IT87_SIO_VID_REG); |
| 915 | 936 | ||
| 916 | reg = superio_inb(IT87_SIO_PINX2_REG); | 937 | reg = superio_inb(IT87_SIO_PINX2_REG); |
| 917 | if (reg & (1 << 0)) | 938 | if (reg & (1 << 0)) |
| @@ -925,18 +946,26 @@ exit: | |||
| 925 | return err; | 946 | return err; |
| 926 | } | 947 | } |
| 927 | 948 | ||
| 928 | /* This function is called by i2c_probe */ | 949 | static int __devinit it87_probe(struct platform_device *pdev) |
| 929 | static int it87_detect(struct i2c_adapter *adapter) | ||
| 930 | { | 950 | { |
| 931 | struct i2c_client *new_client; | ||
| 932 | struct it87_data *data; | 951 | struct it87_data *data; |
| 952 | struct resource *res; | ||
| 953 | struct device *dev = &pdev->dev; | ||
| 954 | struct it87_sio_data *sio_data = dev->platform_data; | ||
| 933 | int err = 0; | 955 | int err = 0; |
| 934 | const char *name; | ||
| 935 | int enable_pwm_interface; | 956 | int enable_pwm_interface; |
| 936 | 957 | static const char *names[] = { | |
| 937 | /* Reserve the ISA region */ | 958 | "it87", |
| 938 | if (!request_region(isa_address, IT87_EXTENT, | 959 | "it8712", |
| 939 | it87_isa_driver.driver.name)){ | 960 | "it8716", |
| 961 | "it8718", | ||
| 962 | }; | ||
| 963 | |||
| 964 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
| 965 | if (!request_region(res->start, IT87_EXTENT, DRVNAME)) { | ||
| 966 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", | ||
| 967 | (unsigned long)res->start, | ||
| 968 | (unsigned long)(res->start + IT87_EXTENT - 1)); | ||
| 940 | err = -EBUSY; | 969 | err = -EBUSY; |
| 941 | goto ERROR0; | 970 | goto ERROR0; |
| 942 | } | 971 | } |
| @@ -946,129 +975,104 @@ static int it87_detect(struct i2c_adapter *adapter) | |||
| 946 | goto ERROR1; | 975 | goto ERROR1; |
| 947 | } | 976 | } |
| 948 | 977 | ||
| 949 | new_client = &data->client; | 978 | data->addr = res->start; |
| 950 | i2c_set_clientdata(new_client, data); | 979 | data->type = sio_data->type; |
| 951 | new_client->addr = isa_address; | 980 | data->name = names[sio_data->type]; |
| 952 | new_client->adapter = adapter; | ||
| 953 | new_client->driver = &it87_isa_driver; | ||
| 954 | 981 | ||
| 955 | /* Now, we do the remaining detection. */ | 982 | /* Now, we do the remaining detection. */ |
| 956 | if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80) | 983 | if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) |
| 957 | || it87_read_value(new_client, IT87_REG_CHIPID) != 0x90) { | 984 | || it87_read_value(data, IT87_REG_CHIPID) != 0x90) { |
| 958 | err = -ENODEV; | 985 | err = -ENODEV; |
| 959 | goto ERROR2; | 986 | goto ERROR2; |
| 960 | } | 987 | } |
| 961 | 988 | ||
| 962 | /* Determine the chip type. */ | 989 | platform_set_drvdata(pdev, data); |
| 963 | switch (chip_type) { | ||
| 964 | case IT8712F_DEVID: | ||
| 965 | data->type = it8712; | ||
| 966 | name = "it8712"; | ||
| 967 | break; | ||
| 968 | case IT8716F_DEVID: | ||
| 969 | data->type = it8716; | ||
| 970 | name = "it8716"; | ||
| 971 | break; | ||
| 972 | case IT8718F_DEVID: | ||
| 973 | data->type = it8718; | ||
| 974 | name = "it8718"; | ||
| 975 | break; | ||
| 976 | default: | ||
| 977 | data->type = it87; | ||
| 978 | name = "it87"; | ||
| 979 | } | ||
| 980 | 990 | ||
| 981 | /* Fill in the remaining client fields and put it into the global list */ | ||
| 982 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | ||
| 983 | mutex_init(&data->update_lock); | 991 | mutex_init(&data->update_lock); |
| 984 | 992 | ||
| 985 | /* Tell the I2C layer a new client has arrived */ | ||
| 986 | if ((err = i2c_attach_client(new_client))) | ||
| 987 | goto ERROR2; | ||
| 988 | |||
| 989 | /* Check PWM configuration */ | 993 | /* Check PWM configuration */ |
| 990 | enable_pwm_interface = it87_check_pwm(new_client); | 994 | enable_pwm_interface = it87_check_pwm(dev); |
| 991 | 995 | ||
| 992 | /* Initialize the IT87 chip */ | 996 | /* Initialize the IT87 chip */ |
| 993 | it87_init_client(new_client, data); | 997 | it87_init_device(pdev); |
| 994 | 998 | ||
| 995 | /* Register sysfs hooks */ | 999 | /* Register sysfs hooks */ |
| 996 | if ((err = sysfs_create_group(&new_client->dev.kobj, &it87_group))) | 1000 | if ((err = sysfs_create_group(&dev->kobj, &it87_group))) |
| 997 | goto ERROR3; | 1001 | goto ERROR2; |
| 998 | 1002 | ||
| 999 | /* Do not create fan files for disabled fans */ | 1003 | /* Do not create fan files for disabled fans */ |
| 1000 | if (data->type == it8716 || data->type == it8718) { | 1004 | if (data->type == it8716 || data->type == it8718) { |
| 1001 | /* 16-bit tachometers */ | 1005 | /* 16-bit tachometers */ |
| 1002 | if (data->has_fan & (1 << 0)) { | 1006 | if (data->has_fan & (1 << 0)) { |
| 1003 | if ((err = device_create_file(&new_client->dev, | 1007 | if ((err = device_create_file(dev, |
| 1004 | &sensor_dev_attr_fan1_input16.dev_attr)) | 1008 | &sensor_dev_attr_fan1_input16.dev_attr)) |
| 1005 | || (err = device_create_file(&new_client->dev, | 1009 | || (err = device_create_file(dev, |
| 1006 | &sensor_dev_attr_fan1_min16.dev_attr))) | 1010 | &sensor_dev_attr_fan1_min16.dev_attr))) |
| 1007 | goto ERROR4; | 1011 | goto ERROR4; |
| 1008 | } | 1012 | } |
| 1009 | if (data->has_fan & (1 << 1)) { | 1013 | if (data->has_fan & (1 << 1)) { |
| 1010 | if ((err = device_create_file(&new_client->dev, | 1014 | if ((err = device_create_file(dev, |
| 1011 | &sensor_dev_attr_fan2_input16.dev_attr)) | 1015 | &sensor_dev_attr_fan2_input16.dev_attr)) |
| 1012 | || (err = device_create_file(&new_client->dev, | 1016 | || (err = device_create_file(dev, |
| 1013 | &sensor_dev_attr_fan2_min16.dev_attr))) | 1017 | &sensor_dev_attr_fan2_min16.dev_attr))) |
| 1014 | goto ERROR4; | 1018 | goto ERROR4; |
| 1015 | } | 1019 | } |
| 1016 | if (data->has_fan & (1 << 2)) { | 1020 | if (data->has_fan & (1 << 2)) { |
| 1017 | if ((err = device_create_file(&new_client->dev, | 1021 | if ((err = device_create_file(dev, |
| 1018 | &sensor_dev_attr_fan3_input16.dev_attr)) | 1022 | &sensor_dev_attr_fan3_input16.dev_attr)) |
| 1019 | || (err = device_create_file(&new_client->dev, | 1023 | || (err = device_create_file(dev, |
| 1020 | &sensor_dev_attr_fan3_min16.dev_attr))) | 1024 | &sensor_dev_attr_fan3_min16.dev_attr))) |
| 1021 | goto ERROR4; | 1025 | goto ERROR4; |
| 1022 | } | 1026 | } |
| 1023 | } else { | 1027 | } else { |
| 1024 | /* 8-bit tachometers with clock divider */ | 1028 | /* 8-bit tachometers with clock divider */ |
| 1025 | if (data->has_fan & (1 << 0)) { | 1029 | if (data->has_fan & (1 << 0)) { |
| 1026 | if ((err = device_create_file(&new_client->dev, | 1030 | if ((err = device_create_file(dev, |
| 1027 | &sensor_dev_attr_fan1_input.dev_attr)) | 1031 | &sensor_dev_attr_fan1_input.dev_attr)) |
| 1028 | || (err = device_create_file(&new_client->dev, | 1032 | || (err = device_create_file(dev, |
| 1029 | &sensor_dev_attr_fan1_min.dev_attr)) | 1033 | &sensor_dev_attr_fan1_min.dev_attr)) |
| 1030 | || (err = device_create_file(&new_client->dev, | 1034 | || (err = device_create_file(dev, |
| 1031 | &sensor_dev_attr_fan1_div.dev_attr))) | 1035 | &sensor_dev_attr_fan1_div.dev_attr))) |
| 1032 | goto ERROR4; | 1036 | goto ERROR4; |
| 1033 | } | 1037 | } |
| 1034 | if (data->has_fan & (1 << 1)) { | 1038 | if (data->has_fan & (1 << 1)) { |
| 1035 | if ((err = device_create_file(&new_client->dev, | 1039 | if ((err = device_create_file(dev, |
| 1036 | &sensor_dev_attr_fan2_input.dev_attr)) | 1040 | &sensor_dev_attr_fan2_input.dev_attr)) |
| 1037 | || (err = device_create_file(&new_client->dev, | 1041 | || (err = device_create_file(dev, |
| 1038 | &sensor_dev_attr_fan2_min.dev_attr)) | 1042 | &sensor_dev_attr_fan2_min.dev_attr)) |
| 1039 | || (err = device_create_file(&new_client->dev, | 1043 | || (err = device_create_file(dev, |
| 1040 | &sensor_dev_attr_fan2_div.dev_attr))) | 1044 | &sensor_dev_attr_fan2_div.dev_attr))) |
| 1041 | goto ERROR4; | 1045 | goto ERROR4; |
| 1042 | } | 1046 | } |
| 1043 | if (data->has_fan & (1 << 2)) { | 1047 | if (data->has_fan & (1 << 2)) { |
| 1044 | if ((err = device_create_file(&new_client->dev, | 1048 | if ((err = device_create_file(dev, |
| 1045 | &sensor_dev_attr_fan3_input.dev_attr)) | 1049 | &sensor_dev_attr_fan3_input.dev_attr)) |
| 1046 | || (err = device_create_file(&new_client->dev, | 1050 | || (err = device_create_file(dev, |
| 1047 | &sensor_dev_attr_fan3_min.dev_attr)) | 1051 | &sensor_dev_attr_fan3_min.dev_attr)) |
| 1048 | || (err = device_create_file(&new_client->dev, | 1052 | || (err = device_create_file(dev, |
| 1049 | &sensor_dev_attr_fan3_div.dev_attr))) | 1053 | &sensor_dev_attr_fan3_div.dev_attr))) |
| 1050 | goto ERROR4; | 1054 | goto ERROR4; |
| 1051 | } | 1055 | } |
| 1052 | } | 1056 | } |
| 1053 | 1057 | ||
| 1054 | if (enable_pwm_interface) { | 1058 | if (enable_pwm_interface) { |
| 1055 | if ((err = device_create_file(&new_client->dev, | 1059 | if ((err = device_create_file(dev, |
| 1056 | &sensor_dev_attr_pwm1_enable.dev_attr)) | 1060 | &sensor_dev_attr_pwm1_enable.dev_attr)) |
| 1057 | || (err = device_create_file(&new_client->dev, | 1061 | || (err = device_create_file(dev, |
| 1058 | &sensor_dev_attr_pwm2_enable.dev_attr)) | 1062 | &sensor_dev_attr_pwm2_enable.dev_attr)) |
| 1059 | || (err = device_create_file(&new_client->dev, | 1063 | || (err = device_create_file(dev, |
| 1060 | &sensor_dev_attr_pwm3_enable.dev_attr)) | 1064 | &sensor_dev_attr_pwm3_enable.dev_attr)) |
| 1061 | || (err = device_create_file(&new_client->dev, | 1065 | || (err = device_create_file(dev, |
| 1062 | &sensor_dev_attr_pwm1.dev_attr)) | 1066 | &sensor_dev_attr_pwm1.dev_attr)) |
| 1063 | || (err = device_create_file(&new_client->dev, | 1067 | || (err = device_create_file(dev, |
| 1064 | &sensor_dev_attr_pwm2.dev_attr)) | 1068 | &sensor_dev_attr_pwm2.dev_attr)) |
| 1065 | || (err = device_create_file(&new_client->dev, | 1069 | || (err = device_create_file(dev, |
| 1066 | &sensor_dev_attr_pwm3.dev_attr)) | 1070 | &sensor_dev_attr_pwm3.dev_attr)) |
| 1067 | || (err = device_create_file(&new_client->dev, | 1071 | || (err = device_create_file(dev, |
| 1068 | &dev_attr_pwm1_freq)) | 1072 | &dev_attr_pwm1_freq)) |
| 1069 | || (err = device_create_file(&new_client->dev, | 1073 | || (err = device_create_file(dev, |
| 1070 | &dev_attr_pwm2_freq)) | 1074 | &dev_attr_pwm2_freq)) |
| 1071 | || (err = device_create_file(&new_client->dev, | 1075 | || (err = device_create_file(dev, |
| 1072 | &dev_attr_pwm3_freq))) | 1076 | &dev_attr_pwm3_freq))) |
| 1073 | goto ERROR4; | 1077 | goto ERROR4; |
| 1074 | } | 1078 | } |
| @@ -1077,15 +1081,15 @@ static int it87_detect(struct i2c_adapter *adapter) | |||
| 1077 | || data->type == it8718) { | 1081 | || data->type == it8718) { |
| 1078 | data->vrm = vid_which_vrm(); | 1082 | data->vrm = vid_which_vrm(); |
| 1079 | /* VID reading from Super-I/O config space if available */ | 1083 | /* VID reading from Super-I/O config space if available */ |
| 1080 | data->vid = vid_value; | 1084 | data->vid = sio_data->vid_value; |
| 1081 | if ((err = device_create_file(&new_client->dev, | 1085 | if ((err = device_create_file(dev, |
| 1082 | &dev_attr_vrm)) | 1086 | &dev_attr_vrm)) |
| 1083 | || (err = device_create_file(&new_client->dev, | 1087 | || (err = device_create_file(dev, |
| 1084 | &dev_attr_cpu0_vid))) | 1088 | &dev_attr_cpu0_vid))) |
| 1085 | goto ERROR4; | 1089 | goto ERROR4; |
| 1086 | } | 1090 | } |
| 1087 | 1091 | ||
| 1088 | data->class_dev = hwmon_device_register(&new_client->dev); | 1092 | data->class_dev = hwmon_device_register(dev); |
| 1089 | if (IS_ERR(data->class_dev)) { | 1093 | if (IS_ERR(data->class_dev)) { |
| 1090 | err = PTR_ERR(data->class_dev); | 1094 | err = PTR_ERR(data->class_dev); |
| 1091 | goto ERROR4; | 1095 | goto ERROR4; |
| @@ -1094,31 +1098,27 @@ static int it87_detect(struct i2c_adapter *adapter) | |||
| 1094 | return 0; | 1098 | return 0; |
| 1095 | 1099 | ||
| 1096 | ERROR4: | 1100 | ERROR4: |
| 1097 | sysfs_remove_group(&new_client->dev.kobj, &it87_group); | 1101 | sysfs_remove_group(&dev->kobj, &it87_group); |
| 1098 | sysfs_remove_group(&new_client->dev.kobj, &it87_group_opt); | 1102 | sysfs_remove_group(&dev->kobj, &it87_group_opt); |
| 1099 | ERROR3: | ||
| 1100 | i2c_detach_client(new_client); | ||
| 1101 | ERROR2: | 1103 | ERROR2: |
| 1104 | platform_set_drvdata(pdev, NULL); | ||
| 1102 | kfree(data); | 1105 | kfree(data); |
| 1103 | ERROR1: | 1106 | ERROR1: |
| 1104 | release_region(isa_address, IT87_EXTENT); | 1107 | release_region(res->start, IT87_EXTENT); |
| 1105 | ERROR0: | 1108 | ERROR0: |
| 1106 | return err; | 1109 | return err; |
| 1107 | } | 1110 | } |
| 1108 | 1111 | ||
| 1109 | static int it87_detach_client(struct i2c_client *client) | 1112 | static int __devexit it87_remove(struct platform_device *pdev) |
| 1110 | { | 1113 | { |
| 1111 | struct it87_data *data = i2c_get_clientdata(client); | 1114 | struct it87_data *data = platform_get_drvdata(pdev); |
| 1112 | int err; | ||
| 1113 | 1115 | ||
| 1114 | hwmon_device_unregister(data->class_dev); | 1116 | hwmon_device_unregister(data->class_dev); |
| 1115 | sysfs_remove_group(&client->dev.kobj, &it87_group); | 1117 | sysfs_remove_group(&pdev->dev.kobj, &it87_group); |
| 1116 | sysfs_remove_group(&client->dev.kobj, &it87_group_opt); | 1118 | sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt); |
| 1117 | 1119 | ||
| 1118 | if ((err = i2c_detach_client(client))) | 1120 | release_region(data->addr, IT87_EXTENT); |
| 1119 | return err; | 1121 | platform_set_drvdata(pdev, NULL); |
| 1120 | |||
| 1121 | release_region(client->addr, IT87_EXTENT); | ||
| 1122 | kfree(data); | 1122 | kfree(data); |
| 1123 | 1123 | ||
| 1124 | return 0; | 1124 | return 0; |
| @@ -1127,28 +1127,29 @@ static int it87_detach_client(struct i2c_client *client) | |||
| 1127 | /* Must be called with data->update_lock held, except during initialization. | 1127 | /* Must be called with data->update_lock held, except during initialization. |
| 1128 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, | 1128 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, |
| 1129 | would slow down the IT87 access and should not be necessary. */ | 1129 | would slow down the IT87 access and should not be necessary. */ |
| 1130 | static int it87_read_value(struct i2c_client *client, u8 reg) | 1130 | static int it87_read_value(struct it87_data *data, u8 reg) |
| 1131 | { | 1131 | { |
| 1132 | outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); | 1132 | outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); |
| 1133 | return inb_p(client->addr + IT87_DATA_REG_OFFSET); | 1133 | return inb_p(data->addr + IT87_DATA_REG_OFFSET); |
| 1134 | } | 1134 | } |
| 1135 | 1135 | ||
| 1136 | /* Must be called with data->update_lock held, except during initialization. | 1136 | /* Must be called with data->update_lock held, except during initialization. |
| 1137 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, | 1137 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, |
| 1138 | would slow down the IT87 access and should not be necessary. */ | 1138 | would slow down the IT87 access and should not be necessary. */ |
| 1139 | static void it87_write_value(struct i2c_client *client, u8 reg, u8 value) | 1139 | static void it87_write_value(struct it87_data *data, u8 reg, u8 value) |
| 1140 | { | 1140 | { |
| 1141 | outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); | 1141 | outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); |
| 1142 | outb_p(value, client->addr + IT87_DATA_REG_OFFSET); | 1142 | outb_p(value, data->addr + IT87_DATA_REG_OFFSET); |
| 1143 | } | 1143 | } |
| 1144 | 1144 | ||
| 1145 | /* Return 1 if and only if the PWM interface is safe to use */ | 1145 | /* Return 1 if and only if the PWM interface is safe to use */ |
| 1146 | static int it87_check_pwm(struct i2c_client *client) | 1146 | static int __devinit it87_check_pwm(struct device *dev) |
| 1147 | { | 1147 | { |
| 1148 | struct it87_data *data = dev_get_drvdata(dev); | ||
| 1148 | /* Some BIOSes fail to correctly configure the IT87 fans. All fans off | 1149 | /* Some BIOSes fail to correctly configure the IT87 fans. All fans off |
| 1149 | * and polarity set to active low is sign that this is the case so we | 1150 | * and polarity set to active low is sign that this is the case so we |
| 1150 | * disable pwm control to protect the user. */ | 1151 | * disable pwm control to protect the user. */ |
| 1151 | int tmp = it87_read_value(client, IT87_REG_FAN_CTL); | 1152 | int tmp = it87_read_value(data, IT87_REG_FAN_CTL); |
| 1152 | if ((tmp & 0x87) == 0) { | 1153 | if ((tmp & 0x87) == 0) { |
| 1153 | if (fix_pwm_polarity) { | 1154 | if (fix_pwm_polarity) { |
| 1154 | /* The user asks us to attempt a chip reconfiguration. | 1155 | /* The user asks us to attempt a chip reconfiguration. |
| @@ -1158,7 +1159,7 @@ static int it87_check_pwm(struct i2c_client *client) | |||
| 1158 | u8 pwm[3]; | 1159 | u8 pwm[3]; |
| 1159 | 1160 | ||
| 1160 | for (i = 0; i < 3; i++) | 1161 | for (i = 0; i < 3; i++) |
| 1161 | pwm[i] = it87_read_value(client, | 1162 | pwm[i] = it87_read_value(data, |
| 1162 | IT87_REG_PWM(i)); | 1163 | IT87_REG_PWM(i)); |
| 1163 | 1164 | ||
| 1164 | /* If any fan is in automatic pwm mode, the polarity | 1165 | /* If any fan is in automatic pwm mode, the polarity |
| @@ -1166,26 +1167,26 @@ static int it87_check_pwm(struct i2c_client *client) | |||
| 1166 | * better don't change anything (but still disable the | 1167 | * better don't change anything (but still disable the |
| 1167 | * PWM interface). */ | 1168 | * PWM interface). */ |
| 1168 | if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { | 1169 | if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { |
| 1169 | dev_info(&client->dev, "Reconfiguring PWM to " | 1170 | dev_info(dev, "Reconfiguring PWM to " |
| 1170 | "active high polarity\n"); | 1171 | "active high polarity\n"); |
| 1171 | it87_write_value(client, IT87_REG_FAN_CTL, | 1172 | it87_write_value(data, IT87_REG_FAN_CTL, |
| 1172 | tmp | 0x87); | 1173 | tmp | 0x87); |
| 1173 | for (i = 0; i < 3; i++) | 1174 | for (i = 0; i < 3; i++) |
| 1174 | it87_write_value(client, | 1175 | it87_write_value(data, |
| 1175 | IT87_REG_PWM(i), | 1176 | IT87_REG_PWM(i), |
| 1176 | 0x7f & ~pwm[i]); | 1177 | 0x7f & ~pwm[i]); |
| 1177 | return 1; | 1178 | return 1; |
| 1178 | } | 1179 | } |
| 1179 | 1180 | ||
| 1180 | dev_info(&client->dev, "PWM configuration is " | 1181 | dev_info(dev, "PWM configuration is " |
| 1181 | "too broken to be fixed\n"); | 1182 | "too broken to be fixed\n"); |
| 1182 | } | 1183 | } |
| 1183 | 1184 | ||
| 1184 | dev_info(&client->dev, "Detected broken BIOS " | 1185 | dev_info(dev, "Detected broken BIOS " |
| 1185 | "defaults, disabling PWM interface\n"); | 1186 | "defaults, disabling PWM interface\n"); |
| 1186 | return 0; | 1187 | return 0; |
| 1187 | } else if (fix_pwm_polarity) { | 1188 | } else if (fix_pwm_polarity) { |
| 1188 | dev_info(&client->dev, "PWM configuration looks " | 1189 | dev_info(dev, "PWM configuration looks " |
| 1189 | "sane, won't touch\n"); | 1190 | "sane, won't touch\n"); |
| 1190 | } | 1191 | } |
| 1191 | 1192 | ||
| @@ -1193,8 +1194,9 @@ static int it87_check_pwm(struct i2c_client *client) | |||
| 1193 | } | 1194 | } |
| 1194 | 1195 | ||
| 1195 | /* Called when we have found a new IT87. */ | 1196 | /* Called when we have found a new IT87. */ |
| 1196 | static void it87_init_client(struct i2c_client *client, struct it87_data *data) | 1197 | static void __devinit it87_init_device(struct platform_device *pdev) |
| 1197 | { | 1198 | { |
| 1199 | struct it87_data *data = platform_get_drvdata(pdev); | ||
| 1198 | int tmp, i; | 1200 | int tmp, i; |
| 1199 | 1201 | ||
| 1200 | /* initialize to sane defaults: | 1202 | /* initialize to sane defaults: |
| @@ -1214,48 +1216,48 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) | |||
| 1214 | * means -1 degree C, which surprisingly doesn't trigger an alarm, | 1216 | * means -1 degree C, which surprisingly doesn't trigger an alarm, |
| 1215 | * but is still confusing, so change to 127 degrees C. */ | 1217 | * but is still confusing, so change to 127 degrees C. */ |
| 1216 | for (i = 0; i < 8; i++) { | 1218 | for (i = 0; i < 8; i++) { |
| 1217 | tmp = it87_read_value(client, IT87_REG_VIN_MIN(i)); | 1219 | tmp = it87_read_value(data, IT87_REG_VIN_MIN(i)); |
| 1218 | if (tmp == 0xff) | 1220 | if (tmp == 0xff) |
| 1219 | it87_write_value(client, IT87_REG_VIN_MIN(i), 0); | 1221 | it87_write_value(data, IT87_REG_VIN_MIN(i), 0); |
| 1220 | } | 1222 | } |
| 1221 | for (i = 0; i < 3; i++) { | 1223 | for (i = 0; i < 3; i++) { |
| 1222 | tmp = it87_read_value(client, IT87_REG_TEMP_HIGH(i)); | 1224 | tmp = it87_read_value(data, IT87_REG_TEMP_HIGH(i)); |
| 1223 | if (tmp == 0xff) | 1225 | if (tmp == 0xff) |
| 1224 | it87_write_value(client, IT87_REG_TEMP_HIGH(i), 127); | 1226 | it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); |
| 1225 | } | 1227 | } |
| 1226 | 1228 | ||
| 1227 | /* Check if temperature channnels are reset manually or by some reason */ | 1229 | /* Check if temperature channnels are reset manually or by some reason */ |
| 1228 | tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE); | 1230 | tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE); |
| 1229 | if ((tmp & 0x3f) == 0) { | 1231 | if ((tmp & 0x3f) == 0) { |
| 1230 | /* Temp1,Temp3=thermistor; Temp2=thermal diode */ | 1232 | /* Temp1,Temp3=thermistor; Temp2=thermal diode */ |
| 1231 | tmp = (tmp & 0xc0) | 0x2a; | 1233 | tmp = (tmp & 0xc0) | 0x2a; |
| 1232 | it87_write_value(client, IT87_REG_TEMP_ENABLE, tmp); | 1234 | it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp); |
| 1233 | } | 1235 | } |
| 1234 | data->sensor = tmp; | 1236 | data->sensor = tmp; |
| 1235 | 1237 | ||
| 1236 | /* Check if voltage monitors are reset manually or by some reason */ | 1238 | /* Check if voltage monitors are reset manually or by some reason */ |
| 1237 | tmp = it87_read_value(client, IT87_REG_VIN_ENABLE); | 1239 | tmp = it87_read_value(data, IT87_REG_VIN_ENABLE); |
| 1238 | if ((tmp & 0xff) == 0) { | 1240 | if ((tmp & 0xff) == 0) { |
| 1239 | /* Enable all voltage monitors */ | 1241 | /* Enable all voltage monitors */ |
| 1240 | it87_write_value(client, IT87_REG_VIN_ENABLE, 0xff); | 1242 | it87_write_value(data, IT87_REG_VIN_ENABLE, 0xff); |
| 1241 | } | 1243 | } |
| 1242 | 1244 | ||
| 1243 | /* Check if tachometers are reset manually or by some reason */ | 1245 | /* Check if tachometers are reset manually or by some reason */ |
| 1244 | data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL); | 1246 | data->fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL); |
| 1245 | if ((data->fan_main_ctrl & 0x70) == 0) { | 1247 | if ((data->fan_main_ctrl & 0x70) == 0) { |
| 1246 | /* Enable all fan tachometers */ | 1248 | /* Enable all fan tachometers */ |
| 1247 | data->fan_main_ctrl |= 0x70; | 1249 | data->fan_main_ctrl |= 0x70; |
| 1248 | it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); | 1250 | it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); |
| 1249 | } | 1251 | } |
| 1250 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; | 1252 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; |
| 1251 | 1253 | ||
| 1252 | /* Set tachometers to 16-bit mode if needed */ | 1254 | /* Set tachometers to 16-bit mode if needed */ |
| 1253 | if (data->type == it8716 || data->type == it8718) { | 1255 | if (data->type == it8716 || data->type == it8718) { |
| 1254 | tmp = it87_read_value(client, IT87_REG_FAN_16BIT); | 1256 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); |
| 1255 | if (~tmp & 0x07 & data->has_fan) { | 1257 | if (~tmp & 0x07 & data->has_fan) { |
| 1256 | dev_dbg(&client->dev, | 1258 | dev_dbg(&pdev->dev, |
| 1257 | "Setting fan1-3 to 16-bit mode\n"); | 1259 | "Setting fan1-3 to 16-bit mode\n"); |
| 1258 | it87_write_value(client, IT87_REG_FAN_16BIT, | 1260 | it87_write_value(data, IT87_REG_FAN_16BIT, |
| 1259 | tmp | 0x07); | 1261 | tmp | 0x07); |
| 1260 | } | 1262 | } |
| 1261 | } | 1263 | } |
| @@ -1265,7 +1267,7 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) | |||
| 1265 | for (i = 0; i < 3; i++) { | 1267 | for (i = 0; i < 3; i++) { |
| 1266 | if (data->fan_main_ctrl & (1 << i)) { | 1268 | if (data->fan_main_ctrl & (1 << i)) { |
| 1267 | /* pwm mode */ | 1269 | /* pwm mode */ |
| 1268 | tmp = it87_read_value(client, IT87_REG_PWM(i)); | 1270 | tmp = it87_read_value(data, IT87_REG_PWM(i)); |
| 1269 | if (tmp & 0x80) { | 1271 | if (tmp & 0x80) { |
| 1270 | /* automatic pwm - not yet implemented, but | 1272 | /* automatic pwm - not yet implemented, but |
| 1271 | * leave the settings made by the BIOS alone | 1273 | * leave the settings made by the BIOS alone |
| @@ -1279,15 +1281,14 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) | |||
| 1279 | } | 1281 | } |
| 1280 | 1282 | ||
| 1281 | /* Start monitoring */ | 1283 | /* Start monitoring */ |
| 1282 | it87_write_value(client, IT87_REG_CONFIG, | 1284 | it87_write_value(data, IT87_REG_CONFIG, |
| 1283 | (it87_read_value(client, IT87_REG_CONFIG) & 0x36) | 1285 | (it87_read_value(data, IT87_REG_CONFIG) & 0x36) |
| 1284 | | (update_vbat ? 0x41 : 0x01)); | 1286 | | (update_vbat ? 0x41 : 0x01)); |
| 1285 | } | 1287 | } |
| 1286 | 1288 | ||
| 1287 | static struct it87_data *it87_update_device(struct device *dev) | 1289 | static struct it87_data *it87_update_device(struct device *dev) |
| 1288 | { | 1290 | { |
| 1289 | struct i2c_client *client = to_i2c_client(dev); | 1291 | struct it87_data *data = dev_get_drvdata(dev); |
| 1290 | struct it87_data *data = i2c_get_clientdata(client); | ||
| 1291 | int i; | 1292 | int i; |
| 1292 | 1293 | ||
| 1293 | mutex_lock(&data->update_lock); | 1294 | mutex_lock(&data->update_lock); |
| @@ -1298,20 +1299,20 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
| 1298 | if (update_vbat) { | 1299 | if (update_vbat) { |
| 1299 | /* Cleared after each update, so reenable. Value | 1300 | /* Cleared after each update, so reenable. Value |
| 1300 | returned by this read will be previous value */ | 1301 | returned by this read will be previous value */ |
| 1301 | it87_write_value(client, IT87_REG_CONFIG, | 1302 | it87_write_value(data, IT87_REG_CONFIG, |
| 1302 | it87_read_value(client, IT87_REG_CONFIG) | 0x40); | 1303 | it87_read_value(data, IT87_REG_CONFIG) | 0x40); |
| 1303 | } | 1304 | } |
| 1304 | for (i = 0; i <= 7; i++) { | 1305 | for (i = 0; i <= 7; i++) { |
| 1305 | data->in[i] = | 1306 | data->in[i] = |
| 1306 | it87_read_value(client, IT87_REG_VIN(i)); | 1307 | it87_read_value(data, IT87_REG_VIN(i)); |
| 1307 | data->in_min[i] = | 1308 | data->in_min[i] = |
| 1308 | it87_read_value(client, IT87_REG_VIN_MIN(i)); | 1309 | it87_read_value(data, IT87_REG_VIN_MIN(i)); |
| 1309 | data->in_max[i] = | 1310 | data->in_max[i] = |
| 1310 | it87_read_value(client, IT87_REG_VIN_MAX(i)); | 1311 | it87_read_value(data, IT87_REG_VIN_MAX(i)); |
| 1311 | } | 1312 | } |
| 1312 | /* in8 (battery) has no limit registers */ | 1313 | /* in8 (battery) has no limit registers */ |
| 1313 | data->in[8] = | 1314 | data->in[8] = |
| 1314 | it87_read_value(client, IT87_REG_VIN(8)); | 1315 | it87_read_value(data, IT87_REG_VIN(8)); |
| 1315 | 1316 | ||
| 1316 | for (i = 0; i < 3; i++) { | 1317 | for (i = 0; i < 3; i++) { |
| 1317 | /* Skip disabled fans */ | 1318 | /* Skip disabled fans */ |
| @@ -1319,46 +1320,47 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
| 1319 | continue; | 1320 | continue; |
| 1320 | 1321 | ||
| 1321 | data->fan_min[i] = | 1322 | data->fan_min[i] = |
| 1322 | it87_read_value(client, IT87_REG_FAN_MIN(i)); | 1323 | it87_read_value(data, IT87_REG_FAN_MIN(i)); |
| 1323 | data->fan[i] = it87_read_value(client, | 1324 | data->fan[i] = it87_read_value(data, |
| 1324 | IT87_REG_FAN(i)); | 1325 | IT87_REG_FAN(i)); |
| 1325 | /* Add high byte if in 16-bit mode */ | 1326 | /* Add high byte if in 16-bit mode */ |
| 1326 | if (data->type == it8716 || data->type == it8718) { | 1327 | if (data->type == it8716 || data->type == it8718) { |
| 1327 | data->fan[i] |= it87_read_value(client, | 1328 | data->fan[i] |= it87_read_value(data, |
| 1328 | IT87_REG_FANX(i)) << 8; | 1329 | IT87_REG_FANX(i)) << 8; |
| 1329 | data->fan_min[i] |= it87_read_value(client, | 1330 | data->fan_min[i] |= it87_read_value(data, |
| 1330 | IT87_REG_FANX_MIN(i)) << 8; | 1331 | IT87_REG_FANX_MIN(i)) << 8; |
| 1331 | } | 1332 | } |
| 1332 | } | 1333 | } |
| 1333 | for (i = 0; i < 3; i++) { | 1334 | for (i = 0; i < 3; i++) { |
| 1334 | data->temp[i] = | 1335 | data->temp[i] = |
| 1335 | it87_read_value(client, IT87_REG_TEMP(i)); | 1336 | it87_read_value(data, IT87_REG_TEMP(i)); |
| 1336 | data->temp_high[i] = | 1337 | data->temp_high[i] = |
| 1337 | it87_read_value(client, IT87_REG_TEMP_HIGH(i)); | 1338 | it87_read_value(data, IT87_REG_TEMP_HIGH(i)); |
| 1338 | data->temp_low[i] = | 1339 | data->temp_low[i] = |
| 1339 | it87_read_value(client, IT87_REG_TEMP_LOW(i)); | 1340 | it87_read_value(data, IT87_REG_TEMP_LOW(i)); |
| 1340 | } | 1341 | } |
| 1341 | 1342 | ||
| 1342 | /* Newer chips don't have clock dividers */ | 1343 | /* Newer chips don't have clock dividers */ |
| 1343 | if ((data->has_fan & 0x07) && data->type != it8716 | 1344 | if ((data->has_fan & 0x07) && data->type != it8716 |
| 1344 | && data->type != it8718) { | 1345 | && data->type != it8718) { |
| 1345 | i = it87_read_value(client, IT87_REG_FAN_DIV); | 1346 | i = it87_read_value(data, IT87_REG_FAN_DIV); |
| 1346 | data->fan_div[0] = i & 0x07; | 1347 | data->fan_div[0] = i & 0x07; |
| 1347 | data->fan_div[1] = (i >> 3) & 0x07; | 1348 | data->fan_div[1] = (i >> 3) & 0x07; |
| 1348 | data->fan_div[2] = (i & 0x40) ? 3 : 1; | 1349 | data->fan_div[2] = (i & 0x40) ? 3 : 1; |
| 1349 | } | 1350 | } |
| 1350 | 1351 | ||
| 1351 | data->alarms = | 1352 | data->alarms = |
| 1352 | it87_read_value(client, IT87_REG_ALARM1) | | 1353 | it87_read_value(data, IT87_REG_ALARM1) | |
| 1353 | (it87_read_value(client, IT87_REG_ALARM2) << 8) | | 1354 | (it87_read_value(data, IT87_REG_ALARM2) << 8) | |
| 1354 | (it87_read_value(client, IT87_REG_ALARM3) << 16); | 1355 | (it87_read_value(data, IT87_REG_ALARM3) << 16); |
| 1355 | data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL); | 1356 | data->fan_main_ctrl = it87_read_value(data, |
| 1356 | data->fan_ctl = it87_read_value(client, IT87_REG_FAN_CTL); | 1357 | IT87_REG_FAN_MAIN_CTRL); |
| 1357 | 1358 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); | |
| 1358 | data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE); | 1359 | |
| 1360 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); | ||
| 1359 | /* The 8705 does not have VID capability */ | 1361 | /* The 8705 does not have VID capability */ |
| 1360 | if (data->type == it8712 || data->type == it8716) { | 1362 | if (data->type == it8712 || data->type == it8716) { |
| 1361 | data->vid = it87_read_value(client, IT87_REG_VID); | 1363 | data->vid = it87_read_value(data, IT87_REG_VID); |
| 1362 | /* The older IT8712F revisions had only 5 VID pins, | 1364 | /* The older IT8712F revisions had only 5 VID pins, |
| 1363 | but we assume it is always safe to read 6 bits. */ | 1365 | but we assume it is always safe to read 6 bits. */ |
| 1364 | data->vid &= 0x3f; | 1366 | data->vid &= 0x3f; |
| @@ -1372,24 +1374,85 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
| 1372 | return data; | 1374 | return data; |
| 1373 | } | 1375 | } |
| 1374 | 1376 | ||
| 1377 | static int __init it87_device_add(unsigned short address, | ||
| 1378 | const struct it87_sio_data *sio_data) | ||
| 1379 | { | ||
| 1380 | struct resource res = { | ||
| 1381 | .start = address , | ||
| 1382 | .end = address + IT87_EXTENT - 1, | ||
| 1383 | .name = DRVNAME, | ||
| 1384 | .flags = IORESOURCE_IO, | ||
| 1385 | }; | ||
| 1386 | int err; | ||
| 1387 | |||
| 1388 | pdev = platform_device_alloc(DRVNAME, address); | ||
| 1389 | if (!pdev) { | ||
| 1390 | err = -ENOMEM; | ||
| 1391 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | ||
| 1392 | goto exit; | ||
| 1393 | } | ||
| 1394 | |||
| 1395 | err = platform_device_add_resources(pdev, &res, 1); | ||
| 1396 | if (err) { | ||
| 1397 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | ||
| 1398 | "(%d)\n", err); | ||
| 1399 | goto exit_device_put; | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | err = platform_device_add_data(pdev, sio_data, | ||
| 1403 | sizeof(struct it87_sio_data)); | ||
| 1404 | if (err) { | ||
| 1405 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | ||
| 1406 | goto exit_device_put; | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | err = platform_device_add(pdev); | ||
| 1410 | if (err) { | ||
| 1411 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | ||
| 1412 | err); | ||
| 1413 | goto exit_device_put; | ||
| 1414 | } | ||
| 1415 | |||
| 1416 | return 0; | ||
| 1417 | |||
| 1418 | exit_device_put: | ||
| 1419 | platform_device_put(pdev); | ||
| 1420 | exit: | ||
| 1421 | return err; | ||
| 1422 | } | ||
| 1423 | |||
| 1375 | static int __init sm_it87_init(void) | 1424 | static int __init sm_it87_init(void) |
| 1376 | { | 1425 | { |
| 1377 | int res; | 1426 | int err; |
| 1427 | unsigned short isa_address=0; | ||
| 1428 | struct it87_sio_data sio_data; | ||
| 1429 | |||
| 1430 | err = it87_find(&isa_address, &sio_data); | ||
| 1431 | if (err) | ||
| 1432 | return err; | ||
| 1433 | err = platform_driver_register(&it87_driver); | ||
| 1434 | if (err) | ||
| 1435 | return err; | ||
| 1378 | 1436 | ||
| 1379 | if ((res = it87_find(&isa_address))) | 1437 | err = it87_device_add(isa_address, &sio_data); |
| 1380 | return res; | 1438 | if (err){ |
| 1381 | return i2c_isa_add_driver(&it87_isa_driver); | 1439 | platform_driver_unregister(&it87_driver); |
| 1440 | return err; | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | return 0; | ||
| 1382 | } | 1444 | } |
| 1383 | 1445 | ||
| 1384 | static void __exit sm_it87_exit(void) | 1446 | static void __exit sm_it87_exit(void) |
| 1385 | { | 1447 | { |
| 1386 | i2c_isa_del_driver(&it87_isa_driver); | 1448 | platform_device_unregister(pdev); |
| 1449 | platform_driver_unregister(&it87_driver); | ||
| 1387 | } | 1450 | } |
| 1388 | 1451 | ||
| 1389 | 1452 | ||
| 1390 | MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>, " | 1453 | MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>, " |
| 1391 | "Jean Delvare <khali@linux-fr.org>"); | 1454 | "Jean Delvare <khali@linux-fr.org>"); |
| 1392 | MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F, SiS950 driver"); | 1455 | MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F/8726F, SiS950 driver"); |
| 1393 | module_param(update_vbat, bool, 0); | 1456 | module_param(update_vbat, bool, 0); |
| 1394 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); | 1457 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); |
| 1395 | module_param(fix_pwm_polarity, bool, 0); | 1458 | module_param(fix_pwm_polarity, bool, 0); |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index d69f3cf07122..2162d69a8c06 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
| @@ -364,7 +364,7 @@ static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, | |||
| 364 | /* Individual alarm files */ | 364 | /* Individual alarm files */ |
| 365 | static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0); | 365 | static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0); |
| 366 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | 366 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); |
| 367 | static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2); | 367 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); |
| 368 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); | 368 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); |
| 369 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | 369 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); |
| 370 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | 370 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); |
| @@ -383,7 +383,7 @@ static struct attribute *lm63_attributes[] = { | |||
| 383 | &dev_attr_temp2_crit_hyst.attr, | 383 | &dev_attr_temp2_crit_hyst.attr, |
| 384 | 384 | ||
| 385 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | 385 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, |
| 386 | &sensor_dev_attr_temp2_input_fault.dev_attr.attr, | 386 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
| 387 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | 387 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, |
| 388 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 388 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
| 389 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 389 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index feb87b41e986..654c0f73464d 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c | |||
| @@ -223,14 +223,14 @@ static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp, NULL, 8); | |||
| 223 | /* Individual alarm files */ | 223 | /* Individual alarm files */ |
| 224 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | 224 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); |
| 225 | static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | 225 | static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 1); |
| 226 | static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 2); | 226 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 2); |
| 227 | static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 4); | 227 | static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 4); |
| 228 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | 228 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); |
| 229 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 8); | 229 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 8); |
| 230 | static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, 9); | 230 | static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, 9); |
| 231 | static SENSOR_DEVICE_ATTR(temp4_input_fault, S_IRUGO, show_alarm, NULL, 10); | 231 | static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_alarm, NULL, 10); |
| 232 | static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, 12); | 232 | static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, 12); |
| 233 | static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 13); | 233 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 13); |
| 234 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 15); | 234 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 15); |
| 235 | /* Raw alarm file for compatibility */ | 235 | /* Raw alarm file for compatibility */ |
| 236 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 236 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
| @@ -245,7 +245,7 @@ static struct attribute *lm83_attributes[] = { | |||
| 245 | 245 | ||
| 246 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 246 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
| 247 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | 247 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, |
| 248 | &sensor_dev_attr_temp3_input_fault.dev_attr.attr, | 248 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
| 249 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | 249 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, |
| 250 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 250 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
| 251 | &dev_attr_alarms.attr, | 251 | &dev_attr_alarms.attr, |
| @@ -266,9 +266,9 @@ static struct attribute *lm83_attributes_opt[] = { | |||
| 266 | 266 | ||
| 267 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | 267 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, |
| 268 | &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, | 268 | &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, |
| 269 | &sensor_dev_attr_temp4_input_fault.dev_attr.attr, | 269 | &sensor_dev_attr_temp4_fault.dev_attr.attr, |
| 270 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | 270 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, |
| 271 | &sensor_dev_attr_temp2_input_fault.dev_attr.attr, | 271 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
| 272 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 272 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
| 273 | NULL | 273 | NULL |
| 274 | }; | 274 | }; |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 6882ce75feee..48833fff4920 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
| @@ -43,6 +43,13 @@ | |||
| 43 | * variants. The extra address and features of the MAX6659 are not | 43 | * variants. The extra address and features of the MAX6659 are not |
| 44 | * supported by this driver. | 44 | * supported by this driver. |
| 45 | * | 45 | * |
| 46 | * This driver also supports the MAX6680 and MAX6681, two other sensor | ||
| 47 | * chips made by Maxim. These are quite similar to the other Maxim | ||
| 48 | * chips. Complete datasheet can be obtained at: | ||
| 49 | * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 | ||
| 50 | * The MAX6680 and MAX6681 only differ in the pinout so they can be | ||
| 51 | * treated identically. | ||
| 52 | * | ||
| 46 | * This driver also supports the ADT7461 chip from Analog Devices but | 53 | * This driver also supports the ADT7461 chip from Analog Devices but |
| 47 | * only in its "compatability mode". If an ADT7461 chip is found but | 54 | * only in its "compatability mode". If an ADT7461 chip is found but |
| 48 | * is configured in non-compatible mode (where its temperature | 55 | * is configured in non-compatible mode (where its temperature |
| @@ -84,20 +91,25 @@ | |||
| 84 | /* | 91 | /* |
| 85 | * Addresses to scan | 92 | * Addresses to scan |
| 86 | * Address is fully defined internally and cannot be changed except for | 93 | * Address is fully defined internally and cannot be changed except for |
| 87 | * MAX6659. | 94 | * MAX6659, MAX6680 and MAX6681. |
| 88 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658 | 95 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658 |
| 89 | * have address 0x4c. | 96 | * have address 0x4c. |
| 90 | * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d. | 97 | * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d. |
| 91 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). | 98 | * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported). |
| 99 | * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | ||
| 100 | * 0x4c, 0x4d or 0x4e. | ||
| 92 | */ | 101 | */ |
| 93 | 102 | ||
| 94 | static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END }; | 103 | static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, |
| 104 | 0x29, 0x2a, 0x2b, | ||
| 105 | 0x4c, 0x4d, 0x4e, | ||
| 106 | I2C_CLIENT_END }; | ||
| 95 | 107 | ||
| 96 | /* | 108 | /* |
| 97 | * Insmod parameters | 109 | * Insmod parameters |
| 98 | */ | 110 | */ |
| 99 | 111 | ||
| 100 | I2C_CLIENT_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461); | 112 | I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680); |
| 101 | 113 | ||
| 102 | /* | 114 | /* |
| 103 | * The LM90 registers | 115 | * The LM90 registers |
| @@ -359,7 +371,7 @@ static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); | |||
| 359 | /* Individual alarm files */ | 371 | /* Individual alarm files */ |
| 360 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | 372 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); |
| 361 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | 373 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); |
| 362 | static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2); | 374 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); |
| 363 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); | 375 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); |
| 364 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | 376 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); |
| 365 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); | 377 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); |
| @@ -381,7 +393,7 @@ static struct attribute *lm90_attributes[] = { | |||
| 381 | 393 | ||
| 382 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 394 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
| 383 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | 395 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, |
| 384 | &sensor_dev_attr_temp2_input_fault.dev_attr.attr, | 396 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
| 385 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | 397 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, |
| 386 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 398 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
| 387 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | 399 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, |
| @@ -429,7 +441,7 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); | |||
| 429 | */ | 441 | */ |
| 430 | 442 | ||
| 431 | /* The ADM1032 supports PEC but not on write byte transactions, so we need | 443 | /* The ADM1032 supports PEC but not on write byte transactions, so we need |
| 432 | to explicitely ask for a transaction without PEC. */ | 444 | to explicitly ask for a transaction without PEC. */ |
| 433 | static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) | 445 | static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) |
| 434 | { | 446 | { |
| 435 | return i2c_smbus_xfer(client->adapter, client->addr, | 447 | return i2c_smbus_xfer(client->adapter, client->addr, |
| @@ -525,7 +537,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 525 | ®_convrate) < 0) | 537 | ®_convrate) < 0) |
| 526 | goto exit_free; | 538 | goto exit_free; |
| 527 | 539 | ||
| 528 | if (man_id == 0x01) { /* National Semiconductor */ | 540 | if ((address == 0x4C || address == 0x4D) |
| 541 | && man_id == 0x01) { /* National Semiconductor */ | ||
| 529 | u8 reg_config2; | 542 | u8 reg_config2; |
| 530 | 543 | ||
| 531 | if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2, | 544 | if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2, |
| @@ -548,7 +561,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 548 | } | 561 | } |
| 549 | } | 562 | } |
| 550 | } else | 563 | } else |
| 551 | if (man_id == 0x41) { /* Analog Devices */ | 564 | if ((address == 0x4C || address == 0x4D) |
| 565 | && man_id == 0x41) { /* Analog Devices */ | ||
| 552 | if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ | 566 | if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ |
| 553 | && (reg_config1 & 0x3F) == 0x00 | 567 | && (reg_config1 & 0x3F) == 0x00 |
| 554 | && reg_convrate <= 0x0A) { | 568 | && reg_convrate <= 0x0A) { |
| @@ -562,18 +576,30 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 562 | } else | 576 | } else |
| 563 | if (man_id == 0x4D) { /* Maxim */ | 577 | if (man_id == 0x4D) { /* Maxim */ |
| 564 | /* | 578 | /* |
| 565 | * The Maxim variants do NOT have a chip_id register. | 579 | * The MAX6657, MAX6658 and MAX6659 do NOT have a |
| 566 | * Reading from that address will return the last read | 580 | * chip_id register. Reading from that address will |
| 567 | * value, which in our case is those of the man_id | 581 | * return the last read value, which in our case is |
| 568 | * register. Likewise, the config1 register seems to | 582 | * those of the man_id register. Likewise, the config1 |
| 569 | * lack a low nibble, so the value will be those of the | 583 | * register seems to lack a low nibble, so the value |
| 570 | * previous read, so in our case those of the man_id | 584 | * will be those of the previous read, so in our case |
| 571 | * register. | 585 | * those of the man_id register. |
| 572 | */ | 586 | */ |
| 573 | if (chip_id == man_id | 587 | if (chip_id == man_id |
| 588 | && (address == 0x4F || address == 0x4D) | ||
| 574 | && (reg_config1 & 0x1F) == (man_id & 0x0F) | 589 | && (reg_config1 & 0x1F) == (man_id & 0x0F) |
| 575 | && reg_convrate <= 0x09) { | 590 | && reg_convrate <= 0x09) { |
| 576 | kind = max6657; | 591 | kind = max6657; |
| 592 | } else | ||
| 593 | /* The chip_id register of the MAX6680 and MAX6681 | ||
| 594 | * holds the revision of the chip. | ||
| 595 | * the lowest bit of the config1 register is unused | ||
| 596 | * and should return zero when read, so should the | ||
| 597 | * second to last bit of config1 (software reset) | ||
| 598 | */ | ||
| 599 | if (chip_id == 0x01 | ||
| 600 | && (reg_config1 & 0x03) == 0x00 | ||
| 601 | && reg_convrate <= 0x07) { | ||
| 602 | kind = max6680; | ||
| 577 | } | 603 | } |
| 578 | } | 604 | } |
| 579 | 605 | ||
| @@ -599,6 +625,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 599 | name = "lm86"; | 625 | name = "lm86"; |
| 600 | } else if (kind == max6657) { | 626 | } else if (kind == max6657) { |
| 601 | name = "max6657"; | 627 | name = "max6657"; |
| 628 | } else if (kind == max6680) { | ||
| 629 | name = "max6680"; | ||
| 602 | } else if (kind == adt7461) { | 630 | } else if (kind == adt7461) { |
| 603 | name = "adt7461"; | 631 | name = "adt7461"; |
| 604 | } | 632 | } |
| @@ -646,7 +674,8 @@ exit: | |||
| 646 | 674 | ||
| 647 | static void lm90_init_client(struct i2c_client *client) | 675 | static void lm90_init_client(struct i2c_client *client) |
| 648 | { | 676 | { |
| 649 | u8 config; | 677 | u8 config, config_orig; |
| 678 | struct lm90_data *data = i2c_get_clientdata(client); | ||
| 650 | 679 | ||
| 651 | /* | 680 | /* |
| 652 | * Start the conversions. | 681 | * Start the conversions. |
| @@ -657,9 +686,20 @@ static void lm90_init_client(struct i2c_client *client) | |||
| 657 | dev_warn(&client->dev, "Initialization failed!\n"); | 686 | dev_warn(&client->dev, "Initialization failed!\n"); |
| 658 | return; | 687 | return; |
| 659 | } | 688 | } |
| 660 | if (config & 0x40) | 689 | config_orig = config; |
| 661 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, | 690 | |
| 662 | config & 0xBF); /* run */ | 691 | /* |
| 692 | * Put MAX6680/MAX8881 into extended resolution (bit 0x10, | ||
| 693 | * 0.125 degree resolution) and range (0x08, extend range | ||
| 694 | * to -64 degree) mode for the remote temperature sensor. | ||
| 695 | */ | ||
| 696 | if (data->kind == max6680) { | ||
| 697 | config |= 0x18; | ||
| 698 | } | ||
| 699 | |||
| 700 | config &= 0xBF; /* run */ | ||
| 701 | if (config != config_orig) /* Only write if changed */ | ||
| 702 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); | ||
| 663 | } | 703 | } |
| 664 | 704 | ||
| 665 | static int lm90_detach_client(struct i2c_client *client) | 705 | static int lm90_detach_client(struct i2c_client *client) |
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c new file mode 100644 index 000000000000..23edf4fe4221 --- /dev/null +++ b/drivers/hwmon/lm93.c | |||
| @@ -0,0 +1,2655 @@ | |||
| 1 | /* | ||
| 2 | lm93.c - Part of lm_sensors, Linux kernel modules for hardware monitoring | ||
| 3 | |||
| 4 | Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com> | ||
| 5 | Copyright (c) 2004 Utilitek Systems, Inc. | ||
| 6 | |||
| 7 | derived in part from lm78.c: | ||
| 8 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> | ||
| 9 | |||
| 10 | derived in part from lm85.c: | ||
| 11 | Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> | ||
| 12 | Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> | ||
| 13 | |||
| 14 | derived in part from w83l785ts.c: | ||
| 15 | Copyright (c) 2003-2004 Jean Delvare <khali@linux-fr.org> | ||
| 16 | |||
| 17 | Ported to Linux 2.6 by Eric J. Bowersox <ericb@aspsys.com> | ||
| 18 | Copyright (c) 2005 Aspen Systems, Inc. | ||
| 19 | |||
| 20 | Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org> | ||
| 21 | Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab | ||
| 22 | |||
| 23 | Modified for mainline integration by Hans J. Koch <hjk@linutronix.de> | ||
| 24 | Copyright (c) 2007 Hans J. Koch, Linutronix GmbH | ||
| 25 | |||
| 26 | This program is free software; you can redistribute it and/or modify | ||
| 27 | it under the terms of the GNU General Public License as published by | ||
| 28 | the Free Software Foundation; either version 2 of the License, or | ||
| 29 | (at your option) any later version. | ||
| 30 | |||
| 31 | This program is distributed in the hope that it will be useful, | ||
| 32 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 33 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 34 | GNU General Public License for more details. | ||
| 35 | |||
| 36 | You should have received a copy of the GNU General Public License | ||
| 37 | along with this program; if not, write to the Free Software | ||
| 38 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 39 | */ | ||
| 40 | |||
| 41 | #include <linux/module.h> | ||
| 42 | #include <linux/init.h> | ||
| 43 | #include <linux/slab.h> | ||
| 44 | #include <linux/i2c.h> | ||
| 45 | #include <linux/hwmon.h> | ||
| 46 | #include <linux/hwmon-sysfs.h> | ||
| 47 | #include <linux/hwmon-vid.h> | ||
| 48 | #include <linux/err.h> | ||
| 49 | #include <linux/delay.h> | ||
| 50 | |||
| 51 | /* LM93 REGISTER ADDRESSES */ | ||
| 52 | |||
| 53 | /* miscellaneous */ | ||
| 54 | #define LM93_REG_MFR_ID 0x3e | ||
| 55 | #define LM93_REG_VER 0x3f | ||
| 56 | #define LM93_REG_STATUS_CONTROL 0xe2 | ||
| 57 | #define LM93_REG_CONFIG 0xe3 | ||
| 58 | #define LM93_REG_SLEEP_CONTROL 0xe4 | ||
| 59 | |||
| 60 | /* alarm values start here */ | ||
| 61 | #define LM93_REG_HOST_ERROR_1 0x48 | ||
| 62 | |||
| 63 | /* voltage inputs: in1-in16 (nr => 0-15) */ | ||
| 64 | #define LM93_REG_IN(nr) (0x56 + (nr)) | ||
| 65 | #define LM93_REG_IN_MIN(nr) (0x90 + (nr) * 2) | ||
| 66 | #define LM93_REG_IN_MAX(nr) (0x91 + (nr) * 2) | ||
| 67 | |||
| 68 | /* temperature inputs: temp1-temp4 (nr => 0-3) */ | ||
| 69 | #define LM93_REG_TEMP(nr) (0x50 + (nr)) | ||
| 70 | #define LM93_REG_TEMP_MIN(nr) (0x78 + (nr) * 2) | ||
| 71 | #define LM93_REG_TEMP_MAX(nr) (0x79 + (nr) * 2) | ||
| 72 | |||
| 73 | /* temp[1-4]_auto_boost (nr => 0-3) */ | ||
| 74 | #define LM93_REG_BOOST(nr) (0x80 + (nr)) | ||
| 75 | |||
| 76 | /* #PROCHOT inputs: prochot1-prochot2 (nr => 0-1) */ | ||
| 77 | #define LM93_REG_PROCHOT_CUR(nr) (0x67 + (nr) * 2) | ||
| 78 | #define LM93_REG_PROCHOT_AVG(nr) (0x68 + (nr) * 2) | ||
| 79 | #define LM93_REG_PROCHOT_MAX(nr) (0xb0 + (nr)) | ||
| 80 | |||
| 81 | /* fan tach inputs: fan1-fan4 (nr => 0-3) */ | ||
| 82 | #define LM93_REG_FAN(nr) (0x6e + (nr) * 2) | ||
| 83 | #define LM93_REG_FAN_MIN(nr) (0xb4 + (nr) * 2) | ||
| 84 | |||
| 85 | /* pwm outputs: pwm1-pwm2 (nr => 0-1, reg => 0-3) */ | ||
| 86 | #define LM93_REG_PWM_CTL(nr,reg) (0xc8 + (reg) + (nr) * 4) | ||
| 87 | #define LM93_PWM_CTL1 0x0 | ||
| 88 | #define LM93_PWM_CTL2 0x1 | ||
| 89 | #define LM93_PWM_CTL3 0x2 | ||
| 90 | #define LM93_PWM_CTL4 0x3 | ||
| 91 | |||
| 92 | /* GPIO input state */ | ||
| 93 | #define LM93_REG_GPI 0x6b | ||
| 94 | |||
| 95 | /* vid inputs: vid1-vid2 (nr => 0-1) */ | ||
| 96 | #define LM93_REG_VID(nr) (0x6c + (nr)) | ||
| 97 | |||
| 98 | /* vccp1 & vccp2: VID relative inputs (nr => 0-1) */ | ||
| 99 | #define LM93_REG_VCCP_LIMIT_OFF(nr) (0xb2 + (nr)) | ||
| 100 | |||
| 101 | /* temp[1-4]_auto_boost_hyst */ | ||
| 102 | #define LM93_REG_BOOST_HYST_12 0xc0 | ||
| 103 | #define LM93_REG_BOOST_HYST_34 0xc1 | ||
| 104 | #define LM93_REG_BOOST_HYST(nr) (0xc0 + (nr)/2) | ||
| 105 | |||
| 106 | /* temp[1-4]_auto_pwm_[min|hyst] */ | ||
| 107 | #define LM93_REG_PWM_MIN_HYST_12 0xc3 | ||
| 108 | #define LM93_REG_PWM_MIN_HYST_34 0xc4 | ||
| 109 | #define LM93_REG_PWM_MIN_HYST(nr) (0xc3 + (nr)/2) | ||
| 110 | |||
| 111 | /* prochot_override & prochot_interval */ | ||
| 112 | #define LM93_REG_PROCHOT_OVERRIDE 0xc6 | ||
| 113 | #define LM93_REG_PROCHOT_INTERVAL 0xc7 | ||
| 114 | |||
| 115 | /* temp[1-4]_auto_base (nr => 0-3) */ | ||
| 116 | #define LM93_REG_TEMP_BASE(nr) (0xd0 + (nr)) | ||
| 117 | |||
| 118 | /* temp[1-4]_auto_offsets (step => 0-11) */ | ||
| 119 | #define LM93_REG_TEMP_OFFSET(step) (0xd4 + (step)) | ||
| 120 | |||
| 121 | /* #PROCHOT & #VRDHOT PWM ramp control */ | ||
| 122 | #define LM93_REG_PWM_RAMP_CTL 0xbf | ||
| 123 | |||
| 124 | /* miscellaneous */ | ||
| 125 | #define LM93_REG_SFC1 0xbc | ||
| 126 | #define LM93_REG_SFC2 0xbd | ||
| 127 | #define LM93_REG_GPI_VID_CTL 0xbe | ||
| 128 | #define LM93_REG_SF_TACH_TO_PWM 0xe0 | ||
| 129 | |||
| 130 | /* error masks */ | ||
| 131 | #define LM93_REG_GPI_ERR_MASK 0xec | ||
| 132 | #define LM93_REG_MISC_ERR_MASK 0xed | ||
| 133 | |||
| 134 | /* LM93 REGISTER VALUES */ | ||
| 135 | #define LM93_MFR_ID 0x73 | ||
| 136 | #define LM93_MFR_ID_PROTOTYPE 0x72 | ||
| 137 | |||
| 138 | /* SMBus capabilities */ | ||
| 139 | #define LM93_SMBUS_FUNC_FULL (I2C_FUNC_SMBUS_BYTE_DATA | \ | ||
| 140 | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA) | ||
| 141 | #define LM93_SMBUS_FUNC_MIN (I2C_FUNC_SMBUS_BYTE_DATA | \ | ||
| 142 | I2C_FUNC_SMBUS_WORD_DATA) | ||
| 143 | |||
| 144 | /* Addresses to scan */ | ||
| 145 | static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; | ||
| 146 | |||
| 147 | /* Insmod parameters */ | ||
| 148 | I2C_CLIENT_INSMOD_1(lm93); | ||
| 149 | |||
| 150 | static int disable_block; | ||
| 151 | module_param(disable_block, bool, 0); | ||
| 152 | MODULE_PARM_DESC(disable_block, | ||
| 153 | "Set to non-zero to disable SMBus block data transactions."); | ||
| 154 | |||
| 155 | static int init; | ||
| 156 | module_param(init, bool, 0); | ||
| 157 | MODULE_PARM_DESC(init, "Set to non-zero to force chip initialization."); | ||
| 158 | |||
| 159 | static int vccp_limit_type[2] = {0,0}; | ||
| 160 | module_param_array(vccp_limit_type, int, NULL, 0); | ||
| 161 | MODULE_PARM_DESC(vccp_limit_type, "Configures in7 and in8 limit modes."); | ||
| 162 | |||
| 163 | static int vid_agtl; | ||
| 164 | module_param(vid_agtl, int, 0); | ||
| 165 | MODULE_PARM_DESC(vid_agtl, "Configures VID pin input thresholds."); | ||
| 166 | |||
| 167 | /* Driver data */ | ||
| 168 | static struct i2c_driver lm93_driver; | ||
| 169 | |||
| 170 | /* LM93 BLOCK READ COMMANDS */ | ||
| 171 | static const struct { u8 cmd; u8 len; } lm93_block_read_cmds[12] = { | ||
| 172 | { 0xf2, 8 }, | ||
| 173 | { 0xf3, 8 }, | ||
| 174 | { 0xf4, 6 }, | ||
| 175 | { 0xf5, 16 }, | ||
| 176 | { 0xf6, 4 }, | ||
| 177 | { 0xf7, 8 }, | ||
| 178 | { 0xf8, 12 }, | ||
| 179 | { 0xf9, 32 }, | ||
| 180 | { 0xfa, 8 }, | ||
| 181 | { 0xfb, 8 }, | ||
| 182 | { 0xfc, 16 }, | ||
| 183 | { 0xfd, 9 }, | ||
| 184 | }; | ||
| 185 | |||
| 186 | /* ALARMS: SYSCTL format described further below | ||
| 187 | REG: 64 bits in 8 registers, as immediately below */ | ||
| 188 | struct block1_t { | ||
| 189 | u8 host_status_1; | ||
| 190 | u8 host_status_2; | ||
| 191 | u8 host_status_3; | ||
| 192 | u8 host_status_4; | ||
| 193 | u8 p1_prochot_status; | ||
| 194 | u8 p2_prochot_status; | ||
| 195 | u8 gpi_status; | ||
| 196 | u8 fan_status; | ||
| 197 | }; | ||
| 198 | |||
| 199 | /* | ||
| 200 | * Client-specific data | ||
| 201 | */ | ||
| 202 | struct lm93_data { | ||
| 203 | struct i2c_client client; | ||
| 204 | struct class_device *class_dev; | ||
| 205 | |||
| 206 | struct mutex update_lock; | ||
| 207 | unsigned long last_updated; /* In jiffies */ | ||
| 208 | |||
| 209 | /* client update function */ | ||
| 210 | void (*update)(struct lm93_data *, struct i2c_client *); | ||
| 211 | |||
| 212 | char valid; /* !=0 if following fields are valid */ | ||
| 213 | |||
| 214 | /* register values, arranged by block read groups */ | ||
| 215 | struct block1_t block1; | ||
| 216 | |||
| 217 | /* temp1 - temp4: unfiltered readings | ||
| 218 | temp1 - temp2: filtered readings */ | ||
| 219 | u8 block2[6]; | ||
| 220 | |||
| 221 | /* vin1 - vin16: readings */ | ||
| 222 | u8 block3[16]; | ||
| 223 | |||
| 224 | /* prochot1 - prochot2: readings */ | ||
| 225 | struct { | ||
| 226 | u8 cur; | ||
| 227 | u8 avg; | ||
| 228 | } block4[2]; | ||
| 229 | |||
| 230 | /* fan counts 1-4 => 14-bits, LE, *left* justified */ | ||
| 231 | u16 block5[4]; | ||
| 232 | |||
| 233 | /* block6 has a lot of data we don't need */ | ||
| 234 | struct { | ||
| 235 | u8 min; | ||
| 236 | u8 max; | ||
| 237 | } temp_lim[3]; | ||
| 238 | |||
| 239 | /* vin1 - vin16: low and high limits */ | ||
| 240 | struct { | ||
| 241 | u8 min; | ||
| 242 | u8 max; | ||
| 243 | } block7[16]; | ||
| 244 | |||
| 245 | /* fan count limits 1-4 => same format as block5 */ | ||
| 246 | u16 block8[4]; | ||
| 247 | |||
| 248 | /* pwm control registers (2 pwms, 4 regs) */ | ||
| 249 | u8 block9[2][4]; | ||
| 250 | |||
| 251 | /* auto/pwm base temp and offset temp registers */ | ||
| 252 | struct { | ||
| 253 | u8 base[4]; | ||
| 254 | u8 offset[12]; | ||
| 255 | } block10; | ||
| 256 | |||
| 257 | /* master config register */ | ||
| 258 | u8 config; | ||
| 259 | |||
| 260 | /* VID1 & VID2 => register format, 6-bits, right justified */ | ||
| 261 | u8 vid[2]; | ||
| 262 | |||
| 263 | /* prochot1 - prochot2: limits */ | ||
| 264 | u8 prochot_max[2]; | ||
| 265 | |||
| 266 | /* vccp1 & vccp2 (in7 & in8): VID relative limits (register format) */ | ||
| 267 | u8 vccp_limits[2]; | ||
| 268 | |||
| 269 | /* GPIO input state (register format, i.e. inverted) */ | ||
| 270 | u8 gpi; | ||
| 271 | |||
| 272 | /* #PROCHOT override (register format) */ | ||
| 273 | u8 prochot_override; | ||
| 274 | |||
| 275 | /* #PROCHOT intervals (register format) */ | ||
| 276 | u8 prochot_interval; | ||
| 277 | |||
| 278 | /* Fan Boost Temperatures (register format) */ | ||
| 279 | u8 boost[4]; | ||
| 280 | |||
| 281 | /* Fan Boost Hysteresis (register format) */ | ||
| 282 | u8 boost_hyst[2]; | ||
| 283 | |||
| 284 | /* Temperature Zone Min. PWM & Hysteresis (register format) */ | ||
| 285 | u8 auto_pwm_min_hyst[2]; | ||
| 286 | |||
| 287 | /* #PROCHOT & #VRDHOT PWM Ramp Control */ | ||
| 288 | u8 pwm_ramp_ctl; | ||
| 289 | |||
| 290 | /* miscellaneous setup regs */ | ||
| 291 | u8 sfc1; | ||
| 292 | u8 sfc2; | ||
| 293 | u8 sf_tach_to_pwm; | ||
| 294 | |||
| 295 | /* The two PWM CTL2 registers can read something other than what was | ||
| 296 | last written for the OVR_DC field (duty cycle override). So, we | ||
| 297 | save the user-commanded value here. */ | ||
| 298 | u8 pwm_override[2]; | ||
| 299 | }; | ||
| 300 | |||
| 301 | /* VID: mV | ||
| 302 | REG: 6-bits, right justified, *always* using Intel VRM/VRD 10 */ | ||
| 303 | static int LM93_VID_FROM_REG(u8 reg) | ||
| 304 | { | ||
| 305 | return vid_from_reg((reg & 0x3f), 100); | ||
| 306 | } | ||
| 307 | |||
| 308 | /* min, max, and nominal register values, per channel (u8) */ | ||
| 309 | static const u8 lm93_vin_reg_min[16] = { | ||
| 310 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 311 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, | ||
| 312 | }; | ||
| 313 | static const u8 lm93_vin_reg_max[16] = { | ||
| 314 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 315 | 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd1, | ||
| 316 | }; | ||
| 317 | /* Values from the datasheet. They're here for documentation only. | ||
| 318 | static const u8 lm93_vin_reg_nom[16] = { | ||
| 319 | 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, | ||
| 320 | 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0xc0, | ||
| 321 | }; | ||
| 322 | */ | ||
| 323 | |||
| 324 | /* min, max, and nominal voltage readings, per channel (mV)*/ | ||
| 325 | static const unsigned long lm93_vin_val_min[16] = { | ||
| 326 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 327 | 0, 0, 0, 0, 0, 0, 0, 3000, | ||
| 328 | }; | ||
| 329 | |||
| 330 | static const unsigned long lm93_vin_val_max[16] = { | ||
| 331 | 1236, 1236, 1236, 1600, 2000, 2000, 1600, 1600, | ||
| 332 | 4400, 6500, 3333, 2625, 1312, 1312, 1236, 3600, | ||
| 333 | }; | ||
| 334 | /* Values from the datasheet. They're here for documentation only. | ||
| 335 | static const unsigned long lm93_vin_val_nom[16] = { | ||
| 336 | 927, 927, 927, 1200, 1500, 1500, 1200, 1200, | ||
| 337 | 3300, 5000, 2500, 1969, 984, 984, 309, 3300, | ||
| 338 | }; | ||
| 339 | */ | ||
| 340 | |||
| 341 | static unsigned LM93_IN_FROM_REG(int nr, u8 reg) | ||
| 342 | { | ||
| 343 | const long uV_max = lm93_vin_val_max[nr] * 1000; | ||
| 344 | const long uV_min = lm93_vin_val_min[nr] * 1000; | ||
| 345 | |||
| 346 | const long slope = (uV_max - uV_min) / | ||
| 347 | (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); | ||
| 348 | const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; | ||
| 349 | |||
| 350 | return (slope * reg + intercept + 500) / 1000; | ||
| 351 | } | ||
| 352 | |||
| 353 | /* IN: mV, limits determined by channel nr | ||
| 354 | REG: scaling determined by channel nr */ | ||
| 355 | static u8 LM93_IN_TO_REG(int nr, unsigned val) | ||
| 356 | { | ||
| 357 | /* range limit */ | ||
| 358 | const long mV = SENSORS_LIMIT(val, | ||
| 359 | lm93_vin_val_min[nr], lm93_vin_val_max[nr]); | ||
| 360 | |||
| 361 | /* try not to lose too much precision here */ | ||
| 362 | const long uV = mV * 1000; | ||
| 363 | const long uV_max = lm93_vin_val_max[nr] * 1000; | ||
| 364 | const long uV_min = lm93_vin_val_min[nr] * 1000; | ||
| 365 | |||
| 366 | /* convert */ | ||
| 367 | const long slope = (uV_max - uV_min) / | ||
| 368 | (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); | ||
| 369 | const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; | ||
| 370 | |||
| 371 | u8 result = ((uV - intercept + (slope/2)) / slope); | ||
| 372 | result = SENSORS_LIMIT(result, | ||
| 373 | lm93_vin_reg_min[nr], lm93_vin_reg_max[nr]); | ||
| 374 | return result; | ||
| 375 | } | ||
| 376 | |||
| 377 | /* vid in mV, upper == 0 indicates low limit, otherwise upper limit */ | ||
| 378 | static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) | ||
| 379 | { | ||
| 380 | const long uV_offset = upper ? (((reg >> 4 & 0x0f) + 1) * 12500) : | ||
| 381 | (((reg >> 0 & 0x0f) + 1) * -25000); | ||
| 382 | const long uV_vid = vid * 1000; | ||
| 383 | return (uV_vid + uV_offset + 5000) / 10000; | ||
| 384 | } | ||
| 385 | |||
| 386 | #define LM93_IN_MIN_FROM_REG(reg,vid) LM93_IN_REL_FROM_REG(reg,0,vid) | ||
| 387 | #define LM93_IN_MAX_FROM_REG(reg,vid) LM93_IN_REL_FROM_REG(reg,1,vid) | ||
| 388 | |||
| 389 | /* vid in mV , upper == 0 indicates low limit, otherwise upper limit | ||
| 390 | upper also determines which nibble of the register is returned | ||
| 391 | (the other nibble will be 0x0) */ | ||
| 392 | static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid) | ||
| 393 | { | ||
| 394 | long uV_offset = vid * 1000 - val * 10000; | ||
| 395 | if (upper) { | ||
| 396 | uV_offset = SENSORS_LIMIT(uV_offset, 12500, 200000); | ||
| 397 | return (u8)((uV_offset / 12500 - 1) << 4); | ||
| 398 | } else { | ||
| 399 | uV_offset = SENSORS_LIMIT(uV_offset, -400000, -25000); | ||
| 400 | return (u8)((uV_offset / -25000 - 1) << 0); | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | /* TEMP: 1/1000 degrees C (-128C to +127C) | ||
| 405 | REG: 1C/bit, two's complement */ | ||
| 406 | static int LM93_TEMP_FROM_REG(u8 reg) | ||
| 407 | { | ||
| 408 | return (s8)reg * 1000; | ||
| 409 | } | ||
| 410 | |||
| 411 | #define LM93_TEMP_MIN (-128000) | ||
| 412 | #define LM93_TEMP_MAX ( 127000) | ||
| 413 | |||
| 414 | /* TEMP: 1/1000 degrees C (-128C to +127C) | ||
| 415 | REG: 1C/bit, two's complement */ | ||
| 416 | static u8 LM93_TEMP_TO_REG(int temp) | ||
| 417 | { | ||
| 418 | int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX); | ||
| 419 | ntemp += (ntemp<0 ? -500 : 500); | ||
| 420 | return (u8)(ntemp / 1000); | ||
| 421 | } | ||
| 422 | |||
| 423 | /* Determine 4-bit temperature offset resolution */ | ||
| 424 | static int LM93_TEMP_OFFSET_MODE_FROM_REG(u8 sfc2, int nr) | ||
| 425 | { | ||
| 426 | /* mode: 0 => 1C/bit, nonzero => 0.5C/bit */ | ||
| 427 | return sfc2 & (nr < 2 ? 0x10 : 0x20); | ||
| 428 | } | ||
| 429 | |||
| 430 | /* This function is common to all 4-bit temperature offsets | ||
| 431 | reg is 4 bits right justified | ||
| 432 | mode 0 => 1C/bit, mode !0 => 0.5C/bit */ | ||
| 433 | static int LM93_TEMP_OFFSET_FROM_REG(u8 reg, int mode) | ||
| 434 | { | ||
| 435 | return (reg & 0x0f) * (mode ? 5 : 10); | ||
| 436 | } | ||
| 437 | |||
| 438 | #define LM93_TEMP_OFFSET_MIN ( 0) | ||
| 439 | #define LM93_TEMP_OFFSET_MAX0 (150) | ||
| 440 | #define LM93_TEMP_OFFSET_MAX1 ( 75) | ||
| 441 | |||
| 442 | /* This function is common to all 4-bit temperature offsets | ||
| 443 | returns 4 bits right justified | ||
| 444 | mode 0 => 1C/bit, mode !0 => 0.5C/bit */ | ||
| 445 | static u8 LM93_TEMP_OFFSET_TO_REG(int off, int mode) | ||
| 446 | { | ||
| 447 | int factor = mode ? 5 : 10; | ||
| 448 | |||
| 449 | off = SENSORS_LIMIT(off, LM93_TEMP_OFFSET_MIN, | ||
| 450 | mode ? LM93_TEMP_OFFSET_MAX1 : LM93_TEMP_OFFSET_MAX0); | ||
| 451 | return (u8)((off + factor/2) / factor); | ||
| 452 | } | ||
| 453 | |||
| 454 | /* 0 <= nr <= 3 */ | ||
| 455 | static int LM93_TEMP_AUTO_OFFSET_FROM_REG(u8 reg, int nr, int mode) | ||
| 456 | { | ||
| 457 | /* temp1-temp2 (nr=0,1) use lower nibble */ | ||
| 458 | if (nr < 2) | ||
| 459 | return LM93_TEMP_OFFSET_FROM_REG(reg & 0x0f, mode); | ||
| 460 | |||
| 461 | /* temp3-temp4 (nr=2,3) use upper nibble */ | ||
| 462 | else | ||
| 463 | return LM93_TEMP_OFFSET_FROM_REG(reg >> 4 & 0x0f, mode); | ||
| 464 | } | ||
| 465 | |||
| 466 | /* TEMP: 1/10 degrees C (0C to +15C (mode 0) or +7.5C (mode non-zero)) | ||
| 467 | REG: 1.0C/bit (mode 0) or 0.5C/bit (mode non-zero) | ||
| 468 | 0 <= nr <= 3 */ | ||
| 469 | static u8 LM93_TEMP_AUTO_OFFSET_TO_REG(u8 old, int off, int nr, int mode) | ||
| 470 | { | ||
| 471 | u8 new = LM93_TEMP_OFFSET_TO_REG(off, mode); | ||
| 472 | |||
| 473 | /* temp1-temp2 (nr=0,1) use lower nibble */ | ||
| 474 | if (nr < 2) | ||
| 475 | return (old & 0xf0) | (new & 0x0f); | ||
| 476 | |||
| 477 | /* temp3-temp4 (nr=2,3) use upper nibble */ | ||
| 478 | else | ||
| 479 | return (new << 4 & 0xf0) | (old & 0x0f); | ||
| 480 | } | ||
| 481 | |||
| 482 | static int LM93_AUTO_BOOST_HYST_FROM_REGS(struct lm93_data *data, int nr, | ||
| 483 | int mode) | ||
| 484 | { | ||
| 485 | u8 reg; | ||
| 486 | |||
| 487 | switch (nr) { | ||
| 488 | case 0: | ||
| 489 | reg = data->boost_hyst[0] & 0x0f; | ||
| 490 | break; | ||
| 491 | case 1: | ||
| 492 | reg = data->boost_hyst[0] >> 4 & 0x0f; | ||
| 493 | break; | ||
| 494 | case 2: | ||
| 495 | reg = data->boost_hyst[1] & 0x0f; | ||
| 496 | break; | ||
| 497 | case 3: | ||
| 498 | default: | ||
| 499 | reg = data->boost_hyst[1] >> 4 & 0x0f; | ||
| 500 | break; | ||
| 501 | } | ||
| 502 | |||
| 503 | return LM93_TEMP_FROM_REG(data->boost[nr]) - | ||
| 504 | LM93_TEMP_OFFSET_FROM_REG(reg, mode); | ||
| 505 | } | ||
| 506 | |||
| 507 | static u8 LM93_AUTO_BOOST_HYST_TO_REG(struct lm93_data *data, long hyst, | ||
| 508 | int nr, int mode) | ||
| 509 | { | ||
| 510 | u8 reg = LM93_TEMP_OFFSET_TO_REG( | ||
| 511 | (LM93_TEMP_FROM_REG(data->boost[nr]) - hyst), mode); | ||
| 512 | |||
| 513 | switch (nr) { | ||
| 514 | case 0: | ||
| 515 | reg = (data->boost_hyst[0] & 0xf0) | (reg & 0x0f); | ||
| 516 | break; | ||
| 517 | case 1: | ||
| 518 | reg = (reg << 4 & 0xf0) | (data->boost_hyst[0] & 0x0f); | ||
| 519 | break; | ||
| 520 | case 2: | ||
| 521 | reg = (data->boost_hyst[1] & 0xf0) | (reg & 0x0f); | ||
| 522 | break; | ||
| 523 | case 3: | ||
| 524 | default: | ||
| 525 | reg = (reg << 4 & 0xf0) | (data->boost_hyst[1] & 0x0f); | ||
| 526 | break; | ||
| 527 | } | ||
| 528 | |||
| 529 | return reg; | ||
| 530 | } | ||
| 531 | |||
| 532 | /* PWM: 0-255 per sensors documentation | ||
| 533 | REG: 0-13 as mapped below... right justified */ | ||
| 534 | typedef enum { LM93_PWM_MAP_HI_FREQ, LM93_PWM_MAP_LO_FREQ } pwm_freq_t; | ||
| 535 | static int lm93_pwm_map[2][16] = { | ||
| 536 | { | ||
| 537 | 0x00, /* 0.00% */ 0x40, /* 25.00% */ | ||
| 538 | 0x50, /* 31.25% */ 0x60, /* 37.50% */ | ||
| 539 | 0x70, /* 43.75% */ 0x80, /* 50.00% */ | ||
| 540 | 0x90, /* 56.25% */ 0xa0, /* 62.50% */ | ||
| 541 | 0xb0, /* 68.75% */ 0xc0, /* 75.00% */ | ||
| 542 | 0xd0, /* 81.25% */ 0xe0, /* 87.50% */ | ||
| 543 | 0xf0, /* 93.75% */ 0xff, /* 100.00% */ | ||
| 544 | 0xff, 0xff, /* 14, 15 are reserved and should never occur */ | ||
| 545 | }, | ||
| 546 | { | ||
| 547 | 0x00, /* 0.00% */ 0x40, /* 25.00% */ | ||
| 548 | 0x49, /* 28.57% */ 0x52, /* 32.14% */ | ||
| 549 | 0x5b, /* 35.71% */ 0x64, /* 39.29% */ | ||
| 550 | 0x6d, /* 42.86% */ 0x76, /* 46.43% */ | ||
| 551 | 0x80, /* 50.00% */ 0x89, /* 53.57% */ | ||
| 552 | 0x92, /* 57.14% */ 0xb6, /* 71.43% */ | ||
| 553 | 0xdb, /* 85.71% */ 0xff, /* 100.00% */ | ||
| 554 | 0xff, 0xff, /* 14, 15 are reserved and should never occur */ | ||
| 555 | }, | ||
| 556 | }; | ||
| 557 | |||
| 558 | static int LM93_PWM_FROM_REG(u8 reg, pwm_freq_t freq) | ||
| 559 | { | ||
| 560 | return lm93_pwm_map[freq][reg & 0x0f]; | ||
| 561 | } | ||
| 562 | |||
| 563 | /* round up to nearest match */ | ||
| 564 | static u8 LM93_PWM_TO_REG(int pwm, pwm_freq_t freq) | ||
| 565 | { | ||
| 566 | int i; | ||
| 567 | for (i = 0; i < 13; i++) | ||
| 568 | if (pwm <= lm93_pwm_map[freq][i]) | ||
| 569 | break; | ||
| 570 | |||
| 571 | /* can fall through with i==13 */ | ||
| 572 | return (u8)i; | ||
| 573 | } | ||
| 574 | |||
| 575 | static int LM93_FAN_FROM_REG(u16 regs) | ||
| 576 | { | ||
| 577 | const u16 count = le16_to_cpu(regs) >> 2; | ||
| 578 | return count==0 ? -1 : count==0x3fff ? 0: 1350000 / count; | ||
| 579 | } | ||
| 580 | |||
| 581 | /* | ||
| 582 | * RPM: (82.5 to 1350000) | ||
| 583 | * REG: 14-bits, LE, *left* justified | ||
| 584 | */ | ||
| 585 | static u16 LM93_FAN_TO_REG(long rpm) | ||
| 586 | { | ||
| 587 | u16 count, regs; | ||
| 588 | |||
| 589 | if (rpm == 0) { | ||
| 590 | count = 0x3fff; | ||
| 591 | } else { | ||
| 592 | rpm = SENSORS_LIMIT(rpm, 1, 1000000); | ||
| 593 | count = SENSORS_LIMIT((1350000 + rpm) / rpm, 1, 0x3ffe); | ||
| 594 | } | ||
| 595 | |||
| 596 | regs = count << 2; | ||
| 597 | return cpu_to_le16(regs); | ||
| 598 | } | ||
| 599 | |||
| 600 | /* PWM FREQ: HZ | ||
| 601 | REG: 0-7 as mapped below */ | ||
| 602 | static int lm93_pwm_freq_map[8] = { | ||
| 603 | 22500, 96, 84, 72, 60, 48, 36, 12 | ||
| 604 | }; | ||
| 605 | |||
| 606 | static int LM93_PWM_FREQ_FROM_REG(u8 reg) | ||
| 607 | { | ||
| 608 | return lm93_pwm_freq_map[reg & 0x07]; | ||
| 609 | } | ||
| 610 | |||
| 611 | /* round up to nearest match */ | ||
| 612 | static u8 LM93_PWM_FREQ_TO_REG(int freq) | ||
| 613 | { | ||
| 614 | int i; | ||
| 615 | for (i = 7; i > 0; i--) | ||
| 616 | if (freq <= lm93_pwm_freq_map[i]) | ||
| 617 | break; | ||
| 618 | |||
| 619 | /* can fall through with i==0 */ | ||
| 620 | return (u8)i; | ||
| 621 | } | ||
| 622 | |||
| 623 | /* TIME: 1/100 seconds | ||
| 624 | * REG: 0-7 as mapped below */ | ||
| 625 | static int lm93_spinup_time_map[8] = { | ||
| 626 | 0, 10, 25, 40, 70, 100, 200, 400, | ||
| 627 | }; | ||
| 628 | |||
| 629 | static int LM93_SPINUP_TIME_FROM_REG(u8 reg) | ||
| 630 | { | ||
| 631 | return lm93_spinup_time_map[reg >> 5 & 0x07]; | ||
| 632 | } | ||
| 633 | |||
| 634 | /* round up to nearest match */ | ||
| 635 | static u8 LM93_SPINUP_TIME_TO_REG(int time) | ||
| 636 | { | ||
| 637 | int i; | ||
| 638 | for (i = 0; i < 7; i++) | ||
| 639 | if (time <= lm93_spinup_time_map[i]) | ||
| 640 | break; | ||
| 641 | |||
| 642 | /* can fall through with i==8 */ | ||
| 643 | return (u8)i; | ||
| 644 | } | ||
| 645 | |||
| 646 | #define LM93_RAMP_MIN 0 | ||
| 647 | #define LM93_RAMP_MAX 75 | ||
| 648 | |||
| 649 | static int LM93_RAMP_FROM_REG(u8 reg) | ||
| 650 | { | ||
| 651 | return (reg & 0x0f) * 5; | ||
| 652 | } | ||
| 653 | |||
| 654 | /* RAMP: 1/100 seconds | ||
| 655 | REG: 50mS/bit 4-bits right justified */ | ||
| 656 | static u8 LM93_RAMP_TO_REG(int ramp) | ||
| 657 | { | ||
| 658 | ramp = SENSORS_LIMIT(ramp, LM93_RAMP_MIN, LM93_RAMP_MAX); | ||
| 659 | return (u8)((ramp + 2) / 5); | ||
| 660 | } | ||
| 661 | |||
| 662 | /* PROCHOT: 0-255, 0 => 0%, 255 => > 96.6% | ||
| 663 | * REG: (same) */ | ||
| 664 | static u8 LM93_PROCHOT_TO_REG(long prochot) | ||
| 665 | { | ||
| 666 | prochot = SENSORS_LIMIT(prochot, 0, 255); | ||
| 667 | return (u8)prochot; | ||
| 668 | } | ||
| 669 | |||
| 670 | /* PROCHOT-INTERVAL: 73 - 37200 (1/100 seconds) | ||
| 671 | * REG: 0-9 as mapped below */ | ||
| 672 | static int lm93_interval_map[10] = { | ||
| 673 | 73, 146, 290, 580, 1170, 2330, 4660, 9320, 18600, 37200, | ||
| 674 | }; | ||
| 675 | |||
| 676 | static int LM93_INTERVAL_FROM_REG(u8 reg) | ||
| 677 | { | ||
| 678 | return lm93_interval_map[reg & 0x0f]; | ||
| 679 | } | ||
| 680 | |||
| 681 | /* round up to nearest match */ | ||
| 682 | static u8 LM93_INTERVAL_TO_REG(long interval) | ||
| 683 | { | ||
| 684 | int i; | ||
| 685 | for (i = 0; i < 9; i++) | ||
| 686 | if (interval <= lm93_interval_map[i]) | ||
| 687 | break; | ||
| 688 | |||
| 689 | /* can fall through with i==9 */ | ||
| 690 | return (u8)i; | ||
| 691 | } | ||
| 692 | |||
| 693 | /* GPIO: 0-255, GPIO0 is LSB | ||
| 694 | * REG: inverted */ | ||
| 695 | static unsigned LM93_GPI_FROM_REG(u8 reg) | ||
| 696 | { | ||
| 697 | return ~reg & 0xff; | ||
| 698 | } | ||
| 699 | |||
| 700 | /* alarm bitmask definitions | ||
| 701 | The LM93 has nearly 64 bits of error status... I've pared that down to | ||
| 702 | what I think is a useful subset in order to fit it into 32 bits. | ||
| 703 | |||
| 704 | Especially note that the #VRD_HOT alarms are missing because we provide | ||
| 705 | that information as values in another sysfs file. | ||
| 706 | |||
| 707 | If libsensors is extended to support 64 bit values, this could be revisited. | ||
| 708 | */ | ||
| 709 | #define LM93_ALARM_IN1 0x00000001 | ||
| 710 | #define LM93_ALARM_IN2 0x00000002 | ||
| 711 | #define LM93_ALARM_IN3 0x00000004 | ||
| 712 | #define LM93_ALARM_IN4 0x00000008 | ||
| 713 | #define LM93_ALARM_IN5 0x00000010 | ||
| 714 | #define LM93_ALARM_IN6 0x00000020 | ||
| 715 | #define LM93_ALARM_IN7 0x00000040 | ||
| 716 | #define LM93_ALARM_IN8 0x00000080 | ||
| 717 | #define LM93_ALARM_IN9 0x00000100 | ||
| 718 | #define LM93_ALARM_IN10 0x00000200 | ||
| 719 | #define LM93_ALARM_IN11 0x00000400 | ||
| 720 | #define LM93_ALARM_IN12 0x00000800 | ||
| 721 | #define LM93_ALARM_IN13 0x00001000 | ||
| 722 | #define LM93_ALARM_IN14 0x00002000 | ||
| 723 | #define LM93_ALARM_IN15 0x00004000 | ||
| 724 | #define LM93_ALARM_IN16 0x00008000 | ||
| 725 | #define LM93_ALARM_FAN1 0x00010000 | ||
| 726 | #define LM93_ALARM_FAN2 0x00020000 | ||
| 727 | #define LM93_ALARM_FAN3 0x00040000 | ||
| 728 | #define LM93_ALARM_FAN4 0x00080000 | ||
| 729 | #define LM93_ALARM_PH1_ERR 0x00100000 | ||
| 730 | #define LM93_ALARM_PH2_ERR 0x00200000 | ||
| 731 | #define LM93_ALARM_SCSI1_ERR 0x00400000 | ||
| 732 | #define LM93_ALARM_SCSI2_ERR 0x00800000 | ||
| 733 | #define LM93_ALARM_DVDDP1_ERR 0x01000000 | ||
| 734 | #define LM93_ALARM_DVDDP2_ERR 0x02000000 | ||
| 735 | #define LM93_ALARM_D1_ERR 0x04000000 | ||
| 736 | #define LM93_ALARM_D2_ERR 0x08000000 | ||
| 737 | #define LM93_ALARM_TEMP1 0x10000000 | ||
| 738 | #define LM93_ALARM_TEMP2 0x20000000 | ||
| 739 | #define LM93_ALARM_TEMP3 0x40000000 | ||
| 740 | |||
| 741 | static unsigned LM93_ALARMS_FROM_REG(struct block1_t b1) | ||
| 742 | { | ||
| 743 | unsigned result; | ||
| 744 | result = b1.host_status_2 & 0x3f; | ||
| 745 | |||
| 746 | if (vccp_limit_type[0]) | ||
| 747 | result |= (b1.host_status_4 & 0x10) << 2; | ||
| 748 | else | ||
| 749 | result |= b1.host_status_2 & 0x40; | ||
| 750 | |||
| 751 | if (vccp_limit_type[1]) | ||
| 752 | result |= (b1.host_status_4 & 0x20) << 2; | ||
| 753 | else | ||
| 754 | result |= b1.host_status_2 & 0x80; | ||
| 755 | |||
| 756 | result |= b1.host_status_3 << 8; | ||
| 757 | result |= (b1.fan_status & 0x0f) << 16; | ||
| 758 | result |= (b1.p1_prochot_status & 0x80) << 13; | ||
| 759 | result |= (b1.p2_prochot_status & 0x80) << 14; | ||
| 760 | result |= (b1.host_status_4 & 0xfc) << 20; | ||
| 761 | result |= (b1.host_status_1 & 0x07) << 28; | ||
| 762 | return result; | ||
| 763 | } | ||
| 764 | |||
| 765 | #define MAX_RETRIES 5 | ||
| 766 | |||
| 767 | static u8 lm93_read_byte(struct i2c_client *client, u8 reg) | ||
| 768 | { | ||
| 769 | int value, i; | ||
| 770 | |||
| 771 | /* retry in case of read errors */ | ||
| 772 | for (i=1; i<=MAX_RETRIES; i++) { | ||
| 773 | if ((value = i2c_smbus_read_byte_data(client, reg)) >= 0) { | ||
| 774 | return value; | ||
| 775 | } else { | ||
| 776 | dev_warn(&client->dev,"lm93: read byte data failed, " | ||
| 777 | "address 0x%02x.\n", reg); | ||
| 778 | mdelay(i + 3); | ||
| 779 | } | ||
| 780 | |||
| 781 | } | ||
| 782 | |||
| 783 | /* <TODO> what to return in case of error? */ | ||
| 784 | dev_err(&client->dev,"lm93: All read byte retries failed!!\n"); | ||
| 785 | return 0; | ||
| 786 | } | ||
| 787 | |||
| 788 | static int lm93_write_byte(struct i2c_client *client, u8 reg, u8 value) | ||
| 789 | { | ||
| 790 | int result; | ||
| 791 | |||
| 792 | /* <TODO> how to handle write errors? */ | ||
| 793 | result = i2c_smbus_write_byte_data(client, reg, value); | ||
| 794 | |||
| 795 | if (result < 0) | ||
| 796 | dev_warn(&client->dev,"lm93: write byte data failed, " | ||
| 797 | "0x%02x at address 0x%02x.\n", value, reg); | ||
| 798 | |||
| 799 | return result; | ||
| 800 | } | ||
| 801 | |||
| 802 | static u16 lm93_read_word(struct i2c_client *client, u8 reg) | ||
| 803 | { | ||
| 804 | int value, i; | ||
| 805 | |||
| 806 | /* retry in case of read errors */ | ||
| 807 | for (i=1; i<=MAX_RETRIES; i++) { | ||
| 808 | if ((value = i2c_smbus_read_word_data(client, reg)) >= 0) { | ||
| 809 | return value; | ||
| 810 | } else { | ||
| 811 | dev_warn(&client->dev,"lm93: read word data failed, " | ||
| 812 | "address 0x%02x.\n", reg); | ||
| 813 | mdelay(i + 3); | ||
| 814 | } | ||
| 815 | |||
| 816 | } | ||
| 817 | |||
| 818 | /* <TODO> what to return in case of error? */ | ||
| 819 | dev_err(&client->dev,"lm93: All read word retries failed!!\n"); | ||
| 820 | return 0; | ||
| 821 | } | ||
| 822 | |||
| 823 | static int lm93_write_word(struct i2c_client *client, u8 reg, u16 value) | ||
| 824 | { | ||
| 825 | int result; | ||
| 826 | |||
| 827 | /* <TODO> how to handle write errors? */ | ||
| 828 | result = i2c_smbus_write_word_data(client, reg, value); | ||
| 829 | |||
| 830 | if (result < 0) | ||
| 831 | dev_warn(&client->dev,"lm93: write word data failed, " | ||
| 832 | "0x%04x at address 0x%02x.\n", value, reg); | ||
| 833 | |||
| 834 | return result; | ||
| 835 | } | ||
| 836 | |||
| 837 | static u8 lm93_block_buffer[I2C_SMBUS_BLOCK_MAX]; | ||
| 838 | |||
| 839 | /* | ||
| 840 | read block data into values, retry if not expected length | ||
| 841 | fbn => index to lm93_block_read_cmds table | ||
| 842 | (Fixed Block Number - section 14.5.2 of LM93 datasheet) | ||
| 843 | */ | ||
| 844 | static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values) | ||
| 845 | { | ||
| 846 | int i, result=0; | ||
| 847 | |||
| 848 | for (i = 1; i <= MAX_RETRIES; i++) { | ||
| 849 | result = i2c_smbus_read_block_data(client, | ||
| 850 | lm93_block_read_cmds[fbn].cmd, lm93_block_buffer); | ||
| 851 | |||
| 852 | if (result == lm93_block_read_cmds[fbn].len) { | ||
| 853 | break; | ||
| 854 | } else { | ||
| 855 | dev_warn(&client->dev,"lm93: block read data failed, " | ||
| 856 | "command 0x%02x.\n", | ||
| 857 | lm93_block_read_cmds[fbn].cmd); | ||
| 858 | mdelay(i + 3); | ||
| 859 | } | ||
| 860 | } | ||
| 861 | |||
| 862 | if (result == lm93_block_read_cmds[fbn].len) { | ||
| 863 | memcpy(values,lm93_block_buffer,lm93_block_read_cmds[fbn].len); | ||
| 864 | } else { | ||
| 865 | /* <TODO> what to do in case of error? */ | ||
| 866 | } | ||
| 867 | } | ||
| 868 | |||
| 869 | static struct lm93_data *lm93_update_device(struct device *dev) | ||
| 870 | { | ||
| 871 | struct i2c_client *client = to_i2c_client(dev); | ||
| 872 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 873 | const unsigned long interval = HZ + (HZ / 2); | ||
| 874 | |||
| 875 | mutex_lock(&data->update_lock); | ||
| 876 | |||
| 877 | if (time_after(jiffies, data->last_updated + interval) || | ||
| 878 | !data->valid) { | ||
| 879 | |||
| 880 | data->update(data, client); | ||
| 881 | data->last_updated = jiffies; | ||
| 882 | data->valid = 1; | ||
| 883 | } | ||
| 884 | |||
| 885 | mutex_unlock(&data->update_lock); | ||
| 886 | return data; | ||
| 887 | } | ||
| 888 | |||
| 889 | /* update routine for data that has no corresponding SMBus block command */ | ||
| 890 | static void lm93_update_client_common(struct lm93_data *data, | ||
| 891 | struct i2c_client *client) | ||
| 892 | { | ||
| 893 | int i; | ||
| 894 | u8 *ptr; | ||
| 895 | |||
| 896 | /* temp1 - temp4: limits */ | ||
| 897 | for (i = 0; i < 4; i++) { | ||
| 898 | data->temp_lim[i].min = | ||
| 899 | lm93_read_byte(client, LM93_REG_TEMP_MIN(i)); | ||
| 900 | data->temp_lim[i].max = | ||
| 901 | lm93_read_byte(client, LM93_REG_TEMP_MAX(i)); | ||
| 902 | } | ||
| 903 | |||
| 904 | /* config register */ | ||
| 905 | data->config = lm93_read_byte(client, LM93_REG_CONFIG); | ||
| 906 | |||
| 907 | /* vid1 - vid2: values */ | ||
| 908 | for (i = 0; i < 2; i++) | ||
| 909 | data->vid[i] = lm93_read_byte(client, LM93_REG_VID(i)); | ||
| 910 | |||
| 911 | /* prochot1 - prochot2: limits */ | ||
| 912 | for (i = 0; i < 2; i++) | ||
| 913 | data->prochot_max[i] = lm93_read_byte(client, | ||
| 914 | LM93_REG_PROCHOT_MAX(i)); | ||
| 915 | |||
| 916 | /* vccp1 - vccp2: VID relative limits */ | ||
| 917 | for (i = 0; i < 2; i++) | ||
| 918 | data->vccp_limits[i] = lm93_read_byte(client, | ||
| 919 | LM93_REG_VCCP_LIMIT_OFF(i)); | ||
| 920 | |||
| 921 | /* GPIO input state */ | ||
| 922 | data->gpi = lm93_read_byte(client, LM93_REG_GPI); | ||
| 923 | |||
| 924 | /* #PROCHOT override state */ | ||
| 925 | data->prochot_override = lm93_read_byte(client, | ||
| 926 | LM93_REG_PROCHOT_OVERRIDE); | ||
| 927 | |||
| 928 | /* #PROCHOT intervals */ | ||
| 929 | data->prochot_interval = lm93_read_byte(client, | ||
| 930 | LM93_REG_PROCHOT_INTERVAL); | ||
| 931 | |||
| 932 | /* Fan Boost Termperature registers */ | ||
| 933 | for (i = 0; i < 4; i++) | ||
| 934 | data->boost[i] = lm93_read_byte(client, LM93_REG_BOOST(i)); | ||
| 935 | |||
| 936 | /* Fan Boost Temperature Hyst. registers */ | ||
| 937 | data->boost_hyst[0] = lm93_read_byte(client, LM93_REG_BOOST_HYST_12); | ||
| 938 | data->boost_hyst[1] = lm93_read_byte(client, LM93_REG_BOOST_HYST_34); | ||
| 939 | |||
| 940 | /* Temperature Zone Min. PWM & Hysteresis registers */ | ||
| 941 | data->auto_pwm_min_hyst[0] = | ||
| 942 | lm93_read_byte(client, LM93_REG_PWM_MIN_HYST_12); | ||
| 943 | data->auto_pwm_min_hyst[1] = | ||
| 944 | lm93_read_byte(client, LM93_REG_PWM_MIN_HYST_34); | ||
| 945 | |||
| 946 | /* #PROCHOT & #VRDHOT PWM Ramp Control register */ | ||
| 947 | data->pwm_ramp_ctl = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); | ||
| 948 | |||
| 949 | /* misc setup registers */ | ||
| 950 | data->sfc1 = lm93_read_byte(client, LM93_REG_SFC1); | ||
| 951 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
| 952 | data->sf_tach_to_pwm = lm93_read_byte(client, | ||
| 953 | LM93_REG_SF_TACH_TO_PWM); | ||
| 954 | |||
| 955 | /* write back alarm values to clear */ | ||
| 956 | for (i = 0, ptr = (u8 *)(&data->block1); i < 8; i++) | ||
| 957 | lm93_write_byte(client, LM93_REG_HOST_ERROR_1 + i, *(ptr + i)); | ||
| 958 | } | ||
| 959 | |||
| 960 | /* update routine which uses SMBus block data commands */ | ||
| 961 | static void lm93_update_client_full(struct lm93_data *data, | ||
| 962 | struct i2c_client *client) | ||
| 963 | { | ||
| 964 | dev_dbg(&client->dev,"starting device update (block data enabled)\n"); | ||
| 965 | |||
| 966 | /* in1 - in16: values & limits */ | ||
| 967 | lm93_read_block(client, 3, (u8 *)(data->block3)); | ||
| 968 | lm93_read_block(client, 7, (u8 *)(data->block7)); | ||
| 969 | |||
| 970 | /* temp1 - temp4: values */ | ||
| 971 | lm93_read_block(client, 2, (u8 *)(data->block2)); | ||
| 972 | |||
| 973 | /* prochot1 - prochot2: values */ | ||
| 974 | lm93_read_block(client, 4, (u8 *)(data->block4)); | ||
| 975 | |||
| 976 | /* fan1 - fan4: values & limits */ | ||
| 977 | lm93_read_block(client, 5, (u8 *)(data->block5)); | ||
| 978 | lm93_read_block(client, 8, (u8 *)(data->block8)); | ||
| 979 | |||
| 980 | /* pmw control registers */ | ||
| 981 | lm93_read_block(client, 9, (u8 *)(data->block9)); | ||
| 982 | |||
| 983 | /* alarm values */ | ||
| 984 | lm93_read_block(client, 1, (u8 *)(&data->block1)); | ||
| 985 | |||
| 986 | /* auto/pwm registers */ | ||
| 987 | lm93_read_block(client, 10, (u8 *)(&data->block10)); | ||
| 988 | |||
| 989 | lm93_update_client_common(data, client); | ||
| 990 | } | ||
| 991 | |||
| 992 | /* update routine which uses SMBus byte/word data commands only */ | ||
| 993 | static void lm93_update_client_min(struct lm93_data *data, | ||
| 994 | struct i2c_client *client) | ||
| 995 | { | ||
| 996 | int i,j; | ||
| 997 | u8 *ptr; | ||
| 998 | |||
| 999 | dev_dbg(&client->dev,"starting device update (block data disabled)\n"); | ||
| 1000 | |||
| 1001 | /* in1 - in16: values & limits */ | ||
| 1002 | for (i = 0; i < 16; i++) { | ||
| 1003 | data->block3[i] = | ||
| 1004 | lm93_read_byte(client, LM93_REG_IN(i)); | ||
| 1005 | data->block7[i].min = | ||
| 1006 | lm93_read_byte(client, LM93_REG_IN_MIN(i)); | ||
| 1007 | data->block7[i].max = | ||
| 1008 | lm93_read_byte(client, LM93_REG_IN_MAX(i)); | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | /* temp1 - temp4: values */ | ||
| 1012 | for (i = 0; i < 4; i++) { | ||
| 1013 | data->block2[i] = | ||
| 1014 | lm93_read_byte(client, LM93_REG_TEMP(i)); | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | /* prochot1 - prochot2: values */ | ||
| 1018 | for (i = 0; i < 2; i++) { | ||
| 1019 | data->block4[i].cur = | ||
| 1020 | lm93_read_byte(client, LM93_REG_PROCHOT_CUR(i)); | ||
| 1021 | data->block4[i].avg = | ||
| 1022 | lm93_read_byte(client, LM93_REG_PROCHOT_AVG(i)); | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | /* fan1 - fan4: values & limits */ | ||
| 1026 | for (i = 0; i < 4; i++) { | ||
| 1027 | data->block5[i] = | ||
| 1028 | lm93_read_word(client, LM93_REG_FAN(i)); | ||
| 1029 | data->block8[i] = | ||
| 1030 | lm93_read_word(client, LM93_REG_FAN_MIN(i)); | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | /* pwm control registers */ | ||
| 1034 | for (i = 0; i < 2; i++) { | ||
| 1035 | for (j = 0; j < 4; j++) { | ||
| 1036 | data->block9[i][j] = | ||
| 1037 | lm93_read_byte(client, LM93_REG_PWM_CTL(i,j)); | ||
| 1038 | } | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | /* alarm values */ | ||
| 1042 | for (i = 0, ptr = (u8 *)(&data->block1); i < 8; i++) { | ||
| 1043 | *(ptr + i) = | ||
| 1044 | lm93_read_byte(client, LM93_REG_HOST_ERROR_1 + i); | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | /* auto/pwm (base temp) registers */ | ||
| 1048 | for (i = 0; i < 4; i++) { | ||
| 1049 | data->block10.base[i] = | ||
| 1050 | lm93_read_byte(client, LM93_REG_TEMP_BASE(i)); | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | /* auto/pwm (offset temp) registers */ | ||
| 1054 | for (i = 0; i < 12; i++) { | ||
| 1055 | data->block10.offset[i] = | ||
| 1056 | lm93_read_byte(client, LM93_REG_TEMP_OFFSET(i)); | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | lm93_update_client_common(data, client); | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | /* following are the sysfs callback functions */ | ||
| 1063 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | ||
| 1064 | char *buf) | ||
| 1065 | { | ||
| 1066 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1067 | |||
| 1068 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1069 | return sprintf(buf, "%d\n", LM93_IN_FROM_REG(nr, data->block3[nr])); | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 0); | ||
| 1073 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 1); | ||
| 1074 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 2); | ||
| 1075 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 3); | ||
| 1076 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 4); | ||
| 1077 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 5); | ||
| 1078 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 6); | ||
| 1079 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_in, NULL, 7); | ||
| 1080 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_in, NULL, 8); | ||
| 1081 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_in, NULL, 9); | ||
| 1082 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_in, NULL, 10); | ||
| 1083 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_in, NULL, 11); | ||
| 1084 | static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_in, NULL, 12); | ||
| 1085 | static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, show_in, NULL, 13); | ||
| 1086 | static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, show_in, NULL, 14); | ||
| 1087 | static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in, NULL, 15); | ||
| 1088 | |||
| 1089 | static ssize_t show_in_min(struct device *dev, | ||
| 1090 | struct device_attribute *attr, char *buf) | ||
| 1091 | { | ||
| 1092 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1093 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1094 | int vccp = nr - 6; | ||
| 1095 | long rc, vid; | ||
| 1096 | |||
| 1097 | if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { | ||
| 1098 | vid = LM93_VID_FROM_REG(data->vid[vccp]); | ||
| 1099 | rc = LM93_IN_MIN_FROM_REG(data->vccp_limits[vccp], vid); | ||
| 1100 | } | ||
| 1101 | else { | ||
| 1102 | rc = LM93_IN_FROM_REG(nr, data->block7[nr].min); \ | ||
| 1103 | } | ||
| 1104 | return sprintf(buf, "%ld\n", rc); \ | ||
| 1105 | } | ||
| 1106 | |||
| 1107 | static ssize_t store_in_min(struct device *dev, struct device_attribute *attr, | ||
| 1108 | const char *buf, size_t count) | ||
| 1109 | { | ||
| 1110 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1111 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1112 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1113 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1114 | int vccp = nr - 6; | ||
| 1115 | long vid; | ||
| 1116 | |||
| 1117 | mutex_lock(&data->update_lock); | ||
| 1118 | if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { | ||
| 1119 | vid = LM93_VID_FROM_REG(data->vid[vccp]); | ||
| 1120 | data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0xf0) | | ||
| 1121 | LM93_IN_REL_TO_REG(val, 0, vid); | ||
| 1122 | lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp), | ||
| 1123 | data->vccp_limits[vccp]); | ||
| 1124 | } | ||
| 1125 | else { | ||
| 1126 | data->block7[nr].min = LM93_IN_TO_REG(nr,val); | ||
| 1127 | lm93_write_byte(client, LM93_REG_IN_MIN(nr), | ||
| 1128 | data->block7[nr].min); | ||
| 1129 | } | ||
| 1130 | mutex_unlock(&data->update_lock); | ||
| 1131 | return count; | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, | ||
| 1135 | show_in_min, store_in_min, 0); | ||
| 1136 | static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, | ||
| 1137 | show_in_min, store_in_min, 1); | ||
| 1138 | static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, | ||
| 1139 | show_in_min, store_in_min, 2); | ||
| 1140 | static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, | ||
| 1141 | show_in_min, store_in_min, 3); | ||
| 1142 | static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, | ||
| 1143 | show_in_min, store_in_min, 4); | ||
| 1144 | static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, | ||
| 1145 | show_in_min, store_in_min, 5); | ||
| 1146 | static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, | ||
| 1147 | show_in_min, store_in_min, 6); | ||
| 1148 | static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, | ||
| 1149 | show_in_min, store_in_min, 7); | ||
| 1150 | static SENSOR_DEVICE_ATTR(in9_min, S_IWUSR | S_IRUGO, | ||
| 1151 | show_in_min, store_in_min, 8); | ||
| 1152 | static SENSOR_DEVICE_ATTR(in10_min, S_IWUSR | S_IRUGO, | ||
| 1153 | show_in_min, store_in_min, 9); | ||
| 1154 | static SENSOR_DEVICE_ATTR(in11_min, S_IWUSR | S_IRUGO, | ||
| 1155 | show_in_min, store_in_min, 10); | ||
| 1156 | static SENSOR_DEVICE_ATTR(in12_min, S_IWUSR | S_IRUGO, | ||
| 1157 | show_in_min, store_in_min, 11); | ||
| 1158 | static SENSOR_DEVICE_ATTR(in13_min, S_IWUSR | S_IRUGO, | ||
| 1159 | show_in_min, store_in_min, 12); | ||
| 1160 | static SENSOR_DEVICE_ATTR(in14_min, S_IWUSR | S_IRUGO, | ||
| 1161 | show_in_min, store_in_min, 13); | ||
| 1162 | static SENSOR_DEVICE_ATTR(in15_min, S_IWUSR | S_IRUGO, | ||
| 1163 | show_in_min, store_in_min, 14); | ||
| 1164 | static SENSOR_DEVICE_ATTR(in16_min, S_IWUSR | S_IRUGO, | ||
| 1165 | show_in_min, store_in_min, 15); | ||
| 1166 | |||
| 1167 | static ssize_t show_in_max(struct device *dev, | ||
| 1168 | struct device_attribute *attr, char *buf) | ||
| 1169 | { | ||
| 1170 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1171 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1172 | int vccp = nr - 6; | ||
| 1173 | long rc, vid; | ||
| 1174 | |||
| 1175 | if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { | ||
| 1176 | vid = LM93_VID_FROM_REG(data->vid[vccp]); | ||
| 1177 | rc = LM93_IN_MAX_FROM_REG(data->vccp_limits[vccp],vid); | ||
| 1178 | } | ||
| 1179 | else { | ||
| 1180 | rc = LM93_IN_FROM_REG(nr,data->block7[nr].max); \ | ||
| 1181 | } | ||
| 1182 | return sprintf(buf,"%ld\n",rc); \ | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | static ssize_t store_in_max(struct device *dev, struct device_attribute *attr, | ||
| 1186 | const char *buf, size_t count) | ||
| 1187 | { | ||
| 1188 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1189 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1190 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1191 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1192 | int vccp = nr - 6; | ||
| 1193 | long vid; | ||
| 1194 | |||
| 1195 | mutex_lock(&data->update_lock); | ||
| 1196 | if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) { | ||
| 1197 | vid = LM93_VID_FROM_REG(data->vid[vccp]); | ||
| 1198 | data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0x0f) | | ||
| 1199 | LM93_IN_REL_TO_REG(val, 1, vid); | ||
| 1200 | lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp), | ||
| 1201 | data->vccp_limits[vccp]); | ||
| 1202 | } | ||
| 1203 | else { | ||
| 1204 | data->block7[nr].max = LM93_IN_TO_REG(nr,val); | ||
| 1205 | lm93_write_byte(client, LM93_REG_IN_MAX(nr), | ||
| 1206 | data->block7[nr].max); | ||
| 1207 | } | ||
| 1208 | mutex_unlock(&data->update_lock); | ||
| 1209 | return count; | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, | ||
| 1213 | show_in_max, store_in_max, 0); | ||
| 1214 | static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, | ||
| 1215 | show_in_max, store_in_max, 1); | ||
| 1216 | static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, | ||
| 1217 | show_in_max, store_in_max, 2); | ||
| 1218 | static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, | ||
| 1219 | show_in_max, store_in_max, 3); | ||
| 1220 | static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, | ||
| 1221 | show_in_max, store_in_max, 4); | ||
| 1222 | static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, | ||
| 1223 | show_in_max, store_in_max, 5); | ||
| 1224 | static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, | ||
| 1225 | show_in_max, store_in_max, 6); | ||
| 1226 | static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, | ||
| 1227 | show_in_max, store_in_max, 7); | ||
| 1228 | static SENSOR_DEVICE_ATTR(in9_max, S_IWUSR | S_IRUGO, | ||
| 1229 | show_in_max, store_in_max, 8); | ||
| 1230 | static SENSOR_DEVICE_ATTR(in10_max, S_IWUSR | S_IRUGO, | ||
| 1231 | show_in_max, store_in_max, 9); | ||
| 1232 | static SENSOR_DEVICE_ATTR(in11_max, S_IWUSR | S_IRUGO, | ||
| 1233 | show_in_max, store_in_max, 10); | ||
| 1234 | static SENSOR_DEVICE_ATTR(in12_max, S_IWUSR | S_IRUGO, | ||
| 1235 | show_in_max, store_in_max, 11); | ||
| 1236 | static SENSOR_DEVICE_ATTR(in13_max, S_IWUSR | S_IRUGO, | ||
| 1237 | show_in_max, store_in_max, 12); | ||
| 1238 | static SENSOR_DEVICE_ATTR(in14_max, S_IWUSR | S_IRUGO, | ||
| 1239 | show_in_max, store_in_max, 13); | ||
| 1240 | static SENSOR_DEVICE_ATTR(in15_max, S_IWUSR | S_IRUGO, | ||
| 1241 | show_in_max, store_in_max, 14); | ||
| 1242 | static SENSOR_DEVICE_ATTR(in16_max, S_IWUSR | S_IRUGO, | ||
| 1243 | show_in_max, store_in_max, 15); | ||
| 1244 | |||
| 1245 | static ssize_t show_temp(struct device *dev, | ||
| 1246 | struct device_attribute *attr, char *buf) | ||
| 1247 | { | ||
| 1248 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1249 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1250 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->block2[nr])); | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
| 1254 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
| 1255 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); | ||
| 1256 | |||
| 1257 | static ssize_t show_temp_min(struct device *dev, | ||
| 1258 | struct device_attribute *attr, char *buf) | ||
| 1259 | { | ||
| 1260 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1261 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1262 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->temp_lim[nr].min)); | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr, | ||
| 1266 | const char *buf, size_t count) | ||
| 1267 | { | ||
| 1268 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1269 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1270 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1271 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1272 | |||
| 1273 | mutex_lock(&data->update_lock); | ||
| 1274 | data->temp_lim[nr].min = LM93_TEMP_TO_REG(val); | ||
| 1275 | lm93_write_byte(client, LM93_REG_TEMP_MIN(nr), data->temp_lim[nr].min); | ||
| 1276 | mutex_unlock(&data->update_lock); | ||
| 1277 | return count; | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, | ||
| 1281 | show_temp_min, store_temp_min, 0); | ||
| 1282 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, | ||
| 1283 | show_temp_min, store_temp_min, 1); | ||
| 1284 | static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, | ||
| 1285 | show_temp_min, store_temp_min, 2); | ||
| 1286 | |||
| 1287 | static ssize_t show_temp_max(struct device *dev, | ||
| 1288 | struct device_attribute *attr, char *buf) | ||
| 1289 | { | ||
| 1290 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1291 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1292 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->temp_lim[nr].max)); | ||
| 1293 | } | ||
| 1294 | |||
| 1295 | static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr, | ||
| 1296 | const char *buf, size_t count) | ||
| 1297 | { | ||
| 1298 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1299 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1300 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1301 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1302 | |||
| 1303 | mutex_lock(&data->update_lock); | ||
| 1304 | data->temp_lim[nr].max = LM93_TEMP_TO_REG(val); | ||
| 1305 | lm93_write_byte(client, LM93_REG_TEMP_MAX(nr), data->temp_lim[nr].max); | ||
| 1306 | mutex_unlock(&data->update_lock); | ||
| 1307 | return count; | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | ||
| 1311 | show_temp_max, store_temp_max, 0); | ||
| 1312 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, | ||
| 1313 | show_temp_max, store_temp_max, 1); | ||
| 1314 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, | ||
| 1315 | show_temp_max, store_temp_max, 2); | ||
| 1316 | |||
| 1317 | static ssize_t show_temp_auto_base(struct device *dev, | ||
| 1318 | struct device_attribute *attr, char *buf) | ||
| 1319 | { | ||
| 1320 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1321 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1322 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->block10.base[nr])); | ||
| 1323 | } | ||
| 1324 | |||
| 1325 | static ssize_t store_temp_auto_base(struct device *dev, | ||
| 1326 | struct device_attribute *attr, | ||
| 1327 | const char *buf, size_t count) | ||
| 1328 | { | ||
| 1329 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1330 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1331 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1332 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1333 | |||
| 1334 | mutex_lock(&data->update_lock); | ||
| 1335 | data->block10.base[nr] = LM93_TEMP_TO_REG(val); | ||
| 1336 | lm93_write_byte(client, LM93_REG_TEMP_BASE(nr), data->block10.base[nr]); | ||
| 1337 | mutex_unlock(&data->update_lock); | ||
| 1338 | return count; | ||
| 1339 | } | ||
| 1340 | |||
| 1341 | static SENSOR_DEVICE_ATTR(temp1_auto_base, S_IWUSR | S_IRUGO, | ||
| 1342 | show_temp_auto_base, store_temp_auto_base, 0); | ||
| 1343 | static SENSOR_DEVICE_ATTR(temp2_auto_base, S_IWUSR | S_IRUGO, | ||
| 1344 | show_temp_auto_base, store_temp_auto_base, 1); | ||
| 1345 | static SENSOR_DEVICE_ATTR(temp3_auto_base, S_IWUSR | S_IRUGO, | ||
| 1346 | show_temp_auto_base, store_temp_auto_base, 2); | ||
| 1347 | |||
| 1348 | static ssize_t show_temp_auto_boost(struct device *dev, | ||
| 1349 | struct device_attribute *attr,char *buf) | ||
| 1350 | { | ||
| 1351 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1352 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1353 | return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->boost[nr])); | ||
| 1354 | } | ||
| 1355 | |||
| 1356 | static ssize_t store_temp_auto_boost(struct device *dev, | ||
| 1357 | struct device_attribute *attr, | ||
| 1358 | const char *buf, size_t count) | ||
| 1359 | { | ||
| 1360 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1361 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1362 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1363 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1364 | |||
| 1365 | mutex_lock(&data->update_lock); | ||
| 1366 | data->boost[nr] = LM93_TEMP_TO_REG(val); | ||
| 1367 | lm93_write_byte(client, LM93_REG_BOOST(nr), data->boost[nr]); | ||
| 1368 | mutex_unlock(&data->update_lock); | ||
| 1369 | return count; | ||
| 1370 | } | ||
| 1371 | |||
| 1372 | static SENSOR_DEVICE_ATTR(temp1_auto_boost, S_IWUSR | S_IRUGO, | ||
| 1373 | show_temp_auto_boost, store_temp_auto_boost, 0); | ||
| 1374 | static SENSOR_DEVICE_ATTR(temp2_auto_boost, S_IWUSR | S_IRUGO, | ||
| 1375 | show_temp_auto_boost, store_temp_auto_boost, 1); | ||
| 1376 | static SENSOR_DEVICE_ATTR(temp3_auto_boost, S_IWUSR | S_IRUGO, | ||
| 1377 | show_temp_auto_boost, store_temp_auto_boost, 2); | ||
| 1378 | |||
| 1379 | static ssize_t show_temp_auto_boost_hyst(struct device *dev, | ||
| 1380 | struct device_attribute *attr, | ||
| 1381 | char *buf) | ||
| 1382 | { | ||
| 1383 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1384 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1385 | int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); | ||
| 1386 | return sprintf(buf,"%d\n", | ||
| 1387 | LM93_AUTO_BOOST_HYST_FROM_REGS(data, nr, mode)); | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | static ssize_t store_temp_auto_boost_hyst(struct device *dev, | ||
| 1391 | struct device_attribute *attr, | ||
| 1392 | const char *buf, size_t count) | ||
| 1393 | { | ||
| 1394 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1395 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1396 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1397 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1398 | |||
| 1399 | mutex_lock(&data->update_lock); | ||
| 1400 | /* force 0.5C/bit mode */ | ||
| 1401 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
| 1402 | data->sfc2 |= ((nr < 2) ? 0x10 : 0x20); | ||
| 1403 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
| 1404 | data->boost_hyst[nr/2] = LM93_AUTO_BOOST_HYST_TO_REG(data, val, nr, 1); | ||
| 1405 | lm93_write_byte(client, LM93_REG_BOOST_HYST(nr), | ||
| 1406 | data->boost_hyst[nr/2]); | ||
| 1407 | mutex_unlock(&data->update_lock); | ||
| 1408 | return count; | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | static SENSOR_DEVICE_ATTR(temp1_auto_boost_hyst, S_IWUSR | S_IRUGO, | ||
| 1412 | show_temp_auto_boost_hyst, | ||
| 1413 | store_temp_auto_boost_hyst, 0); | ||
| 1414 | static SENSOR_DEVICE_ATTR(temp2_auto_boost_hyst, S_IWUSR | S_IRUGO, | ||
| 1415 | show_temp_auto_boost_hyst, | ||
| 1416 | store_temp_auto_boost_hyst, 1); | ||
| 1417 | static SENSOR_DEVICE_ATTR(temp3_auto_boost_hyst, S_IWUSR | S_IRUGO, | ||
| 1418 | show_temp_auto_boost_hyst, | ||
| 1419 | store_temp_auto_boost_hyst, 2); | ||
| 1420 | |||
| 1421 | static ssize_t show_temp_auto_offset(struct device *dev, | ||
| 1422 | struct device_attribute *attr, char *buf) | ||
| 1423 | { | ||
| 1424 | struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr); | ||
| 1425 | int nr = s_attr->index; | ||
| 1426 | int ofs = s_attr->nr; | ||
| 1427 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1428 | int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); | ||
| 1429 | return sprintf(buf,"%d\n", | ||
| 1430 | LM93_TEMP_AUTO_OFFSET_FROM_REG(data->block10.offset[ofs], | ||
| 1431 | nr,mode)); | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | static ssize_t store_temp_auto_offset(struct device *dev, | ||
| 1435 | struct device_attribute *attr, | ||
| 1436 | const char *buf, size_t count) | ||
| 1437 | { | ||
| 1438 | struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr); | ||
| 1439 | int nr = s_attr->index; | ||
| 1440 | int ofs = s_attr->nr; | ||
| 1441 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1442 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1443 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1444 | |||
| 1445 | mutex_lock(&data->update_lock); | ||
| 1446 | /* force 0.5C/bit mode */ | ||
| 1447 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
| 1448 | data->sfc2 |= ((nr < 2) ? 0x10 : 0x20); | ||
| 1449 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
| 1450 | data->block10.offset[ofs] = LM93_TEMP_AUTO_OFFSET_TO_REG( | ||
| 1451 | data->block10.offset[ofs], val, nr, 1); | ||
| 1452 | lm93_write_byte(client, LM93_REG_TEMP_OFFSET(ofs), | ||
| 1453 | data->block10.offset[ofs]); | ||
| 1454 | mutex_unlock(&data->update_lock); | ||
| 1455 | return count; | ||
| 1456 | } | ||
| 1457 | |||
| 1458 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset1, S_IWUSR | S_IRUGO, | ||
| 1459 | show_temp_auto_offset, store_temp_auto_offset, 0, 0); | ||
| 1460 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset2, S_IWUSR | S_IRUGO, | ||
| 1461 | show_temp_auto_offset, store_temp_auto_offset, 1, 0); | ||
| 1462 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset3, S_IWUSR | S_IRUGO, | ||
| 1463 | show_temp_auto_offset, store_temp_auto_offset, 2, 0); | ||
| 1464 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset4, S_IWUSR | S_IRUGO, | ||
| 1465 | show_temp_auto_offset, store_temp_auto_offset, 3, 0); | ||
| 1466 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset5, S_IWUSR | S_IRUGO, | ||
| 1467 | show_temp_auto_offset, store_temp_auto_offset, 4, 0); | ||
| 1468 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset6, S_IWUSR | S_IRUGO, | ||
| 1469 | show_temp_auto_offset, store_temp_auto_offset, 5, 0); | ||
| 1470 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset7, S_IWUSR | S_IRUGO, | ||
| 1471 | show_temp_auto_offset, store_temp_auto_offset, 6, 0); | ||
| 1472 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset8, S_IWUSR | S_IRUGO, | ||
| 1473 | show_temp_auto_offset, store_temp_auto_offset, 7, 0); | ||
| 1474 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset9, S_IWUSR | S_IRUGO, | ||
| 1475 | show_temp_auto_offset, store_temp_auto_offset, 8, 0); | ||
| 1476 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset10, S_IWUSR | S_IRUGO, | ||
| 1477 | show_temp_auto_offset, store_temp_auto_offset, 9, 0); | ||
| 1478 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset11, S_IWUSR | S_IRUGO, | ||
| 1479 | show_temp_auto_offset, store_temp_auto_offset, 10, 0); | ||
| 1480 | static SENSOR_DEVICE_ATTR_2(temp1_auto_offset12, S_IWUSR | S_IRUGO, | ||
| 1481 | show_temp_auto_offset, store_temp_auto_offset, 11, 0); | ||
| 1482 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset1, S_IWUSR | S_IRUGO, | ||
| 1483 | show_temp_auto_offset, store_temp_auto_offset, 0, 1); | ||
| 1484 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset2, S_IWUSR | S_IRUGO, | ||
| 1485 | show_temp_auto_offset, store_temp_auto_offset, 1, 1); | ||
| 1486 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset3, S_IWUSR | S_IRUGO, | ||
| 1487 | show_temp_auto_offset, store_temp_auto_offset, 2, 1); | ||
| 1488 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset4, S_IWUSR | S_IRUGO, | ||
| 1489 | show_temp_auto_offset, store_temp_auto_offset, 3, 1); | ||
| 1490 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset5, S_IWUSR | S_IRUGO, | ||
| 1491 | show_temp_auto_offset, store_temp_auto_offset, 4, 1); | ||
| 1492 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset6, S_IWUSR | S_IRUGO, | ||
| 1493 | show_temp_auto_offset, store_temp_auto_offset, 5, 1); | ||
| 1494 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset7, S_IWUSR | S_IRUGO, | ||
| 1495 | show_temp_auto_offset, store_temp_auto_offset, 6, 1); | ||
| 1496 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset8, S_IWUSR | S_IRUGO, | ||
| 1497 | show_temp_auto_offset, store_temp_auto_offset, 7, 1); | ||
| 1498 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset9, S_IWUSR | S_IRUGO, | ||
| 1499 | show_temp_auto_offset, store_temp_auto_offset, 8, 1); | ||
| 1500 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset10, S_IWUSR | S_IRUGO, | ||
| 1501 | show_temp_auto_offset, store_temp_auto_offset, 9, 1); | ||
| 1502 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset11, S_IWUSR | S_IRUGO, | ||
| 1503 | show_temp_auto_offset, store_temp_auto_offset, 10, 1); | ||
| 1504 | static SENSOR_DEVICE_ATTR_2(temp2_auto_offset12, S_IWUSR | S_IRUGO, | ||
| 1505 | show_temp_auto_offset, store_temp_auto_offset, 11, 1); | ||
| 1506 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset1, S_IWUSR | S_IRUGO, | ||
| 1507 | show_temp_auto_offset, store_temp_auto_offset, 0, 2); | ||
| 1508 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset2, S_IWUSR | S_IRUGO, | ||
| 1509 | show_temp_auto_offset, store_temp_auto_offset, 1, 2); | ||
| 1510 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset3, S_IWUSR | S_IRUGO, | ||
| 1511 | show_temp_auto_offset, store_temp_auto_offset, 2, 2); | ||
| 1512 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset4, S_IWUSR | S_IRUGO, | ||
| 1513 | show_temp_auto_offset, store_temp_auto_offset, 3, 2); | ||
| 1514 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset5, S_IWUSR | S_IRUGO, | ||
| 1515 | show_temp_auto_offset, store_temp_auto_offset, 4, 2); | ||
| 1516 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset6, S_IWUSR | S_IRUGO, | ||
| 1517 | show_temp_auto_offset, store_temp_auto_offset, 5, 2); | ||
| 1518 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset7, S_IWUSR | S_IRUGO, | ||
| 1519 | show_temp_auto_offset, store_temp_auto_offset, 6, 2); | ||
| 1520 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset8, S_IWUSR | S_IRUGO, | ||
| 1521 | show_temp_auto_offset, store_temp_auto_offset, 7, 2); | ||
| 1522 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset9, S_IWUSR | S_IRUGO, | ||
| 1523 | show_temp_auto_offset, store_temp_auto_offset, 8, 2); | ||
| 1524 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset10, S_IWUSR | S_IRUGO, | ||
| 1525 | show_temp_auto_offset, store_temp_auto_offset, 9, 2); | ||
| 1526 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset11, S_IWUSR | S_IRUGO, | ||
| 1527 | show_temp_auto_offset, store_temp_auto_offset, 10, 2); | ||
| 1528 | static SENSOR_DEVICE_ATTR_2(temp3_auto_offset12, S_IWUSR | S_IRUGO, | ||
| 1529 | show_temp_auto_offset, store_temp_auto_offset, 11, 2); | ||
| 1530 | |||
| 1531 | static ssize_t show_temp_auto_pwm_min(struct device *dev, | ||
| 1532 | struct device_attribute *attr, char *buf) | ||
| 1533 | { | ||
| 1534 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1535 | u8 reg, ctl4; | ||
| 1536 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1537 | reg = data->auto_pwm_min_hyst[nr/2] >> 4 & 0x0f; | ||
| 1538 | ctl4 = data->block9[nr][LM93_PWM_CTL4]; | ||
| 1539 | return sprintf(buf,"%d\n",LM93_PWM_FROM_REG(reg, (ctl4 & 0x07) ? | ||
| 1540 | LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ)); | ||
| 1541 | } | ||
| 1542 | |||
| 1543 | static ssize_t store_temp_auto_pwm_min(struct device *dev, | ||
| 1544 | struct device_attribute *attr, | ||
| 1545 | const char *buf, size_t count) | ||
| 1546 | { | ||
| 1547 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1548 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1549 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1550 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1551 | u8 reg, ctl4; | ||
| 1552 | |||
| 1553 | mutex_lock(&data->update_lock); | ||
| 1554 | reg = lm93_read_byte(client, LM93_REG_PWM_MIN_HYST(nr)); | ||
| 1555 | ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); | ||
| 1556 | reg = (reg & 0x0f) | | ||
| 1557 | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? | ||
| 1558 | LM93_PWM_MAP_LO_FREQ : | ||
| 1559 | LM93_PWM_MAP_HI_FREQ) << 4; | ||
| 1560 | data->auto_pwm_min_hyst[nr/2] = reg; | ||
| 1561 | lm93_write_byte(client, LM93_REG_PWM_MIN_HYST(nr), reg); | ||
| 1562 | mutex_unlock(&data->update_lock); | ||
| 1563 | return count; | ||
| 1564 | } | ||
| 1565 | |||
| 1566 | static SENSOR_DEVICE_ATTR(temp1_auto_pwm_min, S_IWUSR | S_IRUGO, | ||
| 1567 | show_temp_auto_pwm_min, | ||
| 1568 | store_temp_auto_pwm_min, 0); | ||
| 1569 | static SENSOR_DEVICE_ATTR(temp2_auto_pwm_min, S_IWUSR | S_IRUGO, | ||
| 1570 | show_temp_auto_pwm_min, | ||
| 1571 | store_temp_auto_pwm_min, 1); | ||
| 1572 | static SENSOR_DEVICE_ATTR(temp3_auto_pwm_min, S_IWUSR | S_IRUGO, | ||
| 1573 | show_temp_auto_pwm_min, | ||
| 1574 | store_temp_auto_pwm_min, 2); | ||
| 1575 | |||
| 1576 | static ssize_t show_temp_auto_offset_hyst(struct device *dev, | ||
| 1577 | struct device_attribute *attr, char *buf) | ||
| 1578 | { | ||
| 1579 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1580 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1581 | int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); | ||
| 1582 | return sprintf(buf,"%d\n",LM93_TEMP_OFFSET_FROM_REG( | ||
| 1583 | data->auto_pwm_min_hyst[nr/2], mode)); | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | static ssize_t store_temp_auto_offset_hyst(struct device *dev, | ||
| 1587 | struct device_attribute *attr, | ||
| 1588 | const char *buf, size_t count) | ||
| 1589 | { | ||
| 1590 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1591 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1592 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1593 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1594 | u8 reg; | ||
| 1595 | |||
| 1596 | mutex_lock(&data->update_lock); | ||
| 1597 | /* force 0.5C/bit mode */ | ||
| 1598 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
| 1599 | data->sfc2 |= ((nr < 2) ? 0x10 : 0x20); | ||
| 1600 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
| 1601 | reg = data->auto_pwm_min_hyst[nr/2]; | ||
| 1602 | reg = (reg & 0xf0) | (LM93_TEMP_OFFSET_TO_REG(val, 1) & 0x0f); | ||
| 1603 | data->auto_pwm_min_hyst[nr/2] = reg; | ||
| 1604 | lm93_write_byte(client, LM93_REG_PWM_MIN_HYST(nr), reg); | ||
| 1605 | mutex_unlock(&data->update_lock); | ||
| 1606 | return count; | ||
| 1607 | } | ||
| 1608 | |||
| 1609 | static SENSOR_DEVICE_ATTR(temp1_auto_offset_hyst, S_IWUSR | S_IRUGO, | ||
| 1610 | show_temp_auto_offset_hyst, | ||
| 1611 | store_temp_auto_offset_hyst, 0); | ||
| 1612 | static SENSOR_DEVICE_ATTR(temp2_auto_offset_hyst, S_IWUSR | S_IRUGO, | ||
| 1613 | show_temp_auto_offset_hyst, | ||
| 1614 | store_temp_auto_offset_hyst, 1); | ||
| 1615 | static SENSOR_DEVICE_ATTR(temp3_auto_offset_hyst, S_IWUSR | S_IRUGO, | ||
| 1616 | show_temp_auto_offset_hyst, | ||
| 1617 | store_temp_auto_offset_hyst, 2); | ||
| 1618 | |||
| 1619 | static ssize_t show_fan_input(struct device *dev, | ||
| 1620 | struct device_attribute *attr, char *buf) | ||
| 1621 | { | ||
| 1622 | struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); | ||
| 1623 | int nr = s_attr->index; | ||
| 1624 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1625 | |||
| 1626 | return sprintf(buf,"%d\n",LM93_FAN_FROM_REG(data->block5[nr])); | ||
| 1627 | } | ||
| 1628 | |||
| 1629 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0); | ||
| 1630 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1); | ||
| 1631 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2); | ||
| 1632 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3); | ||
| 1633 | |||
| 1634 | static ssize_t show_fan_min(struct device *dev, | ||
| 1635 | struct device_attribute *attr, char *buf) | ||
| 1636 | { | ||
| 1637 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1638 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1639 | |||
| 1640 | return sprintf(buf,"%d\n",LM93_FAN_FROM_REG(data->block8[nr])); | ||
| 1641 | } | ||
| 1642 | |||
| 1643 | static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, | ||
| 1644 | const char *buf, size_t count) | ||
| 1645 | { | ||
| 1646 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1647 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1648 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1649 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1650 | |||
| 1651 | mutex_lock(&data->update_lock); | ||
| 1652 | data->block8[nr] = LM93_FAN_TO_REG(val); | ||
| 1653 | lm93_write_word(client,LM93_REG_FAN_MIN(nr),data->block8[nr]); | ||
| 1654 | mutex_unlock(&data->update_lock); | ||
| 1655 | return count; | ||
| 1656 | } | ||
| 1657 | |||
| 1658 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, | ||
| 1659 | show_fan_min, store_fan_min, 0); | ||
| 1660 | static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, | ||
| 1661 | show_fan_min, store_fan_min, 1); | ||
| 1662 | static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, | ||
| 1663 | show_fan_min, store_fan_min, 2); | ||
| 1664 | static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, | ||
| 1665 | show_fan_min, store_fan_min, 3); | ||
| 1666 | |||
| 1667 | /* some tedious bit-twiddling here to deal with the register format: | ||
| 1668 | |||
| 1669 | data->sf_tach_to_pwm: (tach to pwm mapping bits) | ||
| 1670 | |||
| 1671 | bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
| 1672 | T4:P2 T4:P1 T3:P2 T3:P1 T2:P2 T2:P1 T1:P2 T1:P1 | ||
| 1673 | |||
| 1674 | data->sfc2: (enable bits) | ||
| 1675 | |||
| 1676 | bit | 3 | 2 | 1 | 0 | ||
| 1677 | T4 T3 T2 T1 | ||
| 1678 | */ | ||
| 1679 | |||
| 1680 | static ssize_t show_fan_smart_tach(struct device *dev, | ||
| 1681 | struct device_attribute *attr, char *buf) | ||
| 1682 | { | ||
| 1683 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1684 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1685 | long rc = 0; | ||
| 1686 | int mapping; | ||
| 1687 | |||
| 1688 | /* extract the relevant mapping */ | ||
| 1689 | mapping = (data->sf_tach_to_pwm >> (nr * 2)) & 0x03; | ||
| 1690 | |||
| 1691 | /* if there's a mapping and it's enabled */ | ||
| 1692 | if (mapping && ((data->sfc2 >> nr) & 0x01)) | ||
| 1693 | rc = mapping; | ||
| 1694 | return sprintf(buf,"%ld\n",rc); | ||
| 1695 | } | ||
| 1696 | |||
| 1697 | /* helper function - must grab data->update_lock before calling | ||
| 1698 | fan is 0-3, indicating fan1-fan4 */ | ||
| 1699 | static void lm93_write_fan_smart_tach(struct i2c_client *client, | ||
| 1700 | struct lm93_data *data, int fan, long value) | ||
| 1701 | { | ||
| 1702 | /* insert the new mapping and write it out */ | ||
| 1703 | data->sf_tach_to_pwm = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); | ||
| 1704 | data->sf_tach_to_pwm &= ~(0x3 << fan * 2); | ||
| 1705 | data->sf_tach_to_pwm |= value << fan * 2; | ||
| 1706 | lm93_write_byte(client, LM93_REG_SF_TACH_TO_PWM, data->sf_tach_to_pwm); | ||
| 1707 | |||
| 1708 | /* insert the enable bit and write it out */ | ||
| 1709 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
| 1710 | if (value) | ||
| 1711 | data->sfc2 |= 1 << fan; | ||
| 1712 | else | ||
| 1713 | data->sfc2 &= ~(1 << fan); | ||
| 1714 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
| 1715 | } | ||
| 1716 | |||
| 1717 | static ssize_t store_fan_smart_tach(struct device *dev, | ||
| 1718 | struct device_attribute *attr, | ||
| 1719 | const char *buf, size_t count) | ||
| 1720 | { | ||
| 1721 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1722 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1723 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1724 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1725 | |||
| 1726 | mutex_lock(&data->update_lock); | ||
| 1727 | /* sanity test, ignore the write otherwise */ | ||
| 1728 | if (0 <= val && val <= 2) { | ||
| 1729 | /* can't enable if pwm freq is 22.5KHz */ | ||
| 1730 | if (val) { | ||
| 1731 | u8 ctl4 = lm93_read_byte(client, | ||
| 1732 | LM93_REG_PWM_CTL(val-1,LM93_PWM_CTL4)); | ||
| 1733 | if ((ctl4 & 0x07) == 0) | ||
| 1734 | val = 0; | ||
| 1735 | } | ||
| 1736 | lm93_write_fan_smart_tach(client, data, nr, val); | ||
| 1737 | } | ||
| 1738 | mutex_unlock(&data->update_lock); | ||
| 1739 | return count; | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | static SENSOR_DEVICE_ATTR(fan1_smart_tach, S_IWUSR | S_IRUGO, | ||
| 1743 | show_fan_smart_tach, store_fan_smart_tach, 0); | ||
| 1744 | static SENSOR_DEVICE_ATTR(fan2_smart_tach, S_IWUSR | S_IRUGO, | ||
| 1745 | show_fan_smart_tach, store_fan_smart_tach, 1); | ||
| 1746 | static SENSOR_DEVICE_ATTR(fan3_smart_tach, S_IWUSR | S_IRUGO, | ||
| 1747 | show_fan_smart_tach, store_fan_smart_tach, 2); | ||
| 1748 | static SENSOR_DEVICE_ATTR(fan4_smart_tach, S_IWUSR | S_IRUGO, | ||
| 1749 | show_fan_smart_tach, store_fan_smart_tach, 3); | ||
| 1750 | |||
| 1751 | static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | ||
| 1752 | char *buf) | ||
| 1753 | { | ||
| 1754 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1755 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1756 | u8 ctl2, ctl4; | ||
| 1757 | long rc; | ||
| 1758 | |||
| 1759 | ctl2 = data->block9[nr][LM93_PWM_CTL2]; | ||
| 1760 | ctl4 = data->block9[nr][LM93_PWM_CTL4]; | ||
| 1761 | if (ctl2 & 0x01) /* show user commanded value if enabled */ | ||
| 1762 | rc = data->pwm_override[nr]; | ||
| 1763 | else /* show present h/w value if manual pwm disabled */ | ||
| 1764 | rc = LM93_PWM_FROM_REG(ctl2 >> 4, (ctl4 & 0x07) ? | ||
| 1765 | LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); | ||
| 1766 | return sprintf(buf,"%ld\n",rc); | ||
| 1767 | } | ||
| 1768 | |||
| 1769 | static ssize_t store_pwm(struct device *dev, struct device_attribute *attr, | ||
| 1770 | const char *buf, size_t count) | ||
| 1771 | { | ||
| 1772 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1773 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1774 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1775 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1776 | u8 ctl2, ctl4; | ||
| 1777 | |||
| 1778 | mutex_lock(&data->update_lock); | ||
| 1779 | ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2)); | ||
| 1780 | ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); | ||
| 1781 | ctl2 = (ctl2 & 0x0f) | LM93_PWM_TO_REG(val,(ctl4 & 0x07) ? | ||
| 1782 | LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ) << 4; | ||
| 1783 | /* save user commanded value */ | ||
| 1784 | data->pwm_override[nr] = LM93_PWM_FROM_REG(ctl2 >> 4, | ||
| 1785 | (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : | ||
| 1786 | LM93_PWM_MAP_HI_FREQ); | ||
| 1787 | lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2); | ||
| 1788 | mutex_unlock(&data->update_lock); | ||
| 1789 | return count; | ||
| 1790 | } | ||
| 1791 | |||
| 1792 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0); | ||
| 1793 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1); | ||
| 1794 | |||
| 1795 | static ssize_t show_pwm_enable(struct device *dev, | ||
| 1796 | struct device_attribute *attr, char *buf) | ||
| 1797 | { | ||
| 1798 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1799 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1800 | u8 ctl2; | ||
| 1801 | long rc; | ||
| 1802 | |||
| 1803 | ctl2 = data->block9[nr][LM93_PWM_CTL2]; | ||
| 1804 | if (ctl2 & 0x01) /* manual override enabled ? */ | ||
| 1805 | rc = ((ctl2 & 0xF0) == 0xF0) ? 0 : 1; | ||
| 1806 | else | ||
| 1807 | rc = 2; | ||
| 1808 | return sprintf(buf,"%ld\n",rc); | ||
| 1809 | } | ||
| 1810 | |||
| 1811 | static ssize_t store_pwm_enable(struct device *dev, | ||
| 1812 | struct device_attribute *attr, | ||
| 1813 | const char *buf, size_t count) | ||
| 1814 | { | ||
| 1815 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1816 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1817 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1818 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1819 | u8 ctl2; | ||
| 1820 | |||
| 1821 | mutex_lock(&data->update_lock); | ||
| 1822 | ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2)); | ||
| 1823 | |||
| 1824 | switch (val) { | ||
| 1825 | case 0: | ||
| 1826 | ctl2 |= 0xF1; /* enable manual override, set PWM to max */ | ||
| 1827 | break; | ||
| 1828 | case 1: ctl2 |= 0x01; /* enable manual override */ | ||
| 1829 | break; | ||
| 1830 | case 2: ctl2 &= ~0x01; /* disable manual override */ | ||
| 1831 | break; | ||
| 1832 | default: | ||
| 1833 | mutex_unlock(&data->update_lock); | ||
| 1834 | return -EINVAL; | ||
| 1835 | } | ||
| 1836 | |||
| 1837 | lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2); | ||
| 1838 | mutex_unlock(&data->update_lock); | ||
| 1839 | return count; | ||
| 1840 | } | ||
| 1841 | |||
| 1842 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, | ||
| 1843 | show_pwm_enable, store_pwm_enable, 0); | ||
| 1844 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, | ||
| 1845 | show_pwm_enable, store_pwm_enable, 1); | ||
| 1846 | |||
| 1847 | static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, | ||
| 1848 | char *buf) | ||
| 1849 | { | ||
| 1850 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1851 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1852 | u8 ctl4; | ||
| 1853 | |||
| 1854 | ctl4 = data->block9[nr][LM93_PWM_CTL4]; | ||
| 1855 | return sprintf(buf,"%d\n",LM93_PWM_FREQ_FROM_REG(ctl4)); | ||
| 1856 | } | ||
| 1857 | |||
| 1858 | /* helper function - must grab data->update_lock before calling | ||
| 1859 | pwm is 0-1, indicating pwm1-pwm2 | ||
| 1860 | this disables smart tach for all tach channels bound to the given pwm */ | ||
| 1861 | static void lm93_disable_fan_smart_tach(struct i2c_client *client, | ||
| 1862 | struct lm93_data *data, int pwm) | ||
| 1863 | { | ||
| 1864 | int mapping = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); | ||
| 1865 | int mask; | ||
| 1866 | |||
| 1867 | /* collapse the mapping into a mask of enable bits */ | ||
| 1868 | mapping = (mapping >> pwm) & 0x55; | ||
| 1869 | mask = mapping & 0x01; | ||
| 1870 | mask |= (mapping & 0x04) >> 1; | ||
| 1871 | mask |= (mapping & 0x10) >> 2; | ||
| 1872 | mask |= (mapping & 0x40) >> 3; | ||
| 1873 | |||
| 1874 | /* disable smart tach according to the mask */ | ||
| 1875 | data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); | ||
| 1876 | data->sfc2 &= ~mask; | ||
| 1877 | lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); | ||
| 1878 | } | ||
| 1879 | |||
| 1880 | static ssize_t store_pwm_freq(struct device *dev, | ||
| 1881 | struct device_attribute *attr, | ||
| 1882 | const char *buf, size_t count) | ||
| 1883 | { | ||
| 1884 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1885 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1886 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1887 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1888 | u8 ctl4; | ||
| 1889 | |||
| 1890 | mutex_lock(&data->update_lock); | ||
| 1891 | ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); | ||
| 1892 | ctl4 = (ctl4 & 0xf8) | LM93_PWM_FREQ_TO_REG(val); | ||
| 1893 | data->block9[nr][LM93_PWM_CTL4] = ctl4; | ||
| 1894 | /* ctl4 == 0 -> 22.5KHz -> disable smart tach */ | ||
| 1895 | if (!ctl4) | ||
| 1896 | lm93_disable_fan_smart_tach(client, data, nr); | ||
| 1897 | lm93_write_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4), ctl4); | ||
| 1898 | mutex_unlock(&data->update_lock); | ||
| 1899 | return count; | ||
| 1900 | } | ||
| 1901 | |||
| 1902 | static SENSOR_DEVICE_ATTR(pwm1_freq, S_IWUSR | S_IRUGO, | ||
| 1903 | show_pwm_freq, store_pwm_freq, 0); | ||
| 1904 | static SENSOR_DEVICE_ATTR(pwm2_freq, S_IWUSR | S_IRUGO, | ||
| 1905 | show_pwm_freq, store_pwm_freq, 1); | ||
| 1906 | |||
| 1907 | static ssize_t show_pwm_auto_channels(struct device *dev, | ||
| 1908 | struct device_attribute *attr, char *buf) | ||
| 1909 | { | ||
| 1910 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1911 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1912 | return sprintf(buf,"%d\n",data->block9[nr][LM93_PWM_CTL1]); | ||
| 1913 | } | ||
| 1914 | |||
| 1915 | static ssize_t store_pwm_auto_channels(struct device *dev, | ||
| 1916 | struct device_attribute *attr, | ||
| 1917 | const char *buf, size_t count) | ||
| 1918 | { | ||
| 1919 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1920 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1921 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1922 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1923 | |||
| 1924 | mutex_lock(&data->update_lock); | ||
| 1925 | data->block9[nr][LM93_PWM_CTL1] = SENSORS_LIMIT(val, 0, 255); | ||
| 1926 | lm93_write_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL1), | ||
| 1927 | data->block9[nr][LM93_PWM_CTL1]); | ||
| 1928 | mutex_unlock(&data->update_lock); | ||
| 1929 | return count; | ||
| 1930 | } | ||
| 1931 | |||
| 1932 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels, S_IWUSR | S_IRUGO, | ||
| 1933 | show_pwm_auto_channels, store_pwm_auto_channels, 0); | ||
| 1934 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels, S_IWUSR | S_IRUGO, | ||
| 1935 | show_pwm_auto_channels, store_pwm_auto_channels, 1); | ||
| 1936 | |||
| 1937 | static ssize_t show_pwm_auto_spinup_min(struct device *dev, | ||
| 1938 | struct device_attribute *attr,char *buf) | ||
| 1939 | { | ||
| 1940 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1941 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1942 | u8 ctl3, ctl4; | ||
| 1943 | |||
| 1944 | ctl3 = data->block9[nr][LM93_PWM_CTL3]; | ||
| 1945 | ctl4 = data->block9[nr][LM93_PWM_CTL4]; | ||
| 1946 | return sprintf(buf,"%d\n", | ||
| 1947 | LM93_PWM_FROM_REG(ctl3 & 0x0f, (ctl4 & 0x07) ? | ||
| 1948 | LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ)); | ||
| 1949 | } | ||
| 1950 | |||
| 1951 | static ssize_t store_pwm_auto_spinup_min(struct device *dev, | ||
| 1952 | struct device_attribute *attr, | ||
| 1953 | const char *buf, size_t count) | ||
| 1954 | { | ||
| 1955 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1956 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1957 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1958 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1959 | u8 ctl3, ctl4; | ||
| 1960 | |||
| 1961 | mutex_lock(&data->update_lock); | ||
| 1962 | ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); | ||
| 1963 | ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); | ||
| 1964 | ctl3 = (ctl3 & 0xf0) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? | ||
| 1965 | LM93_PWM_MAP_LO_FREQ : | ||
| 1966 | LM93_PWM_MAP_HI_FREQ); | ||
| 1967 | data->block9[nr][LM93_PWM_CTL3] = ctl3; | ||
| 1968 | lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); | ||
| 1969 | mutex_unlock(&data->update_lock); | ||
| 1970 | return count; | ||
| 1971 | } | ||
| 1972 | |||
| 1973 | static SENSOR_DEVICE_ATTR(pwm1_auto_spinup_min, S_IWUSR | S_IRUGO, | ||
| 1974 | show_pwm_auto_spinup_min, | ||
| 1975 | store_pwm_auto_spinup_min, 0); | ||
| 1976 | static SENSOR_DEVICE_ATTR(pwm2_auto_spinup_min, S_IWUSR | S_IRUGO, | ||
| 1977 | show_pwm_auto_spinup_min, | ||
| 1978 | store_pwm_auto_spinup_min, 1); | ||
| 1979 | |||
| 1980 | static ssize_t show_pwm_auto_spinup_time(struct device *dev, | ||
| 1981 | struct device_attribute *attr, char *buf) | ||
| 1982 | { | ||
| 1983 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1984 | struct lm93_data *data = lm93_update_device(dev); | ||
| 1985 | return sprintf(buf,"%d\n",LM93_SPINUP_TIME_FROM_REG( | ||
| 1986 | data->block9[nr][LM93_PWM_CTL3])); | ||
| 1987 | } | ||
| 1988 | |||
| 1989 | static ssize_t store_pwm_auto_spinup_time(struct device *dev, | ||
| 1990 | struct device_attribute *attr, | ||
| 1991 | const char *buf, size_t count) | ||
| 1992 | { | ||
| 1993 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 1994 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1995 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 1996 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 1997 | u8 ctl3; | ||
| 1998 | |||
| 1999 | mutex_lock(&data->update_lock); | ||
| 2000 | ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); | ||
| 2001 | ctl3 = (ctl3 & 0x1f) | (LM93_SPINUP_TIME_TO_REG(val) << 5 & 0xe0); | ||
| 2002 | data->block9[nr][LM93_PWM_CTL3] = ctl3; | ||
| 2003 | lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); | ||
| 2004 | mutex_unlock(&data->update_lock); | ||
| 2005 | return count; | ||
| 2006 | } | ||
| 2007 | |||
| 2008 | static SENSOR_DEVICE_ATTR(pwm1_auto_spinup_time, S_IWUSR | S_IRUGO, | ||
| 2009 | show_pwm_auto_spinup_time, | ||
| 2010 | store_pwm_auto_spinup_time, 0); | ||
| 2011 | static SENSOR_DEVICE_ATTR(pwm2_auto_spinup_time, S_IWUSR | S_IRUGO, | ||
| 2012 | show_pwm_auto_spinup_time, | ||
| 2013 | store_pwm_auto_spinup_time, 1); | ||
| 2014 | |||
| 2015 | static ssize_t show_pwm_auto_prochot_ramp(struct device *dev, | ||
| 2016 | struct device_attribute *attr, char *buf) | ||
| 2017 | { | ||
| 2018 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2019 | return sprintf(buf,"%d\n", | ||
| 2020 | LM93_RAMP_FROM_REG(data->pwm_ramp_ctl >> 4 & 0x0f)); | ||
| 2021 | } | ||
| 2022 | |||
| 2023 | static ssize_t store_pwm_auto_prochot_ramp(struct device *dev, | ||
| 2024 | struct device_attribute *attr, | ||
| 2025 | const char *buf, size_t count) | ||
| 2026 | { | ||
| 2027 | struct i2c_client *client = to_i2c_client(dev); | ||
| 2028 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 2029 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 2030 | u8 ramp; | ||
| 2031 | |||
| 2032 | mutex_lock(&data->update_lock); | ||
| 2033 | ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); | ||
| 2034 | ramp = (ramp & 0x0f) | (LM93_RAMP_TO_REG(val) << 4 & 0xf0); | ||
| 2035 | lm93_write_byte(client, LM93_REG_PWM_RAMP_CTL, ramp); | ||
| 2036 | mutex_unlock(&data->update_lock); | ||
| 2037 | return count; | ||
| 2038 | } | ||
| 2039 | |||
| 2040 | static DEVICE_ATTR(pwm_auto_prochot_ramp, S_IRUGO | S_IWUSR, | ||
| 2041 | show_pwm_auto_prochot_ramp, | ||
| 2042 | store_pwm_auto_prochot_ramp); | ||
| 2043 | |||
| 2044 | static ssize_t show_pwm_auto_vrdhot_ramp(struct device *dev, | ||
| 2045 | struct device_attribute *attr, char *buf) | ||
| 2046 | { | ||
| 2047 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2048 | return sprintf(buf,"%d\n", | ||
| 2049 | LM93_RAMP_FROM_REG(data->pwm_ramp_ctl & 0x0f)); | ||
| 2050 | } | ||
| 2051 | |||
| 2052 | static ssize_t store_pwm_auto_vrdhot_ramp(struct device *dev, | ||
| 2053 | struct device_attribute *attr, | ||
| 2054 | const char *buf, size_t count) | ||
| 2055 | { | ||
| 2056 | struct i2c_client *client = to_i2c_client(dev); | ||
| 2057 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 2058 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 2059 | u8 ramp; | ||
| 2060 | |||
| 2061 | mutex_lock(&data->update_lock); | ||
| 2062 | ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); | ||
| 2063 | ramp = (ramp & 0xf0) | (LM93_RAMP_TO_REG(val) & 0x0f); | ||
| 2064 | lm93_write_byte(client, LM93_REG_PWM_RAMP_CTL, ramp); | ||
| 2065 | mutex_unlock(&data->update_lock); | ||
| 2066 | return 0; | ||
| 2067 | } | ||
| 2068 | |||
| 2069 | static DEVICE_ATTR(pwm_auto_vrdhot_ramp, S_IRUGO | S_IWUSR, | ||
| 2070 | show_pwm_auto_vrdhot_ramp, | ||
| 2071 | store_pwm_auto_vrdhot_ramp); | ||
| 2072 | |||
| 2073 | static ssize_t show_vid(struct device *dev, struct device_attribute *attr, | ||
| 2074 | char *buf) | ||
| 2075 | { | ||
| 2076 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2077 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2078 | return sprintf(buf,"%d\n",LM93_VID_FROM_REG(data->vid[nr])); | ||
| 2079 | } | ||
| 2080 | |||
| 2081 | static SENSOR_DEVICE_ATTR(vid1, S_IRUGO, show_vid, NULL, 0); | ||
| 2082 | static SENSOR_DEVICE_ATTR(vid2, S_IRUGO, show_vid, NULL, 1); | ||
| 2083 | |||
| 2084 | static ssize_t show_prochot(struct device *dev, struct device_attribute *attr, | ||
| 2085 | char *buf) | ||
| 2086 | { | ||
| 2087 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2088 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2089 | return sprintf(buf,"%d\n",data->block4[nr].cur); | ||
| 2090 | } | ||
| 2091 | |||
| 2092 | static SENSOR_DEVICE_ATTR(prochot1, S_IRUGO, show_prochot, NULL, 0); | ||
| 2093 | static SENSOR_DEVICE_ATTR(prochot2, S_IRUGO, show_prochot, NULL, 1); | ||
| 2094 | |||
| 2095 | static ssize_t show_prochot_avg(struct device *dev, | ||
| 2096 | struct device_attribute *attr, char *buf) | ||
| 2097 | { | ||
| 2098 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2099 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2100 | return sprintf(buf,"%d\n",data->block4[nr].avg); | ||
| 2101 | } | ||
| 2102 | |||
| 2103 | static SENSOR_DEVICE_ATTR(prochot1_avg, S_IRUGO, show_prochot_avg, NULL, 0); | ||
| 2104 | static SENSOR_DEVICE_ATTR(prochot2_avg, S_IRUGO, show_prochot_avg, NULL, 1); | ||
| 2105 | |||
| 2106 | static ssize_t show_prochot_max(struct device *dev, | ||
| 2107 | struct device_attribute *attr, char *buf) | ||
| 2108 | { | ||
| 2109 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2110 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2111 | return sprintf(buf,"%d\n",data->prochot_max[nr]); | ||
| 2112 | } | ||
| 2113 | |||
| 2114 | static ssize_t store_prochot_max(struct device *dev, | ||
| 2115 | struct device_attribute *attr, | ||
| 2116 | const char *buf, size_t count) | ||
| 2117 | { | ||
| 2118 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2119 | struct i2c_client *client = to_i2c_client(dev); | ||
| 2120 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 2121 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 2122 | |||
| 2123 | mutex_lock(&data->update_lock); | ||
| 2124 | data->prochot_max[nr] = LM93_PROCHOT_TO_REG(val); | ||
| 2125 | lm93_write_byte(client, LM93_REG_PROCHOT_MAX(nr), | ||
| 2126 | data->prochot_max[nr]); | ||
| 2127 | mutex_unlock(&data->update_lock); | ||
| 2128 | return count; | ||
| 2129 | } | ||
| 2130 | |||
| 2131 | static SENSOR_DEVICE_ATTR(prochot1_max, S_IWUSR | S_IRUGO, | ||
| 2132 | show_prochot_max, store_prochot_max, 0); | ||
| 2133 | static SENSOR_DEVICE_ATTR(prochot2_max, S_IWUSR | S_IRUGO, | ||
| 2134 | show_prochot_max, store_prochot_max, 1); | ||
| 2135 | |||
| 2136 | static const u8 prochot_override_mask[] = { 0x80, 0x40 }; | ||
| 2137 | |||
| 2138 | static ssize_t show_prochot_override(struct device *dev, | ||
| 2139 | struct device_attribute *attr, char *buf) | ||
| 2140 | { | ||
| 2141 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2142 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2143 | return sprintf(buf,"%d\n", | ||
| 2144 | (data->prochot_override & prochot_override_mask[nr]) ? 1 : 0); | ||
| 2145 | } | ||
| 2146 | |||
| 2147 | static ssize_t store_prochot_override(struct device *dev, | ||
| 2148 | struct device_attribute *attr, | ||
| 2149 | const char *buf, size_t count) | ||
| 2150 | { | ||
| 2151 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2152 | struct i2c_client *client = to_i2c_client(dev); | ||
| 2153 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 2154 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 2155 | |||
| 2156 | mutex_lock(&data->update_lock); | ||
| 2157 | if (val) | ||
| 2158 | data->prochot_override |= prochot_override_mask[nr]; | ||
| 2159 | else | ||
| 2160 | data->prochot_override &= (~prochot_override_mask[nr]); | ||
| 2161 | lm93_write_byte(client, LM93_REG_PROCHOT_OVERRIDE, | ||
| 2162 | data->prochot_override); | ||
| 2163 | mutex_unlock(&data->update_lock); | ||
| 2164 | return count; | ||
| 2165 | } | ||
| 2166 | |||
| 2167 | static SENSOR_DEVICE_ATTR(prochot1_override, S_IWUSR | S_IRUGO, | ||
| 2168 | show_prochot_override, store_prochot_override, 0); | ||
| 2169 | static SENSOR_DEVICE_ATTR(prochot2_override, S_IWUSR | S_IRUGO, | ||
| 2170 | show_prochot_override, store_prochot_override, 1); | ||
| 2171 | |||
| 2172 | static ssize_t show_prochot_interval(struct device *dev, | ||
| 2173 | struct device_attribute *attr, char *buf) | ||
| 2174 | { | ||
| 2175 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2176 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2177 | u8 tmp; | ||
| 2178 | if (nr==1) | ||
| 2179 | tmp = (data->prochot_interval & 0xf0) >> 4; | ||
| 2180 | else | ||
| 2181 | tmp = data->prochot_interval & 0x0f; | ||
| 2182 | return sprintf(buf,"%d\n",LM93_INTERVAL_FROM_REG(tmp)); | ||
| 2183 | } | ||
| 2184 | |||
| 2185 | static ssize_t store_prochot_interval(struct device *dev, | ||
| 2186 | struct device_attribute *attr, | ||
| 2187 | const char *buf, size_t count) | ||
| 2188 | { | ||
| 2189 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2190 | struct i2c_client *client = to_i2c_client(dev); | ||
| 2191 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 2192 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 2193 | u8 tmp; | ||
| 2194 | |||
| 2195 | mutex_lock(&data->update_lock); | ||
| 2196 | tmp = lm93_read_byte(client, LM93_REG_PROCHOT_INTERVAL); | ||
| 2197 | if (nr==1) | ||
| 2198 | tmp = (tmp & 0x0f) | (LM93_INTERVAL_TO_REG(val) << 4); | ||
| 2199 | else | ||
| 2200 | tmp = (tmp & 0xf0) | LM93_INTERVAL_TO_REG(val); | ||
| 2201 | data->prochot_interval = tmp; | ||
| 2202 | lm93_write_byte(client, LM93_REG_PROCHOT_INTERVAL, tmp); | ||
| 2203 | mutex_unlock(&data->update_lock); | ||
| 2204 | return count; | ||
| 2205 | } | ||
| 2206 | |||
| 2207 | static SENSOR_DEVICE_ATTR(prochot1_interval, S_IWUSR | S_IRUGO, | ||
| 2208 | show_prochot_interval, store_prochot_interval, 0); | ||
| 2209 | static SENSOR_DEVICE_ATTR(prochot2_interval, S_IWUSR | S_IRUGO, | ||
| 2210 | show_prochot_interval, store_prochot_interval, 1); | ||
| 2211 | |||
| 2212 | static ssize_t show_prochot_override_duty_cycle(struct device *dev, | ||
| 2213 | struct device_attribute *attr, | ||
| 2214 | char *buf) | ||
| 2215 | { | ||
| 2216 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2217 | return sprintf(buf,"%d\n",data->prochot_override & 0x0f); | ||
| 2218 | } | ||
| 2219 | |||
| 2220 | static ssize_t store_prochot_override_duty_cycle(struct device *dev, | ||
| 2221 | struct device_attribute *attr, | ||
| 2222 | const char *buf, size_t count) | ||
| 2223 | { | ||
| 2224 | struct i2c_client *client = to_i2c_client(dev); | ||
| 2225 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 2226 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 2227 | |||
| 2228 | mutex_lock(&data->update_lock); | ||
| 2229 | data->prochot_override = (data->prochot_override & 0xf0) | | ||
| 2230 | SENSORS_LIMIT(val, 0, 15); | ||
| 2231 | lm93_write_byte(client, LM93_REG_PROCHOT_OVERRIDE, | ||
| 2232 | data->prochot_override); | ||
| 2233 | mutex_unlock(&data->update_lock); | ||
| 2234 | return count; | ||
| 2235 | } | ||
| 2236 | |||
| 2237 | static DEVICE_ATTR(prochot_override_duty_cycle, S_IRUGO | S_IWUSR, | ||
| 2238 | show_prochot_override_duty_cycle, | ||
| 2239 | store_prochot_override_duty_cycle); | ||
| 2240 | |||
| 2241 | static ssize_t show_prochot_short(struct device *dev, | ||
| 2242 | struct device_attribute *attr, char *buf) | ||
| 2243 | { | ||
| 2244 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2245 | return sprintf(buf,"%d\n",(data->config & 0x10) ? 1 : 0); | ||
| 2246 | } | ||
| 2247 | |||
| 2248 | static ssize_t store_prochot_short(struct device *dev, | ||
| 2249 | struct device_attribute *attr, | ||
| 2250 | const char *buf, size_t count) | ||
| 2251 | { | ||
| 2252 | struct i2c_client *client = to_i2c_client(dev); | ||
| 2253 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 2254 | u32 val = simple_strtoul(buf, NULL, 10); | ||
| 2255 | |||
| 2256 | mutex_lock(&data->update_lock); | ||
| 2257 | if (val) | ||
| 2258 | data->config |= 0x10; | ||
| 2259 | else | ||
| 2260 | data->config &= ~0x10; | ||
| 2261 | lm93_write_byte(client, LM93_REG_CONFIG, data->config); | ||
| 2262 | mutex_unlock(&data->update_lock); | ||
| 2263 | return count; | ||
| 2264 | } | ||
| 2265 | |||
| 2266 | static DEVICE_ATTR(prochot_short, S_IRUGO | S_IWUSR, | ||
| 2267 | show_prochot_short, store_prochot_short); | ||
| 2268 | |||
| 2269 | static ssize_t show_vrdhot(struct device *dev, struct device_attribute *attr, | ||
| 2270 | char *buf) | ||
| 2271 | { | ||
| 2272 | int nr = (to_sensor_dev_attr(attr))->index; | ||
| 2273 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2274 | return sprintf(buf,"%d\n", | ||
| 2275 | data->block1.host_status_1 & (1 << (nr+4)) ? 1 : 0); | ||
| 2276 | } | ||
| 2277 | |||
| 2278 | static SENSOR_DEVICE_ATTR(vrdhot1, S_IRUGO, show_vrdhot, NULL, 0); | ||
| 2279 | static SENSOR_DEVICE_ATTR(vrdhot2, S_IRUGO, show_vrdhot, NULL, 1); | ||
| 2280 | |||
| 2281 | static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, | ||
| 2282 | char *buf) | ||
| 2283 | { | ||
| 2284 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2285 | return sprintf(buf,"%d\n",LM93_GPI_FROM_REG(data->gpi)); | ||
| 2286 | } | ||
| 2287 | |||
| 2288 | static DEVICE_ATTR(gpio, S_IRUGO, show_gpio, NULL); | ||
| 2289 | |||
| 2290 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | ||
| 2291 | char *buf) | ||
| 2292 | { | ||
| 2293 | struct lm93_data *data = lm93_update_device(dev); | ||
| 2294 | return sprintf(buf,"%d\n",LM93_ALARMS_FROM_REG(data->block1)); | ||
| 2295 | } | ||
| 2296 | |||
| 2297 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
| 2298 | |||
| 2299 | static struct attribute *lm93_attrs[] = { | ||
| 2300 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
| 2301 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
| 2302 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
| 2303 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
| 2304 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
| 2305 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
| 2306 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
| 2307 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
| 2308 | &sensor_dev_attr_in9_input.dev_attr.attr, | ||
| 2309 | &sensor_dev_attr_in10_input.dev_attr.attr, | ||
| 2310 | &sensor_dev_attr_in11_input.dev_attr.attr, | ||
| 2311 | &sensor_dev_attr_in12_input.dev_attr.attr, | ||
| 2312 | &sensor_dev_attr_in13_input.dev_attr.attr, | ||
| 2313 | &sensor_dev_attr_in14_input.dev_attr.attr, | ||
| 2314 | &sensor_dev_attr_in15_input.dev_attr.attr, | ||
| 2315 | &sensor_dev_attr_in16_input.dev_attr.attr, | ||
| 2316 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
| 2317 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
| 2318 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
| 2319 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
| 2320 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
| 2321 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
| 2322 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
| 2323 | &sensor_dev_attr_in8_min.dev_attr.attr, | ||
| 2324 | &sensor_dev_attr_in9_min.dev_attr.attr, | ||
| 2325 | &sensor_dev_attr_in10_min.dev_attr.attr, | ||
| 2326 | &sensor_dev_attr_in11_min.dev_attr.attr, | ||
| 2327 | &sensor_dev_attr_in12_min.dev_attr.attr, | ||
| 2328 | &sensor_dev_attr_in13_min.dev_attr.attr, | ||
| 2329 | &sensor_dev_attr_in14_min.dev_attr.attr, | ||
| 2330 | &sensor_dev_attr_in15_min.dev_attr.attr, | ||
| 2331 | &sensor_dev_attr_in16_min.dev_attr.attr, | ||
| 2332 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
| 2333 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
| 2334 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
| 2335 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
| 2336 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
| 2337 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
| 2338 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
| 2339 | &sensor_dev_attr_in8_max.dev_attr.attr, | ||
| 2340 | &sensor_dev_attr_in9_max.dev_attr.attr, | ||
| 2341 | &sensor_dev_attr_in10_max.dev_attr.attr, | ||
| 2342 | &sensor_dev_attr_in11_max.dev_attr.attr, | ||
| 2343 | &sensor_dev_attr_in12_max.dev_attr.attr, | ||
| 2344 | &sensor_dev_attr_in13_max.dev_attr.attr, | ||
| 2345 | &sensor_dev_attr_in14_max.dev_attr.attr, | ||
| 2346 | &sensor_dev_attr_in15_max.dev_attr.attr, | ||
| 2347 | &sensor_dev_attr_in16_max.dev_attr.attr, | ||
| 2348 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
| 2349 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
| 2350 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
| 2351 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
| 2352 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
| 2353 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
| 2354 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
| 2355 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
| 2356 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
| 2357 | &sensor_dev_attr_temp1_auto_base.dev_attr.attr, | ||
| 2358 | &sensor_dev_attr_temp2_auto_base.dev_attr.attr, | ||
| 2359 | &sensor_dev_attr_temp3_auto_base.dev_attr.attr, | ||
| 2360 | &sensor_dev_attr_temp1_auto_boost.dev_attr.attr, | ||
| 2361 | &sensor_dev_attr_temp2_auto_boost.dev_attr.attr, | ||
| 2362 | &sensor_dev_attr_temp3_auto_boost.dev_attr.attr, | ||
| 2363 | &sensor_dev_attr_temp1_auto_boost_hyst.dev_attr.attr, | ||
| 2364 | &sensor_dev_attr_temp2_auto_boost_hyst.dev_attr.attr, | ||
| 2365 | &sensor_dev_attr_temp3_auto_boost_hyst.dev_attr.attr, | ||
| 2366 | &sensor_dev_attr_temp1_auto_offset1.dev_attr.attr, | ||
| 2367 | &sensor_dev_attr_temp1_auto_offset2.dev_attr.attr, | ||
| 2368 | &sensor_dev_attr_temp1_auto_offset3.dev_attr.attr, | ||
| 2369 | &sensor_dev_attr_temp1_auto_offset4.dev_attr.attr, | ||
| 2370 | &sensor_dev_attr_temp1_auto_offset5.dev_attr.attr, | ||
| 2371 | &sensor_dev_attr_temp1_auto_offset6.dev_attr.attr, | ||
| 2372 | &sensor_dev_attr_temp1_auto_offset7.dev_attr.attr, | ||
| 2373 | &sensor_dev_attr_temp1_auto_offset8.dev_attr.attr, | ||
| 2374 | &sensor_dev_attr_temp1_auto_offset9.dev_attr.attr, | ||
| 2375 | &sensor_dev_attr_temp1_auto_offset10.dev_attr.attr, | ||
| 2376 | &sensor_dev_attr_temp1_auto_offset11.dev_attr.attr, | ||
| 2377 | &sensor_dev_attr_temp1_auto_offset12.dev_attr.attr, | ||
| 2378 | &sensor_dev_attr_temp2_auto_offset1.dev_attr.attr, | ||
| 2379 | &sensor_dev_attr_temp2_auto_offset2.dev_attr.attr, | ||
| 2380 | &sensor_dev_attr_temp2_auto_offset3.dev_attr.attr, | ||
| 2381 | &sensor_dev_attr_temp2_auto_offset4.dev_attr.attr, | ||
| 2382 | &sensor_dev_attr_temp2_auto_offset5.dev_attr.attr, | ||
| 2383 | &sensor_dev_attr_temp2_auto_offset6.dev_attr.attr, | ||
| 2384 | &sensor_dev_attr_temp2_auto_offset7.dev_attr.attr, | ||
| 2385 | &sensor_dev_attr_temp2_auto_offset8.dev_attr.attr, | ||
| 2386 | &sensor_dev_attr_temp2_auto_offset9.dev_attr.attr, | ||
| 2387 | &sensor_dev_attr_temp2_auto_offset10.dev_attr.attr, | ||
| 2388 | &sensor_dev_attr_temp2_auto_offset11.dev_attr.attr, | ||
| 2389 | &sensor_dev_attr_temp2_auto_offset12.dev_attr.attr, | ||
| 2390 | &sensor_dev_attr_temp3_auto_offset1.dev_attr.attr, | ||
| 2391 | &sensor_dev_attr_temp3_auto_offset2.dev_attr.attr, | ||
| 2392 | &sensor_dev_attr_temp3_auto_offset3.dev_attr.attr, | ||
| 2393 | &sensor_dev_attr_temp3_auto_offset4.dev_attr.attr, | ||
| 2394 | &sensor_dev_attr_temp3_auto_offset5.dev_attr.attr, | ||
| 2395 | &sensor_dev_attr_temp3_auto_offset6.dev_attr.attr, | ||
| 2396 | &sensor_dev_attr_temp3_auto_offset7.dev_attr.attr, | ||
| 2397 | &sensor_dev_attr_temp3_auto_offset8.dev_attr.attr, | ||
| 2398 | &sensor_dev_attr_temp3_auto_offset9.dev_attr.attr, | ||
| 2399 | &sensor_dev_attr_temp3_auto_offset10.dev_attr.attr, | ||
| 2400 | &sensor_dev_attr_temp3_auto_offset11.dev_attr.attr, | ||
| 2401 | &sensor_dev_attr_temp3_auto_offset12.dev_attr.attr, | ||
| 2402 | &sensor_dev_attr_temp1_auto_pwm_min.dev_attr.attr, | ||
| 2403 | &sensor_dev_attr_temp2_auto_pwm_min.dev_attr.attr, | ||
| 2404 | &sensor_dev_attr_temp3_auto_pwm_min.dev_attr.attr, | ||
| 2405 | &sensor_dev_attr_temp1_auto_offset_hyst.dev_attr.attr, | ||
| 2406 | &sensor_dev_attr_temp2_auto_offset_hyst.dev_attr.attr, | ||
| 2407 | &sensor_dev_attr_temp3_auto_offset_hyst.dev_attr.attr, | ||
| 2408 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
| 2409 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
| 2410 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
| 2411 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
| 2412 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
| 2413 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
| 2414 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
| 2415 | &sensor_dev_attr_fan4_min.dev_attr.attr, | ||
| 2416 | &sensor_dev_attr_fan1_smart_tach.dev_attr.attr, | ||
| 2417 | &sensor_dev_attr_fan2_smart_tach.dev_attr.attr, | ||
| 2418 | &sensor_dev_attr_fan3_smart_tach.dev_attr.attr, | ||
| 2419 | &sensor_dev_attr_fan4_smart_tach.dev_attr.attr, | ||
| 2420 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
| 2421 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
| 2422 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
| 2423 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
| 2424 | &sensor_dev_attr_pwm1_freq.dev_attr.attr, | ||
| 2425 | &sensor_dev_attr_pwm2_freq.dev_attr.attr, | ||
| 2426 | &sensor_dev_attr_pwm1_auto_channels.dev_attr.attr, | ||
| 2427 | &sensor_dev_attr_pwm2_auto_channels.dev_attr.attr, | ||
| 2428 | &sensor_dev_attr_pwm1_auto_spinup_min.dev_attr.attr, | ||
| 2429 | &sensor_dev_attr_pwm2_auto_spinup_min.dev_attr.attr, | ||
| 2430 | &sensor_dev_attr_pwm1_auto_spinup_time.dev_attr.attr, | ||
| 2431 | &sensor_dev_attr_pwm2_auto_spinup_time.dev_attr.attr, | ||
| 2432 | &dev_attr_pwm_auto_prochot_ramp.attr, | ||
| 2433 | &dev_attr_pwm_auto_vrdhot_ramp.attr, | ||
| 2434 | &sensor_dev_attr_vid1.dev_attr.attr, | ||
| 2435 | &sensor_dev_attr_vid2.dev_attr.attr, | ||
| 2436 | &sensor_dev_attr_prochot1.dev_attr.attr, | ||
| 2437 | &sensor_dev_attr_prochot2.dev_attr.attr, | ||
| 2438 | &sensor_dev_attr_prochot1_avg.dev_attr.attr, | ||
| 2439 | &sensor_dev_attr_prochot2_avg.dev_attr.attr, | ||
| 2440 | &sensor_dev_attr_prochot1_max.dev_attr.attr, | ||
| 2441 | &sensor_dev_attr_prochot2_max.dev_attr.attr, | ||
| 2442 | &sensor_dev_attr_prochot1_override.dev_attr.attr, | ||
| 2443 | &sensor_dev_attr_prochot2_override.dev_attr.attr, | ||
| 2444 | &sensor_dev_attr_prochot1_interval.dev_attr.attr, | ||
| 2445 | &sensor_dev_attr_prochot2_interval.dev_attr.attr, | ||
| 2446 | &dev_attr_prochot_override_duty_cycle.attr, | ||
| 2447 | &dev_attr_prochot_short.attr, | ||
| 2448 | &sensor_dev_attr_vrdhot1.dev_attr.attr, | ||
| 2449 | &sensor_dev_attr_vrdhot2.dev_attr.attr, | ||
| 2450 | &dev_attr_gpio.attr, | ||
| 2451 | &dev_attr_alarms.attr, | ||
| 2452 | NULL | ||
| 2453 | }; | ||
| 2454 | |||
| 2455 | static struct attribute_group lm93_attr_grp = { | ||
| 2456 | .attrs = lm93_attrs, | ||
| 2457 | }; | ||
| 2458 | |||
| 2459 | static void lm93_init_client(struct i2c_client *client) | ||
| 2460 | { | ||
| 2461 | int i; | ||
| 2462 | u8 reg; | ||
| 2463 | |||
| 2464 | /* configure VID pin input thresholds */ | ||
| 2465 | reg = lm93_read_byte(client, LM93_REG_GPI_VID_CTL); | ||
| 2466 | lm93_write_byte(client, LM93_REG_GPI_VID_CTL, | ||
| 2467 | reg | (vid_agtl ? 0x03 : 0x00)); | ||
| 2468 | |||
| 2469 | if (init) { | ||
| 2470 | /* enable #ALERT pin */ | ||
| 2471 | reg = lm93_read_byte(client, LM93_REG_CONFIG); | ||
| 2472 | lm93_write_byte(client, LM93_REG_CONFIG, reg | 0x08); | ||
| 2473 | |||
| 2474 | /* enable ASF mode for BMC status registers */ | ||
| 2475 | reg = lm93_read_byte(client, LM93_REG_STATUS_CONTROL); | ||
| 2476 | lm93_write_byte(client, LM93_REG_STATUS_CONTROL, reg | 0x02); | ||
| 2477 | |||
| 2478 | /* set sleep state to S0 */ | ||
| 2479 | lm93_write_byte(client, LM93_REG_SLEEP_CONTROL, 0); | ||
| 2480 | |||
| 2481 | /* unmask #VRDHOT and dynamic VCCP (if nec) error events */ | ||
| 2482 | reg = lm93_read_byte(client, LM93_REG_MISC_ERR_MASK); | ||
| 2483 | reg &= ~0x03; | ||
| 2484 | reg &= ~(vccp_limit_type[0] ? 0x10 : 0); | ||
| 2485 | reg &= ~(vccp_limit_type[1] ? 0x20 : 0); | ||
| 2486 | lm93_write_byte(client, LM93_REG_MISC_ERR_MASK, reg); | ||
| 2487 | } | ||
| 2488 | |||
| 2489 | /* start monitoring */ | ||
| 2490 | reg = lm93_read_byte(client, LM93_REG_CONFIG); | ||
| 2491 | lm93_write_byte(client, LM93_REG_CONFIG, reg | 0x01); | ||
| 2492 | |||
| 2493 | /* spin until ready */ | ||
| 2494 | for (i=0; i<20; i++) { | ||
| 2495 | msleep(10); | ||
| 2496 | if ((lm93_read_byte(client, LM93_REG_CONFIG) & 0x80) == 0x80) | ||
| 2497 | return; | ||
| 2498 | } | ||
| 2499 | |||
| 2500 | dev_warn(&client->dev,"timed out waiting for sensor " | ||
| 2501 | "chip to signal ready!\n"); | ||
| 2502 | } | ||
| 2503 | |||
| 2504 | static int lm93_detect(struct i2c_adapter *adapter, int address, int kind) | ||
| 2505 | { | ||
| 2506 | struct lm93_data *data; | ||
| 2507 | struct i2c_client *client; | ||
| 2508 | |||
| 2509 | int err = -ENODEV, func; | ||
| 2510 | void (*update)(struct lm93_data *, struct i2c_client *); | ||
| 2511 | |||
| 2512 | /* choose update routine based on bus capabilities */ | ||
| 2513 | func = i2c_get_functionality(adapter); | ||
| 2514 | if ( ((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) && | ||
| 2515 | (!disable_block) ) { | ||
| 2516 | dev_dbg(&adapter->dev,"using SMBus block data transactions\n"); | ||
| 2517 | update = lm93_update_client_full; | ||
| 2518 | } else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) { | ||
| 2519 | dev_dbg(&adapter->dev,"disabled SMBus block data " | ||
| 2520 | "transactions\n"); | ||
| 2521 | update = lm93_update_client_min; | ||
| 2522 | } else { | ||
| 2523 | dev_dbg(&adapter->dev,"detect failed, " | ||
| 2524 | "smbus byte and/or word data not supported!\n"); | ||
| 2525 | goto err_out; | ||
| 2526 | } | ||
| 2527 | |||
| 2528 | /* OK. For now, we presume we have a valid client. We now create the | ||
| 2529 | client structure, even though we cannot fill it completely yet. | ||
| 2530 | But it allows us to access lm78_{read,write}_value. */ | ||
| 2531 | |||
| 2532 | if ( !(data = kzalloc(sizeof(struct lm93_data), GFP_KERNEL))) { | ||
| 2533 | dev_dbg(&adapter->dev,"out of memory!\n"); | ||
| 2534 | err = -ENOMEM; | ||
| 2535 | goto err_out; | ||
| 2536 | } | ||
| 2537 | |||
| 2538 | client = &data->client; | ||
| 2539 | i2c_set_clientdata(client, data); | ||
| 2540 | client->addr = address; | ||
| 2541 | client->adapter = adapter; | ||
| 2542 | client->driver = &lm93_driver; | ||
| 2543 | |||
| 2544 | /* detection */ | ||
| 2545 | if (kind < 0) { | ||
| 2546 | int mfr = lm93_read_byte(client, LM93_REG_MFR_ID); | ||
| 2547 | |||
| 2548 | if (mfr != 0x01) { | ||
| 2549 | dev_dbg(&adapter->dev,"detect failed, " | ||
| 2550 | "bad manufacturer id 0x%02x!\n", mfr); | ||
| 2551 | goto err_free; | ||
| 2552 | } | ||
| 2553 | } | ||
| 2554 | |||
| 2555 | if (kind <= 0) { | ||
| 2556 | int ver = lm93_read_byte(client, LM93_REG_VER); | ||
| 2557 | |||
| 2558 | if ((ver == LM93_MFR_ID) || (ver == LM93_MFR_ID_PROTOTYPE)) { | ||
| 2559 | kind = lm93; | ||
| 2560 | } else { | ||
| 2561 | dev_dbg(&adapter->dev,"detect failed, " | ||
| 2562 | "bad version id 0x%02x!\n", ver); | ||
| 2563 | if (kind == 0) | ||
| 2564 | dev_dbg(&adapter->dev, | ||
| 2565 | "(ignored 'force' parameter)\n"); | ||
| 2566 | goto err_free; | ||
| 2567 | } | ||
| 2568 | } | ||
| 2569 | |||
| 2570 | /* fill in remaining client fields */ | ||
| 2571 | strlcpy(client->name, "lm93", I2C_NAME_SIZE); | ||
| 2572 | dev_dbg(&adapter->dev,"loading %s at %d,0x%02x\n", | ||
| 2573 | client->name, i2c_adapter_id(client->adapter), | ||
| 2574 | client->addr); | ||
| 2575 | |||
| 2576 | /* housekeeping */ | ||
| 2577 | data->valid = 0; | ||
| 2578 | data->update = update; | ||
| 2579 | mutex_init(&data->update_lock); | ||
| 2580 | |||
| 2581 | /* tell the I2C layer a new client has arrived */ | ||
| 2582 | if ((err = i2c_attach_client(client))) | ||
| 2583 | goto err_free; | ||
| 2584 | |||
| 2585 | /* initialize the chip */ | ||
| 2586 | lm93_init_client(client); | ||
| 2587 | |||
| 2588 | err = sysfs_create_group(&client->dev.kobj, &lm93_attr_grp); | ||
| 2589 | if (err) | ||
| 2590 | goto err_detach; | ||
| 2591 | |||
| 2592 | /* Register hwmon driver class */ | ||
| 2593 | data->class_dev = hwmon_device_register(&client->dev); | ||
| 2594 | if ( !IS_ERR(data->class_dev)) | ||
| 2595 | return 0; | ||
| 2596 | |||
| 2597 | err = PTR_ERR(data->class_dev); | ||
| 2598 | dev_err(&client->dev, "error registering hwmon device.\n"); | ||
| 2599 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); | ||
| 2600 | err_detach: | ||
| 2601 | i2c_detach_client(client); | ||
| 2602 | err_free: | ||
| 2603 | kfree(data); | ||
| 2604 | err_out: | ||
| 2605 | return err; | ||
| 2606 | } | ||
| 2607 | |||
| 2608 | /* This function is called when: | ||
| 2609 | * lm93_driver is inserted (when this module is loaded), for each | ||
| 2610 | available adapter | ||
| 2611 | * when a new adapter is inserted (and lm93_driver is still present) */ | ||
| 2612 | static int lm93_attach_adapter(struct i2c_adapter *adapter) | ||
| 2613 | { | ||
| 2614 | return i2c_probe(adapter, &addr_data, lm93_detect); | ||
| 2615 | } | ||
| 2616 | |||
| 2617 | static int lm93_detach_client(struct i2c_client *client) | ||
| 2618 | { | ||
| 2619 | struct lm93_data *data = i2c_get_clientdata(client); | ||
| 2620 | int err = 0; | ||
| 2621 | |||
| 2622 | hwmon_device_unregister(data->class_dev); | ||
| 2623 | sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); | ||
| 2624 | |||
| 2625 | err = i2c_detach_client(client); | ||
| 2626 | if (!err) | ||
| 2627 | kfree(data); | ||
| 2628 | return err; | ||
| 2629 | } | ||
| 2630 | |||
| 2631 | static struct i2c_driver lm93_driver = { | ||
| 2632 | .driver = { | ||
| 2633 | .name = "lm93", | ||
| 2634 | }, | ||
| 2635 | .attach_adapter = lm93_attach_adapter, | ||
| 2636 | .detach_client = lm93_detach_client, | ||
| 2637 | }; | ||
| 2638 | |||
| 2639 | static int __init lm93_init(void) | ||
| 2640 | { | ||
| 2641 | return i2c_add_driver(&lm93_driver); | ||
| 2642 | } | ||
| 2643 | |||
| 2644 | static void __exit lm93_exit(void) | ||
| 2645 | { | ||
| 2646 | i2c_del_driver(&lm93_driver); | ||
| 2647 | } | ||
| 2648 | |||
| 2649 | MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, " | ||
| 2650 | "Hans J. Koch <hjk@linutronix.de"); | ||
| 2651 | MODULE_DESCRIPTION("LM93 driver"); | ||
| 2652 | MODULE_LICENSE("GPL"); | ||
| 2653 | |||
| 2654 | module_init(lm93_init); | ||
| 2655 | module_exit(lm93_exit); | ||
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index c8a21be09d87..cb72526c346a 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * pc87360.c - Part of lm_sensors, Linux kernel modules | 2 | * pc87360.c - Part of lm_sensors, Linux kernel modules |
| 3 | * for hardware monitoring | 3 | * for hardware monitoring |
| 4 | * Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> | 4 | * Copyright (C) 2004, 2007 Jean Delvare <khali@linux-fr.org> |
| 5 | * | 5 | * |
| 6 | * Copied from smsc47m1.c: | 6 | * Copied from smsc47m1.c: |
| 7 | * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> | 7 | * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> |
| @@ -37,8 +37,7 @@ | |||
| 37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <linux/jiffies.h> | 39 | #include <linux/jiffies.h> |
| 40 | #include <linux/i2c.h> | 40 | #include <linux/platform_device.h> |
| 41 | #include <linux/i2c-isa.h> | ||
| 42 | #include <linux/hwmon.h> | 41 | #include <linux/hwmon.h> |
| 43 | #include <linux/hwmon-sysfs.h> | 42 | #include <linux/hwmon-sysfs.h> |
| 44 | #include <linux/hwmon-vid.h> | 43 | #include <linux/hwmon-vid.h> |
| @@ -47,12 +46,10 @@ | |||
| 47 | #include <asm/io.h> | 46 | #include <asm/io.h> |
| 48 | 47 | ||
| 49 | static u8 devid; | 48 | static u8 devid; |
| 50 | static unsigned short address; | 49 | static struct platform_device *pdev; |
| 51 | static unsigned short extra_isa[3]; | 50 | static unsigned short extra_isa[3]; |
| 52 | static u8 confreg[4]; | 51 | static u8 confreg[4]; |
| 53 | 52 | ||
| 54 | enum chips { any_chip, pc87360, pc87363, pc87364, pc87365, pc87366 }; | ||
| 55 | |||
| 56 | static int init = 1; | 53 | static int init = 1; |
| 57 | module_param(init, int, 0); | 54 | module_param(init, int, 0); |
| 58 | MODULE_PARM_DESC(init, | 55 | MODULE_PARM_DESC(init, |
| @@ -178,11 +175,11 @@ static inline u8 PWM_TO_REG(int val, int inv) | |||
| 178 | ((val) + 500) / 1000) | 175 | ((val) + 500) / 1000) |
| 179 | 176 | ||
| 180 | /* | 177 | /* |
| 181 | * Client data (each client gets its own) | 178 | * Device data |
| 182 | */ | 179 | */ |
| 183 | 180 | ||
| 184 | struct pc87360_data { | 181 | struct pc87360_data { |
| 185 | struct i2c_client client; | 182 | const char *name; |
| 186 | struct class_device *class_dev; | 183 | struct class_device *class_dev; |
| 187 | struct mutex lock; | 184 | struct mutex lock; |
| 188 | struct mutex update_lock; | 185 | struct mutex update_lock; |
| @@ -222,27 +219,28 @@ struct pc87360_data { | |||
| 222 | * Functions declaration | 219 | * Functions declaration |
| 223 | */ | 220 | */ |
| 224 | 221 | ||
| 225 | static int pc87360_detect(struct i2c_adapter *adapter); | 222 | static int pc87360_probe(struct platform_device *pdev); |
| 226 | static int pc87360_detach_client(struct i2c_client *client); | 223 | static int pc87360_remove(struct platform_device *pdev); |
| 227 | 224 | ||
| 228 | static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, | 225 | static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, |
| 229 | u8 reg); | 226 | u8 reg); |
| 230 | static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, | 227 | static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, |
| 231 | u8 reg, u8 value); | 228 | u8 reg, u8 value); |
| 232 | static void pc87360_init_client(struct i2c_client *client, int use_thermistors); | 229 | static void pc87360_init_device(struct platform_device *pdev, |
| 230 | int use_thermistors); | ||
| 233 | static struct pc87360_data *pc87360_update_device(struct device *dev); | 231 | static struct pc87360_data *pc87360_update_device(struct device *dev); |
| 234 | 232 | ||
| 235 | /* | 233 | /* |
| 236 | * Driver data (common to all clients) | 234 | * Driver data |
| 237 | */ | 235 | */ |
| 238 | 236 | ||
| 239 | static struct i2c_driver pc87360_driver = { | 237 | static struct platform_driver pc87360_driver = { |
| 240 | .driver = { | 238 | .driver = { |
| 241 | .owner = THIS_MODULE, | 239 | .owner = THIS_MODULE, |
| 242 | .name = "pc87360", | 240 | .name = "pc87360", |
| 243 | }, | 241 | }, |
| 244 | .attach_adapter = pc87360_detect, | 242 | .probe = pc87360_probe, |
| 245 | .detach_client = pc87360_detach_client, | 243 | .remove = __devexit_p(pc87360_remove), |
| 246 | }; | 244 | }; |
| 247 | 245 | ||
| 248 | /* | 246 | /* |
| @@ -281,8 +279,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr, | |||
| 281 | size_t count) | 279 | size_t count) |
| 282 | { | 280 | { |
| 283 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 281 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 284 | struct i2c_client *client = to_i2c_client(dev); | 282 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 285 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 286 | long fan_min = simple_strtol(buf, NULL, 10); | 283 | long fan_min = simple_strtol(buf, NULL, 10); |
| 287 | 284 | ||
| 288 | mutex_lock(&data->update_lock); | 285 | mutex_lock(&data->update_lock); |
| @@ -347,8 +344,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, con | |||
| 347 | size_t count) | 344 | size_t count) |
| 348 | { | 345 | { |
| 349 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 346 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 350 | struct i2c_client *client = to_i2c_client(dev); | 347 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 351 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 352 | long val = simple_strtol(buf, NULL, 10); | 348 | long val = simple_strtol(buf, NULL, 10); |
| 353 | 349 | ||
| 354 | mutex_lock(&data->update_lock); | 350 | mutex_lock(&data->update_lock); |
| @@ -410,8 +406,7 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, | |||
| 410 | size_t count) | 406 | size_t count) |
| 411 | { | 407 | { |
| 412 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 408 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 413 | struct i2c_client *client = to_i2c_client(dev); | 409 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 414 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 415 | long val = simple_strtol(buf, NULL, 10); | 410 | long val = simple_strtol(buf, NULL, 10); |
| 416 | 411 | ||
| 417 | mutex_lock(&data->update_lock); | 412 | mutex_lock(&data->update_lock); |
| @@ -425,8 +420,7 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, | |||
| 425 | size_t count) | 420 | size_t count) |
| 426 | { | 421 | { |
| 427 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 422 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 428 | struct i2c_client *client = to_i2c_client(dev); | 423 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 429 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 430 | long val = simple_strtol(buf, NULL, 10); | 424 | long val = simple_strtol(buf, NULL, 10); |
| 431 | 425 | ||
| 432 | mutex_lock(&data->update_lock); | 426 | mutex_lock(&data->update_lock); |
| @@ -511,8 +505,7 @@ static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char | |||
| 511 | } | 505 | } |
| 512 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 506 | static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
| 513 | { | 507 | { |
| 514 | struct i2c_client *client = to_i2c_client(dev); | 508 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 515 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 516 | data->vrm = simple_strtoul(buf, NULL, 10); | 509 | data->vrm = simple_strtoul(buf, NULL, 10); |
| 517 | return count; | 510 | return count; |
| 518 | } | 511 | } |
| @@ -584,8 +577,7 @@ static ssize_t set_therm_min(struct device *dev, struct device_attribute *devatt | |||
| 584 | size_t count) | 577 | size_t count) |
| 585 | { | 578 | { |
| 586 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 579 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 587 | struct i2c_client *client = to_i2c_client(dev); | 580 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 588 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 589 | long val = simple_strtol(buf, NULL, 10); | 581 | long val = simple_strtol(buf, NULL, 10); |
| 590 | 582 | ||
| 591 | mutex_lock(&data->update_lock); | 583 | mutex_lock(&data->update_lock); |
| @@ -599,8 +591,7 @@ static ssize_t set_therm_max(struct device *dev, struct device_attribute *devatt | |||
| 599 | size_t count) | 591 | size_t count) |
| 600 | { | 592 | { |
| 601 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 593 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 602 | struct i2c_client *client = to_i2c_client(dev); | 594 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 603 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 604 | long val = simple_strtol(buf, NULL, 10); | 595 | long val = simple_strtol(buf, NULL, 10); |
| 605 | 596 | ||
| 606 | mutex_lock(&data->update_lock); | 597 | mutex_lock(&data->update_lock); |
| @@ -614,8 +605,7 @@ static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devat | |||
| 614 | size_t count) | 605 | size_t count) |
| 615 | { | 606 | { |
| 616 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 607 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 617 | struct i2c_client *client = to_i2c_client(dev); | 608 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 618 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 619 | long val = simple_strtol(buf, NULL, 10); | 609 | long val = simple_strtol(buf, NULL, 10); |
| 620 | 610 | ||
| 621 | mutex_lock(&data->update_lock); | 611 | mutex_lock(&data->update_lock); |
| @@ -715,8 +705,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr | |||
| 715 | size_t count) | 705 | size_t count) |
| 716 | { | 706 | { |
| 717 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 707 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 718 | struct i2c_client *client = to_i2c_client(dev); | 708 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 719 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 720 | long val = simple_strtol(buf, NULL, 10); | 709 | long val = simple_strtol(buf, NULL, 10); |
| 721 | 710 | ||
| 722 | mutex_lock(&data->update_lock); | 711 | mutex_lock(&data->update_lock); |
| @@ -730,8 +719,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr | |||
| 730 | size_t count) | 719 | size_t count) |
| 731 | { | 720 | { |
| 732 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 721 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 733 | struct i2c_client *client = to_i2c_client(dev); | 722 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 734 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 735 | long val = simple_strtol(buf, NULL, 10); | 723 | long val = simple_strtol(buf, NULL, 10); |
| 736 | 724 | ||
| 737 | mutex_lock(&data->update_lock); | 725 | mutex_lock(&data->update_lock); |
| @@ -745,8 +733,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devatt | |||
| 745 | size_t count) | 733 | size_t count) |
| 746 | { | 734 | { |
| 747 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 735 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 748 | struct i2c_client *client = to_i2c_client(dev); | 736 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 749 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 750 | long val = simple_strtol(buf, NULL, 10); | 737 | long val = simple_strtol(buf, NULL, 10); |
| 751 | 738 | ||
| 752 | mutex_lock(&data->update_lock); | 739 | mutex_lock(&data->update_lock); |
| @@ -818,6 +805,14 @@ static const struct attribute_group pc8736x_temp_group = { | |||
| 818 | .attrs = pc8736x_temp_attr_array, | 805 | .attrs = pc8736x_temp_attr_array, |
| 819 | }; | 806 | }; |
| 820 | 807 | ||
| 808 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
| 809 | *devattr, char *buf) | ||
| 810 | { | ||
| 811 | struct pc87360_data *data = dev_get_drvdata(dev); | ||
| 812 | return sprintf(buf, "%s\n", data->name); | ||
| 813 | } | ||
| 814 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 815 | |||
| 821 | /* | 816 | /* |
| 822 | * Device detection, registration and update | 817 | * Device detection, registration and update |
| 823 | */ | 818 | */ |
| @@ -912,28 +907,18 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses | |||
| 912 | return 0; | 907 | return 0; |
| 913 | } | 908 | } |
| 914 | 909 | ||
| 915 | static int pc87360_detect(struct i2c_adapter *adapter) | 910 | static int __devinit pc87360_probe(struct platform_device *pdev) |
| 916 | { | 911 | { |
| 917 | int i; | 912 | int i; |
| 918 | struct i2c_client *client; | ||
| 919 | struct pc87360_data *data; | 913 | struct pc87360_data *data; |
| 920 | int err = 0; | 914 | int err = 0; |
| 921 | const char *name = "pc87360"; | 915 | const char *name = "pc87360"; |
| 922 | int use_thermistors = 0; | 916 | int use_thermistors = 0; |
| 923 | struct device *dev; | 917 | struct device *dev = &pdev->dev; |
| 924 | 918 | ||
| 925 | if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL))) | 919 | if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL))) |
| 926 | return -ENOMEM; | 920 | return -ENOMEM; |
| 927 | 921 | ||
| 928 | client = &data->client; | ||
| 929 | dev = &client->dev; | ||
| 930 | i2c_set_clientdata(client, data); | ||
| 931 | client->addr = address; | ||
| 932 | mutex_init(&data->lock); | ||
| 933 | client->adapter = adapter; | ||
| 934 | client->driver = &pc87360_driver; | ||
| 935 | client->flags = 0; | ||
| 936 | |||
| 937 | data->fannr = 2; | 922 | data->fannr = 2; |
| 938 | data->innr = 0; | 923 | data->innr = 0; |
| 939 | data->tempnr = 0; | 924 | data->tempnr = 0; |
| @@ -960,15 +945,17 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
| 960 | break; | 945 | break; |
| 961 | } | 946 | } |
| 962 | 947 | ||
| 963 | strlcpy(client->name, name, sizeof(client->name)); | 948 | data->name = name; |
| 964 | data->valid = 0; | 949 | data->valid = 0; |
| 950 | mutex_init(&data->lock); | ||
| 965 | mutex_init(&data->update_lock); | 951 | mutex_init(&data->update_lock); |
| 952 | platform_set_drvdata(pdev, data); | ||
| 966 | 953 | ||
| 967 | for (i = 0; i < 3; i++) { | 954 | for (i = 0; i < 3; i++) { |
| 968 | if (((data->address[i] = extra_isa[i])) | 955 | if (((data->address[i] = extra_isa[i])) |
| 969 | && !request_region(extra_isa[i], PC87360_EXTENT, | 956 | && !request_region(extra_isa[i], PC87360_EXTENT, |
| 970 | pc87360_driver.driver.name)) { | 957 | pc87360_driver.driver.name)) { |
| 971 | dev_err(&client->dev, "Region 0x%x-0x%x already " | 958 | dev_err(dev, "Region 0x%x-0x%x already " |
| 972 | "in use!\n", extra_isa[i], | 959 | "in use!\n", extra_isa[i], |
| 973 | extra_isa[i]+PC87360_EXTENT-1); | 960 | extra_isa[i]+PC87360_EXTENT-1); |
| 974 | for (i--; i >= 0; i--) | 961 | for (i--; i >= 0; i--) |
| @@ -982,9 +969,6 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
| 982 | if (data->fannr) | 969 | if (data->fannr) |
| 983 | data->fan_conf = confreg[0] | (confreg[1] << 8); | 970 | data->fan_conf = confreg[0] | (confreg[1] << 8); |
| 984 | 971 | ||
| 985 | if ((err = i2c_attach_client(client))) | ||
| 986 | goto ERROR2; | ||
| 987 | |||
| 988 | /* Use the correct reference voltage | 972 | /* Use the correct reference voltage |
| 989 | Unless both the VLM and the TMS logical devices agree to | 973 | Unless both the VLM and the TMS logical devices agree to |
| 990 | use an external Vref, the internal one is used. */ | 974 | use an external Vref, the internal one is used. */ |
| @@ -996,7 +980,7 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
| 996 | PC87365_REG_TEMP_CONFIG); | 980 | PC87365_REG_TEMP_CONFIG); |
| 997 | } | 981 | } |
| 998 | data->in_vref = (i&0x02) ? 3025 : 2966; | 982 | data->in_vref = (i&0x02) ? 3025 : 2966; |
| 999 | dev_dbg(&client->dev, "Using %s reference voltage\n", | 983 | dev_dbg(dev, "Using %s reference voltage\n", |
| 1000 | (i&0x02) ? "external" : "internal"); | 984 | (i&0x02) ? "external" : "internal"); |
| 1001 | 985 | ||
| 1002 | data->vid_conf = confreg[3]; | 986 | data->vid_conf = confreg[3]; |
| @@ -1015,18 +999,18 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
| 1015 | if (devid == 0xe9 && data->address[1]) /* PC87366 */ | 999 | if (devid == 0xe9 && data->address[1]) /* PC87366 */ |
| 1016 | use_thermistors = confreg[2] & 0x40; | 1000 | use_thermistors = confreg[2] & 0x40; |
| 1017 | 1001 | ||
| 1018 | pc87360_init_client(client, use_thermistors); | 1002 | pc87360_init_device(pdev, use_thermistors); |
| 1019 | } | 1003 | } |
| 1020 | 1004 | ||
| 1021 | /* Register all-or-nothing sysfs groups */ | 1005 | /* Register all-or-nothing sysfs groups */ |
| 1022 | 1006 | ||
| 1023 | if (data->innr && | 1007 | if (data->innr && |
| 1024 | (err = sysfs_create_group(&client->dev.kobj, | 1008 | (err = sysfs_create_group(&dev->kobj, |
| 1025 | &pc8736x_vin_group))) | 1009 | &pc8736x_vin_group))) |
| 1026 | goto ERROR3; | 1010 | goto ERROR3; |
| 1027 | 1011 | ||
| 1028 | if (data->innr == 14 && | 1012 | if (data->innr == 14 && |
| 1029 | (err = sysfs_create_group(&client->dev.kobj, | 1013 | (err = sysfs_create_group(&dev->kobj, |
| 1030 | &pc8736x_therm_group))) | 1014 | &pc8736x_therm_group))) |
| 1031 | goto ERROR3; | 1015 | goto ERROR3; |
| 1032 | 1016 | ||
| @@ -1067,7 +1051,10 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
| 1067 | goto ERROR3; | 1051 | goto ERROR3; |
| 1068 | } | 1052 | } |
| 1069 | 1053 | ||
| 1070 | data->class_dev = hwmon_device_register(&client->dev); | 1054 | if ((err = device_create_file(dev, &dev_attr_name))) |
| 1055 | goto ERROR3; | ||
| 1056 | |||
| 1057 | data->class_dev = hwmon_device_register(dev); | ||
| 1071 | if (IS_ERR(data->class_dev)) { | 1058 | if (IS_ERR(data->class_dev)) { |
| 1072 | err = PTR_ERR(data->class_dev); | 1059 | err = PTR_ERR(data->class_dev); |
| 1073 | goto ERROR3; | 1060 | goto ERROR3; |
| @@ -1075,14 +1062,12 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
| 1075 | return 0; | 1062 | return 0; |
| 1076 | 1063 | ||
| 1077 | ERROR3: | 1064 | ERROR3: |
| 1065 | device_remove_file(dev, &dev_attr_name); | ||
| 1078 | /* can still remove groups whose members were added individually */ | 1066 | /* can still remove groups whose members were added individually */ |
| 1079 | sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group); | 1067 | sysfs_remove_group(&dev->kobj, &pc8736x_temp_group); |
| 1080 | sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group); | 1068 | sysfs_remove_group(&dev->kobj, &pc8736x_fan_group); |
| 1081 | sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group); | 1069 | sysfs_remove_group(&dev->kobj, &pc8736x_therm_group); |
| 1082 | sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group); | 1070 | sysfs_remove_group(&dev->kobj, &pc8736x_vin_group); |
| 1083 | |||
| 1084 | i2c_detach_client(client); | ||
| 1085 | ERROR2: | ||
| 1086 | for (i = 0; i < 3; i++) { | 1071 | for (i = 0; i < 3; i++) { |
| 1087 | if (data->address[i]) { | 1072 | if (data->address[i]) { |
| 1088 | release_region(data->address[i], PC87360_EXTENT); | 1073 | release_region(data->address[i], PC87360_EXTENT); |
| @@ -1093,20 +1078,18 @@ ERROR1: | |||
| 1093 | return err; | 1078 | return err; |
| 1094 | } | 1079 | } |
| 1095 | 1080 | ||
| 1096 | static int pc87360_detach_client(struct i2c_client *client) | 1081 | static int __devexit pc87360_remove(struct platform_device *pdev) |
| 1097 | { | 1082 | { |
| 1098 | struct pc87360_data *data = i2c_get_clientdata(client); | 1083 | struct pc87360_data *data = platform_get_drvdata(pdev); |
| 1099 | int i; | 1084 | int i; |
| 1100 | 1085 | ||
| 1101 | hwmon_device_unregister(data->class_dev); | 1086 | hwmon_device_unregister(data->class_dev); |
| 1102 | 1087 | ||
| 1103 | sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group); | 1088 | device_remove_file(&pdev->dev, &dev_attr_name); |
| 1104 | sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group); | 1089 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group); |
| 1105 | sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group); | 1090 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_fan_group); |
| 1106 | sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group); | 1091 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_therm_group); |
| 1107 | 1092 | sysfs_remove_group(&pdev->dev.kobj, &pc8736x_vin_group); | |
| 1108 | if ((i = i2c_detach_client(client))) | ||
| 1109 | return i; | ||
| 1110 | 1093 | ||
| 1111 | for (i = 0; i < 3; i++) { | 1094 | for (i = 0; i < 3; i++) { |
| 1112 | if (data->address[i]) { | 1095 | if (data->address[i]) { |
| @@ -1144,9 +1127,10 @@ static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, | |||
| 1144 | mutex_unlock(&(data->lock)); | 1127 | mutex_unlock(&(data->lock)); |
| 1145 | } | 1128 | } |
| 1146 | 1129 | ||
| 1147 | static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | 1130 | static void pc87360_init_device(struct platform_device *pdev, |
| 1131 | int use_thermistors) | ||
| 1148 | { | 1132 | { |
| 1149 | struct pc87360_data *data = i2c_get_clientdata(client); | 1133 | struct pc87360_data *data = platform_get_drvdata(pdev); |
| 1150 | int i, nr; | 1134 | int i, nr; |
| 1151 | const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 }; | 1135 | const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 }; |
| 1152 | const u8 init_temp[3] = { 2, 2, 1 }; | 1136 | const u8 init_temp[3] = { 2, 2, 1 }; |
| @@ -1155,7 +1139,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
| 1155 | if (init >= 2 && data->innr) { | 1139 | if (init >= 2 && data->innr) { |
| 1156 | reg = pc87360_read_value(data, LD_IN, NO_BANK, | 1140 | reg = pc87360_read_value(data, LD_IN, NO_BANK, |
| 1157 | PC87365_REG_IN_CONVRATE); | 1141 | PC87365_REG_IN_CONVRATE); |
| 1158 | dev_info(&client->dev, "VLM conversion set to " | 1142 | dev_info(&pdev->dev, "VLM conversion set to " |
| 1159 | "1s period, 160us delay\n"); | 1143 | "1s period, 160us delay\n"); |
| 1160 | pc87360_write_value(data, LD_IN, NO_BANK, | 1144 | pc87360_write_value(data, LD_IN, NO_BANK, |
| 1161 | PC87365_REG_IN_CONVRATE, | 1145 | PC87365_REG_IN_CONVRATE, |
| @@ -1169,7 +1153,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
| 1169 | reg = pc87360_read_value(data, LD_IN, i, | 1153 | reg = pc87360_read_value(data, LD_IN, i, |
| 1170 | PC87365_REG_IN_STATUS); | 1154 | PC87365_REG_IN_STATUS); |
| 1171 | if (!(reg & 0x01)) { | 1155 | if (!(reg & 0x01)) { |
| 1172 | dev_dbg(&client->dev, "Forcibly " | 1156 | dev_dbg(&pdev->dev, "Forcibly " |
| 1173 | "enabling in%d\n", i); | 1157 | "enabling in%d\n", i); |
| 1174 | pc87360_write_value(data, LD_IN, i, | 1158 | pc87360_write_value(data, LD_IN, i, |
| 1175 | PC87365_REG_IN_STATUS, | 1159 | PC87365_REG_IN_STATUS, |
| @@ -1193,7 +1177,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
| 1193 | reg = pc87360_read_value(data, LD_TEMP, i, | 1177 | reg = pc87360_read_value(data, LD_TEMP, i, |
| 1194 | PC87365_REG_TEMP_STATUS); | 1178 | PC87365_REG_TEMP_STATUS); |
| 1195 | if (!(reg & 0x01)) { | 1179 | if (!(reg & 0x01)) { |
| 1196 | dev_dbg(&client->dev, "Forcibly " | 1180 | dev_dbg(&pdev->dev, "Forcibly " |
| 1197 | "enabling temp%d\n", i+1); | 1181 | "enabling temp%d\n", i+1); |
| 1198 | pc87360_write_value(data, LD_TEMP, i, | 1182 | pc87360_write_value(data, LD_TEMP, i, |
| 1199 | PC87365_REG_TEMP_STATUS, | 1183 | PC87365_REG_TEMP_STATUS, |
| @@ -1210,7 +1194,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
| 1210 | reg = pc87360_read_value(data, LD_TEMP, | 1194 | reg = pc87360_read_value(data, LD_TEMP, |
| 1211 | (i-11)/2, PC87365_REG_TEMP_STATUS); | 1195 | (i-11)/2, PC87365_REG_TEMP_STATUS); |
| 1212 | if (reg & 0x01) { | 1196 | if (reg & 0x01) { |
| 1213 | dev_dbg(&client->dev, "Skipping " | 1197 | dev_dbg(&pdev->dev, "Skipping " |
| 1214 | "temp%d, pin already in use " | 1198 | "temp%d, pin already in use " |
| 1215 | "by temp%d\n", i-7, (i-11)/2); | 1199 | "by temp%d\n", i-7, (i-11)/2); |
| 1216 | continue; | 1200 | continue; |
| @@ -1220,7 +1204,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
| 1220 | reg = pc87360_read_value(data, LD_IN, i, | 1204 | reg = pc87360_read_value(data, LD_IN, i, |
| 1221 | PC87365_REG_IN_STATUS); | 1205 | PC87365_REG_IN_STATUS); |
| 1222 | if (!(reg & 0x01)) { | 1206 | if (!(reg & 0x01)) { |
| 1223 | dev_dbg(&client->dev, "Forcibly " | 1207 | dev_dbg(&pdev->dev, "Forcibly " |
| 1224 | "enabling temp%d\n", i-7); | 1208 | "enabling temp%d\n", i-7); |
| 1225 | pc87360_write_value(data, LD_IN, i, | 1209 | pc87360_write_value(data, LD_IN, i, |
| 1226 | PC87365_REG_TEMP_STATUS, | 1210 | PC87365_REG_TEMP_STATUS, |
| @@ -1234,7 +1218,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
| 1234 | reg = pc87360_read_value(data, LD_IN, NO_BANK, | 1218 | reg = pc87360_read_value(data, LD_IN, NO_BANK, |
| 1235 | PC87365_REG_IN_CONFIG); | 1219 | PC87365_REG_IN_CONFIG); |
| 1236 | if (reg & 0x01) { | 1220 | if (reg & 0x01) { |
| 1237 | dev_dbg(&client->dev, "Forcibly " | 1221 | dev_dbg(&pdev->dev, "Forcibly " |
| 1238 | "enabling monitoring (VLM)\n"); | 1222 | "enabling monitoring (VLM)\n"); |
| 1239 | pc87360_write_value(data, LD_IN, NO_BANK, | 1223 | pc87360_write_value(data, LD_IN, NO_BANK, |
| 1240 | PC87365_REG_IN_CONFIG, | 1224 | PC87365_REG_IN_CONFIG, |
| @@ -1246,7 +1230,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
| 1246 | reg = pc87360_read_value(data, LD_TEMP, NO_BANK, | 1230 | reg = pc87360_read_value(data, LD_TEMP, NO_BANK, |
| 1247 | PC87365_REG_TEMP_CONFIG); | 1231 | PC87365_REG_TEMP_CONFIG); |
| 1248 | if (reg & 0x01) { | 1232 | if (reg & 0x01) { |
| 1249 | dev_dbg(&client->dev, "Forcibly enabling " | 1233 | dev_dbg(&pdev->dev, "Forcibly enabling " |
| 1250 | "monitoring (TMS)\n"); | 1234 | "monitoring (TMS)\n"); |
| 1251 | pc87360_write_value(data, LD_TEMP, NO_BANK, | 1235 | pc87360_write_value(data, LD_TEMP, NO_BANK, |
| 1252 | PC87365_REG_TEMP_CONFIG, | 1236 | PC87365_REG_TEMP_CONFIG, |
| @@ -1268,9 +1252,9 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
| 1268 | } | 1252 | } |
| 1269 | } | 1253 | } |
| 1270 | 1254 | ||
| 1271 | static void pc87360_autodiv(struct i2c_client *client, int nr) | 1255 | static void pc87360_autodiv(struct device *dev, int nr) |
| 1272 | { | 1256 | { |
| 1273 | struct pc87360_data *data = i2c_get_clientdata(client); | 1257 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 1274 | u8 old_min = data->fan_min[nr]; | 1258 | u8 old_min = data->fan_min[nr]; |
| 1275 | 1259 | ||
| 1276 | /* Increase clock divider if needed and possible */ | 1260 | /* Increase clock divider if needed and possible */ |
| @@ -1280,7 +1264,7 @@ static void pc87360_autodiv(struct i2c_client *client, int nr) | |||
| 1280 | data->fan_status[nr] += 0x20; | 1264 | data->fan_status[nr] += 0x20; |
| 1281 | data->fan_min[nr] >>= 1; | 1265 | data->fan_min[nr] >>= 1; |
| 1282 | data->fan[nr] >>= 1; | 1266 | data->fan[nr] >>= 1; |
| 1283 | dev_dbg(&client->dev, "Increasing " | 1267 | dev_dbg(dev, "Increasing " |
| 1284 | "clock divider to %d for fan %d\n", | 1268 | "clock divider to %d for fan %d\n", |
| 1285 | FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1); | 1269 | FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1); |
| 1286 | } | 1270 | } |
| @@ -1292,7 +1276,7 @@ static void pc87360_autodiv(struct i2c_client *client, int nr) | |||
| 1292 | data->fan_status[nr] -= 0x20; | 1276 | data->fan_status[nr] -= 0x20; |
| 1293 | data->fan_min[nr] <<= 1; | 1277 | data->fan_min[nr] <<= 1; |
| 1294 | data->fan[nr] <<= 1; | 1278 | data->fan[nr] <<= 1; |
| 1295 | dev_dbg(&client->dev, "Decreasing " | 1279 | dev_dbg(dev, "Decreasing " |
| 1296 | "clock divider to %d for fan %d\n", | 1280 | "clock divider to %d for fan %d\n", |
| 1297 | FAN_DIV_FROM_REG(data->fan_status[nr]), | 1281 | FAN_DIV_FROM_REG(data->fan_status[nr]), |
| 1298 | nr+1); | 1282 | nr+1); |
| @@ -1309,14 +1293,13 @@ static void pc87360_autodiv(struct i2c_client *client, int nr) | |||
| 1309 | 1293 | ||
| 1310 | static struct pc87360_data *pc87360_update_device(struct device *dev) | 1294 | static struct pc87360_data *pc87360_update_device(struct device *dev) |
| 1311 | { | 1295 | { |
| 1312 | struct i2c_client *client = to_i2c_client(dev); | 1296 | struct pc87360_data *data = dev_get_drvdata(dev); |
| 1313 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
| 1314 | u8 i; | 1297 | u8 i; |
| 1315 | 1298 | ||
| 1316 | mutex_lock(&data->update_lock); | 1299 | mutex_lock(&data->update_lock); |
| 1317 | 1300 | ||
| 1318 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | 1301 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { |
| 1319 | dev_dbg(&client->dev, "Data update\n"); | 1302 | dev_dbg(dev, "Data update\n"); |
| 1320 | 1303 | ||
| 1321 | /* Fans */ | 1304 | /* Fans */ |
| 1322 | for (i = 0; i < data->fannr; i++) { | 1305 | for (i = 0; i < data->fannr; i++) { |
| @@ -1330,7 +1313,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
| 1330 | LD_FAN, NO_BANK, | 1313 | LD_FAN, NO_BANK, |
| 1331 | PC87360_REG_FAN_MIN(i)); | 1314 | PC87360_REG_FAN_MIN(i)); |
| 1332 | /* Change clock divider if needed */ | 1315 | /* Change clock divider if needed */ |
| 1333 | pc87360_autodiv(client, i); | 1316 | pc87360_autodiv(dev, i); |
| 1334 | /* Clear bits and write new divider */ | 1317 | /* Clear bits and write new divider */ |
| 1335 | pc87360_write_value(data, LD_FAN, NO_BANK, | 1318 | pc87360_write_value(data, LD_FAN, NO_BANK, |
| 1336 | PC87360_REG_FAN_STATUS(i), | 1319 | PC87360_REG_FAN_STATUS(i), |
| @@ -1418,9 +1401,53 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
| 1418 | return data; | 1401 | return data; |
| 1419 | } | 1402 | } |
| 1420 | 1403 | ||
| 1404 | static int __init pc87360_device_add(unsigned short address) | ||
| 1405 | { | ||
| 1406 | struct resource res = { | ||
| 1407 | .name = "pc87360", | ||
| 1408 | .flags = IORESOURCE_IO, | ||
| 1409 | }; | ||
| 1410 | int err, i; | ||
| 1411 | |||
| 1412 | pdev = platform_device_alloc("pc87360", address); | ||
| 1413 | if (!pdev) { | ||
| 1414 | err = -ENOMEM; | ||
| 1415 | printk(KERN_ERR "pc87360: Device allocation failed\n"); | ||
| 1416 | goto exit; | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | for (i = 0; i < 3; i++) { | ||
| 1420 | if (!extra_isa[i]) | ||
| 1421 | continue; | ||
| 1422 | res.start = extra_isa[i]; | ||
| 1423 | res.end = extra_isa[i] + PC87360_EXTENT - 1; | ||
| 1424 | err = platform_device_add_resources(pdev, &res, 1); | ||
| 1425 | if (err) { | ||
| 1426 | printk(KERN_ERR "pc87360: Device resource[%d] " | ||
| 1427 | "addition failed (%d)\n", i, err); | ||
| 1428 | goto exit_device_put; | ||
| 1429 | } | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | err = platform_device_add(pdev); | ||
| 1433 | if (err) { | ||
| 1434 | printk(KERN_ERR "pc87360: Device addition failed (%d)\n", | ||
| 1435 | err); | ||
| 1436 | goto exit_device_put; | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | return 0; | ||
| 1440 | |||
| 1441 | exit_device_put: | ||
| 1442 | platform_device_put(pdev); | ||
| 1443 | exit: | ||
| 1444 | return err; | ||
| 1445 | } | ||
| 1446 | |||
| 1421 | static int __init pc87360_init(void) | 1447 | static int __init pc87360_init(void) |
| 1422 | { | 1448 | { |
| 1423 | int i; | 1449 | int err, i; |
| 1450 | unsigned short address = 0; | ||
| 1424 | 1451 | ||
| 1425 | if (pc87360_find(0x2e, &devid, extra_isa) | 1452 | if (pc87360_find(0x2e, &devid, extra_isa) |
| 1426 | && pc87360_find(0x4e, &devid, extra_isa)) { | 1453 | && pc87360_find(0x4e, &devid, extra_isa)) { |
| @@ -1443,12 +1470,27 @@ static int __init pc87360_init(void) | |||
| 1443 | return -ENODEV; | 1470 | return -ENODEV; |
| 1444 | } | 1471 | } |
| 1445 | 1472 | ||
| 1446 | return i2c_isa_add_driver(&pc87360_driver); | 1473 | err = platform_driver_register(&pc87360_driver); |
| 1474 | if (err) | ||
| 1475 | goto exit; | ||
| 1476 | |||
| 1477 | /* Sets global pdev as a side effect */ | ||
| 1478 | err = pc87360_device_add(address); | ||
| 1479 | if (err) | ||
| 1480 | goto exit_driver; | ||
| 1481 | |||
| 1482 | return 0; | ||
| 1483 | |||
| 1484 | exit_driver: | ||
| 1485 | platform_driver_unregister(&pc87360_driver); | ||
| 1486 | exit: | ||
| 1487 | return err; | ||
| 1447 | } | 1488 | } |
| 1448 | 1489 | ||
| 1449 | static void __exit pc87360_exit(void) | 1490 | static void __exit pc87360_exit(void) |
| 1450 | { | 1491 | { |
| 1451 | i2c_isa_del_driver(&pc87360_driver); | 1492 | platform_device_unregister(pdev); |
| 1493 | platform_driver_unregister(&pc87360_driver); | ||
| 1452 | } | 1494 | } |
| 1453 | 1495 | ||
| 1454 | 1496 | ||
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 29354fa26f81..2915bc4ad0d5 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c | |||
| @@ -484,7 +484,6 @@ static int __devexit pc87427_remove(struct platform_device *pdev) | |||
| 484 | struct resource *res; | 484 | struct resource *res; |
| 485 | int i; | 485 | int i; |
| 486 | 486 | ||
| 487 | platform_set_drvdata(pdev, NULL); | ||
| 488 | hwmon_device_unregister(data->class_dev); | 487 | hwmon_device_unregister(data->class_dev); |
| 489 | device_remove_file(&pdev->dev, &dev_attr_name); | 488 | device_remove_file(&pdev->dev, &dev_attr_name); |
| 490 | for (i = 0; i < 8; i++) { | 489 | for (i = 0; i < 8; i++) { |
| @@ -492,6 +491,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev) | |||
| 492 | continue; | 491 | continue; |
| 493 | sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); | 492 | sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); |
| 494 | } | 493 | } |
| 494 | platform_set_drvdata(pdev, NULL); | ||
| 495 | kfree(data); | 495 | kfree(data); |
| 496 | 496 | ||
| 497 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 497 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 3f400263fc0f..83321b28cf0e 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
| @@ -54,9 +54,9 @@ | |||
| 54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
| 55 | #include <linux/ioport.h> | 55 | #include <linux/ioport.h> |
| 56 | #include <linux/pci.h> | 56 | #include <linux/pci.h> |
| 57 | #include <linux/i2c.h> | 57 | #include <linux/platform_device.h> |
| 58 | #include <linux/i2c-isa.h> | ||
| 59 | #include <linux/hwmon.h> | 58 | #include <linux/hwmon.h> |
| 59 | #include <linux/hwmon-sysfs.h> | ||
| 60 | #include <linux/err.h> | 60 | #include <linux/err.h> |
| 61 | #include <linux/init.h> | 61 | #include <linux/init.h> |
| 62 | #include <linux/jiffies.h> | 62 | #include <linux/jiffies.h> |
| @@ -72,17 +72,13 @@ module_param(force_addr, ushort, 0); | |||
| 72 | MODULE_PARM_DESC(force_addr, | 72 | MODULE_PARM_DESC(force_addr, |
| 73 | "Initialize the base address of the sensors"); | 73 | "Initialize the base address of the sensors"); |
| 74 | 74 | ||
| 75 | /* Device address | 75 | static struct platform_device *pdev; |
| 76 | Note that we can't determine the ISA address until we have initialized | ||
| 77 | our module */ | ||
| 78 | static unsigned short address; | ||
| 79 | 76 | ||
| 80 | /* Many SIS5595 constants specified below */ | 77 | /* Many SIS5595 constants specified below */ |
| 81 | 78 | ||
| 82 | /* Length of ISA address segment */ | 79 | /* Length of ISA address segment */ |
| 83 | #define SIS5595_EXTENT 8 | 80 | #define SIS5595_EXTENT 8 |
| 84 | /* PCI Config Registers */ | 81 | /* PCI Config Registers */ |
| 85 | #define SIS5595_REVISION_REG 0x08 | ||
| 86 | #define SIS5595_BASE_REG 0x68 | 82 | #define SIS5595_BASE_REG 0x68 |
| 87 | #define SIS5595_PIN_REG 0x7A | 83 | #define SIS5595_PIN_REG 0x7A |
| 88 | #define SIS5595_ENABLE_REG 0x7B | 84 | #define SIS5595_ENABLE_REG 0x7B |
| @@ -165,7 +161,8 @@ static inline u8 DIV_TO_REG(int val) | |||
| 165 | /* For each registered chip, we need to keep some data in memory. | 161 | /* For each registered chip, we need to keep some data in memory. |
| 166 | The structure is dynamically allocated. */ | 162 | The structure is dynamically allocated. */ |
| 167 | struct sis5595_data { | 163 | struct sis5595_data { |
| 168 | struct i2c_client client; | 164 | unsigned short addr; |
| 165 | const char *name; | ||
| 169 | struct class_device *class_dev; | 166 | struct class_device *class_dev; |
| 170 | struct mutex lock; | 167 | struct mutex lock; |
| 171 | 168 | ||
| @@ -189,102 +186,88 @@ struct sis5595_data { | |||
| 189 | 186 | ||
| 190 | static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */ | 187 | static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */ |
| 191 | 188 | ||
| 192 | static int sis5595_detect(struct i2c_adapter *adapter); | 189 | static int sis5595_probe(struct platform_device *pdev); |
| 193 | static int sis5595_detach_client(struct i2c_client *client); | 190 | static int sis5595_remove(struct platform_device *pdev); |
| 194 | 191 | ||
| 195 | static int sis5595_read_value(struct i2c_client *client, u8 reg); | 192 | static int sis5595_read_value(struct sis5595_data *data, u8 reg); |
| 196 | static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value); | 193 | static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value); |
| 197 | static struct sis5595_data *sis5595_update_device(struct device *dev); | 194 | static struct sis5595_data *sis5595_update_device(struct device *dev); |
| 198 | static void sis5595_init_client(struct i2c_client *client); | 195 | static void sis5595_init_device(struct sis5595_data *data); |
| 199 | 196 | ||
| 200 | static struct i2c_driver sis5595_driver = { | 197 | static struct platform_driver sis5595_driver = { |
| 201 | .driver = { | 198 | .driver = { |
| 202 | .owner = THIS_MODULE, | 199 | .owner = THIS_MODULE, |
| 203 | .name = "sis5595", | 200 | .name = "sis5595", |
| 204 | }, | 201 | }, |
| 205 | .attach_adapter = sis5595_detect, | 202 | .probe = sis5595_probe, |
| 206 | .detach_client = sis5595_detach_client, | 203 | .remove = __devexit_p(sis5595_remove), |
| 207 | }; | 204 | }; |
| 208 | 205 | ||
| 209 | /* 4 Voltages */ | 206 | /* 4 Voltages */ |
| 210 | static ssize_t show_in(struct device *dev, char *buf, int nr) | 207 | static ssize_t show_in(struct device *dev, struct device_attribute *da, |
| 208 | char *buf) | ||
| 211 | { | 209 | { |
| 212 | struct sis5595_data *data = sis5595_update_device(dev); | 210 | struct sis5595_data *data = sis5595_update_device(dev); |
| 211 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 212 | int nr = attr->index; | ||
| 213 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])); | 213 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])); |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | static ssize_t show_in_min(struct device *dev, char *buf, int nr) | 216 | static ssize_t show_in_min(struct device *dev, struct device_attribute *da, |
| 217 | char *buf) | ||
| 217 | { | 218 | { |
| 218 | struct sis5595_data *data = sis5595_update_device(dev); | 219 | struct sis5595_data *data = sis5595_update_device(dev); |
| 220 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 221 | int nr = attr->index; | ||
| 219 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])); | 222 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])); |
| 220 | } | 223 | } |
| 221 | 224 | ||
| 222 | static ssize_t show_in_max(struct device *dev, char *buf, int nr) | 225 | static ssize_t show_in_max(struct device *dev, struct device_attribute *da, |
| 226 | char *buf) | ||
| 223 | { | 227 | { |
| 224 | struct sis5595_data *data = sis5595_update_device(dev); | 228 | struct sis5595_data *data = sis5595_update_device(dev); |
| 229 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 230 | int nr = attr->index; | ||
| 225 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])); | 231 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])); |
| 226 | } | 232 | } |
| 227 | 233 | ||
| 228 | static ssize_t set_in_min(struct device *dev, const char *buf, | 234 | static ssize_t set_in_min(struct device *dev, struct device_attribute *da, |
| 229 | size_t count, int nr) | 235 | const char *buf, size_t count) |
| 230 | { | 236 | { |
| 231 | struct i2c_client *client = to_i2c_client(dev); | 237 | struct sis5595_data *data = dev_get_drvdata(dev); |
| 232 | struct sis5595_data *data = i2c_get_clientdata(client); | 238 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 239 | int nr = attr->index; | ||
| 233 | unsigned long val = simple_strtoul(buf, NULL, 10); | 240 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 234 | 241 | ||
| 235 | mutex_lock(&data->update_lock); | 242 | mutex_lock(&data->update_lock); |
| 236 | data->in_min[nr] = IN_TO_REG(val); | 243 | data->in_min[nr] = IN_TO_REG(val); |
| 237 | sis5595_write_value(client, SIS5595_REG_IN_MIN(nr), data->in_min[nr]); | 244 | sis5595_write_value(data, SIS5595_REG_IN_MIN(nr), data->in_min[nr]); |
| 238 | mutex_unlock(&data->update_lock); | 245 | mutex_unlock(&data->update_lock); |
| 239 | return count; | 246 | return count; |
| 240 | } | 247 | } |
| 241 | 248 | ||
| 242 | static ssize_t set_in_max(struct device *dev, const char *buf, | 249 | static ssize_t set_in_max(struct device *dev, struct device_attribute *da, |
| 243 | size_t count, int nr) | 250 | const char *buf, size_t count) |
| 244 | { | 251 | { |
| 245 | struct i2c_client *client = to_i2c_client(dev); | 252 | struct sis5595_data *data = dev_get_drvdata(dev); |
| 246 | struct sis5595_data *data = i2c_get_clientdata(client); | 253 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 254 | int nr = attr->index; | ||
| 247 | unsigned long val = simple_strtoul(buf, NULL, 10); | 255 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 248 | 256 | ||
| 249 | mutex_lock(&data->update_lock); | 257 | mutex_lock(&data->update_lock); |
| 250 | data->in_max[nr] = IN_TO_REG(val); | 258 | data->in_max[nr] = IN_TO_REG(val); |
| 251 | sis5595_write_value(client, SIS5595_REG_IN_MAX(nr), data->in_max[nr]); | 259 | sis5595_write_value(data, SIS5595_REG_IN_MAX(nr), data->in_max[nr]); |
| 252 | mutex_unlock(&data->update_lock); | 260 | mutex_unlock(&data->update_lock); |
| 253 | return count; | 261 | return count; |
| 254 | } | 262 | } |
| 255 | 263 | ||
| 256 | #define show_in_offset(offset) \ | 264 | #define show_in_offset(offset) \ |
| 257 | static ssize_t \ | 265 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
| 258 | show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 266 | show_in, NULL, offset); \ |
| 259 | { \ | 267 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ |
| 260 | return show_in(dev, buf, offset); \ | 268 | show_in_min, set_in_min, offset); \ |
| 261 | } \ | 269 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ |
| 262 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ | 270 | show_in_max, set_in_max, offset); |
| 263 | show_in##offset, NULL); \ | ||
| 264 | static ssize_t \ | ||
| 265 | show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
| 266 | { \ | ||
| 267 | return show_in_min(dev, buf, offset); \ | ||
| 268 | } \ | ||
| 269 | static ssize_t \ | ||
| 270 | show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
| 271 | { \ | ||
| 272 | return show_in_max(dev, buf, offset); \ | ||
| 273 | } \ | ||
| 274 | static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
| 275 | const char *buf, size_t count) \ | ||
| 276 | { \ | ||
| 277 | return set_in_min(dev, buf, count, offset); \ | ||
| 278 | } \ | ||
| 279 | static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \ | ||
| 280 | const char *buf, size_t count) \ | ||
| 281 | { \ | ||
| 282 | return set_in_max(dev, buf, count, offset); \ | ||
| 283 | } \ | ||
| 284 | static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
| 285 | show_in##offset##_min, set_in##offset##_min); \ | ||
| 286 | static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
| 287 | show_in##offset##_max, set_in##offset##_max); | ||
| 288 | 271 | ||
| 289 | show_in_offset(0); | 272 | show_in_offset(0); |
| 290 | show_in_offset(1); | 273 | show_in_offset(1); |
| @@ -307,13 +290,12 @@ static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, | |||
| 307 | 290 | ||
| 308 | static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 291 | static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
| 309 | { | 292 | { |
| 310 | struct i2c_client *client = to_i2c_client(dev); | 293 | struct sis5595_data *data = dev_get_drvdata(dev); |
| 311 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
| 312 | long val = simple_strtol(buf, NULL, 10); | 294 | long val = simple_strtol(buf, NULL, 10); |
| 313 | 295 | ||
| 314 | mutex_lock(&data->update_lock); | 296 | mutex_lock(&data->update_lock); |
| 315 | data->temp_over = TEMP_TO_REG(val); | 297 | data->temp_over = TEMP_TO_REG(val); |
| 316 | sis5595_write_value(client, SIS5595_REG_TEMP_OVER, data->temp_over); | 298 | sis5595_write_value(data, SIS5595_REG_TEMP_OVER, data->temp_over); |
| 317 | mutex_unlock(&data->update_lock); | 299 | mutex_unlock(&data->update_lock); |
| 318 | return count; | 300 | return count; |
| 319 | } | 301 | } |
| @@ -326,13 +308,12 @@ static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, | |||
| 326 | 308 | ||
| 327 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 309 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
| 328 | { | 310 | { |
| 329 | struct i2c_client *client = to_i2c_client(dev); | 311 | struct sis5595_data *data = dev_get_drvdata(dev); |
| 330 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
| 331 | long val = simple_strtol(buf, NULL, 10); | 312 | long val = simple_strtol(buf, NULL, 10); |
| 332 | 313 | ||
| 333 | mutex_lock(&data->update_lock); | 314 | mutex_lock(&data->update_lock); |
| 334 | data->temp_hyst = TEMP_TO_REG(val); | 315 | data->temp_hyst = TEMP_TO_REG(val); |
| 335 | sis5595_write_value(client, SIS5595_REG_TEMP_HYST, data->temp_hyst); | 316 | sis5595_write_value(data, SIS5595_REG_TEMP_HYST, data->temp_hyst); |
| 336 | mutex_unlock(&data->update_lock); | 317 | mutex_unlock(&data->update_lock); |
| 337 | return count; | 318 | return count; |
| 338 | } | 319 | } |
| @@ -344,37 +325,47 @@ static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, | |||
| 344 | show_temp_hyst, set_temp_hyst); | 325 | show_temp_hyst, set_temp_hyst); |
| 345 | 326 | ||
| 346 | /* 2 Fans */ | 327 | /* 2 Fans */ |
| 347 | static ssize_t show_fan(struct device *dev, char *buf, int nr) | 328 | static ssize_t show_fan(struct device *dev, struct device_attribute *da, |
| 329 | char *buf) | ||
| 348 | { | 330 | { |
| 349 | struct sis5595_data *data = sis5595_update_device(dev); | 331 | struct sis5595_data *data = sis5595_update_device(dev); |
| 332 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 333 | int nr = attr->index; | ||
| 350 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], | 334 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], |
| 351 | DIV_FROM_REG(data->fan_div[nr])) ); | 335 | DIV_FROM_REG(data->fan_div[nr])) ); |
| 352 | } | 336 | } |
| 353 | 337 | ||
| 354 | static ssize_t show_fan_min(struct device *dev, char *buf, int nr) | 338 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, |
| 339 | char *buf) | ||
| 355 | { | 340 | { |
| 356 | struct sis5595_data *data = sis5595_update_device(dev); | 341 | struct sis5595_data *data = sis5595_update_device(dev); |
| 342 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 343 | int nr = attr->index; | ||
| 357 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], | 344 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], |
| 358 | DIV_FROM_REG(data->fan_div[nr])) ); | 345 | DIV_FROM_REG(data->fan_div[nr])) ); |
| 359 | } | 346 | } |
| 360 | 347 | ||
| 361 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 348 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, |
| 362 | size_t count, int nr) | 349 | const char *buf, size_t count) |
| 363 | { | 350 | { |
| 364 | struct i2c_client *client = to_i2c_client(dev); | 351 | struct sis5595_data *data = dev_get_drvdata(dev); |
| 365 | struct sis5595_data *data = i2c_get_clientdata(client); | 352 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 353 | int nr = attr->index; | ||
| 366 | unsigned long val = simple_strtoul(buf, NULL, 10); | 354 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 367 | 355 | ||
| 368 | mutex_lock(&data->update_lock); | 356 | mutex_lock(&data->update_lock); |
| 369 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 357 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
| 370 | sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); | 358 | sis5595_write_value(data, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); |
| 371 | mutex_unlock(&data->update_lock); | 359 | mutex_unlock(&data->update_lock); |
| 372 | return count; | 360 | return count; |
| 373 | } | 361 | } |
| 374 | 362 | ||
| 375 | static ssize_t show_fan_div(struct device *dev, char *buf, int nr) | 363 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *da, |
| 364 | char *buf) | ||
| 376 | { | 365 | { |
| 377 | struct sis5595_data *data = sis5595_update_device(dev); | 366 | struct sis5595_data *data = sis5595_update_device(dev); |
| 367 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 368 | int nr = attr->index; | ||
| 378 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); | 369 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); |
| 379 | } | 370 | } |
| 380 | 371 | ||
| @@ -382,11 +373,12 @@ static ssize_t show_fan_div(struct device *dev, char *buf, int nr) | |||
| 382 | determined in part by the fan divisor. This follows the principle of | 373 | determined in part by the fan divisor. This follows the principle of |
| 383 | least surprise; the user doesn't expect the fan minimum to change just | 374 | least surprise; the user doesn't expect the fan minimum to change just |
| 384 | because the divisor changed. */ | 375 | because the divisor changed. */ |
| 385 | static ssize_t set_fan_div(struct device *dev, const char *buf, | 376 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, |
| 386 | size_t count, int nr) | 377 | const char *buf, size_t count) |
| 387 | { | 378 | { |
| 388 | struct i2c_client *client = to_i2c_client(dev); | 379 | struct sis5595_data *data = dev_get_drvdata(dev); |
| 389 | struct sis5595_data *data = i2c_get_clientdata(client); | 380 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 381 | int nr = attr->index; | ||
| 390 | unsigned long min; | 382 | unsigned long min; |
| 391 | unsigned long val = simple_strtoul(buf, NULL, 10); | 383 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 392 | int reg; | 384 | int reg; |
| @@ -394,7 +386,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, | |||
| 394 | mutex_lock(&data->update_lock); | 386 | mutex_lock(&data->update_lock); |
| 395 | min = FAN_FROM_REG(data->fan_min[nr], | 387 | min = FAN_FROM_REG(data->fan_min[nr], |
| 396 | DIV_FROM_REG(data->fan_div[nr])); | 388 | DIV_FROM_REG(data->fan_div[nr])); |
| 397 | reg = sis5595_read_value(client, SIS5595_REG_FANDIV); | 389 | reg = sis5595_read_value(data, SIS5595_REG_FANDIV); |
| 398 | 390 | ||
| 399 | switch (val) { | 391 | switch (val) { |
| 400 | case 1: data->fan_div[nr] = 0; break; | 392 | case 1: data->fan_div[nr] = 0; break; |
| @@ -402,7 +394,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, | |||
| 402 | case 4: data->fan_div[nr] = 2; break; | 394 | case 4: data->fan_div[nr] = 2; break; |
| 403 | case 8: data->fan_div[nr] = 3; break; | 395 | case 8: data->fan_div[nr] = 3; break; |
| 404 | default: | 396 | default: |
| 405 | dev_err(&client->dev, "fan_div value %ld not " | 397 | dev_err(dev, "fan_div value %ld not " |
| 406 | "supported. Choose one of 1, 2, 4 or 8!\n", val); | 398 | "supported. Choose one of 1, 2, 4 or 8!\n", val); |
| 407 | mutex_unlock(&data->update_lock); | 399 | mutex_unlock(&data->update_lock); |
| 408 | return -EINVAL; | 400 | return -EINVAL; |
| @@ -416,55 +408,25 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, | |||
| 416 | reg = (reg & 0x3f) | (data->fan_div[nr] << 6); | 408 | reg = (reg & 0x3f) | (data->fan_div[nr] << 6); |
| 417 | break; | 409 | break; |
| 418 | } | 410 | } |
| 419 | sis5595_write_value(client, SIS5595_REG_FANDIV, reg); | 411 | sis5595_write_value(data, SIS5595_REG_FANDIV, reg); |
| 420 | data->fan_min[nr] = | 412 | data->fan_min[nr] = |
| 421 | FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 413 | FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
| 422 | sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); | 414 | sis5595_write_value(data, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); |
| 423 | mutex_unlock(&data->update_lock); | 415 | mutex_unlock(&data->update_lock); |
| 424 | return count; | 416 | return count; |
| 425 | } | 417 | } |
| 426 | 418 | ||
| 427 | #define show_fan_offset(offset) \ | 419 | #define show_fan_offset(offset) \ |
| 428 | static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 420 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
| 429 | { \ | 421 | show_fan, NULL, offset - 1); \ |
| 430 | return show_fan(dev, buf, offset - 1); \ | 422 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ |
| 431 | } \ | 423 | show_fan_min, set_fan_min, offset - 1); \ |
| 432 | static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | 424 | static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ |
| 433 | { \ | 425 | show_fan_div, set_fan_div, offset - 1); |
| 434 | return show_fan_min(dev, buf, offset - 1); \ | ||
| 435 | } \ | ||
| 436 | static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
| 437 | { \ | ||
| 438 | return show_fan_div(dev, buf, offset - 1); \ | ||
| 439 | } \ | ||
| 440 | static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
| 441 | const char *buf, size_t count) \ | ||
| 442 | { \ | ||
| 443 | return set_fan_min(dev, buf, count, offset - 1); \ | ||
| 444 | } \ | ||
| 445 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ | ||
| 446 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
| 447 | show_fan_##offset##_min, set_fan_##offset##_min); | ||
| 448 | 426 | ||
| 449 | show_fan_offset(1); | 427 | show_fan_offset(1); |
| 450 | show_fan_offset(2); | 428 | show_fan_offset(2); |
| 451 | 429 | ||
| 452 | static ssize_t set_fan_1_div(struct device *dev, struct device_attribute *attr, const char *buf, | ||
| 453 | size_t count) | ||
| 454 | { | ||
| 455 | return set_fan_div(dev, buf, count, 0) ; | ||
| 456 | } | ||
| 457 | |||
| 458 | static ssize_t set_fan_2_div(struct device *dev, struct device_attribute *attr, const char *buf, | ||
| 459 | size_t count) | ||
| 460 | { | ||
| 461 | return set_fan_div(dev, buf, count, 1) ; | ||
| 462 | } | ||
| 463 | static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, | ||
| 464 | show_fan_1_div, set_fan_1_div); | ||
| 465 | static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, | ||
| 466 | show_fan_2_div, set_fan_2_div); | ||
| 467 | |||
| 468 | /* Alarms */ | 430 | /* Alarms */ |
| 469 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) | 431 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) |
| 470 | { | 432 | { |
| @@ -473,28 +435,37 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch | |||
| 473 | } | 435 | } |
| 474 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 436 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
| 475 | 437 | ||
| 438 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, | ||
| 439 | char *buf) | ||
| 440 | { | ||
| 441 | struct sis5595_data *data = dev_get_drvdata(dev); | ||
| 442 | return sprintf(buf, "%s\n", data->name); | ||
| 443 | } | ||
| 444 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 445 | |||
| 476 | static struct attribute *sis5595_attributes[] = { | 446 | static struct attribute *sis5595_attributes[] = { |
| 477 | &dev_attr_in0_input.attr, | 447 | &sensor_dev_attr_in0_input.dev_attr.attr, |
| 478 | &dev_attr_in0_min.attr, | 448 | &sensor_dev_attr_in0_min.dev_attr.attr, |
| 479 | &dev_attr_in0_max.attr, | 449 | &sensor_dev_attr_in0_max.dev_attr.attr, |
| 480 | &dev_attr_in1_input.attr, | 450 | &sensor_dev_attr_in1_input.dev_attr.attr, |
| 481 | &dev_attr_in1_min.attr, | 451 | &sensor_dev_attr_in1_min.dev_attr.attr, |
| 482 | &dev_attr_in1_max.attr, | 452 | &sensor_dev_attr_in1_max.dev_attr.attr, |
| 483 | &dev_attr_in2_input.attr, | 453 | &sensor_dev_attr_in2_input.dev_attr.attr, |
| 484 | &dev_attr_in2_min.attr, | 454 | &sensor_dev_attr_in2_min.dev_attr.attr, |
| 485 | &dev_attr_in2_max.attr, | 455 | &sensor_dev_attr_in2_max.dev_attr.attr, |
| 486 | &dev_attr_in3_input.attr, | 456 | &sensor_dev_attr_in3_input.dev_attr.attr, |
| 487 | &dev_attr_in3_min.attr, | 457 | &sensor_dev_attr_in3_min.dev_attr.attr, |
| 488 | &dev_attr_in3_max.attr, | 458 | &sensor_dev_attr_in3_max.dev_attr.attr, |
| 489 | 459 | ||
| 490 | &dev_attr_fan1_input.attr, | 460 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
| 491 | &dev_attr_fan1_min.attr, | 461 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
| 492 | &dev_attr_fan1_div.attr, | 462 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
| 493 | &dev_attr_fan2_input.attr, | 463 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
| 494 | &dev_attr_fan2_min.attr, | 464 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
| 495 | &dev_attr_fan2_div.attr, | 465 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
| 496 | 466 | ||
| 497 | &dev_attr_alarms.attr, | 467 | &dev_attr_alarms.attr, |
| 468 | &dev_attr_name.attr, | ||
| 498 | NULL | 469 | NULL |
| 499 | }; | 470 | }; |
| 500 | 471 | ||
| @@ -503,9 +474,9 @@ static const struct attribute_group sis5595_group = { | |||
| 503 | }; | 474 | }; |
| 504 | 475 | ||
| 505 | static struct attribute *sis5595_attributes_opt[] = { | 476 | static struct attribute *sis5595_attributes_opt[] = { |
| 506 | &dev_attr_in4_input.attr, | 477 | &sensor_dev_attr_in4_input.dev_attr.attr, |
| 507 | &dev_attr_in4_min.attr, | 478 | &sensor_dev_attr_in4_min.dev_attr.attr, |
| 508 | &dev_attr_in4_max.attr, | 479 | &sensor_dev_attr_in4_max.dev_attr.attr, |
| 509 | 480 | ||
| 510 | &dev_attr_temp1_input.attr, | 481 | &dev_attr_temp1_input.attr, |
| 511 | &dev_attr_temp1_max.attr, | 482 | &dev_attr_temp1_max.attr, |
| @@ -518,68 +489,35 @@ static const struct attribute_group sis5595_group_opt = { | |||
| 518 | }; | 489 | }; |
| 519 | 490 | ||
| 520 | /* This is called when the module is loaded */ | 491 | /* This is called when the module is loaded */ |
| 521 | static int sis5595_detect(struct i2c_adapter *adapter) | 492 | static int __devinit sis5595_probe(struct platform_device *pdev) |
| 522 | { | 493 | { |
| 523 | int err = 0; | 494 | int err = 0; |
| 524 | int i; | 495 | int i; |
| 525 | struct i2c_client *new_client; | ||
| 526 | struct sis5595_data *data; | 496 | struct sis5595_data *data; |
| 497 | struct resource *res; | ||
| 527 | char val; | 498 | char val; |
| 528 | u16 a; | ||
| 529 | 499 | ||
| 530 | if (force_addr) | ||
| 531 | address = force_addr & ~(SIS5595_EXTENT - 1); | ||
| 532 | /* Reserve the ISA region */ | 500 | /* Reserve the ISA region */ |
| 533 | if (!request_region(address, SIS5595_EXTENT, | 501 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 502 | if (!request_region(res->start, SIS5595_EXTENT, | ||
| 534 | sis5595_driver.driver.name)) { | 503 | sis5595_driver.driver.name)) { |
| 535 | err = -EBUSY; | 504 | err = -EBUSY; |
| 536 | goto exit; | 505 | goto exit; |
| 537 | } | 506 | } |
| 538 | if (force_addr) { | ||
| 539 | dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", address); | ||
| 540 | if (PCIBIOS_SUCCESSFUL != | ||
| 541 | pci_write_config_word(s_bridge, SIS5595_BASE_REG, address)) | ||
| 542 | goto exit_release; | ||
| 543 | if (PCIBIOS_SUCCESSFUL != | ||
| 544 | pci_read_config_word(s_bridge, SIS5595_BASE_REG, &a)) | ||
| 545 | goto exit_release; | ||
| 546 | if ((a & ~(SIS5595_EXTENT - 1)) != address) | ||
| 547 | /* doesn't work for some chips? */ | ||
| 548 | goto exit_release; | ||
| 549 | } | ||
| 550 | |||
| 551 | if (PCIBIOS_SUCCESSFUL != | ||
| 552 | pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) { | ||
| 553 | goto exit_release; | ||
| 554 | } | ||
| 555 | if ((val & 0x80) == 0) { | ||
| 556 | if (PCIBIOS_SUCCESSFUL != | ||
| 557 | pci_write_config_byte(s_bridge, SIS5595_ENABLE_REG, | ||
| 558 | val | 0x80)) | ||
| 559 | goto exit_release; | ||
| 560 | if (PCIBIOS_SUCCESSFUL != | ||
| 561 | pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) | ||
| 562 | goto exit_release; | ||
| 563 | if ((val & 0x80) == 0) | ||
| 564 | /* doesn't work for some chips! */ | ||
| 565 | goto exit_release; | ||
| 566 | } | ||
| 567 | 507 | ||
| 568 | if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) { | 508 | if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) { |
| 569 | err = -ENOMEM; | 509 | err = -ENOMEM; |
| 570 | goto exit_release; | 510 | goto exit_release; |
| 571 | } | 511 | } |
| 572 | 512 | ||
| 573 | new_client = &data->client; | ||
| 574 | new_client->addr = address; | ||
| 575 | mutex_init(&data->lock); | 513 | mutex_init(&data->lock); |
| 576 | i2c_set_clientdata(new_client, data); | 514 | mutex_init(&data->update_lock); |
| 577 | new_client->adapter = adapter; | 515 | data->addr = res->start; |
| 578 | new_client->driver = &sis5595_driver; | 516 | data->name = "sis5595"; |
| 579 | new_client->flags = 0; | 517 | platform_set_drvdata(pdev, data); |
| 580 | 518 | ||
| 581 | /* Check revision and pin registers to determine whether 4 or 5 voltages */ | 519 | /* Check revision and pin registers to determine whether 4 or 5 voltages */ |
| 582 | pci_read_config_byte(s_bridge, SIS5595_REVISION_REG, &(data->revision)); | 520 | pci_read_config_byte(s_bridge, PCI_REVISION_ID, &data->revision); |
| 583 | /* 4 voltages, 1 temp */ | 521 | /* 4 voltages, 1 temp */ |
| 584 | data->maxins = 3; | 522 | data->maxins = 3; |
| 585 | if (data->revision >= REV2MIN) { | 523 | if (data->revision >= REV2MIN) { |
| @@ -589,47 +527,37 @@ static int sis5595_detect(struct i2c_adapter *adapter) | |||
| 589 | data->maxins = 4; | 527 | data->maxins = 4; |
| 590 | } | 528 | } |
| 591 | 529 | ||
| 592 | /* Fill in the remaining client fields and put it into the global list */ | ||
| 593 | strlcpy(new_client->name, "sis5595", I2C_NAME_SIZE); | ||
| 594 | |||
| 595 | data->valid = 0; | ||
| 596 | mutex_init(&data->update_lock); | ||
| 597 | |||
| 598 | /* Tell the I2C layer a new client has arrived */ | ||
| 599 | if ((err = i2c_attach_client(new_client))) | ||
| 600 | goto exit_free; | ||
| 601 | |||
| 602 | /* Initialize the SIS5595 chip */ | 530 | /* Initialize the SIS5595 chip */ |
| 603 | sis5595_init_client(new_client); | 531 | sis5595_init_device(data); |
| 604 | 532 | ||
| 605 | /* A few vars need to be filled upon startup */ | 533 | /* A few vars need to be filled upon startup */ |
| 606 | for (i = 0; i < 2; i++) { | 534 | for (i = 0; i < 2; i++) { |
| 607 | data->fan_min[i] = sis5595_read_value(new_client, | 535 | data->fan_min[i] = sis5595_read_value(data, |
| 608 | SIS5595_REG_FAN_MIN(i)); | 536 | SIS5595_REG_FAN_MIN(i)); |
| 609 | } | 537 | } |
| 610 | 538 | ||
| 611 | /* Register sysfs hooks */ | 539 | /* Register sysfs hooks */ |
| 612 | if ((err = sysfs_create_group(&new_client->dev.kobj, &sis5595_group))) | 540 | if ((err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group))) |
| 613 | goto exit_detach; | 541 | goto exit_free; |
| 614 | if (data->maxins == 4) { | 542 | if (data->maxins == 4) { |
| 615 | if ((err = device_create_file(&new_client->dev, | 543 | if ((err = device_create_file(&pdev->dev, |
| 616 | &dev_attr_in4_input)) | 544 | &sensor_dev_attr_in4_input.dev_attr)) |
| 617 | || (err = device_create_file(&new_client->dev, | 545 | || (err = device_create_file(&pdev->dev, |
| 618 | &dev_attr_in4_min)) | 546 | &sensor_dev_attr_in4_min.dev_attr)) |
| 619 | || (err = device_create_file(&new_client->dev, | 547 | || (err = device_create_file(&pdev->dev, |
| 620 | &dev_attr_in4_max))) | 548 | &sensor_dev_attr_in4_max.dev_attr))) |
| 621 | goto exit_remove_files; | 549 | goto exit_remove_files; |
| 622 | } else { | 550 | } else { |
| 623 | if ((err = device_create_file(&new_client->dev, | 551 | if ((err = device_create_file(&pdev->dev, |
| 624 | &dev_attr_temp1_input)) | 552 | &dev_attr_temp1_input)) |
| 625 | || (err = device_create_file(&new_client->dev, | 553 | || (err = device_create_file(&pdev->dev, |
| 626 | &dev_attr_temp1_max)) | 554 | &dev_attr_temp1_max)) |
| 627 | || (err = device_create_file(&new_client->dev, | 555 | || (err = device_create_file(&pdev->dev, |
| 628 | &dev_attr_temp1_max_hyst))) | 556 | &dev_attr_temp1_max_hyst))) |
| 629 | goto exit_remove_files; | 557 | goto exit_remove_files; |
| 630 | } | 558 | } |
| 631 | 559 | ||
| 632 | data->class_dev = hwmon_device_register(&new_client->dev); | 560 | data->class_dev = hwmon_device_register(&pdev->dev); |
| 633 | if (IS_ERR(data->class_dev)) { | 561 | if (IS_ERR(data->class_dev)) { |
| 634 | err = PTR_ERR(data->class_dev); | 562 | err = PTR_ERR(data->class_dev); |
| 635 | goto exit_remove_files; | 563 | goto exit_remove_files; |
| @@ -638,32 +566,26 @@ static int sis5595_detect(struct i2c_adapter *adapter) | |||
| 638 | return 0; | 566 | return 0; |
| 639 | 567 | ||
| 640 | exit_remove_files: | 568 | exit_remove_files: |
| 641 | sysfs_remove_group(&new_client->dev.kobj, &sis5595_group); | 569 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); |
| 642 | sysfs_remove_group(&new_client->dev.kobj, &sis5595_group_opt); | 570 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); |
| 643 | exit_detach: | ||
| 644 | i2c_detach_client(new_client); | ||
| 645 | exit_free: | 571 | exit_free: |
| 646 | kfree(data); | 572 | kfree(data); |
| 647 | exit_release: | 573 | exit_release: |
| 648 | release_region(address, SIS5595_EXTENT); | 574 | release_region(res->start, SIS5595_EXTENT); |
| 649 | exit: | 575 | exit: |
| 650 | return err; | 576 | return err; |
| 651 | } | 577 | } |
| 652 | 578 | ||
| 653 | static int sis5595_detach_client(struct i2c_client *client) | 579 | static int __devexit sis5595_remove(struct platform_device *pdev) |
| 654 | { | 580 | { |
| 655 | struct sis5595_data *data = i2c_get_clientdata(client); | 581 | struct sis5595_data *data = platform_get_drvdata(pdev); |
| 656 | int err; | ||
| 657 | 582 | ||
| 658 | hwmon_device_unregister(data->class_dev); | 583 | hwmon_device_unregister(data->class_dev); |
| 659 | sysfs_remove_group(&client->dev.kobj, &sis5595_group); | 584 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); |
| 660 | sysfs_remove_group(&client->dev.kobj, &sis5595_group_opt); | 585 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); |
| 661 | |||
| 662 | if ((err = i2c_detach_client(client))) | ||
| 663 | return err; | ||
| 664 | |||
| 665 | release_region(client->addr, SIS5595_EXTENT); | ||
| 666 | 586 | ||
| 587 | release_region(data->addr, SIS5595_EXTENT); | ||
| 588 | platform_set_drvdata(pdev, NULL); | ||
| 667 | kfree(data); | 589 | kfree(data); |
| 668 | 590 | ||
| 669 | return 0; | 591 | return 0; |
| @@ -671,41 +593,37 @@ static int sis5595_detach_client(struct i2c_client *client) | |||
| 671 | 593 | ||
| 672 | 594 | ||
| 673 | /* ISA access must be locked explicitly. */ | 595 | /* ISA access must be locked explicitly. */ |
| 674 | static int sis5595_read_value(struct i2c_client *client, u8 reg) | 596 | static int sis5595_read_value(struct sis5595_data *data, u8 reg) |
| 675 | { | 597 | { |
| 676 | int res; | 598 | int res; |
| 677 | 599 | ||
| 678 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
| 679 | mutex_lock(&data->lock); | 600 | mutex_lock(&data->lock); |
| 680 | outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); | 601 | outb_p(reg, data->addr + SIS5595_ADDR_REG_OFFSET); |
| 681 | res = inb_p(client->addr + SIS5595_DATA_REG_OFFSET); | 602 | res = inb_p(data->addr + SIS5595_DATA_REG_OFFSET); |
| 682 | mutex_unlock(&data->lock); | 603 | mutex_unlock(&data->lock); |
| 683 | return res; | 604 | return res; |
| 684 | } | 605 | } |
| 685 | 606 | ||
| 686 | static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value) | 607 | static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value) |
| 687 | { | 608 | { |
| 688 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
| 689 | mutex_lock(&data->lock); | 609 | mutex_lock(&data->lock); |
| 690 | outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); | 610 | outb_p(reg, data->addr + SIS5595_ADDR_REG_OFFSET); |
| 691 | outb_p(value, client->addr + SIS5595_DATA_REG_OFFSET); | 611 | outb_p(value, data->addr + SIS5595_DATA_REG_OFFSET); |
| 692 | mutex_unlock(&data->lock); | 612 | mutex_unlock(&data->lock); |
| 693 | return 0; | ||
| 694 | } | 613 | } |
| 695 | 614 | ||
| 696 | /* Called when we have found a new SIS5595. */ | 615 | /* Called when we have found a new SIS5595. */ |
| 697 | static void sis5595_init_client(struct i2c_client *client) | 616 | static void __devinit sis5595_init_device(struct sis5595_data *data) |
| 698 | { | 617 | { |
| 699 | u8 config = sis5595_read_value(client, SIS5595_REG_CONFIG); | 618 | u8 config = sis5595_read_value(data, SIS5595_REG_CONFIG); |
| 700 | if (!(config & 0x01)) | 619 | if (!(config & 0x01)) |
| 701 | sis5595_write_value(client, SIS5595_REG_CONFIG, | 620 | sis5595_write_value(data, SIS5595_REG_CONFIG, |
| 702 | (config & 0xf7) | 0x01); | 621 | (config & 0xf7) | 0x01); |
| 703 | } | 622 | } |
| 704 | 623 | ||
| 705 | static struct sis5595_data *sis5595_update_device(struct device *dev) | 624 | static struct sis5595_data *sis5595_update_device(struct device *dev) |
| 706 | { | 625 | { |
| 707 | struct i2c_client *client = to_i2c_client(dev); | 626 | struct sis5595_data *data = dev_get_drvdata(dev); |
| 708 | struct sis5595_data *data = i2c_get_clientdata(client); | ||
| 709 | int i; | 627 | int i; |
| 710 | 628 | ||
| 711 | mutex_lock(&data->update_lock); | 629 | mutex_lock(&data->update_lock); |
| @@ -715,35 +633,35 @@ static struct sis5595_data *sis5595_update_device(struct device *dev) | |||
| 715 | 633 | ||
| 716 | for (i = 0; i <= data->maxins; i++) { | 634 | for (i = 0; i <= data->maxins; i++) { |
| 717 | data->in[i] = | 635 | data->in[i] = |
| 718 | sis5595_read_value(client, SIS5595_REG_IN(i)); | 636 | sis5595_read_value(data, SIS5595_REG_IN(i)); |
| 719 | data->in_min[i] = | 637 | data->in_min[i] = |
| 720 | sis5595_read_value(client, | 638 | sis5595_read_value(data, |
| 721 | SIS5595_REG_IN_MIN(i)); | 639 | SIS5595_REG_IN_MIN(i)); |
| 722 | data->in_max[i] = | 640 | data->in_max[i] = |
| 723 | sis5595_read_value(client, | 641 | sis5595_read_value(data, |
| 724 | SIS5595_REG_IN_MAX(i)); | 642 | SIS5595_REG_IN_MAX(i)); |
| 725 | } | 643 | } |
| 726 | for (i = 0; i < 2; i++) { | 644 | for (i = 0; i < 2; i++) { |
| 727 | data->fan[i] = | 645 | data->fan[i] = |
| 728 | sis5595_read_value(client, SIS5595_REG_FAN(i)); | 646 | sis5595_read_value(data, SIS5595_REG_FAN(i)); |
| 729 | data->fan_min[i] = | 647 | data->fan_min[i] = |
| 730 | sis5595_read_value(client, | 648 | sis5595_read_value(data, |
| 731 | SIS5595_REG_FAN_MIN(i)); | 649 | SIS5595_REG_FAN_MIN(i)); |
| 732 | } | 650 | } |
| 733 | if (data->maxins == 3) { | 651 | if (data->maxins == 3) { |
| 734 | data->temp = | 652 | data->temp = |
| 735 | sis5595_read_value(client, SIS5595_REG_TEMP); | 653 | sis5595_read_value(data, SIS5595_REG_TEMP); |
| 736 | data->temp_over = | 654 | data->temp_over = |
| 737 | sis5595_read_value(client, SIS5595_REG_TEMP_OVER); | 655 | sis5595_read_value(data, SIS5595_REG_TEMP_OVER); |
| 738 | data->temp_hyst = | 656 | data->temp_hyst = |
| 739 | sis5595_read_value(client, SIS5595_REG_TEMP_HYST); | 657 | sis5595_read_value(data, SIS5595_REG_TEMP_HYST); |
| 740 | } | 658 | } |
| 741 | i = sis5595_read_value(client, SIS5595_REG_FANDIV); | 659 | i = sis5595_read_value(data, SIS5595_REG_FANDIV); |
| 742 | data->fan_div[0] = (i >> 4) & 0x03; | 660 | data->fan_div[0] = (i >> 4) & 0x03; |
| 743 | data->fan_div[1] = i >> 6; | 661 | data->fan_div[1] = i >> 6; |
| 744 | data->alarms = | 662 | data->alarms = |
| 745 | sis5595_read_value(client, SIS5595_REG_ALARM1) | | 663 | sis5595_read_value(data, SIS5595_REG_ALARM1) | |
| 746 | (sis5595_read_value(client, SIS5595_REG_ALARM2) << 8); | 664 | (sis5595_read_value(data, SIS5595_REG_ALARM2) << 8); |
| 747 | data->last_updated = jiffies; | 665 | data->last_updated = jiffies; |
| 748 | data->valid = 1; | 666 | data->valid = 1; |
| 749 | } | 667 | } |
| @@ -774,10 +692,50 @@ static int blacklist[] __devinitdata = { | |||
| 774 | PCI_DEVICE_ID_SI_5598, | 692 | PCI_DEVICE_ID_SI_5598, |
| 775 | 0 }; | 693 | 0 }; |
| 776 | 694 | ||
| 695 | static int __devinit sis5595_device_add(unsigned short address) | ||
| 696 | { | ||
| 697 | struct resource res = { | ||
| 698 | .start = address, | ||
| 699 | .end = address + SIS5595_EXTENT - 1, | ||
| 700 | .name = "sis5595", | ||
| 701 | .flags = IORESOURCE_IO, | ||
| 702 | }; | ||
| 703 | int err; | ||
| 704 | |||
| 705 | pdev = platform_device_alloc("sis5595", address); | ||
| 706 | if (!pdev) { | ||
| 707 | err = -ENOMEM; | ||
| 708 | printk(KERN_ERR "sis5595: Device allocation failed\n"); | ||
| 709 | goto exit; | ||
| 710 | } | ||
| 711 | |||
| 712 | err = platform_device_add_resources(pdev, &res, 1); | ||
| 713 | if (err) { | ||
| 714 | printk(KERN_ERR "sis5595: Device resource addition failed " | ||
| 715 | "(%d)\n", err); | ||
| 716 | goto exit_device_put; | ||
| 717 | } | ||
| 718 | |||
| 719 | err = platform_device_add(pdev); | ||
| 720 | if (err) { | ||
| 721 | printk(KERN_ERR "sis5595: Device addition failed (%d)\n", | ||
| 722 | err); | ||
| 723 | goto exit_device_put; | ||
| 724 | } | ||
| 725 | |||
| 726 | return 0; | ||
| 727 | |||
| 728 | exit_device_put: | ||
| 729 | platform_device_put(pdev); | ||
| 730 | exit: | ||
| 731 | return err; | ||
| 732 | } | ||
| 733 | |||
| 777 | static int __devinit sis5595_pci_probe(struct pci_dev *dev, | 734 | static int __devinit sis5595_pci_probe(struct pci_dev *dev, |
| 778 | const struct pci_device_id *id) | 735 | const struct pci_device_id *id) |
| 779 | { | 736 | { |
| 780 | u16 val; | 737 | u16 address; |
| 738 | u8 enable; | ||
| 781 | int *i; | 739 | int *i; |
| 782 | 740 | ||
| 783 | for (i = blacklist; *i != 0; i++) { | 741 | for (i = blacklist; *i != 0; i++) { |
| @@ -790,27 +748,68 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev, | |||
| 790 | } | 748 | } |
| 791 | } | 749 | } |
| 792 | 750 | ||
| 751 | force_addr &= ~(SIS5595_EXTENT - 1); | ||
| 752 | if (force_addr) { | ||
| 753 | dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", force_addr); | ||
| 754 | pci_write_config_word(dev, SIS5595_BASE_REG, force_addr); | ||
| 755 | } | ||
| 756 | |||
| 793 | if (PCIBIOS_SUCCESSFUL != | 757 | if (PCIBIOS_SUCCESSFUL != |
| 794 | pci_read_config_word(dev, SIS5595_BASE_REG, &val)) | 758 | pci_read_config_word(dev, SIS5595_BASE_REG, &address)) { |
| 759 | dev_err(&dev->dev, "Failed to read ISA address\n"); | ||
| 795 | return -ENODEV; | 760 | return -ENODEV; |
| 761 | } | ||
| 796 | 762 | ||
| 797 | address = val & ~(SIS5595_EXTENT - 1); | 763 | address &= ~(SIS5595_EXTENT - 1); |
| 798 | if (address == 0 && force_addr == 0) { | 764 | if (!address) { |
| 799 | dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n"); | 765 | dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n"); |
| 800 | return -ENODEV; | 766 | return -ENODEV; |
| 801 | } | 767 | } |
| 768 | if (force_addr && address != force_addr) { | ||
| 769 | /* doesn't work for some chips? */ | ||
| 770 | dev_err(&dev->dev, "Failed to force ISA address\n"); | ||
| 771 | return -ENODEV; | ||
| 772 | } | ||
| 802 | 773 | ||
| 803 | s_bridge = pci_dev_get(dev); | 774 | if (PCIBIOS_SUCCESSFUL != |
| 804 | if (i2c_isa_add_driver(&sis5595_driver)) { | 775 | pci_read_config_byte(dev, SIS5595_ENABLE_REG, &enable)) { |
| 805 | pci_dev_put(s_bridge); | 776 | dev_err(&dev->dev, "Failed to read enable register\n"); |
| 806 | s_bridge = NULL; | 777 | return -ENODEV; |
| 778 | } | ||
| 779 | if (!(enable & 0x80)) { | ||
| 780 | if ((PCIBIOS_SUCCESSFUL != | ||
| 781 | pci_write_config_byte(dev, SIS5595_ENABLE_REG, | ||
| 782 | enable | 0x80)) | ||
| 783 | || (PCIBIOS_SUCCESSFUL != | ||
| 784 | pci_read_config_byte(dev, SIS5595_ENABLE_REG, &enable)) | ||
| 785 | || (!(enable & 0x80))) { | ||
| 786 | /* doesn't work for some chips! */ | ||
| 787 | dev_err(&dev->dev, "Failed to enable HWM device\n"); | ||
| 788 | return -ENODEV; | ||
| 789 | } | ||
| 807 | } | 790 | } |
| 808 | 791 | ||
| 792 | if (platform_driver_register(&sis5595_driver)) { | ||
| 793 | dev_dbg(&dev->dev, "Failed to register sis5595 driver\n"); | ||
| 794 | goto exit; | ||
| 795 | } | ||
| 796 | |||
| 797 | s_bridge = pci_dev_get(dev); | ||
| 798 | /* Sets global pdev as a side effect */ | ||
| 799 | if (sis5595_device_add(address)) | ||
| 800 | goto exit_unregister; | ||
| 801 | |||
| 809 | /* Always return failure here. This is to allow other drivers to bind | 802 | /* Always return failure here. This is to allow other drivers to bind |
| 810 | * to this pci device. We don't really want to have control over the | 803 | * to this pci device. We don't really want to have control over the |
| 811 | * pci device, we only wanted to read as few register values from it. | 804 | * pci device, we only wanted to read as few register values from it. |
| 812 | */ | 805 | */ |
| 813 | return -ENODEV; | 806 | return -ENODEV; |
| 807 | |||
| 808 | exit_unregister: | ||
| 809 | pci_dev_put(dev); | ||
| 810 | platform_driver_unregister(&sis5595_driver); | ||
| 811 | exit: | ||
| 812 | return -ENODEV; | ||
| 814 | } | 813 | } |
| 815 | 814 | ||
| 816 | static struct pci_driver sis5595_pci_driver = { | 815 | static struct pci_driver sis5595_pci_driver = { |
| @@ -828,7 +827,8 @@ static void __exit sm_sis5595_exit(void) | |||
| 828 | { | 827 | { |
| 829 | pci_unregister_driver(&sis5595_pci_driver); | 828 | pci_unregister_driver(&sis5595_pci_driver); |
| 830 | if (s_bridge != NULL) { | 829 | if (s_bridge != NULL) { |
| 831 | i2c_isa_del_driver(&sis5595_driver); | 830 | platform_device_unregister(pdev); |
| 831 | platform_driver_unregister(&sis5595_driver); | ||
| 832 | pci_dev_put(s_bridge); | 832 | pci_dev_put(s_bridge); |
| 833 | s_bridge = NULL; | 833 | s_bridge = NULL; |
| 834 | } | 834 | } |
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 943abbd95ab5..45266b30ce1d 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c | |||
| @@ -174,6 +174,8 @@ static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); | |||
| 174 | REG: count of 90kHz pulses / revolution */ | 174 | REG: count of 90kHz pulses / revolution */ |
| 175 | static int fan_from_reg(u16 reg) | 175 | static int fan_from_reg(u16 reg) |
| 176 | { | 176 | { |
| 177 | if (reg == 0 || reg == 0xffff) | ||
| 178 | return 0; | ||
| 177 | return 90000 * 60 / reg; | 179 | return 90000 * 60 / reg; |
| 178 | } | 180 | } |
| 179 | 181 | ||
| @@ -333,7 +335,7 @@ static int __init smsc47b397_find(unsigned short *addr) | |||
| 333 | superio_enter(); | 335 | superio_enter(); |
| 334 | id = superio_inb(SUPERIO_REG_DEVID); | 336 | id = superio_inb(SUPERIO_REG_DEVID); |
| 335 | 337 | ||
| 336 | if ((id != 0x6f) && (id != 0x81)) { | 338 | if ((id != 0x6f) && (id != 0x81) && (id != 0x85)) { |
| 337 | superio_exit(); | 339 | superio_exit(); |
| 338 | return -ENODEV; | 340 | return -ENODEV; |
| 339 | } | 341 | } |
| @@ -346,7 +348,8 @@ static int __init smsc47b397_find(unsigned short *addr) | |||
| 346 | 348 | ||
| 347 | printk(KERN_INFO DRVNAME ": found SMSC %s " | 349 | printk(KERN_INFO DRVNAME ": found SMSC %s " |
| 348 | "(base address 0x%04x, revision %u)\n", | 350 | "(base address 0x%04x, revision %u)\n", |
| 349 | id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev); | 351 | id == 0x81 ? "SCH5307-NS" : id == 0x85 ? "SCH5317" : |
| 352 | "LPC47B397-NC", *addr, rev); | ||
| 350 | 353 | ||
| 351 | superio_exit(); | 354 | superio_exit(); |
| 352 | return 0; | 355 | return 0; |
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 1e21c8cc948f..1de2f2be8708 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
| @@ -597,6 +597,7 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) | |||
| 597 | error_remove_files: | 597 | error_remove_files: |
| 598 | sysfs_remove_group(&dev->kobj, &smsc47m1_group); | 598 | sysfs_remove_group(&dev->kobj, &smsc47m1_group); |
| 599 | error_free: | 599 | error_free: |
| 600 | platform_set_drvdata(pdev, NULL); | ||
| 600 | kfree(data); | 601 | kfree(data); |
| 601 | error_release: | 602 | error_release: |
| 602 | release_region(res->start, SMSC_EXTENT); | 603 | release_region(res->start, SMSC_EXTENT); |
| @@ -608,12 +609,12 @@ static int __devexit smsc47m1_remove(struct platform_device *pdev) | |||
| 608 | struct smsc47m1_data *data = platform_get_drvdata(pdev); | 609 | struct smsc47m1_data *data = platform_get_drvdata(pdev); |
| 609 | struct resource *res; | 610 | struct resource *res; |
| 610 | 611 | ||
| 611 | platform_set_drvdata(pdev, NULL); | ||
| 612 | hwmon_device_unregister(data->class_dev); | 612 | hwmon_device_unregister(data->class_dev); |
| 613 | sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); | 613 | sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); |
| 614 | 614 | ||
| 615 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 615 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 616 | release_region(res->start, SMSC_EXTENT); | 616 | release_region(res->start, SMSC_EXTENT); |
| 617 | platform_set_drvdata(pdev, NULL); | ||
| 617 | kfree(data); | 618 | kfree(data); |
| 618 | 619 | ||
| 619 | return 0; | 620 | return 0; |
| @@ -693,15 +694,12 @@ static int __init smsc47m1_device_add(unsigned short address, | |||
| 693 | goto exit_device_put; | 694 | goto exit_device_put; |
| 694 | } | 695 | } |
| 695 | 696 | ||
| 696 | pdev->dev.platform_data = kmalloc(sizeof(struct smsc47m1_sio_data), | 697 | err = platform_device_add_data(pdev, sio_data, |
| 697 | GFP_KERNEL); | 698 | sizeof(struct smsc47m1_sio_data)); |
| 698 | if (!pdev->dev.platform_data) { | 699 | if (err) { |
| 699 | err = -ENOMEM; | ||
| 700 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | 700 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); |
| 701 | goto exit_device_put; | 701 | goto exit_device_put; |
| 702 | } | 702 | } |
| 703 | memcpy(pdev->dev.platform_data, sio_data, | ||
| 704 | sizeof(struct smsc47m1_sio_data)); | ||
| 705 | 703 | ||
| 706 | err = platform_device_add(pdev); | 704 | err = platform_device_add(pdev); |
| 707 | if (err) { | 705 | if (err) { |
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index a012f396f354..d3a3ba04cb0f 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/hwmon-vid.h> | 31 | #include <linux/hwmon-vid.h> |
| 32 | #include <linux/err.h> | 32 | #include <linux/err.h> |
| 33 | #include <linux/sysfs.h> | 33 | #include <linux/sysfs.h> |
| 34 | #include <linux/mutex.h> | ||
| 34 | 35 | ||
| 35 | /* Addresses to scan */ | 36 | /* Addresses to scan */ |
| 36 | static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; | 37 | static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; |
| @@ -97,7 +98,7 @@ static inline int TEMP_FROM_REG(s8 val) | |||
| 97 | struct smsc47m192_data { | 98 | struct smsc47m192_data { |
| 98 | struct i2c_client client; | 99 | struct i2c_client client; |
| 99 | struct class_device *class_dev; | 100 | struct class_device *class_dev; |
| 100 | struct semaphore update_lock; | 101 | struct mutex update_lock; |
| 101 | char valid; /* !=0 if following fields are valid */ | 102 | char valid; /* !=0 if following fields are valid */ |
| 102 | unsigned long last_updated; /* In jiffies */ | 103 | unsigned long last_updated; /* In jiffies */ |
| 103 | 104 | ||
| @@ -164,11 +165,11 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | |||
| 164 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 165 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
| 165 | unsigned long val = simple_strtoul(buf, NULL, 10); | 166 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 166 | 167 | ||
| 167 | down(&data->update_lock); | 168 | mutex_lock(&data->update_lock); |
| 168 | data->in_min[nr] = IN_TO_REG(val, nr); | 169 | data->in_min[nr] = IN_TO_REG(val, nr); |
| 169 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr), | 170 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr), |
| 170 | data->in_min[nr]); | 171 | data->in_min[nr]); |
| 171 | up(&data->update_lock); | 172 | mutex_unlock(&data->update_lock); |
| 172 | return count; | 173 | return count; |
| 173 | } | 174 | } |
| 174 | 175 | ||
| @@ -181,11 +182,11 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | |||
| 181 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 182 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
| 182 | unsigned long val = simple_strtoul(buf, NULL, 10); | 183 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 183 | 184 | ||
| 184 | down(&data->update_lock); | 185 | mutex_lock(&data->update_lock); |
| 185 | data->in_max[nr] = IN_TO_REG(val, nr); | 186 | data->in_max[nr] = IN_TO_REG(val, nr); |
| 186 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr), | 187 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr), |
| 187 | data->in_max[nr]); | 188 | data->in_max[nr]); |
| 188 | up(&data->update_lock); | 189 | mutex_unlock(&data->update_lock); |
| 189 | return count; | 190 | return count; |
| 190 | } | 191 | } |
| 191 | 192 | ||
| @@ -243,11 +244,11 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
| 243 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 244 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
| 244 | long val = simple_strtol(buf, NULL, 10); | 245 | long val = simple_strtol(buf, NULL, 10); |
| 245 | 246 | ||
| 246 | down(&data->update_lock); | 247 | mutex_lock(&data->update_lock); |
| 247 | data->temp_min[nr] = TEMP_TO_REG(val); | 248 | data->temp_min[nr] = TEMP_TO_REG(val); |
| 248 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr], | 249 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr], |
| 249 | data->temp_min[nr]); | 250 | data->temp_min[nr]); |
| 250 | up(&data->update_lock); | 251 | mutex_unlock(&data->update_lock); |
| 251 | return count; | 252 | return count; |
| 252 | } | 253 | } |
| 253 | 254 | ||
| @@ -260,11 +261,11 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
| 260 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 261 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
| 261 | long val = simple_strtol(buf, NULL, 10); | 262 | long val = simple_strtol(buf, NULL, 10); |
| 262 | 263 | ||
| 263 | down(&data->update_lock); | 264 | mutex_lock(&data->update_lock); |
| 264 | data->temp_max[nr] = TEMP_TO_REG(val); | 265 | data->temp_max[nr] = TEMP_TO_REG(val); |
| 265 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr], | 266 | i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr], |
| 266 | data->temp_max[nr]); | 267 | data->temp_max[nr]); |
| 267 | up(&data->update_lock); | 268 | mutex_unlock(&data->update_lock); |
| 268 | return count; | 269 | return count; |
| 269 | } | 270 | } |
| 270 | 271 | ||
| @@ -287,7 +288,7 @@ static ssize_t set_temp_offset(struct device *dev, struct device_attribute | |||
| 287 | u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); | 288 | u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR); |
| 288 | long val = simple_strtol(buf, NULL, 10); | 289 | long val = simple_strtol(buf, NULL, 10); |
| 289 | 290 | ||
| 290 | down(&data->update_lock); | 291 | mutex_lock(&data->update_lock); |
| 291 | data->temp_offset[nr] = TEMP_TO_REG(val); | 292 | data->temp_offset[nr] = TEMP_TO_REG(val); |
| 292 | if (nr>1) | 293 | if (nr>1) |
| 293 | i2c_smbus_write_byte_data(client, | 294 | i2c_smbus_write_byte_data(client, |
| @@ -303,7 +304,7 @@ static ssize_t set_temp_offset(struct device *dev, struct device_attribute | |||
| 303 | } else if ((sfr & 0x10) == (nr==0 ? 0x10 : 0)) | 304 | } else if ((sfr & 0x10) == (nr==0 ? 0x10 : 0)) |
| 304 | i2c_smbus_write_byte_data(client, | 305 | i2c_smbus_write_byte_data(client, |
| 305 | SMSC47M192_REG_TEMP_OFFSET(nr), 0); | 306 | SMSC47M192_REG_TEMP_OFFSET(nr), 0); |
| 306 | up(&data->update_lock); | 307 | mutex_unlock(&data->update_lock); |
| 307 | return count; | 308 | return count; |
| 308 | } | 309 | } |
| 309 | 310 | ||
| @@ -360,8 +361,8 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | |||
| 360 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0x0010); | 361 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0x0010); |
| 361 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0x0020); | 362 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0x0020); |
| 362 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0x0040); | 363 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0x0040); |
| 363 | static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 0x4000); | 364 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 0x4000); |
| 364 | static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 0x8000); | 365 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 0x8000); |
| 365 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0x0001); | 366 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0x0001); |
| 366 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0x0002); | 367 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0x0002); |
| 367 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 0x0004); | 368 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 0x0004); |
| @@ -411,13 +412,13 @@ static struct attribute *smsc47m192_attributes[] = { | |||
| 411 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 412 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
| 412 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | 413 | &sensor_dev_attr_temp2_offset.dev_attr.attr, |
| 413 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | 414 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, |
| 414 | &sensor_dev_attr_temp2_input_fault.dev_attr.attr, | 415 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
| 415 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 416 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
| 416 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 417 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
| 417 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 418 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
| 418 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | 419 | &sensor_dev_attr_temp3_offset.dev_attr.attr, |
| 419 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | 420 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, |
| 420 | &sensor_dev_attr_temp3_input_fault.dev_attr.attr, | 421 | &sensor_dev_attr_temp3_fault.dev_attr.attr, |
| 421 | 422 | ||
| 422 | &dev_attr_cpu0_vid.attr, | 423 | &dev_attr_cpu0_vid.attr, |
| 423 | &dev_attr_vrm.attr, | 424 | &dev_attr_vrm.attr, |
| @@ -531,7 +532,7 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, | |||
| 531 | /* Fill in the remaining client fields and put into the global list */ | 532 | /* Fill in the remaining client fields and put into the global list */ |
| 532 | strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE); | 533 | strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE); |
| 533 | data->vrm = vid_which_vrm(); | 534 | data->vrm = vid_which_vrm(); |
| 534 | init_MUTEX(&data->update_lock); | 535 | mutex_init(&data->update_lock); |
| 535 | 536 | ||
| 536 | /* Tell the I2C layer a new client has arrived */ | 537 | /* Tell the I2C layer a new client has arrived */ |
| 537 | if ((err = i2c_attach_client(client))) | 538 | if ((err = i2c_attach_client(client))) |
| @@ -594,7 +595,7 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) | |||
| 594 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 595 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
| 595 | int i, config; | 596 | int i, config; |
| 596 | 597 | ||
| 597 | down(&data->update_lock); | 598 | mutex_lock(&data->update_lock); |
| 598 | 599 | ||
| 599 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 600 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
| 600 | || !data->valid) { | 601 | || !data->valid) { |
| @@ -645,7 +646,7 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev) | |||
| 645 | data->valid = 1; | 646 | data->valid = 1; |
| 646 | } | 647 | } |
| 647 | 648 | ||
| 648 | up(&data->update_lock); | 649 | mutex_unlock(&data->update_lock); |
| 649 | 650 | ||
| 650 | return data; | 651 | return data; |
| 651 | } | 652 | } |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 9a440c8cc520..24a6851491d0 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
| @@ -34,9 +34,9 @@ | |||
| 34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
| 36 | #include <linux/jiffies.h> | 36 | #include <linux/jiffies.h> |
| 37 | #include <linux/i2c.h> | 37 | #include <linux/platform_device.h> |
| 38 | #include <linux/i2c-isa.h> | ||
| 39 | #include <linux/hwmon.h> | 38 | #include <linux/hwmon.h> |
| 39 | #include <linux/hwmon-sysfs.h> | ||
| 40 | #include <linux/err.h> | 40 | #include <linux/err.h> |
| 41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
| 42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
| @@ -51,10 +51,7 @@ module_param(force_addr, ushort, 0); | |||
| 51 | MODULE_PARM_DESC(force_addr, | 51 | MODULE_PARM_DESC(force_addr, |
| 52 | "Initialize the base address of the sensors"); | 52 | "Initialize the base address of the sensors"); |
| 53 | 53 | ||
| 54 | /* Device address | 54 | static struct platform_device *pdev; |
| 55 | Note that we can't determine the ISA address until we have initialized | ||
| 56 | our module */ | ||
| 57 | static unsigned short address; | ||
| 58 | 55 | ||
| 59 | /* | 56 | /* |
| 60 | The Via 686a southbridge has a LM78-like chip integrated on the same IC. | 57 | The Via 686a southbridge has a LM78-like chip integrated on the same IC. |
| @@ -295,7 +292,8 @@ static inline long TEMP_FROM_REG10(u16 val) | |||
| 295 | /* For each registered chip, we need to keep some data in memory. | 292 | /* For each registered chip, we need to keep some data in memory. |
| 296 | The structure is dynamically allocated. */ | 293 | The structure is dynamically allocated. */ |
| 297 | struct via686a_data { | 294 | struct via686a_data { |
| 298 | struct i2c_client client; | 295 | unsigned short addr; |
| 296 | const char *name; | ||
| 299 | struct class_device *class_dev; | 297 | struct class_device *class_dev; |
| 300 | struct mutex update_lock; | 298 | struct mutex update_lock; |
| 301 | char valid; /* !=0 if following fields are valid */ | 299 | char valid; /* !=0 if following fields are valid */ |
| @@ -315,98 +313,85 @@ struct via686a_data { | |||
| 315 | 313 | ||
| 316 | static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ | 314 | static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ |
| 317 | 315 | ||
| 318 | static int via686a_detect(struct i2c_adapter *adapter); | 316 | static int via686a_probe(struct platform_device *pdev); |
| 319 | static int via686a_detach_client(struct i2c_client *client); | 317 | static int via686a_remove(struct platform_device *pdev); |
| 320 | 318 | ||
| 321 | static inline int via686a_read_value(struct i2c_client *client, u8 reg) | 319 | static inline int via686a_read_value(struct via686a_data *data, u8 reg) |
| 322 | { | 320 | { |
| 323 | return (inb_p(client->addr + reg)); | 321 | return inb_p(data->addr + reg); |
| 324 | } | 322 | } |
| 325 | 323 | ||
| 326 | static inline void via686a_write_value(struct i2c_client *client, u8 reg, | 324 | static inline void via686a_write_value(struct via686a_data *data, u8 reg, |
| 327 | u8 value) | 325 | u8 value) |
| 328 | { | 326 | { |
| 329 | outb_p(value, client->addr + reg); | 327 | outb_p(value, data->addr + reg); |
| 330 | } | 328 | } |
| 331 | 329 | ||
| 332 | static struct via686a_data *via686a_update_device(struct device *dev); | 330 | static struct via686a_data *via686a_update_device(struct device *dev); |
| 333 | static void via686a_init_client(struct i2c_client *client); | 331 | static void via686a_init_device(struct via686a_data *data); |
| 334 | 332 | ||
| 335 | /* following are the sysfs callback functions */ | 333 | /* following are the sysfs callback functions */ |
| 336 | 334 | ||
| 337 | /* 7 voltage sensors */ | 335 | /* 7 voltage sensors */ |
| 338 | static ssize_t show_in(struct device *dev, char *buf, int nr) { | 336 | static ssize_t show_in(struct device *dev, struct device_attribute *da, |
| 337 | char *buf) { | ||
| 339 | struct via686a_data *data = via686a_update_device(dev); | 338 | struct via686a_data *data = via686a_update_device(dev); |
| 339 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 340 | int nr = attr->index; | ||
| 340 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)); | 341 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)); |
| 341 | } | 342 | } |
| 342 | 343 | ||
| 343 | static ssize_t show_in_min(struct device *dev, char *buf, int nr) { | 344 | static ssize_t show_in_min(struct device *dev, struct device_attribute *da, |
| 345 | char *buf) { | ||
| 344 | struct via686a_data *data = via686a_update_device(dev); | 346 | struct via686a_data *data = via686a_update_device(dev); |
| 347 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 348 | int nr = attr->index; | ||
| 345 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)); | 349 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)); |
| 346 | } | 350 | } |
| 347 | 351 | ||
| 348 | static ssize_t show_in_max(struct device *dev, char *buf, int nr) { | 352 | static ssize_t show_in_max(struct device *dev, struct device_attribute *da, |
| 353 | char *buf) { | ||
| 349 | struct via686a_data *data = via686a_update_device(dev); | 354 | struct via686a_data *data = via686a_update_device(dev); |
| 355 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 356 | int nr = attr->index; | ||
| 350 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)); | 357 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)); |
| 351 | } | 358 | } |
| 352 | 359 | ||
| 353 | static ssize_t set_in_min(struct device *dev, const char *buf, | 360 | static ssize_t set_in_min(struct device *dev, struct device_attribute *da, |
| 354 | size_t count, int nr) { | 361 | const char *buf, size_t count) { |
| 355 | struct i2c_client *client = to_i2c_client(dev); | 362 | struct via686a_data *data = dev_get_drvdata(dev); |
| 356 | struct via686a_data *data = i2c_get_clientdata(client); | 363 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 364 | int nr = attr->index; | ||
| 357 | unsigned long val = simple_strtoul(buf, NULL, 10); | 365 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 358 | 366 | ||
| 359 | mutex_lock(&data->update_lock); | 367 | mutex_lock(&data->update_lock); |
| 360 | data->in_min[nr] = IN_TO_REG(val, nr); | 368 | data->in_min[nr] = IN_TO_REG(val, nr); |
| 361 | via686a_write_value(client, VIA686A_REG_IN_MIN(nr), | 369 | via686a_write_value(data, VIA686A_REG_IN_MIN(nr), |
| 362 | data->in_min[nr]); | 370 | data->in_min[nr]); |
| 363 | mutex_unlock(&data->update_lock); | 371 | mutex_unlock(&data->update_lock); |
| 364 | return count; | 372 | return count; |
| 365 | } | 373 | } |
| 366 | static ssize_t set_in_max(struct device *dev, const char *buf, | 374 | static ssize_t set_in_max(struct device *dev, struct device_attribute *da, |
| 367 | size_t count, int nr) { | 375 | const char *buf, size_t count) { |
| 368 | struct i2c_client *client = to_i2c_client(dev); | 376 | struct via686a_data *data = dev_get_drvdata(dev); |
| 369 | struct via686a_data *data = i2c_get_clientdata(client); | 377 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 378 | int nr = attr->index; | ||
| 370 | unsigned long val = simple_strtoul(buf, NULL, 10); | 379 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 371 | 380 | ||
| 372 | mutex_lock(&data->update_lock); | 381 | mutex_lock(&data->update_lock); |
| 373 | data->in_max[nr] = IN_TO_REG(val, nr); | 382 | data->in_max[nr] = IN_TO_REG(val, nr); |
| 374 | via686a_write_value(client, VIA686A_REG_IN_MAX(nr), | 383 | via686a_write_value(data, VIA686A_REG_IN_MAX(nr), |
| 375 | data->in_max[nr]); | 384 | data->in_max[nr]); |
| 376 | mutex_unlock(&data->update_lock); | 385 | mutex_unlock(&data->update_lock); |
| 377 | return count; | 386 | return count; |
| 378 | } | 387 | } |
| 379 | #define show_in_offset(offset) \ | 388 | #define show_in_offset(offset) \ |
| 380 | static ssize_t \ | 389 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
| 381 | show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 390 | show_in, NULL, offset); \ |
| 382 | { \ | 391 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ |
| 383 | return show_in(dev, buf, offset); \ | 392 | show_in_min, set_in_min, offset); \ |
| 384 | } \ | 393 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ |
| 385 | static ssize_t \ | 394 | show_in_max, set_in_max, offset); |
| 386 | show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
| 387 | { \ | ||
| 388 | return show_in_min(dev, buf, offset); \ | ||
| 389 | } \ | ||
| 390 | static ssize_t \ | ||
| 391 | show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
| 392 | { \ | ||
| 393 | return show_in_max(dev, buf, offset); \ | ||
| 394 | } \ | ||
| 395 | static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
| 396 | const char *buf, size_t count) \ | ||
| 397 | { \ | ||
| 398 | return set_in_min(dev, buf, count, offset); \ | ||
| 399 | } \ | ||
| 400 | static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \ | ||
| 401 | const char *buf, size_t count) \ | ||
| 402 | { \ | ||
| 403 | return set_in_max(dev, buf, count, offset); \ | ||
| 404 | } \ | ||
| 405 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);\ | ||
| 406 | static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
| 407 | show_in##offset##_min, set_in##offset##_min); \ | ||
| 408 | static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
| 409 | show_in##offset##_max, set_in##offset##_max); | ||
| 410 | 395 | ||
| 411 | show_in_offset(0); | 396 | show_in_offset(0); |
| 412 | show_in_offset(1); | 397 | show_in_offset(1); |
| @@ -415,150 +400,128 @@ show_in_offset(3); | |||
| 415 | show_in_offset(4); | 400 | show_in_offset(4); |
| 416 | 401 | ||
| 417 | /* 3 temperatures */ | 402 | /* 3 temperatures */ |
| 418 | static ssize_t show_temp(struct device *dev, char *buf, int nr) { | 403 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, |
| 404 | char *buf) { | ||
| 419 | struct via686a_data *data = via686a_update_device(dev); | 405 | struct via686a_data *data = via686a_update_device(dev); |
| 406 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 407 | int nr = attr->index; | ||
| 420 | return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])); | 408 | return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])); |
| 421 | } | 409 | } |
| 422 | static ssize_t show_temp_over(struct device *dev, char *buf, int nr) { | 410 | static ssize_t show_temp_over(struct device *dev, struct device_attribute *da, |
| 411 | char *buf) { | ||
| 423 | struct via686a_data *data = via686a_update_device(dev); | 412 | struct via686a_data *data = via686a_update_device(dev); |
| 413 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 414 | int nr = attr->index; | ||
| 424 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])); | 415 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])); |
| 425 | } | 416 | } |
| 426 | static ssize_t show_temp_hyst(struct device *dev, char *buf, int nr) { | 417 | static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da, |
| 418 | char *buf) { | ||
| 427 | struct via686a_data *data = via686a_update_device(dev); | 419 | struct via686a_data *data = via686a_update_device(dev); |
| 420 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 421 | int nr = attr->index; | ||
| 428 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])); | 422 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])); |
| 429 | } | 423 | } |
| 430 | static ssize_t set_temp_over(struct device *dev, const char *buf, | 424 | static ssize_t set_temp_over(struct device *dev, struct device_attribute *da, |
| 431 | size_t count, int nr) { | 425 | const char *buf, size_t count) { |
| 432 | struct i2c_client *client = to_i2c_client(dev); | 426 | struct via686a_data *data = dev_get_drvdata(dev); |
| 433 | struct via686a_data *data = i2c_get_clientdata(client); | 427 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 428 | int nr = attr->index; | ||
| 434 | int val = simple_strtol(buf, NULL, 10); | 429 | int val = simple_strtol(buf, NULL, 10); |
| 435 | 430 | ||
| 436 | mutex_lock(&data->update_lock); | 431 | mutex_lock(&data->update_lock); |
| 437 | data->temp_over[nr] = TEMP_TO_REG(val); | 432 | data->temp_over[nr] = TEMP_TO_REG(val); |
| 438 | via686a_write_value(client, VIA686A_REG_TEMP_OVER[nr], | 433 | via686a_write_value(data, VIA686A_REG_TEMP_OVER[nr], |
| 439 | data->temp_over[nr]); | 434 | data->temp_over[nr]); |
| 440 | mutex_unlock(&data->update_lock); | 435 | mutex_unlock(&data->update_lock); |
| 441 | return count; | 436 | return count; |
| 442 | } | 437 | } |
| 443 | static ssize_t set_temp_hyst(struct device *dev, const char *buf, | 438 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da, |
| 444 | size_t count, int nr) { | 439 | const char *buf, size_t count) { |
| 445 | struct i2c_client *client = to_i2c_client(dev); | 440 | struct via686a_data *data = dev_get_drvdata(dev); |
| 446 | struct via686a_data *data = i2c_get_clientdata(client); | 441 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 442 | int nr = attr->index; | ||
| 447 | int val = simple_strtol(buf, NULL, 10); | 443 | int val = simple_strtol(buf, NULL, 10); |
| 448 | 444 | ||
| 449 | mutex_lock(&data->update_lock); | 445 | mutex_lock(&data->update_lock); |
| 450 | data->temp_hyst[nr] = TEMP_TO_REG(val); | 446 | data->temp_hyst[nr] = TEMP_TO_REG(val); |
| 451 | via686a_write_value(client, VIA686A_REG_TEMP_HYST[nr], | 447 | via686a_write_value(data, VIA686A_REG_TEMP_HYST[nr], |
| 452 | data->temp_hyst[nr]); | 448 | data->temp_hyst[nr]); |
| 453 | mutex_unlock(&data->update_lock); | 449 | mutex_unlock(&data->update_lock); |
| 454 | return count; | 450 | return count; |
| 455 | } | 451 | } |
| 456 | #define show_temp_offset(offset) \ | 452 | #define show_temp_offset(offset) \ |
| 457 | static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 453 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
| 458 | { \ | 454 | show_temp, NULL, offset - 1); \ |
| 459 | return show_temp(dev, buf, offset - 1); \ | 455 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
| 460 | } \ | 456 | show_temp_over, set_temp_over, offset - 1); \ |
| 461 | static ssize_t \ | 457 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ |
| 462 | show_temp_##offset##_over (struct device *dev, struct device_attribute *attr, char *buf) \ | 458 | show_temp_hyst, set_temp_hyst, offset - 1); |
| 463 | { \ | ||
| 464 | return show_temp_over(dev, buf, offset - 1); \ | ||
| 465 | } \ | ||
| 466 | static ssize_t \ | ||
| 467 | show_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
| 468 | { \ | ||
| 469 | return show_temp_hyst(dev, buf, offset - 1); \ | ||
| 470 | } \ | ||
| 471 | static ssize_t set_temp_##offset##_over (struct device *dev, struct device_attribute *attr, \ | ||
| 472 | const char *buf, size_t count) \ | ||
| 473 | { \ | ||
| 474 | return set_temp_over(dev, buf, count, offset - 1); \ | ||
| 475 | } \ | ||
| 476 | static ssize_t set_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, \ | ||
| 477 | const char *buf, size_t count) \ | ||
| 478 | { \ | ||
| 479 | return set_temp_hyst(dev, buf, count, offset - 1); \ | ||
| 480 | } \ | ||
| 481 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);\ | ||
| 482 | static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
| 483 | show_temp_##offset##_over, set_temp_##offset##_over); \ | ||
| 484 | static DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ | ||
| 485 | show_temp_##offset##_hyst, set_temp_##offset##_hyst); | ||
| 486 | 459 | ||
| 487 | show_temp_offset(1); | 460 | show_temp_offset(1); |
| 488 | show_temp_offset(2); | 461 | show_temp_offset(2); |
| 489 | show_temp_offset(3); | 462 | show_temp_offset(3); |
| 490 | 463 | ||
| 491 | /* 2 Fans */ | 464 | /* 2 Fans */ |
| 492 | static ssize_t show_fan(struct device *dev, char *buf, int nr) { | 465 | static ssize_t show_fan(struct device *dev, struct device_attribute *da, |
| 466 | char *buf) { | ||
| 493 | struct via686a_data *data = via686a_update_device(dev); | 467 | struct via686a_data *data = via686a_update_device(dev); |
| 468 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 469 | int nr = attr->index; | ||
| 494 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], | 470 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], |
| 495 | DIV_FROM_REG(data->fan_div[nr])) ); | 471 | DIV_FROM_REG(data->fan_div[nr])) ); |
| 496 | } | 472 | } |
| 497 | static ssize_t show_fan_min(struct device *dev, char *buf, int nr) { | 473 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, |
| 474 | char *buf) { | ||
| 498 | struct via686a_data *data = via686a_update_device(dev); | 475 | struct via686a_data *data = via686a_update_device(dev); |
| 476 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 477 | int nr = attr->index; | ||
| 499 | return sprintf(buf, "%d\n", | 478 | return sprintf(buf, "%d\n", |
| 500 | FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) ); | 479 | FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) ); |
| 501 | } | 480 | } |
| 502 | static ssize_t show_fan_div(struct device *dev, char *buf, int nr) { | 481 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *da, |
| 482 | char *buf) { | ||
| 503 | struct via686a_data *data = via686a_update_device(dev); | 483 | struct via686a_data *data = via686a_update_device(dev); |
| 484 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 485 | int nr = attr->index; | ||
| 504 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); | 486 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); |
| 505 | } | 487 | } |
| 506 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 488 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, |
| 507 | size_t count, int nr) { | 489 | const char *buf, size_t count) { |
| 508 | struct i2c_client *client = to_i2c_client(dev); | 490 | struct via686a_data *data = dev_get_drvdata(dev); |
| 509 | struct via686a_data *data = i2c_get_clientdata(client); | 491 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 492 | int nr = attr->index; | ||
| 510 | int val = simple_strtol(buf, NULL, 10); | 493 | int val = simple_strtol(buf, NULL, 10); |
| 511 | 494 | ||
| 512 | mutex_lock(&data->update_lock); | 495 | mutex_lock(&data->update_lock); |
| 513 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 496 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
| 514 | via686a_write_value(client, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]); | 497 | via686a_write_value(data, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]); |
| 515 | mutex_unlock(&data->update_lock); | 498 | mutex_unlock(&data->update_lock); |
| 516 | return count; | 499 | return count; |
| 517 | } | 500 | } |
| 518 | static ssize_t set_fan_div(struct device *dev, const char *buf, | 501 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, |
| 519 | size_t count, int nr) { | 502 | const char *buf, size_t count) { |
| 520 | struct i2c_client *client = to_i2c_client(dev); | 503 | struct via686a_data *data = dev_get_drvdata(dev); |
| 521 | struct via686a_data *data = i2c_get_clientdata(client); | 504 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
| 505 | int nr = attr->index; | ||
| 522 | int val = simple_strtol(buf, NULL, 10); | 506 | int val = simple_strtol(buf, NULL, 10); |
| 523 | int old; | 507 | int old; |
| 524 | 508 | ||
| 525 | mutex_lock(&data->update_lock); | 509 | mutex_lock(&data->update_lock); |
| 526 | old = via686a_read_value(client, VIA686A_REG_FANDIV); | 510 | old = via686a_read_value(data, VIA686A_REG_FANDIV); |
| 527 | data->fan_div[nr] = DIV_TO_REG(val); | 511 | data->fan_div[nr] = DIV_TO_REG(val); |
| 528 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); | 512 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); |
| 529 | via686a_write_value(client, VIA686A_REG_FANDIV, old); | 513 | via686a_write_value(data, VIA686A_REG_FANDIV, old); |
| 530 | mutex_unlock(&data->update_lock); | 514 | mutex_unlock(&data->update_lock); |
| 531 | return count; | 515 | return count; |
| 532 | } | 516 | } |
| 533 | 517 | ||
| 534 | #define show_fan_offset(offset) \ | 518 | #define show_fan_offset(offset) \ |
| 535 | static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 519 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
| 536 | { \ | 520 | show_fan, NULL, offset - 1); \ |
| 537 | return show_fan(dev, buf, offset - 1); \ | 521 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ |
| 538 | } \ | 522 | show_fan_min, set_fan_min, offset - 1); \ |
| 539 | static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | 523 | static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ |
| 540 | { \ | 524 | show_fan_div, set_fan_div, offset - 1); |
| 541 | return show_fan_min(dev, buf, offset - 1); \ | ||
| 542 | } \ | ||
| 543 | static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
| 544 | { \ | ||
| 545 | return show_fan_div(dev, buf, offset - 1); \ | ||
| 546 | } \ | ||
| 547 | static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
| 548 | const char *buf, size_t count) \ | ||
| 549 | { \ | ||
| 550 | return set_fan_min(dev, buf, count, offset - 1); \ | ||
| 551 | } \ | ||
| 552 | static ssize_t set_fan_##offset##_div (struct device *dev, struct device_attribute *attr, \ | ||
| 553 | const char *buf, size_t count) \ | ||
| 554 | { \ | ||
| 555 | return set_fan_div(dev, buf, count, offset - 1); \ | ||
| 556 | } \ | ||
| 557 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ | ||
| 558 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
| 559 | show_fan_##offset##_min, set_fan_##offset##_min); \ | ||
| 560 | static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ | ||
| 561 | show_fan_##offset##_div, set_fan_##offset##_div); | ||
| 562 | 525 | ||
| 563 | show_fan_offset(1); | 526 | show_fan_offset(1); |
| 564 | show_fan_offset(2); | 527 | show_fan_offset(2); |
| @@ -570,41 +533,50 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch | |||
| 570 | } | 533 | } |
| 571 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 534 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
| 572 | 535 | ||
| 536 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
| 537 | *devattr, char *buf) | ||
| 538 | { | ||
| 539 | struct via686a_data *data = dev_get_drvdata(dev); | ||
| 540 | return sprintf(buf, "%s\n", data->name); | ||
| 541 | } | ||
| 542 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 543 | |||
| 573 | static struct attribute *via686a_attributes[] = { | 544 | static struct attribute *via686a_attributes[] = { |
| 574 | &dev_attr_in0_input.attr, | 545 | &sensor_dev_attr_in0_input.dev_attr.attr, |
| 575 | &dev_attr_in1_input.attr, | 546 | &sensor_dev_attr_in1_input.dev_attr.attr, |
| 576 | &dev_attr_in2_input.attr, | 547 | &sensor_dev_attr_in2_input.dev_attr.attr, |
| 577 | &dev_attr_in3_input.attr, | 548 | &sensor_dev_attr_in3_input.dev_attr.attr, |
| 578 | &dev_attr_in4_input.attr, | 549 | &sensor_dev_attr_in4_input.dev_attr.attr, |
| 579 | &dev_attr_in0_min.attr, | 550 | &sensor_dev_attr_in0_min.dev_attr.attr, |
| 580 | &dev_attr_in1_min.attr, | 551 | &sensor_dev_attr_in1_min.dev_attr.attr, |
| 581 | &dev_attr_in2_min.attr, | 552 | &sensor_dev_attr_in2_min.dev_attr.attr, |
| 582 | &dev_attr_in3_min.attr, | 553 | &sensor_dev_attr_in3_min.dev_attr.attr, |
| 583 | &dev_attr_in4_min.attr, | 554 | &sensor_dev_attr_in4_min.dev_attr.attr, |
| 584 | &dev_attr_in0_max.attr, | 555 | &sensor_dev_attr_in0_max.dev_attr.attr, |
| 585 | &dev_attr_in1_max.attr, | 556 | &sensor_dev_attr_in1_max.dev_attr.attr, |
| 586 | &dev_attr_in2_max.attr, | 557 | &sensor_dev_attr_in2_max.dev_attr.attr, |
| 587 | &dev_attr_in3_max.attr, | 558 | &sensor_dev_attr_in3_max.dev_attr.attr, |
| 588 | &dev_attr_in4_max.attr, | 559 | &sensor_dev_attr_in4_max.dev_attr.attr, |
| 589 | 560 | ||
| 590 | &dev_attr_temp1_input.attr, | 561 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
| 591 | &dev_attr_temp2_input.attr, | 562 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
| 592 | &dev_attr_temp3_input.attr, | 563 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
| 593 | &dev_attr_temp1_max.attr, | 564 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
| 594 | &dev_attr_temp2_max.attr, | 565 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
| 595 | &dev_attr_temp3_max.attr, | 566 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
| 596 | &dev_attr_temp1_max_hyst.attr, | 567 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
| 597 | &dev_attr_temp2_max_hyst.attr, | 568 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, |
| 598 | &dev_attr_temp3_max_hyst.attr, | 569 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, |
| 599 | 570 | ||
| 600 | &dev_attr_fan1_input.attr, | 571 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
| 601 | &dev_attr_fan2_input.attr, | 572 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
| 602 | &dev_attr_fan1_min.attr, | 573 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
| 603 | &dev_attr_fan2_min.attr, | 574 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
| 604 | &dev_attr_fan1_div.attr, | 575 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
| 605 | &dev_attr_fan2_div.attr, | 576 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
| 606 | 577 | ||
| 607 | &dev_attr_alarms.attr, | 578 | &dev_attr_alarms.attr, |
| 579 | &dev_attr_name.attr, | ||
| 608 | NULL | 580 | NULL |
| 609 | }; | 581 | }; |
| 610 | 582 | ||
| @@ -612,58 +584,29 @@ static const struct attribute_group via686a_group = { | |||
| 612 | .attrs = via686a_attributes, | 584 | .attrs = via686a_attributes, |
| 613 | }; | 585 | }; |
| 614 | 586 | ||
| 615 | /* The driver. I choose to use type i2c_driver, as at is identical to both | 587 | static struct platform_driver via686a_driver = { |
| 616 | smbus_driver and isa_driver, and clients could be of either kind */ | ||
| 617 | static struct i2c_driver via686a_driver = { | ||
| 618 | .driver = { | 588 | .driver = { |
| 619 | .owner = THIS_MODULE, | 589 | .owner = THIS_MODULE, |
| 620 | .name = "via686a", | 590 | .name = "via686a", |
| 621 | }, | 591 | }, |
| 622 | .attach_adapter = via686a_detect, | 592 | .probe = via686a_probe, |
| 623 | .detach_client = via686a_detach_client, | 593 | .remove = __devexit_p(via686a_remove), |
| 624 | }; | 594 | }; |
| 625 | 595 | ||
| 626 | 596 | ||
| 627 | /* This is called when the module is loaded */ | 597 | /* This is called when the module is loaded */ |
| 628 | static int via686a_detect(struct i2c_adapter *adapter) | 598 | static int __devinit via686a_probe(struct platform_device *pdev) |
| 629 | { | 599 | { |
| 630 | struct i2c_client *new_client; | ||
| 631 | struct via686a_data *data; | 600 | struct via686a_data *data; |
| 632 | int err = 0; | 601 | struct resource *res; |
| 633 | const char client_name[] = "via686a"; | 602 | int err; |
| 634 | u16 val; | ||
| 635 | |||
| 636 | /* 8231 requires multiple of 256, we enforce that on 686 as well */ | ||
| 637 | if (force_addr) { | ||
| 638 | address = force_addr & 0xFF00; | ||
| 639 | dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", | ||
| 640 | address); | ||
| 641 | if (PCIBIOS_SUCCESSFUL != | ||
| 642 | pci_write_config_word(s_bridge, VIA686A_BASE_REG, address)) | ||
| 643 | return -ENODEV; | ||
| 644 | } | ||
| 645 | if (PCIBIOS_SUCCESSFUL != | ||
| 646 | pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val)) | ||
| 647 | return -ENODEV; | ||
| 648 | if (!(val & 0x0001)) { | ||
| 649 | if (force_addr) { | ||
| 650 | dev_info(&adapter->dev, "enabling sensors\n"); | ||
| 651 | if (PCIBIOS_SUCCESSFUL != | ||
| 652 | pci_write_config_word(s_bridge, VIA686A_ENABLE_REG, | ||
| 653 | val | 0x0001)) | ||
| 654 | return -ENODEV; | ||
| 655 | } else { | ||
| 656 | dev_warn(&adapter->dev, "sensors disabled - enable " | ||
| 657 | "with force_addr=0x%x\n", address); | ||
| 658 | return -ENODEV; | ||
| 659 | } | ||
| 660 | } | ||
| 661 | 603 | ||
| 662 | /* Reserve the ISA region */ | 604 | /* Reserve the ISA region */ |
| 663 | if (!request_region(address, VIA686A_EXTENT, | 605 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 606 | if (!request_region(res->start, VIA686A_EXTENT, | ||
| 664 | via686a_driver.driver.name)) { | 607 | via686a_driver.driver.name)) { |
| 665 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | 608 | dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n", |
| 666 | address); | 609 | (unsigned long)res->start, (unsigned long)res->end); |
| 667 | return -ENODEV; | 610 | return -ENODEV; |
| 668 | } | 611 | } |
| 669 | 612 | ||
| @@ -672,30 +615,19 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
| 672 | goto exit_release; | 615 | goto exit_release; |
| 673 | } | 616 | } |
| 674 | 617 | ||
| 675 | new_client = &data->client; | 618 | platform_set_drvdata(pdev, data); |
| 676 | i2c_set_clientdata(new_client, data); | 619 | data->addr = res->start; |
| 677 | new_client->addr = address; | 620 | data->name = "via686a"; |
| 678 | new_client->adapter = adapter; | ||
| 679 | new_client->driver = &via686a_driver; | ||
| 680 | new_client->flags = 0; | ||
| 681 | |||
| 682 | /* Fill in the remaining client fields and put into the global list */ | ||
| 683 | strlcpy(new_client->name, client_name, I2C_NAME_SIZE); | ||
| 684 | |||
| 685 | data->valid = 0; | ||
| 686 | mutex_init(&data->update_lock); | 621 | mutex_init(&data->update_lock); |
| 687 | /* Tell the I2C layer a new client has arrived */ | ||
| 688 | if ((err = i2c_attach_client(new_client))) | ||
| 689 | goto exit_free; | ||
| 690 | 622 | ||
| 691 | /* Initialize the VIA686A chip */ | 623 | /* Initialize the VIA686A chip */ |
| 692 | via686a_init_client(new_client); | 624 | via686a_init_device(data); |
| 693 | 625 | ||
| 694 | /* Register sysfs hooks */ | 626 | /* Register sysfs hooks */ |
| 695 | if ((err = sysfs_create_group(&new_client->dev.kobj, &via686a_group))) | 627 | if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group))) |
| 696 | goto exit_detach; | 628 | goto exit_free; |
| 697 | 629 | ||
| 698 | data->class_dev = hwmon_device_register(&new_client->dev); | 630 | data->class_dev = hwmon_device_register(&pdev->dev); |
| 699 | if (IS_ERR(data->class_dev)) { | 631 | if (IS_ERR(data->class_dev)) { |
| 700 | err = PTR_ERR(data->class_dev); | 632 | err = PTR_ERR(data->class_dev); |
| 701 | goto exit_remove_files; | 633 | goto exit_remove_files; |
| @@ -704,51 +636,46 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
| 704 | return 0; | 636 | return 0; |
| 705 | 637 | ||
| 706 | exit_remove_files: | 638 | exit_remove_files: |
| 707 | sysfs_remove_group(&new_client->dev.kobj, &via686a_group); | 639 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
| 708 | exit_detach: | ||
| 709 | i2c_detach_client(new_client); | ||
| 710 | exit_free: | 640 | exit_free: |
| 711 | kfree(data); | 641 | kfree(data); |
| 712 | exit_release: | 642 | exit_release: |
| 713 | release_region(address, VIA686A_EXTENT); | 643 | release_region(res->start, VIA686A_EXTENT); |
| 714 | return err; | 644 | return err; |
| 715 | } | 645 | } |
| 716 | 646 | ||
| 717 | static int via686a_detach_client(struct i2c_client *client) | 647 | static int __devexit via686a_remove(struct platform_device *pdev) |
| 718 | { | 648 | { |
| 719 | struct via686a_data *data = i2c_get_clientdata(client); | 649 | struct via686a_data *data = platform_get_drvdata(pdev); |
| 720 | int err; | ||
| 721 | 650 | ||
| 722 | hwmon_device_unregister(data->class_dev); | 651 | hwmon_device_unregister(data->class_dev); |
| 723 | sysfs_remove_group(&client->dev.kobj, &via686a_group); | 652 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
| 724 | 653 | ||
| 725 | if ((err = i2c_detach_client(client))) | 654 | release_region(data->addr, VIA686A_EXTENT); |
| 726 | return err; | 655 | platform_set_drvdata(pdev, NULL); |
| 727 | |||
| 728 | release_region(client->addr, VIA686A_EXTENT); | ||
| 729 | kfree(data); | 656 | kfree(data); |
| 730 | 657 | ||
| 731 | return 0; | 658 | return 0; |
| 732 | } | 659 | } |
| 733 | 660 | ||
| 734 | static void via686a_init_client(struct i2c_client *client) | 661 | static void __devinit via686a_init_device(struct via686a_data *data) |
| 735 | { | 662 | { |
| 736 | u8 reg; | 663 | u8 reg; |
| 737 | 664 | ||
| 738 | /* Start monitoring */ | 665 | /* Start monitoring */ |
| 739 | reg = via686a_read_value(client, VIA686A_REG_CONFIG); | 666 | reg = via686a_read_value(data, VIA686A_REG_CONFIG); |
| 740 | via686a_write_value(client, VIA686A_REG_CONFIG, (reg|0x01)&0x7F); | 667 | via686a_write_value(data, VIA686A_REG_CONFIG, (reg | 0x01) & 0x7F); |
| 741 | 668 | ||
| 742 | /* Configure temp interrupt mode for continuous-interrupt operation */ | 669 | /* Configure temp interrupt mode for continuous-interrupt operation */ |
| 743 | via686a_write_value(client, VIA686A_REG_TEMP_MODE, | 670 | reg = via686a_read_value(data, VIA686A_REG_TEMP_MODE); |
| 744 | via686a_read_value(client, VIA686A_REG_TEMP_MODE) & | 671 | via686a_write_value(data, VIA686A_REG_TEMP_MODE, |
| 745 | !(VIA686A_TEMP_MODE_MASK | VIA686A_TEMP_MODE_CONTINUOUS)); | 672 | (reg & ~VIA686A_TEMP_MODE_MASK) |
| 673 | | VIA686A_TEMP_MODE_CONTINUOUS); | ||
| 746 | } | 674 | } |
| 747 | 675 | ||
| 748 | static struct via686a_data *via686a_update_device(struct device *dev) | 676 | static struct via686a_data *via686a_update_device(struct device *dev) |
| 749 | { | 677 | { |
| 750 | struct i2c_client *client = to_i2c_client(dev); | 678 | struct via686a_data *data = dev_get_drvdata(dev); |
| 751 | struct via686a_data *data = i2c_get_clientdata(client); | ||
| 752 | int i; | 679 | int i; |
| 753 | 680 | ||
| 754 | mutex_lock(&data->update_lock); | 681 | mutex_lock(&data->update_lock); |
| @@ -757,27 +684,27 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
| 757 | || !data->valid) { | 684 | || !data->valid) { |
| 758 | for (i = 0; i <= 4; i++) { | 685 | for (i = 0; i <= 4; i++) { |
| 759 | data->in[i] = | 686 | data->in[i] = |
| 760 | via686a_read_value(client, VIA686A_REG_IN(i)); | 687 | via686a_read_value(data, VIA686A_REG_IN(i)); |
| 761 | data->in_min[i] = via686a_read_value(client, | 688 | data->in_min[i] = via686a_read_value(data, |
| 762 | VIA686A_REG_IN_MIN | 689 | VIA686A_REG_IN_MIN |
| 763 | (i)); | 690 | (i)); |
| 764 | data->in_max[i] = | 691 | data->in_max[i] = |
| 765 | via686a_read_value(client, VIA686A_REG_IN_MAX(i)); | 692 | via686a_read_value(data, VIA686A_REG_IN_MAX(i)); |
| 766 | } | 693 | } |
| 767 | for (i = 1; i <= 2; i++) { | 694 | for (i = 1; i <= 2; i++) { |
| 768 | data->fan[i - 1] = | 695 | data->fan[i - 1] = |
| 769 | via686a_read_value(client, VIA686A_REG_FAN(i)); | 696 | via686a_read_value(data, VIA686A_REG_FAN(i)); |
| 770 | data->fan_min[i - 1] = via686a_read_value(client, | 697 | data->fan_min[i - 1] = via686a_read_value(data, |
| 771 | VIA686A_REG_FAN_MIN(i)); | 698 | VIA686A_REG_FAN_MIN(i)); |
| 772 | } | 699 | } |
| 773 | for (i = 0; i <= 2; i++) { | 700 | for (i = 0; i <= 2; i++) { |
| 774 | data->temp[i] = via686a_read_value(client, | 701 | data->temp[i] = via686a_read_value(data, |
| 775 | VIA686A_REG_TEMP[i]) << 2; | 702 | VIA686A_REG_TEMP[i]) << 2; |
| 776 | data->temp_over[i] = | 703 | data->temp_over[i] = |
| 777 | via686a_read_value(client, | 704 | via686a_read_value(data, |
| 778 | VIA686A_REG_TEMP_OVER[i]); | 705 | VIA686A_REG_TEMP_OVER[i]); |
| 779 | data->temp_hyst[i] = | 706 | data->temp_hyst[i] = |
| 780 | via686a_read_value(client, | 707 | via686a_read_value(data, |
| 781 | VIA686A_REG_TEMP_HYST[i]); | 708 | VIA686A_REG_TEMP_HYST[i]); |
| 782 | } | 709 | } |
| 783 | /* add in lower 2 bits | 710 | /* add in lower 2 bits |
| @@ -785,23 +712,23 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
| 785 | temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 | 712 | temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 |
| 786 | temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 | 713 | temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 |
| 787 | */ | 714 | */ |
| 788 | data->temp[0] |= (via686a_read_value(client, | 715 | data->temp[0] |= (via686a_read_value(data, |
| 789 | VIA686A_REG_TEMP_LOW1) | 716 | VIA686A_REG_TEMP_LOW1) |
| 790 | & 0xc0) >> 6; | 717 | & 0xc0) >> 6; |
| 791 | data->temp[1] |= | 718 | data->temp[1] |= |
| 792 | (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & | 719 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & |
| 793 | 0x30) >> 4; | 720 | 0x30) >> 4; |
| 794 | data->temp[2] |= | 721 | data->temp[2] |= |
| 795 | (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & | 722 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & |
| 796 | 0xc0) >> 6; | 723 | 0xc0) >> 6; |
| 797 | 724 | ||
| 798 | i = via686a_read_value(client, VIA686A_REG_FANDIV); | 725 | i = via686a_read_value(data, VIA686A_REG_FANDIV); |
| 799 | data->fan_div[0] = (i >> 4) & 0x03; | 726 | data->fan_div[0] = (i >> 4) & 0x03; |
| 800 | data->fan_div[1] = i >> 6; | 727 | data->fan_div[1] = i >> 6; |
| 801 | data->alarms = | 728 | data->alarms = |
| 802 | via686a_read_value(client, | 729 | via686a_read_value(data, |
| 803 | VIA686A_REG_ALARM1) | | 730 | VIA686A_REG_ALARM1) | |
| 804 | (via686a_read_value(client, VIA686A_REG_ALARM2) << 8); | 731 | (via686a_read_value(data, VIA686A_REG_ALARM2) << 8); |
| 805 | data->last_updated = jiffies; | 732 | data->last_updated = jiffies; |
| 806 | data->valid = 1; | 733 | data->valid = 1; |
| 807 | } | 734 | } |
| @@ -818,32 +745,102 @@ static struct pci_device_id via686a_pci_ids[] = { | |||
| 818 | 745 | ||
| 819 | MODULE_DEVICE_TABLE(pci, via686a_pci_ids); | 746 | MODULE_DEVICE_TABLE(pci, via686a_pci_ids); |
| 820 | 747 | ||
| 748 | static int __devinit via686a_device_add(unsigned short address) | ||
| 749 | { | ||
| 750 | struct resource res = { | ||
| 751 | .start = address, | ||
| 752 | .end = address + VIA686A_EXTENT - 1, | ||
| 753 | .name = "via686a", | ||
| 754 | .flags = IORESOURCE_IO, | ||
| 755 | }; | ||
| 756 | int err; | ||
| 757 | |||
| 758 | pdev = platform_device_alloc("via686a", address); | ||
| 759 | if (!pdev) { | ||
| 760 | err = -ENOMEM; | ||
| 761 | printk(KERN_ERR "via686a: Device allocation failed\n"); | ||
| 762 | goto exit; | ||
| 763 | } | ||
| 764 | |||
| 765 | err = platform_device_add_resources(pdev, &res, 1); | ||
| 766 | if (err) { | ||
| 767 | printk(KERN_ERR "via686a: Device resource addition failed " | ||
| 768 | "(%d)\n", err); | ||
| 769 | goto exit_device_put; | ||
| 770 | } | ||
| 771 | |||
| 772 | err = platform_device_add(pdev); | ||
| 773 | if (err) { | ||
| 774 | printk(KERN_ERR "via686a: Device addition failed (%d)\n", | ||
| 775 | err); | ||
| 776 | goto exit_device_put; | ||
| 777 | } | ||
| 778 | |||
| 779 | return 0; | ||
| 780 | |||
| 781 | exit_device_put: | ||
| 782 | platform_device_put(pdev); | ||
| 783 | exit: | ||
| 784 | return err; | ||
| 785 | } | ||
| 786 | |||
| 821 | static int __devinit via686a_pci_probe(struct pci_dev *dev, | 787 | static int __devinit via686a_pci_probe(struct pci_dev *dev, |
| 822 | const struct pci_device_id *id) | 788 | const struct pci_device_id *id) |
| 823 | { | 789 | { |
| 824 | u16 val; | 790 | u16 address, val; |
| 825 | 791 | ||
| 792 | if (force_addr) { | ||
| 793 | address = force_addr & ~(VIA686A_EXTENT - 1); | ||
| 794 | dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", address); | ||
| 795 | if (PCIBIOS_SUCCESSFUL != | ||
| 796 | pci_write_config_word(dev, VIA686A_BASE_REG, address | 1)) | ||
| 797 | return -ENODEV; | ||
| 798 | } | ||
| 826 | if (PCIBIOS_SUCCESSFUL != | 799 | if (PCIBIOS_SUCCESSFUL != |
| 827 | pci_read_config_word(dev, VIA686A_BASE_REG, &val)) | 800 | pci_read_config_word(dev, VIA686A_BASE_REG, &val)) |
| 828 | return -ENODEV; | 801 | return -ENODEV; |
| 829 | 802 | ||
| 830 | address = val & ~(VIA686A_EXTENT - 1); | 803 | address = val & ~(VIA686A_EXTENT - 1); |
| 831 | if (address == 0 && force_addr == 0) { | 804 | if (address == 0) { |
| 832 | dev_err(&dev->dev, "base address not set - upgrade BIOS " | 805 | dev_err(&dev->dev, "base address not set - upgrade BIOS " |
| 833 | "or use force_addr=0xaddr\n"); | 806 | "or use force_addr=0xaddr\n"); |
| 834 | return -ENODEV; | 807 | return -ENODEV; |
| 835 | } | 808 | } |
| 836 | 809 | ||
| 837 | s_bridge = pci_dev_get(dev); | 810 | if (PCIBIOS_SUCCESSFUL != |
| 838 | if (i2c_isa_add_driver(&via686a_driver)) { | 811 | pci_read_config_word(dev, VIA686A_ENABLE_REG, &val)) |
| 839 | pci_dev_put(s_bridge); | 812 | return -ENODEV; |
| 840 | s_bridge = NULL; | 813 | if (!(val & 0x0001)) { |
| 814 | if (!force_addr) { | ||
| 815 | dev_warn(&dev->dev, "Sensors disabled, enable " | ||
| 816 | "with force_addr=0x%x\n", address); | ||
| 817 | return -ENODEV; | ||
| 818 | } | ||
| 819 | |||
| 820 | dev_warn(&dev->dev, "Enabling sensors\n"); | ||
| 821 | if (PCIBIOS_SUCCESSFUL != | ||
| 822 | pci_write_config_word(dev, VIA686A_ENABLE_REG, | ||
| 823 | val | 0x0001)) | ||
| 824 | return -ENODEV; | ||
| 841 | } | 825 | } |
| 842 | 826 | ||
| 827 | if (platform_driver_register(&via686a_driver)) | ||
| 828 | goto exit; | ||
| 829 | |||
| 830 | /* Sets global pdev as a side effect */ | ||
| 831 | if (via686a_device_add(address)) | ||
| 832 | goto exit_unregister; | ||
| 833 | |||
| 843 | /* Always return failure here. This is to allow other drivers to bind | 834 | /* Always return failure here. This is to allow other drivers to bind |
| 844 | * to this pci device. We don't really want to have control over the | 835 | * to this pci device. We don't really want to have control over the |
| 845 | * pci device, we only wanted to read as few register values from it. | 836 | * pci device, we only wanted to read as few register values from it. |
| 846 | */ | 837 | */ |
| 838 | s_bridge = pci_dev_get(dev); | ||
| 839 | return -ENODEV; | ||
| 840 | |||
| 841 | exit_unregister: | ||
| 842 | platform_driver_unregister(&via686a_driver); | ||
| 843 | exit: | ||
| 847 | return -ENODEV; | 844 | return -ENODEV; |
| 848 | } | 845 | } |
| 849 | 846 | ||
| @@ -862,7 +859,8 @@ static void __exit sm_via686a_exit(void) | |||
| 862 | { | 859 | { |
| 863 | pci_unregister_driver(&via686a_pci_driver); | 860 | pci_unregister_driver(&via686a_pci_driver); |
| 864 | if (s_bridge != NULL) { | 861 | if (s_bridge != NULL) { |
| 865 | i2c_isa_del_driver(&via686a_driver); | 862 | platform_device_unregister(pdev); |
| 863 | platform_driver_unregister(&via686a_driver); | ||
| 866 | pci_dev_put(s_bridge); | 864 | pci_dev_put(s_bridge); |
| 867 | s_bridge = NULL; | 865 | s_bridge = NULL; |
| 868 | } | 866 | } |
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index a6a4aa0eee16..c604972f0186 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c | |||
| @@ -29,8 +29,7 @@ | |||
| 29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
| 31 | #include <linux/jiffies.h> | 31 | #include <linux/jiffies.h> |
| 32 | #include <linux/i2c.h> | 32 | #include <linux/platform_device.h> |
| 33 | #include <linux/i2c-isa.h> | ||
| 34 | #include <linux/hwmon.h> | 33 | #include <linux/hwmon.h> |
| 35 | #include <linux/hwmon-sysfs.h> | 34 | #include <linux/hwmon-sysfs.h> |
| 36 | #include <linux/hwmon-vid.h> | 35 | #include <linux/hwmon-vid.h> |
| @@ -42,10 +41,7 @@ static int force_addr; | |||
| 42 | module_param(force_addr, int, 0); | 41 | module_param(force_addr, int, 0); |
| 43 | MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors"); | 42 | MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors"); |
| 44 | 43 | ||
| 45 | /* Device address | 44 | static struct platform_device *pdev; |
| 46 | Note that we can't determine the ISA address until we have initialized | ||
| 47 | our module */ | ||
| 48 | static unsigned short isa_address; | ||
| 49 | 45 | ||
| 50 | #define VT8231_EXTENT 0x80 | 46 | #define VT8231_EXTENT 0x80 |
| 51 | #define VT8231_BASE_REG 0x70 | 47 | #define VT8231_BASE_REG 0x70 |
| @@ -148,7 +144,9 @@ static inline u8 FAN_TO_REG(long rpm, int div) | |||
| 148 | #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 1310720 / ((val) * (div))) | 144 | #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 1310720 / ((val) * (div))) |
| 149 | 145 | ||
| 150 | struct vt8231_data { | 146 | struct vt8231_data { |
| 151 | struct i2c_client client; | 147 | unsigned short addr; |
| 148 | const char *name; | ||
| 149 | |||
| 152 | struct mutex update_lock; | 150 | struct mutex update_lock; |
| 153 | struct class_device *class_dev; | 151 | struct class_device *class_dev; |
| 154 | char valid; /* !=0 if following fields are valid */ | 152 | char valid; /* !=0 if following fields are valid */ |
| @@ -168,20 +166,20 @@ struct vt8231_data { | |||
| 168 | }; | 166 | }; |
| 169 | 167 | ||
| 170 | static struct pci_dev *s_bridge; | 168 | static struct pci_dev *s_bridge; |
| 171 | static int vt8231_detect(struct i2c_adapter *adapter); | 169 | static int vt8231_probe(struct platform_device *pdev); |
| 172 | static int vt8231_detach_client(struct i2c_client *client); | 170 | static int vt8231_remove(struct platform_device *pdev); |
| 173 | static struct vt8231_data *vt8231_update_device(struct device *dev); | 171 | static struct vt8231_data *vt8231_update_device(struct device *dev); |
| 174 | static void vt8231_init_client(struct i2c_client *client); | 172 | static void vt8231_init_device(struct vt8231_data *data); |
| 175 | 173 | ||
| 176 | static inline int vt8231_read_value(struct i2c_client *client, u8 reg) | 174 | static inline int vt8231_read_value(struct vt8231_data *data, u8 reg) |
| 177 | { | 175 | { |
| 178 | return inb_p(client->addr + reg); | 176 | return inb_p(data->addr + reg); |
| 179 | } | 177 | } |
| 180 | 178 | ||
| 181 | static inline void vt8231_write_value(struct i2c_client *client, u8 reg, | 179 | static inline void vt8231_write_value(struct vt8231_data *data, u8 reg, |
| 182 | u8 value) | 180 | u8 value) |
| 183 | { | 181 | { |
| 184 | outb_p(value, client->addr + reg); | 182 | outb_p(value, data->addr + reg); |
| 185 | } | 183 | } |
| 186 | 184 | ||
| 187 | /* following are the sysfs callback functions */ | 185 | /* following are the sysfs callback functions */ |
| @@ -220,13 +218,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | |||
| 220 | { | 218 | { |
| 221 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 219 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 222 | int nr = sensor_attr->index; | 220 | int nr = sensor_attr->index; |
| 223 | struct i2c_client *client = to_i2c_client(dev); | 221 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 224 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 225 | unsigned long val = simple_strtoul(buf, NULL, 10); | 222 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 226 | 223 | ||
| 227 | mutex_lock(&data->update_lock); | 224 | mutex_lock(&data->update_lock); |
| 228 | data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); | 225 | data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); |
| 229 | vt8231_write_value(client, regvoltmin[nr], data->in_min[nr]); | 226 | vt8231_write_value(data, regvoltmin[nr], data->in_min[nr]); |
| 230 | mutex_unlock(&data->update_lock); | 227 | mutex_unlock(&data->update_lock); |
| 231 | return count; | 228 | return count; |
| 232 | } | 229 | } |
| @@ -236,13 +233,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | |||
| 236 | { | 233 | { |
| 237 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 234 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 238 | int nr = sensor_attr->index; | 235 | int nr = sensor_attr->index; |
| 239 | struct i2c_client *client = to_i2c_client(dev); | 236 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 240 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 241 | unsigned long val = simple_strtoul(buf, NULL, 10); | 237 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 242 | 238 | ||
| 243 | mutex_lock(&data->update_lock); | 239 | mutex_lock(&data->update_lock); |
| 244 | data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); | 240 | data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); |
| 245 | vt8231_write_value(client, regvoltmax[nr], data->in_max[nr]); | 241 | vt8231_write_value(data, regvoltmax[nr], data->in_max[nr]); |
| 246 | mutex_unlock(&data->update_lock); | 242 | mutex_unlock(&data->update_lock); |
| 247 | return count; | 243 | return count; |
| 248 | } | 244 | } |
| @@ -278,14 +274,13 @@ static ssize_t show_in5_max(struct device *dev, struct device_attribute *attr, | |||
| 278 | static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr, | 274 | static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr, |
| 279 | const char *buf, size_t count) | 275 | const char *buf, size_t count) |
| 280 | { | 276 | { |
| 281 | struct i2c_client *client = to_i2c_client(dev); | 277 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 282 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 283 | unsigned long val = simple_strtoul(buf, NULL, 10); | 278 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 284 | 279 | ||
| 285 | mutex_lock(&data->update_lock); | 280 | mutex_lock(&data->update_lock); |
| 286 | data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, | 281 | data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, |
| 287 | 0, 255); | 282 | 0, 255); |
| 288 | vt8231_write_value(client, regvoltmin[5], data->in_min[5]); | 283 | vt8231_write_value(data, regvoltmin[5], data->in_min[5]); |
| 289 | mutex_unlock(&data->update_lock); | 284 | mutex_unlock(&data->update_lock); |
| 290 | return count; | 285 | return count; |
| 291 | } | 286 | } |
| @@ -293,14 +288,13 @@ static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr, | |||
| 293 | static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr, | 288 | static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr, |
| 294 | const char *buf, size_t count) | 289 | const char *buf, size_t count) |
| 295 | { | 290 | { |
| 296 | struct i2c_client *client = to_i2c_client(dev); | 291 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 297 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 298 | unsigned long val = simple_strtoul(buf, NULL, 10); | 292 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 299 | 293 | ||
| 300 | mutex_lock(&data->update_lock); | 294 | mutex_lock(&data->update_lock); |
| 301 | data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, | 295 | data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, |
| 302 | 0, 255); | 296 | 0, 255); |
| 303 | vt8231_write_value(client, regvoltmax[5], data->in_max[5]); | 297 | vt8231_write_value(data, regvoltmax[5], data->in_max[5]); |
| 304 | mutex_unlock(&data->update_lock); | 298 | mutex_unlock(&data->update_lock); |
| 305 | return count; | 299 | return count; |
| 306 | } | 300 | } |
| @@ -348,26 +342,24 @@ static ssize_t show_temp0_min(struct device *dev, struct device_attribute *attr, | |||
| 348 | static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr, | 342 | static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr, |
| 349 | const char *buf, size_t count) | 343 | const char *buf, size_t count) |
| 350 | { | 344 | { |
| 351 | struct i2c_client *client = to_i2c_client(dev); | 345 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 352 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 353 | int val = simple_strtol(buf, NULL, 10); | 346 | int val = simple_strtol(buf, NULL, 10); |
| 354 | 347 | ||
| 355 | mutex_lock(&data->update_lock); | 348 | mutex_lock(&data->update_lock); |
| 356 | data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); | 349 | data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); |
| 357 | vt8231_write_value(client, regtempmax[0], data->temp_max[0]); | 350 | vt8231_write_value(data, regtempmax[0], data->temp_max[0]); |
| 358 | mutex_unlock(&data->update_lock); | 351 | mutex_unlock(&data->update_lock); |
| 359 | return count; | 352 | return count; |
| 360 | } | 353 | } |
| 361 | static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr, | 354 | static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr, |
| 362 | const char *buf, size_t count) | 355 | const char *buf, size_t count) |
| 363 | { | 356 | { |
| 364 | struct i2c_client *client = to_i2c_client(dev); | 357 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 365 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 366 | int val = simple_strtol(buf, NULL, 10); | 358 | int val = simple_strtol(buf, NULL, 10); |
| 367 | 359 | ||
| 368 | mutex_lock(&data->update_lock); | 360 | mutex_lock(&data->update_lock); |
| 369 | data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); | 361 | data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); |
| 370 | vt8231_write_value(client, regtempmin[0], data->temp_min[0]); | 362 | vt8231_write_value(data, regtempmin[0], data->temp_min[0]); |
| 371 | mutex_unlock(&data->update_lock); | 363 | mutex_unlock(&data->update_lock); |
| 372 | return count; | 364 | return count; |
| 373 | } | 365 | } |
| @@ -404,13 +396,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
| 404 | { | 396 | { |
| 405 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 397 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 406 | int nr = sensor_attr->index; | 398 | int nr = sensor_attr->index; |
| 407 | struct i2c_client *client = to_i2c_client(dev); | 399 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 408 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 409 | int val = simple_strtol(buf, NULL, 10); | 400 | int val = simple_strtol(buf, NULL, 10); |
| 410 | 401 | ||
| 411 | mutex_lock(&data->update_lock); | 402 | mutex_lock(&data->update_lock); |
| 412 | data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); | 403 | data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); |
| 413 | vt8231_write_value(client, regtempmax[nr], data->temp_max[nr]); | 404 | vt8231_write_value(data, regtempmax[nr], data->temp_max[nr]); |
| 414 | mutex_unlock(&data->update_lock); | 405 | mutex_unlock(&data->update_lock); |
| 415 | return count; | 406 | return count; |
| 416 | } | 407 | } |
| @@ -419,13 +410,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
| 419 | { | 410 | { |
| 420 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 411 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 421 | int nr = sensor_attr->index; | 412 | int nr = sensor_attr->index; |
| 422 | struct i2c_client *client = to_i2c_client(dev); | 413 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 423 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 424 | int val = simple_strtol(buf, NULL, 10); | 414 | int val = simple_strtol(buf, NULL, 10); |
| 425 | 415 | ||
| 426 | mutex_lock(&data->update_lock); | 416 | mutex_lock(&data->update_lock); |
| 427 | data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); | 417 | data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); |
| 428 | vt8231_write_value(client, regtempmin[nr], data->temp_min[nr]); | 418 | vt8231_write_value(data, regtempmin[nr], data->temp_min[nr]); |
| 429 | mutex_unlock(&data->update_lock); | 419 | mutex_unlock(&data->update_lock); |
| 430 | return count; | 420 | return count; |
| 431 | } | 421 | } |
| @@ -486,13 +476,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
| 486 | { | 476 | { |
| 487 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 477 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 488 | int nr = sensor_attr->index; | 478 | int nr = sensor_attr->index; |
| 489 | struct i2c_client *client = to_i2c_client(dev); | 479 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 490 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 491 | int val = simple_strtoul(buf, NULL, 10); | 480 | int val = simple_strtoul(buf, NULL, 10); |
| 492 | 481 | ||
| 493 | mutex_lock(&data->update_lock); | 482 | mutex_lock(&data->update_lock); |
| 494 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 483 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
| 495 | vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); | 484 | vt8231_write_value(data, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); |
| 496 | mutex_unlock(&data->update_lock); | 485 | mutex_unlock(&data->update_lock); |
| 497 | return count; | 486 | return count; |
| 498 | } | 487 | } |
| @@ -500,12 +489,11 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
| 500 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | 489 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, |
| 501 | const char *buf, size_t count) | 490 | const char *buf, size_t count) |
| 502 | { | 491 | { |
| 503 | struct i2c_client *client = to_i2c_client(dev); | 492 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 504 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 505 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 493 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 506 | unsigned long val = simple_strtoul(buf, NULL, 10); | 494 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 507 | int nr = sensor_attr->index; | 495 | int nr = sensor_attr->index; |
| 508 | int old = vt8231_read_value(client, VT8231_REG_FANDIV); | 496 | int old = vt8231_read_value(data, VT8231_REG_FANDIV); |
| 509 | long min = FAN_FROM_REG(data->fan_min[nr], | 497 | long min = FAN_FROM_REG(data->fan_min[nr], |
| 510 | DIV_FROM_REG(data->fan_div[nr])); | 498 | DIV_FROM_REG(data->fan_div[nr])); |
| 511 | 499 | ||
| @@ -516,7 +504,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
| 516 | case 4: data->fan_div[nr] = 2; break; | 504 | case 4: data->fan_div[nr] = 2; break; |
| 517 | case 8: data->fan_div[nr] = 3; break; | 505 | case 8: data->fan_div[nr] = 3; break; |
| 518 | default: | 506 | default: |
| 519 | dev_err(&client->dev, "fan_div value %ld not supported." | 507 | dev_err(dev, "fan_div value %ld not supported." |
| 520 | "Choose one of 1, 2, 4 or 8!\n", val); | 508 | "Choose one of 1, 2, 4 or 8!\n", val); |
| 521 | mutex_unlock(&data->update_lock); | 509 | mutex_unlock(&data->update_lock); |
| 522 | return -EINVAL; | 510 | return -EINVAL; |
| @@ -524,10 +512,10 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
| 524 | 512 | ||
| 525 | /* Correct the fan minimum speed */ | 513 | /* Correct the fan minimum speed */ |
| 526 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 514 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
| 527 | vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); | 515 | vt8231_write_value(data, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); |
| 528 | 516 | ||
| 529 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); | 517 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); |
| 530 | vt8231_write_value(client, VT8231_REG_FANDIV, old); | 518 | vt8231_write_value(data, VT8231_REG_FANDIV, old); |
| 531 | mutex_unlock(&data->update_lock); | 519 | mutex_unlock(&data->update_lock); |
| 532 | return count; | 520 | return count; |
| 533 | } | 521 | } |
| @@ -551,9 +539,16 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | |||
| 551 | struct vt8231_data *data = vt8231_update_device(dev); | 539 | struct vt8231_data *data = vt8231_update_device(dev); |
| 552 | return sprintf(buf, "%d\n", data->alarms); | 540 | return sprintf(buf, "%d\n", data->alarms); |
| 553 | } | 541 | } |
| 554 | |||
| 555 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 542 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
| 556 | 543 | ||
| 544 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
| 545 | *devattr, char *buf) | ||
| 546 | { | ||
| 547 | struct vt8231_data *data = dev_get_drvdata(dev); | ||
| 548 | return sprintf(buf, "%s\n", data->name); | ||
| 549 | } | ||
| 550 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 551 | |||
| 557 | static struct attribute *vt8231_attributes_temps[6][4] = { | 552 | static struct attribute *vt8231_attributes_temps[6][4] = { |
| 558 | { | 553 | { |
| 559 | &dev_attr_temp1_input.attr, | 554 | &dev_attr_temp1_input.attr, |
| @@ -648,6 +643,7 @@ static struct attribute *vt8231_attributes[] = { | |||
| 648 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 643 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
| 649 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 644 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
| 650 | &dev_attr_alarms.attr, | 645 | &dev_attr_alarms.attr, |
| 646 | &dev_attr_name.attr, | ||
| 651 | NULL | 647 | NULL |
| 652 | }; | 648 | }; |
| 653 | 649 | ||
| @@ -655,13 +651,13 @@ static const struct attribute_group vt8231_group = { | |||
| 655 | .attrs = vt8231_attributes, | 651 | .attrs = vt8231_attributes, |
| 656 | }; | 652 | }; |
| 657 | 653 | ||
| 658 | static struct i2c_driver vt8231_driver = { | 654 | static struct platform_driver vt8231_driver = { |
| 659 | .driver = { | 655 | .driver = { |
| 660 | .owner = THIS_MODULE, | 656 | .owner = THIS_MODULE, |
| 661 | .name = "vt8231", | 657 | .name = "vt8231", |
| 662 | }, | 658 | }, |
| 663 | .attach_adapter = vt8231_detect, | 659 | .probe = vt8231_probe, |
| 664 | .detach_client = vt8231_detach_client, | 660 | .remove = __devexit_p(vt8231_remove), |
| 665 | }; | 661 | }; |
| 666 | 662 | ||
| 667 | static struct pci_device_id vt8231_pci_ids[] = { | 663 | static struct pci_device_id vt8231_pci_ids[] = { |
| @@ -680,40 +676,18 @@ static struct pci_driver vt8231_pci_driver = { | |||
| 680 | .probe = vt8231_pci_probe, | 676 | .probe = vt8231_pci_probe, |
| 681 | }; | 677 | }; |
| 682 | 678 | ||
| 683 | int vt8231_detect(struct i2c_adapter *adapter) | 679 | int vt8231_probe(struct platform_device *pdev) |
| 684 | { | 680 | { |
| 685 | struct i2c_client *client; | 681 | struct resource *res; |
| 686 | struct vt8231_data *data; | 682 | struct vt8231_data *data; |
| 687 | int err = 0, i; | 683 | int err = 0, i; |
| 688 | u16 val; | ||
| 689 | |||
| 690 | /* 8231 requires multiple of 256 */ | ||
| 691 | if (force_addr) { | ||
| 692 | isa_address = force_addr & 0xFF00; | ||
| 693 | dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", | ||
| 694 | isa_address); | ||
| 695 | if (PCIBIOS_SUCCESSFUL != pci_write_config_word(s_bridge, | ||
| 696 | VT8231_BASE_REG, isa_address)) | ||
| 697 | return -ENODEV; | ||
| 698 | } | ||
| 699 | |||
| 700 | if (PCIBIOS_SUCCESSFUL != | ||
| 701 | pci_read_config_word(s_bridge, VT8231_ENABLE_REG, &val)) | ||
| 702 | return -ENODEV; | ||
| 703 | |||
| 704 | if (!(val & 0x0001)) { | ||
| 705 | dev_warn(&adapter->dev, "enabling sensors\n"); | ||
| 706 | if (PCIBIOS_SUCCESSFUL != | ||
| 707 | pci_write_config_word(s_bridge, VT8231_ENABLE_REG, | ||
| 708 | val | 0x0001)) | ||
| 709 | return -ENODEV; | ||
| 710 | } | ||
| 711 | 684 | ||
| 712 | /* Reserve the ISA region */ | 685 | /* Reserve the ISA region */ |
| 713 | if (!request_region(isa_address, VT8231_EXTENT, | 686 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 714 | vt8231_pci_driver.name)) { | 687 | if (!request_region(res->start, VT8231_EXTENT, |
| 715 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | 688 | vt8231_driver.driver.name)) { |
| 716 | isa_address); | 689 | dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n", |
| 690 | (unsigned long)res->start, (unsigned long)res->end); | ||
| 717 | return -ENODEV; | 691 | return -ENODEV; |
| 718 | } | 692 | } |
| 719 | 693 | ||
| @@ -722,33 +696,23 @@ int vt8231_detect(struct i2c_adapter *adapter) | |||
| 722 | goto exit_release; | 696 | goto exit_release; |
| 723 | } | 697 | } |
| 724 | 698 | ||
| 725 | client = &data->client; | 699 | platform_set_drvdata(pdev, data); |
| 726 | i2c_set_clientdata(client, data); | 700 | data->addr = res->start; |
| 727 | client->addr = isa_address; | 701 | data->name = "vt8231"; |
| 728 | client->adapter = adapter; | ||
| 729 | client->driver = &vt8231_driver; | ||
| 730 | |||
| 731 | /* Fill in the remaining client fields and put into the global list */ | ||
| 732 | strlcpy(client->name, "vt8231", I2C_NAME_SIZE); | ||
| 733 | 702 | ||
| 734 | mutex_init(&data->update_lock); | 703 | mutex_init(&data->update_lock); |
| 735 | 704 | vt8231_init_device(data); | |
| 736 | /* Tell the I2C layer a new client has arrived */ | ||
| 737 | if ((err = i2c_attach_client(client))) | ||
| 738 | goto exit_free; | ||
| 739 | |||
| 740 | vt8231_init_client(client); | ||
| 741 | 705 | ||
| 742 | /* Register sysfs hooks */ | 706 | /* Register sysfs hooks */ |
| 743 | if ((err = sysfs_create_group(&client->dev.kobj, &vt8231_group))) | 707 | if ((err = sysfs_create_group(&pdev->dev.kobj, &vt8231_group))) |
| 744 | goto exit_detach; | 708 | goto exit_free; |
| 745 | 709 | ||
| 746 | /* Must update device information to find out the config field */ | 710 | /* Must update device information to find out the config field */ |
| 747 | data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG); | 711 | data->uch_config = vt8231_read_value(data, VT8231_REG_UCH_CONFIG); |
| 748 | 712 | ||
| 749 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) { | 713 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) { |
| 750 | if (ISTEMP(i, data->uch_config)) { | 714 | if (ISTEMP(i, data->uch_config)) { |
| 751 | if ((err = sysfs_create_group(&client->dev.kobj, | 715 | if ((err = sysfs_create_group(&pdev->dev.kobj, |
| 752 | &vt8231_group_temps[i]))) | 716 | &vt8231_group_temps[i]))) |
| 753 | goto exit_remove_files; | 717 | goto exit_remove_files; |
| 754 | } | 718 | } |
| @@ -756,13 +720,13 @@ int vt8231_detect(struct i2c_adapter *adapter) | |||
| 756 | 720 | ||
| 757 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) { | 721 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) { |
| 758 | if (ISVOLT(i, data->uch_config)) { | 722 | if (ISVOLT(i, data->uch_config)) { |
| 759 | if ((err = sysfs_create_group(&client->dev.kobj, | 723 | if ((err = sysfs_create_group(&pdev->dev.kobj, |
| 760 | &vt8231_group_volts[i]))) | 724 | &vt8231_group_volts[i]))) |
| 761 | goto exit_remove_files; | 725 | goto exit_remove_files; |
| 762 | } | 726 | } |
| 763 | } | 727 | } |
| 764 | 728 | ||
| 765 | data->class_dev = hwmon_device_register(&client->dev); | 729 | data->class_dev = hwmon_device_register(&pdev->dev); |
| 766 | if (IS_ERR(data->class_dev)) { | 730 | if (IS_ERR(data->class_dev)) { |
| 767 | err = PTR_ERR(data->class_dev); | 731 | err = PTR_ERR(data->class_dev); |
| 768 | goto exit_remove_files; | 732 | goto exit_remove_files; |
| @@ -771,56 +735,52 @@ int vt8231_detect(struct i2c_adapter *adapter) | |||
| 771 | 735 | ||
| 772 | exit_remove_files: | 736 | exit_remove_files: |
| 773 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) | 737 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) |
| 774 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]); | 738 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]); |
| 775 | 739 | ||
| 776 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) | 740 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) |
| 777 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]); | 741 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_temps[i]); |
| 742 | |||
| 743 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group); | ||
| 778 | 744 | ||
| 779 | sysfs_remove_group(&client->dev.kobj, &vt8231_group); | ||
| 780 | exit_detach: | ||
| 781 | i2c_detach_client(client); | ||
| 782 | exit_free: | 745 | exit_free: |
| 746 | platform_set_drvdata(pdev, NULL); | ||
| 783 | kfree(data); | 747 | kfree(data); |
| 748 | |||
| 784 | exit_release: | 749 | exit_release: |
| 785 | release_region(isa_address, VT8231_EXTENT); | 750 | release_region(res->start, VT8231_EXTENT); |
| 786 | return err; | 751 | return err; |
| 787 | } | 752 | } |
| 788 | 753 | ||
| 789 | static int vt8231_detach_client(struct i2c_client *client) | 754 | static int vt8231_remove(struct platform_device *pdev) |
| 790 | { | 755 | { |
| 791 | struct vt8231_data *data = i2c_get_clientdata(client); | 756 | struct vt8231_data *data = platform_get_drvdata(pdev); |
| 792 | int err, i; | 757 | int i; |
| 793 | 758 | ||
| 794 | hwmon_device_unregister(data->class_dev); | 759 | hwmon_device_unregister(data->class_dev); |
| 795 | 760 | ||
| 796 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) | 761 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) |
| 797 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]); | 762 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_volts[i]); |
| 798 | 763 | ||
| 799 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) | 764 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) |
| 800 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]); | 765 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_temps[i]); |
| 801 | 766 | ||
| 802 | sysfs_remove_group(&client->dev.kobj, &vt8231_group); | 767 | sysfs_remove_group(&pdev->dev.kobj, &vt8231_group); |
| 803 | 768 | ||
| 804 | if ((err = i2c_detach_client(client))) { | 769 | release_region(data->addr, VT8231_EXTENT); |
| 805 | return err; | 770 | platform_set_drvdata(pdev, NULL); |
| 806 | } | ||
| 807 | |||
| 808 | release_region(client->addr, VT8231_EXTENT); | ||
| 809 | kfree(data); | 771 | kfree(data); |
| 810 | |||
| 811 | return 0; | 772 | return 0; |
| 812 | } | 773 | } |
| 813 | 774 | ||
| 814 | static void vt8231_init_client(struct i2c_client *client) | 775 | static void vt8231_init_device(struct vt8231_data *data) |
| 815 | { | 776 | { |
| 816 | vt8231_write_value(client, VT8231_REG_TEMP1_CONFIG, 0); | 777 | vt8231_write_value(data, VT8231_REG_TEMP1_CONFIG, 0); |
| 817 | vt8231_write_value(client, VT8231_REG_TEMP2_CONFIG, 0); | 778 | vt8231_write_value(data, VT8231_REG_TEMP2_CONFIG, 0); |
| 818 | } | 779 | } |
| 819 | 780 | ||
| 820 | static struct vt8231_data *vt8231_update_device(struct device *dev) | 781 | static struct vt8231_data *vt8231_update_device(struct device *dev) |
| 821 | { | 782 | { |
| 822 | struct i2c_client *client = to_i2c_client(dev); | 783 | struct vt8231_data *data = dev_get_drvdata(dev); |
| 823 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
| 824 | int i; | 784 | int i; |
| 825 | u16 low; | 785 | u16 low; |
| 826 | 786 | ||
| @@ -830,41 +790,41 @@ static struct vt8231_data *vt8231_update_device(struct device *dev) | |||
| 830 | || !data->valid) { | 790 | || !data->valid) { |
| 831 | for (i = 0; i < 6; i++) { | 791 | for (i = 0; i < 6; i++) { |
| 832 | if (ISVOLT(i, data->uch_config)) { | 792 | if (ISVOLT(i, data->uch_config)) { |
| 833 | data->in[i] = vt8231_read_value(client, | 793 | data->in[i] = vt8231_read_value(data, |
| 834 | regvolt[i]); | 794 | regvolt[i]); |
| 835 | data->in_min[i] = vt8231_read_value(client, | 795 | data->in_min[i] = vt8231_read_value(data, |
| 836 | regvoltmin[i]); | 796 | regvoltmin[i]); |
| 837 | data->in_max[i] = vt8231_read_value(client, | 797 | data->in_max[i] = vt8231_read_value(data, |
| 838 | regvoltmax[i]); | 798 | regvoltmax[i]); |
| 839 | } | 799 | } |
| 840 | } | 800 | } |
| 841 | for (i = 0; i < 2; i++) { | 801 | for (i = 0; i < 2; i++) { |
| 842 | data->fan[i] = vt8231_read_value(client, | 802 | data->fan[i] = vt8231_read_value(data, |
| 843 | VT8231_REG_FAN(i)); | 803 | VT8231_REG_FAN(i)); |
| 844 | data->fan_min[i] = vt8231_read_value(client, | 804 | data->fan_min[i] = vt8231_read_value(data, |
| 845 | VT8231_REG_FAN_MIN(i)); | 805 | VT8231_REG_FAN_MIN(i)); |
| 846 | } | 806 | } |
| 847 | 807 | ||
| 848 | low = vt8231_read_value(client, VT8231_REG_TEMP_LOW01); | 808 | low = vt8231_read_value(data, VT8231_REG_TEMP_LOW01); |
| 849 | low = (low >> 6) | ((low & 0x30) >> 2) | 809 | low = (low >> 6) | ((low & 0x30) >> 2) |
| 850 | | (vt8231_read_value(client, VT8231_REG_TEMP_LOW25) << 4); | 810 | | (vt8231_read_value(data, VT8231_REG_TEMP_LOW25) << 4); |
| 851 | for (i = 0; i < 6; i++) { | 811 | for (i = 0; i < 6; i++) { |
| 852 | if (ISTEMP(i, data->uch_config)) { | 812 | if (ISTEMP(i, data->uch_config)) { |
| 853 | data->temp[i] = (vt8231_read_value(client, | 813 | data->temp[i] = (vt8231_read_value(data, |
| 854 | regtemp[i]) << 2) | 814 | regtemp[i]) << 2) |
| 855 | | ((low >> (2 * i)) & 0x03); | 815 | | ((low >> (2 * i)) & 0x03); |
| 856 | data->temp_max[i] = vt8231_read_value(client, | 816 | data->temp_max[i] = vt8231_read_value(data, |
| 857 | regtempmax[i]); | 817 | regtempmax[i]); |
| 858 | data->temp_min[i] = vt8231_read_value(client, | 818 | data->temp_min[i] = vt8231_read_value(data, |
| 859 | regtempmin[i]); | 819 | regtempmin[i]); |
| 860 | } | 820 | } |
| 861 | } | 821 | } |
| 862 | 822 | ||
| 863 | i = vt8231_read_value(client, VT8231_REG_FANDIV); | 823 | i = vt8231_read_value(data, VT8231_REG_FANDIV); |
| 864 | data->fan_div[0] = (i >> 4) & 0x03; | 824 | data->fan_div[0] = (i >> 4) & 0x03; |
| 865 | data->fan_div[1] = i >> 6; | 825 | data->fan_div[1] = i >> 6; |
| 866 | data->alarms = vt8231_read_value(client, VT8231_REG_ALARM1) | | 826 | data->alarms = vt8231_read_value(data, VT8231_REG_ALARM1) | |
| 867 | (vt8231_read_value(client, VT8231_REG_ALARM2) << 8); | 827 | (vt8231_read_value(data, VT8231_REG_ALARM2) << 8); |
| 868 | 828 | ||
| 869 | /* Set alarm flags correctly */ | 829 | /* Set alarm flags correctly */ |
| 870 | if (!data->fan[0] && data->fan_min[0]) { | 830 | if (!data->fan[0] && data->fan_min[0]) { |
| @@ -888,33 +848,102 @@ static struct vt8231_data *vt8231_update_device(struct device *dev) | |||
| 888 | return data; | 848 | return data; |
| 889 | } | 849 | } |
| 890 | 850 | ||
| 851 | static int __devinit vt8231_device_add(unsigned short address) | ||
| 852 | { | ||
| 853 | struct resource res = { | ||
| 854 | .start = address, | ||
| 855 | .end = address + VT8231_EXTENT - 1, | ||
| 856 | .name = "vt8231", | ||
| 857 | .flags = IORESOURCE_IO, | ||
| 858 | }; | ||
| 859 | int err; | ||
| 860 | |||
| 861 | pdev = platform_device_alloc("vt8231", address); | ||
| 862 | if (!pdev) { | ||
| 863 | err = -ENOMEM; | ||
| 864 | printk(KERN_ERR "vt8231: Device allocation failed\n"); | ||
| 865 | goto exit; | ||
| 866 | } | ||
| 867 | |||
| 868 | err = platform_device_add_resources(pdev, &res, 1); | ||
| 869 | if (err) { | ||
| 870 | printk(KERN_ERR "vt8231: Device resource addition failed " | ||
| 871 | "(%d)\n", err); | ||
| 872 | goto exit_device_put; | ||
| 873 | } | ||
| 874 | |||
| 875 | err = platform_device_add(pdev); | ||
| 876 | if (err) { | ||
| 877 | printk(KERN_ERR "vt8231: Device addition failed (%d)\n", | ||
| 878 | err); | ||
| 879 | goto exit_device_put; | ||
| 880 | } | ||
| 881 | |||
| 882 | return 0; | ||
| 883 | |||
| 884 | exit_device_put: | ||
| 885 | platform_device_put(pdev); | ||
| 886 | exit: | ||
| 887 | return err; | ||
| 888 | } | ||
| 889 | |||
| 891 | static int __devinit vt8231_pci_probe(struct pci_dev *dev, | 890 | static int __devinit vt8231_pci_probe(struct pci_dev *dev, |
| 892 | const struct pci_device_id *id) | 891 | const struct pci_device_id *id) |
| 893 | { | 892 | { |
| 894 | u16 val; | 893 | u16 address, val; |
| 894 | if (force_addr) { | ||
| 895 | address = force_addr & 0xff00; | ||
| 896 | dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", | ||
| 897 | address); | ||
| 898 | |||
| 899 | if (PCIBIOS_SUCCESSFUL != | ||
| 900 | pci_write_config_word(dev, VT8231_BASE_REG, address | 1)) | ||
| 901 | return -ENODEV; | ||
| 902 | } | ||
| 895 | 903 | ||
| 896 | if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_BASE_REG, | 904 | if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_BASE_REG, |
| 897 | &val)) | 905 | &val)) |
| 898 | return -ENODEV; | 906 | return -ENODEV; |
| 899 | 907 | ||
| 900 | isa_address = val & ~(VT8231_EXTENT - 1); | 908 | address = val & ~(VT8231_EXTENT - 1); |
| 901 | if (isa_address == 0 && force_addr == 0) { | 909 | if (address == 0) { |
| 902 | dev_err(&dev->dev, "base address not set -\ | 910 | dev_err(&dev->dev, "base address not set -\ |
| 903 | upgrade BIOS or use force_addr=0xaddr\n"); | 911 | upgrade BIOS or use force_addr=0xaddr\n"); |
| 904 | return -ENODEV; | 912 | return -ENODEV; |
| 905 | } | 913 | } |
| 906 | 914 | ||
| 907 | s_bridge = pci_dev_get(dev); | 915 | if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_ENABLE_REG, |
| 916 | &val)) | ||
| 917 | return -ENODEV; | ||
| 908 | 918 | ||
| 909 | if (i2c_isa_add_driver(&vt8231_driver)) { | 919 | if (!(val & 0x0001)) { |
| 910 | pci_dev_put(s_bridge); | 920 | dev_warn(&dev->dev, "enabling sensors\n"); |
| 911 | s_bridge = NULL; | 921 | if (PCIBIOS_SUCCESSFUL != |
| 922 | pci_write_config_word(dev, VT8231_ENABLE_REG, | ||
| 923 | val | 0x0001)) | ||
| 924 | return -ENODEV; | ||
| 912 | } | 925 | } |
| 913 | 926 | ||
| 927 | if (platform_driver_register(&vt8231_driver)) | ||
| 928 | goto exit; | ||
| 929 | |||
| 930 | /* Sets global pdev as a side effect */ | ||
| 931 | if (vt8231_device_add(address)) | ||
| 932 | goto exit_unregister; | ||
| 933 | |||
| 914 | /* Always return failure here. This is to allow other drivers to bind | 934 | /* Always return failure here. This is to allow other drivers to bind |
| 915 | * to this pci device. We don't really want to have control over the | 935 | * to this pci device. We don't really want to have control over the |
| 916 | * pci device, we only wanted to read as few register values from it. | 936 | * pci device, we only wanted to read as few register values from it. |
| 917 | */ | 937 | */ |
| 938 | |||
| 939 | /* We do, however, mark ourselves as using the PCI device to stop it | ||
| 940 | getting unloaded. */ | ||
| 941 | s_bridge = pci_dev_get(dev); | ||
| 942 | return -ENODEV; | ||
| 943 | |||
| 944 | exit_unregister: | ||
| 945 | platform_driver_unregister(&vt8231_driver); | ||
| 946 | exit: | ||
| 918 | return -ENODEV; | 947 | return -ENODEV; |
| 919 | } | 948 | } |
| 920 | 949 | ||
| @@ -927,7 +956,8 @@ static void __exit sm_vt8231_exit(void) | |||
| 927 | { | 956 | { |
| 928 | pci_unregister_driver(&vt8231_pci_driver); | 957 | pci_unregister_driver(&vt8231_pci_driver); |
| 929 | if (s_bridge != NULL) { | 958 | if (s_bridge != NULL) { |
| 930 | i2c_isa_del_driver(&vt8231_driver); | 959 | platform_device_unregister(pdev); |
| 960 | platform_driver_unregister(&vt8231_driver); | ||
| 931 | pci_dev_put(s_bridge); | 961 | pci_dev_put(s_bridge); |
| 932 | s_bridge = NULL; | 962 | s_bridge = NULL; |
| 933 | } | 963 | } |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 30a76404f0af..c51ae2e17758 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
| @@ -41,41 +41,39 @@ | |||
| 41 | #include <linux/module.h> | 41 | #include <linux/module.h> |
| 42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
| 43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
| 44 | #include <linux/i2c.h> | 44 | #include <linux/jiffies.h> |
| 45 | #include <linux/i2c-isa.h> | 45 | #include <linux/platform_device.h> |
| 46 | #include <linux/hwmon.h> | 46 | #include <linux/hwmon.h> |
| 47 | #include <linux/hwmon-sysfs.h> | 47 | #include <linux/hwmon-sysfs.h> |
| 48 | #include <linux/hwmon-vid.h> | ||
| 48 | #include <linux/err.h> | 49 | #include <linux/err.h> |
| 49 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
| 50 | #include <asm/io.h> | 51 | #include <asm/io.h> |
| 51 | #include "lm75.h" | 52 | #include "lm75.h" |
| 52 | 53 | ||
| 53 | /* The actual ISA address is read from Super-I/O configuration space */ | 54 | enum kinds { w83627ehf, w83627dhg }; |
| 54 | static unsigned short address; | ||
| 55 | 55 | ||
| 56 | /* | 56 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ |
| 57 | * Super-I/O constants and functions | 57 | static const char * w83627ehf_device_names[] = { |
| 58 | */ | 58 | "w83627ehf", |
| 59 | "w83627dhg", | ||
| 60 | }; | ||
| 61 | |||
| 62 | #define DRVNAME "w83627ehf" | ||
| 59 | 63 | ||
| 60 | /* | 64 | /* |
| 61 | * The three following globals are initialized in w83627ehf_find(), before | 65 | * Super-I/O constants and functions |
| 62 | * the i2c-isa device is created. Otherwise, they could be stored in | ||
| 63 | * w83627ehf_data. This is ugly, but necessary, and when the driver is next | ||
| 64 | * updated to become a platform driver, the globals will disappear. | ||
| 65 | */ | 66 | */ |
| 66 | static int REG; /* The register to read/write */ | ||
| 67 | static int VAL; /* The value to read/write */ | ||
| 68 | /* The w83627ehf/ehg have 10 voltage inputs, but the w83627dhg has 9. This | ||
| 69 | * value is also used in w83627ehf_detect() to export a device name in sysfs | ||
| 70 | * (e.g. w83627ehf or w83627dhg) */ | ||
| 71 | static int w83627ehf_num_in; | ||
| 72 | 67 | ||
| 73 | #define W83627EHF_LD_HWM 0x0b | 68 | #define W83627EHF_LD_HWM 0x0b |
| 74 | 69 | ||
| 75 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | 70 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ |
| 76 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | 71 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ |
| 72 | #define SIO_REG_EN_VRM10 0x2C /* GPIO3, GPIO4 selection */ | ||
| 77 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | 73 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ |
| 78 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | 74 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ |
| 75 | #define SIO_REG_VID_CTRL 0xF0 /* VID control */ | ||
| 76 | #define SIO_REG_VID_DATA 0xF1 /* VID data */ | ||
| 79 | 77 | ||
| 80 | #define SIO_W83627EHF_ID 0x8850 | 78 | #define SIO_W83627EHF_ID 0x8850 |
| 81 | #define SIO_W83627EHG_ID 0x8860 | 79 | #define SIO_W83627EHG_ID 0x8860 |
| @@ -83,38 +81,38 @@ static int w83627ehf_num_in; | |||
| 83 | #define SIO_ID_MASK 0xFFF0 | 81 | #define SIO_ID_MASK 0xFFF0 |
| 84 | 82 | ||
| 85 | static inline void | 83 | static inline void |
| 86 | superio_outb(int reg, int val) | 84 | superio_outb(int ioreg, int reg, int val) |
| 87 | { | 85 | { |
| 88 | outb(reg, REG); | 86 | outb(reg, ioreg); |
| 89 | outb(val, VAL); | 87 | outb(val, ioreg + 1); |
| 90 | } | 88 | } |
| 91 | 89 | ||
| 92 | static inline int | 90 | static inline int |
| 93 | superio_inb(int reg) | 91 | superio_inb(int ioreg, int reg) |
| 94 | { | 92 | { |
| 95 | outb(reg, REG); | 93 | outb(reg, ioreg); |
| 96 | return inb(VAL); | 94 | return inb(ioreg + 1); |
| 97 | } | 95 | } |
| 98 | 96 | ||
| 99 | static inline void | 97 | static inline void |
| 100 | superio_select(int ld) | 98 | superio_select(int ioreg, int ld) |
| 101 | { | 99 | { |
| 102 | outb(SIO_REG_LDSEL, REG); | 100 | outb(SIO_REG_LDSEL, ioreg); |
| 103 | outb(ld, VAL); | 101 | outb(ld, ioreg + 1); |
| 104 | } | 102 | } |
| 105 | 103 | ||
| 106 | static inline void | 104 | static inline void |
| 107 | superio_enter(void) | 105 | superio_enter(int ioreg) |
| 108 | { | 106 | { |
| 109 | outb(0x87, REG); | 107 | outb(0x87, ioreg); |
| 110 | outb(0x87, REG); | 108 | outb(0x87, ioreg); |
| 111 | } | 109 | } |
| 112 | 110 | ||
| 113 | static inline void | 111 | static inline void |
| 114 | superio_exit(void) | 112 | superio_exit(int ioreg) |
| 115 | { | 113 | { |
| 116 | outb(0x02, REG); | 114 | outb(0x02, ioreg); |
| 117 | outb(0x02, VAL); | 115 | outb(0x02, ioreg + 1); |
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | /* | 118 | /* |
| @@ -124,8 +122,8 @@ superio_exit(void) | |||
| 124 | #define IOREGION_ALIGNMENT ~7 | 122 | #define IOREGION_ALIGNMENT ~7 |
| 125 | #define IOREGION_OFFSET 5 | 123 | #define IOREGION_OFFSET 5 |
| 126 | #define IOREGION_LENGTH 2 | 124 | #define IOREGION_LENGTH 2 |
| 127 | #define ADDR_REG_OFFSET 5 | 125 | #define ADDR_REG_OFFSET 0 |
| 128 | #define DATA_REG_OFFSET 6 | 126 | #define DATA_REG_OFFSET 1 |
| 129 | 127 | ||
| 130 | #define W83627EHF_REG_BANK 0x4E | 128 | #define W83627EHF_REG_BANK 0x4E |
| 131 | #define W83627EHF_REG_CONFIG 0x40 | 129 | #define W83627EHF_REG_CONFIG 0x40 |
| @@ -255,7 +253,9 @@ static inline u8 in_to_reg(u32 val, u8 nr) | |||
| 255 | */ | 253 | */ |
| 256 | 254 | ||
| 257 | struct w83627ehf_data { | 255 | struct w83627ehf_data { |
| 258 | struct i2c_client client; | 256 | int addr; /* IO base of hw monitor block */ |
| 257 | const char *name; | ||
| 258 | |||
| 259 | struct class_device *class_dev; | 259 | struct class_device *class_dev; |
| 260 | struct mutex lock; | 260 | struct mutex lock; |
| 261 | 261 | ||
| @@ -264,6 +264,7 @@ struct w83627ehf_data { | |||
| 264 | unsigned long last_updated; /* In jiffies */ | 264 | unsigned long last_updated; /* In jiffies */ |
| 265 | 265 | ||
| 266 | /* Register values */ | 266 | /* Register values */ |
| 267 | u8 in_num; /* number of in inputs we have */ | ||
| 267 | u8 in[10]; /* Register value */ | 268 | u8 in[10]; /* Register value */ |
| 268 | u8 in_max[10]; /* Register value */ | 269 | u8 in_max[10]; /* Register value */ |
| 269 | u8 in_min[10]; /* Register value */ | 270 | u8 in_min[10]; /* Register value */ |
| @@ -271,6 +272,7 @@ struct w83627ehf_data { | |||
| 271 | u8 fan_min[5]; | 272 | u8 fan_min[5]; |
| 272 | u8 fan_div[5]; | 273 | u8 fan_div[5]; |
| 273 | u8 has_fan; /* some fan inputs can be disabled */ | 274 | u8 has_fan; /* some fan inputs can be disabled */ |
| 275 | u8 temp_type[3]; | ||
| 274 | s8 temp1; | 276 | s8 temp1; |
| 275 | s8 temp1_max; | 277 | s8 temp1_max; |
| 276 | s8 temp1_max_hyst; | 278 | s8 temp1_max_hyst; |
| @@ -288,6 +290,14 @@ struct w83627ehf_data { | |||
| 288 | 290 | ||
| 289 | u8 fan_min_output[4]; /* minimum fan speed */ | 291 | u8 fan_min_output[4]; /* minimum fan speed */ |
| 290 | u8 fan_stop_time[4]; | 292 | u8 fan_stop_time[4]; |
| 293 | |||
| 294 | u8 vid; | ||
| 295 | u8 vrm; | ||
| 296 | }; | ||
| 297 | |||
| 298 | struct w83627ehf_sio_data { | ||
| 299 | int sioreg; | ||
| 300 | enum kinds kind; | ||
| 291 | }; | 301 | }; |
| 292 | 302 | ||
| 293 | static inline int is_word_sized(u16 reg) | 303 | static inline int is_word_sized(u16 reg) |
| @@ -303,156 +313,152 @@ static inline int is_word_sized(u16 reg) | |||
| 303 | nothing for registers which live in bank 0. For others, they respectively | 313 | nothing for registers which live in bank 0. For others, they respectively |
| 304 | set the bank register to the correct value (before the register is | 314 | set the bank register to the correct value (before the register is |
| 305 | accessed), and back to 0 (afterwards). */ | 315 | accessed), and back to 0 (afterwards). */ |
| 306 | static inline void w83627ehf_set_bank(struct i2c_client *client, u16 reg) | 316 | static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) |
| 307 | { | 317 | { |
| 308 | if (reg & 0xff00) { | 318 | if (reg & 0xff00) { |
| 309 | outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET); | 319 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
| 310 | outb_p(reg >> 8, client->addr + DATA_REG_OFFSET); | 320 | outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); |
| 311 | } | 321 | } |
| 312 | } | 322 | } |
| 313 | 323 | ||
| 314 | static inline void w83627ehf_reset_bank(struct i2c_client *client, u16 reg) | 324 | static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) |
| 315 | { | 325 | { |
| 316 | if (reg & 0xff00) { | 326 | if (reg & 0xff00) { |
| 317 | outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET); | 327 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
| 318 | outb_p(0, client->addr + DATA_REG_OFFSET); | 328 | outb_p(0, data->addr + DATA_REG_OFFSET); |
| 319 | } | 329 | } |
| 320 | } | 330 | } |
| 321 | 331 | ||
| 322 | static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg) | 332 | static u16 w83627ehf_read_value(struct w83627ehf_data *data, u16 reg) |
| 323 | { | 333 | { |
| 324 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 325 | int res, word_sized = is_word_sized(reg); | 334 | int res, word_sized = is_word_sized(reg); |
| 326 | 335 | ||
| 327 | mutex_lock(&data->lock); | 336 | mutex_lock(&data->lock); |
| 328 | 337 | ||
| 329 | w83627ehf_set_bank(client, reg); | 338 | w83627ehf_set_bank(data, reg); |
| 330 | outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); | 339 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); |
| 331 | res = inb_p(client->addr + DATA_REG_OFFSET); | 340 | res = inb_p(data->addr + DATA_REG_OFFSET); |
| 332 | if (word_sized) { | 341 | if (word_sized) { |
| 333 | outb_p((reg & 0xff) + 1, | 342 | outb_p((reg & 0xff) + 1, |
| 334 | client->addr + ADDR_REG_OFFSET); | 343 | data->addr + ADDR_REG_OFFSET); |
| 335 | res = (res << 8) + inb_p(client->addr + DATA_REG_OFFSET); | 344 | res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET); |
| 336 | } | 345 | } |
| 337 | w83627ehf_reset_bank(client, reg); | 346 | w83627ehf_reset_bank(data, reg); |
| 338 | 347 | ||
| 339 | mutex_unlock(&data->lock); | 348 | mutex_unlock(&data->lock); |
| 340 | 349 | ||
| 341 | return res; | 350 | return res; |
| 342 | } | 351 | } |
| 343 | 352 | ||
| 344 | static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value) | 353 | static int w83627ehf_write_value(struct w83627ehf_data *data, u16 reg, u16 value) |
| 345 | { | 354 | { |
| 346 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 347 | int word_sized = is_word_sized(reg); | 355 | int word_sized = is_word_sized(reg); |
| 348 | 356 | ||
| 349 | mutex_lock(&data->lock); | 357 | mutex_lock(&data->lock); |
| 350 | 358 | ||
| 351 | w83627ehf_set_bank(client, reg); | 359 | w83627ehf_set_bank(data, reg); |
| 352 | outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); | 360 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); |
| 353 | if (word_sized) { | 361 | if (word_sized) { |
| 354 | outb_p(value >> 8, client->addr + DATA_REG_OFFSET); | 362 | outb_p(value >> 8, data->addr + DATA_REG_OFFSET); |
| 355 | outb_p((reg & 0xff) + 1, | 363 | outb_p((reg & 0xff) + 1, |
| 356 | client->addr + ADDR_REG_OFFSET); | 364 | data->addr + ADDR_REG_OFFSET); |
| 357 | } | 365 | } |
| 358 | outb_p(value & 0xff, client->addr + DATA_REG_OFFSET); | 366 | outb_p(value & 0xff, data->addr + DATA_REG_OFFSET); |
| 359 | w83627ehf_reset_bank(client, reg); | 367 | w83627ehf_reset_bank(data, reg); |
| 360 | 368 | ||
| 361 | mutex_unlock(&data->lock); | 369 | mutex_unlock(&data->lock); |
| 362 | return 0; | 370 | return 0; |
| 363 | } | 371 | } |
| 364 | 372 | ||
| 365 | /* This function assumes that the caller holds data->update_lock */ | 373 | /* This function assumes that the caller holds data->update_lock */ |
| 366 | static void w83627ehf_write_fan_div(struct i2c_client *client, int nr) | 374 | static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr) |
| 367 | { | 375 | { |
| 368 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 369 | u8 reg; | 376 | u8 reg; |
| 370 | 377 | ||
| 371 | switch (nr) { | 378 | switch (nr) { |
| 372 | case 0: | 379 | case 0: |
| 373 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf) | 380 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0xcf) |
| 374 | | ((data->fan_div[0] & 0x03) << 4); | 381 | | ((data->fan_div[0] & 0x03) << 4); |
| 375 | /* fan5 input control bit is write only, compute the value */ | 382 | /* fan5 input control bit is write only, compute the value */ |
| 376 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | 383 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; |
| 377 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 384 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg); |
| 378 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf) | 385 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xdf) |
| 379 | | ((data->fan_div[0] & 0x04) << 3); | 386 | | ((data->fan_div[0] & 0x04) << 3); |
| 380 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 387 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
| 381 | break; | 388 | break; |
| 382 | case 1: | 389 | case 1: |
| 383 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f) | 390 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0x3f) |
| 384 | | ((data->fan_div[1] & 0x03) << 6); | 391 | | ((data->fan_div[1] & 0x03) << 6); |
| 385 | /* fan5 input control bit is write only, compute the value */ | 392 | /* fan5 input control bit is write only, compute the value */ |
| 386 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | 393 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; |
| 387 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 394 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg); |
| 388 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf) | 395 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xbf) |
| 389 | | ((data->fan_div[1] & 0x04) << 4); | 396 | | ((data->fan_div[1] & 0x04) << 4); |
| 390 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 397 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
| 391 | break; | 398 | break; |
| 392 | case 2: | 399 | case 2: |
| 393 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV2) & 0x3f) | 400 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV2) & 0x3f) |
| 394 | | ((data->fan_div[2] & 0x03) << 6); | 401 | | ((data->fan_div[2] & 0x03) << 6); |
| 395 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV2, reg); | 402 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV2, reg); |
| 396 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0x7f) | 403 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0x7f) |
| 397 | | ((data->fan_div[2] & 0x04) << 5); | 404 | | ((data->fan_div[2] & 0x04) << 5); |
| 398 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 405 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
| 399 | break; | 406 | break; |
| 400 | case 3: | 407 | case 3: |
| 401 | reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0xfc) | 408 | reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0xfc) |
| 402 | | (data->fan_div[3] & 0x03); | 409 | | (data->fan_div[3] & 0x03); |
| 403 | w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg); | 410 | w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg); |
| 404 | reg = (w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT) & 0x7f) | 411 | reg = (w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT) & 0x7f) |
| 405 | | ((data->fan_div[3] & 0x04) << 5); | 412 | | ((data->fan_div[3] & 0x04) << 5); |
| 406 | w83627ehf_write_value(client, W83627EHF_REG_SMI_OVT, reg); | 413 | w83627ehf_write_value(data, W83627EHF_REG_SMI_OVT, reg); |
| 407 | break; | 414 | break; |
| 408 | case 4: | 415 | case 4: |
| 409 | reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0x73) | 416 | reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0x73) |
| 410 | | ((data->fan_div[4] & 0x03) << 2) | 417 | | ((data->fan_div[4] & 0x03) << 2) |
| 411 | | ((data->fan_div[4] & 0x04) << 5); | 418 | | ((data->fan_div[4] & 0x04) << 5); |
| 412 | w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg); | 419 | w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg); |
| 413 | break; | 420 | break; |
| 414 | } | 421 | } |
| 415 | } | 422 | } |
| 416 | 423 | ||
| 417 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | 424 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) |
| 418 | { | 425 | { |
| 419 | struct i2c_client *client = to_i2c_client(dev); | 426 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 420 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 421 | int pwmcfg = 0, tolerance = 0; /* shut up the compiler */ | 427 | int pwmcfg = 0, tolerance = 0; /* shut up the compiler */ |
| 422 | int i; | 428 | int i; |
| 423 | 429 | ||
| 424 | mutex_lock(&data->update_lock); | 430 | mutex_lock(&data->update_lock); |
| 425 | 431 | ||
| 426 | if (time_after(jiffies, data->last_updated + HZ) | 432 | if (time_after(jiffies, data->last_updated + HZ + HZ/2) |
| 427 | || !data->valid) { | 433 | || !data->valid) { |
| 428 | /* Fan clock dividers */ | 434 | /* Fan clock dividers */ |
| 429 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); | 435 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); |
| 430 | data->fan_div[0] = (i >> 4) & 0x03; | 436 | data->fan_div[0] = (i >> 4) & 0x03; |
| 431 | data->fan_div[1] = (i >> 6) & 0x03; | 437 | data->fan_div[1] = (i >> 6) & 0x03; |
| 432 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV2); | 438 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); |
| 433 | data->fan_div[2] = (i >> 6) & 0x03; | 439 | data->fan_div[2] = (i >> 6) & 0x03; |
| 434 | i = w83627ehf_read_value(client, W83627EHF_REG_VBAT); | 440 | i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); |
| 435 | data->fan_div[0] |= (i >> 3) & 0x04; | 441 | data->fan_div[0] |= (i >> 3) & 0x04; |
| 436 | data->fan_div[1] |= (i >> 4) & 0x04; | 442 | data->fan_div[1] |= (i >> 4) & 0x04; |
| 437 | data->fan_div[2] |= (i >> 5) & 0x04; | 443 | data->fan_div[2] |= (i >> 5) & 0x04; |
| 438 | if (data->has_fan & ((1 << 3) | (1 << 4))) { | 444 | if (data->has_fan & ((1 << 3) | (1 << 4))) { |
| 439 | i = w83627ehf_read_value(client, W83627EHF_REG_DIODE); | 445 | i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); |
| 440 | data->fan_div[3] = i & 0x03; | 446 | data->fan_div[3] = i & 0x03; |
| 441 | data->fan_div[4] = ((i >> 2) & 0x03) | 447 | data->fan_div[4] = ((i >> 2) & 0x03) |
| 442 | | ((i >> 5) & 0x04); | 448 | | ((i >> 5) & 0x04); |
| 443 | } | 449 | } |
| 444 | if (data->has_fan & (1 << 3)) { | 450 | if (data->has_fan & (1 << 3)) { |
| 445 | i = w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT); | 451 | i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); |
| 446 | data->fan_div[3] |= (i >> 5) & 0x04; | 452 | data->fan_div[3] |= (i >> 5) & 0x04; |
| 447 | } | 453 | } |
| 448 | 454 | ||
| 449 | /* Measured voltages and limits */ | 455 | /* Measured voltages and limits */ |
| 450 | for (i = 0; i < w83627ehf_num_in; i++) { | 456 | for (i = 0; i < data->in_num; i++) { |
| 451 | data->in[i] = w83627ehf_read_value(client, | 457 | data->in[i] = w83627ehf_read_value(data, |
| 452 | W83627EHF_REG_IN(i)); | 458 | W83627EHF_REG_IN(i)); |
| 453 | data->in_min[i] = w83627ehf_read_value(client, | 459 | data->in_min[i] = w83627ehf_read_value(data, |
| 454 | W83627EHF_REG_IN_MIN(i)); | 460 | W83627EHF_REG_IN_MIN(i)); |
| 455 | data->in_max[i] = w83627ehf_read_value(client, | 461 | data->in_max[i] = w83627ehf_read_value(data, |
| 456 | W83627EHF_REG_IN_MAX(i)); | 462 | W83627EHF_REG_IN_MAX(i)); |
| 457 | } | 463 | } |
| 458 | 464 | ||
| @@ -461,9 +467,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 461 | if (!(data->has_fan & (1 << i))) | 467 | if (!(data->has_fan & (1 << i))) |
| 462 | continue; | 468 | continue; |
| 463 | 469 | ||
| 464 | data->fan[i] = w83627ehf_read_value(client, | 470 | data->fan[i] = w83627ehf_read_value(data, |
| 465 | W83627EHF_REG_FAN[i]); | 471 | W83627EHF_REG_FAN[i]); |
| 466 | data->fan_min[i] = w83627ehf_read_value(client, | 472 | data->fan_min[i] = w83627ehf_read_value(data, |
| 467 | W83627EHF_REG_FAN_MIN[i]); | 473 | W83627EHF_REG_FAN_MIN[i]); |
| 468 | 474 | ||
| 469 | /* If we failed to measure the fan speed and clock | 475 | /* If we failed to measure the fan speed and clock |
| @@ -471,16 +477,16 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 471 | time */ | 477 | time */ |
| 472 | if (data->fan[i] == 0xff | 478 | if (data->fan[i] == 0xff |
| 473 | && data->fan_div[i] < 0x07) { | 479 | && data->fan_div[i] < 0x07) { |
| 474 | dev_dbg(&client->dev, "Increasing fan%d " | 480 | dev_dbg(dev, "Increasing fan%d " |
| 475 | "clock divider from %u to %u\n", | 481 | "clock divider from %u to %u\n", |
| 476 | i + 1, div_from_reg(data->fan_div[i]), | 482 | i + 1, div_from_reg(data->fan_div[i]), |
| 477 | div_from_reg(data->fan_div[i] + 1)); | 483 | div_from_reg(data->fan_div[i] + 1)); |
| 478 | data->fan_div[i]++; | 484 | data->fan_div[i]++; |
| 479 | w83627ehf_write_fan_div(client, i); | 485 | w83627ehf_write_fan_div(data, i); |
| 480 | /* Preserve min limit if possible */ | 486 | /* Preserve min limit if possible */ |
| 481 | if (data->fan_min[i] >= 2 | 487 | if (data->fan_min[i] >= 2 |
| 482 | && data->fan_min[i] != 255) | 488 | && data->fan_min[i] != 255) |
| 483 | w83627ehf_write_value(client, | 489 | w83627ehf_write_value(data, |
| 484 | W83627EHF_REG_FAN_MIN[i], | 490 | W83627EHF_REG_FAN_MIN[i], |
| 485 | (data->fan_min[i] /= 2)); | 491 | (data->fan_min[i] /= 2)); |
| 486 | } | 492 | } |
| @@ -489,9 +495,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 489 | for (i = 0; i < 4; i++) { | 495 | for (i = 0; i < 4; i++) { |
| 490 | /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ | 496 | /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ |
| 491 | if (i != 1) { | 497 | if (i != 1) { |
| 492 | pwmcfg = w83627ehf_read_value(client, | 498 | pwmcfg = w83627ehf_read_value(data, |
| 493 | W83627EHF_REG_PWM_ENABLE[i]); | 499 | W83627EHF_REG_PWM_ENABLE[i]); |
| 494 | tolerance = w83627ehf_read_value(client, | 500 | tolerance = w83627ehf_read_value(data, |
| 495 | W83627EHF_REG_TOLERANCE[i]); | 501 | W83627EHF_REG_TOLERANCE[i]); |
| 496 | } | 502 | } |
| 497 | data->pwm_mode[i] = | 503 | data->pwm_mode[i] = |
| @@ -500,14 +506,14 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 500 | data->pwm_enable[i] = | 506 | data->pwm_enable[i] = |
| 501 | ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i]) | 507 | ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i]) |
| 502 | & 3) + 1; | 508 | & 3) + 1; |
| 503 | data->pwm[i] = w83627ehf_read_value(client, | 509 | data->pwm[i] = w83627ehf_read_value(data, |
| 504 | W83627EHF_REG_PWM[i]); | 510 | W83627EHF_REG_PWM[i]); |
| 505 | data->fan_min_output[i] = w83627ehf_read_value(client, | 511 | data->fan_min_output[i] = w83627ehf_read_value(data, |
| 506 | W83627EHF_REG_FAN_MIN_OUTPUT[i]); | 512 | W83627EHF_REG_FAN_MIN_OUTPUT[i]); |
| 507 | data->fan_stop_time[i] = w83627ehf_read_value(client, | 513 | data->fan_stop_time[i] = w83627ehf_read_value(data, |
| 508 | W83627EHF_REG_FAN_STOP_TIME[i]); | 514 | W83627EHF_REG_FAN_STOP_TIME[i]); |
| 509 | data->target_temp[i] = | 515 | data->target_temp[i] = |
| 510 | w83627ehf_read_value(client, | 516 | w83627ehf_read_value(data, |
| 511 | W83627EHF_REG_TARGET[i]) & | 517 | W83627EHF_REG_TARGET[i]) & |
| 512 | (data->pwm_mode[i] == 1 ? 0x7f : 0xff); | 518 | (data->pwm_mode[i] == 1 ? 0x7f : 0xff); |
| 513 | data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) | 519 | data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) |
| @@ -515,26 +521,26 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 515 | } | 521 | } |
| 516 | 522 | ||
| 517 | /* Measured temperatures and limits */ | 523 | /* Measured temperatures and limits */ |
| 518 | data->temp1 = w83627ehf_read_value(client, | 524 | data->temp1 = w83627ehf_read_value(data, |
| 519 | W83627EHF_REG_TEMP1); | 525 | W83627EHF_REG_TEMP1); |
| 520 | data->temp1_max = w83627ehf_read_value(client, | 526 | data->temp1_max = w83627ehf_read_value(data, |
| 521 | W83627EHF_REG_TEMP1_OVER); | 527 | W83627EHF_REG_TEMP1_OVER); |
| 522 | data->temp1_max_hyst = w83627ehf_read_value(client, | 528 | data->temp1_max_hyst = w83627ehf_read_value(data, |
| 523 | W83627EHF_REG_TEMP1_HYST); | 529 | W83627EHF_REG_TEMP1_HYST); |
| 524 | for (i = 0; i < 2; i++) { | 530 | for (i = 0; i < 2; i++) { |
| 525 | data->temp[i] = w83627ehf_read_value(client, | 531 | data->temp[i] = w83627ehf_read_value(data, |
| 526 | W83627EHF_REG_TEMP[i]); | 532 | W83627EHF_REG_TEMP[i]); |
| 527 | data->temp_max[i] = w83627ehf_read_value(client, | 533 | data->temp_max[i] = w83627ehf_read_value(data, |
| 528 | W83627EHF_REG_TEMP_OVER[i]); | 534 | W83627EHF_REG_TEMP_OVER[i]); |
| 529 | data->temp_max_hyst[i] = w83627ehf_read_value(client, | 535 | data->temp_max_hyst[i] = w83627ehf_read_value(data, |
| 530 | W83627EHF_REG_TEMP_HYST[i]); | 536 | W83627EHF_REG_TEMP_HYST[i]); |
| 531 | } | 537 | } |
| 532 | 538 | ||
| 533 | data->alarms = w83627ehf_read_value(client, | 539 | data->alarms = w83627ehf_read_value(data, |
| 534 | W83627EHF_REG_ALARM1) | | 540 | W83627EHF_REG_ALARM1) | |
| 535 | (w83627ehf_read_value(client, | 541 | (w83627ehf_read_value(data, |
| 536 | W83627EHF_REG_ALARM2) << 8) | | 542 | W83627EHF_REG_ALARM2) << 8) | |
| 537 | (w83627ehf_read_value(client, | 543 | (w83627ehf_read_value(data, |
| 538 | W83627EHF_REG_ALARM3) << 16); | 544 | W83627EHF_REG_ALARM3) << 16); |
| 539 | 545 | ||
| 540 | data->last_updated = jiffies; | 546 | data->last_updated = jiffies; |
| @@ -567,15 +573,14 @@ static ssize_t \ | |||
| 567 | store_in_##reg (struct device *dev, struct device_attribute *attr, \ | 573 | store_in_##reg (struct device *dev, struct device_attribute *attr, \ |
| 568 | const char *buf, size_t count) \ | 574 | const char *buf, size_t count) \ |
| 569 | { \ | 575 | { \ |
| 570 | struct i2c_client *client = to_i2c_client(dev); \ | 576 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
| 571 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
| 572 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 577 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
| 573 | int nr = sensor_attr->index; \ | 578 | int nr = sensor_attr->index; \ |
| 574 | u32 val = simple_strtoul(buf, NULL, 10); \ | 579 | u32 val = simple_strtoul(buf, NULL, 10); \ |
| 575 | \ | 580 | \ |
| 576 | mutex_lock(&data->update_lock); \ | 581 | mutex_lock(&data->update_lock); \ |
| 577 | data->in_##reg[nr] = in_to_reg(val, nr); \ | 582 | data->in_##reg[nr] = in_to_reg(val, nr); \ |
| 578 | w83627ehf_write_value(client, W83627EHF_REG_IN_##REG(nr), \ | 583 | w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \ |
| 579 | data->in_##reg[nr]); \ | 584 | data->in_##reg[nr]); \ |
| 580 | mutex_unlock(&data->update_lock); \ | 585 | mutex_unlock(&data->update_lock); \ |
| 581 | return count; \ | 586 | return count; \ |
| @@ -673,8 +678,7 @@ static ssize_t | |||
| 673 | store_fan_min(struct device *dev, struct device_attribute *attr, | 678 | store_fan_min(struct device *dev, struct device_attribute *attr, |
| 674 | const char *buf, size_t count) | 679 | const char *buf, size_t count) |
| 675 | { | 680 | { |
| 676 | struct i2c_client *client = to_i2c_client(dev); | 681 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 677 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 678 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 682 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 679 | int nr = sensor_attr->index; | 683 | int nr = sensor_attr->index; |
| 680 | unsigned int val = simple_strtoul(buf, NULL, 10); | 684 | unsigned int val = simple_strtoul(buf, NULL, 10); |
| @@ -716,18 +720,25 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
| 716 | /* Write both the fan clock divider (if it changed) and the new | 720 | /* Write both the fan clock divider (if it changed) and the new |
| 717 | fan min (unconditionally) */ | 721 | fan min (unconditionally) */ |
| 718 | if (new_div != data->fan_div[nr]) { | 722 | if (new_div != data->fan_div[nr]) { |
| 719 | if (new_div > data->fan_div[nr]) | 723 | /* Preserve the fan speed reading */ |
| 720 | data->fan[nr] >>= (data->fan_div[nr] - new_div); | 724 | if (data->fan[nr] != 0xff) { |
| 721 | else | 725 | if (new_div > data->fan_div[nr]) |
| 722 | data->fan[nr] <<= (new_div - data->fan_div[nr]); | 726 | data->fan[nr] >>= new_div - data->fan_div[nr]; |
| 727 | else if (data->fan[nr] & 0x80) | ||
| 728 | data->fan[nr] = 0xff; | ||
| 729 | else | ||
| 730 | data->fan[nr] <<= data->fan_div[nr] - new_div; | ||
| 731 | } | ||
| 723 | 732 | ||
| 724 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", | 733 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", |
| 725 | nr + 1, div_from_reg(data->fan_div[nr]), | 734 | nr + 1, div_from_reg(data->fan_div[nr]), |
| 726 | div_from_reg(new_div)); | 735 | div_from_reg(new_div)); |
| 727 | data->fan_div[nr] = new_div; | 736 | data->fan_div[nr] = new_div; |
| 728 | w83627ehf_write_fan_div(client, nr); | 737 | w83627ehf_write_fan_div(data, nr); |
| 738 | /* Give the chip time to sample a new speed value */ | ||
| 739 | data->last_updated = jiffies; | ||
| 729 | } | 740 | } |
| 730 | w83627ehf_write_value(client, W83627EHF_REG_FAN_MIN[nr], | 741 | w83627ehf_write_value(data, W83627EHF_REG_FAN_MIN[nr], |
| 731 | data->fan_min[nr]); | 742 | data->fan_min[nr]); |
| 732 | mutex_unlock(&data->update_lock); | 743 | mutex_unlock(&data->update_lock); |
| 733 | 744 | ||
| @@ -788,13 +799,12 @@ static ssize_t \ | |||
| 788 | store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ | 799 | store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ |
| 789 | const char *buf, size_t count) \ | 800 | const char *buf, size_t count) \ |
| 790 | { \ | 801 | { \ |
| 791 | struct i2c_client *client = to_i2c_client(dev); \ | 802 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
| 792 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
| 793 | u32 val = simple_strtoul(buf, NULL, 10); \ | 803 | u32 val = simple_strtoul(buf, NULL, 10); \ |
| 794 | \ | 804 | \ |
| 795 | mutex_lock(&data->update_lock); \ | 805 | mutex_lock(&data->update_lock); \ |
| 796 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ | 806 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ |
| 797 | w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \ | 807 | w83627ehf_write_value(data, W83627EHF_REG_TEMP1_##REG, \ |
| 798 | data->temp1_##reg); \ | 808 | data->temp1_##reg); \ |
| 799 | mutex_unlock(&data->update_lock); \ | 809 | mutex_unlock(&data->update_lock); \ |
| 800 | return count; \ | 810 | return count; \ |
| @@ -822,15 +832,14 @@ static ssize_t \ | |||
| 822 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 832 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
| 823 | const char *buf, size_t count) \ | 833 | const char *buf, size_t count) \ |
| 824 | { \ | 834 | { \ |
| 825 | struct i2c_client *client = to_i2c_client(dev); \ | 835 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
| 826 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
| 827 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 836 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
| 828 | int nr = sensor_attr->index; \ | 837 | int nr = sensor_attr->index; \ |
| 829 | u32 val = simple_strtoul(buf, NULL, 10); \ | 838 | u32 val = simple_strtoul(buf, NULL, 10); \ |
| 830 | \ | 839 | \ |
| 831 | mutex_lock(&data->update_lock); \ | 840 | mutex_lock(&data->update_lock); \ |
| 832 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ | 841 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ |
| 833 | w83627ehf_write_value(client, W83627EHF_REG_TEMP_##REG[nr], \ | 842 | w83627ehf_write_value(data, W83627EHF_REG_TEMP_##REG[nr], \ |
| 834 | data->reg[nr]); \ | 843 | data->reg[nr]); \ |
| 835 | mutex_unlock(&data->update_lock); \ | 844 | mutex_unlock(&data->update_lock); \ |
| 836 | return count; \ | 845 | return count; \ |
| @@ -838,6 +847,15 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ | |||
| 838 | store_temp_reg(OVER, temp_max); | 847 | store_temp_reg(OVER, temp_max); |
| 839 | store_temp_reg(HYST, temp_max_hyst); | 848 | store_temp_reg(HYST, temp_max_hyst); |
| 840 | 849 | ||
| 850 | static ssize_t | ||
| 851 | show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 852 | { | ||
| 853 | struct w83627ehf_data *data = w83627ehf_update_device(dev); | ||
| 854 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
| 855 | int nr = sensor_attr->index; | ||
| 856 | return sprintf(buf, "%d\n", (int)data->temp_type[nr]); | ||
| 857 | } | ||
| 858 | |||
| 841 | static struct sensor_device_attribute sda_temp[] = { | 859 | static struct sensor_device_attribute sda_temp[] = { |
| 842 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), | 860 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), |
| 843 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), | 861 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), |
| @@ -857,6 +875,9 @@ static struct sensor_device_attribute sda_temp[] = { | |||
| 857 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), | 875 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), |
| 858 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), | 876 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), |
| 859 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), | 877 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), |
| 878 | SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), | ||
| 879 | SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), | ||
| 880 | SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), | ||
| 860 | }; | 881 | }; |
| 861 | 882 | ||
| 862 | #define show_pwm_reg(reg) \ | 883 | #define show_pwm_reg(reg) \ |
| @@ -877,8 +898,7 @@ static ssize_t | |||
| 877 | store_pwm_mode(struct device *dev, struct device_attribute *attr, | 898 | store_pwm_mode(struct device *dev, struct device_attribute *attr, |
| 878 | const char *buf, size_t count) | 899 | const char *buf, size_t count) |
| 879 | { | 900 | { |
| 880 | struct i2c_client *client = to_i2c_client(dev); | 901 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 881 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 882 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 902 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 883 | int nr = sensor_attr->index; | 903 | int nr = sensor_attr->index; |
| 884 | u32 val = simple_strtoul(buf, NULL, 10); | 904 | u32 val = simple_strtoul(buf, NULL, 10); |
| @@ -887,12 +907,12 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, | |||
| 887 | if (val > 1) | 907 | if (val > 1) |
| 888 | return -EINVAL; | 908 | return -EINVAL; |
| 889 | mutex_lock(&data->update_lock); | 909 | mutex_lock(&data->update_lock); |
| 890 | reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); | 910 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
| 891 | data->pwm_mode[nr] = val; | 911 | data->pwm_mode[nr] = val; |
| 892 | reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); | 912 | reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); |
| 893 | if (!val) | 913 | if (!val) |
| 894 | reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; | 914 | reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; |
| 895 | w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); | 915 | w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); |
| 896 | mutex_unlock(&data->update_lock); | 916 | mutex_unlock(&data->update_lock); |
| 897 | return count; | 917 | return count; |
| 898 | } | 918 | } |
| @@ -901,15 +921,14 @@ static ssize_t | |||
| 901 | store_pwm(struct device *dev, struct device_attribute *attr, | 921 | store_pwm(struct device *dev, struct device_attribute *attr, |
| 902 | const char *buf, size_t count) | 922 | const char *buf, size_t count) |
| 903 | { | 923 | { |
| 904 | struct i2c_client *client = to_i2c_client(dev); | 924 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 905 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 906 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 925 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 907 | int nr = sensor_attr->index; | 926 | int nr = sensor_attr->index; |
| 908 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); | 927 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); |
| 909 | 928 | ||
| 910 | mutex_lock(&data->update_lock); | 929 | mutex_lock(&data->update_lock); |
| 911 | data->pwm[nr] = val; | 930 | data->pwm[nr] = val; |
| 912 | w83627ehf_write_value(client, W83627EHF_REG_PWM[nr], val); | 931 | w83627ehf_write_value(data, W83627EHF_REG_PWM[nr], val); |
| 913 | mutex_unlock(&data->update_lock); | 932 | mutex_unlock(&data->update_lock); |
| 914 | return count; | 933 | return count; |
| 915 | } | 934 | } |
| @@ -918,8 +937,7 @@ static ssize_t | |||
| 918 | store_pwm_enable(struct device *dev, struct device_attribute *attr, | 937 | store_pwm_enable(struct device *dev, struct device_attribute *attr, |
| 919 | const char *buf, size_t count) | 938 | const char *buf, size_t count) |
| 920 | { | 939 | { |
| 921 | struct i2c_client *client = to_i2c_client(dev); | 940 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 922 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 923 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 941 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 924 | int nr = sensor_attr->index; | 942 | int nr = sensor_attr->index; |
| 925 | u32 val = simple_strtoul(buf, NULL, 10); | 943 | u32 val = simple_strtoul(buf, NULL, 10); |
| @@ -928,11 +946,11 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
| 928 | if (!val || (val > 2)) /* only modes 1 and 2 are supported */ | 946 | if (!val || (val > 2)) /* only modes 1 and 2 are supported */ |
| 929 | return -EINVAL; | 947 | return -EINVAL; |
| 930 | mutex_lock(&data->update_lock); | 948 | mutex_lock(&data->update_lock); |
| 931 | reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); | 949 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
| 932 | data->pwm_enable[nr] = val; | 950 | data->pwm_enable[nr] = val; |
| 933 | reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); | 951 | reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); |
| 934 | reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; | 952 | reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; |
| 935 | w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); | 953 | w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); |
| 936 | mutex_unlock(&data->update_lock); | 954 | mutex_unlock(&data->update_lock); |
| 937 | return count; | 955 | return count; |
| 938 | } | 956 | } |
| @@ -955,15 +973,14 @@ static ssize_t | |||
| 955 | store_target_temp(struct device *dev, struct device_attribute *attr, | 973 | store_target_temp(struct device *dev, struct device_attribute *attr, |
| 956 | const char *buf, size_t count) | 974 | const char *buf, size_t count) |
| 957 | { | 975 | { |
| 958 | struct i2c_client *client = to_i2c_client(dev); | 976 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 959 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 960 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 977 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 961 | int nr = sensor_attr->index; | 978 | int nr = sensor_attr->index; |
| 962 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000); | 979 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000); |
| 963 | 980 | ||
| 964 | mutex_lock(&data->update_lock); | 981 | mutex_lock(&data->update_lock); |
| 965 | data->target_temp[nr] = val; | 982 | data->target_temp[nr] = val; |
| 966 | w83627ehf_write_value(client, W83627EHF_REG_TARGET[nr], val); | 983 | w83627ehf_write_value(data, W83627EHF_REG_TARGET[nr], val); |
| 967 | mutex_unlock(&data->update_lock); | 984 | mutex_unlock(&data->update_lock); |
| 968 | return count; | 985 | return count; |
| 969 | } | 986 | } |
| @@ -972,8 +989,7 @@ static ssize_t | |||
| 972 | store_tolerance(struct device *dev, struct device_attribute *attr, | 989 | store_tolerance(struct device *dev, struct device_attribute *attr, |
| 973 | const char *buf, size_t count) | 990 | const char *buf, size_t count) |
| 974 | { | 991 | { |
| 975 | struct i2c_client *client = to_i2c_client(dev); | 992 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 976 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 977 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 993 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 978 | int nr = sensor_attr->index; | 994 | int nr = sensor_attr->index; |
| 979 | u16 reg; | 995 | u16 reg; |
| @@ -981,13 +997,13 @@ store_tolerance(struct device *dev, struct device_attribute *attr, | |||
| 981 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000); | 997 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000); |
| 982 | 998 | ||
| 983 | mutex_lock(&data->update_lock); | 999 | mutex_lock(&data->update_lock); |
| 984 | reg = w83627ehf_read_value(client, W83627EHF_REG_TOLERANCE[nr]); | 1000 | reg = w83627ehf_read_value(data, W83627EHF_REG_TOLERANCE[nr]); |
| 985 | data->tolerance[nr] = val; | 1001 | data->tolerance[nr] = val; |
| 986 | if (nr == 1) | 1002 | if (nr == 1) |
| 987 | reg = (reg & 0x0f) | (val << 4); | 1003 | reg = (reg & 0x0f) | (val << 4); |
| 988 | else | 1004 | else |
| 989 | reg = (reg & 0xf0) | val; | 1005 | reg = (reg & 0xf0) | val; |
| 990 | w83627ehf_write_value(client, W83627EHF_REG_TOLERANCE[nr], reg); | 1006 | w83627ehf_write_value(data, W83627EHF_REG_TOLERANCE[nr], reg); |
| 991 | mutex_unlock(&data->update_lock); | 1007 | mutex_unlock(&data->update_lock); |
| 992 | return count; | 1008 | return count; |
| 993 | } | 1009 | } |
| @@ -1058,14 +1074,13 @@ static ssize_t \ | |||
| 1058 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 1074 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
| 1059 | const char *buf, size_t count) \ | 1075 | const char *buf, size_t count) \ |
| 1060 | {\ | 1076 | {\ |
| 1061 | struct i2c_client *client = to_i2c_client(dev); \ | 1077 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
| 1062 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
| 1063 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 1078 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
| 1064 | int nr = sensor_attr->index; \ | 1079 | int nr = sensor_attr->index; \ |
| 1065 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ | 1080 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ |
| 1066 | mutex_lock(&data->update_lock); \ | 1081 | mutex_lock(&data->update_lock); \ |
| 1067 | data->reg[nr] = val; \ | 1082 | data->reg[nr] = val; \ |
| 1068 | w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ | 1083 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ |
| 1069 | mutex_unlock(&data->update_lock); \ | 1084 | mutex_unlock(&data->update_lock); \ |
| 1070 | return count; \ | 1085 | return count; \ |
| 1071 | } | 1086 | } |
| @@ -1087,21 +1102,28 @@ static ssize_t \ | |||
| 1087 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 1102 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
| 1088 | const char *buf, size_t count) \ | 1103 | const char *buf, size_t count) \ |
| 1089 | { \ | 1104 | { \ |
| 1090 | struct i2c_client *client = to_i2c_client(dev); \ | 1105 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
| 1091 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
| 1092 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 1106 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
| 1093 | int nr = sensor_attr->index; \ | 1107 | int nr = sensor_attr->index; \ |
| 1094 | u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \ | 1108 | u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \ |
| 1095 | data->pwm_mode[nr]); \ | 1109 | data->pwm_mode[nr]); \ |
| 1096 | mutex_lock(&data->update_lock); \ | 1110 | mutex_lock(&data->update_lock); \ |
| 1097 | data->reg[nr] = val; \ | 1111 | data->reg[nr] = val; \ |
| 1098 | w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ | 1112 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ |
| 1099 | mutex_unlock(&data->update_lock); \ | 1113 | mutex_unlock(&data->update_lock); \ |
| 1100 | return count; \ | 1114 | return count; \ |
| 1101 | } \ | 1115 | } \ |
| 1102 | 1116 | ||
| 1103 | fan_time_functions(fan_stop_time, FAN_STOP_TIME) | 1117 | fan_time_functions(fan_stop_time, FAN_STOP_TIME) |
| 1104 | 1118 | ||
| 1119 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, | ||
| 1120 | char *buf) | ||
| 1121 | { | ||
| 1122 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
| 1123 | |||
| 1124 | return sprintf(buf, "%s\n", data->name); | ||
| 1125 | } | ||
| 1126 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 1105 | 1127 | ||
| 1106 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { | 1128 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { |
| 1107 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | 1129 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
| @@ -1125,8 +1147,16 @@ static struct sensor_device_attribute sda_sf3_arrays[] = { | |||
| 1125 | store_fan_min_output, 2), | 1147 | store_fan_min_output, 2), |
| 1126 | }; | 1148 | }; |
| 1127 | 1149 | ||
| 1150 | static ssize_t | ||
| 1151 | show_vid(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 1152 | { | ||
| 1153 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
| 1154 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); | ||
| 1155 | } | ||
| 1156 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | ||
| 1157 | |||
| 1128 | /* | 1158 | /* |
| 1129 | * Driver and client management | 1159 | * Driver and device management |
| 1130 | */ | 1160 | */ |
| 1131 | 1161 | ||
| 1132 | static void w83627ehf_device_remove_files(struct device *dev) | 1162 | static void w83627ehf_device_remove_files(struct device *dev) |
| @@ -1134,12 +1164,13 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
| 1134 | /* some entries in the following arrays may not have been used in | 1164 | /* some entries in the following arrays may not have been used in |
| 1135 | * device_create_file(), but device_remove_file() will ignore them */ | 1165 | * device_create_file(), but device_remove_file() will ignore them */ |
| 1136 | int i; | 1166 | int i; |
| 1167 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
| 1137 | 1168 | ||
| 1138 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) | 1169 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) |
| 1139 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); | 1170 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); |
| 1140 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | 1171 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) |
| 1141 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | 1172 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); |
| 1142 | for (i = 0; i < w83627ehf_num_in; i++) { | 1173 | for (i = 0; i < data->in_num; i++) { |
| 1143 | device_remove_file(dev, &sda_in_input[i].dev_attr); | 1174 | device_remove_file(dev, &sda_in_input[i].dev_attr); |
| 1144 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); | 1175 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); |
| 1145 | device_remove_file(dev, &sda_in_min[i].dev_attr); | 1176 | device_remove_file(dev, &sda_in_min[i].dev_attr); |
| @@ -1160,43 +1191,64 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
| 1160 | } | 1191 | } |
| 1161 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) | 1192 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) |
| 1162 | device_remove_file(dev, &sda_temp[i].dev_attr); | 1193 | device_remove_file(dev, &sda_temp[i].dev_attr); |
| 1163 | } | ||
| 1164 | 1194 | ||
| 1165 | static struct i2c_driver w83627ehf_driver; | 1195 | device_remove_file(dev, &dev_attr_name); |
| 1196 | if (data->vid != 0x3f) | ||
| 1197 | device_remove_file(dev, &dev_attr_cpu0_vid); | ||
| 1198 | } | ||
| 1166 | 1199 | ||
| 1167 | static void w83627ehf_init_client(struct i2c_client *client) | 1200 | /* Get the monitoring functions started */ |
| 1201 | static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data) | ||
| 1168 | { | 1202 | { |
| 1169 | int i; | 1203 | int i; |
| 1170 | u8 tmp; | 1204 | u8 tmp, diode; |
| 1171 | 1205 | ||
| 1172 | /* Start monitoring is needed */ | 1206 | /* Start monitoring is needed */ |
| 1173 | tmp = w83627ehf_read_value(client, W83627EHF_REG_CONFIG); | 1207 | tmp = w83627ehf_read_value(data, W83627EHF_REG_CONFIG); |
| 1174 | if (!(tmp & 0x01)) | 1208 | if (!(tmp & 0x01)) |
| 1175 | w83627ehf_write_value(client, W83627EHF_REG_CONFIG, | 1209 | w83627ehf_write_value(data, W83627EHF_REG_CONFIG, |
| 1176 | tmp | 0x01); | 1210 | tmp | 0x01); |
| 1177 | 1211 | ||
| 1178 | /* Enable temp2 and temp3 if needed */ | 1212 | /* Enable temp2 and temp3 if needed */ |
| 1179 | for (i = 0; i < 2; i++) { | 1213 | for (i = 0; i < 2; i++) { |
| 1180 | tmp = w83627ehf_read_value(client, | 1214 | tmp = w83627ehf_read_value(data, |
| 1181 | W83627EHF_REG_TEMP_CONFIG[i]); | 1215 | W83627EHF_REG_TEMP_CONFIG[i]); |
| 1182 | if (tmp & 0x01) | 1216 | if (tmp & 0x01) |
| 1183 | w83627ehf_write_value(client, | 1217 | w83627ehf_write_value(data, |
| 1184 | W83627EHF_REG_TEMP_CONFIG[i], | 1218 | W83627EHF_REG_TEMP_CONFIG[i], |
| 1185 | tmp & 0xfe); | 1219 | tmp & 0xfe); |
| 1186 | } | 1220 | } |
| 1221 | |||
| 1222 | /* Enable VBAT monitoring if needed */ | ||
| 1223 | tmp = w83627ehf_read_value(data, W83627EHF_REG_VBAT); | ||
| 1224 | if (!(tmp & 0x01)) | ||
| 1225 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, tmp | 0x01); | ||
| 1226 | |||
| 1227 | /* Get thermal sensor types */ | ||
| 1228 | diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); | ||
| 1229 | for (i = 0; i < 3; i++) { | ||
| 1230 | if ((tmp & (0x02 << i))) | ||
| 1231 | data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 2; | ||
| 1232 | else | ||
| 1233 | data->temp_type[i] = 4; /* thermistor */ | ||
| 1234 | } | ||
| 1187 | } | 1235 | } |
| 1188 | 1236 | ||
| 1189 | static int w83627ehf_detect(struct i2c_adapter *adapter) | 1237 | static int __devinit w83627ehf_probe(struct platform_device *pdev) |
| 1190 | { | 1238 | { |
| 1191 | struct i2c_client *client; | 1239 | struct device *dev = &pdev->dev; |
| 1240 | struct w83627ehf_sio_data *sio_data = dev->platform_data; | ||
| 1192 | struct w83627ehf_data *data; | 1241 | struct w83627ehf_data *data; |
| 1193 | struct device *dev; | 1242 | struct resource *res; |
| 1194 | u8 fan4pin, fan5pin; | 1243 | u8 fan4pin, fan5pin, en_vrm10; |
| 1195 | int i, err = 0; | 1244 | int i, err = 0; |
| 1196 | 1245 | ||
| 1197 | if (!request_region(address + IOREGION_OFFSET, IOREGION_LENGTH, | 1246 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 1198 | w83627ehf_driver.driver.name)) { | 1247 | if (!request_region(res->start, IOREGION_LENGTH, DRVNAME)) { |
| 1199 | err = -EBUSY; | 1248 | err = -EBUSY; |
| 1249 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", | ||
| 1250 | (unsigned long)res->start, | ||
| 1251 | (unsigned long)res->start + IOREGION_LENGTH - 1); | ||
| 1200 | goto exit; | 1252 | goto exit; |
| 1201 | } | 1253 | } |
| 1202 | 1254 | ||
| @@ -1205,41 +1257,47 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1205 | goto exit_release; | 1257 | goto exit_release; |
| 1206 | } | 1258 | } |
| 1207 | 1259 | ||
| 1208 | client = &data->client; | 1260 | data->addr = res->start; |
| 1209 | i2c_set_clientdata(client, data); | ||
| 1210 | client->addr = address; | ||
| 1211 | mutex_init(&data->lock); | 1261 | mutex_init(&data->lock); |
| 1212 | client->adapter = adapter; | ||
| 1213 | client->driver = &w83627ehf_driver; | ||
| 1214 | client->flags = 0; | ||
| 1215 | dev = &client->dev; | ||
| 1216 | |||
| 1217 | if (w83627ehf_num_in == 9) | ||
| 1218 | strlcpy(client->name, "w83627dhg", I2C_NAME_SIZE); | ||
| 1219 | else /* just say ehf. 627EHG is 627EHF in lead-free packaging. */ | ||
| 1220 | strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); | ||
| 1221 | |||
| 1222 | data->valid = 0; | ||
| 1223 | mutex_init(&data->update_lock); | 1262 | mutex_init(&data->update_lock); |
| 1263 | data->name = w83627ehf_device_names[sio_data->kind]; | ||
| 1264 | platform_set_drvdata(pdev, data); | ||
| 1224 | 1265 | ||
| 1225 | /* Tell the i2c layer a new client has arrived */ | 1266 | /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */ |
| 1226 | if ((err = i2c_attach_client(client))) | 1267 | data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10; |
| 1227 | goto exit_free; | ||
| 1228 | 1268 | ||
| 1229 | /* Initialize the chip */ | 1269 | /* Initialize the chip */ |
| 1230 | w83627ehf_init_client(client); | 1270 | w83627ehf_init_device(data); |
| 1231 | 1271 | ||
| 1232 | /* A few vars need to be filled upon startup */ | 1272 | data->vrm = vid_which_vrm(); |
| 1233 | for (i = 0; i < 5; i++) | 1273 | superio_enter(sio_data->sioreg); |
| 1234 | data->fan_min[i] = w83627ehf_read_value(client, | 1274 | /* Set VID input sensibility if needed. In theory the BIOS should |
| 1235 | W83627EHF_REG_FAN_MIN[i]); | 1275 | have set it, but in practice it's not always the case. */ |
| 1276 | en_vrm10 = superio_inb(sio_data->sioreg, SIO_REG_EN_VRM10); | ||
| 1277 | if ((en_vrm10 & 0x08) && data->vrm != 100) { | ||
| 1278 | dev_warn(dev, "Setting VID input voltage to TTL\n"); | ||
| 1279 | superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, | ||
| 1280 | en_vrm10 & ~0x08); | ||
| 1281 | } else if (!(en_vrm10 & 0x08) && data->vrm == 100) { | ||
| 1282 | dev_warn(dev, "Setting VID input voltage to VRM10\n"); | ||
| 1283 | superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, | ||
| 1284 | en_vrm10 | 0x08); | ||
| 1285 | } | ||
| 1286 | /* Read VID value */ | ||
| 1287 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); | ||
| 1288 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) | ||
| 1289 | data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA) & 0x3f; | ||
| 1290 | else { | ||
| 1291 | dev_info(dev, "VID pins in output mode, CPU VID not " | ||
| 1292 | "available\n"); | ||
| 1293 | data->vid = 0x3f; | ||
| 1294 | } | ||
| 1236 | 1295 | ||
| 1237 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ | 1296 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ |
| 1238 | 1297 | ||
| 1239 | superio_enter(); | 1298 | fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2; |
| 1240 | fan5pin = superio_inb(0x24) & 0x2; | 1299 | fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6; |
| 1241 | fan4pin = superio_inb(0x29) & 0x6; | 1300 | superio_exit(sio_data->sioreg); |
| 1242 | superio_exit(); | ||
| 1243 | 1301 | ||
| 1244 | /* It looks like fan4 and fan5 pins can be alternatively used | 1302 | /* It looks like fan4 and fan5 pins can be alternatively used |
| 1245 | as fan on/off switches, but fan5 control is write only :/ | 1303 | as fan on/off switches, but fan5 control is write only :/ |
| @@ -1248,7 +1306,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1248 | is not the default. */ | 1306 | is not the default. */ |
| 1249 | 1307 | ||
| 1250 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ | 1308 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ |
| 1251 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); | 1309 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); |
| 1252 | if ((i & (1 << 2)) && (!fan4pin)) | 1310 | if ((i & (1 << 2)) && (!fan4pin)) |
| 1253 | data->has_fan |= (1 << 3); | 1311 | data->has_fan |= (1 << 3); |
| 1254 | if (!(i & (1 << 1)) && (!fan5pin)) | 1312 | if (!(i & (1 << 1)) && (!fan5pin)) |
| @@ -1268,7 +1326,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1268 | goto exit_remove; | 1326 | goto exit_remove; |
| 1269 | } | 1327 | } |
| 1270 | 1328 | ||
| 1271 | for (i = 0; i < w83627ehf_num_in; i++) | 1329 | for (i = 0; i < data->in_num; i++) |
| 1272 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) | 1330 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) |
| 1273 | || (err = device_create_file(dev, | 1331 | || (err = device_create_file(dev, |
| 1274 | &sda_in_alarm[i].dev_attr)) | 1332 | &sda_in_alarm[i].dev_attr)) |
| @@ -1308,6 +1366,16 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1308 | if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) | 1366 | if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) |
| 1309 | goto exit_remove; | 1367 | goto exit_remove; |
| 1310 | 1368 | ||
| 1369 | err = device_create_file(dev, &dev_attr_name); | ||
| 1370 | if (err) | ||
| 1371 | goto exit_remove; | ||
| 1372 | |||
| 1373 | if (data->vid != 0x3f) { | ||
| 1374 | err = device_create_file(dev, &dev_attr_cpu0_vid); | ||
| 1375 | if (err) | ||
| 1376 | goto exit_remove; | ||
| 1377 | } | ||
| 1378 | |||
| 1311 | data->class_dev = hwmon_device_register(dev); | 1379 | data->class_dev = hwmon_device_register(dev); |
| 1312 | if (IS_ERR(data->class_dev)) { | 1380 | if (IS_ERR(data->class_dev)) { |
| 1313 | err = PTR_ERR(data->class_dev); | 1381 | err = PTR_ERR(data->class_dev); |
| @@ -1318,95 +1386,172 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1318 | 1386 | ||
| 1319 | exit_remove: | 1387 | exit_remove: |
| 1320 | w83627ehf_device_remove_files(dev); | 1388 | w83627ehf_device_remove_files(dev); |
| 1321 | i2c_detach_client(client); | ||
| 1322 | exit_free: | ||
| 1323 | kfree(data); | 1389 | kfree(data); |
| 1390 | platform_set_drvdata(pdev, NULL); | ||
| 1324 | exit_release: | 1391 | exit_release: |
| 1325 | release_region(address + IOREGION_OFFSET, IOREGION_LENGTH); | 1392 | release_region(res->start, IOREGION_LENGTH); |
| 1326 | exit: | 1393 | exit: |
| 1327 | return err; | 1394 | return err; |
| 1328 | } | 1395 | } |
| 1329 | 1396 | ||
| 1330 | static int w83627ehf_detach_client(struct i2c_client *client) | 1397 | static int __devexit w83627ehf_remove(struct platform_device *pdev) |
| 1331 | { | 1398 | { |
| 1332 | struct w83627ehf_data *data = i2c_get_clientdata(client); | 1399 | struct w83627ehf_data *data = platform_get_drvdata(pdev); |
| 1333 | int err; | ||
| 1334 | 1400 | ||
| 1335 | hwmon_device_unregister(data->class_dev); | 1401 | hwmon_device_unregister(data->class_dev); |
| 1336 | w83627ehf_device_remove_files(&client->dev); | 1402 | w83627ehf_device_remove_files(&pdev->dev); |
| 1337 | 1403 | release_region(data->addr, IOREGION_LENGTH); | |
| 1338 | if ((err = i2c_detach_client(client))) | 1404 | platform_set_drvdata(pdev, NULL); |
| 1339 | return err; | ||
| 1340 | release_region(client->addr + IOREGION_OFFSET, IOREGION_LENGTH); | ||
| 1341 | kfree(data); | 1405 | kfree(data); |
| 1342 | 1406 | ||
| 1343 | return 0; | 1407 | return 0; |
| 1344 | } | 1408 | } |
| 1345 | 1409 | ||
| 1346 | static struct i2c_driver w83627ehf_driver = { | 1410 | static struct platform_driver w83627ehf_driver = { |
| 1347 | .driver = { | 1411 | .driver = { |
| 1348 | .owner = THIS_MODULE, | 1412 | .owner = THIS_MODULE, |
| 1349 | .name = "w83627ehf", | 1413 | .name = DRVNAME, |
| 1350 | }, | 1414 | }, |
| 1351 | .attach_adapter = w83627ehf_detect, | 1415 | .probe = w83627ehf_probe, |
| 1352 | .detach_client = w83627ehf_detach_client, | 1416 | .remove = __devexit_p(w83627ehf_remove), |
| 1353 | }; | 1417 | }; |
| 1354 | 1418 | ||
| 1355 | static int __init w83627ehf_find(int sioaddr, unsigned short *addr) | 1419 | /* w83627ehf_find() looks for a '627 in the Super-I/O config space */ |
| 1420 | static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | ||
| 1421 | struct w83627ehf_sio_data *sio_data) | ||
| 1356 | { | 1422 | { |
| 1423 | static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; | ||
| 1424 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; | ||
| 1425 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; | ||
| 1426 | |||
| 1357 | u16 val; | 1427 | u16 val; |
| 1428 | const char *sio_name; | ||
| 1358 | 1429 | ||
| 1359 | REG = sioaddr; | 1430 | superio_enter(sioaddr); |
| 1360 | VAL = sioaddr + 1; | ||
| 1361 | superio_enter(); | ||
| 1362 | 1431 | ||
| 1363 | val = (superio_inb(SIO_REG_DEVID) << 8) | 1432 | val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) |
| 1364 | | superio_inb(SIO_REG_DEVID + 1); | 1433 | | superio_inb(sioaddr, SIO_REG_DEVID + 1); |
| 1365 | switch (val & SIO_ID_MASK) { | 1434 | switch (val & SIO_ID_MASK) { |
| 1366 | case SIO_W83627DHG_ID: | ||
| 1367 | w83627ehf_num_in = 9; | ||
| 1368 | break; | ||
| 1369 | case SIO_W83627EHF_ID: | 1435 | case SIO_W83627EHF_ID: |
| 1436 | sio_data->kind = w83627ehf; | ||
| 1437 | sio_name = sio_name_W83627EHF; | ||
| 1438 | break; | ||
| 1370 | case SIO_W83627EHG_ID: | 1439 | case SIO_W83627EHG_ID: |
| 1371 | w83627ehf_num_in = 10; | 1440 | sio_data->kind = w83627ehf; |
| 1441 | sio_name = sio_name_W83627EHG; | ||
| 1442 | break; | ||
| 1443 | case SIO_W83627DHG_ID: | ||
| 1444 | sio_data->kind = w83627dhg; | ||
| 1445 | sio_name = sio_name_W83627DHG; | ||
| 1372 | break; | 1446 | break; |
| 1373 | default: | 1447 | default: |
| 1374 | printk(KERN_WARNING "w83627ehf: unsupported chip ID: 0x%04x\n", | 1448 | if (val != 0xffff) |
| 1375 | val); | 1449 | pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n", |
| 1376 | superio_exit(); | 1450 | val); |
| 1451 | superio_exit(sioaddr); | ||
| 1377 | return -ENODEV; | 1452 | return -ENODEV; |
| 1378 | } | 1453 | } |
| 1379 | 1454 | ||
| 1380 | superio_select(W83627EHF_LD_HWM); | 1455 | /* We have a known chip, find the HWM I/O address */ |
| 1381 | val = (superio_inb(SIO_REG_ADDR) << 8) | 1456 | superio_select(sioaddr, W83627EHF_LD_HWM); |
| 1382 | | superio_inb(SIO_REG_ADDR + 1); | 1457 | val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8) |
| 1458 | | superio_inb(sioaddr, SIO_REG_ADDR + 1); | ||
| 1383 | *addr = val & IOREGION_ALIGNMENT; | 1459 | *addr = val & IOREGION_ALIGNMENT; |
| 1384 | if (*addr == 0) { | 1460 | if (*addr == 0) { |
| 1385 | superio_exit(); | 1461 | printk(KERN_ERR DRVNAME ": Refusing to enable a Super-I/O " |
| 1462 | "device with a base I/O port 0.\n"); | ||
| 1463 | superio_exit(sioaddr); | ||
| 1386 | return -ENODEV; | 1464 | return -ENODEV; |
| 1387 | } | 1465 | } |
| 1388 | 1466 | ||
| 1389 | /* Activate logical device if needed */ | 1467 | /* Activate logical device if needed */ |
| 1390 | val = superio_inb(SIO_REG_ENABLE); | 1468 | val = superio_inb(sioaddr, SIO_REG_ENABLE); |
| 1391 | if (!(val & 0x01)) | 1469 | if (!(val & 0x01)) { |
| 1392 | superio_outb(SIO_REG_ENABLE, val | 0x01); | 1470 | printk(KERN_WARNING DRVNAME ": Forcibly enabling Super-I/O. " |
| 1471 | "Sensor is probably unusable.\n"); | ||
| 1472 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | superio_exit(sioaddr); | ||
| 1476 | pr_info(DRVNAME ": Found %s chip at %#x\n", sio_name, *addr); | ||
| 1477 | sio_data->sioreg = sioaddr; | ||
| 1393 | 1478 | ||
| 1394 | superio_exit(); | ||
| 1395 | return 0; | 1479 | return 0; |
| 1396 | } | 1480 | } |
| 1397 | 1481 | ||
| 1482 | /* when Super-I/O functions move to a separate file, the Super-I/O | ||
| 1483 | * bus will manage the lifetime of the device and this module will only keep | ||
| 1484 | * track of the w83627ehf driver. But since we platform_device_alloc(), we | ||
| 1485 | * must keep track of the device */ | ||
| 1486 | static struct platform_device *pdev; | ||
| 1487 | |||
| 1398 | static int __init sensors_w83627ehf_init(void) | 1488 | static int __init sensors_w83627ehf_init(void) |
| 1399 | { | 1489 | { |
| 1400 | if (w83627ehf_find(0x2e, &address) | 1490 | int err; |
| 1401 | && w83627ehf_find(0x4e, &address)) | 1491 | unsigned short address; |
| 1492 | struct resource res; | ||
| 1493 | struct w83627ehf_sio_data sio_data; | ||
| 1494 | |||
| 1495 | /* initialize sio_data->kind and sio_data->sioreg. | ||
| 1496 | * | ||
| 1497 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
| 1498 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a | ||
| 1499 | * w83627ehf hardware monitor, and call probe() */ | ||
| 1500 | if (w83627ehf_find(0x2e, &address, &sio_data) && | ||
| 1501 | w83627ehf_find(0x4e, &address, &sio_data)) | ||
| 1402 | return -ENODEV; | 1502 | return -ENODEV; |
| 1403 | 1503 | ||
| 1404 | return i2c_isa_add_driver(&w83627ehf_driver); | 1504 | err = platform_driver_register(&w83627ehf_driver); |
| 1505 | if (err) | ||
| 1506 | goto exit; | ||
| 1507 | |||
| 1508 | if (!(pdev = platform_device_alloc(DRVNAME, address))) { | ||
| 1509 | err = -ENOMEM; | ||
| 1510 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | ||
| 1511 | goto exit_unregister; | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | err = platform_device_add_data(pdev, &sio_data, | ||
| 1515 | sizeof(struct w83627ehf_sio_data)); | ||
| 1516 | if (err) { | ||
| 1517 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | ||
| 1518 | goto exit_device_put; | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | memset(&res, 0, sizeof(res)); | ||
| 1522 | res.name = DRVNAME; | ||
| 1523 | res.start = address + IOREGION_OFFSET; | ||
| 1524 | res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; | ||
| 1525 | res.flags = IORESOURCE_IO; | ||
| 1526 | err = platform_device_add_resources(pdev, &res, 1); | ||
| 1527 | if (err) { | ||
| 1528 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | ||
| 1529 | "(%d)\n", err); | ||
| 1530 | goto exit_device_put; | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | /* platform_device_add calls probe() */ | ||
| 1534 | err = platform_device_add(pdev); | ||
| 1535 | if (err) { | ||
| 1536 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | ||
| 1537 | err); | ||
| 1538 | goto exit_device_put; | ||
| 1539 | } | ||
| 1540 | |||
| 1541 | return 0; | ||
| 1542 | |||
| 1543 | exit_device_put: | ||
| 1544 | platform_device_put(pdev); | ||
| 1545 | exit_unregister: | ||
| 1546 | platform_driver_unregister(&w83627ehf_driver); | ||
| 1547 | exit: | ||
| 1548 | return err; | ||
| 1405 | } | 1549 | } |
| 1406 | 1550 | ||
| 1407 | static void __exit sensors_w83627ehf_exit(void) | 1551 | static void __exit sensors_w83627ehf_exit(void) |
| 1408 | { | 1552 | { |
| 1409 | i2c_isa_del_driver(&w83627ehf_driver); | 1553 | platform_device_unregister(pdev); |
| 1554 | platform_driver_unregister(&w83627ehf_driver); | ||
| 1410 | } | 1555 | } |
| 1411 | 1556 | ||
| 1412 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); | 1557 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 12cb40a975de..1ce78179b005 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
| @@ -220,6 +220,18 @@ static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, | |||
| 220 | #define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ | 220 | #define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ |
| 221 | regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1]) | 221 | regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1]) |
| 222 | 222 | ||
| 223 | #define W83627HF_REG_PWM_FREQ 0x5C /* Only for the 627HF */ | ||
| 224 | |||
| 225 | #define W83637HF_REG_PWM_FREQ1 0x00 /* 697HF/687THF too */ | ||
| 226 | #define W83637HF_REG_PWM_FREQ2 0x02 /* 697HF/687THF too */ | ||
| 227 | #define W83637HF_REG_PWM_FREQ3 0x10 /* 687THF too */ | ||
| 228 | |||
| 229 | static const u8 W83637HF_REG_PWM_FREQ[] = { W83637HF_REG_PWM_FREQ1, | ||
| 230 | W83637HF_REG_PWM_FREQ2, | ||
| 231 | W83637HF_REG_PWM_FREQ3 }; | ||
| 232 | |||
| 233 | #define W83627HF_BASE_PWM_FREQ 46870 | ||
| 234 | |||
| 223 | #define W83781D_REG_I2C_ADDR 0x48 | 235 | #define W83781D_REG_I2C_ADDR 0x48 |
| 224 | #define W83781D_REG_I2C_SUBADDR 0x4A | 236 | #define W83781D_REG_I2C_SUBADDR 0x4A |
| 225 | 237 | ||
| @@ -267,6 +279,49 @@ static int TEMP_FROM_REG(u8 reg) | |||
| 267 | 279 | ||
| 268 | #define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) | 280 | #define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) |
| 269 | 281 | ||
| 282 | static inline unsigned long pwm_freq_from_reg_627hf(u8 reg) | ||
| 283 | { | ||
| 284 | unsigned long freq; | ||
| 285 | freq = W83627HF_BASE_PWM_FREQ >> reg; | ||
| 286 | return freq; | ||
| 287 | } | ||
| 288 | static inline u8 pwm_freq_to_reg_627hf(unsigned long val) | ||
| 289 | { | ||
| 290 | u8 i; | ||
| 291 | /* Only 5 dividers (1 2 4 8 16) | ||
| 292 | Search for the nearest available frequency */ | ||
| 293 | for (i = 0; i < 4; i++) { | ||
| 294 | if (val > (((W83627HF_BASE_PWM_FREQ >> i) + | ||
| 295 | (W83627HF_BASE_PWM_FREQ >> (i+1))) / 2)) | ||
| 296 | break; | ||
| 297 | } | ||
| 298 | return i; | ||
| 299 | } | ||
| 300 | |||
| 301 | static inline unsigned long pwm_freq_from_reg(u8 reg) | ||
| 302 | { | ||
| 303 | /* Clock bit 8 -> 180 kHz or 24 MHz */ | ||
| 304 | unsigned long clock = (reg & 0x80) ? 180000UL : 24000000UL; | ||
| 305 | |||
| 306 | reg &= 0x7f; | ||
| 307 | /* This should not happen but anyway... */ | ||
| 308 | if (reg == 0) | ||
| 309 | reg++; | ||
| 310 | return (clock / (reg << 8)); | ||
| 311 | } | ||
| 312 | static inline u8 pwm_freq_to_reg(unsigned long val) | ||
| 313 | { | ||
| 314 | /* Minimum divider value is 0x01 and maximum is 0x7F */ | ||
| 315 | if (val >= 93750) /* The highest we can do */ | ||
| 316 | return 0x01; | ||
| 317 | if (val >= 720) /* Use 24 MHz clock */ | ||
| 318 | return (24000000UL / (val << 8)); | ||
| 319 | if (val < 6) /* The lowest we can do */ | ||
| 320 | return 0xFF; | ||
| 321 | else /* Use 180 kHz clock */ | ||
| 322 | return (0x80 | (180000UL / (val << 8))); | ||
| 323 | } | ||
| 324 | |||
| 270 | #define BEEP_MASK_FROM_REG(val) (val) | 325 | #define BEEP_MASK_FROM_REG(val) (val) |
| 271 | #define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) | 326 | #define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) |
| 272 | #define BEEP_ENABLE_TO_REG(val) ((val)?1:0) | 327 | #define BEEP_ENABLE_TO_REG(val) ((val)?1:0) |
| @@ -316,6 +371,7 @@ struct w83627hf_data { | |||
| 316 | u32 beep_mask; /* Register encoding, combined */ | 371 | u32 beep_mask; /* Register encoding, combined */ |
| 317 | u8 beep_enable; /* Boolean */ | 372 | u8 beep_enable; /* Boolean */ |
| 318 | u8 pwm[3]; /* Register value */ | 373 | u8 pwm[3]; /* Register value */ |
| 374 | u8 pwm_freq[3]; /* Register value */ | ||
| 319 | u16 sens[3]; /* 782D/783S only. | 375 | u16 sens[3]; /* 782D/783S only. |
| 320 | 1 = pentium diode; 2 = 3904 diode; | 376 | 1 = pentium diode; 2 = 3904 diode; |
| 321 | 3000-5000 = thermistor beta. | 377 | 3000-5000 = thermistor beta. |
| @@ -852,6 +908,64 @@ sysfs_pwm(2); | |||
| 852 | sysfs_pwm(3); | 908 | sysfs_pwm(3); |
| 853 | 909 | ||
| 854 | static ssize_t | 910 | static ssize_t |
| 911 | show_pwm_freq_reg(struct device *dev, char *buf, int nr) | ||
| 912 | { | ||
| 913 | struct w83627hf_data *data = w83627hf_update_device(dev); | ||
| 914 | if (data->type == w83627hf) | ||
| 915 | return sprintf(buf, "%ld\n", | ||
| 916 | pwm_freq_from_reg_627hf(data->pwm_freq[nr - 1])); | ||
| 917 | else | ||
| 918 | return sprintf(buf, "%ld\n", | ||
| 919 | pwm_freq_from_reg(data->pwm_freq[nr - 1])); | ||
| 920 | } | ||
| 921 | |||
| 922 | static ssize_t | ||
| 923 | store_pwm_freq_reg(struct device *dev, const char *buf, size_t count, int nr) | ||
| 924 | { | ||
| 925 | struct w83627hf_data *data = dev_get_drvdata(dev); | ||
| 926 | static const u8 mask[]={0xF8, 0x8F}; | ||
| 927 | u32 val; | ||
| 928 | |||
| 929 | val = simple_strtoul(buf, NULL, 10); | ||
| 930 | |||
| 931 | mutex_lock(&data->update_lock); | ||
| 932 | |||
| 933 | if (data->type == w83627hf) { | ||
| 934 | data->pwm_freq[nr - 1] = pwm_freq_to_reg_627hf(val); | ||
| 935 | w83627hf_write_value(data, W83627HF_REG_PWM_FREQ, | ||
| 936 | (data->pwm_freq[nr - 1] << ((nr - 1)*4)) | | ||
| 937 | (w83627hf_read_value(data, | ||
| 938 | W83627HF_REG_PWM_FREQ) & mask[nr - 1])); | ||
| 939 | } else { | ||
| 940 | data->pwm_freq[nr - 1] = pwm_freq_to_reg(val); | ||
| 941 | w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr - 1], | ||
| 942 | data->pwm_freq[nr - 1]); | ||
| 943 | } | ||
| 944 | |||
| 945 | mutex_unlock(&data->update_lock); | ||
| 946 | return count; | ||
| 947 | } | ||
| 948 | |||
| 949 | #define sysfs_pwm_freq(offset) \ | ||
| 950 | static ssize_t show_regs_pwm_freq_##offset(struct device *dev, \ | ||
| 951 | struct device_attribute *attr, char *buf) \ | ||
| 952 | { \ | ||
| 953 | return show_pwm_freq_reg(dev, buf, offset); \ | ||
| 954 | } \ | ||
| 955 | static ssize_t \ | ||
| 956 | store_regs_pwm_freq_##offset(struct device *dev, \ | ||
| 957 | struct device_attribute *attr, const char *buf, size_t count) \ | ||
| 958 | { \ | ||
| 959 | return store_pwm_freq_reg(dev, buf, count, offset); \ | ||
| 960 | } \ | ||
| 961 | static DEVICE_ATTR(pwm##offset##_freq, S_IRUGO | S_IWUSR, \ | ||
| 962 | show_regs_pwm_freq_##offset, store_regs_pwm_freq_##offset); | ||
| 963 | |||
| 964 | sysfs_pwm_freq(1); | ||
| 965 | sysfs_pwm_freq(2); | ||
| 966 | sysfs_pwm_freq(3); | ||
| 967 | |||
| 968 | static ssize_t | ||
| 855 | show_sensor_reg(struct device *dev, char *buf, int nr) | 969 | show_sensor_reg(struct device *dev, char *buf, int nr) |
| 856 | { | 970 | { |
| 857 | struct w83627hf_data *data = w83627hf_update_device(dev); | 971 | struct w83627hf_data *data = w83627hf_update_device(dev); |
| @@ -1077,6 +1191,9 @@ static struct attribute *w83627hf_attributes_opt[] = { | |||
| 1077 | 1191 | ||
| 1078 | &dev_attr_pwm3.attr, | 1192 | &dev_attr_pwm3.attr, |
| 1079 | 1193 | ||
| 1194 | &dev_attr_pwm1_freq.attr, | ||
| 1195 | &dev_attr_pwm2_freq.attr, | ||
| 1196 | &dev_attr_pwm3_freq.attr, | ||
| 1080 | NULL | 1197 | NULL |
| 1081 | }; | 1198 | }; |
| 1082 | 1199 | ||
| @@ -1139,7 +1256,9 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
| 1139 | || (err = device_create_file(dev, &dev_attr_in5_max)) | 1256 | || (err = device_create_file(dev, &dev_attr_in5_max)) |
| 1140 | || (err = device_create_file(dev, &dev_attr_in6_input)) | 1257 | || (err = device_create_file(dev, &dev_attr_in6_input)) |
| 1141 | || (err = device_create_file(dev, &dev_attr_in6_min)) | 1258 | || (err = device_create_file(dev, &dev_attr_in6_min)) |
| 1142 | || (err = device_create_file(dev, &dev_attr_in6_max))) | 1259 | || (err = device_create_file(dev, &dev_attr_in6_max)) |
| 1260 | || (err = device_create_file(dev, &dev_attr_pwm1_freq)) | ||
| 1261 | || (err = device_create_file(dev, &dev_attr_pwm2_freq))) | ||
| 1143 | goto ERROR4; | 1262 | goto ERROR4; |
| 1144 | 1263 | ||
| 1145 | if (data->type != w83697hf) | 1264 | if (data->type != w83697hf) |
| @@ -1169,6 +1288,12 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
| 1169 | if ((err = device_create_file(dev, &dev_attr_pwm3))) | 1288 | if ((err = device_create_file(dev, &dev_attr_pwm3))) |
| 1170 | goto ERROR4; | 1289 | goto ERROR4; |
| 1171 | 1290 | ||
| 1291 | if (data->type == w83637hf || data->type == w83687thf) | ||
| 1292 | if ((err = device_create_file(dev, &dev_attr_pwm1_freq)) | ||
| 1293 | || (err = device_create_file(dev, &dev_attr_pwm2_freq)) | ||
| 1294 | || (err = device_create_file(dev, &dev_attr_pwm3_freq))) | ||
| 1295 | goto ERROR4; | ||
| 1296 | |||
| 1172 | data->class_dev = hwmon_device_register(dev); | 1297 | data->class_dev = hwmon_device_register(dev); |
| 1173 | if (IS_ERR(data->class_dev)) { | 1298 | if (IS_ERR(data->class_dev)) { |
| 1174 | err = PTR_ERR(data->class_dev); | 1299 | err = PTR_ERR(data->class_dev); |
| @@ -1181,6 +1306,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
| 1181 | sysfs_remove_group(&dev->kobj, &w83627hf_group); | 1306 | sysfs_remove_group(&dev->kobj, &w83627hf_group); |
| 1182 | sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); | 1307 | sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); |
| 1183 | ERROR3: | 1308 | ERROR3: |
| 1309 | platform_set_drvdata(pdev, NULL); | ||
| 1184 | kfree(data); | 1310 | kfree(data); |
| 1185 | ERROR1: | 1311 | ERROR1: |
| 1186 | release_region(res->start, WINB_REGION_SIZE); | 1312 | release_region(res->start, WINB_REGION_SIZE); |
| @@ -1193,11 +1319,11 @@ static int __devexit w83627hf_remove(struct platform_device *pdev) | |||
| 1193 | struct w83627hf_data *data = platform_get_drvdata(pdev); | 1319 | struct w83627hf_data *data = platform_get_drvdata(pdev); |
| 1194 | struct resource *res; | 1320 | struct resource *res; |
| 1195 | 1321 | ||
| 1196 | platform_set_drvdata(pdev, NULL); | ||
| 1197 | hwmon_device_unregister(data->class_dev); | 1322 | hwmon_device_unregister(data->class_dev); |
| 1198 | 1323 | ||
| 1199 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); | 1324 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); |
| 1200 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); | 1325 | sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); |
| 1326 | platform_set_drvdata(pdev, NULL); | ||
| 1201 | kfree(data); | 1327 | kfree(data); |
| 1202 | 1328 | ||
| 1203 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1329 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| @@ -1472,6 +1598,20 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
| 1472 | (data->type == w83627hf || data->type == w83697hf)) | 1598 | (data->type == w83627hf || data->type == w83697hf)) |
| 1473 | break; | 1599 | break; |
| 1474 | } | 1600 | } |
| 1601 | if (data->type == w83627hf) { | ||
| 1602 | u8 tmp = w83627hf_read_value(data, | ||
| 1603 | W83627HF_REG_PWM_FREQ); | ||
| 1604 | data->pwm_freq[0] = tmp & 0x07; | ||
| 1605 | data->pwm_freq[1] = (tmp >> 4) & 0x07; | ||
| 1606 | } else if (data->type != w83627thf) { | ||
| 1607 | for (i = 1; i <= 3; i++) { | ||
| 1608 | data->pwm_freq[i - 1] = | ||
| 1609 | w83627hf_read_value(data, | ||
| 1610 | W83637HF_REG_PWM_FREQ[i - 1]); | ||
| 1611 | if (i == 2 && (data->type == w83697hf)) | ||
| 1612 | break; | ||
| 1613 | } | ||
| 1614 | } | ||
| 1475 | 1615 | ||
| 1476 | data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1)); | 1616 | data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1)); |
| 1477 | data->temp_max = | 1617 | data->temp_max = |
| @@ -1548,15 +1688,12 @@ static int __init w83627hf_device_add(unsigned short address, | |||
| 1548 | goto exit_device_put; | 1688 | goto exit_device_put; |
| 1549 | } | 1689 | } |
| 1550 | 1690 | ||
| 1551 | pdev->dev.platform_data = kmalloc(sizeof(struct w83627hf_sio_data), | 1691 | err = platform_device_add_data(pdev, sio_data, |
| 1552 | GFP_KERNEL); | 1692 | sizeof(struct w83627hf_sio_data)); |
| 1553 | if (!pdev->dev.platform_data) { | 1693 | if (err) { |
| 1554 | err = -ENOMEM; | ||
| 1555 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | 1694 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); |
| 1556 | goto exit_device_put; | 1695 | goto exit_device_put; |
| 1557 | } | 1696 | } |
| 1558 | memcpy(pdev->dev.platform_data, sio_data, | ||
| 1559 | sizeof(struct w83627hf_sio_data)); | ||
| 1560 | 1697 | ||
| 1561 | err = platform_device_add(pdev); | 1698 | err = platform_device_add(pdev); |
| 1562 | if (err) { | 1699 | if (err) { |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 1c77e14480dc..da1647869f91 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -237,9 +237,6 @@ config I2C_IOP3XX | |||
| 237 | This driver can also be built as a module. If so, the module | 237 | This driver can also be built as a module. If so, the module |
| 238 | will be called i2c-iop3xx. | 238 | will be called i2c-iop3xx. |
| 239 | 239 | ||
| 240 | config I2C_ISA | ||
| 241 | tristate | ||
| 242 | |||
| 243 | config I2C_IXP4XX | 240 | config I2C_IXP4XX |
| 244 | tristate "IXP4xx GPIO-Based I2C Interface (DEPRECATED)" | 241 | tristate "IXP4xx GPIO-Based I2C Interface (DEPRECATED)" |
| 245 | depends on ARCH_IXP4XX | 242 | depends on ARCH_IXP4XX |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index a6db4e38bda8..5b752e4e1918 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
| @@ -18,7 +18,6 @@ obj-$(CONFIG_I2C_I801) += i2c-i801.o | |||
| 18 | obj-$(CONFIG_I2C_I810) += i2c-i810.o | 18 | obj-$(CONFIG_I2C_I810) += i2c-i810.o |
| 19 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o | 19 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o |
| 20 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o | 20 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o |
| 21 | obj-$(CONFIG_I2C_ISA) += i2c-isa.o | ||
| 22 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o | 21 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o |
| 23 | obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o | 22 | obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o |
| 24 | obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o | 23 | obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o |
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c deleted file mode 100644 index b0e1370075de..000000000000 --- a/drivers/i2c/busses/i2c-isa.c +++ /dev/null | |||
| @@ -1,192 +0,0 @@ | |||
| 1 | /* | ||
| 2 | i2c-isa.c - an i2c-core-like thing for ISA hardware monitoring chips | ||
| 3 | Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | ||
| 4 | |||
| 5 | Based on the i2c-isa pseudo-adapter from the lm_sensors project | ||
| 6 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> | ||
| 7 | |||
| 8 | This program is free software; you can redistribute it and/or modify | ||
| 9 | it under the terms of the GNU General Public License as published by | ||
| 10 | the Free Software Foundation; either version 2 of the License, or | ||
| 11 | (at your option) any later version. | ||
| 12 | |||
| 13 | This program is distributed in the hope that it will be useful, | ||
| 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | GNU General Public License for more details. | ||
| 17 | |||
| 18 | You should have received a copy of the GNU General Public License | ||
| 19 | along with this program; if not, write to the Free Software | ||
| 20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 21 | */ | ||
| 22 | |||
| 23 | /* This implements an i2c-core-like thing for ISA hardware monitoring | ||
| 24 | chips. Such chips are linked to the i2c subsystem for historical | ||
| 25 | reasons (because the early ISA hardware monitoring chips such as the | ||
| 26 | LM78 had both an I2C and an ISA interface). They used to be | ||
| 27 | registered with the main i2c-core, but as a first step in the | ||
| 28 | direction of a clean separation between I2C and ISA chip drivers, | ||
| 29 | we now have this separate core for ISA ones. It is significantly | ||
| 30 | more simple than the real one, of course, because we don't have to | ||
| 31 | handle multiple busses: there is only one (fake) ISA adapter. | ||
| 32 | It is worth noting that we still rely on i2c-core for some things | ||
| 33 | at the moment - but hopefully this won't last. */ | ||
| 34 | |||
| 35 | #include <linux/init.h> | ||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/kernel.h> | ||
| 38 | #include <linux/errno.h> | ||
| 39 | #include <linux/i2c.h> | ||
| 40 | #include <linux/i2c-isa.h> | ||
| 41 | #include <linux/platform_device.h> | ||
| 42 | #include <linux/completion.h> | ||
| 43 | |||
| 44 | /* Exported by i2c-core for i2c-isa only */ | ||
| 45 | extern void i2c_adapter_dev_release(struct device *dev); | ||
| 46 | extern struct class i2c_adapter_class; | ||
| 47 | |||
| 48 | static u32 isa_func(struct i2c_adapter *adapter); | ||
| 49 | |||
| 50 | /* This is the actual algorithm we define */ | ||
| 51 | static const struct i2c_algorithm isa_algorithm = { | ||
| 52 | .functionality = isa_func, | ||
| 53 | }; | ||
| 54 | |||
| 55 | /* There can only be one... */ | ||
| 56 | static struct i2c_adapter isa_adapter = { | ||
| 57 | .owner = THIS_MODULE, | ||
| 58 | .id = I2C_HW_ISA, | ||
| 59 | .class = I2C_CLASS_HWMON, | ||
| 60 | .algo = &isa_algorithm, | ||
| 61 | .name = "ISA main adapter", | ||
| 62 | }; | ||
| 63 | |||
| 64 | /* We can't do a thing... */ | ||
| 65 | static u32 isa_func(struct i2c_adapter *adapter) | ||
| 66 | { | ||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | |||
| 71 | /* We implement an interface which resembles i2c_{add,del}_driver, | ||
| 72 | but for i2c-isa drivers. We don't have to remember and handle lists | ||
| 73 | of drivers and adapters so this is much more simple, of course. */ | ||
| 74 | |||
| 75 | int i2c_isa_add_driver(struct i2c_driver *driver) | ||
| 76 | { | ||
| 77 | int res; | ||
| 78 | |||
| 79 | /* Add the driver to the list of i2c drivers in the driver core */ | ||
| 80 | driver->driver.bus = &i2c_bus_type; | ||
| 81 | res = driver_register(&driver->driver); | ||
| 82 | if (res) | ||
| 83 | return res; | ||
| 84 | dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name); | ||
| 85 | |||
| 86 | /* Now look for clients */ | ||
| 87 | res = driver->attach_adapter(&isa_adapter); | ||
| 88 | if (res) { | ||
| 89 | dev_dbg(&isa_adapter.dev, | ||
| 90 | "Driver %s failed to attach adapter, unregistering\n", | ||
| 91 | driver->driver.name); | ||
| 92 | driver_unregister(&driver->driver); | ||
| 93 | } | ||
| 94 | return res; | ||
| 95 | } | ||
| 96 | |||
| 97 | int i2c_isa_del_driver(struct i2c_driver *driver) | ||
| 98 | { | ||
| 99 | struct list_head *item, *_n; | ||
| 100 | struct i2c_client *client; | ||
| 101 | int res; | ||
| 102 | |||
| 103 | /* Detach all clients belonging to this one driver */ | ||
| 104 | list_for_each_safe(item, _n, &isa_adapter.clients) { | ||
| 105 | client = list_entry(item, struct i2c_client, list); | ||
| 106 | if (client->driver != driver) | ||
| 107 | continue; | ||
| 108 | dev_dbg(&isa_adapter.dev, "Detaching client %s at 0x%x\n", | ||
| 109 | client->name, client->addr); | ||
| 110 | if ((res = driver->detach_client(client))) { | ||
| 111 | dev_err(&isa_adapter.dev, "Failed, driver " | ||
| 112 | "%s not unregistered!\n", | ||
| 113 | driver->driver.name); | ||
| 114 | return res; | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | /* Get the driver off the core list */ | ||
| 119 | driver_unregister(&driver->driver); | ||
| 120 | dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->driver.name); | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | static int __init i2c_isa_init(void) | ||
| 127 | { | ||
| 128 | int err; | ||
| 129 | |||
| 130 | mutex_init(&isa_adapter.clist_lock); | ||
| 131 | INIT_LIST_HEAD(&isa_adapter.clients); | ||
| 132 | |||
| 133 | isa_adapter.nr = ANY_I2C_ISA_BUS; | ||
| 134 | isa_adapter.dev.parent = &platform_bus; | ||
| 135 | sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr); | ||
| 136 | isa_adapter.dev.release = &i2c_adapter_dev_release; | ||
| 137 | isa_adapter.dev.class = &i2c_adapter_class; | ||
| 138 | err = device_register(&isa_adapter.dev); | ||
| 139 | if (err) { | ||
| 140 | printk(KERN_ERR "i2c-isa: Failed to register device\n"); | ||
| 141 | goto exit; | ||
| 142 | } | ||
| 143 | |||
| 144 | dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name); | ||
| 145 | |||
| 146 | return 0; | ||
| 147 | |||
| 148 | exit: | ||
| 149 | return err; | ||
| 150 | } | ||
| 151 | |||
| 152 | static void __exit i2c_isa_exit(void) | ||
| 153 | { | ||
| 154 | #ifdef DEBUG | ||
| 155 | struct list_head *item, *_n; | ||
| 156 | struct i2c_client *client = NULL; | ||
| 157 | #endif | ||
| 158 | |||
| 159 | /* There should be no more active client */ | ||
| 160 | #ifdef DEBUG | ||
| 161 | dev_dbg(&isa_adapter.dev, "Looking for clients\n"); | ||
| 162 | list_for_each_safe(item, _n, &isa_adapter.clients) { | ||
| 163 | client = list_entry(item, struct i2c_client, list); | ||
| 164 | dev_err(&isa_adapter.dev, "Driver %s still has an active " | ||
| 165 | "ISA client at 0x%x\n", client->driver->driver.name, | ||
| 166 | client->addr); | ||
| 167 | } | ||
| 168 | if (client != NULL) | ||
| 169 | return; | ||
| 170 | #endif | ||
| 171 | |||
| 172 | /* Clean up the sysfs representation */ | ||
| 173 | dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n"); | ||
| 174 | init_completion(&isa_adapter.dev_released); | ||
| 175 | device_unregister(&isa_adapter.dev); | ||
| 176 | |||
| 177 | /* Wait for sysfs to drop all references */ | ||
| 178 | dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n"); | ||
| 179 | wait_for_completion(&isa_adapter.dev_released); | ||
| 180 | |||
| 181 | dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name); | ||
| 182 | } | ||
| 183 | |||
| 184 | EXPORT_SYMBOL(i2c_isa_add_driver); | ||
| 185 | EXPORT_SYMBOL(i2c_isa_del_driver); | ||
| 186 | |||
| 187 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); | ||
| 188 | MODULE_DESCRIPTION("ISA bus access through i2c"); | ||
| 189 | MODULE_LICENSE("GPL"); | ||
| 190 | |||
| 191 | module_init(i2c_isa_init); | ||
| 192 | module_exit(i2c_isa_exit); | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 6971a62397db..d663e6960d93 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -288,7 +288,6 @@ void i2c_adapter_dev_release(struct device *dev) | |||
| 288 | struct i2c_adapter *adap = to_i2c_adapter(dev); | 288 | struct i2c_adapter *adap = to_i2c_adapter(dev); |
| 289 | complete(&adap->dev_released); | 289 | complete(&adap->dev_released); |
| 290 | } | 290 | } |
| 291 | EXPORT_SYMBOL_GPL(i2c_adapter_dev_release); /* exported to i2c-isa */ | ||
| 292 | 291 | ||
| 293 | static ssize_t | 292 | static ssize_t |
| 294 | show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf) | 293 | show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf) |
| @@ -307,7 +306,6 @@ struct class i2c_adapter_class = { | |||
| 307 | .name = "i2c-adapter", | 306 | .name = "i2c-adapter", |
| 308 | .dev_attrs = i2c_adapter_attrs, | 307 | .dev_attrs = i2c_adapter_attrs, |
| 309 | }; | 308 | }; |
| 310 | EXPORT_SYMBOL_GPL(i2c_adapter_class); /* exported to i2c-isa */ | ||
| 311 | 309 | ||
| 312 | static void i2c_scan_static_board_info(struct i2c_adapter *adapter) | 310 | static void i2c_scan_static_board_info(struct i2c_adapter *adapter) |
| 313 | { | 311 | { |
diff --git a/include/linux/i2c-isa.h b/include/linux/i2c-isa.h deleted file mode 100644 index 67e3598c4cec..000000000000 --- a/include/linux/i2c-isa.h +++ /dev/null | |||
| @@ -1,36 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * i2c-isa.h - definitions for the i2c-isa pseudo-i2c-adapter interface | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef _LINUX_I2C_ISA_H | ||
| 22 | #define _LINUX_I2C_ISA_H | ||
| 23 | |||
| 24 | #include <linux/i2c.h> | ||
| 25 | |||
| 26 | extern int i2c_isa_add_driver(struct i2c_driver *driver); | ||
| 27 | extern int i2c_isa_del_driver(struct i2c_driver *driver); | ||
| 28 | |||
| 29 | /* Detect whether we are on the isa bus. This is only useful to hybrid | ||
| 30 | (i2c+isa) drivers. */ | ||
| 31 | #define i2c_is_isa_adapter(adapptr) \ | ||
| 32 | ((adapptr)->id == I2C_HW_ISA) | ||
| 33 | #define i2c_is_isa_client(clientptr) \ | ||
| 34 | i2c_is_isa_adapter((clientptr)->adapter) | ||
| 35 | |||
| 36 | #endif /* _LINUX_I2C_ISA_H */ | ||
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 2eaba21b9b1a..0c37a737a2b2 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
| @@ -368,7 +368,6 @@ struct i2c_client_address_data { | |||
| 368 | 368 | ||
| 369 | /* The numbers to use to set I2C bus address */ | 369 | /* The numbers to use to set I2C bus address */ |
| 370 | #define ANY_I2C_BUS 0xffff | 370 | #define ANY_I2C_BUS 0xffff |
| 371 | #define ANY_I2C_ISA_BUS 9191 | ||
| 372 | 371 | ||
| 373 | 372 | ||
| 374 | /* ----- functions exported by i2c.o */ | 373 | /* ----- functions exported by i2c.o */ |
