diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 17:37:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 17:37:52 -0400 |
commit | f37ab0fba271e43edab0e3ae9fe644fcda455402 (patch) | |
tree | 9389e993a99c7ad87c0e8643d464c48f3ac97eca | |
parent | 0b0c9d3a5872e8a02a071c6f0775ee6bf00a1206 (diff) | |
parent | 5510e62a66bad22b104d5d854445523d7f5754f7 (diff) |
Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
Pull hwmon updates from Jean Delvare:
"We have support for the MCP3021, MC13892 and GMT G781, automatic fan
speed control for LM63/LM64 chips, and a few clean-ups."
* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
hwmon: Add MCP3021 ADC driver
hwmon: (mc13783-adc) Add support for the MC13892 PMIC
hwmon: (mc13783-adc) Remove space before tab
hwmon: (lm63) Let the user adjust the lookup table
hwmon: (lm63) Make fan speed control strategy changeable
hwmon: (lm63) Reorganize the code
hwmon: (lm90) Restore original configuration if probe function fails
hwmon: (lm90) Add support for GMT G781
hwmon: (lm90) Fix multi-line comments
hwmon: (w83795) Fix multi-line comments
hwmon: (w83795) Unconditionally support manual fan speed control
hwmon: (fam15h_power) Increase output resolution
hwmon: (fam15h_power) Correct sign extension of running_avg_capture
-rw-r--r-- | Documentation/hwmon/lm90 | 4 | ||||
-rw-r--r-- | Documentation/hwmon/mc13783-adc | 50 | ||||
-rw-r--r-- | Documentation/hwmon/mcp3021 | 22 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 28 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
-rw-r--r-- | drivers/hwmon/fam15h_power.c | 10 | ||||
-rw-r--r-- | drivers/hwmon/lm63.c | 586 | ||||
-rw-r--r-- | drivers/hwmon/lm90.c | 98 | ||||
-rw-r--r-- | drivers/hwmon/mc13783-adc.c | 103 | ||||
-rw-r--r-- | drivers/hwmon/mcp3021.c | 171 | ||||
-rw-r--r-- | drivers/hwmon/w83795.c | 132 |
11 files changed, 826 insertions, 379 deletions
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90 index 9cd14cfe6515..b466974e142f 100644 --- a/Documentation/hwmon/lm90 +++ b/Documentation/hwmon/lm90 | |||
@@ -118,6 +118,10 @@ Supported chips: | |||
118 | Addresses scanned: I2C 0x48 through 0x4F | 118 | Addresses scanned: I2C 0x48 through 0x4F |
119 | Datasheet: Publicly available at NXP website | 119 | Datasheet: Publicly available at NXP website |
120 | http://ics.nxp.com/products/interface/datasheet/sa56004x.pdf | 120 | http://ics.nxp.com/products/interface/datasheet/sa56004x.pdf |
121 | * GMT G781 | ||
122 | Prefix: 'g781' | ||
123 | Addresses scanned: I2C 0x4c, 0x4d | ||
124 | Datasheet: Not publicly available from GMT | ||
121 | 125 | ||
122 | Author: Jean Delvare <khali@linux-fr.org> | 126 | Author: Jean Delvare <khali@linux-fr.org> |
123 | 127 | ||
diff --git a/Documentation/hwmon/mc13783-adc b/Documentation/hwmon/mc13783-adc index 044531a86405..d0e7b3fa9e75 100644 --- a/Documentation/hwmon/mc13783-adc +++ b/Documentation/hwmon/mc13783-adc | |||
@@ -3,8 +3,11 @@ Kernel driver mc13783-adc | |||
3 | 3 | ||
4 | Supported chips: | 4 | Supported chips: |
5 | * Freescale Atlas MC13783 | 5 | * Freescale Atlas MC13783 |
6 | Prefix: 'mc13783_adc' | 6 | Prefix: 'mc13783' |
7 | Datasheet: http://www.freescale.com/files/rf_if/doc/data_sheet/MC13783.pdf?fsrch=1 | 7 | Datasheet: http://www.freescale.com/files/rf_if/doc/data_sheet/MC13783.pdf?fsrch=1 |
8 | * Freescale Atlas MC13892 | ||
9 | Prefix: 'mc13892' | ||
10 | Datasheet: http://cache.freescale.com/files/analog/doc/data_sheet/MC13892.pdf?fsrch=1&sr=1 | ||
8 | 11 | ||
9 | Authors: | 12 | Authors: |
10 | Sascha Hauer <s.hauer@pengutronix.de> | 13 | Sascha Hauer <s.hauer@pengutronix.de> |
@@ -13,20 +16,21 @@ Authors: | |||
13 | Description | 16 | Description |
14 | ----------- | 17 | ----------- |
15 | 18 | ||
16 | The Freescale MC13783 is a Power Management and Audio Circuit. Among | 19 | The Freescale MC13783 and MC13892 are Power Management and Audio Circuits. |
17 | other things it contains a 10-bit A/D converter. The converter has 16 | 20 | Among other things they contain a 10-bit A/D converter. The converter has 16 |
18 | channels which can be used in different modes. | 21 | (MC13783) resp. 12 (MC13892) channels which can be used in different modes. The |
19 | The A/D converter has a resolution of 2.25mV. Channels 0-4 have | 22 | A/D converter has a resolution of 2.25mV. |
20 | a dedicated meaning with chip internal scaling applied. Channels 5-7 | ||
21 | can be used as general purpose inputs or alternatively in a dedicated | ||
22 | mode. Channels 12-15 are occupied by the touchscreen if it's active. | ||
23 | 23 | ||
24 | Currently the driver only supports channels 2 and 5-15 with no alternative | 24 | Some channels can be used as General Purpose inputs or in a dedicated mode with |
25 | modes for channels 5-7. | 25 | a chip internal scaling applied . |
26 | 26 | ||
27 | See this table for the meaning of the different channels and their chip | 27 | Currently the driver only supports the Application Supply channel (BP / BPSNS), |
28 | internal scaling: | 28 | the General Purpose inputs and touchscreen. |
29 | 29 | ||
30 | See the following tables for the meaning of the different channels and their | ||
31 | chip internal scaling: | ||
32 | |||
33 | MC13783: | ||
30 | Channel Signal Input Range Scaling | 34 | Channel Signal Input Range Scaling |
31 | ------------------------------------------------------------------------------- | 35 | ------------------------------------------------------------------------------- |
32 | 0 Battery Voltage (BATT) 2.50 - 4.65V -2.40V | 36 | 0 Battery Voltage (BATT) 2.50 - 4.65V -2.40V |
@@ -34,7 +38,7 @@ Channel Signal Input Range Scaling | |||
34 | 2 Application Supply (BP) 2.50 - 4.65V -2.40V | 38 | 2 Application Supply (BP) 2.50 - 4.65V -2.40V |
35 | 3 Charger Voltage (CHRGRAW) 0 - 10V / /5 | 39 | 3 Charger Voltage (CHRGRAW) 0 - 10V / /5 |
36 | 0 - 20V /10 | 40 | 0 - 20V /10 |
37 | 4 Charger Current (CHRGISNSP-CHRGISNSN) -0.25V - 0.25V x4 | 41 | 4 Charger Current (CHRGISNSP-CHRGISNSN) -0.25 - 0.25V x4 |
38 | 5 General Purpose ADIN5 / Battery Pack Thermistor 0 - 2.30V No | 42 | 5 General Purpose ADIN5 / Battery Pack Thermistor 0 - 2.30V No |
39 | 6 General Purpose ADIN6 / Backup Voltage (LICELL) 0 - 2.30V / No / | 43 | 6 General Purpose ADIN6 / Backup Voltage (LICELL) 0 - 2.30V / No / |
40 | 1.50 - 3.50V -1.20V | 44 | 1.50 - 3.50V -1.20V |
@@ -48,3 +52,23 @@ Channel Signal Input Range Scaling | |||
48 | 13 General Purpose TSX2 / Touchscreen X-plate 2 0 - 2.30V No | 52 | 13 General Purpose TSX2 / Touchscreen X-plate 2 0 - 2.30V No |
49 | 14 General Purpose TSY1 / Touchscreen Y-plate 1 0 - 2.30V No | 53 | 14 General Purpose TSY1 / Touchscreen Y-plate 1 0 - 2.30V No |
50 | 15 General Purpose TSY2 / Touchscreen Y-plate 2 0 - 2.30V No | 54 | 15 General Purpose TSY2 / Touchscreen Y-plate 2 0 - 2.30V No |
55 | |||
56 | MC13892: | ||
57 | Channel Signal Input Range Scaling | ||
58 | ------------------------------------------------------------------------------- | ||
59 | 0 Battery Voltage (BATT) 0 - 4.8V /2 | ||
60 | 1 Battery Current (BATT - BATTISNSCC) -60 - 60 mV x20 | ||
61 | 2 Application Supply (BPSNS) 0 - 4.8V /2 | ||
62 | 3 Charger Voltage (CHRGRAW) 0 - 12V / /5 | ||
63 | 0 - 20V /10 | ||
64 | 4 Charger Current (CHRGISNS-BPSNS) / -0.3 - 0.3V / x4 / | ||
65 | Touchscreen X-plate 1 0 - 2.4V No | ||
66 | 5 General Purpose ADIN5 / Battery Pack Thermistor 0 - 2.4V No | ||
67 | 6 General Purpose ADIN6 / Backup Voltage (LICELL) 0 - 2.4V / No | ||
68 | Backup Voltage (LICELL) 0 - 3.6V x2/3 | ||
69 | 7 General Purpose ADIN7 / UID / Die Temperature 0 - 2.4V / No / | ||
70 | 0 - 4.8V /2 | ||
71 | 12 General Purpose TSX1 / Touchscreen X-plate 1 0 - 2.4V No | ||
72 | 13 General Purpose TSX2 / Touchscreen X-plate 2 0 - 2.4V No | ||
73 | 14 General Purpose TSY1 / Touchscreen Y-plate 1 0 - 2.4V No | ||
74 | 15 General Purpose TSY2 / Touchscreen Y-plate 2 0 - 2.4V No | ||
diff --git a/Documentation/hwmon/mcp3021 b/Documentation/hwmon/mcp3021 new file mode 100644 index 000000000000..325fd87e81b2 --- /dev/null +++ b/Documentation/hwmon/mcp3021 | |||
@@ -0,0 +1,22 @@ | |||
1 | Kernel driver MCP3021 | ||
2 | ====================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Microchip Technology MCP3021 | ||
6 | Prefix: 'mcp3021' | ||
7 | Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21805a.pdf | ||
8 | |||
9 | Author: Mingkai Hu | ||
10 | |||
11 | Description | ||
12 | ----------- | ||
13 | |||
14 | This driver implements support for the Microchip Technology MCP3021 chip. | ||
15 | |||
16 | The Microchip Technology Inc. MCP3021 is a successive approximation A/D | ||
17 | converter (ADC) with 10-bit resolution. | ||
18 | This device provides one single-ended input with very low power consumption. | ||
19 | Communication to the MCP3021 is performed using a 2-wire I2C compatible | ||
20 | interface. Standard (100 kHz) and Fast (400 kHz) I2C modes are available. | ||
21 | The default I2C device address is 0x4d (contact the Microchip factory for | ||
22 | additional address options). | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 811e6c47e7e6..5b32d56dbb4d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -648,7 +648,8 @@ config SENSORS_LM90 | |||
648 | LM86, LM89 and LM99, Analog Devices ADM1032, ADT7461, and ADT7461A, | 648 | LM86, LM89 and LM99, Analog Devices ADM1032, ADT7461, and ADT7461A, |
649 | Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, | 649 | Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, |
650 | MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, ON Semiconductor NCT1008, | 650 | MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, ON Semiconductor NCT1008, |
651 | Winbond/Nuvoton W83L771W/G/AWG/ASG and Philips SA56004 sensor chips. | 651 | Winbond/Nuvoton W83L771W/G/AWG/ASG, Philips SA56004, and GMT G781 |
652 | sensor chips. | ||
652 | 653 | ||
653 | This driver can also be built as a module. If so, the module | 654 | This driver can also be built as a module. If so, the module |
654 | will be called lm90. | 655 | will be called lm90. |
@@ -812,6 +813,16 @@ config SENSORS_MAX6650 | |||
812 | This driver can also be built as a module. If so, the module | 813 | This driver can also be built as a module. If so, the module |
813 | will be called max6650. | 814 | will be called max6650. |
814 | 815 | ||
816 | config SENSORS_MCP3021 | ||
817 | tristate "Microchip MCP3021" | ||
818 | depends on I2C && EXPERIMENTAL | ||
819 | help | ||
820 | If you say yes here you get support for the MCP3021 chip | ||
821 | that is a A/D converter (ADC) with 10-bit resolution. | ||
822 | |||
823 | This driver can also be built as a module. If so, the module | ||
824 | will be called mcp3021. | ||
825 | |||
815 | config SENSORS_NTC_THERMISTOR | 826 | config SENSORS_NTC_THERMISTOR |
816 | tristate "NTC thermistor support" | 827 | tristate "NTC thermistor support" |
817 | depends on EXPERIMENTAL | 828 | depends on EXPERIMENTAL |
@@ -1229,18 +1240,19 @@ config SENSORS_W83795 | |||
1229 | depends on I2C && EXPERIMENTAL | 1240 | depends on I2C && EXPERIMENTAL |
1230 | help | 1241 | help |
1231 | If you say yes here you get support for the Winbond W83795G and | 1242 | If you say yes here you get support for the Winbond W83795G and |
1232 | W83795ADG hardware monitoring chip. | 1243 | W83795ADG hardware monitoring chip, including manual fan speed |
1244 | control. | ||
1233 | 1245 | ||
1234 | This driver can also be built as a module. If so, the module | 1246 | This driver can also be built as a module. If so, the module |
1235 | will be called w83795. | 1247 | will be called w83795. |
1236 | 1248 | ||
1237 | config SENSORS_W83795_FANCTRL | 1249 | config SENSORS_W83795_FANCTRL |
1238 | boolean "Include fan control support (DANGEROUS)" | 1250 | boolean "Include automatic fan control support (DANGEROUS)" |
1239 | depends on SENSORS_W83795 && EXPERIMENTAL | 1251 | depends on SENSORS_W83795 && EXPERIMENTAL |
1240 | default n | 1252 | default n |
1241 | help | 1253 | help |
1242 | If you say yes here, support for the both manual and automatic | 1254 | If you say yes here, support for automatic fan speed control |
1243 | fan control features will be included in the driver. | 1255 | will be included in the driver. |
1244 | 1256 | ||
1245 | This part of the code wasn't carefully reviewed and tested yet, | 1257 | This part of the code wasn't carefully reviewed and tested yet, |
1246 | so enabling this option is strongly discouraged on production | 1258 | so enabling this option is strongly discouraged on production |
@@ -1358,10 +1370,10 @@ config SENSORS_APPLESMC | |||
1358 | the awesome power of applesmc. | 1370 | the awesome power of applesmc. |
1359 | 1371 | ||
1360 | config SENSORS_MC13783_ADC | 1372 | config SENSORS_MC13783_ADC |
1361 | tristate "Freescale MC13783 ADC" | 1373 | tristate "Freescale MC13783/MC13892 ADC" |
1362 | depends on MFD_MC13783 | 1374 | depends on MFD_MC13XXX |
1363 | help | 1375 | help |
1364 | Support for the A/D converter on MC13783 PMIC. | 1376 | Support for the A/D converter on MC13783 and MC13892 PMIC. |
1365 | 1377 | ||
1366 | if ACPI | 1378 | if ACPI |
1367 | 1379 | ||
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 8251ce8cd035..6d3f11f71815 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -95,6 +95,7 @@ obj-$(CONFIG_SENSORS_MAX6639) += max6639.o | |||
95 | obj-$(CONFIG_SENSORS_MAX6642) += max6642.o | 95 | obj-$(CONFIG_SENSORS_MAX6642) += max6642.o |
96 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | 96 | obj-$(CONFIG_SENSORS_MAX6650) += max6650.o |
97 | obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o | 97 | obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o |
98 | obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o | ||
98 | obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o | 99 | obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o |
99 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 100 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
100 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o | 101 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o |
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index 523f8fb9e7d9..b7494af1e4a9 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c | |||
@@ -60,15 +60,15 @@ static ssize_t show_power(struct device *dev, | |||
60 | pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5), | 60 | pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5), |
61 | REG_TDP_RUNNING_AVERAGE, &val); | 61 | REG_TDP_RUNNING_AVERAGE, &val); |
62 | running_avg_capture = (val >> 4) & 0x3fffff; | 62 | running_avg_capture = (val >> 4) & 0x3fffff; |
63 | running_avg_capture = sign_extend32(running_avg_capture, 22); | 63 | running_avg_capture = sign_extend32(running_avg_capture, 21); |
64 | running_avg_range = val & 0xf; | 64 | running_avg_range = (val & 0xf) + 1; |
65 | 65 | ||
66 | pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5), | 66 | pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5), |
67 | REG_TDP_LIMIT3, &val); | 67 | REG_TDP_LIMIT3, &val); |
68 | 68 | ||
69 | tdp_limit = val >> 16; | 69 | tdp_limit = val >> 16; |
70 | curr_pwr_watts = tdp_limit + data->base_tdp - | 70 | curr_pwr_watts = (tdp_limit + data->base_tdp) << running_avg_range; |
71 | (s32)(running_avg_capture >> (running_avg_range + 1)); | 71 | curr_pwr_watts -= running_avg_capture; |
72 | curr_pwr_watts *= data->tdp_to_watts; | 72 | curr_pwr_watts *= data->tdp_to_watts; |
73 | 73 | ||
74 | /* | 74 | /* |
@@ -78,7 +78,7 @@ static ssize_t show_power(struct device *dev, | |||
78 | * scaling factor 1/(2^16). For conversion we use | 78 | * scaling factor 1/(2^16). For conversion we use |
79 | * (10^6)/(2^16) = 15625/(2^10) | 79 | * (10^6)/(2^16) = 15625/(2^10) |
80 | */ | 80 | */ |
81 | curr_pwr_watts = (curr_pwr_watts * 15625) >> 10; | 81 | curr_pwr_watts = (curr_pwr_watts * 15625) >> (10 + running_avg_range); |
82 | return sprintf(buf, "%u\n", (unsigned int) curr_pwr_watts); | 82 | return sprintf(buf, "%u\n", (unsigned int) curr_pwr_watts); |
83 | } | 83 | } |
84 | static DEVICE_ATTR(power1_input, S_IRUGO, show_power, NULL); | 84 | static DEVICE_ATTR(power1_input, S_IRUGO, show_power, NULL); |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 15c05cc83e2c..602a0f0b0de8 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
@@ -148,46 +148,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; | |||
148 | #define UPDATE_INTERVAL(max, rate) \ | 148 | #define UPDATE_INTERVAL(max, rate) \ |
149 | ((1000 << (LM63_MAX_CONVRATE - (rate))) / (max)) | 149 | ((1000 << (LM63_MAX_CONVRATE - (rate))) / (max)) |
150 | 150 | ||
151 | /* | ||
152 | * Functions declaration | ||
153 | */ | ||
154 | |||
155 | static int lm63_probe(struct i2c_client *client, | ||
156 | const struct i2c_device_id *id); | ||
157 | static int lm63_remove(struct i2c_client *client); | ||
158 | |||
159 | static struct lm63_data *lm63_update_device(struct device *dev); | ||
160 | |||
161 | static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info); | ||
162 | static void lm63_init_client(struct i2c_client *client); | ||
163 | |||
164 | enum chips { lm63, lm64, lm96163 }; | 151 | enum chips { lm63, lm64, lm96163 }; |
165 | 152 | ||
166 | /* | 153 | /* |
167 | * Driver data (common to all clients) | ||
168 | */ | ||
169 | |||
170 | static const struct i2c_device_id lm63_id[] = { | ||
171 | { "lm63", lm63 }, | ||
172 | { "lm64", lm64 }, | ||
173 | { "lm96163", lm96163 }, | ||
174 | { } | ||
175 | }; | ||
176 | MODULE_DEVICE_TABLE(i2c, lm63_id); | ||
177 | |||
178 | static struct i2c_driver lm63_driver = { | ||
179 | .class = I2C_CLASS_HWMON, | ||
180 | .driver = { | ||
181 | .name = "lm63", | ||
182 | }, | ||
183 | .probe = lm63_probe, | ||
184 | .remove = lm63_remove, | ||
185 | .id_table = lm63_id, | ||
186 | .detect = lm63_detect, | ||
187 | .address_list = normal_i2c, | ||
188 | }; | ||
189 | |||
190 | /* | ||
191 | * Client data (each client gets its own) | 154 | * Client data (each client gets its own) |
192 | */ | 155 | */ |
193 | 156 | ||
@@ -242,6 +205,145 @@ static inline int lut_temp_from_reg(struct lm63_data *data, int nr) | |||
242 | return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000); | 205 | return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000); |
243 | } | 206 | } |
244 | 207 | ||
208 | static inline int lut_temp_to_reg(struct lm63_data *data, long val) | ||
209 | { | ||
210 | val -= data->temp2_offset; | ||
211 | if (data->lut_temp_highres) | ||
212 | return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127500), 500); | ||
213 | else | ||
214 | return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127000), 1000); | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Update the lookup table register cache. | ||
219 | * client->update_lock must be held when calling this function. | ||
220 | */ | ||
221 | static void lm63_update_lut(struct i2c_client *client) | ||
222 | { | ||
223 | struct lm63_data *data = i2c_get_clientdata(client); | ||
224 | int i; | ||
225 | |||
226 | if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || | ||
227 | !data->lut_valid) { | ||
228 | for (i = 0; i < data->lut_size; i++) { | ||
229 | data->pwm1[1 + i] = i2c_smbus_read_byte_data(client, | ||
230 | LM63_REG_LUT_PWM(i)); | ||
231 | data->temp8[3 + i] = i2c_smbus_read_byte_data(client, | ||
232 | LM63_REG_LUT_TEMP(i)); | ||
233 | } | ||
234 | data->lut_temp_hyst = i2c_smbus_read_byte_data(client, | ||
235 | LM63_REG_LUT_TEMP_HYST); | ||
236 | |||
237 | data->lut_last_updated = jiffies; | ||
238 | data->lut_valid = 1; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | static struct lm63_data *lm63_update_device(struct device *dev) | ||
243 | { | ||
244 | struct i2c_client *client = to_i2c_client(dev); | ||
245 | struct lm63_data *data = i2c_get_clientdata(client); | ||
246 | unsigned long next_update; | ||
247 | |||
248 | mutex_lock(&data->update_lock); | ||
249 | |||
250 | next_update = data->last_updated | ||
251 | + msecs_to_jiffies(data->update_interval) + 1; | ||
252 | |||
253 | if (time_after(jiffies, next_update) || !data->valid) { | ||
254 | if (data->config & 0x04) { /* tachometer enabled */ | ||
255 | /* order matters for fan1_input */ | ||
256 | data->fan[0] = i2c_smbus_read_byte_data(client, | ||
257 | LM63_REG_TACH_COUNT_LSB) & 0xFC; | ||
258 | data->fan[0] |= i2c_smbus_read_byte_data(client, | ||
259 | LM63_REG_TACH_COUNT_MSB) << 8; | ||
260 | data->fan[1] = (i2c_smbus_read_byte_data(client, | ||
261 | LM63_REG_TACH_LIMIT_LSB) & 0xFC) | ||
262 | | (i2c_smbus_read_byte_data(client, | ||
263 | LM63_REG_TACH_LIMIT_MSB) << 8); | ||
264 | } | ||
265 | |||
266 | data->pwm1_freq = i2c_smbus_read_byte_data(client, | ||
267 | LM63_REG_PWM_FREQ); | ||
268 | if (data->pwm1_freq == 0) | ||
269 | data->pwm1_freq = 1; | ||
270 | data->pwm1[0] = i2c_smbus_read_byte_data(client, | ||
271 | LM63_REG_PWM_VALUE); | ||
272 | |||
273 | data->temp8[0] = i2c_smbus_read_byte_data(client, | ||
274 | LM63_REG_LOCAL_TEMP); | ||
275 | data->temp8[1] = i2c_smbus_read_byte_data(client, | ||
276 | LM63_REG_LOCAL_HIGH); | ||
277 | |||
278 | /* order matters for temp2_input */ | ||
279 | data->temp11[0] = i2c_smbus_read_byte_data(client, | ||
280 | LM63_REG_REMOTE_TEMP_MSB) << 8; | ||
281 | data->temp11[0] |= i2c_smbus_read_byte_data(client, | ||
282 | LM63_REG_REMOTE_TEMP_LSB); | ||
283 | data->temp11[1] = (i2c_smbus_read_byte_data(client, | ||
284 | LM63_REG_REMOTE_LOW_MSB) << 8) | ||
285 | | i2c_smbus_read_byte_data(client, | ||
286 | LM63_REG_REMOTE_LOW_LSB); | ||
287 | data->temp11[2] = (i2c_smbus_read_byte_data(client, | ||
288 | LM63_REG_REMOTE_HIGH_MSB) << 8) | ||
289 | | i2c_smbus_read_byte_data(client, | ||
290 | LM63_REG_REMOTE_HIGH_LSB); | ||
291 | data->temp11[3] = (i2c_smbus_read_byte_data(client, | ||
292 | LM63_REG_REMOTE_OFFSET_MSB) << 8) | ||
293 | | i2c_smbus_read_byte_data(client, | ||
294 | LM63_REG_REMOTE_OFFSET_LSB); | ||
295 | |||
296 | if (data->kind == lm96163) | ||
297 | data->temp11u = (i2c_smbus_read_byte_data(client, | ||
298 | LM96163_REG_REMOTE_TEMP_U_MSB) << 8) | ||
299 | | i2c_smbus_read_byte_data(client, | ||
300 | LM96163_REG_REMOTE_TEMP_U_LSB); | ||
301 | |||
302 | data->temp8[2] = i2c_smbus_read_byte_data(client, | ||
303 | LM63_REG_REMOTE_TCRIT); | ||
304 | data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, | ||
305 | LM63_REG_REMOTE_TCRIT_HYST); | ||
306 | |||
307 | data->alarms = i2c_smbus_read_byte_data(client, | ||
308 | LM63_REG_ALERT_STATUS) & 0x7F; | ||
309 | |||
310 | data->last_updated = jiffies; | ||
311 | data->valid = 1; | ||
312 | } | ||
313 | |||
314 | lm63_update_lut(client); | ||
315 | |||
316 | mutex_unlock(&data->update_lock); | ||
317 | |||
318 | return data; | ||
319 | } | ||
320 | |||
321 | /* | ||
322 | * Trip points in the lookup table should be in ascending order for both | ||
323 | * temperatures and PWM output values. | ||
324 | */ | ||
325 | static int lm63_lut_looks_bad(struct i2c_client *client) | ||
326 | { | ||
327 | struct lm63_data *data = i2c_get_clientdata(client); | ||
328 | int i; | ||
329 | |||
330 | mutex_lock(&data->update_lock); | ||
331 | lm63_update_lut(client); | ||
332 | |||
333 | for (i = 1; i < data->lut_size; i++) { | ||
334 | if (data->pwm1[1 + i - 1] > data->pwm1[1 + i] | ||
335 | || data->temp8[3 + i - 1] > data->temp8[3 + i]) { | ||
336 | dev_warn(&client->dev, | ||
337 | "Lookup table doesn't look sane (check entries %d and %d)\n", | ||
338 | i, i + 1); | ||
339 | break; | ||
340 | } | ||
341 | } | ||
342 | mutex_unlock(&data->update_lock); | ||
343 | |||
344 | return i == data->lut_size ? 0 : 1; | ||
345 | } | ||
346 | |||
245 | /* | 347 | /* |
246 | * Sysfs callback functions and files | 348 | * Sysfs callback functions and files |
247 | */ | 349 | */ |
@@ -294,13 +396,16 @@ static ssize_t show_pwm1(struct device *dev, struct device_attribute *devattr, | |||
294 | return sprintf(buf, "%d\n", pwm); | 396 | return sprintf(buf, "%d\n", pwm); |
295 | } | 397 | } |
296 | 398 | ||
297 | static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, | 399 | static ssize_t set_pwm1(struct device *dev, struct device_attribute *devattr, |
298 | const char *buf, size_t count) | 400 | const char *buf, size_t count) |
299 | { | 401 | { |
402 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
300 | struct i2c_client *client = to_i2c_client(dev); | 403 | struct i2c_client *client = to_i2c_client(dev); |
301 | struct lm63_data *data = i2c_get_clientdata(client); | 404 | struct lm63_data *data = i2c_get_clientdata(client); |
405 | int nr = attr->index; | ||
302 | unsigned long val; | 406 | unsigned long val; |
303 | int err; | 407 | int err; |
408 | u8 reg; | ||
304 | 409 | ||
305 | if (!(data->config_fan & 0x20)) /* register is read-only */ | 410 | if (!(data->config_fan & 0x20)) /* register is read-only */ |
306 | return -EPERM; | 411 | return -EPERM; |
@@ -309,11 +414,13 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, | |||
309 | if (err) | 414 | if (err) |
310 | return err; | 415 | return err; |
311 | 416 | ||
417 | reg = nr ? LM63_REG_LUT_PWM(nr - 1) : LM63_REG_PWM_VALUE; | ||
312 | val = SENSORS_LIMIT(val, 0, 255); | 418 | val = SENSORS_LIMIT(val, 0, 255); |
419 | |||
313 | mutex_lock(&data->update_lock); | 420 | mutex_lock(&data->update_lock); |
314 | data->pwm1[0] = data->pwm_highres ? val : | 421 | data->pwm1[nr] = data->pwm_highres ? val : |
315 | (val * data->pwm1_freq * 2 + 127) / 255; | 422 | (val * data->pwm1_freq * 2 + 127) / 255; |
316 | i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1[0]); | 423 | i2c_smbus_write_byte_data(client, reg, data->pwm1[nr]); |
317 | mutex_unlock(&data->update_lock); | 424 | mutex_unlock(&data->update_lock); |
318 | return count; | 425 | return count; |
319 | } | 426 | } |
@@ -325,6 +432,41 @@ static ssize_t show_pwm1_enable(struct device *dev, | |||
325 | return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); | 432 | return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); |
326 | } | 433 | } |
327 | 434 | ||
435 | static ssize_t set_pwm1_enable(struct device *dev, | ||
436 | struct device_attribute *dummy, | ||
437 | const char *buf, size_t count) | ||
438 | { | ||
439 | struct i2c_client *client = to_i2c_client(dev); | ||
440 | struct lm63_data *data = i2c_get_clientdata(client); | ||
441 | unsigned long val; | ||
442 | int err; | ||
443 | |||
444 | err = kstrtoul(buf, 10, &val); | ||
445 | if (err) | ||
446 | return err; | ||
447 | if (val < 1 || val > 2) | ||
448 | return -EINVAL; | ||
449 | |||
450 | /* | ||
451 | * Only let the user switch to automatic mode if the lookup table | ||
452 | * looks sane. | ||
453 | */ | ||
454 | if (val == 2 && lm63_lut_looks_bad(client)) | ||
455 | return -EPERM; | ||
456 | |||
457 | mutex_lock(&data->update_lock); | ||
458 | data->config_fan = i2c_smbus_read_byte_data(client, | ||
459 | LM63_REG_CONFIG_FAN); | ||
460 | if (val == 1) | ||
461 | data->config_fan |= 0x20; | ||
462 | else | ||
463 | data->config_fan &= ~0x20; | ||
464 | i2c_smbus_write_byte_data(client, LM63_REG_CONFIG_FAN, | ||
465 | data->config_fan); | ||
466 | mutex_unlock(&data->update_lock); | ||
467 | return count; | ||
468 | } | ||
469 | |||
328 | /* | 470 | /* |
329 | * There are 8bit registers for both local(temp1) and remote(temp2) sensor. | 471 | * There are 8bit registers for both local(temp1) and remote(temp2) sensor. |
330 | * For remote sensor registers temp2_offset has to be considered, | 472 | * For remote sensor registers temp2_offset has to be considered, |
@@ -367,23 +509,31 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, | |||
367 | struct i2c_client *client = to_i2c_client(dev); | 509 | struct i2c_client *client = to_i2c_client(dev); |
368 | struct lm63_data *data = i2c_get_clientdata(client); | 510 | struct lm63_data *data = i2c_get_clientdata(client); |
369 | int nr = attr->index; | 511 | int nr = attr->index; |
370 | int reg = nr == 2 ? LM63_REG_REMOTE_TCRIT : LM63_REG_LOCAL_HIGH; | ||
371 | long val; | 512 | long val; |
372 | int err; | 513 | int err; |
373 | int temp; | 514 | int temp; |
515 | u8 reg; | ||
374 | 516 | ||
375 | err = kstrtol(buf, 10, &val); | 517 | err = kstrtol(buf, 10, &val); |
376 | if (err) | 518 | if (err) |
377 | return err; | 519 | return err; |
378 | 520 | ||
379 | mutex_lock(&data->update_lock); | 521 | mutex_lock(&data->update_lock); |
380 | if (nr == 2) { | 522 | switch (nr) { |
523 | case 2: | ||
524 | reg = LM63_REG_REMOTE_TCRIT; | ||
381 | if (data->remote_unsigned) | 525 | if (data->remote_unsigned) |
382 | temp = TEMP8U_TO_REG(val - data->temp2_offset); | 526 | temp = TEMP8U_TO_REG(val - data->temp2_offset); |
383 | else | 527 | else |
384 | temp = TEMP8_TO_REG(val - data->temp2_offset); | 528 | temp = TEMP8_TO_REG(val - data->temp2_offset); |
385 | } else { | 529 | break; |
530 | case 1: | ||
531 | reg = LM63_REG_LOCAL_HIGH; | ||
386 | temp = TEMP8_TO_REG(val); | 532 | temp = TEMP8_TO_REG(val); |
533 | break; | ||
534 | default: /* lookup table */ | ||
535 | reg = LM63_REG_LUT_TEMP(nr - 3); | ||
536 | temp = lut_temp_to_reg(data, val); | ||
387 | } | 537 | } |
388 | data->temp8[nr] = temp; | 538 | data->temp8[nr] = temp; |
389 | i2c_smbus_write_byte_data(client, reg, temp); | 539 | i2c_smbus_write_byte_data(client, reg, temp); |
@@ -613,65 +763,78 @@ static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan, | |||
613 | set_fan, 1); | 763 | set_fan, 1); |
614 | 764 | ||
615 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0); | 765 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0); |
616 | static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL); | 766 | static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, |
617 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO, show_pwm1, NULL, 1); | 767 | show_pwm1_enable, set_pwm1_enable); |
618 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IRUGO, | 768 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, |
619 | show_lut_temp, NULL, 3); | 769 | show_pwm1, set_pwm1, 1); |
770 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
771 | show_lut_temp, set_temp8, 3); | ||
620 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO, | 772 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO, |
621 | show_lut_temp_hyst, NULL, 3); | 773 | show_lut_temp_hyst, NULL, 3); |
622 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO, show_pwm1, NULL, 2); | 774 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, |
623 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IRUGO, | 775 | show_pwm1, set_pwm1, 2); |
624 | show_lut_temp, NULL, 4); | 776 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO, |
777 | show_lut_temp, set_temp8, 4); | ||
625 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO, | 778 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO, |
626 | show_lut_temp_hyst, NULL, 4); | 779 | show_lut_temp_hyst, NULL, 4); |
627 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO, show_pwm1, NULL, 3); | 780 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO, |
628 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IRUGO, | 781 | show_pwm1, set_pwm1, 3); |
629 | show_lut_temp, NULL, 5); | 782 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO, |
783 | show_lut_temp, set_temp8, 5); | ||
630 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO, | 784 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO, |
631 | show_lut_temp_hyst, NULL, 5); | 785 | show_lut_temp_hyst, NULL, 5); |
632 | static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO, show_pwm1, NULL, 4); | 786 | static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO, |
633 | static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IRUGO, | 787 | show_pwm1, set_pwm1, 4); |
634 | show_lut_temp, NULL, 6); | 788 | static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO, |
789 | show_lut_temp, set_temp8, 6); | ||
635 | static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO, | 790 | static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO, |
636 | show_lut_temp_hyst, NULL, 6); | 791 | show_lut_temp_hyst, NULL, 6); |
637 | static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm1, NULL, 5); | 792 | static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO, |
638 | static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IRUGO, | 793 | show_pwm1, set_pwm1, 5); |
639 | show_lut_temp, NULL, 7); | 794 | static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO, |
795 | show_lut_temp, set_temp8, 7); | ||
640 | static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO, | 796 | static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO, |
641 | show_lut_temp_hyst, NULL, 7); | 797 | show_lut_temp_hyst, NULL, 7); |
642 | static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IRUGO, show_pwm1, NULL, 6); | 798 | static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO, |
643 | static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IRUGO, | 799 | show_pwm1, set_pwm1, 6); |
644 | show_lut_temp, NULL, 8); | 800 | static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO, |
801 | show_lut_temp, set_temp8, 8); | ||
645 | static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO, | 802 | static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO, |
646 | show_lut_temp_hyst, NULL, 8); | 803 | show_lut_temp_hyst, NULL, 8); |
647 | static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IRUGO, show_pwm1, NULL, 7); | 804 | static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO, |
648 | static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IRUGO, | 805 | show_pwm1, set_pwm1, 7); |
649 | show_lut_temp, NULL, 9); | 806 | static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO, |
807 | show_lut_temp, set_temp8, 9); | ||
650 | static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO, | 808 | static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO, |
651 | show_lut_temp_hyst, NULL, 9); | 809 | show_lut_temp_hyst, NULL, 9); |
652 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IRUGO, show_pwm1, NULL, 8); | 810 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IWUSR | S_IRUGO, |
653 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO, | 811 | show_pwm1, set_pwm1, 8); |
654 | show_lut_temp, NULL, 10); | 812 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IWUSR | S_IRUGO, |
813 | show_lut_temp, set_temp8, 10); | ||
655 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, | 814 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, |
656 | show_lut_temp_hyst, NULL, 10); | 815 | show_lut_temp_hyst, NULL, 10); |
657 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9); | 816 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IWUSR | S_IRUGO, |
658 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO, | 817 | show_pwm1, set_pwm1, 9); |
659 | show_lut_temp, NULL, 11); | 818 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IWUSR | S_IRUGO, |
819 | show_lut_temp, set_temp8, 11); | ||
660 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO, | 820 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO, |
661 | show_lut_temp_hyst, NULL, 11); | 821 | show_lut_temp_hyst, NULL, 11); |
662 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10); | 822 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IWUSR | S_IRUGO, |
663 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO, | 823 | show_pwm1, set_pwm1, 10); |
664 | show_lut_temp, NULL, 12); | 824 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IWUSR | S_IRUGO, |
825 | show_lut_temp, set_temp8, 12); | ||
665 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO, | 826 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO, |
666 | show_lut_temp_hyst, NULL, 12); | 827 | show_lut_temp_hyst, NULL, 12); |
667 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11); | 828 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IWUSR | S_IRUGO, |
668 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO, | 829 | show_pwm1, set_pwm1, 11); |
669 | show_lut_temp, NULL, 13); | 830 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IWUSR | S_IRUGO, |
831 | show_lut_temp, set_temp8, 13); | ||
670 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO, | 832 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO, |
671 | show_lut_temp_hyst, NULL, 13); | 833 | show_lut_temp_hyst, NULL, 13); |
672 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12); | 834 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IWUSR | S_IRUGO, |
673 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO, | 835 | show_pwm1, set_pwm1, 12); |
674 | show_lut_temp, NULL, 14); | 836 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IWUSR | S_IRUGO, |
837 | show_lut_temp, set_temp8, 14); | ||
675 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO, | 838 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO, |
676 | show_lut_temp_hyst, NULL, 14); | 839 | show_lut_temp_hyst, NULL, 14); |
677 | 840 | ||
@@ -817,28 +980,25 @@ static const struct attribute_group lm63_group_fan1 = { | |||
817 | */ | 980 | */ |
818 | 981 | ||
819 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 982 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
820 | static int lm63_detect(struct i2c_client *new_client, | 983 | static int lm63_detect(struct i2c_client *client, |
821 | struct i2c_board_info *info) | 984 | struct i2c_board_info *info) |
822 | { | 985 | { |
823 | struct i2c_adapter *adapter = new_client->adapter; | 986 | struct i2c_adapter *adapter = client->adapter; |
824 | u8 man_id, chip_id, reg_config1, reg_config2; | 987 | u8 man_id, chip_id, reg_config1, reg_config2; |
825 | u8 reg_alert_status, reg_alert_mask; | 988 | u8 reg_alert_status, reg_alert_mask; |
826 | int address = new_client->addr; | 989 | int address = client->addr; |
827 | 990 | ||
828 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 991 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
829 | return -ENODEV; | 992 | return -ENODEV; |
830 | 993 | ||
831 | man_id = i2c_smbus_read_byte_data(new_client, LM63_REG_MAN_ID); | 994 | man_id = i2c_smbus_read_byte_data(client, LM63_REG_MAN_ID); |
832 | chip_id = i2c_smbus_read_byte_data(new_client, LM63_REG_CHIP_ID); | 995 | chip_id = i2c_smbus_read_byte_data(client, LM63_REG_CHIP_ID); |
833 | 996 | ||
834 | reg_config1 = i2c_smbus_read_byte_data(new_client, | 997 | reg_config1 = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1); |
835 | LM63_REG_CONFIG1); | 998 | reg_config2 = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG2); |
836 | reg_config2 = i2c_smbus_read_byte_data(new_client, | 999 | reg_alert_status = i2c_smbus_read_byte_data(client, |
837 | LM63_REG_CONFIG2); | ||
838 | reg_alert_status = i2c_smbus_read_byte_data(new_client, | ||
839 | LM63_REG_ALERT_STATUS); | 1000 | LM63_REG_ALERT_STATUS); |
840 | reg_alert_mask = i2c_smbus_read_byte_data(new_client, | 1001 | reg_alert_mask = i2c_smbus_read_byte_data(client, LM63_REG_ALERT_MASK); |
841 | LM63_REG_ALERT_MASK); | ||
842 | 1002 | ||
843 | if (man_id != 0x01 /* National Semiconductor */ | 1003 | if (man_id != 0x01 /* National Semiconductor */ |
844 | || (reg_config1 & 0x18) != 0x00 | 1004 | || (reg_config1 & 0x18) != 0x00 |
@@ -863,74 +1023,6 @@ static int lm63_detect(struct i2c_client *new_client, | |||
863 | return 0; | 1023 | return 0; |
864 | } | 1024 | } |
865 | 1025 | ||
866 | static int lm63_probe(struct i2c_client *new_client, | ||
867 | const struct i2c_device_id *id) | ||
868 | { | ||
869 | struct lm63_data *data; | ||
870 | int err; | ||
871 | |||
872 | data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL); | ||
873 | if (!data) { | ||
874 | err = -ENOMEM; | ||
875 | goto exit; | ||
876 | } | ||
877 | |||
878 | i2c_set_clientdata(new_client, data); | ||
879 | data->valid = 0; | ||
880 | mutex_init(&data->update_lock); | ||
881 | |||
882 | /* Set the device type */ | ||
883 | data->kind = id->driver_data; | ||
884 | if (data->kind == lm64) | ||
885 | data->temp2_offset = 16000; | ||
886 | |||
887 | /* Initialize chip */ | ||
888 | lm63_init_client(new_client); | ||
889 | |||
890 | /* Register sysfs hooks */ | ||
891 | err = sysfs_create_group(&new_client->dev.kobj, &lm63_group); | ||
892 | if (err) | ||
893 | goto exit_free; | ||
894 | if (data->config & 0x04) { /* tachometer enabled */ | ||
895 | err = sysfs_create_group(&new_client->dev.kobj, | ||
896 | &lm63_group_fan1); | ||
897 | if (err) | ||
898 | goto exit_remove_files; | ||
899 | } | ||
900 | if (data->kind == lm96163) { | ||
901 | err = device_create_file(&new_client->dev, | ||
902 | &dev_attr_temp2_type); | ||
903 | if (err) | ||
904 | goto exit_remove_files; | ||
905 | |||
906 | err = sysfs_create_group(&new_client->dev.kobj, | ||
907 | &lm63_group_extra_lut); | ||
908 | if (err) | ||
909 | goto exit_remove_files; | ||
910 | } | ||
911 | |||
912 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
913 | if (IS_ERR(data->hwmon_dev)) { | ||
914 | err = PTR_ERR(data->hwmon_dev); | ||
915 | goto exit_remove_files; | ||
916 | } | ||
917 | |||
918 | return 0; | ||
919 | |||
920 | exit_remove_files: | ||
921 | sysfs_remove_group(&new_client->dev.kobj, &lm63_group); | ||
922 | sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); | ||
923 | if (data->kind == lm96163) { | ||
924 | device_remove_file(&new_client->dev, &dev_attr_temp2_type); | ||
925 | sysfs_remove_group(&new_client->dev.kobj, | ||
926 | &lm63_group_extra_lut); | ||
927 | } | ||
928 | exit_free: | ||
929 | kfree(data); | ||
930 | exit: | ||
931 | return err; | ||
932 | } | ||
933 | |||
934 | /* | 1026 | /* |
935 | * Ideally we shouldn't have to initialize anything, since the BIOS | 1027 | * Ideally we shouldn't have to initialize anything, since the BIOS |
936 | * should have taken care of everything | 1028 | * should have taken care of everything |
@@ -1010,114 +1102,110 @@ static void lm63_init_client(struct i2c_client *client) | |||
1010 | (data->config_fan & 0x20) ? "manual" : "auto"); | 1102 | (data->config_fan & 0x20) ? "manual" : "auto"); |
1011 | } | 1103 | } |
1012 | 1104 | ||
1013 | static int lm63_remove(struct i2c_client *client) | 1105 | static int lm63_probe(struct i2c_client *client, |
1106 | const struct i2c_device_id *id) | ||
1014 | { | 1107 | { |
1015 | struct lm63_data *data = i2c_get_clientdata(client); | 1108 | struct lm63_data *data; |
1109 | int err; | ||
1016 | 1110 | ||
1017 | hwmon_device_unregister(data->hwmon_dev); | 1111 | data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL); |
1112 | if (!data) { | ||
1113 | err = -ENOMEM; | ||
1114 | goto exit; | ||
1115 | } | ||
1116 | |||
1117 | i2c_set_clientdata(client, data); | ||
1118 | data->valid = 0; | ||
1119 | mutex_init(&data->update_lock); | ||
1120 | |||
1121 | /* Set the device type */ | ||
1122 | data->kind = id->driver_data; | ||
1123 | if (data->kind == lm64) | ||
1124 | data->temp2_offset = 16000; | ||
1125 | |||
1126 | /* Initialize chip */ | ||
1127 | lm63_init_client(client); | ||
1128 | |||
1129 | /* Register sysfs hooks */ | ||
1130 | err = sysfs_create_group(&client->dev.kobj, &lm63_group); | ||
1131 | if (err) | ||
1132 | goto exit_free; | ||
1133 | if (data->config & 0x04) { /* tachometer enabled */ | ||
1134 | err = sysfs_create_group(&client->dev.kobj, &lm63_group_fan1); | ||
1135 | if (err) | ||
1136 | goto exit_remove_files; | ||
1137 | } | ||
1138 | if (data->kind == lm96163) { | ||
1139 | err = device_create_file(&client->dev, &dev_attr_temp2_type); | ||
1140 | if (err) | ||
1141 | goto exit_remove_files; | ||
1142 | |||
1143 | err = sysfs_create_group(&client->dev.kobj, | ||
1144 | &lm63_group_extra_lut); | ||
1145 | if (err) | ||
1146 | goto exit_remove_files; | ||
1147 | } | ||
1148 | |||
1149 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
1150 | if (IS_ERR(data->hwmon_dev)) { | ||
1151 | err = PTR_ERR(data->hwmon_dev); | ||
1152 | goto exit_remove_files; | ||
1153 | } | ||
1154 | |||
1155 | return 0; | ||
1156 | |||
1157 | exit_remove_files: | ||
1018 | sysfs_remove_group(&client->dev.kobj, &lm63_group); | 1158 | sysfs_remove_group(&client->dev.kobj, &lm63_group); |
1019 | sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); | 1159 | sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); |
1020 | if (data->kind == lm96163) { | 1160 | if (data->kind == lm96163) { |
1021 | device_remove_file(&client->dev, &dev_attr_temp2_type); | 1161 | device_remove_file(&client->dev, &dev_attr_temp2_type); |
1022 | sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); | 1162 | sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); |
1023 | } | 1163 | } |
1024 | 1164 | exit_free: | |
1025 | kfree(data); | 1165 | kfree(data); |
1026 | return 0; | 1166 | exit: |
1167 | return err; | ||
1027 | } | 1168 | } |
1028 | 1169 | ||
1029 | static struct lm63_data *lm63_update_device(struct device *dev) | 1170 | static int lm63_remove(struct i2c_client *client) |
1030 | { | 1171 | { |
1031 | struct i2c_client *client = to_i2c_client(dev); | ||
1032 | struct lm63_data *data = i2c_get_clientdata(client); | 1172 | struct lm63_data *data = i2c_get_clientdata(client); |
1033 | unsigned long next_update; | ||
1034 | int i; | ||
1035 | |||
1036 | mutex_lock(&data->update_lock); | ||
1037 | |||
1038 | next_update = data->last_updated | ||
1039 | + msecs_to_jiffies(data->update_interval) + 1; | ||
1040 | |||
1041 | if (time_after(jiffies, next_update) || !data->valid) { | ||
1042 | if (data->config & 0x04) { /* tachometer enabled */ | ||
1043 | /* order matters for fan1_input */ | ||
1044 | data->fan[0] = i2c_smbus_read_byte_data(client, | ||
1045 | LM63_REG_TACH_COUNT_LSB) & 0xFC; | ||
1046 | data->fan[0] |= i2c_smbus_read_byte_data(client, | ||
1047 | LM63_REG_TACH_COUNT_MSB) << 8; | ||
1048 | data->fan[1] = (i2c_smbus_read_byte_data(client, | ||
1049 | LM63_REG_TACH_LIMIT_LSB) & 0xFC) | ||
1050 | | (i2c_smbus_read_byte_data(client, | ||
1051 | LM63_REG_TACH_LIMIT_MSB) << 8); | ||
1052 | } | ||
1053 | |||
1054 | data->pwm1_freq = i2c_smbus_read_byte_data(client, | ||
1055 | LM63_REG_PWM_FREQ); | ||
1056 | if (data->pwm1_freq == 0) | ||
1057 | data->pwm1_freq = 1; | ||
1058 | data->pwm1[0] = i2c_smbus_read_byte_data(client, | ||
1059 | LM63_REG_PWM_VALUE); | ||
1060 | |||
1061 | data->temp8[0] = i2c_smbus_read_byte_data(client, | ||
1062 | LM63_REG_LOCAL_TEMP); | ||
1063 | data->temp8[1] = i2c_smbus_read_byte_data(client, | ||
1064 | LM63_REG_LOCAL_HIGH); | ||
1065 | |||
1066 | /* order matters for temp2_input */ | ||
1067 | data->temp11[0] = i2c_smbus_read_byte_data(client, | ||
1068 | LM63_REG_REMOTE_TEMP_MSB) << 8; | ||
1069 | data->temp11[0] |= i2c_smbus_read_byte_data(client, | ||
1070 | LM63_REG_REMOTE_TEMP_LSB); | ||
1071 | data->temp11[1] = (i2c_smbus_read_byte_data(client, | ||
1072 | LM63_REG_REMOTE_LOW_MSB) << 8) | ||
1073 | | i2c_smbus_read_byte_data(client, | ||
1074 | LM63_REG_REMOTE_LOW_LSB); | ||
1075 | data->temp11[2] = (i2c_smbus_read_byte_data(client, | ||
1076 | LM63_REG_REMOTE_HIGH_MSB) << 8) | ||
1077 | | i2c_smbus_read_byte_data(client, | ||
1078 | LM63_REG_REMOTE_HIGH_LSB); | ||
1079 | data->temp11[3] = (i2c_smbus_read_byte_data(client, | ||
1080 | LM63_REG_REMOTE_OFFSET_MSB) << 8) | ||
1081 | | i2c_smbus_read_byte_data(client, | ||
1082 | LM63_REG_REMOTE_OFFSET_LSB); | ||
1083 | |||
1084 | if (data->kind == lm96163) | ||
1085 | data->temp11u = (i2c_smbus_read_byte_data(client, | ||
1086 | LM96163_REG_REMOTE_TEMP_U_MSB) << 8) | ||
1087 | | i2c_smbus_read_byte_data(client, | ||
1088 | LM96163_REG_REMOTE_TEMP_U_LSB); | ||
1089 | |||
1090 | data->temp8[2] = i2c_smbus_read_byte_data(client, | ||
1091 | LM63_REG_REMOTE_TCRIT); | ||
1092 | data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, | ||
1093 | LM63_REG_REMOTE_TCRIT_HYST); | ||
1094 | |||
1095 | data->alarms = i2c_smbus_read_byte_data(client, | ||
1096 | LM63_REG_ALERT_STATUS) & 0x7F; | ||
1097 | 1173 | ||
1098 | data->last_updated = jiffies; | 1174 | hwmon_device_unregister(data->hwmon_dev); |
1099 | data->valid = 1; | 1175 | sysfs_remove_group(&client->dev.kobj, &lm63_group); |
1176 | sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); | ||
1177 | if (data->kind == lm96163) { | ||
1178 | device_remove_file(&client->dev, &dev_attr_temp2_type); | ||
1179 | sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); | ||
1100 | } | 1180 | } |
1101 | 1181 | ||
1102 | if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || | 1182 | kfree(data); |
1103 | !data->lut_valid) { | 1183 | return 0; |
1104 | for (i = 0; i < data->lut_size; i++) { | 1184 | } |
1105 | data->pwm1[1 + i] = i2c_smbus_read_byte_data(client, | ||
1106 | LM63_REG_LUT_PWM(i)); | ||
1107 | data->temp8[3 + i] = i2c_smbus_read_byte_data(client, | ||
1108 | LM63_REG_LUT_TEMP(i)); | ||
1109 | } | ||
1110 | data->lut_temp_hyst = i2c_smbus_read_byte_data(client, | ||
1111 | LM63_REG_LUT_TEMP_HYST); | ||
1112 | 1185 | ||
1113 | data->lut_last_updated = jiffies; | 1186 | /* |
1114 | data->lut_valid = 1; | 1187 | * Driver data (common to all clients) |
1115 | } | 1188 | */ |
1116 | 1189 | ||
1117 | mutex_unlock(&data->update_lock); | 1190 | static const struct i2c_device_id lm63_id[] = { |
1191 | { "lm63", lm63 }, | ||
1192 | { "lm64", lm64 }, | ||
1193 | { "lm96163", lm96163 }, | ||
1194 | { } | ||
1195 | }; | ||
1196 | MODULE_DEVICE_TABLE(i2c, lm63_id); | ||
1118 | 1197 | ||
1119 | return data; | 1198 | static struct i2c_driver lm63_driver = { |
1120 | } | 1199 | .class = I2C_CLASS_HWMON, |
1200 | .driver = { | ||
1201 | .name = "lm63", | ||
1202 | }, | ||
1203 | .probe = lm63_probe, | ||
1204 | .remove = lm63_remove, | ||
1205 | .id_table = lm63_id, | ||
1206 | .detect = lm63_detect, | ||
1207 | .address_list = normal_i2c, | ||
1208 | }; | ||
1121 | 1209 | ||
1122 | module_i2c_driver(lm63_driver); | 1210 | module_i2c_driver(lm63_driver); |
1123 | 1211 | ||
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 248f2b40dfaf..22b14a68e35e 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -57,6 +57,9 @@ | |||
57 | * This driver also supports the SA56004 from Philips. This device is | 57 | * This driver also supports the SA56004 from Philips. This device is |
58 | * pin-compatible with the LM86, the ED/EDP parts are also address-compatible. | 58 | * pin-compatible with the LM86, the ED/EDP parts are also address-compatible. |
59 | * | 59 | * |
60 | * This driver also supports the G781 from GMT. This device is compatible | ||
61 | * with the ADM1032. | ||
62 | * | ||
60 | * Since the LM90 was the first chipset supported by this driver, most | 63 | * Since the LM90 was the first chipset supported by this driver, most |
61 | * comments will refer to this chipset, but are actually general and | 64 | * comments will refer to this chipset, but are actually general and |
62 | * concern all supported chipsets, unless mentioned otherwise. | 65 | * concern all supported chipsets, unless mentioned otherwise. |
@@ -107,7 +110,7 @@ static const unsigned short normal_i2c[] = { | |||
107 | 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; | 110 | 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; |
108 | 111 | ||
109 | enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, | 112 | enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, |
110 | max6646, w83l771, max6696, sa56004 }; | 113 | max6646, w83l771, max6696, sa56004, g781 }; |
111 | 114 | ||
112 | /* | 115 | /* |
113 | * The LM90 registers | 116 | * The LM90 registers |
@@ -184,6 +187,7 @@ static const struct i2c_device_id lm90_id[] = { | |||
184 | { "adm1032", adm1032 }, | 187 | { "adm1032", adm1032 }, |
185 | { "adt7461", adt7461 }, | 188 | { "adt7461", adt7461 }, |
186 | { "adt7461a", adt7461 }, | 189 | { "adt7461a", adt7461 }, |
190 | { "g781", g781 }, | ||
187 | { "lm90", lm90 }, | 191 | { "lm90", lm90 }, |
188 | { "lm86", lm86 }, | 192 | { "lm86", lm86 }, |
189 | { "lm89", lm86 }, | 193 | { "lm89", lm86 }, |
@@ -229,6 +233,12 @@ static const struct lm90_params lm90_params[] = { | |||
229 | .alert_alarms = 0x7c, | 233 | .alert_alarms = 0x7c, |
230 | .max_convrate = 10, | 234 | .max_convrate = 10, |
231 | }, | 235 | }, |
236 | [g781] = { | ||
237 | .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | ||
238 | | LM90_HAVE_BROKEN_ALERT, | ||
239 | .alert_alarms = 0x7c, | ||
240 | .max_convrate = 8, | ||
241 | }, | ||
232 | [lm86] = { | 242 | [lm86] = { |
233 | .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, | 243 | .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, |
234 | .alert_alarms = 0x7b, | 244 | .alert_alarms = 0x7b, |
@@ -308,22 +318,24 @@ struct lm90_data { | |||
308 | 318 | ||
309 | /* registers values */ | 319 | /* registers values */ |
310 | s8 temp8[8]; /* 0: local low limit | 320 | s8 temp8[8]; /* 0: local low limit |
311 | 1: local high limit | 321 | * 1: local high limit |
312 | 2: local critical limit | 322 | * 2: local critical limit |
313 | 3: remote critical limit | 323 | * 3: remote critical limit |
314 | 4: local emergency limit (max6659 and max6695/96) | 324 | * 4: local emergency limit (max6659 and max6695/96) |
315 | 5: remote emergency limit (max6659 and max6695/96) | 325 | * 5: remote emergency limit (max6659 and max6695/96) |
316 | 6: remote 2 critical limit (max6695/96 only) | 326 | * 6: remote 2 critical limit (max6695/96 only) |
317 | 7: remote 2 emergency limit (max6695/96 only) */ | 327 | * 7: remote 2 emergency limit (max6695/96 only) |
328 | */ | ||
318 | s16 temp11[8]; /* 0: remote input | 329 | s16 temp11[8]; /* 0: remote input |
319 | 1: remote low limit | 330 | * 1: remote low limit |
320 | 2: remote high limit | 331 | * 2: remote high limit |
321 | 3: remote offset (except max6646, max6657/58/59, | 332 | * 3: remote offset (except max6646, max6657/58/59, |
322 | and max6695/96) | 333 | * and max6695/96) |
323 | 4: local input | 334 | * 4: local input |
324 | 5: remote 2 input (max6695/96 only) | 335 | * 5: remote 2 input (max6695/96 only) |
325 | 6: remote 2 low limit (max6695/96 only) | 336 | * 6: remote 2 low limit (max6695/96 only) |
326 | 7: remote 2 high limit (ma6695/96 only) */ | 337 | * 7: remote 2 high limit (max6695/96 only) |
338 | */ | ||
327 | u8 temp_hyst; | 339 | u8 temp_hyst; |
328 | u16 alarms; /* bitvector (upper 8 bits for max6695/96) */ | 340 | u16 alarms; /* bitvector (upper 8 bits for max6695/96) */ |
329 | }; | 341 | }; |
@@ -533,8 +545,10 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
533 | data->alarms |= alarms << 8; | 545 | data->alarms |= alarms << 8; |
534 | } | 546 | } |
535 | 547 | ||
536 | /* Re-enable ALERT# output if it was originally enabled and | 548 | /* |
537 | * relevant alarms are all clear */ | 549 | * Re-enable ALERT# output if it was originally enabled and |
550 | * relevant alarms are all clear | ||
551 | */ | ||
538 | if ((data->config_orig & 0x80) == 0 | 552 | if ((data->config_orig & 0x80) == 0 |
539 | && (data->alarms & data->alert_alarms) == 0) { | 553 | && (data->alarms & data->alert_alarms) == 0) { |
540 | u8 config; | 554 | u8 config; |
@@ -1162,8 +1176,10 @@ static int lm90_detect(struct i2c_client *client, | |||
1162 | && (config1 & 0x3F) == 0x00 | 1176 | && (config1 & 0x3F) == 0x00 |
1163 | && convrate <= 0x0A) { | 1177 | && convrate <= 0x0A) { |
1164 | name = "adm1032"; | 1178 | name = "adm1032"; |
1165 | /* The ADM1032 supports PEC, but only if combined | 1179 | /* |
1166 | transactions are not used. */ | 1180 | * The ADM1032 supports PEC, but only if combined |
1181 | * transactions are not used. | ||
1182 | */ | ||
1167 | if (i2c_check_functionality(adapter, | 1183 | if (i2c_check_functionality(adapter, |
1168 | I2C_FUNC_SMBUS_BYTE)) | 1184 | I2C_FUNC_SMBUS_BYTE)) |
1169 | info->flags |= I2C_CLIENT_PEC; | 1185 | info->flags |= I2C_CLIENT_PEC; |
@@ -1283,6 +1299,13 @@ static int lm90_detect(struct i2c_client *client, | |||
1283 | && convrate <= 0x09) { | 1299 | && convrate <= 0x09) { |
1284 | name = "sa56004"; | 1300 | name = "sa56004"; |
1285 | } | 1301 | } |
1302 | } else | ||
1303 | if ((address == 0x4C || address == 0x4D) | ||
1304 | && man_id == 0x47) { /* GMT */ | ||
1305 | if (chip_id == 0x01 /* G781 */ | ||
1306 | && (config1 & 0x3F) == 0x00 | ||
1307 | && convrate <= 0x08) | ||
1308 | name = "g781"; | ||
1286 | } | 1309 | } |
1287 | 1310 | ||
1288 | if (!name) { /* identification failed */ | 1311 | if (!name) { /* identification failed */ |
@@ -1313,6 +1336,15 @@ static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) | |||
1313 | sysfs_remove_group(&dev->kobj, &lm90_group); | 1336 | sysfs_remove_group(&dev->kobj, &lm90_group); |
1314 | } | 1337 | } |
1315 | 1338 | ||
1339 | static void lm90_restore_conf(struct i2c_client *client, struct lm90_data *data) | ||
1340 | { | ||
1341 | /* Restore initial configuration */ | ||
1342 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, | ||
1343 | data->convrate_orig); | ||
1344 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, | ||
1345 | data->config_orig); | ||
1346 | } | ||
1347 | |||
1316 | static void lm90_init_client(struct i2c_client *client) | 1348 | static void lm90_init_client(struct i2c_client *client) |
1317 | { | 1349 | { |
1318 | u8 config, convrate; | 1350 | u8 config, convrate; |
@@ -1382,8 +1414,10 @@ static int lm90_probe(struct i2c_client *client, | |||
1382 | client->flags &= ~I2C_CLIENT_PEC; | 1414 | client->flags &= ~I2C_CLIENT_PEC; |
1383 | } | 1415 | } |
1384 | 1416 | ||
1385 | /* Different devices have different alarm bits triggering the | 1417 | /* |
1386 | * ALERT# output */ | 1418 | * Different devices have different alarm bits triggering the |
1419 | * ALERT# output | ||
1420 | */ | ||
1387 | data->alert_alarms = lm90_params[data->kind].alert_alarms; | 1421 | data->alert_alarms = lm90_params[data->kind].alert_alarms; |
1388 | 1422 | ||
1389 | /* Set chip capabilities */ | 1423 | /* Set chip capabilities */ |
@@ -1399,7 +1433,7 @@ static int lm90_probe(struct i2c_client *client, | |||
1399 | /* Register sysfs hooks */ | 1433 | /* Register sysfs hooks */ |
1400 | err = sysfs_create_group(&dev->kobj, &lm90_group); | 1434 | err = sysfs_create_group(&dev->kobj, &lm90_group); |
1401 | if (err) | 1435 | if (err) |
1402 | goto exit_free; | 1436 | goto exit_restore; |
1403 | if (client->flags & I2C_CLIENT_PEC) { | 1437 | if (client->flags & I2C_CLIENT_PEC) { |
1404 | err = device_create_file(dev, &dev_attr_pec); | 1438 | err = device_create_file(dev, &dev_attr_pec); |
1405 | if (err) | 1439 | if (err) |
@@ -1438,7 +1472,8 @@ static int lm90_probe(struct i2c_client *client, | |||
1438 | 1472 | ||
1439 | exit_remove_files: | 1473 | exit_remove_files: |
1440 | lm90_remove_files(client, data); | 1474 | lm90_remove_files(client, data); |
1441 | exit_free: | 1475 | exit_restore: |
1476 | lm90_restore_conf(client, data); | ||
1442 | kfree(data); | 1477 | kfree(data); |
1443 | exit: | 1478 | exit: |
1444 | return err; | 1479 | return err; |
@@ -1450,12 +1485,7 @@ static int lm90_remove(struct i2c_client *client) | |||
1450 | 1485 | ||
1451 | hwmon_device_unregister(data->hwmon_dev); | 1486 | hwmon_device_unregister(data->hwmon_dev); |
1452 | lm90_remove_files(client, data); | 1487 | lm90_remove_files(client, data); |
1453 | 1488 | lm90_restore_conf(client, data); | |
1454 | /* Restore initial configuration */ | ||
1455 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, | ||
1456 | data->convrate_orig); | ||
1457 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, | ||
1458 | data->config_orig); | ||
1459 | 1489 | ||
1460 | kfree(data); | 1490 | kfree(data); |
1461 | return 0; | 1491 | return 0; |
@@ -1488,9 +1518,11 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag) | |||
1488 | dev_warn(&client->dev, | 1518 | dev_warn(&client->dev, |
1489 | "temp%d out of range, please check!\n", 3); | 1519 | "temp%d out of range, please check!\n", 3); |
1490 | 1520 | ||
1491 | /* Disable ALERT# output, because these chips don't implement | 1521 | /* |
1492 | SMBus alert correctly; they should only hold the alert line | 1522 | * Disable ALERT# output, because these chips don't implement |
1493 | low briefly. */ | 1523 | * SMBus alert correctly; they should only hold the alert line |
1524 | * low briefly. | ||
1525 | */ | ||
1494 | if ((data->flags & LM90_HAVE_BROKEN_ALERT) | 1526 | if ((data->flags & LM90_HAVE_BROKEN_ALERT) |
1495 | && (alarms & data->alert_alarms)) { | 1527 | && (alarms & data->alert_alarms)) { |
1496 | dev_dbg(&client->dev, "Disabling ALERT#\n"); | 1528 | dev_dbg(&client->dev, "Disabling ALERT#\n"); |
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c index ef65ab56b094..6c6b240a782e 100644 --- a/drivers/hwmon/mc13783-adc.c +++ b/drivers/hwmon/mc13783-adc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the Freescale Semiconductor MC13783 adc. | 2 | * Driver for the ADC on Freescale Semiconductor MC13783 and MC13892 PMICs. |
3 | * | 3 | * |
4 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | 4 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. |
5 | * Copyright (C) 2009 Sascha Hauer, Pengutronix | 5 | * Copyright (C) 2009 Sascha Hauer, Pengutronix |
@@ -18,7 +18,7 @@ | |||
18 | * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/mfd/mc13783.h> | 21 | #include <linux/mfd/mc13xxx.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/hwmon-sysfs.h> | 23 | #include <linux/hwmon-sysfs.h> |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
@@ -28,24 +28,30 @@ | |||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/err.h> | 29 | #include <linux/err.h> |
30 | 30 | ||
31 | #define MC13783_ADC_NAME "mc13783-adc" | 31 | #define DRIVER_NAME "mc13783-adc" |
32 | |||
33 | /* platform device id driver data */ | ||
34 | #define MC13783_ADC_16CHANS 1 | ||
35 | #define MC13783_ADC_BPDIV2 2 | ||
32 | 36 | ||
33 | struct mc13783_adc_priv { | 37 | struct mc13783_adc_priv { |
34 | struct mc13xxx *mc13xxx; | 38 | struct mc13xxx *mc13xxx; |
35 | struct device *hwmon_dev; | 39 | struct device *hwmon_dev; |
40 | char name[10]; | ||
36 | }; | 41 | }; |
37 | 42 | ||
38 | static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute | 43 | static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute |
39 | *devattr, char *buf) | 44 | *devattr, char *buf) |
40 | { | 45 | { |
41 | return sprintf(buf, "mc13783_adc\n"); | 46 | struct mc13783_adc_priv *priv = dev_get_drvdata(dev); |
47 | |||
48 | return sprintf(buf, "%s\n", priv->name); | ||
42 | } | 49 | } |
43 | 50 | ||
44 | static int mc13783_adc_read(struct device *dev, | 51 | static int mc13783_adc_read(struct device *dev, |
45 | struct device_attribute *devattr, unsigned int *val) | 52 | struct device_attribute *devattr, unsigned int *val) |
46 | { | 53 | { |
47 | struct platform_device *pdev = to_platform_device(dev); | 54 | struct mc13783_adc_priv *priv = dev_get_drvdata(dev); |
48 | struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); | ||
49 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 55 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
50 | unsigned int channel = attr->index; | 56 | unsigned int channel = attr->index; |
51 | unsigned int sample[4]; | 57 | unsigned int sample[4]; |
@@ -68,16 +74,21 @@ static ssize_t mc13783_adc_read_bp(struct device *dev, | |||
68 | struct device_attribute *devattr, char *buf) | 74 | struct device_attribute *devattr, char *buf) |
69 | { | 75 | { |
70 | unsigned val; | 76 | unsigned val; |
77 | struct platform_device *pdev = to_platform_device(dev); | ||
78 | kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; | ||
71 | int ret = mc13783_adc_read(dev, devattr, &val); | 79 | int ret = mc13783_adc_read(dev, devattr, &val); |
72 | 80 | ||
73 | if (ret) | 81 | if (ret) |
74 | return ret; | 82 | return ret; |
75 | 83 | ||
76 | /* | 84 | if (driver_data & MC13783_ADC_BPDIV2) |
77 | * BP (channel 2) reports with offset 2.4V to the actual value to fit | 85 | val = DIV_ROUND_CLOSEST(val * 9, 2); |
78 | * the input range of the ADC. unit = 2.25mV = 9/4 mV. | 86 | else |
79 | */ | 87 | /* |
80 | val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400; | 88 | * BP (channel 2) reports with offset 2.4V to the actual value |
89 | * to fit the input range of the ADC. unit = 2.25mV = 9/4 mV. | ||
90 | */ | ||
91 | val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400; | ||
81 | 92 | ||
82 | return sprintf(buf, "%u\n", val); | 93 | return sprintf(buf, "%u\n", val); |
83 | } | 94 | } |
@@ -114,12 +125,21 @@ static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, mc13783_adc_read_gp, NULL, 13); | |||
114 | static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, mc13783_adc_read_gp, NULL, 14); | 125 | static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, mc13783_adc_read_gp, NULL, 14); |
115 | static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, mc13783_adc_read_gp, NULL, 15); | 126 | static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, mc13783_adc_read_gp, NULL, 15); |
116 | 127 | ||
117 | static struct attribute *mc13783_attr[] = { | 128 | static struct attribute *mc13783_attr_base[] = { |
118 | &dev_attr_name.attr, | 129 | &dev_attr_name.attr, |
119 | &sensor_dev_attr_in2_input.dev_attr.attr, | 130 | &sensor_dev_attr_in2_input.dev_attr.attr, |
120 | &sensor_dev_attr_in5_input.dev_attr.attr, | 131 | &sensor_dev_attr_in5_input.dev_attr.attr, |
121 | &sensor_dev_attr_in6_input.dev_attr.attr, | 132 | &sensor_dev_attr_in6_input.dev_attr.attr, |
122 | &sensor_dev_attr_in7_input.dev_attr.attr, | 133 | &sensor_dev_attr_in7_input.dev_attr.attr, |
134 | NULL | ||
135 | }; | ||
136 | |||
137 | static const struct attribute_group mc13783_group_base = { | ||
138 | .attrs = mc13783_attr_base, | ||
139 | }; | ||
140 | |||
141 | /* these are only used if MC13783_ADC_16CHANS is provided in driver data */ | ||
142 | static struct attribute *mc13783_attr_16chans[] = { | ||
123 | &sensor_dev_attr_in8_input.dev_attr.attr, | 143 | &sensor_dev_attr_in8_input.dev_attr.attr, |
124 | &sensor_dev_attr_in9_input.dev_attr.attr, | 144 | &sensor_dev_attr_in9_input.dev_attr.attr, |
125 | &sensor_dev_attr_in10_input.dev_attr.attr, | 145 | &sensor_dev_attr_in10_input.dev_attr.attr, |
@@ -127,8 +147,8 @@ static struct attribute *mc13783_attr[] = { | |||
127 | NULL | 147 | NULL |
128 | }; | 148 | }; |
129 | 149 | ||
130 | static const struct attribute_group mc13783_group = { | 150 | static const struct attribute_group mc13783_group_16chans = { |
131 | .attrs = mc13783_attr, | 151 | .attrs = mc13783_attr_16chans, |
132 | }; | 152 | }; |
133 | 153 | ||
134 | /* last four channels may be occupied by the touchscreen */ | 154 | /* last four channels may be occupied by the touchscreen */ |
@@ -156,24 +176,37 @@ static int __init mc13783_adc_probe(struct platform_device *pdev) | |||
156 | { | 176 | { |
157 | struct mc13783_adc_priv *priv; | 177 | struct mc13783_adc_priv *priv; |
158 | int ret; | 178 | int ret; |
179 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
180 | char *dash; | ||
159 | 181 | ||
160 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 182 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
161 | if (!priv) | 183 | if (!priv) |
162 | return -ENOMEM; | 184 | return -ENOMEM; |
163 | 185 | ||
164 | priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); | 186 | priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); |
187 | snprintf(priv->name, ARRAY_SIZE(priv->name), "%s", id->name); | ||
188 | dash = strchr(priv->name, '-'); | ||
189 | if (dash) | ||
190 | *dash = '\0'; | ||
165 | 191 | ||
166 | platform_set_drvdata(pdev, priv); | 192 | platform_set_drvdata(pdev, priv); |
167 | 193 | ||
168 | /* Register sysfs hooks */ | 194 | /* Register sysfs hooks */ |
169 | ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group); | 195 | ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_base); |
170 | if (ret) | 196 | if (ret) |
171 | goto out_err_create1; | 197 | goto out_err_create_base; |
198 | |||
199 | if (id->driver_data & MC13783_ADC_16CHANS) { | ||
200 | ret = sysfs_create_group(&pdev->dev.kobj, | ||
201 | &mc13783_group_16chans); | ||
202 | if (ret) | ||
203 | goto out_err_create_16chans; | ||
204 | } | ||
172 | 205 | ||
173 | if (!mc13783_adc_use_touchscreen(pdev)) { | 206 | if (!mc13783_adc_use_touchscreen(pdev)) { |
174 | ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts); | 207 | ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts); |
175 | if (ret) | 208 | if (ret) |
176 | goto out_err_create2; | 209 | goto out_err_create_ts; |
177 | } | 210 | } |
178 | 211 | ||
179 | priv->hwmon_dev = hwmon_device_register(&pdev->dev); | 212 | priv->hwmon_dev = hwmon_device_register(&pdev->dev); |
@@ -184,17 +217,20 @@ static int __init mc13783_adc_probe(struct platform_device *pdev) | |||
184 | goto out_err_register; | 217 | goto out_err_register; |
185 | } | 218 | } |
186 | 219 | ||
187 | |||
188 | return 0; | 220 | return 0; |
189 | 221 | ||
190 | out_err_register: | 222 | out_err_register: |
191 | 223 | ||
192 | if (!mc13783_adc_use_touchscreen(pdev)) | 224 | if (!mc13783_adc_use_touchscreen(pdev)) |
193 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); | 225 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); |
194 | out_err_create2: | 226 | out_err_create_ts: |
195 | 227 | ||
196 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group); | 228 | if (id->driver_data & MC13783_ADC_16CHANS) |
197 | out_err_create1: | 229 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans); |
230 | out_err_create_16chans: | ||
231 | |||
232 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); | ||
233 | out_err_create_base: | ||
198 | 234 | ||
199 | platform_set_drvdata(pdev, NULL); | 235 | platform_set_drvdata(pdev, NULL); |
200 | kfree(priv); | 236 | kfree(priv); |
@@ -205,13 +241,17 @@ out_err_create1: | |||
205 | static int __devexit mc13783_adc_remove(struct platform_device *pdev) | 241 | static int __devexit mc13783_adc_remove(struct platform_device *pdev) |
206 | { | 242 | { |
207 | struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); | 243 | struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); |
244 | kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; | ||
208 | 245 | ||
209 | hwmon_device_unregister(priv->hwmon_dev); | 246 | hwmon_device_unregister(priv->hwmon_dev); |
210 | 247 | ||
211 | if (!mc13783_adc_use_touchscreen(pdev)) | 248 | if (!mc13783_adc_use_touchscreen(pdev)) |
212 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); | 249 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); |
213 | 250 | ||
214 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group); | 251 | if (driver_data & MC13783_ADC_16CHANS) |
252 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans); | ||
253 | |||
254 | sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); | ||
215 | 255 | ||
216 | platform_set_drvdata(pdev, NULL); | 256 | platform_set_drvdata(pdev, NULL); |
217 | kfree(priv); | 257 | kfree(priv); |
@@ -219,12 +259,26 @@ static int __devexit mc13783_adc_remove(struct platform_device *pdev) | |||
219 | return 0; | 259 | return 0; |
220 | } | 260 | } |
221 | 261 | ||
262 | static const struct platform_device_id mc13783_adc_idtable[] = { | ||
263 | { | ||
264 | .name = "mc13783-adc", | ||
265 | .driver_data = MC13783_ADC_16CHANS, | ||
266 | }, { | ||
267 | .name = "mc13892-adc", | ||
268 | .driver_data = MC13783_ADC_BPDIV2, | ||
269 | }, { | ||
270 | /* sentinel */ | ||
271 | } | ||
272 | }; | ||
273 | MODULE_DEVICE_TABLE(platform, mc13783_adc_idtable); | ||
274 | |||
222 | static struct platform_driver mc13783_adc_driver = { | 275 | static struct platform_driver mc13783_adc_driver = { |
223 | .remove = __devexit_p(mc13783_adc_remove), | 276 | .remove = __devexit_p(mc13783_adc_remove), |
224 | .driver = { | 277 | .driver = { |
225 | .owner = THIS_MODULE, | 278 | .owner = THIS_MODULE, |
226 | .name = MC13783_ADC_NAME, | 279 | .name = DRIVER_NAME, |
227 | }, | 280 | }, |
281 | .id_table = mc13783_adc_idtable, | ||
228 | }; | 282 | }; |
229 | 283 | ||
230 | static int __init mc13783_adc_init(void) | 284 | static int __init mc13783_adc_init(void) |
@@ -243,4 +297,3 @@ module_exit(mc13783_adc_exit); | |||
243 | MODULE_DESCRIPTION("MC13783 ADC driver"); | 297 | MODULE_DESCRIPTION("MC13783 ADC driver"); |
244 | MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); | 298 | MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); |
245 | MODULE_LICENSE("GPL"); | 299 | MODULE_LICENSE("GPL"); |
246 | MODULE_ALIAS("platform:" MC13783_ADC_NAME); | ||
diff --git a/drivers/hwmon/mcp3021.c b/drivers/hwmon/mcp3021.c new file mode 100644 index 000000000000..d0afc0cd3ff4 --- /dev/null +++ b/drivers/hwmon/mcp3021.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * mcp3021.c - driver for the Microchip MCP3021 chip | ||
3 | * | ||
4 | * Copyright (C) 2008-2009, 2012 Freescale Semiconductor, Inc. | ||
5 | * Author: Mingkai Hu <Mingkai.hu@freescale.com> | ||
6 | * | ||
7 | * This driver export the value of analog input voltage to sysfs, the | ||
8 | * voltage unit is mV. Through the sysfs interface, lm-sensors tool | ||
9 | * can also display the input voltage. | ||
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 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/hwmon.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/device.h> | ||
24 | |||
25 | /* Vdd info */ | ||
26 | #define MCP3021_VDD_MAX 5500 | ||
27 | #define MCP3021_VDD_MIN 2700 | ||
28 | #define MCP3021_VDD_REF 3300 | ||
29 | |||
30 | /* output format */ | ||
31 | #define MCP3021_SAR_SHIFT 2 | ||
32 | #define MCP3021_SAR_MASK 0x3ff | ||
33 | |||
34 | #define MCP3021_OUTPUT_RES 10 /* 10-bit resolution */ | ||
35 | #define MCP3021_OUTPUT_SCALE 4 | ||
36 | |||
37 | /* | ||
38 | * Client data (each client gets its own) | ||
39 | */ | ||
40 | struct mcp3021_data { | ||
41 | struct device *hwmon_dev; | ||
42 | u32 vdd; /* device power supply */ | ||
43 | }; | ||
44 | |||
45 | static int mcp3021_read16(struct i2c_client *client) | ||
46 | { | ||
47 | int ret; | ||
48 | u16 reg; | ||
49 | __be16 buf; | ||
50 | |||
51 | ret = i2c_master_recv(client, (char *)&buf, 2); | ||
52 | if (ret < 0) | ||
53 | return ret; | ||
54 | if (ret != 2) | ||
55 | return -EIO; | ||
56 | |||
57 | /* The output code of the MCP3021 is transmitted with MSB first. */ | ||
58 | reg = be16_to_cpu(buf); | ||
59 | |||
60 | /* | ||
61 | * The ten-bit output code is composed of the lower 4-bit of the | ||
62 | * first byte and the upper 6-bit of the second byte. | ||
63 | */ | ||
64 | reg = (reg >> MCP3021_SAR_SHIFT) & MCP3021_SAR_MASK; | ||
65 | |||
66 | return reg; | ||
67 | } | ||
68 | |||
69 | static inline u16 volts_from_reg(u16 vdd, u16 val) | ||
70 | { | ||
71 | if (val == 0) | ||
72 | return 0; | ||
73 | |||
74 | val = val * MCP3021_OUTPUT_SCALE - MCP3021_OUTPUT_SCALE / 2; | ||
75 | |||
76 | return val * DIV_ROUND_CLOSEST(vdd, | ||
77 | (1 << MCP3021_OUTPUT_RES) * MCP3021_OUTPUT_SCALE); | ||
78 | } | ||
79 | |||
80 | static ssize_t show_in_input(struct device *dev, struct device_attribute *attr, | ||
81 | char *buf) | ||
82 | { | ||
83 | struct i2c_client *client = to_i2c_client(dev); | ||
84 | struct mcp3021_data *data = i2c_get_clientdata(client); | ||
85 | int reg, in_input; | ||
86 | |||
87 | reg = mcp3021_read16(client); | ||
88 | if (reg < 0) | ||
89 | return reg; | ||
90 | |||
91 | in_input = volts_from_reg(data->vdd, reg); | ||
92 | return sprintf(buf, "%d\n", in_input); | ||
93 | } | ||
94 | |||
95 | static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input, NULL); | ||
96 | |||
97 | static int mcp3021_probe(struct i2c_client *client, | ||
98 | const struct i2c_device_id *id) | ||
99 | { | ||
100 | int err; | ||
101 | struct mcp3021_data *data = NULL; | ||
102 | |||
103 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
104 | return -ENODEV; | ||
105 | |||
106 | data = kzalloc(sizeof(struct mcp3021_data), GFP_KERNEL); | ||
107 | if (!data) | ||
108 | return -ENOMEM; | ||
109 | |||
110 | i2c_set_clientdata(client, data); | ||
111 | |||
112 | if (client->dev.platform_data) { | ||
113 | data->vdd = *(u32 *)client->dev.platform_data; | ||
114 | if (data->vdd > MCP3021_VDD_MAX || | ||
115 | data->vdd < MCP3021_VDD_MIN) { | ||
116 | err = -EINVAL; | ||
117 | goto exit_free; | ||
118 | } | ||
119 | } else | ||
120 | data->vdd = MCP3021_VDD_REF; | ||
121 | |||
122 | err = sysfs_create_file(&client->dev.kobj, &dev_attr_in0_input.attr); | ||
123 | if (err) | ||
124 | goto exit_free; | ||
125 | |||
126 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
127 | if (IS_ERR(data->hwmon_dev)) { | ||
128 | err = PTR_ERR(data->hwmon_dev); | ||
129 | goto exit_remove; | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | |||
134 | exit_remove: | ||
135 | sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr); | ||
136 | exit_free: | ||
137 | kfree(data); | ||
138 | return err; | ||
139 | } | ||
140 | |||
141 | static int mcp3021_remove(struct i2c_client *client) | ||
142 | { | ||
143 | struct mcp3021_data *data = i2c_get_clientdata(client); | ||
144 | |||
145 | hwmon_device_unregister(data->hwmon_dev); | ||
146 | sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr); | ||
147 | kfree(data); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static const struct i2c_device_id mcp3021_id[] = { | ||
153 | { "mcp3021", 0 }, | ||
154 | { } | ||
155 | }; | ||
156 | MODULE_DEVICE_TABLE(i2c, mcp3021_id); | ||
157 | |||
158 | static struct i2c_driver mcp3021_driver = { | ||
159 | .driver = { | ||
160 | .name = "mcp3021", | ||
161 | }, | ||
162 | .probe = mcp3021_probe, | ||
163 | .remove = mcp3021_remove, | ||
164 | .id_table = mcp3021_id, | ||
165 | }; | ||
166 | |||
167 | module_i2c_driver(mcp3021_driver); | ||
168 | |||
169 | MODULE_AUTHOR("Mingkai Hu <Mingkai.hu@freescale.com>"); | ||
170 | MODULE_DESCRIPTION("Microchip MCP3021 driver"); | ||
171 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index deb12c982800..d887cb3b72e8 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c | |||
@@ -72,8 +72,10 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); | |||
72 | #define TEMP_CRIT_HYST 2 | 72 | #define TEMP_CRIT_HYST 2 |
73 | #define TEMP_WARN 3 | 73 | #define TEMP_WARN 3 |
74 | #define TEMP_WARN_HYST 4 | 74 | #define TEMP_WARN_HYST 4 |
75 | /* only crit and crit_hyst affect real-time alarm status | 75 | /* |
76 | * current crit crit_hyst warn warn_hyst */ | 76 | * only crit and crit_hyst affect real-time alarm status |
77 | * current crit crit_hyst warn warn_hyst | ||
78 | */ | ||
77 | static const u16 W83795_REG_TEMP[][5] = { | 79 | static const u16 W83795_REG_TEMP[][5] = { |
78 | {0x21, 0x96, 0x97, 0x98, 0x99}, /* TD1/TR1 */ | 80 | {0x21, 0x96, 0x97, 0x98, 0x99}, /* TD1/TR1 */ |
79 | {0x22, 0x9a, 0x9b, 0x9c, 0x9d}, /* TD2/TR2 */ | 81 | {0x22, 0x9a, 0x9b, 0x9c, 0x9d}, /* TD2/TR2 */ |
@@ -354,26 +356,34 @@ struct w83795_data { | |||
354 | u8 temp_mode; /* Bit vector, 0 = TR, 1 = TD */ | 356 | u8 temp_mode; /* Bit vector, 0 = TR, 1 = TD */ |
355 | u8 temp_src[3]; /* Register value */ | 357 | u8 temp_src[3]; /* Register value */ |
356 | 358 | ||
357 | u8 enable_dts; /* Enable PECI and SB-TSI, | 359 | u8 enable_dts; /* |
360 | * Enable PECI and SB-TSI, | ||
358 | * bit 0: =1 enable, =0 disable, | 361 | * bit 0: =1 enable, =0 disable, |
359 | * bit 1: =1 AMD SB-TSI, =0 Intel PECI */ | 362 | * bit 1: =1 AMD SB-TSI, =0 Intel PECI |
363 | */ | ||
360 | u8 has_dts; /* Enable monitor DTS temp */ | 364 | u8 has_dts; /* Enable monitor DTS temp */ |
361 | s8 dts[8]; /* Register value */ | 365 | s8 dts[8]; /* Register value */ |
362 | u8 dts_read_vrlsb[8]; /* Register value */ | 366 | u8 dts_read_vrlsb[8]; /* Register value */ |
363 | s8 dts_ext[4]; /* Register value */ | 367 | s8 dts_ext[4]; /* Register value */ |
364 | 368 | ||
365 | u8 has_pwm; /* 795g supports 8 pwm, 795adg only supports 2, | 369 | u8 has_pwm; /* |
370 | * 795g supports 8 pwm, 795adg only supports 2, | ||
366 | * no config register, only affected by chip | 371 | * no config register, only affected by chip |
367 | * type */ | 372 | * type |
368 | u8 pwm[8][5]; /* Register value, output, freq, start, | 373 | */ |
369 | * non stop, stop time */ | 374 | u8 pwm[8][5]; /* |
375 | * Register value, output, freq, start, | ||
376 | * non stop, stop time | ||
377 | */ | ||
370 | u16 clkin; /* CLKIN frequency in kHz */ | 378 | u16 clkin; /* CLKIN frequency in kHz */ |
371 | u8 pwm_fcms[2]; /* Register value */ | 379 | u8 pwm_fcms[2]; /* Register value */ |
372 | u8 pwm_tfmr[6]; /* Register value */ | 380 | u8 pwm_tfmr[6]; /* Register value */ |
373 | u8 pwm_fomc; /* Register value */ | 381 | u8 pwm_fomc; /* Register value */ |
374 | 382 | ||
375 | u16 target_speed[8]; /* Register value, target speed for speed | 383 | u16 target_speed[8]; /* |
376 | * cruise */ | 384 | * Register value, target speed for speed |
385 | * cruise | ||
386 | */ | ||
377 | u8 tol_speed; /* tolerance of target speed */ | 387 | u8 tol_speed; /* tolerance of target speed */ |
378 | u8 pwm_temp[6][4]; /* TTTI, CTFS, HCT, HOT */ | 388 | u8 pwm_temp[6][4]; /* TTTI, CTFS, HCT, HOT */ |
379 | u8 sf4_reg[6][2][7]; /* 6 temp, temp/dcpwm, 7 registers */ | 389 | u8 sf4_reg[6][2][7]; /* 6 temp, temp/dcpwm, 7 registers */ |
@@ -482,8 +492,10 @@ static void w83795_update_limits(struct i2c_client *client) | |||
482 | /* Read the fan limits */ | 492 | /* Read the fan limits */ |
483 | lsb = 0; /* Silent false gcc warning */ | 493 | lsb = 0; /* Silent false gcc warning */ |
484 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { | 494 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { |
485 | /* Each register contains LSB for 2 fans, but we want to | 495 | /* |
486 | * read it only once to save time */ | 496 | * Each register contains LSB for 2 fans, but we want to |
497 | * read it only once to save time | ||
498 | */ | ||
487 | if ((i & 1) == 0 && (data->has_fan & (3 << i))) | 499 | if ((i & 1) == 0 && (data->has_fan & (3 << i))) |
488 | lsb = w83795_read(client, W83795_REG_FAN_MIN_LSB(i)); | 500 | lsb = w83795_read(client, W83795_REG_FAN_MIN_LSB(i)); |
489 | 501 | ||
@@ -665,9 +677,11 @@ static struct w83795_data *w83795_update_device(struct device *dev) | |||
665 | w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); | 677 | w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); |
666 | } | 678 | } |
667 | 679 | ||
668 | /* Update intrusion and alarms | 680 | /* |
681 | * Update intrusion and alarms | ||
669 | * It is important to read intrusion first, because reading from | 682 | * It is important to read intrusion first, because reading from |
670 | * register SMI STS6 clears the interrupt status temporarily. */ | 683 | * register SMI STS6 clears the interrupt status temporarily. |
684 | */ | ||
671 | tmp = w83795_read(client, W83795_REG_ALARM_CTRL); | 685 | tmp = w83795_read(client, W83795_REG_ALARM_CTRL); |
672 | /* Switch to interrupt status for intrusion if needed */ | 686 | /* Switch to interrupt status for intrusion if needed */ |
673 | if (tmp & ALARM_CTRL_RTSACS) | 687 | if (tmp & ALARM_CTRL_RTSACS) |
@@ -929,6 +943,14 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
929 | if (val < 1 || val > 2) | 943 | if (val < 1 || val > 2) |
930 | return -EINVAL; | 944 | return -EINVAL; |
931 | 945 | ||
946 | #ifndef CONFIG_SENSORS_W83795_FANCTRL | ||
947 | if (val > 1) { | ||
948 | dev_warn(dev, "Automatic fan speed control support disabled\n"); | ||
949 | dev_warn(dev, "Build with CONFIG_SENSORS_W83795_FANCTRL=y if you want it\n"); | ||
950 | return -EOPNOTSUPP; | ||
951 | } | ||
952 | #endif | ||
953 | |||
932 | mutex_lock(&data->update_lock); | 954 | mutex_lock(&data->update_lock); |
933 | switch (val) { | 955 | switch (val) { |
934 | case 1: | 956 | case 1: |
@@ -1595,8 +1617,10 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1595 | 1617 | ||
1596 | #define NOT_USED -1 | 1618 | #define NOT_USED -1 |
1597 | 1619 | ||
1598 | /* Don't change the attribute order, _max, _min and _beep are accessed by index | 1620 | /* |
1599 | * somewhere else in the code */ | 1621 | * Don't change the attribute order, _max, _min and _beep are accessed by index |
1622 | * somewhere else in the code | ||
1623 | */ | ||
1600 | #define SENSOR_ATTR_IN(index) { \ | 1624 | #define SENSOR_ATTR_IN(index) { \ |
1601 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ | 1625 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ |
1602 | IN_READ, index), \ | 1626 | IN_READ, index), \ |
@@ -1610,8 +1634,10 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1610 | show_alarm_beep, store_beep, BEEP_ENABLE, \ | 1634 | show_alarm_beep, store_beep, BEEP_ENABLE, \ |
1611 | index + ((index > 14) ? 1 : 0)) } | 1635 | index + ((index > 14) ? 1 : 0)) } |
1612 | 1636 | ||
1613 | /* Don't change the attribute order, _beep is accessed by index | 1637 | /* |
1614 | * somewhere else in the code */ | 1638 | * Don't change the attribute order, _beep is accessed by index |
1639 | * somewhere else in the code | ||
1640 | */ | ||
1615 | #define SENSOR_ATTR_FAN(index) { \ | 1641 | #define SENSOR_ATTR_FAN(index) { \ |
1616 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ | 1642 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ |
1617 | NULL, FAN_INPUT, index - 1), \ | 1643 | NULL, FAN_INPUT, index - 1), \ |
@@ -1625,23 +1651,25 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1625 | #define SENSOR_ATTR_PWM(index) { \ | 1651 | #define SENSOR_ATTR_PWM(index) { \ |
1626 | SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm, \ | 1652 | SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm, \ |
1627 | store_pwm, PWM_OUTPUT, index - 1), \ | 1653 | store_pwm, PWM_OUTPUT, index - 1), \ |
1654 | SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ | ||
1655 | show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ | ||
1656 | SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO, \ | ||
1657 | show_pwm_mode, NULL, NOT_USED, index - 1), \ | ||
1658 | SENSOR_ATTR_2(pwm##index##_freq, S_IWUSR | S_IRUGO, \ | ||
1659 | show_pwm, store_pwm, PWM_FREQ, index - 1), \ | ||
1628 | SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO, \ | 1660 | SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO, \ |
1629 | show_pwm, store_pwm, PWM_NONSTOP, index - 1), \ | 1661 | show_pwm, store_pwm, PWM_NONSTOP, index - 1), \ |
1630 | SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO, \ | 1662 | SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO, \ |
1631 | show_pwm, store_pwm, PWM_START, index - 1), \ | 1663 | show_pwm, store_pwm, PWM_START, index - 1), \ |
1632 | SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO, \ | 1664 | SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO, \ |
1633 | show_pwm, store_pwm, PWM_STOP_TIME, index - 1), \ | 1665 | show_pwm, store_pwm, PWM_STOP_TIME, index - 1), \ |
1634 | SENSOR_ATTR_2(pwm##index##_freq, S_IWUSR | S_IRUGO, \ | ||
1635 | show_pwm, store_pwm, PWM_FREQ, index - 1), \ | ||
1636 | SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ | ||
1637 | show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ | ||
1638 | SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO, \ | ||
1639 | show_pwm_mode, NULL, NOT_USED, index - 1), \ | ||
1640 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ | 1666 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ |
1641 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } | 1667 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } |
1642 | 1668 | ||
1643 | /* Don't change the attribute order, _beep is accessed by index | 1669 | /* |
1644 | * somewhere else in the code */ | 1670 | * Don't change the attribute order, _beep is accessed by index |
1671 | * somewhere else in the code | ||
1672 | */ | ||
1645 | #define SENSOR_ATTR_DTS(index) { \ | 1673 | #define SENSOR_ATTR_DTS(index) { \ |
1646 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ | 1674 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ |
1647 | show_dts_mode, NULL, NOT_USED, index - 7), \ | 1675 | show_dts_mode, NULL, NOT_USED, index - 7), \ |
@@ -1660,8 +1688,10 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
1660 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ | 1688 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ |
1661 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } | 1689 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } |
1662 | 1690 | ||
1663 | /* Don't change the attribute order, _beep is accessed by index | 1691 | /* |
1664 | * somewhere else in the code */ | 1692 | * Don't change the attribute order, _beep is accessed by index |
1693 | * somewhere else in the code | ||
1694 | */ | ||
1665 | #define SENSOR_ATTR_TEMP(index) { \ | 1695 | #define SENSOR_ATTR_TEMP(index) { \ |
1666 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ | 1696 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ |
1667 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ | 1697 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ |
@@ -1867,8 +1897,10 @@ static int w83795_get_device_id(struct i2c_client *client) | |||
1867 | 1897 | ||
1868 | device_id = i2c_smbus_read_byte_data(client, W83795_REG_DEVICEID); | 1898 | device_id = i2c_smbus_read_byte_data(client, W83795_REG_DEVICEID); |
1869 | 1899 | ||
1870 | /* Special case for rev. A chips; can't be checked first because later | 1900 | /* |
1871 | revisions emulate this for compatibility */ | 1901 | * Special case for rev. A chips; can't be checked first because later |
1902 | * revisions emulate this for compatibility | ||
1903 | */ | ||
1872 | if (device_id < 0 || (device_id & 0xf0) != 0x50) { | 1904 | if (device_id < 0 || (device_id & 0xf0) != 0x50) { |
1873 | int alt_id; | 1905 | int alt_id; |
1874 | 1906 | ||
@@ -1920,8 +1952,10 @@ static int w83795_detect(struct i2c_client *client, | |||
1920 | return -ENODEV; | 1952 | return -ENODEV; |
1921 | } | 1953 | } |
1922 | 1954 | ||
1923 | /* If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR | 1955 | /* |
1924 | should match */ | 1956 | * If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR |
1957 | * should match | ||
1958 | */ | ||
1925 | if ((bank & 0x07) == 0) { | 1959 | if ((bank & 0x07) == 0) { |
1926 | i2c_addr = i2c_smbus_read_byte_data(client, | 1960 | i2c_addr = i2c_smbus_read_byte_data(client, |
1927 | W83795_REG_I2C_ADDR); | 1961 | W83795_REG_I2C_ADDR); |
@@ -1933,10 +1967,12 @@ static int w83795_detect(struct i2c_client *client, | |||
1933 | } | 1967 | } |
1934 | } | 1968 | } |
1935 | 1969 | ||
1936 | /* Check 795 chip type: 795G or 795ADG | 1970 | /* |
1937 | Usually we don't write to chips during detection, but here we don't | 1971 | * Check 795 chip type: 795G or 795ADG |
1938 | quite have the choice; hopefully it's OK, we are about to return | 1972 | * Usually we don't write to chips during detection, but here we don't |
1939 | success anyway */ | 1973 | * quite have the choice; hopefully it's OK, we are about to return |
1974 | * success anyway | ||
1975 | */ | ||
1940 | if ((bank & 0x07) != 0) | 1976 | if ((bank & 0x07) != 0) |
1941 | i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, | 1977 | i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, |
1942 | bank & ~0x07); | 1978 | bank & ~0x07); |
@@ -1953,6 +1989,14 @@ static int w83795_detect(struct i2c_client *client, | |||
1953 | return 0; | 1989 | return 0; |
1954 | } | 1990 | } |
1955 | 1991 | ||
1992 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | ||
1993 | #define NUM_PWM_ATTRIBUTES ARRAY_SIZE(w83795_pwm[0]) | ||
1994 | #define NUM_TEMP_ATTRIBUTES ARRAY_SIZE(w83795_temp[0]) | ||
1995 | #else | ||
1996 | #define NUM_PWM_ATTRIBUTES 4 | ||
1997 | #define NUM_TEMP_ATTRIBUTES 8 | ||
1998 | #endif | ||
1999 | |||
1956 | static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | 2000 | static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, |
1957 | const struct device_attribute *)) | 2001 | const struct device_attribute *)) |
1958 | { | 2002 | { |
@@ -2006,24 +2050,18 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | |||
2006 | } | 2050 | } |
2007 | } | 2051 | } |
2008 | 2052 | ||
2009 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | ||
2010 | for (i = 0; i < data->has_pwm; i++) { | 2053 | for (i = 0; i < data->has_pwm; i++) { |
2011 | for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) { | 2054 | for (j = 0; j < NUM_PWM_ATTRIBUTES; j++) { |
2012 | err = fn(dev, &w83795_pwm[i][j].dev_attr); | 2055 | err = fn(dev, &w83795_pwm[i][j].dev_attr); |
2013 | if (err) | 2056 | if (err) |
2014 | return err; | 2057 | return err; |
2015 | } | 2058 | } |
2016 | } | 2059 | } |
2017 | #endif | ||
2018 | 2060 | ||
2019 | for (i = 0; i < ARRAY_SIZE(w83795_temp); i++) { | 2061 | for (i = 0; i < ARRAY_SIZE(w83795_temp); i++) { |
2020 | if (!(data->has_temp & (1 << i))) | 2062 | if (!(data->has_temp & (1 << i))) |
2021 | continue; | 2063 | continue; |
2022 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 2064 | for (j = 0; j < NUM_TEMP_ATTRIBUTES; j++) { |
2023 | for (j = 0; j < ARRAY_SIZE(w83795_temp[0]); j++) { | ||
2024 | #else | ||
2025 | for (j = 0; j < 8; j++) { | ||
2026 | #endif | ||
2027 | if (j == 7 && !data->enable_beep) | 2065 | if (j == 7 && !data->enable_beep) |
2028 | continue; | 2066 | continue; |
2029 | err = fn(dev, &w83795_temp[i][j].dev_attr); | 2067 | err = fn(dev, &w83795_temp[i][j].dev_attr); |
@@ -2183,8 +2221,10 @@ static int w83795_probe(struct i2c_client *client, | |||
2183 | /* The W83795G has a dedicated BEEP pin */ | 2221 | /* The W83795G has a dedicated BEEP pin */ |
2184 | data->enable_beep = 1; | 2222 | data->enable_beep = 1; |
2185 | } else { | 2223 | } else { |
2186 | /* The W83795ADG has a shared pin for OVT# and BEEP, so you | 2224 | /* |
2187 | * can't have both */ | 2225 | * The W83795ADG has a shared pin for OVT# and BEEP, so you |
2226 | * can't have both | ||
2227 | */ | ||
2188 | tmp = w83795_read(client, W83795_REG_OVT_CFG); | 2228 | tmp = w83795_read(client, W83795_REG_OVT_CFG); |
2189 | if ((tmp & OVT_CFG_SEL) == 0) | 2229 | if ((tmp & OVT_CFG_SEL) == 0) |
2190 | data->enable_beep = 1; | 2230 | data->enable_beep = 1; |