diff options
author | Anton Vorontsov <cbouatmailru@gmail.com> | 2012-01-04 00:09:35 -0500 |
---|---|---|
committer | Anton Vorontsov <cbouatmailru@gmail.com> | 2012-01-04 00:09:35 -0500 |
commit | 251f39fe42dae863bd24e30864e6b66076ba076d (patch) | |
tree | c804944bc17f3836d19cc8b5bc611dd1fb0ea915 /drivers/hwmon | |
parent | 9b8872273af6983b246252a6508fa7cf34c69d6e (diff) | |
parent | 35b4c01e29bdd9632dabf9784ed3486333f00427 (diff) |
Merge branch 'power-supply-scope' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen
Diffstat (limited to 'drivers/hwmon')
46 files changed, 2438 insertions, 780 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 0b62c3c6b7ce..9ec854ae118b 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -68,6 +68,16 @@ config SENSORS_ABITUGURU3 | |||
68 | This driver can also be built as a module. If so, the module | 68 | This driver can also be built as a module. If so, the module |
69 | will be called abituguru3. | 69 | will be called abituguru3. |
70 | 70 | ||
71 | config SENSORS_AD7314 | ||
72 | tristate "Analog Devices AD7314 and compatibles" | ||
73 | depends on SPI && EXPERIMENTAL | ||
74 | help | ||
75 | If you say yes here you get support for the Analog Devices | ||
76 | AD7314, ADT7301 and ADT7302 temperature sensors. | ||
77 | |||
78 | This driver can also be built as a module. If so, the module | ||
79 | will be called ad7314. | ||
80 | |||
71 | config SENSORS_AD7414 | 81 | config SENSORS_AD7414 |
72 | tristate "Analog Devices AD7414" | 82 | tristate "Analog Devices AD7414" |
73 | depends on I2C && EXPERIMENTAL | 83 | depends on I2C && EXPERIMENTAL |
@@ -303,6 +313,16 @@ config SENSORS_DS1621 | |||
303 | This driver can also be built as a module. If so, the module | 313 | This driver can also be built as a module. If so, the module |
304 | will be called ds1621. | 314 | will be called ds1621. |
305 | 315 | ||
316 | config SENSORS_EXYNOS4_TMU | ||
317 | tristate "Temperature sensor on Samsung EXYNOS4" | ||
318 | depends on EXYNOS4_DEV_TMU | ||
319 | help | ||
320 | If you say yes here you get support for TMU (Thermal Managment | ||
321 | Unit) on SAMSUNG EXYNOS4 series of SoC. | ||
322 | |||
323 | This driver can also be built as a module. If so, the module | ||
324 | will be called exynos4-tmu. | ||
325 | |||
306 | config SENSORS_I5K_AMB | 326 | config SENSORS_I5K_AMB |
307 | tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets" | 327 | tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets" |
308 | depends on PCI && EXPERIMENTAL | 328 | depends on PCI && EXPERIMENTAL |
@@ -315,6 +335,7 @@ config SENSORS_I5K_AMB | |||
315 | 335 | ||
316 | config SENSORS_F71805F | 336 | config SENSORS_F71805F |
317 | tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG" | 337 | tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG" |
338 | depends on !PPC | ||
318 | help | 339 | help |
319 | If you say yes here you get support for hardware monitoring | 340 | If you say yes here you get support for hardware monitoring |
320 | features of the Fintek F71805F/FG, F71806F/FG and F71872F/FG | 341 | features of the Fintek F71805F/FG, F71806F/FG and F71872F/FG |
@@ -325,6 +346,7 @@ config SENSORS_F71805F | |||
325 | 346 | ||
326 | config SENSORS_F71882FG | 347 | config SENSORS_F71882FG |
327 | tristate "Fintek F71882FG and compatibles" | 348 | tristate "Fintek F71882FG and compatibles" |
349 | depends on !PPC | ||
328 | help | 350 | help |
329 | If you say yes here you get support for hardware monitoring | 351 | If you say yes here you get support for hardware monitoring |
330 | features of many Fintek Super-I/O (LPC) chips. The currently | 352 | features of many Fintek Super-I/O (LPC) chips. The currently |
@@ -448,6 +470,7 @@ config SENSORS_IBMPEX | |||
448 | 470 | ||
449 | config SENSORS_IT87 | 471 | config SENSORS_IT87 |
450 | tristate "ITE IT87xx and compatibles" | 472 | tristate "ITE IT87xx and compatibles" |
473 | depends on !PPC | ||
451 | select HWMON_VID | 474 | select HWMON_VID |
452 | help | 475 | help |
453 | If you say yes here you get support for ITE IT8705F, IT8712F, | 476 | If you say yes here you get support for ITE IT8705F, IT8712F, |
@@ -531,6 +554,7 @@ config SENSORS_LM75 | |||
531 | If you say yes here you get support for one common type of | 554 | If you say yes here you get support for one common type of |
532 | temperature sensor chip, with models including: | 555 | temperature sensor chip, with models including: |
533 | 556 | ||
557 | - Analog Devices ADT75 | ||
534 | - Dallas Semiconductor DS75 and DS1775 | 558 | - Dallas Semiconductor DS75 and DS1775 |
535 | - Maxim MAX6625 and MAX6626 | 559 | - Maxim MAX6625 and MAX6626 |
536 | - Microchip MCP980x | 560 | - Microchip MCP980x |
@@ -803,6 +827,7 @@ config SENSORS_NTC_THERMISTOR | |||
803 | 827 | ||
804 | config SENSORS_PC87360 | 828 | config SENSORS_PC87360 |
805 | tristate "National Semiconductor PC87360 family" | 829 | tristate "National Semiconductor PC87360 family" |
830 | depends on !PPC | ||
806 | select HWMON_VID | 831 | select HWMON_VID |
807 | help | 832 | help |
808 | If you say yes here you get access to the hardware monitoring | 833 | If you say yes here you get access to the hardware monitoring |
@@ -816,6 +841,7 @@ config SENSORS_PC87360 | |||
816 | 841 | ||
817 | config SENSORS_PC87427 | 842 | config SENSORS_PC87427 |
818 | tristate "National Semiconductor PC87427" | 843 | tristate "National Semiconductor PC87427" |
844 | depends on !PPC | ||
819 | help | 845 | help |
820 | If you say yes here you get access to the hardware monitoring | 846 | If you say yes here you get access to the hardware monitoring |
821 | functions of the National Semiconductor PC87427 Super-I/O chip. | 847 | functions of the National Semiconductor PC87427 Super-I/O chip. |
@@ -907,7 +933,7 @@ config SENSORS_SMM665 | |||
907 | 933 | ||
908 | config SENSORS_DME1737 | 934 | config SENSORS_DME1737 |
909 | tristate "SMSC DME1737, SCH311x and compatibles" | 935 | tristate "SMSC DME1737, SCH311x and compatibles" |
910 | depends on I2C && EXPERIMENTAL | 936 | depends on I2C && EXPERIMENTAL && !PPC |
911 | select HWMON_VID | 937 | select HWMON_VID |
912 | help | 938 | help |
913 | If you say yes here you get support for the hardware monitoring | 939 | If you say yes here you get support for the hardware monitoring |
@@ -949,6 +975,7 @@ config SENSORS_EMC6W201 | |||
949 | 975 | ||
950 | config SENSORS_SMSC47M1 | 976 | config SENSORS_SMSC47M1 |
951 | tristate "SMSC LPC47M10x and compatibles" | 977 | tristate "SMSC LPC47M10x and compatibles" |
978 | depends on !PPC | ||
952 | help | 979 | help |
953 | If you say yes here you get support for the integrated fan | 980 | If you say yes here you get support for the integrated fan |
954 | monitoring and control capabilities of the SMSC LPC47B27x, | 981 | monitoring and control capabilities of the SMSC LPC47B27x, |
@@ -982,7 +1009,7 @@ config SENSORS_SMSC47M192 | |||
982 | 1009 | ||
983 | config SENSORS_SMSC47B397 | 1010 | config SENSORS_SMSC47B397 |
984 | tristate "SMSC LPC47B397-NC" | 1011 | tristate "SMSC LPC47B397-NC" |
985 | depends on EXPERIMENTAL | 1012 | depends on EXPERIMENTAL && !PPC |
986 | help | 1013 | help |
987 | If you say yes here you get support for the SMSC LPC47B397-NC | 1014 | If you say yes here you get support for the SMSC LPC47B397-NC |
988 | sensor chip. | 1015 | sensor chip. |
@@ -996,6 +1023,7 @@ config SENSORS_SCH56XX_COMMON | |||
996 | 1023 | ||
997 | config SENSORS_SCH5627 | 1024 | config SENSORS_SCH5627 |
998 | tristate "SMSC SCH5627" | 1025 | tristate "SMSC SCH5627" |
1026 | depends on !PPC | ||
999 | select SENSORS_SCH56XX_COMMON | 1027 | select SENSORS_SCH56XX_COMMON |
1000 | help | 1028 | help |
1001 | If you say yes here you get support for the hardware monitoring | 1029 | If you say yes here you get support for the hardware monitoring |
@@ -1006,6 +1034,7 @@ config SENSORS_SCH5627 | |||
1006 | 1034 | ||
1007 | config SENSORS_SCH5636 | 1035 | config SENSORS_SCH5636 |
1008 | tristate "SMSC SCH5636" | 1036 | tristate "SMSC SCH5636" |
1037 | depends on !PPC | ||
1009 | select SENSORS_SCH56XX_COMMON | 1038 | select SENSORS_SCH56XX_COMMON |
1010 | help | 1039 | help |
1011 | SMSC SCH5636 Super I/O chips include an embedded microcontroller for | 1040 | SMSC SCH5636 Super I/O chips include an embedded microcontroller for |
@@ -1129,6 +1158,7 @@ config SENSORS_VIA686A | |||
1129 | 1158 | ||
1130 | config SENSORS_VT1211 | 1159 | config SENSORS_VT1211 |
1131 | tristate "VIA VT1211" | 1160 | tristate "VIA VT1211" |
1161 | depends on !PPC | ||
1132 | select HWMON_VID | 1162 | select HWMON_VID |
1133 | help | 1163 | help |
1134 | If you say yes here then you get support for hardware monitoring | 1164 | If you say yes here then you get support for hardware monitoring |
@@ -1241,6 +1271,7 @@ config SENSORS_W83L786NG | |||
1241 | 1271 | ||
1242 | config SENSORS_W83627HF | 1272 | config SENSORS_W83627HF |
1243 | tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF" | 1273 | tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF" |
1274 | depends on !PPC | ||
1244 | select HWMON_VID | 1275 | select HWMON_VID |
1245 | help | 1276 | help |
1246 | If you say yes here you get support for the Winbond W836X7 series | 1277 | If you say yes here you get support for the Winbond W836X7 series |
@@ -1251,7 +1282,8 @@ config SENSORS_W83627HF | |||
1251 | will be called w83627hf. | 1282 | will be called w83627hf. |
1252 | 1283 | ||
1253 | config SENSORS_W83627EHF | 1284 | config SENSORS_W83627EHF |
1254 | tristate "Winbond W83627EHF/EHG/DHG, W83667HG, NCT6775F, NCT6776F" | 1285 | tristate "Winbond W83627EHF/EHG/DHG/UHG, W83667HG, NCT6775F, NCT6776F" |
1286 | depends on !PPC | ||
1255 | select HWMON_VID | 1287 | select HWMON_VID |
1256 | help | 1288 | help |
1257 | If you say yes here you get support for the hardware | 1289 | If you say yes here you get support for the hardware |
@@ -1260,7 +1292,8 @@ config SENSORS_W83627EHF | |||
1260 | This driver also supports the W83627EHG, which is the lead-free | 1292 | This driver also supports the W83627EHG, which is the lead-free |
1261 | version of the W83627EHF, and the W83627DHG, which is a similar | 1293 | version of the W83627EHF, and the W83627DHG, which is a similar |
1262 | chip suited for specific Intel processors that use PECI such as | 1294 | chip suited for specific Intel processors that use PECI such as |
1263 | the Core 2 Duo. | 1295 | the Core 2 Duo. And also the W83627UHG, which is a stripped down |
1296 | version of the W83627DHG (as far as hardware monitoring goes.) | ||
1264 | 1297 | ||
1265 | This driver also supports Nuvoton W83667HG, W83667HG-B, NCT6775F | 1298 | This driver also supports Nuvoton W83667HG, W83667HG-B, NCT6775F |
1266 | (also known as W83667HG-I), and NCT6776F. | 1299 | (also known as W83667HG-I), and NCT6776F. |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 3c9ccefea791..8251ce8cd035 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -21,6 +21,7 @@ obj-$(CONFIG_SENSORS_W83791D) += w83791d.o | |||
21 | 21 | ||
22 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o | 22 | obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o |
23 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o | 23 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o |
24 | obj-$(CONFIG_SENSORS_AD7314) += ad7314.o | ||
24 | obj-$(CONFIG_SENSORS_AD7414) += ad7414.o | 25 | obj-$(CONFIG_SENSORS_AD7414) += ad7414.o |
25 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o | 26 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o |
26 | obj-$(CONFIG_SENSORS_ADCXX) += adcxx.o | 27 | obj-$(CONFIG_SENSORS_ADCXX) += adcxx.o |
@@ -47,6 +48,7 @@ obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | |||
47 | obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o | 48 | obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o |
48 | obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o | 49 | obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o |
49 | obj-$(CONFIG_SENSORS_EMC6W201) += emc6w201.o | 50 | obj-$(CONFIG_SENSORS_EMC6W201) += emc6w201.o |
51 | obj-$(CONFIG_SENSORS_EXYNOS4_TMU) += exynos4_tmu.o | ||
50 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | 52 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o |
51 | obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o | 53 | obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o |
52 | obj-$(CONFIG_SENSORS_F75375S) += f75375s.o | 54 | obj-$(CONFIG_SENSORS_F75375S) += f75375s.o |
diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c new file mode 100644 index 000000000000..318e38e85376 --- /dev/null +++ b/drivers/hwmon/ad7314.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | * AD7314 digital temperature sensor driver for AD7314, ADT7301 and ADT7302 | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | * | ||
8 | * Conversion to hwmon from IIO done by Jonathan Cameron <jic23@cam.ac.uk> | ||
9 | */ | ||
10 | #include <linux/device.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/sysfs.h> | ||
14 | #include <linux/spi/spi.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/hwmon.h> | ||
18 | #include <linux/hwmon-sysfs.h> | ||
19 | |||
20 | /* | ||
21 | * AD7314 power mode | ||
22 | */ | ||
23 | #define AD7314_PD 0x2000 | ||
24 | |||
25 | /* | ||
26 | * AD7314 temperature masks | ||
27 | */ | ||
28 | #define AD7314_TEMP_SIGN 0x200 | ||
29 | #define AD7314_TEMP_MASK 0x7FE0 | ||
30 | #define AD7314_TEMP_OFFSET 5 | ||
31 | |||
32 | /* | ||
33 | * ADT7301 and ADT7302 temperature masks | ||
34 | */ | ||
35 | #define ADT7301_TEMP_SIGN 0x2000 | ||
36 | #define ADT7301_TEMP_MASK 0x3FFF | ||
37 | |||
38 | enum ad7314_variant { | ||
39 | adt7301, | ||
40 | adt7302, | ||
41 | ad7314, | ||
42 | }; | ||
43 | |||
44 | struct ad7314_data { | ||
45 | struct spi_device *spi_dev; | ||
46 | struct device *hwmon_dev; | ||
47 | u16 rx ____cacheline_aligned; | ||
48 | }; | ||
49 | |||
50 | static int ad7314_spi_read(struct ad7314_data *chip, s16 *data) | ||
51 | { | ||
52 | int ret; | ||
53 | |||
54 | ret = spi_read(chip->spi_dev, (u8 *)&chip->rx, sizeof(chip->rx)); | ||
55 | if (ret < 0) { | ||
56 | dev_err(&chip->spi_dev->dev, "SPI read error\n"); | ||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | *data = be16_to_cpu(chip->rx); | ||
61 | |||
62 | return ret; | ||
63 | } | ||
64 | |||
65 | static ssize_t ad7314_show_temperature(struct device *dev, | ||
66 | struct device_attribute *attr, | ||
67 | char *buf) | ||
68 | { | ||
69 | struct ad7314_data *chip = dev_get_drvdata(dev); | ||
70 | s16 data; | ||
71 | int ret; | ||
72 | |||
73 | ret = ad7314_spi_read(chip, &data); | ||
74 | if (ret < 0) | ||
75 | return ret; | ||
76 | switch (spi_get_device_id(chip->spi_dev)->driver_data) { | ||
77 | case ad7314: | ||
78 | data = (data & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET; | ||
79 | data = (data << 6) >> 6; | ||
80 | |||
81 | return sprintf(buf, "%d\n", 250 * data); | ||
82 | case adt7301: | ||
83 | case adt7302: | ||
84 | /* | ||
85 | * Documented as a 13 bit twos complement register | ||
86 | * with a sign bit - which is a 14 bit 2's complement | ||
87 | * register. 1lsb - 31.25 milli degrees centigrade | ||
88 | */ | ||
89 | data &= ADT7301_TEMP_MASK; | ||
90 | data = (data << 2) >> 2; | ||
91 | |||
92 | return sprintf(buf, "%d\n", | ||
93 | DIV_ROUND_CLOSEST(data * 3125, 100)); | ||
94 | default: | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, | ||
100 | ad7314_show_temperature, NULL, 0); | ||
101 | |||
102 | static struct attribute *ad7314_attributes[] = { | ||
103 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
104 | NULL, | ||
105 | }; | ||
106 | |||
107 | static const struct attribute_group ad7314_group = { | ||
108 | .attrs = ad7314_attributes, | ||
109 | }; | ||
110 | |||
111 | static int __devinit ad7314_probe(struct spi_device *spi_dev) | ||
112 | { | ||
113 | int ret; | ||
114 | struct ad7314_data *chip; | ||
115 | |||
116 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
117 | if (chip == NULL) { | ||
118 | ret = -ENOMEM; | ||
119 | goto error_ret; | ||
120 | } | ||
121 | dev_set_drvdata(&spi_dev->dev, chip); | ||
122 | |||
123 | ret = sysfs_create_group(&spi_dev->dev.kobj, &ad7314_group); | ||
124 | if (ret < 0) | ||
125 | goto error_free_chip; | ||
126 | chip->hwmon_dev = hwmon_device_register(&spi_dev->dev); | ||
127 | if (IS_ERR(chip->hwmon_dev)) { | ||
128 | ret = PTR_ERR(chip->hwmon_dev); | ||
129 | goto error_remove_group; | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | error_remove_group: | ||
134 | sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group); | ||
135 | error_free_chip: | ||
136 | kfree(chip); | ||
137 | error_ret: | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | static int __devexit ad7314_remove(struct spi_device *spi_dev) | ||
142 | { | ||
143 | struct ad7314_data *chip = dev_get_drvdata(&spi_dev->dev); | ||
144 | |||
145 | hwmon_device_unregister(chip->hwmon_dev); | ||
146 | sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group); | ||
147 | kfree(chip); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static const struct spi_device_id ad7314_id[] = { | ||
153 | { "adt7301", adt7301 }, | ||
154 | { "adt7302", adt7302 }, | ||
155 | { "ad7314", ad7314 }, | ||
156 | { } | ||
157 | }; | ||
158 | MODULE_DEVICE_TABLE(spi, ad7314_id); | ||
159 | |||
160 | static struct spi_driver ad7314_driver = { | ||
161 | .driver = { | ||
162 | .name = "ad7314", | ||
163 | .bus = &spi_bus_type, | ||
164 | .owner = THIS_MODULE, | ||
165 | }, | ||
166 | .probe = ad7314_probe, | ||
167 | .remove = __devexit_p(ad7314_remove), | ||
168 | .id_table = ad7314_id, | ||
169 | }; | ||
170 | |||
171 | static __init int ad7314_init(void) | ||
172 | { | ||
173 | return spi_register_driver(&ad7314_driver); | ||
174 | } | ||
175 | module_init(ad7314_init); | ||
176 | |||
177 | static __exit void ad7314_exit(void) | ||
178 | { | ||
179 | spi_unregister_driver(&ad7314_driver); | ||
180 | } | ||
181 | module_exit(ad7314_exit); | ||
182 | |||
183 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | ||
184 | MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital" | ||
185 | " temperature sensor driver"); | ||
186 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c index d46c0c758ddf..df29a7fff9e7 100644 --- a/drivers/hwmon/ad7414.c +++ b/drivers/hwmon/ad7414.c | |||
@@ -58,10 +58,9 @@ static inline int ad7414_temp_from_reg(s16 reg) | |||
58 | 58 | ||
59 | static inline int ad7414_read(struct i2c_client *client, u8 reg) | 59 | static inline int ad7414_read(struct i2c_client *client, u8 reg) |
60 | { | 60 | { |
61 | if (reg == AD7414_REG_TEMP) { | 61 | if (reg == AD7414_REG_TEMP) |
62 | int value = i2c_smbus_read_word_data(client, reg); | 62 | return i2c_smbus_read_word_swapped(client, reg); |
63 | return (value < 0) ? value : swab16(value); | 63 | else |
64 | } else | ||
65 | return i2c_smbus_read_byte_data(client, reg); | 64 | return i2c_smbus_read_byte_data(client, reg); |
66 | } | 65 | } |
67 | 66 | ||
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index ffc781fec185..8cb718ce8237 100644 --- a/drivers/hwmon/ad7418.c +++ b/drivers/hwmon/ad7418.c | |||
@@ -76,20 +76,6 @@ static struct i2c_driver ad7418_driver = { | |||
76 | .id_table = ad7418_id, | 76 | .id_table = ad7418_id, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* All registers are word-sized, except for the configuration registers. | ||
80 | * AD7418 uses a high-byte first convention. Do NOT use those functions to | ||
81 | * access the configuration registers CONF and CONF2, as they are byte-sized. | ||
82 | */ | ||
83 | static inline int ad7418_read(struct i2c_client *client, u8 reg) | ||
84 | { | ||
85 | return swab16(i2c_smbus_read_word_data(client, reg)); | ||
86 | } | ||
87 | |||
88 | static inline int ad7418_write(struct i2c_client *client, u8 reg, u16 value) | ||
89 | { | ||
90 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | ||
91 | } | ||
92 | |||
93 | static void ad7418_init_client(struct i2c_client *client) | 79 | static void ad7418_init_client(struct i2c_client *client) |
94 | { | 80 | { |
95 | struct ad7418_data *data = i2c_get_clientdata(client); | 81 | struct ad7418_data *data = i2c_get_clientdata(client); |
@@ -128,7 +114,9 @@ static struct ad7418_data *ad7418_update_device(struct device *dev) | |||
128 | udelay(30); | 114 | udelay(30); |
129 | 115 | ||
130 | for (i = 0; i < 3; i++) { | 116 | for (i = 0; i < 3; i++) { |
131 | data->temp[i] = ad7418_read(client, AD7418_REG_TEMP[i]); | 117 | data->temp[i] = |
118 | i2c_smbus_read_word_swapped(client, | ||
119 | AD7418_REG_TEMP[i]); | ||
132 | } | 120 | } |
133 | 121 | ||
134 | for (i = 0, ch = 4; i < data->adc_max; i++, ch--) { | 122 | for (i = 0, ch = 4; i < data->adc_max; i++, ch--) { |
@@ -138,11 +126,12 @@ static struct ad7418_data *ad7418_update_device(struct device *dev) | |||
138 | 126 | ||
139 | udelay(15); | 127 | udelay(15); |
140 | data->in[data->adc_max - 1 - i] = | 128 | data->in[data->adc_max - 1 - i] = |
141 | ad7418_read(client, AD7418_REG_ADC); | 129 | i2c_smbus_read_word_swapped(client, |
130 | AD7418_REG_ADC); | ||
142 | } | 131 | } |
143 | 132 | ||
144 | /* restore old configuration value */ | 133 | /* restore old configuration value */ |
145 | ad7418_write(client, AD7418_REG_CONF, cfg); | 134 | i2c_smbus_write_word_swapped(client, AD7418_REG_CONF, cfg); |
146 | 135 | ||
147 | data->last_updated = jiffies; | 136 | data->last_updated = jiffies; |
148 | data->valid = 1; | 137 | data->valid = 1; |
@@ -182,7 +171,9 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, | |||
182 | 171 | ||
183 | mutex_lock(&data->lock); | 172 | mutex_lock(&data->lock); |
184 | data->temp[attr->index] = LM75_TEMP_TO_REG(temp); | 173 | data->temp[attr->index] = LM75_TEMP_TO_REG(temp); |
185 | ad7418_write(client, AD7418_REG_TEMP[attr->index], data->temp[attr->index]); | 174 | i2c_smbus_write_word_swapped(client, |
175 | AD7418_REG_TEMP[attr->index], | ||
176 | data->temp[attr->index]); | ||
186 | mutex_unlock(&data->lock); | 177 | mutex_unlock(&data->lock); |
187 | return count; | 178 | return count; |
188 | } | 179 | } |
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index e9beeda4cbe5..eedca3cf9968 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c | |||
@@ -59,19 +59,6 @@ struct ads1015_data { | |||
59 | struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; | 59 | struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static s32 ads1015_read_reg(struct i2c_client *client, unsigned int reg) | ||
63 | { | ||
64 | s32 data = i2c_smbus_read_word_data(client, reg); | ||
65 | |||
66 | return (data < 0) ? data : swab16(data); | ||
67 | } | ||
68 | |||
69 | static s32 ads1015_write_reg(struct i2c_client *client, unsigned int reg, | ||
70 | u16 val) | ||
71 | { | ||
72 | return i2c_smbus_write_word_data(client, reg, swab16(val)); | ||
73 | } | ||
74 | |||
75 | static int ads1015_read_value(struct i2c_client *client, unsigned int channel, | 62 | static int ads1015_read_value(struct i2c_client *client, unsigned int channel, |
76 | int *value) | 63 | int *value) |
77 | { | 64 | { |
@@ -87,7 +74,7 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel, | |||
87 | mutex_lock(&data->update_lock); | 74 | mutex_lock(&data->update_lock); |
88 | 75 | ||
89 | /* get channel parameters */ | 76 | /* get channel parameters */ |
90 | res = ads1015_read_reg(client, ADS1015_CONFIG); | 77 | res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG); |
91 | if (res < 0) | 78 | if (res < 0) |
92 | goto err_unlock; | 79 | goto err_unlock; |
93 | config = res; | 80 | config = res; |
@@ -101,13 +88,13 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel, | |||
101 | config |= (pga & 0x0007) << 9; | 88 | config |= (pga & 0x0007) << 9; |
102 | config |= (data_rate & 0x0007) << 5; | 89 | config |= (data_rate & 0x0007) << 5; |
103 | 90 | ||
104 | res = ads1015_write_reg(client, ADS1015_CONFIG, config); | 91 | res = i2c_smbus_write_word_swapped(client, ADS1015_CONFIG, config); |
105 | if (res < 0) | 92 | if (res < 0) |
106 | goto err_unlock; | 93 | goto err_unlock; |
107 | 94 | ||
108 | /* wait until conversion finished */ | 95 | /* wait until conversion finished */ |
109 | msleep(conversion_time_ms); | 96 | msleep(conversion_time_ms); |
110 | res = ads1015_read_reg(client, ADS1015_CONFIG); | 97 | res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG); |
111 | if (res < 0) | 98 | if (res < 0) |
112 | goto err_unlock; | 99 | goto err_unlock; |
113 | config = res; | 100 | config = res; |
@@ -117,7 +104,7 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel, | |||
117 | goto err_unlock; | 104 | goto err_unlock; |
118 | } | 105 | } |
119 | 106 | ||
120 | res = ads1015_read_reg(client, ADS1015_CONVERSION); | 107 | res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION); |
121 | if (res < 0) | 108 | if (res < 0) |
122 | goto err_unlock; | 109 | goto err_unlock; |
123 | conversion = res; | 110 | conversion = res; |
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index c42c5a69a664..cfcc3b6fb6bf 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c | |||
@@ -74,13 +74,6 @@ static int ads7828_detect(struct i2c_client *client, | |||
74 | static int ads7828_probe(struct i2c_client *client, | 74 | static int ads7828_probe(struct i2c_client *client, |
75 | const struct i2c_device_id *id); | 75 | const struct i2c_device_id *id); |
76 | 76 | ||
77 | /* The ADS7828 returns the 12-bit sample in two bytes, | ||
78 | these are read as a word then byte-swapped */ | ||
79 | static u16 ads7828_read_value(struct i2c_client *client, u8 reg) | ||
80 | { | ||
81 | return swab16(i2c_smbus_read_word_data(client, reg)); | ||
82 | } | ||
83 | |||
84 | static inline u8 channel_cmd_byte(int ch) | 77 | static inline u8 channel_cmd_byte(int ch) |
85 | { | 78 | { |
86 | /* cmd byte C2,C1,C0 - see datasheet */ | 79 | /* cmd byte C2,C1,C0 - see datasheet */ |
@@ -104,7 +97,8 @@ static struct ads7828_data *ads7828_update_device(struct device *dev) | |||
104 | 97 | ||
105 | for (ch = 0; ch < ADS7828_NCH; ch++) { | 98 | for (ch = 0; ch < ADS7828_NCH; ch++) { |
106 | u8 cmd = channel_cmd_byte(ch); | 99 | u8 cmd = channel_cmd_byte(ch); |
107 | data->adc_input[ch] = ads7828_read_value(client, cmd); | 100 | data->adc_input[ch] = |
101 | i2c_smbus_read_word_swapped(client, cmd); | ||
108 | } | 102 | } |
109 | data->last_updated = jiffies; | 103 | data->last_updated = jiffies; |
110 | data->valid = 1; | 104 | data->valid = 1; |
@@ -203,7 +197,7 @@ static int ads7828_detect(struct i2c_client *client, | |||
203 | for (ch = 0; ch < ADS7828_NCH; ch++) { | 197 | for (ch = 0; ch < ADS7828_NCH; ch++) { |
204 | u16 in_data; | 198 | u16 in_data; |
205 | u8 cmd = channel_cmd_byte(ch); | 199 | u8 cmd = channel_cmd_byte(ch); |
206 | in_data = ads7828_read_value(client, cmd); | 200 | in_data = i2c_smbus_read_word_swapped(client, cmd); |
207 | if (in_data & 0xF000) { | 201 | if (in_data & 0xF000) { |
208 | pr_debug("%s : Doesn't look like an ads7828 device\n", | 202 | pr_debug("%s : Doesn't look like an ads7828 device\n", |
209 | __func__); | 203 | __func__); |
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index c02a052d3085..d7bd1f3f2a31 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c | |||
@@ -829,17 +829,17 @@ static int asb100_read_value(struct i2c_client *client, u16 reg) | |||
829 | /* convert from ISA to LM75 I2C addresses */ | 829 | /* convert from ISA to LM75 I2C addresses */ |
830 | switch (reg & 0xff) { | 830 | switch (reg & 0xff) { |
831 | case 0x50: /* TEMP */ | 831 | case 0x50: /* TEMP */ |
832 | res = swab16(i2c_smbus_read_word_data(cl, 0)); | 832 | res = i2c_smbus_read_word_swapped(cl, 0); |
833 | break; | 833 | break; |
834 | case 0x52: /* CONFIG */ | 834 | case 0x52: /* CONFIG */ |
835 | res = i2c_smbus_read_byte_data(cl, 1); | 835 | res = i2c_smbus_read_byte_data(cl, 1); |
836 | break; | 836 | break; |
837 | case 0x53: /* HYST */ | 837 | case 0x53: /* HYST */ |
838 | res = swab16(i2c_smbus_read_word_data(cl, 2)); | 838 | res = i2c_smbus_read_word_swapped(cl, 2); |
839 | break; | 839 | break; |
840 | case 0x55: /* MAX */ | 840 | case 0x55: /* MAX */ |
841 | default: | 841 | default: |
842 | res = swab16(i2c_smbus_read_word_data(cl, 3)); | 842 | res = i2c_smbus_read_word_swapped(cl, 3); |
843 | break; | 843 | break; |
844 | } | 844 | } |
845 | } | 845 | } |
@@ -877,10 +877,10 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value) | |||
877 | i2c_smbus_write_byte_data(cl, 1, value & 0xff); | 877 | i2c_smbus_write_byte_data(cl, 1, value & 0xff); |
878 | break; | 878 | break; |
879 | case 0x53: /* HYST */ | 879 | case 0x53: /* HYST */ |
880 | i2c_smbus_write_word_data(cl, 2, swab16(value)); | 880 | i2c_smbus_write_word_swapped(cl, 2, value); |
881 | break; | 881 | break; |
882 | case 0x55: /* MAX */ | 882 | case 0x55: /* MAX */ |
883 | i2c_smbus_write_word_data(cl, 3, swab16(value)); | 883 | i2c_smbus_write_word_swapped(cl, 3, value); |
884 | break; | 884 | break; |
885 | } | 885 | } |
886 | } | 886 | } |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 932383786642..104b3767516c 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -60,14 +60,13 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); | |||
60 | #ifdef CONFIG_SMP | 60 | #ifdef CONFIG_SMP |
61 | #define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id | 61 | #define TO_PHYS_ID(cpu) cpu_data(cpu).phys_proc_id |
62 | #define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id | 62 | #define TO_CORE_ID(cpu) cpu_data(cpu).cpu_core_id |
63 | #define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) | ||
64 | #define for_each_sibling(i, cpu) for_each_cpu(i, cpu_sibling_mask(cpu)) | 63 | #define for_each_sibling(i, cpu) for_each_cpu(i, cpu_sibling_mask(cpu)) |
65 | #else | 64 | #else |
66 | #define TO_PHYS_ID(cpu) (cpu) | 65 | #define TO_PHYS_ID(cpu) (cpu) |
67 | #define TO_CORE_ID(cpu) (cpu) | 66 | #define TO_CORE_ID(cpu) (cpu) |
68 | #define TO_ATTR_NO(cpu) (cpu) | ||
69 | #define for_each_sibling(i, cpu) for (i = 0; false; ) | 67 | #define for_each_sibling(i, cpu) for (i = 0; false; ) |
70 | #endif | 68 | #endif |
69 | #define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) | ||
71 | 70 | ||
72 | /* | 71 | /* |
73 | * Per-Core Temperature Data | 72 | * Per-Core Temperature Data |
@@ -325,15 +324,6 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | |||
325 | return adjust_tjmax(c, id, dev); | 324 | return adjust_tjmax(c, id, dev); |
326 | } | 325 | } |
327 | 326 | ||
328 | static void __devinit get_ucode_rev_on_cpu(void *edx) | ||
329 | { | ||
330 | u32 eax; | ||
331 | |||
332 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | ||
333 | sync_core(); | ||
334 | rdmsr(MSR_IA32_UCODE_REV, eax, *(u32 *)edx); | ||
335 | } | ||
336 | |||
337 | static int create_name_attr(struct platform_data *pdata, struct device *dev) | 327 | static int create_name_attr(struct platform_data *pdata, struct device *dev) |
338 | { | 328 | { |
339 | sysfs_attr_init(&pdata->name_attr.attr); | 329 | sysfs_attr_init(&pdata->name_attr.attr); |
@@ -380,27 +370,16 @@ exit_free: | |||
380 | static int __cpuinit chk_ucode_version(unsigned int cpu) | 370 | static int __cpuinit chk_ucode_version(unsigned int cpu) |
381 | { | 371 | { |
382 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 372 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
383 | int err; | ||
384 | u32 edx; | ||
385 | 373 | ||
386 | /* | 374 | /* |
387 | * Check if we have problem with errata AE18 of Core processors: | 375 | * Check if we have problem with errata AE18 of Core processors: |
388 | * Readings might stop update when processor visited too deep sleep, | 376 | * Readings might stop update when processor visited too deep sleep, |
389 | * fixed for stepping D0 (6EC). | 377 | * fixed for stepping D0 (6EC). |
390 | */ | 378 | */ |
391 | if (c->x86_model == 0xe && c->x86_mask < 0xc) { | 379 | if (c->x86_model == 0xe && c->x86_mask < 0xc && c->microcode < 0x39) { |
392 | /* check for microcode update */ | 380 | pr_err("Errata AE18 not fixed, update BIOS or " |
393 | err = smp_call_function_single(cpu, get_ucode_rev_on_cpu, | 381 | "microcode of the CPU!\n"); |
394 | &edx, 1); | 382 | return -ENODEV; |
395 | if (err) { | ||
396 | pr_err("Cannot determine microcode revision of " | ||
397 | "CPU#%u (%d)!\n", cpu, err); | ||
398 | return -ENODEV; | ||
399 | } else if (edx < 0x39) { | ||
400 | pr_err("Errata AE18 not fixed, update BIOS or " | ||
401 | "microcode of the CPU!\n"); | ||
402 | return -ENODEV; | ||
403 | } | ||
404 | } | 383 | } |
405 | return 0; | 384 | return 0; |
406 | } | 385 | } |
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index e11363467a8d..ef1ac996752e 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c | |||
@@ -80,24 +80,6 @@ struct ds1621_data { | |||
80 | u8 conf; /* Register encoding, combined */ | 80 | u8 conf; /* Register encoding, combined */ |
81 | }; | 81 | }; |
82 | 82 | ||
83 | /* Temperature registers are word-sized. | ||
84 | DS1621 uses a high-byte first convention, which is exactly opposite to | ||
85 | the SMBus standard. */ | ||
86 | static int ds1621_read_temp(struct i2c_client *client, u8 reg) | ||
87 | { | ||
88 | int ret; | ||
89 | |||
90 | ret = i2c_smbus_read_word_data(client, reg); | ||
91 | if (ret < 0) | ||
92 | return ret; | ||
93 | return swab16(ret); | ||
94 | } | ||
95 | |||
96 | static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value) | ||
97 | { | ||
98 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | ||
99 | } | ||
100 | |||
101 | static void ds1621_init_client(struct i2c_client *client) | 83 | static void ds1621_init_client(struct i2c_client *client) |
102 | { | 84 | { |
103 | u8 conf, new_conf; | 85 | u8 conf, new_conf; |
@@ -136,7 +118,7 @@ static struct ds1621_data *ds1621_update_client(struct device *dev) | |||
136 | data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); | 118 | data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); |
137 | 119 | ||
138 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) | 120 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) |
139 | data->temp[i] = ds1621_read_temp(client, | 121 | data->temp[i] = i2c_smbus_read_word_swapped(client, |
140 | DS1621_REG_TEMP[i]); | 122 | DS1621_REG_TEMP[i]); |
141 | 123 | ||
142 | /* reset alarms if necessary */ | 124 | /* reset alarms if necessary */ |
@@ -177,8 +159,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
177 | 159 | ||
178 | mutex_lock(&data->update_lock); | 160 | mutex_lock(&data->update_lock); |
179 | data->temp[attr->index] = val; | 161 | data->temp[attr->index] = val; |
180 | ds1621_write_temp(client, DS1621_REG_TEMP[attr->index], | 162 | i2c_smbus_write_word_swapped(client, DS1621_REG_TEMP[attr->index], |
181 | data->temp[attr->index]); | 163 | data->temp[attr->index]); |
182 | mutex_unlock(&data->update_lock); | 164 | mutex_unlock(&data->update_lock); |
183 | return count; | 165 | return count; |
184 | } | 166 | } |
diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c index 4f7c3fc40a89..225ae4f36583 100644 --- a/drivers/hwmon/ds620.c +++ b/drivers/hwmon/ds620.c | |||
@@ -75,33 +75,13 @@ struct ds620_data { | |||
75 | s16 temp[3]; /* Register values, word */ | 75 | s16 temp[3]; /* Register values, word */ |
76 | }; | 76 | }; |
77 | 77 | ||
78 | /* | ||
79 | * Temperature registers are word-sized. | ||
80 | * DS620 uses a high-byte first convention, which is exactly opposite to | ||
81 | * the SMBus standard. | ||
82 | */ | ||
83 | static int ds620_read_temp(struct i2c_client *client, u8 reg) | ||
84 | { | ||
85 | int ret; | ||
86 | |||
87 | ret = i2c_smbus_read_word_data(client, reg); | ||
88 | if (ret < 0) | ||
89 | return ret; | ||
90 | return swab16(ret); | ||
91 | } | ||
92 | |||
93 | static int ds620_write_temp(struct i2c_client *client, u8 reg, u16 value) | ||
94 | { | ||
95 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | ||
96 | } | ||
97 | |||
98 | static void ds620_init_client(struct i2c_client *client) | 78 | static void ds620_init_client(struct i2c_client *client) |
99 | { | 79 | { |
100 | struct ds620_platform_data *ds620_info = client->dev.platform_data; | 80 | struct ds620_platform_data *ds620_info = client->dev.platform_data; |
101 | u16 conf, new_conf; | 81 | u16 conf, new_conf; |
102 | 82 | ||
103 | new_conf = conf = | 83 | new_conf = conf = |
104 | swab16(i2c_smbus_read_word_data(client, DS620_REG_CONF)); | 84 | i2c_smbus_read_word_swapped(client, DS620_REG_CONF); |
105 | 85 | ||
106 | /* switch to continuous conversion mode */ | 86 | /* switch to continuous conversion mode */ |
107 | new_conf &= ~DS620_REG_CONFIG_1SHOT; | 87 | new_conf &= ~DS620_REG_CONFIG_1SHOT; |
@@ -118,8 +98,7 @@ static void ds620_init_client(struct i2c_client *client) | |||
118 | new_conf |= DS620_REG_CONFIG_R1 | DS620_REG_CONFIG_R0; | 98 | new_conf |= DS620_REG_CONFIG_R1 | DS620_REG_CONFIG_R0; |
119 | 99 | ||
120 | if (conf != new_conf) | 100 | if (conf != new_conf) |
121 | i2c_smbus_write_word_data(client, DS620_REG_CONF, | 101 | i2c_smbus_write_word_swapped(client, DS620_REG_CONF, new_conf); |
122 | swab16(new_conf)); | ||
123 | 102 | ||
124 | /* start conversion */ | 103 | /* start conversion */ |
125 | i2c_smbus_write_byte(client, DS620_COM_START); | 104 | i2c_smbus_write_byte(client, DS620_COM_START); |
@@ -141,8 +120,8 @@ static struct ds620_data *ds620_update_client(struct device *dev) | |||
141 | dev_dbg(&client->dev, "Starting ds620 update\n"); | 120 | dev_dbg(&client->dev, "Starting ds620 update\n"); |
142 | 121 | ||
143 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { | 122 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { |
144 | res = ds620_read_temp(client, | 123 | res = i2c_smbus_read_word_swapped(client, |
145 | DS620_REG_TEMP[i]); | 124 | DS620_REG_TEMP[i]); |
146 | if (res < 0) { | 125 | if (res < 0) { |
147 | ret = ERR_PTR(res); | 126 | ret = ERR_PTR(res); |
148 | goto abort; | 127 | goto abort; |
@@ -191,8 +170,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
191 | 170 | ||
192 | mutex_lock(&data->update_lock); | 171 | mutex_lock(&data->update_lock); |
193 | data->temp[attr->index] = val; | 172 | data->temp[attr->index] = val; |
194 | ds620_write_temp(client, DS620_REG_TEMP[attr->index], | 173 | i2c_smbus_write_word_swapped(client, DS620_REG_TEMP[attr->index], |
195 | data->temp[attr->index]); | 174 | data->temp[attr->index]); |
196 | mutex_unlock(&data->update_lock); | 175 | mutex_unlock(&data->update_lock); |
197 | return count; | 176 | return count; |
198 | } | 177 | } |
@@ -210,16 +189,15 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *da, | |||
210 | return PTR_ERR(data); | 189 | return PTR_ERR(data); |
211 | 190 | ||
212 | /* reset alarms if necessary */ | 191 | /* reset alarms if necessary */ |
213 | res = i2c_smbus_read_word_data(client, DS620_REG_CONF); | 192 | res = i2c_smbus_read_word_swapped(client, DS620_REG_CONF); |
214 | if (res < 0) | 193 | if (res < 0) |
215 | return res; | 194 | return res; |
216 | 195 | ||
217 | conf = swab16(res); | 196 | new_conf = conf = res; |
218 | new_conf = conf; | ||
219 | new_conf &= ~attr->index; | 197 | new_conf &= ~attr->index; |
220 | if (conf != new_conf) { | 198 | if (conf != new_conf) { |
221 | res = i2c_smbus_write_word_data(client, DS620_REG_CONF, | 199 | res = i2c_smbus_write_word_swapped(client, DS620_REG_CONF, |
222 | swab16(new_conf)); | 200 | new_conf); |
223 | if (res < 0) | 201 | if (res < 0) |
224 | return res; | 202 | return res; |
225 | } | 203 | } |
diff --git a/drivers/hwmon/exynos4_tmu.c b/drivers/hwmon/exynos4_tmu.c new file mode 100644 index 000000000000..faa0884f61f6 --- /dev/null +++ b/drivers/hwmon/exynos4_tmu.c | |||
@@ -0,0 +1,524 @@ | |||
1 | /* | ||
2 | * exynos4_tmu.c - Samsung EXYNOS4 TMU (Thermal Management Unit) | ||
3 | * | ||
4 | * Copyright (C) 2011 Samsung Electronics | ||
5 | * Donggeun Kim <dg77.kim@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/clk.h> | ||
30 | #include <linux/workqueue.h> | ||
31 | #include <linux/sysfs.h> | ||
32 | #include <linux/kobject.h> | ||
33 | #include <linux/io.h> | ||
34 | #include <linux/mutex.h> | ||
35 | |||
36 | #include <linux/hwmon.h> | ||
37 | #include <linux/hwmon-sysfs.h> | ||
38 | |||
39 | #include <linux/platform_data/exynos4_tmu.h> | ||
40 | |||
41 | #define EXYNOS4_TMU_REG_TRIMINFO 0x0 | ||
42 | #define EXYNOS4_TMU_REG_CONTROL 0x20 | ||
43 | #define EXYNOS4_TMU_REG_STATUS 0x28 | ||
44 | #define EXYNOS4_TMU_REG_CURRENT_TEMP 0x40 | ||
45 | #define EXYNOS4_TMU_REG_THRESHOLD_TEMP 0x44 | ||
46 | #define EXYNOS4_TMU_REG_TRIG_LEVEL0 0x50 | ||
47 | #define EXYNOS4_TMU_REG_TRIG_LEVEL1 0x54 | ||
48 | #define EXYNOS4_TMU_REG_TRIG_LEVEL2 0x58 | ||
49 | #define EXYNOS4_TMU_REG_TRIG_LEVEL3 0x5C | ||
50 | #define EXYNOS4_TMU_REG_PAST_TEMP0 0x60 | ||
51 | #define EXYNOS4_TMU_REG_PAST_TEMP1 0x64 | ||
52 | #define EXYNOS4_TMU_REG_PAST_TEMP2 0x68 | ||
53 | #define EXYNOS4_TMU_REG_PAST_TEMP3 0x6C | ||
54 | #define EXYNOS4_TMU_REG_INTEN 0x70 | ||
55 | #define EXYNOS4_TMU_REG_INTSTAT 0x74 | ||
56 | #define EXYNOS4_TMU_REG_INTCLEAR 0x78 | ||
57 | |||
58 | #define EXYNOS4_TMU_GAIN_SHIFT 8 | ||
59 | #define EXYNOS4_TMU_REF_VOLTAGE_SHIFT 24 | ||
60 | |||
61 | #define EXYNOS4_TMU_TRIM_TEMP_MASK 0xff | ||
62 | #define EXYNOS4_TMU_CORE_ON 3 | ||
63 | #define EXYNOS4_TMU_CORE_OFF 2 | ||
64 | #define EXYNOS4_TMU_DEF_CODE_TO_TEMP_OFFSET 50 | ||
65 | #define EXYNOS4_TMU_TRIG_LEVEL0_MASK 0x1 | ||
66 | #define EXYNOS4_TMU_TRIG_LEVEL1_MASK 0x10 | ||
67 | #define EXYNOS4_TMU_TRIG_LEVEL2_MASK 0x100 | ||
68 | #define EXYNOS4_TMU_TRIG_LEVEL3_MASK 0x1000 | ||
69 | #define EXYNOS4_TMU_INTCLEAR_VAL 0x1111 | ||
70 | |||
71 | struct exynos4_tmu_data { | ||
72 | struct exynos4_tmu_platform_data *pdata; | ||
73 | struct device *hwmon_dev; | ||
74 | struct resource *mem; | ||
75 | void __iomem *base; | ||
76 | int irq; | ||
77 | struct work_struct irq_work; | ||
78 | struct mutex lock; | ||
79 | struct clk *clk; | ||
80 | u8 temp_error1, temp_error2; | ||
81 | }; | ||
82 | |||
83 | /* | ||
84 | * TMU treats temperature as a mapped temperature code. | ||
85 | * The temperature is converted differently depending on the calibration type. | ||
86 | */ | ||
87 | static int temp_to_code(struct exynos4_tmu_data *data, u8 temp) | ||
88 | { | ||
89 | struct exynos4_tmu_platform_data *pdata = data->pdata; | ||
90 | int temp_code; | ||
91 | |||
92 | /* temp should range between 25 and 125 */ | ||
93 | if (temp < 25 || temp > 125) { | ||
94 | temp_code = -EINVAL; | ||
95 | goto out; | ||
96 | } | ||
97 | |||
98 | switch (pdata->cal_type) { | ||
99 | case TYPE_TWO_POINT_TRIMMING: | ||
100 | temp_code = (temp - 25) * | ||
101 | (data->temp_error2 - data->temp_error1) / | ||
102 | (85 - 25) + data->temp_error1; | ||
103 | break; | ||
104 | case TYPE_ONE_POINT_TRIMMING: | ||
105 | temp_code = temp + data->temp_error1 - 25; | ||
106 | break; | ||
107 | default: | ||
108 | temp_code = temp + EXYNOS4_TMU_DEF_CODE_TO_TEMP_OFFSET; | ||
109 | break; | ||
110 | } | ||
111 | out: | ||
112 | return temp_code; | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * Calculate a temperature value from a temperature code. | ||
117 | * The unit of the temperature is degree Celsius. | ||
118 | */ | ||
119 | static int code_to_temp(struct exynos4_tmu_data *data, u8 temp_code) | ||
120 | { | ||
121 | struct exynos4_tmu_platform_data *pdata = data->pdata; | ||
122 | int temp; | ||
123 | |||
124 | /* temp_code should range between 75 and 175 */ | ||
125 | if (temp_code < 75 || temp_code > 175) { | ||
126 | temp = -ENODATA; | ||
127 | goto out; | ||
128 | } | ||
129 | |||
130 | switch (pdata->cal_type) { | ||
131 | case TYPE_TWO_POINT_TRIMMING: | ||
132 | temp = (temp_code - data->temp_error1) * (85 - 25) / | ||
133 | (data->temp_error2 - data->temp_error1) + 25; | ||
134 | break; | ||
135 | case TYPE_ONE_POINT_TRIMMING: | ||
136 | temp = temp_code - data->temp_error1 + 25; | ||
137 | break; | ||
138 | default: | ||
139 | temp = temp_code - EXYNOS4_TMU_DEF_CODE_TO_TEMP_OFFSET; | ||
140 | break; | ||
141 | } | ||
142 | out: | ||
143 | return temp; | ||
144 | } | ||
145 | |||
146 | static int exynos4_tmu_initialize(struct platform_device *pdev) | ||
147 | { | ||
148 | struct exynos4_tmu_data *data = platform_get_drvdata(pdev); | ||
149 | struct exynos4_tmu_platform_data *pdata = data->pdata; | ||
150 | unsigned int status, trim_info; | ||
151 | int ret = 0, threshold_code; | ||
152 | |||
153 | mutex_lock(&data->lock); | ||
154 | clk_enable(data->clk); | ||
155 | |||
156 | status = readb(data->base + EXYNOS4_TMU_REG_STATUS); | ||
157 | if (!status) { | ||
158 | ret = -EBUSY; | ||
159 | goto out; | ||
160 | } | ||
161 | |||
162 | /* Save trimming info in order to perform calibration */ | ||
163 | trim_info = readl(data->base + EXYNOS4_TMU_REG_TRIMINFO); | ||
164 | data->temp_error1 = trim_info & EXYNOS4_TMU_TRIM_TEMP_MASK; | ||
165 | data->temp_error2 = ((trim_info >> 8) & EXYNOS4_TMU_TRIM_TEMP_MASK); | ||
166 | |||
167 | /* Write temperature code for threshold */ | ||
168 | threshold_code = temp_to_code(data, pdata->threshold); | ||
169 | if (threshold_code < 0) { | ||
170 | ret = threshold_code; | ||
171 | goto out; | ||
172 | } | ||
173 | writeb(threshold_code, | ||
174 | data->base + EXYNOS4_TMU_REG_THRESHOLD_TEMP); | ||
175 | |||
176 | writeb(pdata->trigger_levels[0], | ||
177 | data->base + EXYNOS4_TMU_REG_TRIG_LEVEL0); | ||
178 | writeb(pdata->trigger_levels[1], | ||
179 | data->base + EXYNOS4_TMU_REG_TRIG_LEVEL1); | ||
180 | writeb(pdata->trigger_levels[2], | ||
181 | data->base + EXYNOS4_TMU_REG_TRIG_LEVEL2); | ||
182 | writeb(pdata->trigger_levels[3], | ||
183 | data->base + EXYNOS4_TMU_REG_TRIG_LEVEL3); | ||
184 | |||
185 | writel(EXYNOS4_TMU_INTCLEAR_VAL, | ||
186 | data->base + EXYNOS4_TMU_REG_INTCLEAR); | ||
187 | out: | ||
188 | clk_disable(data->clk); | ||
189 | mutex_unlock(&data->lock); | ||
190 | |||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | static void exynos4_tmu_control(struct platform_device *pdev, bool on) | ||
195 | { | ||
196 | struct exynos4_tmu_data *data = platform_get_drvdata(pdev); | ||
197 | struct exynos4_tmu_platform_data *pdata = data->pdata; | ||
198 | unsigned int con, interrupt_en; | ||
199 | |||
200 | mutex_lock(&data->lock); | ||
201 | clk_enable(data->clk); | ||
202 | |||
203 | con = pdata->reference_voltage << EXYNOS4_TMU_REF_VOLTAGE_SHIFT | | ||
204 | pdata->gain << EXYNOS4_TMU_GAIN_SHIFT; | ||
205 | if (on) { | ||
206 | con |= EXYNOS4_TMU_CORE_ON; | ||
207 | interrupt_en = pdata->trigger_level3_en << 12 | | ||
208 | pdata->trigger_level2_en << 8 | | ||
209 | pdata->trigger_level1_en << 4 | | ||
210 | pdata->trigger_level0_en; | ||
211 | } else { | ||
212 | con |= EXYNOS4_TMU_CORE_OFF; | ||
213 | interrupt_en = 0; /* Disable all interrupts */ | ||
214 | } | ||
215 | writel(interrupt_en, data->base + EXYNOS4_TMU_REG_INTEN); | ||
216 | writel(con, data->base + EXYNOS4_TMU_REG_CONTROL); | ||
217 | |||
218 | clk_disable(data->clk); | ||
219 | mutex_unlock(&data->lock); | ||
220 | } | ||
221 | |||
222 | static int exynos4_tmu_read(struct exynos4_tmu_data *data) | ||
223 | { | ||
224 | u8 temp_code; | ||
225 | int temp; | ||
226 | |||
227 | mutex_lock(&data->lock); | ||
228 | clk_enable(data->clk); | ||
229 | |||
230 | temp_code = readb(data->base + EXYNOS4_TMU_REG_CURRENT_TEMP); | ||
231 | temp = code_to_temp(data, temp_code); | ||
232 | |||
233 | clk_disable(data->clk); | ||
234 | mutex_unlock(&data->lock); | ||
235 | |||
236 | return temp; | ||
237 | } | ||
238 | |||
239 | static void exynos4_tmu_work(struct work_struct *work) | ||
240 | { | ||
241 | struct exynos4_tmu_data *data = container_of(work, | ||
242 | struct exynos4_tmu_data, irq_work); | ||
243 | |||
244 | mutex_lock(&data->lock); | ||
245 | clk_enable(data->clk); | ||
246 | |||
247 | writel(EXYNOS4_TMU_INTCLEAR_VAL, data->base + EXYNOS4_TMU_REG_INTCLEAR); | ||
248 | |||
249 | kobject_uevent(&data->hwmon_dev->kobj, KOBJ_CHANGE); | ||
250 | |||
251 | enable_irq(data->irq); | ||
252 | |||
253 | clk_disable(data->clk); | ||
254 | mutex_unlock(&data->lock); | ||
255 | } | ||
256 | |||
257 | static irqreturn_t exynos4_tmu_irq(int irq, void *id) | ||
258 | { | ||
259 | struct exynos4_tmu_data *data = id; | ||
260 | |||
261 | disable_irq_nosync(irq); | ||
262 | schedule_work(&data->irq_work); | ||
263 | |||
264 | return IRQ_HANDLED; | ||
265 | } | ||
266 | |||
267 | static ssize_t exynos4_tmu_show_name(struct device *dev, | ||
268 | struct device_attribute *attr, char *buf) | ||
269 | { | ||
270 | return sprintf(buf, "exynos4-tmu\n"); | ||
271 | } | ||
272 | |||
273 | static ssize_t exynos4_tmu_show_temp(struct device *dev, | ||
274 | struct device_attribute *attr, char *buf) | ||
275 | { | ||
276 | struct exynos4_tmu_data *data = dev_get_drvdata(dev); | ||
277 | int ret; | ||
278 | |||
279 | ret = exynos4_tmu_read(data); | ||
280 | if (ret < 0) | ||
281 | return ret; | ||
282 | |||
283 | /* convert from degree Celsius to millidegree Celsius */ | ||
284 | return sprintf(buf, "%d\n", ret * 1000); | ||
285 | } | ||
286 | |||
287 | static ssize_t exynos4_tmu_show_alarm(struct device *dev, | ||
288 | struct device_attribute *devattr, char *buf) | ||
289 | { | ||
290 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
291 | struct exynos4_tmu_data *data = dev_get_drvdata(dev); | ||
292 | struct exynos4_tmu_platform_data *pdata = data->pdata; | ||
293 | int temp; | ||
294 | unsigned int trigger_level; | ||
295 | |||
296 | temp = exynos4_tmu_read(data); | ||
297 | if (temp < 0) | ||
298 | return temp; | ||
299 | |||
300 | trigger_level = pdata->threshold + pdata->trigger_levels[attr->index]; | ||
301 | |||
302 | return sprintf(buf, "%d\n", !!(temp > trigger_level)); | ||
303 | } | ||
304 | |||
305 | static ssize_t exynos4_tmu_show_level(struct device *dev, | ||
306 | struct device_attribute *devattr, char *buf) | ||
307 | { | ||
308 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
309 | struct exynos4_tmu_data *data = dev_get_drvdata(dev); | ||
310 | struct exynos4_tmu_platform_data *pdata = data->pdata; | ||
311 | unsigned int temp = pdata->threshold + | ||
312 | pdata->trigger_levels[attr->index]; | ||
313 | |||
314 | return sprintf(buf, "%u\n", temp * 1000); | ||
315 | } | ||
316 | |||
317 | static DEVICE_ATTR(name, S_IRUGO, exynos4_tmu_show_name, NULL); | ||
318 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, exynos4_tmu_show_temp, NULL, 0); | ||
319 | |||
320 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, | ||
321 | exynos4_tmu_show_alarm, NULL, 1); | ||
322 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, | ||
323 | exynos4_tmu_show_alarm, NULL, 2); | ||
324 | static SENSOR_DEVICE_ATTR(temp1_emergency_alarm, S_IRUGO, | ||
325 | exynos4_tmu_show_alarm, NULL, 3); | ||
326 | |||
327 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, exynos4_tmu_show_level, NULL, 1); | ||
328 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, exynos4_tmu_show_level, NULL, 2); | ||
329 | static SENSOR_DEVICE_ATTR(temp1_emergency, S_IRUGO, | ||
330 | exynos4_tmu_show_level, NULL, 3); | ||
331 | |||
332 | static struct attribute *exynos4_tmu_attributes[] = { | ||
333 | &dev_attr_name.attr, | ||
334 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
335 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
336 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
337 | &sensor_dev_attr_temp1_emergency_alarm.dev_attr.attr, | ||
338 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
339 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
340 | &sensor_dev_attr_temp1_emergency.dev_attr.attr, | ||
341 | NULL, | ||
342 | }; | ||
343 | |||
344 | static const struct attribute_group exynos4_tmu_attr_group = { | ||
345 | .attrs = exynos4_tmu_attributes, | ||
346 | }; | ||
347 | |||
348 | static int __devinit exynos4_tmu_probe(struct platform_device *pdev) | ||
349 | { | ||
350 | struct exynos4_tmu_data *data; | ||
351 | struct exynos4_tmu_platform_data *pdata = pdev->dev.platform_data; | ||
352 | int ret; | ||
353 | |||
354 | if (!pdata) { | ||
355 | dev_err(&pdev->dev, "No platform init data supplied.\n"); | ||
356 | return -ENODEV; | ||
357 | } | ||
358 | |||
359 | data = kzalloc(sizeof(struct exynos4_tmu_data), GFP_KERNEL); | ||
360 | if (!data) { | ||
361 | dev_err(&pdev->dev, "Failed to allocate driver structure\n"); | ||
362 | return -ENOMEM; | ||
363 | } | ||
364 | |||
365 | data->irq = platform_get_irq(pdev, 0); | ||
366 | if (data->irq < 0) { | ||
367 | ret = data->irq; | ||
368 | dev_err(&pdev->dev, "Failed to get platform irq\n"); | ||
369 | goto err_free; | ||
370 | } | ||
371 | |||
372 | INIT_WORK(&data->irq_work, exynos4_tmu_work); | ||
373 | |||
374 | data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
375 | if (!data->mem) { | ||
376 | ret = -ENOENT; | ||
377 | dev_err(&pdev->dev, "Failed to get platform resource\n"); | ||
378 | goto err_free; | ||
379 | } | ||
380 | |||
381 | data->mem = request_mem_region(data->mem->start, | ||
382 | resource_size(data->mem), pdev->name); | ||
383 | if (!data->mem) { | ||
384 | ret = -ENODEV; | ||
385 | dev_err(&pdev->dev, "Failed to request memory region\n"); | ||
386 | goto err_free; | ||
387 | } | ||
388 | |||
389 | data->base = ioremap(data->mem->start, resource_size(data->mem)); | ||
390 | if (!data->base) { | ||
391 | ret = -ENODEV; | ||
392 | dev_err(&pdev->dev, "Failed to ioremap memory\n"); | ||
393 | goto err_mem_region; | ||
394 | } | ||
395 | |||
396 | ret = request_irq(data->irq, exynos4_tmu_irq, | ||
397 | IRQF_TRIGGER_RISING, | ||
398 | "exynos4-tmu", data); | ||
399 | if (ret) { | ||
400 | dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq); | ||
401 | goto err_io_remap; | ||
402 | } | ||
403 | |||
404 | data->clk = clk_get(NULL, "tmu_apbif"); | ||
405 | if (IS_ERR(data->clk)) { | ||
406 | ret = PTR_ERR(data->clk); | ||
407 | dev_err(&pdev->dev, "Failed to get clock\n"); | ||
408 | goto err_irq; | ||
409 | } | ||
410 | |||
411 | data->pdata = pdata; | ||
412 | platform_set_drvdata(pdev, data); | ||
413 | mutex_init(&data->lock); | ||
414 | |||
415 | ret = exynos4_tmu_initialize(pdev); | ||
416 | if (ret) { | ||
417 | dev_err(&pdev->dev, "Failed to initialize TMU\n"); | ||
418 | goto err_clk; | ||
419 | } | ||
420 | |||
421 | ret = sysfs_create_group(&pdev->dev.kobj, &exynos4_tmu_attr_group); | ||
422 | if (ret) { | ||
423 | dev_err(&pdev->dev, "Failed to create sysfs group\n"); | ||
424 | goto err_clk; | ||
425 | } | ||
426 | |||
427 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
428 | if (IS_ERR(data->hwmon_dev)) { | ||
429 | ret = PTR_ERR(data->hwmon_dev); | ||
430 | dev_err(&pdev->dev, "Failed to register hwmon device\n"); | ||
431 | goto err_create_group; | ||
432 | } | ||
433 | |||
434 | exynos4_tmu_control(pdev, true); | ||
435 | |||
436 | return 0; | ||
437 | |||
438 | err_create_group: | ||
439 | sysfs_remove_group(&pdev->dev.kobj, &exynos4_tmu_attr_group); | ||
440 | err_clk: | ||
441 | platform_set_drvdata(pdev, NULL); | ||
442 | clk_put(data->clk); | ||
443 | err_irq: | ||
444 | free_irq(data->irq, data); | ||
445 | err_io_remap: | ||
446 | iounmap(data->base); | ||
447 | err_mem_region: | ||
448 | release_mem_region(data->mem->start, resource_size(data->mem)); | ||
449 | err_free: | ||
450 | kfree(data); | ||
451 | |||
452 | return ret; | ||
453 | } | ||
454 | |||
455 | static int __devexit exynos4_tmu_remove(struct platform_device *pdev) | ||
456 | { | ||
457 | struct exynos4_tmu_data *data = platform_get_drvdata(pdev); | ||
458 | |||
459 | exynos4_tmu_control(pdev, false); | ||
460 | |||
461 | hwmon_device_unregister(data->hwmon_dev); | ||
462 | sysfs_remove_group(&pdev->dev.kobj, &exynos4_tmu_attr_group); | ||
463 | |||
464 | clk_put(data->clk); | ||
465 | |||
466 | free_irq(data->irq, data); | ||
467 | |||
468 | iounmap(data->base); | ||
469 | release_mem_region(data->mem->start, resource_size(data->mem)); | ||
470 | |||
471 | platform_set_drvdata(pdev, NULL); | ||
472 | |||
473 | kfree(data); | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | #ifdef CONFIG_PM | ||
479 | static int exynos4_tmu_suspend(struct platform_device *pdev, pm_message_t state) | ||
480 | { | ||
481 | exynos4_tmu_control(pdev, false); | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static int exynos4_tmu_resume(struct platform_device *pdev) | ||
487 | { | ||
488 | exynos4_tmu_initialize(pdev); | ||
489 | exynos4_tmu_control(pdev, true); | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | #else | ||
494 | #define exynos4_tmu_suspend NULL | ||
495 | #define exynos4_tmu_resume NULL | ||
496 | #endif | ||
497 | |||
498 | static struct platform_driver exynos4_tmu_driver = { | ||
499 | .driver = { | ||
500 | .name = "exynos4-tmu", | ||
501 | .owner = THIS_MODULE, | ||
502 | }, | ||
503 | .probe = exynos4_tmu_probe, | ||
504 | .remove = __devexit_p(exynos4_tmu_remove), | ||
505 | .suspend = exynos4_tmu_suspend, | ||
506 | .resume = exynos4_tmu_resume, | ||
507 | }; | ||
508 | |||
509 | static int __init exynos4_tmu_driver_init(void) | ||
510 | { | ||
511 | return platform_driver_register(&exynos4_tmu_driver); | ||
512 | } | ||
513 | module_init(exynos4_tmu_driver_init); | ||
514 | |||
515 | static void __exit exynos4_tmu_driver_exit(void) | ||
516 | { | ||
517 | platform_driver_unregister(&exynos4_tmu_driver); | ||
518 | } | ||
519 | module_exit(exynos4_tmu_driver_exit); | ||
520 | |||
521 | MODULE_DESCRIPTION("EXYNOS4 TMU Driver"); | ||
522 | MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); | ||
523 | MODULE_LICENSE("GPL"); | ||
524 | MODULE_ALIAS("platform:exynos4-tmu"); | ||
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 2d96ed2bf8ed..59dd881c71d8 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -605,7 +605,7 @@ static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = { | |||
605 | 605 | ||
606 | /* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the | 606 | /* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the |
607 | standard models */ | 607 | standard models */ |
608 | static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { | 608 | static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[3][7] = { { |
609 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, | 609 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, |
610 | show_pwm_auto_point_channel, | 610 | show_pwm_auto_point_channel, |
611 | store_pwm_auto_point_channel, 0, 0), | 611 | store_pwm_auto_point_channel, 0, 0), |
@@ -627,7 +627,7 @@ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { | |||
627 | 0, 0), | 627 | 0, 0), |
628 | SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, | 628 | SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, |
629 | show_pwm_auto_point_temp_hyst, NULL, 3, 0), | 629 | show_pwm_auto_point_temp_hyst, NULL, 3, 0), |
630 | 630 | }, { | |
631 | SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, | 631 | SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, |
632 | show_pwm_auto_point_channel, | 632 | show_pwm_auto_point_channel, |
633 | store_pwm_auto_point_channel, 0, 1), | 633 | store_pwm_auto_point_channel, 0, 1), |
@@ -649,7 +649,7 @@ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { | |||
649 | 0, 1), | 649 | 0, 1), |
650 | SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, | 650 | SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, |
651 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), | 651 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), |
652 | 652 | }, { | |
653 | SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, | 653 | SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, |
654 | show_pwm_auto_point_channel, | 654 | show_pwm_auto_point_channel, |
655 | store_pwm_auto_point_channel, 0, 2), | 655 | store_pwm_auto_point_channel, 0, 2), |
@@ -671,12 +671,12 @@ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { | |||
671 | 0, 2), | 671 | 0, 2), |
672 | SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, | 672 | SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, |
673 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), | 673 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), |
674 | }; | 674 | } }; |
675 | 675 | ||
676 | /* PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the | 676 | /* PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the |
677 | pwm setting when the temperature is above the pwmX_auto_point1_temp can be | 677 | pwm setting when the temperature is above the pwmX_auto_point1_temp can be |
678 | programmed instead of being hardcoded to 0xff */ | 678 | programmed instead of being hardcoded to 0xff */ |
679 | static struct sensor_device_attribute_2 f71869_auto_pwm_attr[] = { | 679 | static struct sensor_device_attribute_2 f71869_auto_pwm_attr[3][8] = { { |
680 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, | 680 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, |
681 | show_pwm_auto_point_channel, | 681 | show_pwm_auto_point_channel, |
682 | store_pwm_auto_point_channel, 0, 0), | 682 | store_pwm_auto_point_channel, 0, 0), |
@@ -701,7 +701,7 @@ static struct sensor_device_attribute_2 f71869_auto_pwm_attr[] = { | |||
701 | 0, 0), | 701 | 0, 0), |
702 | SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, | 702 | SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, |
703 | show_pwm_auto_point_temp_hyst, NULL, 3, 0), | 703 | show_pwm_auto_point_temp_hyst, NULL, 3, 0), |
704 | 704 | }, { | |
705 | SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, | 705 | SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, |
706 | show_pwm_auto_point_channel, | 706 | show_pwm_auto_point_channel, |
707 | store_pwm_auto_point_channel, 0, 1), | 707 | store_pwm_auto_point_channel, 0, 1), |
@@ -726,7 +726,7 @@ static struct sensor_device_attribute_2 f71869_auto_pwm_attr[] = { | |||
726 | 0, 1), | 726 | 0, 1), |
727 | SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, | 727 | SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, |
728 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), | 728 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), |
729 | 729 | }, { | |
730 | SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, | 730 | SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, |
731 | show_pwm_auto_point_channel, | 731 | show_pwm_auto_point_channel, |
732 | store_pwm_auto_point_channel, 0, 2), | 732 | store_pwm_auto_point_channel, 0, 2), |
@@ -751,7 +751,7 @@ static struct sensor_device_attribute_2 f71869_auto_pwm_attr[] = { | |||
751 | 0, 2), | 751 | 0, 2), |
752 | SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, | 752 | SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, |
753 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), | 753 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), |
754 | }; | 754 | } }; |
755 | 755 | ||
756 | /* PWM attr for the standard models */ | 756 | /* PWM attr for the standard models */ |
757 | static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { { | 757 | static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { { |
@@ -928,7 +928,7 @@ static struct sensor_device_attribute_2 f8000_fan_attr[] = { | |||
928 | /* PWM attr for the f8000, zones mapped to temp instead of to pwm! | 928 | /* PWM attr for the f8000, zones mapped to temp instead of to pwm! |
929 | Also the register block at offset A0 maps to TEMP1 (so our temp2, as the | 929 | Also the register block at offset A0 maps to TEMP1 (so our temp2, as the |
930 | F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */ | 930 | F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */ |
931 | static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = { | 931 | static struct sensor_device_attribute_2 f8000_auto_pwm_attr[3][14] = { { |
932 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, | 932 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, |
933 | show_pwm_auto_point_channel, | 933 | show_pwm_auto_point_channel, |
934 | store_pwm_auto_point_channel, 0, 0), | 934 | store_pwm_auto_point_channel, 0, 0), |
@@ -969,7 +969,7 @@ static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = { | |||
969 | show_pwm_auto_point_temp_hyst, NULL, 2, 2), | 969 | show_pwm_auto_point_temp_hyst, NULL, 2, 2), |
970 | SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO, | 970 | SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO, |
971 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), | 971 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), |
972 | 972 | }, { | |
973 | SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, | 973 | SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, |
974 | show_pwm_auto_point_channel, | 974 | show_pwm_auto_point_channel, |
975 | store_pwm_auto_point_channel, 0, 1), | 975 | store_pwm_auto_point_channel, 0, 1), |
@@ -1010,7 +1010,7 @@ static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = { | |||
1010 | show_pwm_auto_point_temp_hyst, NULL, 2, 0), | 1010 | show_pwm_auto_point_temp_hyst, NULL, 2, 0), |
1011 | SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO, | 1011 | SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO, |
1012 | show_pwm_auto_point_temp_hyst, NULL, 3, 0), | 1012 | show_pwm_auto_point_temp_hyst, NULL, 3, 0), |
1013 | 1013 | }, { | |
1014 | SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, | 1014 | SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, |
1015 | show_pwm_auto_point_channel, | 1015 | show_pwm_auto_point_channel, |
1016 | store_pwm_auto_point_channel, 0, 2), | 1016 | store_pwm_auto_point_channel, 0, 2), |
@@ -1051,7 +1051,7 @@ static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = { | |||
1051 | show_pwm_auto_point_temp_hyst, NULL, 2, 1), | 1051 | show_pwm_auto_point_temp_hyst, NULL, 2, 1), |
1052 | SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO, | 1052 | SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO, |
1053 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), | 1053 | show_pwm_auto_point_temp_hyst, NULL, 3, 1), |
1054 | }; | 1054 | } }; |
1055 | 1055 | ||
1056 | /* Super I/O functions */ | 1056 | /* Super I/O functions */ |
1057 | static inline int superio_inb(int base, int reg) | 1057 | static inline int superio_inb(int base, int reg) |
@@ -2154,6 +2154,104 @@ static void f71882fg_remove_sysfs_files(struct platform_device *pdev, | |||
2154 | device_remove_file(&pdev->dev, &attr[i].dev_attr); | 2154 | device_remove_file(&pdev->dev, &attr[i].dev_attr); |
2155 | } | 2155 | } |
2156 | 2156 | ||
2157 | static int __devinit f71882fg_create_fan_sysfs_files( | ||
2158 | struct platform_device *pdev, int idx) | ||
2159 | { | ||
2160 | struct f71882fg_data *data = platform_get_drvdata(pdev); | ||
2161 | int err; | ||
2162 | |||
2163 | /* Sanity check the pwm setting */ | ||
2164 | err = 0; | ||
2165 | switch (data->type) { | ||
2166 | case f71858fg: | ||
2167 | if (((data->pwm_enable >> (idx * 2)) & 3) == 3) | ||
2168 | err = 1; | ||
2169 | break; | ||
2170 | case f71862fg: | ||
2171 | if (((data->pwm_enable >> (idx * 2)) & 1) != 1) | ||
2172 | err = 1; | ||
2173 | break; | ||
2174 | case f8000: | ||
2175 | if (idx == 2) | ||
2176 | err = data->pwm_enable & 0x20; | ||
2177 | break; | ||
2178 | default: | ||
2179 | break; | ||
2180 | } | ||
2181 | if (err) { | ||
2182 | dev_err(&pdev->dev, | ||
2183 | "Invalid (reserved) pwm settings: 0x%02x, " | ||
2184 | "skipping fan %d\n", | ||
2185 | (data->pwm_enable >> (idx * 2)) & 3, idx + 1); | ||
2186 | return 0; /* This is a non fatal condition */ | ||
2187 | } | ||
2188 | |||
2189 | err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[idx][0], | ||
2190 | ARRAY_SIZE(fxxxx_fan_attr[0])); | ||
2191 | if (err) | ||
2192 | return err; | ||
2193 | |||
2194 | if (f71882fg_fan_has_beep[data->type]) { | ||
2195 | err = f71882fg_create_sysfs_files(pdev, | ||
2196 | &fxxxx_fan_beep_attr[idx], | ||
2197 | 1); | ||
2198 | if (err) | ||
2199 | return err; | ||
2200 | } | ||
2201 | |||
2202 | dev_info(&pdev->dev, "Fan: %d is in %s mode\n", idx + 1, | ||
2203 | (data->pwm_enable & (1 << (2 * idx))) ? "duty-cycle" : "RPM"); | ||
2204 | |||
2205 | /* Check for unsupported auto pwm settings */ | ||
2206 | switch (data->type) { | ||
2207 | case f71808e: | ||
2208 | case f71808a: | ||
2209 | case f71869: | ||
2210 | case f71869a: | ||
2211 | case f71889fg: | ||
2212 | case f71889ed: | ||
2213 | case f71889a: | ||
2214 | data->pwm_auto_point_mapping[idx] = | ||
2215 | f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(idx)); | ||
2216 | if ((data->pwm_auto_point_mapping[idx] & 0x80) || | ||
2217 | (data->pwm_auto_point_mapping[idx] & 3) == 0) { | ||
2218 | dev_warn(&pdev->dev, | ||
2219 | "Auto pwm controlled by raw digital " | ||
2220 | "data, disabling pwm auto_point " | ||
2221 | "sysfs attributes for fan %d\n", idx + 1); | ||
2222 | return 0; /* This is a non fatal condition */ | ||
2223 | } | ||
2224 | break; | ||
2225 | default: | ||
2226 | break; | ||
2227 | } | ||
2228 | |||
2229 | switch (data->type) { | ||
2230 | case f71862fg: | ||
2231 | err = f71882fg_create_sysfs_files(pdev, | ||
2232 | &f71862fg_auto_pwm_attr[idx][0], | ||
2233 | ARRAY_SIZE(f71862fg_auto_pwm_attr[0])); | ||
2234 | break; | ||
2235 | case f71808e: | ||
2236 | case f71869: | ||
2237 | err = f71882fg_create_sysfs_files(pdev, | ||
2238 | &f71869_auto_pwm_attr[idx][0], | ||
2239 | ARRAY_SIZE(f71869_auto_pwm_attr[0])); | ||
2240 | break; | ||
2241 | case f8000: | ||
2242 | err = f71882fg_create_sysfs_files(pdev, | ||
2243 | &f8000_auto_pwm_attr[idx][0], | ||
2244 | ARRAY_SIZE(f8000_auto_pwm_attr[0])); | ||
2245 | break; | ||
2246 | default: | ||
2247 | err = f71882fg_create_sysfs_files(pdev, | ||
2248 | &fxxxx_auto_pwm_attr[idx][0], | ||
2249 | ARRAY_SIZE(fxxxx_auto_pwm_attr[0])); | ||
2250 | } | ||
2251 | |||
2252 | return err; | ||
2253 | } | ||
2254 | |||
2157 | static int __devinit f71882fg_probe(struct platform_device *pdev) | 2255 | static int __devinit f71882fg_probe(struct platform_device *pdev) |
2158 | { | 2256 | { |
2159 | struct f71882fg_data *data; | 2257 | struct f71882fg_data *data; |
@@ -2272,117 +2370,29 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2272 | data->pwm_enable = | 2370 | data->pwm_enable = |
2273 | f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); | 2371 | f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); |
2274 | 2372 | ||
2275 | /* Sanity check the pwm settings */ | 2373 | for (i = 0; i < nr_fans; i++) { |
2276 | switch (data->type) { | 2374 | err = f71882fg_create_fan_sysfs_files(pdev, i); |
2277 | case f71858fg: | ||
2278 | err = 0; | ||
2279 | for (i = 0; i < nr_fans; i++) | ||
2280 | if (((data->pwm_enable >> (i * 2)) & 3) == 3) | ||
2281 | err = 1; | ||
2282 | break; | ||
2283 | case f71862fg: | ||
2284 | err = (data->pwm_enable & 0x15) != 0x15; | ||
2285 | break; | ||
2286 | case f8000: | ||
2287 | err = data->pwm_enable & 0x20; | ||
2288 | break; | ||
2289 | default: | ||
2290 | err = 0; | ||
2291 | break; | ||
2292 | } | ||
2293 | if (err) { | ||
2294 | dev_err(&pdev->dev, | ||
2295 | "Invalid (reserved) pwm settings: 0x%02x\n", | ||
2296 | (unsigned int)data->pwm_enable); | ||
2297 | err = -ENODEV; | ||
2298 | goto exit_unregister_sysfs; | ||
2299 | } | ||
2300 | |||
2301 | err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[0][0], | ||
2302 | ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans); | ||
2303 | if (err) | ||
2304 | goto exit_unregister_sysfs; | ||
2305 | |||
2306 | if (f71882fg_fan_has_beep[data->type]) { | ||
2307 | err = f71882fg_create_sysfs_files(pdev, | ||
2308 | fxxxx_fan_beep_attr, nr_fans); | ||
2309 | if (err) | 2375 | if (err) |
2310 | goto exit_unregister_sysfs; | 2376 | goto exit_unregister_sysfs; |
2311 | } | 2377 | } |
2312 | 2378 | ||
2313 | switch (data->type) { | 2379 | /* Some types have 1 extra fan with limited functionality */ |
2314 | case f71808e: | ||
2315 | case f71808a: | ||
2316 | case f71869: | ||
2317 | case f71869a: | ||
2318 | case f71889fg: | ||
2319 | case f71889ed: | ||
2320 | case f71889a: | ||
2321 | for (i = 0; i < nr_fans; i++) { | ||
2322 | data->pwm_auto_point_mapping[i] = | ||
2323 | f71882fg_read8(data, | ||
2324 | F71882FG_REG_POINT_MAPPING(i)); | ||
2325 | if ((data->pwm_auto_point_mapping[i] & 0x80) || | ||
2326 | (data->pwm_auto_point_mapping[i] & 3) == 0) | ||
2327 | break; | ||
2328 | } | ||
2329 | if (i != nr_fans) { | ||
2330 | dev_warn(&pdev->dev, | ||
2331 | "Auto pwm controlled by raw digital " | ||
2332 | "data, disabling pwm auto_point " | ||
2333 | "sysfs attributes\n"); | ||
2334 | goto no_pwm_auto_point; | ||
2335 | } | ||
2336 | break; | ||
2337 | default: | ||
2338 | break; | ||
2339 | } | ||
2340 | |||
2341 | switch (data->type) { | 2380 | switch (data->type) { |
2342 | case f71808a: | 2381 | case f71808a: |
2343 | err = f71882fg_create_sysfs_files(pdev, | 2382 | err = f71882fg_create_sysfs_files(pdev, |
2344 | &fxxxx_auto_pwm_attr[0][0], | ||
2345 | ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); | ||
2346 | if (err) | ||
2347 | goto exit_unregister_sysfs; | ||
2348 | err = f71882fg_create_sysfs_files(pdev, | ||
2349 | f71808a_fan3_attr, | 2383 | f71808a_fan3_attr, |
2350 | ARRAY_SIZE(f71808a_fan3_attr)); | 2384 | ARRAY_SIZE(f71808a_fan3_attr)); |
2351 | break; | 2385 | break; |
2352 | case f71862fg: | ||
2353 | err = f71882fg_create_sysfs_files(pdev, | ||
2354 | f71862fg_auto_pwm_attr, | ||
2355 | ARRAY_SIZE(f71862fg_auto_pwm_attr)); | ||
2356 | break; | ||
2357 | case f71808e: | ||
2358 | case f71869: | ||
2359 | err = f71882fg_create_sysfs_files(pdev, | ||
2360 | f71869_auto_pwm_attr, | ||
2361 | ARRAY_SIZE(f71869_auto_pwm_attr)); | ||
2362 | break; | ||
2363 | case f8000: | 2386 | case f8000: |
2364 | err = f71882fg_create_sysfs_files(pdev, | 2387 | err = f71882fg_create_sysfs_files(pdev, |
2365 | f8000_fan_attr, | 2388 | f8000_fan_attr, |
2366 | ARRAY_SIZE(f8000_fan_attr)); | 2389 | ARRAY_SIZE(f8000_fan_attr)); |
2367 | if (err) | ||
2368 | goto exit_unregister_sysfs; | ||
2369 | err = f71882fg_create_sysfs_files(pdev, | ||
2370 | f8000_auto_pwm_attr, | ||
2371 | ARRAY_SIZE(f8000_auto_pwm_attr)); | ||
2372 | break; | 2390 | break; |
2373 | default: | 2391 | default: |
2374 | err = f71882fg_create_sysfs_files(pdev, | 2392 | break; |
2375 | &fxxxx_auto_pwm_attr[0][0], | ||
2376 | ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); | ||
2377 | } | 2393 | } |
2378 | if (err) | 2394 | if (err) |
2379 | goto exit_unregister_sysfs; | 2395 | goto exit_unregister_sysfs; |
2380 | |||
2381 | no_pwm_auto_point: | ||
2382 | for (i = 0; i < nr_fans; i++) | ||
2383 | dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1, | ||
2384 | (data->pwm_enable & (1 << 2 * i)) ? | ||
2385 | "duty-cycle" : "RPM"); | ||
2386 | } | 2396 | } |
2387 | 2397 | ||
2388 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | 2398 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
@@ -2476,22 +2486,23 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2476 | break; | 2486 | break; |
2477 | case f71862fg: | 2487 | case f71862fg: |
2478 | f71882fg_remove_sysfs_files(pdev, | 2488 | f71882fg_remove_sysfs_files(pdev, |
2479 | f71862fg_auto_pwm_attr, | 2489 | &f71862fg_auto_pwm_attr[0][0], |
2480 | ARRAY_SIZE(f71862fg_auto_pwm_attr)); | 2490 | ARRAY_SIZE(f71862fg_auto_pwm_attr[0]) * |
2491 | nr_fans); | ||
2481 | break; | 2492 | break; |
2482 | case f71808e: | 2493 | case f71808e: |
2483 | case f71869: | 2494 | case f71869: |
2484 | f71882fg_remove_sysfs_files(pdev, | 2495 | f71882fg_remove_sysfs_files(pdev, |
2485 | f71869_auto_pwm_attr, | 2496 | &f71869_auto_pwm_attr[0][0], |
2486 | ARRAY_SIZE(f71869_auto_pwm_attr)); | 2497 | ARRAY_SIZE(f71869_auto_pwm_attr[0]) * nr_fans); |
2487 | break; | 2498 | break; |
2488 | case f8000: | 2499 | case f8000: |
2489 | f71882fg_remove_sysfs_files(pdev, | 2500 | f71882fg_remove_sysfs_files(pdev, |
2490 | f8000_fan_attr, | 2501 | f8000_fan_attr, |
2491 | ARRAY_SIZE(f8000_fan_attr)); | 2502 | ARRAY_SIZE(f8000_fan_attr)); |
2492 | f71882fg_remove_sysfs_files(pdev, | 2503 | f71882fg_remove_sysfs_files(pdev, |
2493 | f8000_auto_pwm_attr, | 2504 | &f8000_auto_pwm_attr[0][0], |
2494 | ARRAY_SIZE(f8000_auto_pwm_attr)); | 2505 | ARRAY_SIZE(f8000_auto_pwm_attr[0]) * nr_fans); |
2495 | break; | 2506 | break; |
2496 | default: | 2507 | default: |
2497 | f71882fg_remove_sysfs_files(pdev, | 2508 | f71882fg_remove_sysfs_files(pdev, |
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index e7ae5743e181..a13e2da97e30 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c | |||
@@ -591,7 +591,7 @@ static int gl518_remove(struct i2c_client *client) | |||
591 | static int gl518_read_value(struct i2c_client *client, u8 reg) | 591 | static int gl518_read_value(struct i2c_client *client, u8 reg) |
592 | { | 592 | { |
593 | if ((reg >= 0x07) && (reg <= 0x0c)) | 593 | if ((reg >= 0x07) && (reg <= 0x0c)) |
594 | return swab16(i2c_smbus_read_word_data(client, reg)); | 594 | return i2c_smbus_read_word_swapped(client, reg); |
595 | else | 595 | else |
596 | return i2c_smbus_read_byte_data(client, reg); | 596 | return i2c_smbus_read_byte_data(client, reg); |
597 | } | 597 | } |
@@ -599,7 +599,7 @@ static int gl518_read_value(struct i2c_client *client, u8 reg) | |||
599 | static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value) | 599 | static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value) |
600 | { | 600 | { |
601 | if ((reg >= 0x07) && (reg <= 0x0c)) | 601 | if ((reg >= 0x07) && (reg <= 0x0c)) |
602 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | 602 | return i2c_smbus_write_word_swapped(client, reg, value); |
603 | else | 603 | else |
604 | return i2c_smbus_write_byte_data(client, reg, value); | 604 | return i2c_smbus_write_byte_data(client, reg, value); |
605 | } | 605 | } |
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 131ea8625f08..cd6085bbfba7 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c | |||
@@ -821,7 +821,7 @@ static int gl520_remove(struct i2c_client *client) | |||
821 | static int gl520_read_value(struct i2c_client *client, u8 reg) | 821 | static int gl520_read_value(struct i2c_client *client, u8 reg) |
822 | { | 822 | { |
823 | if ((reg >= 0x07) && (reg <= 0x0c)) | 823 | if ((reg >= 0x07) && (reg <= 0x0c)) |
824 | return swab16(i2c_smbus_read_word_data(client, reg)); | 824 | return i2c_smbus_read_word_swapped(client, reg); |
825 | else | 825 | else |
826 | return i2c_smbus_read_byte_data(client, reg); | 826 | return i2c_smbus_read_byte_data(client, reg); |
827 | } | 827 | } |
@@ -829,7 +829,7 @@ static int gl520_read_value(struct i2c_client *client, u8 reg) | |||
829 | static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value) | 829 | static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value) |
830 | { | 830 | { |
831 | if ((reg >= 0x07) && (reg <= 0x0c)) | 831 | if ((reg >= 0x07) && (reg <= 0x0c)) |
832 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | 832 | return i2c_smbus_write_word_swapped(client, reg, value); |
833 | else | 833 | else |
834 | return i2c_smbus_write_byte_data(client, reg, value); | 834 | return i2c_smbus_write_byte_data(client, reg, value); |
835 | } | 835 | } |
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index a61e7815a2a9..6460487e41b5 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -27,8 +27,7 @@ | |||
27 | 27 | ||
28 | static struct class *hwmon_class; | 28 | static struct class *hwmon_class; |
29 | 29 | ||
30 | static DEFINE_IDR(hwmon_idr); | 30 | static DEFINE_IDA(hwmon_ida); |
31 | static DEFINE_SPINLOCK(idr_lock); | ||
32 | 31 | ||
33 | /** | 32 | /** |
34 | * hwmon_device_register - register w/ hwmon | 33 | * hwmon_device_register - register w/ hwmon |
@@ -42,30 +41,17 @@ static DEFINE_SPINLOCK(idr_lock); | |||
42 | struct device *hwmon_device_register(struct device *dev) | 41 | struct device *hwmon_device_register(struct device *dev) |
43 | { | 42 | { |
44 | struct device *hwdev; | 43 | struct device *hwdev; |
45 | int id, err; | 44 | int id; |
46 | |||
47 | again: | ||
48 | if (unlikely(idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0)) | ||
49 | return ERR_PTR(-ENOMEM); | ||
50 | |||
51 | spin_lock(&idr_lock); | ||
52 | err = idr_get_new(&hwmon_idr, NULL, &id); | ||
53 | spin_unlock(&idr_lock); | ||
54 | 45 | ||
55 | if (unlikely(err == -EAGAIN)) | 46 | id = ida_simple_get(&hwmon_ida, 0, 0, GFP_KERNEL); |
56 | goto again; | 47 | if (id < 0) |
57 | else if (unlikely(err)) | 48 | return ERR_PTR(id); |
58 | return ERR_PTR(err); | ||
59 | 49 | ||
60 | id = id & MAX_ID_MASK; | ||
61 | hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL, | 50 | hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL, |
62 | HWMON_ID_FORMAT, id); | 51 | HWMON_ID_FORMAT, id); |
63 | 52 | ||
64 | if (IS_ERR(hwdev)) { | 53 | if (IS_ERR(hwdev)) |
65 | spin_lock(&idr_lock); | 54 | ida_simple_remove(&hwmon_ida, id); |
66 | idr_remove(&hwmon_idr, id); | ||
67 | spin_unlock(&idr_lock); | ||
68 | } | ||
69 | 55 | ||
70 | return hwdev; | 56 | return hwdev; |
71 | } | 57 | } |
@@ -81,9 +67,7 @@ void hwmon_device_unregister(struct device *dev) | |||
81 | 67 | ||
82 | if (likely(sscanf(dev_name(dev), HWMON_ID_FORMAT, &id) == 1)) { | 68 | if (likely(sscanf(dev_name(dev), HWMON_ID_FORMAT, &id) == 1)) { |
83 | device_unregister(dev); | 69 | device_unregister(dev); |
84 | spin_lock(&idr_lock); | 70 | ida_simple_remove(&hwmon_ida, id); |
85 | idr_remove(&hwmon_idr, id); | ||
86 | spin_unlock(&idr_lock); | ||
87 | } else | 71 | } else |
88 | dev_dbg(dev->parent, | 72 | dev_dbg(dev->parent, |
89 | "hwmon_device_unregister() failed: bad class ID!\n"); | 73 | "hwmon_device_unregister() failed: bad class ID!\n"); |
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index c316294c48b4..6a967d7dbdee 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c | |||
@@ -88,8 +88,7 @@ | |||
88 | #define AEM_MIN_POWER_INTERVAL 200 | 88 | #define AEM_MIN_POWER_INTERVAL 200 |
89 | #define UJ_PER_MJ 1000L | 89 | #define UJ_PER_MJ 1000L |
90 | 90 | ||
91 | static DEFINE_IDR(aem_idr); | 91 | static DEFINE_IDA(aem_ida); |
92 | static DEFINE_SPINLOCK(aem_idr_lock); | ||
93 | 92 | ||
94 | static struct platform_driver aem_driver = { | 93 | static struct platform_driver aem_driver = { |
95 | .driver = { | 94 | .driver = { |
@@ -148,8 +147,9 @@ struct aem_data { | |||
148 | int id; | 147 | int id; |
149 | struct aem_ipmi_data ipmi; | 148 | struct aem_ipmi_data ipmi; |
150 | 149 | ||
151 | /* Function to update sensors */ | 150 | /* Function and buffer to update sensors */ |
152 | void (*update)(struct aem_data *data); | 151 | void (*update)(struct aem_data *data); |
152 | struct aem_read_sensor_resp *rs_resp; | ||
153 | 153 | ||
154 | /* | 154 | /* |
155 | * AEM 1.x sensors: | 155 | * AEM 1.x sensors: |
@@ -246,8 +246,6 @@ static void aem_bmc_gone(int iface); | |||
246 | static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); | 246 | static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); |
247 | 247 | ||
248 | static void aem_remove_sensors(struct aem_data *data); | 248 | static void aem_remove_sensors(struct aem_data *data); |
249 | static int aem_init_aem1(struct aem_ipmi_data *probe); | ||
250 | static int aem_init_aem2(struct aem_ipmi_data *probe); | ||
251 | static int aem1_find_sensors(struct aem_data *data); | 249 | static int aem1_find_sensors(struct aem_data *data); |
252 | static int aem2_find_sensors(struct aem_data *data); | 250 | static int aem2_find_sensors(struct aem_data *data); |
253 | static void update_aem1_sensors(struct aem_data *data); | 251 | static void update_aem1_sensors(struct aem_data *data); |
@@ -356,47 +354,16 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
356 | complete(&data->read_complete); | 354 | complete(&data->read_complete); |
357 | } | 355 | } |
358 | 356 | ||
359 | /* ID functions */ | ||
360 | |||
361 | /* Obtain an id */ | ||
362 | static int aem_idr_get(int *id) | ||
363 | { | ||
364 | int i, err; | ||
365 | |||
366 | again: | ||
367 | if (unlikely(!idr_pre_get(&aem_idr, GFP_KERNEL))) | ||
368 | return -ENOMEM; | ||
369 | |||
370 | spin_lock(&aem_idr_lock); | ||
371 | err = idr_get_new(&aem_idr, NULL, &i); | ||
372 | spin_unlock(&aem_idr_lock); | ||
373 | |||
374 | if (unlikely(err == -EAGAIN)) | ||
375 | goto again; | ||
376 | else if (unlikely(err)) | ||
377 | return err; | ||
378 | |||
379 | *id = i & MAX_ID_MASK; | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | /* Release an object ID */ | ||
384 | static void aem_idr_put(int id) | ||
385 | { | ||
386 | spin_lock(&aem_idr_lock); | ||
387 | idr_remove(&aem_idr, id); | ||
388 | spin_unlock(&aem_idr_lock); | ||
389 | } | ||
390 | |||
391 | /* Sensor support functions */ | 357 | /* Sensor support functions */ |
392 | 358 | ||
393 | /* Read a sensor value */ | 359 | /* Read a sensor value; must be called with data->lock held */ |
394 | static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, | 360 | static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, |
395 | void *buf, size_t size) | 361 | void *buf, size_t size) |
396 | { | 362 | { |
397 | int rs_size, res; | 363 | int rs_size, res; |
398 | struct aem_read_sensor_req rs_req; | 364 | struct aem_read_sensor_req rs_req; |
399 | struct aem_read_sensor_resp *rs_resp; | 365 | /* Use preallocated rx buffer */ |
366 | struct aem_read_sensor_resp *rs_resp = data->rs_resp; | ||
400 | struct aem_ipmi_data *ipmi = &data->ipmi; | 367 | struct aem_ipmi_data *ipmi = &data->ipmi; |
401 | 368 | ||
402 | /* AEM registers are 1, 2, 4 or 8 bytes */ | 369 | /* AEM registers are 1, 2, 4 or 8 bytes */ |
@@ -422,10 +389,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, | |||
422 | ipmi->tx_message.data_len = sizeof(rs_req); | 389 | ipmi->tx_message.data_len = sizeof(rs_req); |
423 | 390 | ||
424 | rs_size = sizeof(*rs_resp) + size; | 391 | rs_size = sizeof(*rs_resp) + size; |
425 | rs_resp = kzalloc(rs_size, GFP_KERNEL); | ||
426 | if (!rs_resp) | ||
427 | return -ENOMEM; | ||
428 | |||
429 | ipmi->rx_msg_data = rs_resp; | 392 | ipmi->rx_msg_data = rs_resp; |
430 | ipmi->rx_msg_len = rs_size; | 393 | ipmi->rx_msg_len = rs_size; |
431 | 394 | ||
@@ -468,7 +431,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, | |||
468 | res = 0; | 431 | res = 0; |
469 | 432 | ||
470 | out: | 433 | out: |
471 | kfree(rs_resp); | ||
472 | return res; | 434 | return res; |
473 | } | 435 | } |
474 | 436 | ||
@@ -526,11 +488,12 @@ static void aem_delete(struct aem_data *data) | |||
526 | { | 488 | { |
527 | list_del(&data->list); | 489 | list_del(&data->list); |
528 | aem_remove_sensors(data); | 490 | aem_remove_sensors(data); |
491 | kfree(data->rs_resp); | ||
529 | hwmon_device_unregister(data->hwmon_dev); | 492 | hwmon_device_unregister(data->hwmon_dev); |
530 | ipmi_destroy_user(data->ipmi.user); | 493 | ipmi_destroy_user(data->ipmi.user); |
531 | platform_set_drvdata(data->pdev, NULL); | 494 | platform_set_drvdata(data->pdev, NULL); |
532 | platform_device_unregister(data->pdev); | 495 | platform_device_unregister(data->pdev); |
533 | aem_idr_put(data->id); | 496 | ida_simple_remove(&aem_ida, data->id); |
534 | kfree(data); | 497 | kfree(data); |
535 | } | 498 | } |
536 | 499 | ||
@@ -587,7 +550,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | |||
587 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; | 550 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; |
588 | 551 | ||
589 | /* Create sub-device for this fw instance */ | 552 | /* Create sub-device for this fw instance */ |
590 | if (aem_idr_get(&data->id)) | 553 | data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL); |
554 | if (data->id < 0) | ||
591 | goto id_err; | 555 | goto id_err; |
592 | 556 | ||
593 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 557 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
@@ -602,24 +566,31 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | |||
602 | platform_set_drvdata(data->pdev, data); | 566 | platform_set_drvdata(data->pdev, data); |
603 | 567 | ||
604 | /* Set up IPMI interface */ | 568 | /* Set up IPMI interface */ |
605 | if (aem_init_ipmi_data(&data->ipmi, probe->interface, | 569 | res = aem_init_ipmi_data(&data->ipmi, probe->interface, |
606 | probe->bmc_device)) | 570 | probe->bmc_device); |
571 | if (res) | ||
607 | goto ipmi_err; | 572 | goto ipmi_err; |
608 | 573 | ||
609 | /* Register with hwmon */ | 574 | /* Register with hwmon */ |
610 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); | 575 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); |
611 | |||
612 | if (IS_ERR(data->hwmon_dev)) { | 576 | if (IS_ERR(data->hwmon_dev)) { |
613 | dev_err(&data->pdev->dev, "Unable to register hwmon " | 577 | dev_err(&data->pdev->dev, "Unable to register hwmon " |
614 | "device for IPMI interface %d\n", | 578 | "device for IPMI interface %d\n", |
615 | probe->interface); | 579 | probe->interface); |
580 | res = PTR_ERR(data->hwmon_dev); | ||
616 | goto hwmon_reg_err; | 581 | goto hwmon_reg_err; |
617 | } | 582 | } |
618 | 583 | ||
619 | data->update = update_aem1_sensors; | 584 | data->update = update_aem1_sensors; |
585 | data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL); | ||
586 | if (!data->rs_resp) { | ||
587 | res = -ENOMEM; | ||
588 | goto alloc_resp_err; | ||
589 | } | ||
620 | 590 | ||
621 | /* Find sensors */ | 591 | /* Find sensors */ |
622 | if (aem1_find_sensors(data)) | 592 | res = aem1_find_sensors(data); |
593 | if (res) | ||
623 | goto sensor_err; | 594 | goto sensor_err; |
624 | 595 | ||
625 | /* Add to our list of AEM devices */ | 596 | /* Add to our list of AEM devices */ |
@@ -631,6 +602,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | |||
631 | return 0; | 602 | return 0; |
632 | 603 | ||
633 | sensor_err: | 604 | sensor_err: |
605 | kfree(data->rs_resp); | ||
606 | alloc_resp_err: | ||
634 | hwmon_device_unregister(data->hwmon_dev); | 607 | hwmon_device_unregister(data->hwmon_dev); |
635 | hwmon_reg_err: | 608 | hwmon_reg_err: |
636 | ipmi_destroy_user(data->ipmi.user); | 609 | ipmi_destroy_user(data->ipmi.user); |
@@ -638,7 +611,7 @@ ipmi_err: | |||
638 | platform_set_drvdata(data->pdev, NULL); | 611 | platform_set_drvdata(data->pdev, NULL); |
639 | platform_device_unregister(data->pdev); | 612 | platform_device_unregister(data->pdev); |
640 | dev_err: | 613 | dev_err: |
641 | aem_idr_put(data->id); | 614 | ida_simple_remove(&aem_ida, data->id); |
642 | id_err: | 615 | id_err: |
643 | kfree(data); | 616 | kfree(data); |
644 | 617 | ||
@@ -646,7 +619,7 @@ id_err: | |||
646 | } | 619 | } |
647 | 620 | ||
648 | /* Find and initialize all AEM1 instances */ | 621 | /* Find and initialize all AEM1 instances */ |
649 | static int aem_init_aem1(struct aem_ipmi_data *probe) | 622 | static void aem_init_aem1(struct aem_ipmi_data *probe) |
650 | { | 623 | { |
651 | int num, i, err; | 624 | int num, i, err; |
652 | 625 | ||
@@ -657,11 +630,8 @@ static int aem_init_aem1(struct aem_ipmi_data *probe) | |||
657 | dev_err(probe->bmc_device, | 630 | dev_err(probe->bmc_device, |
658 | "Error %d initializing AEM1 0x%X\n", | 631 | "Error %d initializing AEM1 0x%X\n", |
659 | err, i); | 632 | err, i); |
660 | return err; | ||
661 | } | 633 | } |
662 | } | 634 | } |
663 | |||
664 | return 0; | ||
665 | } | 635 | } |
666 | 636 | ||
667 | /* Probe functions for AEM2 devices */ | 637 | /* Probe functions for AEM2 devices */ |
@@ -720,7 +690,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
720 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; | 690 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; |
721 | 691 | ||
722 | /* Create sub-device for this fw instance */ | 692 | /* Create sub-device for this fw instance */ |
723 | if (aem_idr_get(&data->id)) | 693 | data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL); |
694 | if (data->id < 0) | ||
724 | goto id_err; | 695 | goto id_err; |
725 | 696 | ||
726 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 697 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
@@ -735,24 +706,31 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
735 | platform_set_drvdata(data->pdev, data); | 706 | platform_set_drvdata(data->pdev, data); |
736 | 707 | ||
737 | /* Set up IPMI interface */ | 708 | /* Set up IPMI interface */ |
738 | if (aem_init_ipmi_data(&data->ipmi, probe->interface, | 709 | res = aem_init_ipmi_data(&data->ipmi, probe->interface, |
739 | probe->bmc_device)) | 710 | probe->bmc_device); |
711 | if (res) | ||
740 | goto ipmi_err; | 712 | goto ipmi_err; |
741 | 713 | ||
742 | /* Register with hwmon */ | 714 | /* Register with hwmon */ |
743 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); | 715 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); |
744 | |||
745 | if (IS_ERR(data->hwmon_dev)) { | 716 | if (IS_ERR(data->hwmon_dev)) { |
746 | dev_err(&data->pdev->dev, "Unable to register hwmon " | 717 | dev_err(&data->pdev->dev, "Unable to register hwmon " |
747 | "device for IPMI interface %d\n", | 718 | "device for IPMI interface %d\n", |
748 | probe->interface); | 719 | probe->interface); |
720 | res = PTR_ERR(data->hwmon_dev); | ||
749 | goto hwmon_reg_err; | 721 | goto hwmon_reg_err; |
750 | } | 722 | } |
751 | 723 | ||
752 | data->update = update_aem2_sensors; | 724 | data->update = update_aem2_sensors; |
725 | data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL); | ||
726 | if (!data->rs_resp) { | ||
727 | res = -ENOMEM; | ||
728 | goto alloc_resp_err; | ||
729 | } | ||
753 | 730 | ||
754 | /* Find sensors */ | 731 | /* Find sensors */ |
755 | if (aem2_find_sensors(data)) | 732 | res = aem2_find_sensors(data); |
733 | if (res) | ||
756 | goto sensor_err; | 734 | goto sensor_err; |
757 | 735 | ||
758 | /* Add to our list of AEM devices */ | 736 | /* Add to our list of AEM devices */ |
@@ -764,6 +742,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
764 | return 0; | 742 | return 0; |
765 | 743 | ||
766 | sensor_err: | 744 | sensor_err: |
745 | kfree(data->rs_resp); | ||
746 | alloc_resp_err: | ||
767 | hwmon_device_unregister(data->hwmon_dev); | 747 | hwmon_device_unregister(data->hwmon_dev); |
768 | hwmon_reg_err: | 748 | hwmon_reg_err: |
769 | ipmi_destroy_user(data->ipmi.user); | 749 | ipmi_destroy_user(data->ipmi.user); |
@@ -771,7 +751,7 @@ ipmi_err: | |||
771 | platform_set_drvdata(data->pdev, NULL); | 751 | platform_set_drvdata(data->pdev, NULL); |
772 | platform_device_unregister(data->pdev); | 752 | platform_device_unregister(data->pdev); |
773 | dev_err: | 753 | dev_err: |
774 | aem_idr_put(data->id); | 754 | ida_simple_remove(&aem_ida, data->id); |
775 | id_err: | 755 | id_err: |
776 | kfree(data); | 756 | kfree(data); |
777 | 757 | ||
@@ -779,7 +759,7 @@ id_err: | |||
779 | } | 759 | } |
780 | 760 | ||
781 | /* Find and initialize all AEM2 instances */ | 761 | /* Find and initialize all AEM2 instances */ |
782 | static int aem_init_aem2(struct aem_ipmi_data *probe) | 762 | static void aem_init_aem2(struct aem_ipmi_data *probe) |
783 | { | 763 | { |
784 | struct aem_find_instance_resp fi_resp; | 764 | struct aem_find_instance_resp fi_resp; |
785 | int err; | 765 | int err; |
@@ -798,12 +778,9 @@ static int aem_init_aem2(struct aem_ipmi_data *probe) | |||
798 | dev_err(probe->bmc_device, | 778 | dev_err(probe->bmc_device, |
799 | "Error %d initializing AEM2 0x%X\n", | 779 | "Error %d initializing AEM2 0x%X\n", |
800 | err, fi_resp.module_handle); | 780 | err, fi_resp.module_handle); |
801 | return err; | ||
802 | } | 781 | } |
803 | i++; | 782 | i++; |
804 | } | 783 | } |
805 | |||
806 | return 0; | ||
807 | } | 784 | } |
808 | 785 | ||
809 | /* Probe a BMC for AEM firmware instances */ | 786 | /* Probe a BMC for AEM firmware instances */ |
diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 02cebb74e206..2d3d72805ff4 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c | |||
@@ -154,8 +154,6 @@ static int jc42_probe(struct i2c_client *client, | |||
154 | const struct i2c_device_id *id); | 154 | const struct i2c_device_id *id); |
155 | static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info); | 155 | static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info); |
156 | static int jc42_remove(struct i2c_client *client); | 156 | static int jc42_remove(struct i2c_client *client); |
157 | static int jc42_read_value(struct i2c_client *client, u8 reg); | ||
158 | static int jc42_write_value(struct i2c_client *client, u8 reg, u16 value); | ||
159 | 157 | ||
160 | static struct jc42_data *jc42_update_device(struct device *dev); | 158 | static struct jc42_data *jc42_update_device(struct device *dev); |
161 | 159 | ||
@@ -187,7 +185,7 @@ static int jc42_suspend(struct device *dev) | |||
187 | struct jc42_data *data = i2c_get_clientdata(client); | 185 | struct jc42_data *data = i2c_get_clientdata(client); |
188 | 186 | ||
189 | data->config |= JC42_CFG_SHUTDOWN; | 187 | data->config |= JC42_CFG_SHUTDOWN; |
190 | jc42_write_value(client, JC42_REG_CONFIG, data->config); | 188 | i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config); |
191 | return 0; | 189 | return 0; |
192 | } | 190 | } |
193 | 191 | ||
@@ -197,7 +195,7 @@ static int jc42_resume(struct device *dev) | |||
197 | struct jc42_data *data = i2c_get_clientdata(client); | 195 | struct jc42_data *data = i2c_get_clientdata(client); |
198 | 196 | ||
199 | data->config &= ~JC42_CFG_SHUTDOWN; | 197 | data->config &= ~JC42_CFG_SHUTDOWN; |
200 | jc42_write_value(client, JC42_REG_CONFIG, data->config); | 198 | i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config); |
201 | return 0; | 199 | return 0; |
202 | } | 200 | } |
203 | 201 | ||
@@ -315,7 +313,7 @@ static ssize_t set_##value(struct device *dev, \ | |||
315 | return -EINVAL; \ | 313 | return -EINVAL; \ |
316 | mutex_lock(&data->update_lock); \ | 314 | mutex_lock(&data->update_lock); \ |
317 | data->value = jc42_temp_to_reg(val, data->extended); \ | 315 | data->value = jc42_temp_to_reg(val, data->extended); \ |
318 | err = jc42_write_value(client, reg, data->value); \ | 316 | err = i2c_smbus_write_word_swapped(client, reg, data->value); \ |
319 | if (err < 0) \ | 317 | if (err < 0) \ |
320 | ret = err; \ | 318 | ret = err; \ |
321 | mutex_unlock(&data->update_lock); \ | 319 | mutex_unlock(&data->update_lock); \ |
@@ -357,7 +355,8 @@ static ssize_t set_temp_crit_hyst(struct device *dev, | |||
357 | data->config = (data->config | 355 | data->config = (data->config |
358 | & ~(JC42_CFG_HYST_MASK << JC42_CFG_HYST_SHIFT)) | 356 | & ~(JC42_CFG_HYST_MASK << JC42_CFG_HYST_SHIFT)) |
359 | | (hyst << JC42_CFG_HYST_SHIFT); | 357 | | (hyst << JC42_CFG_HYST_SHIFT); |
360 | err = jc42_write_value(client, JC42_REG_CONFIG, data->config); | 358 | err = i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, |
359 | data->config); | ||
361 | if (err < 0) | 360 | if (err < 0) |
362 | ret = err; | 361 | ret = err; |
363 | mutex_unlock(&data->update_lock); | 362 | mutex_unlock(&data->update_lock); |
@@ -452,10 +451,10 @@ static int jc42_detect(struct i2c_client *new_client, | |||
452 | I2C_FUNC_SMBUS_WORD_DATA)) | 451 | I2C_FUNC_SMBUS_WORD_DATA)) |
453 | return -ENODEV; | 452 | return -ENODEV; |
454 | 453 | ||
455 | cap = jc42_read_value(new_client, JC42_REG_CAP); | 454 | cap = i2c_smbus_read_word_swapped(new_client, JC42_REG_CAP); |
456 | config = jc42_read_value(new_client, JC42_REG_CONFIG); | 455 | config = i2c_smbus_read_word_swapped(new_client, JC42_REG_CONFIG); |
457 | manid = jc42_read_value(new_client, JC42_REG_MANID); | 456 | manid = i2c_smbus_read_word_swapped(new_client, JC42_REG_MANID); |
458 | devid = jc42_read_value(new_client, JC42_REG_DEVICEID); | 457 | devid = i2c_smbus_read_word_swapped(new_client, JC42_REG_DEVICEID); |
459 | 458 | ||
460 | if (cap < 0 || config < 0 || manid < 0 || devid < 0) | 459 | if (cap < 0 || config < 0 || manid < 0 || devid < 0) |
461 | return -ENODEV; | 460 | return -ENODEV; |
@@ -489,14 +488,14 @@ static int jc42_probe(struct i2c_client *new_client, | |||
489 | i2c_set_clientdata(new_client, data); | 488 | i2c_set_clientdata(new_client, data); |
490 | mutex_init(&data->update_lock); | 489 | mutex_init(&data->update_lock); |
491 | 490 | ||
492 | cap = jc42_read_value(new_client, JC42_REG_CAP); | 491 | cap = i2c_smbus_read_word_swapped(new_client, JC42_REG_CAP); |
493 | if (cap < 0) { | 492 | if (cap < 0) { |
494 | err = -EINVAL; | 493 | err = -EINVAL; |
495 | goto exit_free; | 494 | goto exit_free; |
496 | } | 495 | } |
497 | data->extended = !!(cap & JC42_CAP_RANGE); | 496 | data->extended = !!(cap & JC42_CAP_RANGE); |
498 | 497 | ||
499 | config = jc42_read_value(new_client, JC42_REG_CONFIG); | 498 | config = i2c_smbus_read_word_swapped(new_client, JC42_REG_CONFIG); |
500 | if (config < 0) { | 499 | if (config < 0) { |
501 | err = -EINVAL; | 500 | err = -EINVAL; |
502 | goto exit_free; | 501 | goto exit_free; |
@@ -504,7 +503,8 @@ static int jc42_probe(struct i2c_client *new_client, | |||
504 | data->orig_config = config; | 503 | data->orig_config = config; |
505 | if (config & JC42_CFG_SHUTDOWN) { | 504 | if (config & JC42_CFG_SHUTDOWN) { |
506 | config &= ~JC42_CFG_SHUTDOWN; | 505 | config &= ~JC42_CFG_SHUTDOWN; |
507 | jc42_write_value(new_client, JC42_REG_CONFIG, config); | 506 | i2c_smbus_write_word_swapped(new_client, JC42_REG_CONFIG, |
507 | config); | ||
508 | } | 508 | } |
509 | data->config = config; | 509 | data->config = config; |
510 | 510 | ||
@@ -535,25 +535,12 @@ static int jc42_remove(struct i2c_client *client) | |||
535 | hwmon_device_unregister(data->hwmon_dev); | 535 | hwmon_device_unregister(data->hwmon_dev); |
536 | sysfs_remove_group(&client->dev.kobj, &jc42_group); | 536 | sysfs_remove_group(&client->dev.kobj, &jc42_group); |
537 | if (data->config != data->orig_config) | 537 | if (data->config != data->orig_config) |
538 | jc42_write_value(client, JC42_REG_CONFIG, data->orig_config); | 538 | i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, |
539 | data->orig_config); | ||
539 | kfree(data); | 540 | kfree(data); |
540 | return 0; | 541 | return 0; |
541 | } | 542 | } |
542 | 543 | ||
543 | /* All registers are word-sized. */ | ||
544 | static int jc42_read_value(struct i2c_client *client, u8 reg) | ||
545 | { | ||
546 | int ret = i2c_smbus_read_word_data(client, reg); | ||
547 | if (ret < 0) | ||
548 | return ret; | ||
549 | return swab16(ret); | ||
550 | } | ||
551 | |||
552 | static int jc42_write_value(struct i2c_client *client, u8 reg, u16 value) | ||
553 | { | ||
554 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | ||
555 | } | ||
556 | |||
557 | static struct jc42_data *jc42_update_device(struct device *dev) | 544 | static struct jc42_data *jc42_update_device(struct device *dev) |
558 | { | 545 | { |
559 | struct i2c_client *client = to_i2c_client(dev); | 546 | struct i2c_client *client = to_i2c_client(dev); |
@@ -564,28 +551,29 @@ static struct jc42_data *jc42_update_device(struct device *dev) | |||
564 | mutex_lock(&data->update_lock); | 551 | mutex_lock(&data->update_lock); |
565 | 552 | ||
566 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 553 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { |
567 | val = jc42_read_value(client, JC42_REG_TEMP); | 554 | val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP); |
568 | if (val < 0) { | 555 | if (val < 0) { |
569 | ret = ERR_PTR(val); | 556 | ret = ERR_PTR(val); |
570 | goto abort; | 557 | goto abort; |
571 | } | 558 | } |
572 | data->temp_input = val; | 559 | data->temp_input = val; |
573 | 560 | ||
574 | val = jc42_read_value(client, JC42_REG_TEMP_CRITICAL); | 561 | val = i2c_smbus_read_word_swapped(client, |
562 | JC42_REG_TEMP_CRITICAL); | ||
575 | if (val < 0) { | 563 | if (val < 0) { |
576 | ret = ERR_PTR(val); | 564 | ret = ERR_PTR(val); |
577 | goto abort; | 565 | goto abort; |
578 | } | 566 | } |
579 | data->temp_crit = val; | 567 | data->temp_crit = val; |
580 | 568 | ||
581 | val = jc42_read_value(client, JC42_REG_TEMP_LOWER); | 569 | val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_LOWER); |
582 | if (val < 0) { | 570 | if (val < 0) { |
583 | ret = ERR_PTR(val); | 571 | ret = ERR_PTR(val); |
584 | goto abort; | 572 | goto abort; |
585 | } | 573 | } |
586 | data->temp_min = val; | 574 | data->temp_min = val; |
587 | 575 | ||
588 | val = jc42_read_value(client, JC42_REG_TEMP_UPPER); | 576 | val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_UPPER); |
589 | if (val < 0) { | 577 | if (val < 0) { |
590 | ret = ERR_PTR(val); | 578 | ret = ERR_PTR(val); |
591 | goto abort; | 579 | goto abort; |
diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index 29b9030d42c3..9e64d96620d3 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c | |||
@@ -34,7 +34,7 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, | |||
34 | #define LM73_REG_CTRL 0x04 | 34 | #define LM73_REG_CTRL 0x04 |
35 | #define LM73_REG_ID 0x07 | 35 | #define LM73_REG_ID 0x07 |
36 | 36 | ||
37 | #define LM73_ID 0x9001 /* or 0x190 after a swab16() */ | 37 | #define LM73_ID 0x9001 /* 0x0190, byte-swapped */ |
38 | #define DRVNAME "lm73" | 38 | #define DRVNAME "lm73" |
39 | #define LM73_TEMP_MIN (-40) | 39 | #define LM73_TEMP_MIN (-40) |
40 | #define LM73_TEMP_MAX 150 | 40 | #define LM73_TEMP_MAX 150 |
@@ -57,7 +57,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
57 | /* Write value */ | 57 | /* Write value */ |
58 | value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4), | 58 | value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4), |
59 | (LM73_TEMP_MAX*4)) << 5; | 59 | (LM73_TEMP_MAX*4)) << 5; |
60 | i2c_smbus_write_word_data(client, attr->index, swab16(value)); | 60 | i2c_smbus_write_word_swapped(client, attr->index, value); |
61 | return count; | 61 | return count; |
62 | } | 62 | } |
63 | 63 | ||
@@ -68,8 +68,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da, | |||
68 | struct i2c_client *client = to_i2c_client(dev); | 68 | struct i2c_client *client = to_i2c_client(dev); |
69 | /* use integer division instead of equivalent right shift to | 69 | /* use integer division instead of equivalent right shift to |
70 | guarantee arithmetic shift and preserve the sign */ | 70 | guarantee arithmetic shift and preserve the sign */ |
71 | int temp = ((s16) (swab16(i2c_smbus_read_word_data(client, | 71 | int temp = ((s16) (i2c_smbus_read_word_swapped(client, |
72 | attr->index)))*250) / 32; | 72 | attr->index))*250) / 32; |
73 | return sprintf(buf, "%d\n", temp); | 73 | return sprintf(buf, "%d\n", temp); |
74 | } | 74 | } |
75 | 75 | ||
@@ -150,17 +150,31 @@ static int lm73_detect(struct i2c_client *new_client, | |||
150 | struct i2c_board_info *info) | 150 | struct i2c_board_info *info) |
151 | { | 151 | { |
152 | struct i2c_adapter *adapter = new_client->adapter; | 152 | struct i2c_adapter *adapter = new_client->adapter; |
153 | u16 id; | 153 | int id, ctrl, conf; |
154 | u8 ctrl; | ||
155 | 154 | ||
156 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 155 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
157 | I2C_FUNC_SMBUS_WORD_DATA)) | 156 | I2C_FUNC_SMBUS_WORD_DATA)) |
158 | return -ENODEV; | 157 | return -ENODEV; |
159 | 158 | ||
159 | /* | ||
160 | * Do as much detection as possible with byte reads first, as word | ||
161 | * reads can confuse other devices. | ||
162 | */ | ||
163 | ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL); | ||
164 | if (ctrl < 0 || (ctrl & 0x10)) | ||
165 | return -ENODEV; | ||
166 | |||
167 | conf = i2c_smbus_read_byte_data(new_client, LM73_REG_CONF); | ||
168 | if (conf < 0 || (conf & 0x0c)) | ||
169 | return -ENODEV; | ||
170 | |||
171 | id = i2c_smbus_read_byte_data(new_client, LM73_REG_ID); | ||
172 | if (id < 0 || id != (LM73_ID & 0xff)) | ||
173 | return -ENODEV; | ||
174 | |||
160 | /* Check device ID */ | 175 | /* Check device ID */ |
161 | id = i2c_smbus_read_word_data(new_client, LM73_REG_ID); | 176 | id = i2c_smbus_read_word_data(new_client, LM73_REG_ID); |
162 | ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL); | 177 | if (id < 0 || id != LM73_ID) |
163 | if ((id != LM73_ID) || (ctrl & 0x10)) | ||
164 | return -ENODEV; | 178 | return -ENODEV; |
165 | 179 | ||
166 | strlcpy(info->type, "lm73", I2C_NAME_SIZE); | 180 | strlcpy(info->type, "lm73", I2C_NAME_SIZE); |
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index ef902d5d06ab..1888dd0fc05f 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -35,6 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | enum lm75_type { /* keep sorted in alphabetical order */ | 37 | enum lm75_type { /* keep sorted in alphabetical order */ |
38 | adt75, | ||
38 | ds1775, | 39 | ds1775, |
39 | ds75, | 40 | ds75, |
40 | lm75, | 41 | lm75, |
@@ -213,6 +214,7 @@ static int lm75_remove(struct i2c_client *client) | |||
213 | } | 214 | } |
214 | 215 | ||
215 | static const struct i2c_device_id lm75_ids[] = { | 216 | static const struct i2c_device_id lm75_ids[] = { |
217 | { "adt75", adt75, }, | ||
216 | { "ds1775", ds1775, }, | 218 | { "ds1775", ds1775, }, |
217 | { "ds75", ds75, }, | 219 | { "ds75", ds75, }, |
218 | { "lm75", lm75, }, | 220 | { "lm75", lm75, }, |
@@ -247,19 +249,30 @@ static int lm75_detect(struct i2c_client *new_client, | |||
247 | I2C_FUNC_SMBUS_WORD_DATA)) | 249 | I2C_FUNC_SMBUS_WORD_DATA)) |
248 | return -ENODEV; | 250 | return -ENODEV; |
249 | 251 | ||
250 | /* Now, we do the remaining detection. There is no identification- | 252 | /* |
251 | dedicated register so we have to rely on several tricks: | 253 | * Now, we do the remaining detection. There is no identification- |
252 | unused bits, registers cycling over 8-address boundaries, | 254 | * dedicated register so we have to rely on several tricks: |
253 | addresses 0x04-0x07 returning the last read value. | 255 | * unused bits, registers cycling over 8-address boundaries, |
254 | The cycling+unused addresses combination is not tested, | 256 | * addresses 0x04-0x07 returning the last read value. |
255 | since it would significantly slow the detection down and would | 257 | * The cycling+unused addresses combination is not tested, |
256 | hardly add any value. | 258 | * since it would significantly slow the detection down and would |
257 | 259 | * hardly add any value. | |
258 | The National Semiconductor LM75A is different than earlier | 260 | * |
259 | LM75s. It has an ID byte of 0xaX (where X is the chip | 261 | * The National Semiconductor LM75A is different than earlier |
260 | revision, with 1 being the only revision in existence) in | 262 | * LM75s. It has an ID byte of 0xaX (where X is the chip |
261 | register 7, and unused registers return 0xff rather than the | 263 | * revision, with 1 being the only revision in existence) in |
262 | last read value. */ | 264 | * register 7, and unused registers return 0xff rather than the |
265 | * last read value. | ||
266 | * | ||
267 | * Note that this function only detects the original National | ||
268 | * Semiconductor LM75 and the LM75A. Clones from other vendors | ||
269 | * aren't detected, on purpose, because they are typically never | ||
270 | * found on PC hardware. They are found on embedded designs where | ||
271 | * they can be instantiated explicitly so detection is not needed. | ||
272 | * The absence of identification registers on all these clones | ||
273 | * would make their exhaustive detection very difficult and weak, | ||
274 | * and odds are that the driver would bind to unsupported devices. | ||
275 | */ | ||
263 | 276 | ||
264 | /* Unused bits */ | 277 | /* Unused bits */ |
265 | conf = i2c_smbus_read_byte_data(new_client, 1); | 278 | conf = i2c_smbus_read_byte_data(new_client, 1); |
@@ -371,13 +384,10 @@ static struct i2c_driver lm75_driver = { | |||
371 | */ | 384 | */ |
372 | static int lm75_read_value(struct i2c_client *client, u8 reg) | 385 | static int lm75_read_value(struct i2c_client *client, u8 reg) |
373 | { | 386 | { |
374 | int value; | ||
375 | |||
376 | if (reg == LM75_REG_CONF) | 387 | if (reg == LM75_REG_CONF) |
377 | return i2c_smbus_read_byte_data(client, reg); | 388 | return i2c_smbus_read_byte_data(client, reg); |
378 | 389 | else | |
379 | value = i2c_smbus_read_word_data(client, reg); | 390 | return i2c_smbus_read_word_swapped(client, reg); |
380 | return (value < 0) ? value : swab16(value); | ||
381 | } | 391 | } |
382 | 392 | ||
383 | static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) | 393 | static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) |
@@ -385,7 +395,7 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) | |||
385 | if (reg == LM75_REG_CONF) | 395 | if (reg == LM75_REG_CONF) |
386 | return i2c_smbus_write_byte_data(client, reg, value); | 396 | return i2c_smbus_write_byte_data(client, reg, value); |
387 | else | 397 | else |
388 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | 398 | return i2c_smbus_write_word_swapped(client, reg, value); |
389 | } | 399 | } |
390 | 400 | ||
391 | static struct lm75_data *lm75_update_device(struct device *dev) | 401 | static struct lm75_data *lm75_update_device(struct device *dev) |
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index b28a297be50c..8dfc6782d596 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c | |||
@@ -365,7 +365,7 @@ static u16 lm77_read_value(struct i2c_client *client, u8 reg) | |||
365 | if (reg == LM77_REG_CONF) | 365 | if (reg == LM77_REG_CONF) |
366 | return i2c_smbus_read_byte_data(client, reg); | 366 | return i2c_smbus_read_byte_data(client, reg); |
367 | else | 367 | else |
368 | return swab16(i2c_smbus_read_word_data(client, reg)); | 368 | return i2c_smbus_read_word_swapped(client, reg); |
369 | } | 369 | } |
370 | 370 | ||
371 | static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value) | 371 | static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value) |
@@ -373,7 +373,7 @@ static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value) | |||
373 | if (reg == LM77_REG_CONF) | 373 | if (reg == LM77_REG_CONF) |
374 | return i2c_smbus_write_byte_data(client, reg, value); | 374 | return i2c_smbus_write_byte_data(client, reg, value); |
375 | else | 375 | else |
376 | return i2c_smbus_write_word_data(client, reg, swab16(value)); | 376 | return i2c_smbus_write_word_swapped(client, reg, value); |
377 | } | 377 | } |
378 | 378 | ||
379 | static void lm77_init_client(struct i2c_client *client) | 379 | static void lm77_init_client(struct i2c_client *client) |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 90ddb8774210..615bc4f4e530 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -1105,41 +1105,37 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); | |||
1105 | */ | 1105 | */ |
1106 | 1106 | ||
1107 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 1107 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1108 | static int lm90_detect(struct i2c_client *new_client, | 1108 | static int lm90_detect(struct i2c_client *client, |
1109 | struct i2c_board_info *info) | 1109 | struct i2c_board_info *info) |
1110 | { | 1110 | { |
1111 | struct i2c_adapter *adapter = new_client->adapter; | 1111 | struct i2c_adapter *adapter = client->adapter; |
1112 | int address = new_client->addr; | 1112 | int address = client->addr; |
1113 | const char *name = NULL; | 1113 | const char *name = NULL; |
1114 | int man_id, chip_id, reg_config1, reg_config2, reg_convrate; | 1114 | int man_id, chip_id, config1, config2, convrate; |
1115 | 1115 | ||
1116 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 1116 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
1117 | return -ENODEV; | 1117 | return -ENODEV; |
1118 | 1118 | ||
1119 | /* detection and identification */ | 1119 | /* detection and identification */ |
1120 | if ((man_id = i2c_smbus_read_byte_data(new_client, | 1120 | man_id = i2c_smbus_read_byte_data(client, LM90_REG_R_MAN_ID); |
1121 | LM90_REG_R_MAN_ID)) < 0 | 1121 | chip_id = i2c_smbus_read_byte_data(client, LM90_REG_R_CHIP_ID); |
1122 | || (chip_id = i2c_smbus_read_byte_data(new_client, | 1122 | config1 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1); |
1123 | LM90_REG_R_CHIP_ID)) < 0 | 1123 | convrate = i2c_smbus_read_byte_data(client, LM90_REG_R_CONVRATE); |
1124 | || (reg_config1 = i2c_smbus_read_byte_data(new_client, | 1124 | if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0) |
1125 | LM90_REG_R_CONFIG1)) < 0 | ||
1126 | || (reg_convrate = i2c_smbus_read_byte_data(new_client, | ||
1127 | LM90_REG_R_CONVRATE)) < 0) | ||
1128 | return -ENODEV; | 1125 | return -ENODEV; |
1129 | 1126 | ||
1130 | if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) { | 1127 | if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) { |
1131 | reg_config2 = i2c_smbus_read_byte_data(new_client, | 1128 | config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2); |
1132 | LM90_REG_R_CONFIG2); | 1129 | if (config2 < 0) |
1133 | if (reg_config2 < 0) | ||
1134 | return -ENODEV; | 1130 | return -ENODEV; |
1135 | } else | 1131 | } else |
1136 | reg_config2 = 0; /* Make compiler happy */ | 1132 | config2 = 0; /* Make compiler happy */ |
1137 | 1133 | ||
1138 | if ((address == 0x4C || address == 0x4D) | 1134 | if ((address == 0x4C || address == 0x4D) |
1139 | && man_id == 0x01) { /* National Semiconductor */ | 1135 | && man_id == 0x01) { /* National Semiconductor */ |
1140 | if ((reg_config1 & 0x2A) == 0x00 | 1136 | if ((config1 & 0x2A) == 0x00 |
1141 | && (reg_config2 & 0xF8) == 0x00 | 1137 | && (config2 & 0xF8) == 0x00 |
1142 | && reg_convrate <= 0x09) { | 1138 | && convrate <= 0x09) { |
1143 | if (address == 0x4C | 1139 | if (address == 0x4C |
1144 | && (chip_id & 0xF0) == 0x20) { /* LM90 */ | 1140 | && (chip_id & 0xF0) == 0x20) { /* LM90 */ |
1145 | name = "lm90"; | 1141 | name = "lm90"; |
@@ -1163,8 +1159,8 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1163 | if ((address == 0x4C || address == 0x4D) | 1159 | if ((address == 0x4C || address == 0x4D) |
1164 | && man_id == 0x41) { /* Analog Devices */ | 1160 | && man_id == 0x41) { /* Analog Devices */ |
1165 | if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ | 1161 | if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ |
1166 | && (reg_config1 & 0x3F) == 0x00 | 1162 | && (config1 & 0x3F) == 0x00 |
1167 | && reg_convrate <= 0x0A) { | 1163 | && convrate <= 0x0A) { |
1168 | name = "adm1032"; | 1164 | name = "adm1032"; |
1169 | /* The ADM1032 supports PEC, but only if combined | 1165 | /* The ADM1032 supports PEC, but only if combined |
1170 | transactions are not used. */ | 1166 | transactions are not used. */ |
@@ -1173,18 +1169,18 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1173 | info->flags |= I2C_CLIENT_PEC; | 1169 | info->flags |= I2C_CLIENT_PEC; |
1174 | } else | 1170 | } else |
1175 | if (chip_id == 0x51 /* ADT7461 */ | 1171 | if (chip_id == 0x51 /* ADT7461 */ |
1176 | && (reg_config1 & 0x1B) == 0x00 | 1172 | && (config1 & 0x1B) == 0x00 |
1177 | && reg_convrate <= 0x0A) { | 1173 | && convrate <= 0x0A) { |
1178 | name = "adt7461"; | 1174 | name = "adt7461"; |
1179 | } else | 1175 | } else |
1180 | if (chip_id == 0x57 /* ADT7461A, NCT1008 */ | 1176 | if (chip_id == 0x57 /* ADT7461A, NCT1008 */ |
1181 | && (reg_config1 & 0x1B) == 0x00 | 1177 | && (config1 & 0x1B) == 0x00 |
1182 | && reg_convrate <= 0x0A) { | 1178 | && convrate <= 0x0A) { |
1183 | name = "adt7461a"; | 1179 | name = "adt7461a"; |
1184 | } | 1180 | } |
1185 | } else | 1181 | } else |
1186 | if (man_id == 0x4D) { /* Maxim */ | 1182 | if (man_id == 0x4D) { /* Maxim */ |
1187 | int reg_emerg, reg_emerg2, reg_status2; | 1183 | int emerg, emerg2, status2; |
1188 | 1184 | ||
1189 | /* | 1185 | /* |
1190 | * We read MAX6659_REG_R_REMOTE_EMERG twice, and re-read | 1186 | * We read MAX6659_REG_R_REMOTE_EMERG twice, and re-read |
@@ -1192,13 +1188,15 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1192 | * exists, both readings will reflect the same value. Otherwise, | 1188 | * exists, both readings will reflect the same value. Otherwise, |
1193 | * the readings will be different. | 1189 | * the readings will be different. |
1194 | */ | 1190 | */ |
1195 | if ((reg_emerg = i2c_smbus_read_byte_data(new_client, | 1191 | emerg = i2c_smbus_read_byte_data(client, |
1196 | MAX6659_REG_R_REMOTE_EMERG)) < 0 | 1192 | MAX6659_REG_R_REMOTE_EMERG); |
1197 | || i2c_smbus_read_byte_data(new_client, LM90_REG_R_MAN_ID) < 0 | 1193 | man_id = i2c_smbus_read_byte_data(client, |
1198 | || (reg_emerg2 = i2c_smbus_read_byte_data(new_client, | 1194 | LM90_REG_R_MAN_ID); |
1199 | MAX6659_REG_R_REMOTE_EMERG)) < 0 | 1195 | emerg2 = i2c_smbus_read_byte_data(client, |
1200 | || (reg_status2 = i2c_smbus_read_byte_data(new_client, | 1196 | MAX6659_REG_R_REMOTE_EMERG); |
1201 | MAX6696_REG_R_STATUS2)) < 0) | 1197 | status2 = i2c_smbus_read_byte_data(client, |
1198 | MAX6696_REG_R_STATUS2); | ||
1199 | if (emerg < 0 || man_id < 0 || emerg2 < 0 || status2 < 0) | ||
1202 | return -ENODEV; | 1200 | return -ENODEV; |
1203 | 1201 | ||
1204 | /* | 1202 | /* |
@@ -1216,8 +1214,8 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1216 | */ | 1214 | */ |
1217 | if (chip_id == man_id | 1215 | if (chip_id == man_id |
1218 | && (address == 0x4C || address == 0x4D || address == 0x4E) | 1216 | && (address == 0x4C || address == 0x4D || address == 0x4E) |
1219 | && (reg_config1 & 0x1F) == (man_id & 0x0F) | 1217 | && (config1 & 0x1F) == (man_id & 0x0F) |
1220 | && reg_convrate <= 0x09) { | 1218 | && convrate <= 0x09) { |
1221 | if (address == 0x4C) | 1219 | if (address == 0x4C) |
1222 | name = "max6657"; | 1220 | name = "max6657"; |
1223 | else | 1221 | else |
@@ -1235,10 +1233,10 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1235 | * one of those registers exists. | 1233 | * one of those registers exists. |
1236 | */ | 1234 | */ |
1237 | if (chip_id == 0x01 | 1235 | if (chip_id == 0x01 |
1238 | && (reg_config1 & 0x10) == 0x00 | 1236 | && (config1 & 0x10) == 0x00 |
1239 | && (reg_status2 & 0x01) == 0x00 | 1237 | && (status2 & 0x01) == 0x00 |
1240 | && reg_emerg == reg_emerg2 | 1238 | && emerg == emerg2 |
1241 | && reg_convrate <= 0x07) { | 1239 | && convrate <= 0x07) { |
1242 | name = "max6696"; | 1240 | name = "max6696"; |
1243 | } else | 1241 | } else |
1244 | /* | 1242 | /* |
@@ -1248,8 +1246,8 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1248 | * second to last bit of config1 (software reset). | 1246 | * second to last bit of config1 (software reset). |
1249 | */ | 1247 | */ |
1250 | if (chip_id == 0x01 | 1248 | if (chip_id == 0x01 |
1251 | && (reg_config1 & 0x03) == 0x00 | 1249 | && (config1 & 0x03) == 0x00 |
1252 | && reg_convrate <= 0x07) { | 1250 | && convrate <= 0x07) { |
1253 | name = "max6680"; | 1251 | name = "max6680"; |
1254 | } else | 1252 | } else |
1255 | /* | 1253 | /* |
@@ -1258,21 +1256,21 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1258 | * register are unused and should return zero when read. | 1256 | * register are unused and should return zero when read. |
1259 | */ | 1257 | */ |
1260 | if (chip_id == 0x59 | 1258 | if (chip_id == 0x59 |
1261 | && (reg_config1 & 0x3f) == 0x00 | 1259 | && (config1 & 0x3f) == 0x00 |
1262 | && reg_convrate <= 0x07) { | 1260 | && convrate <= 0x07) { |
1263 | name = "max6646"; | 1261 | name = "max6646"; |
1264 | } | 1262 | } |
1265 | } else | 1263 | } else |
1266 | if (address == 0x4C | 1264 | if (address == 0x4C |
1267 | && man_id == 0x5C) { /* Winbond/Nuvoton */ | 1265 | && man_id == 0x5C) { /* Winbond/Nuvoton */ |
1268 | if ((reg_config1 & 0x2A) == 0x00 | 1266 | if ((config1 & 0x2A) == 0x00 |
1269 | && (reg_config2 & 0xF8) == 0x00) { | 1267 | && (config2 & 0xF8) == 0x00) { |
1270 | if (chip_id == 0x01 /* W83L771W/G */ | 1268 | if (chip_id == 0x01 /* W83L771W/G */ |
1271 | && reg_convrate <= 0x09) { | 1269 | && convrate <= 0x09) { |
1272 | name = "w83l771"; | 1270 | name = "w83l771"; |
1273 | } else | 1271 | } else |
1274 | if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */ | 1272 | if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */ |
1275 | && reg_convrate <= 0x08) { | 1273 | && convrate <= 0x08) { |
1276 | name = "w83l771"; | 1274 | name = "w83l771"; |
1277 | } | 1275 | } |
1278 | } | 1276 | } |
@@ -1280,9 +1278,9 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1280 | if (address >= 0x48 && address <= 0x4F | 1278 | if (address >= 0x48 && address <= 0x4F |
1281 | && man_id == 0xA1) { /* NXP Semiconductor/Philips */ | 1279 | && man_id == 0xA1) { /* NXP Semiconductor/Philips */ |
1282 | if (chip_id == 0x00 | 1280 | if (chip_id == 0x00 |
1283 | && (reg_config1 & 0x2A) == 0x00 | 1281 | && (config1 & 0x2A) == 0x00 |
1284 | && (reg_config2 & 0xFE) == 0x00 | 1282 | && (config2 & 0xFE) == 0x00 |
1285 | && reg_convrate <= 0x09) { | 1283 | && convrate <= 0x09) { |
1286 | name = "sa56004"; | 1284 | name = "sa56004"; |
1287 | } | 1285 | } |
1288 | } | 1286 | } |
@@ -1301,19 +1299,18 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1301 | 1299 | ||
1302 | static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) | 1300 | static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) |
1303 | { | 1301 | { |
1302 | struct device *dev = &client->dev; | ||
1303 | |||
1304 | if (data->flags & LM90_HAVE_TEMP3) | 1304 | if (data->flags & LM90_HAVE_TEMP3) |
1305 | sysfs_remove_group(&client->dev.kobj, &lm90_temp3_group); | 1305 | sysfs_remove_group(&dev->kobj, &lm90_temp3_group); |
1306 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) | 1306 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) |
1307 | sysfs_remove_group(&client->dev.kobj, | 1307 | sysfs_remove_group(&dev->kobj, &lm90_emergency_alarm_group); |
1308 | &lm90_emergency_alarm_group); | ||
1309 | if (data->flags & LM90_HAVE_EMERGENCY) | 1308 | if (data->flags & LM90_HAVE_EMERGENCY) |
1310 | sysfs_remove_group(&client->dev.kobj, | 1309 | sysfs_remove_group(&dev->kobj, &lm90_emergency_group); |
1311 | &lm90_emergency_group); | ||
1312 | if (data->flags & LM90_HAVE_OFFSET) | 1310 | if (data->flags & LM90_HAVE_OFFSET) |
1313 | device_remove_file(&client->dev, | 1311 | device_remove_file(dev, &sensor_dev_attr_temp2_offset.dev_attr); |
1314 | &sensor_dev_attr_temp2_offset.dev_attr); | 1312 | device_remove_file(dev, &dev_attr_pec); |
1315 | device_remove_file(&client->dev, &dev_attr_pec); | 1313 | sysfs_remove_group(&dev->kobj, &lm90_group); |
1316 | sysfs_remove_group(&client->dev.kobj, &lm90_group); | ||
1317 | } | 1314 | } |
1318 | 1315 | ||
1319 | static void lm90_init_client(struct i2c_client *client) | 1316 | static void lm90_init_client(struct i2c_client *client) |
@@ -1362,10 +1359,11 @@ static void lm90_init_client(struct i2c_client *client) | |||
1362 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); | 1359 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); |
1363 | } | 1360 | } |
1364 | 1361 | ||
1365 | static int lm90_probe(struct i2c_client *new_client, | 1362 | static int lm90_probe(struct i2c_client *client, |
1366 | const struct i2c_device_id *id) | 1363 | const struct i2c_device_id *id) |
1367 | { | 1364 | { |
1368 | struct i2c_adapter *adapter = to_i2c_adapter(new_client->dev.parent); | 1365 | struct device *dev = &client->dev; |
1366 | struct i2c_adapter *adapter = to_i2c_adapter(dev->parent); | ||
1369 | struct lm90_data *data; | 1367 | struct lm90_data *data; |
1370 | int err; | 1368 | int err; |
1371 | 1369 | ||
@@ -1374,14 +1372,14 @@ static int lm90_probe(struct i2c_client *new_client, | |||
1374 | err = -ENOMEM; | 1372 | err = -ENOMEM; |
1375 | goto exit; | 1373 | goto exit; |
1376 | } | 1374 | } |
1377 | i2c_set_clientdata(new_client, data); | 1375 | i2c_set_clientdata(client, data); |
1378 | mutex_init(&data->update_lock); | 1376 | mutex_init(&data->update_lock); |
1379 | 1377 | ||
1380 | /* Set the device type */ | 1378 | /* Set the device type */ |
1381 | data->kind = id->driver_data; | 1379 | data->kind = id->driver_data; |
1382 | if (data->kind == adm1032) { | 1380 | if (data->kind == adm1032) { |
1383 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) | 1381 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) |
1384 | new_client->flags &= ~I2C_CLIENT_PEC; | 1382 | client->flags &= ~I2C_CLIENT_PEC; |
1385 | } | 1383 | } |
1386 | 1384 | ||
1387 | /* Different devices have different alarm bits triggering the | 1385 | /* Different devices have different alarm bits triggering the |
@@ -1396,43 +1394,41 @@ static int lm90_probe(struct i2c_client *new_client, | |||
1396 | data->max_convrate = lm90_params[data->kind].max_convrate; | 1394 | data->max_convrate = lm90_params[data->kind].max_convrate; |
1397 | 1395 | ||
1398 | /* Initialize the LM90 chip */ | 1396 | /* Initialize the LM90 chip */ |
1399 | lm90_init_client(new_client); | 1397 | lm90_init_client(client); |
1400 | 1398 | ||
1401 | /* Register sysfs hooks */ | 1399 | /* Register sysfs hooks */ |
1402 | err = sysfs_create_group(&new_client->dev.kobj, &lm90_group); | 1400 | err = sysfs_create_group(&dev->kobj, &lm90_group); |
1403 | if (err) | 1401 | if (err) |
1404 | goto exit_free; | 1402 | goto exit_free; |
1405 | if (new_client->flags & I2C_CLIENT_PEC) { | 1403 | if (client->flags & I2C_CLIENT_PEC) { |
1406 | err = device_create_file(&new_client->dev, &dev_attr_pec); | 1404 | err = device_create_file(dev, &dev_attr_pec); |
1407 | if (err) | 1405 | if (err) |
1408 | goto exit_remove_files; | 1406 | goto exit_remove_files; |
1409 | } | 1407 | } |
1410 | if (data->flags & LM90_HAVE_OFFSET) { | 1408 | if (data->flags & LM90_HAVE_OFFSET) { |
1411 | err = device_create_file(&new_client->dev, | 1409 | err = device_create_file(dev, |
1412 | &sensor_dev_attr_temp2_offset.dev_attr); | 1410 | &sensor_dev_attr_temp2_offset.dev_attr); |
1413 | if (err) | 1411 | if (err) |
1414 | goto exit_remove_files; | 1412 | goto exit_remove_files; |
1415 | } | 1413 | } |
1416 | if (data->flags & LM90_HAVE_EMERGENCY) { | 1414 | if (data->flags & LM90_HAVE_EMERGENCY) { |
1417 | err = sysfs_create_group(&new_client->dev.kobj, | 1415 | err = sysfs_create_group(&dev->kobj, &lm90_emergency_group); |
1418 | &lm90_emergency_group); | ||
1419 | if (err) | 1416 | if (err) |
1420 | goto exit_remove_files; | 1417 | goto exit_remove_files; |
1421 | } | 1418 | } |
1422 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) { | 1419 | if (data->flags & LM90_HAVE_EMERGENCY_ALARM) { |
1423 | err = sysfs_create_group(&new_client->dev.kobj, | 1420 | err = sysfs_create_group(&dev->kobj, |
1424 | &lm90_emergency_alarm_group); | 1421 | &lm90_emergency_alarm_group); |
1425 | if (err) | 1422 | if (err) |
1426 | goto exit_remove_files; | 1423 | goto exit_remove_files; |
1427 | } | 1424 | } |
1428 | if (data->flags & LM90_HAVE_TEMP3) { | 1425 | if (data->flags & LM90_HAVE_TEMP3) { |
1429 | err = sysfs_create_group(&new_client->dev.kobj, | 1426 | err = sysfs_create_group(&dev->kobj, &lm90_temp3_group); |
1430 | &lm90_temp3_group); | ||
1431 | if (err) | 1427 | if (err) |
1432 | goto exit_remove_files; | 1428 | goto exit_remove_files; |
1433 | } | 1429 | } |
1434 | 1430 | ||
1435 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 1431 | data->hwmon_dev = hwmon_device_register(dev); |
1436 | if (IS_ERR(data->hwmon_dev)) { | 1432 | if (IS_ERR(data->hwmon_dev)) { |
1437 | err = PTR_ERR(data->hwmon_dev); | 1433 | err = PTR_ERR(data->hwmon_dev); |
1438 | goto exit_remove_files; | 1434 | goto exit_remove_files; |
@@ -1441,7 +1437,7 @@ static int lm90_probe(struct i2c_client *new_client, | |||
1441 | return 0; | 1437 | return 0; |
1442 | 1438 | ||
1443 | exit_remove_files: | 1439 | exit_remove_files: |
1444 | lm90_remove_files(new_client, data); | 1440 | lm90_remove_files(client, data); |
1445 | exit_free: | 1441 | exit_free: |
1446 | kfree(data); | 1442 | kfree(data); |
1447 | exit: | 1443 | exit: |
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index 7c31e6205f85..8fcbd4d422c5 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c | |||
@@ -117,16 +117,16 @@ static struct lm92_data *lm92_update_device(struct device *dev) | |||
117 | if (time_after(jiffies, data->last_updated + HZ) | 117 | if (time_after(jiffies, data->last_updated + HZ) |
118 | || !data->valid) { | 118 | || !data->valid) { |
119 | dev_dbg(&client->dev, "Updating lm92 data\n"); | 119 | dev_dbg(&client->dev, "Updating lm92 data\n"); |
120 | data->temp1_input = swab16(i2c_smbus_read_word_data(client, | 120 | data->temp1_input = i2c_smbus_read_word_swapped(client, |
121 | LM92_REG_TEMP)); | 121 | LM92_REG_TEMP); |
122 | data->temp1_hyst = swab16(i2c_smbus_read_word_data(client, | 122 | data->temp1_hyst = i2c_smbus_read_word_swapped(client, |
123 | LM92_REG_TEMP_HYST)); | 123 | LM92_REG_TEMP_HYST); |
124 | data->temp1_crit = swab16(i2c_smbus_read_word_data(client, | 124 | data->temp1_crit = i2c_smbus_read_word_swapped(client, |
125 | LM92_REG_TEMP_CRIT)); | 125 | LM92_REG_TEMP_CRIT); |
126 | data->temp1_min = swab16(i2c_smbus_read_word_data(client, | 126 | data->temp1_min = i2c_smbus_read_word_swapped(client, |
127 | LM92_REG_TEMP_LOW)); | 127 | LM92_REG_TEMP_LOW); |
128 | data->temp1_max = swab16(i2c_smbus_read_word_data(client, | 128 | data->temp1_max = i2c_smbus_read_word_swapped(client, |
129 | LM92_REG_TEMP_HIGH)); | 129 | LM92_REG_TEMP_HIGH); |
130 | 130 | ||
131 | data->last_updated = jiffies; | 131 | data->last_updated = jiffies; |
132 | data->valid = 1; | 132 | data->valid = 1; |
@@ -158,7 +158,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co | |||
158 | \ | 158 | \ |
159 | mutex_lock(&data->update_lock); \ | 159 | mutex_lock(&data->update_lock); \ |
160 | data->value = TEMP_TO_REG(val); \ | 160 | data->value = TEMP_TO_REG(val); \ |
161 | i2c_smbus_write_word_data(client, reg, swab16(data->value)); \ | 161 | i2c_smbus_write_word_swapped(client, reg, data->value); \ |
162 | mutex_unlock(&data->update_lock); \ | 162 | mutex_unlock(&data->update_lock); \ |
163 | return count; \ | 163 | return count; \ |
164 | } | 164 | } |
@@ -194,8 +194,8 @@ static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute * | |||
194 | 194 | ||
195 | mutex_lock(&data->update_lock); | 195 | mutex_lock(&data->update_lock); |
196 | data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val; | 196 | data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val; |
197 | i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST, | 197 | i2c_smbus_write_word_swapped(client, LM92_REG_TEMP_HYST, |
198 | swab16(TEMP_TO_REG(data->temp1_hyst))); | 198 | TEMP_TO_REG(data->temp1_hyst)); |
199 | mutex_unlock(&data->update_lock); | 199 | mutex_unlock(&data->update_lock); |
200 | return count; | 200 | return count; |
201 | } | 201 | } |
diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c index dd2d7b9620c2..385886a4f224 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c | |||
@@ -137,10 +137,10 @@ static int max16065_read_adc(struct i2c_client *client, int reg) | |||
137 | { | 137 | { |
138 | int rv; | 138 | int rv; |
139 | 139 | ||
140 | rv = i2c_smbus_read_word_data(client, reg); | 140 | rv = i2c_smbus_read_word_swapped(client, reg); |
141 | if (unlikely(rv < 0)) | 141 | if (unlikely(rv < 0)) |
142 | return rv; | 142 | return rv; |
143 | return ((rv & 0xff) << 2) | ((rv >> 14) & 0x03); | 143 | return rv >> 6; |
144 | } | 144 | } |
145 | 145 | ||
146 | static struct max16065_data *max16065_update_device(struct device *dev) | 146 | static struct max16065_data *max16065_update_device(struct device *dev) |
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c index d5226c9e1201..ef65ab56b094 100644 --- a/drivers/hwmon/mc13783-adc.c +++ b/drivers/hwmon/mc13783-adc.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #define MC13783_ADC_NAME "mc13783-adc" | 31 | #define MC13783_ADC_NAME "mc13783-adc" |
32 | 32 | ||
33 | struct mc13783_adc_priv { | 33 | struct mc13783_adc_priv { |
34 | struct mc13783 *mc13783; | 34 | struct mc13xxx *mc13xxx; |
35 | struct device *hwmon_dev; | 35 | struct device *hwmon_dev; |
36 | }; | 36 | }; |
37 | 37 | ||
@@ -51,8 +51,8 @@ static int mc13783_adc_read(struct device *dev, | |||
51 | unsigned int sample[4]; | 51 | unsigned int sample[4]; |
52 | int ret; | 52 | int ret; |
53 | 53 | ||
54 | ret = mc13783_adc_do_conversion(priv->mc13783, | 54 | ret = mc13xxx_adc_do_conversion(priv->mc13xxx, |
55 | MC13783_ADC_MODE_MULT_CHAN, | 55 | MC13XXX_ADC_MODE_MULT_CHAN, |
56 | channel, sample); | 56 | channel, sample); |
57 | if (ret) | 57 | if (ret) |
58 | return ret; | 58 | return ret; |
@@ -147,9 +147,9 @@ static const struct attribute_group mc13783_group_ts = { | |||
147 | static int mc13783_adc_use_touchscreen(struct platform_device *pdev) | 147 | static int mc13783_adc_use_touchscreen(struct platform_device *pdev) |
148 | { | 148 | { |
149 | struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); | 149 | struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); |
150 | unsigned flags = mc13783_get_flags(priv->mc13783); | 150 | unsigned flags = mc13xxx_get_flags(priv->mc13xxx); |
151 | 151 | ||
152 | return flags & MC13783_USE_TOUCHSCREEN; | 152 | return flags & MC13XXX_USE_TOUCHSCREEN; |
153 | } | 153 | } |
154 | 154 | ||
155 | static int __init mc13783_adc_probe(struct platform_device *pdev) | 155 | static int __init mc13783_adc_probe(struct platform_device *pdev) |
@@ -161,7 +161,7 @@ static int __init mc13783_adc_probe(struct platform_device *pdev) | |||
161 | if (!priv) | 161 | if (!priv) |
162 | return -ENOMEM; | 162 | return -ENOMEM; |
163 | 163 | ||
164 | priv->mc13783 = dev_get_drvdata(pdev->dev.parent); | 164 | priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); |
165 | 165 | ||
166 | platform_set_drvdata(pdev, priv); | 166 | platform_set_drvdata(pdev, priv); |
167 | 167 | ||
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index c9237b9dcff2..4b26f51920ba 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig | |||
@@ -20,17 +20,18 @@ config SENSORS_PMBUS | |||
20 | help | 20 | help |
21 | If you say yes here you get hardware monitoring support for generic | 21 | If you say yes here you get hardware monitoring support for generic |
22 | PMBus devices, including but not limited to ADP4000, BMR450, BMR451, | 22 | PMBus devices, including but not limited to ADP4000, BMR450, BMR451, |
23 | BMR453, BMR454, LTC2978, NCP4200, and NCP4208. | 23 | BMR453, BMR454, NCP4200, and NCP4208. |
24 | 24 | ||
25 | This driver can also be built as a module. If so, the module will | 25 | This driver can also be built as a module. If so, the module will |
26 | be called pmbus. | 26 | be called pmbus. |
27 | 27 | ||
28 | config SENSORS_ADM1275 | 28 | config SENSORS_ADM1275 |
29 | tristate "Analog Devices ADM1275" | 29 | tristate "Analog Devices ADM1275 and compatibles" |
30 | default n | 30 | default n |
31 | help | 31 | help |
32 | If you say yes here you get hardware monitoring support for Analog | 32 | If you say yes here you get hardware monitoring support for Analog |
33 | Devices ADM1275 Hot-Swap Controller and Digital Power Monitor. | 33 | Devices ADM1275 and ADM1276 Hot-Swap Controller and Digital Power |
34 | Monitor. | ||
34 | 35 | ||
35 | This driver can also be built as a module. If so, the module will | 36 | This driver can also be built as a module. If so, the module will |
36 | be called adm1275. | 37 | be called adm1275. |
@@ -45,6 +46,16 @@ config SENSORS_LM25066 | |||
45 | This driver can also be built as a module. If so, the module will | 46 | This driver can also be built as a module. If so, the module will |
46 | be called lm25066. | 47 | be called lm25066. |
47 | 48 | ||
49 | config SENSORS_LTC2978 | ||
50 | tristate "Linear Technologies LTC2978 and LTC3880" | ||
51 | default n | ||
52 | help | ||
53 | If you say yes here you get hardware monitoring support for Linear | ||
54 | Technology LTC2978 and LTC3880. | ||
55 | |||
56 | This driver can also be built as a module. If so, the module will | ||
57 | be called ltc2978. | ||
58 | |||
48 | config SENSORS_MAX16064 | 59 | config SENSORS_MAX16064 |
49 | tristate "Maxim MAX16064" | 60 | tristate "Maxim MAX16064" |
50 | default n | 61 | default n |
@@ -97,4 +108,15 @@ config SENSORS_UCD9200 | |||
97 | This driver can also be built as a module. If so, the module will | 108 | This driver can also be built as a module. If so, the module will |
98 | be called ucd9200. | 109 | be called ucd9200. |
99 | 110 | ||
111 | config SENSORS_ZL6100 | ||
112 | tristate "Intersil ZL6100 and compatibles" | ||
113 | default n | ||
114 | help | ||
115 | If you say yes here you get hardware monitoring support for Intersil | ||
116 | ZL2004, ZL2006, ZL2008, ZL2105, ZL2106, ZL6100, and ZL6105 Digital | ||
117 | DC/DC Controllers. | ||
118 | |||
119 | This driver can also be built as a module. If so, the module will | ||
120 | be called zl6100. | ||
121 | |||
100 | endif # PMBUS | 122 | endif # PMBUS |
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile index 623eedb1ed9a..789376c85dbb 100644 --- a/drivers/hwmon/pmbus/Makefile +++ b/drivers/hwmon/pmbus/Makefile | |||
@@ -6,8 +6,10 @@ obj-$(CONFIG_PMBUS) += pmbus_core.o | |||
6 | obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o | 6 | obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o |
7 | obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o | 7 | obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o |
8 | obj-$(CONFIG_SENSORS_LM25066) += lm25066.o | 8 | obj-$(CONFIG_SENSORS_LM25066) += lm25066.o |
9 | obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o | ||
9 | obj-$(CONFIG_SENSORS_MAX16064) += max16064.o | 10 | obj-$(CONFIG_SENSORS_MAX16064) += max16064.o |
10 | obj-$(CONFIG_SENSORS_MAX34440) += max34440.o | 11 | obj-$(CONFIG_SENSORS_MAX34440) += max34440.o |
11 | obj-$(CONFIG_SENSORS_MAX8688) += max8688.o | 12 | obj-$(CONFIG_SENSORS_MAX8688) += max8688.o |
12 | obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o | 13 | obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o |
13 | obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o | 14 | obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o |
15 | obj-$(CONFIG_SENSORS_ZL6100) += zl6100.o | ||
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index c936e2782309..980a4d9d5028 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include "pmbus.h" | 24 | #include "pmbus.h" |
25 | 25 | ||
26 | enum chips { adm1275, adm1276 }; | ||
27 | |||
26 | #define ADM1275_PEAK_IOUT 0xd0 | 28 | #define ADM1275_PEAK_IOUT 0xd0 |
27 | #define ADM1275_PEAK_VIN 0xd1 | 29 | #define ADM1275_PEAK_VIN 0xd1 |
28 | #define ADM1275_PEAK_VOUT 0xd2 | 30 | #define ADM1275_PEAK_VOUT 0xd2 |
@@ -31,14 +33,47 @@ | |||
31 | #define ADM1275_VIN_VOUT_SELECT (1 << 6) | 33 | #define ADM1275_VIN_VOUT_SELECT (1 << 6) |
32 | #define ADM1275_VRANGE (1 << 5) | 34 | #define ADM1275_VRANGE (1 << 5) |
33 | 35 | ||
36 | #define ADM1275_IOUT_WARN2_LIMIT 0xd7 | ||
37 | #define ADM1275_DEVICE_CONFIG 0xd8 | ||
38 | |||
39 | #define ADM1275_IOUT_WARN2_SELECT (1 << 4) | ||
40 | |||
41 | #define ADM1276_PEAK_PIN 0xda | ||
42 | |||
43 | #define ADM1275_MFR_STATUS_IOUT_WARN2 (1 << 0) | ||
44 | |||
45 | struct adm1275_data { | ||
46 | int id; | ||
47 | bool have_oc_fault; | ||
48 | struct pmbus_driver_info info; | ||
49 | }; | ||
50 | |||
51 | #define to_adm1275_data(x) container_of(x, struct adm1275_data, info) | ||
52 | |||
34 | static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) | 53 | static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) |
35 | { | 54 | { |
36 | int ret; | 55 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
56 | const struct adm1275_data *data = to_adm1275_data(info); | ||
57 | int ret = 0; | ||
37 | 58 | ||
38 | if (page) | 59 | if (page) |
39 | return -EINVAL; | 60 | return -ENXIO; |
40 | 61 | ||
41 | switch (reg) { | 62 | switch (reg) { |
63 | case PMBUS_IOUT_UC_FAULT_LIMIT: | ||
64 | if (data->have_oc_fault) { | ||
65 | ret = -ENXIO; | ||
66 | break; | ||
67 | } | ||
68 | ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT); | ||
69 | break; | ||
70 | case PMBUS_IOUT_OC_FAULT_LIMIT: | ||
71 | if (!data->have_oc_fault) { | ||
72 | ret = -ENXIO; | ||
73 | break; | ||
74 | } | ||
75 | ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT); | ||
76 | break; | ||
42 | case PMBUS_VIRT_READ_IOUT_MAX: | 77 | case PMBUS_VIRT_READ_IOUT_MAX: |
43 | ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT); | 78 | ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT); |
44 | break; | 79 | break; |
@@ -48,10 +83,20 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) | |||
48 | case PMBUS_VIRT_READ_VIN_MAX: | 83 | case PMBUS_VIRT_READ_VIN_MAX: |
49 | ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN); | 84 | ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN); |
50 | break; | 85 | break; |
86 | case PMBUS_VIRT_READ_PIN_MAX: | ||
87 | if (data->id != adm1276) { | ||
88 | ret = -ENXIO; | ||
89 | break; | ||
90 | } | ||
91 | ret = pmbus_read_word_data(client, 0, ADM1276_PEAK_PIN); | ||
92 | break; | ||
51 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | 93 | case PMBUS_VIRT_RESET_IOUT_HISTORY: |
52 | case PMBUS_VIRT_RESET_VOUT_HISTORY: | 94 | case PMBUS_VIRT_RESET_VOUT_HISTORY: |
53 | case PMBUS_VIRT_RESET_VIN_HISTORY: | 95 | case PMBUS_VIRT_RESET_VIN_HISTORY: |
54 | ret = 0; | 96 | break; |
97 | case PMBUS_VIRT_RESET_PIN_HISTORY: | ||
98 | if (data->id != adm1276) | ||
99 | ret = -ENXIO; | ||
55 | break; | 100 | break; |
56 | default: | 101 | default: |
57 | ret = -ENODATA; | 102 | ret = -ENODATA; |
@@ -66,9 +111,14 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg, | |||
66 | int ret; | 111 | int ret; |
67 | 112 | ||
68 | if (page) | 113 | if (page) |
69 | return -EINVAL; | 114 | return -ENXIO; |
70 | 115 | ||
71 | switch (reg) { | 116 | switch (reg) { |
117 | case PMBUS_IOUT_UC_FAULT_LIMIT: | ||
118 | case PMBUS_IOUT_OC_FAULT_LIMIT: | ||
119 | ret = pmbus_write_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT, | ||
120 | word); | ||
121 | break; | ||
72 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | 122 | case PMBUS_VIRT_RESET_IOUT_HISTORY: |
73 | ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_IOUT, 0); | 123 | ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_IOUT, 0); |
74 | break; | 124 | break; |
@@ -78,6 +128,41 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg, | |||
78 | case PMBUS_VIRT_RESET_VIN_HISTORY: | 128 | case PMBUS_VIRT_RESET_VIN_HISTORY: |
79 | ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VIN, 0); | 129 | ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VIN, 0); |
80 | break; | 130 | break; |
131 | case PMBUS_VIRT_RESET_PIN_HISTORY: | ||
132 | ret = pmbus_write_word_data(client, 0, ADM1276_PEAK_PIN, 0); | ||
133 | break; | ||
134 | default: | ||
135 | ret = -ENODATA; | ||
136 | break; | ||
137 | } | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg) | ||
142 | { | ||
143 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
144 | const struct adm1275_data *data = to_adm1275_data(info); | ||
145 | int mfr_status, ret; | ||
146 | |||
147 | if (page > 0) | ||
148 | return -ENXIO; | ||
149 | |||
150 | switch (reg) { | ||
151 | case PMBUS_STATUS_IOUT: | ||
152 | ret = pmbus_read_byte_data(client, page, PMBUS_STATUS_IOUT); | ||
153 | if (ret < 0) | ||
154 | break; | ||
155 | mfr_status = pmbus_read_byte_data(client, page, | ||
156 | PMBUS_STATUS_MFR_SPECIFIC); | ||
157 | if (mfr_status < 0) { | ||
158 | ret = mfr_status; | ||
159 | break; | ||
160 | } | ||
161 | if (mfr_status & ADM1275_MFR_STATUS_IOUT_WARN2) { | ||
162 | ret |= data->have_oc_fault ? | ||
163 | PB_IOUT_OC_FAULT : PB_IOUT_UC_FAULT; | ||
164 | } | ||
165 | break; | ||
81 | default: | 166 | default: |
82 | ret = -ENODATA; | 167 | ret = -ENODATA; |
83 | break; | 168 | break; |
@@ -88,16 +173,17 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg, | |||
88 | static int adm1275_probe(struct i2c_client *client, | 173 | static int adm1275_probe(struct i2c_client *client, |
89 | const struct i2c_device_id *id) | 174 | const struct i2c_device_id *id) |
90 | { | 175 | { |
91 | int config; | 176 | int config, device_config; |
92 | int ret; | 177 | int ret; |
93 | struct pmbus_driver_info *info; | 178 | struct pmbus_driver_info *info; |
179 | struct adm1275_data *data; | ||
94 | 180 | ||
95 | if (!i2c_check_functionality(client->adapter, | 181 | if (!i2c_check_functionality(client->adapter, |
96 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) | 182 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) |
97 | return -ENODEV; | 183 | return -ENODEV; |
98 | 184 | ||
99 | info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL); | 185 | data = kzalloc(sizeof(struct adm1275_data), GFP_KERNEL); |
100 | if (!info) | 186 | if (!data) |
101 | return -ENOMEM; | 187 | return -ENOMEM; |
102 | 188 | ||
103 | config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG); | 189 | config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG); |
@@ -106,6 +192,15 @@ static int adm1275_probe(struct i2c_client *client, | |||
106 | goto err_mem; | 192 | goto err_mem; |
107 | } | 193 | } |
108 | 194 | ||
195 | device_config = i2c_smbus_read_byte_data(client, ADM1275_DEVICE_CONFIG); | ||
196 | if (device_config < 0) { | ||
197 | ret = device_config; | ||
198 | goto err_mem; | ||
199 | } | ||
200 | |||
201 | data->id = id->driver_data; | ||
202 | info = &data->info; | ||
203 | |||
109 | info->pages = 1; | 204 | info->pages = 1; |
110 | info->format[PSC_VOLTAGE_IN] = direct; | 205 | info->format[PSC_VOLTAGE_IN] = direct; |
111 | info->format[PSC_VOLTAGE_OUT] = direct; | 206 | info->format[PSC_VOLTAGE_OUT] = direct; |
@@ -116,6 +211,7 @@ static int adm1275_probe(struct i2c_client *client, | |||
116 | info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | 211 | info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; |
117 | 212 | ||
118 | info->read_word_data = adm1275_read_word_data; | 213 | info->read_word_data = adm1275_read_word_data; |
214 | info->read_byte_data = adm1275_read_byte_data; | ||
119 | info->write_word_data = adm1275_write_word_data; | 215 | info->write_word_data = adm1275_write_word_data; |
120 | 216 | ||
121 | if (config & ADM1275_VRANGE) { | 217 | if (config & ADM1275_VRANGE) { |
@@ -134,10 +230,36 @@ static int adm1275_probe(struct i2c_client *client, | |||
134 | info->R[PSC_VOLTAGE_OUT] = -1; | 230 | info->R[PSC_VOLTAGE_OUT] = -1; |
135 | } | 231 | } |
136 | 232 | ||
137 | if (config & ADM1275_VIN_VOUT_SELECT) | 233 | if (device_config & ADM1275_IOUT_WARN2_SELECT) |
138 | info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | 234 | data->have_oc_fault = true; |
139 | else | 235 | |
140 | info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT; | 236 | switch (id->driver_data) { |
237 | case adm1275: | ||
238 | if (config & ADM1275_VIN_VOUT_SELECT) | ||
239 | info->func[0] |= | ||
240 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | ||
241 | else | ||
242 | info->func[0] |= | ||
243 | PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT; | ||
244 | break; | ||
245 | case adm1276: | ||
246 | info->format[PSC_POWER] = direct; | ||
247 | info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN | ||
248 | | PMBUS_HAVE_STATUS_INPUT; | ||
249 | if (config & ADM1275_VIN_VOUT_SELECT) | ||
250 | info->func[0] |= | ||
251 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; | ||
252 | if (config & ADM1275_VRANGE) { | ||
253 | info->m[PSC_POWER] = 6043; | ||
254 | info->b[PSC_POWER] = 0; | ||
255 | info->R[PSC_POWER] = -2; | ||
256 | } else { | ||
257 | info->m[PSC_POWER] = 2115; | ||
258 | info->b[PSC_POWER] = 0; | ||
259 | info->R[PSC_POWER] = -1; | ||
260 | } | ||
261 | break; | ||
262 | } | ||
141 | 263 | ||
142 | ret = pmbus_do_probe(client, id, info); | 264 | ret = pmbus_do_probe(client, id, info); |
143 | if (ret) | 265 | if (ret) |
@@ -145,22 +267,23 @@ static int adm1275_probe(struct i2c_client *client, | |||
145 | return 0; | 267 | return 0; |
146 | 268 | ||
147 | err_mem: | 269 | err_mem: |
148 | kfree(info); | 270 | kfree(data); |
149 | return ret; | 271 | return ret; |
150 | } | 272 | } |
151 | 273 | ||
152 | static int adm1275_remove(struct i2c_client *client) | 274 | static int adm1275_remove(struct i2c_client *client) |
153 | { | 275 | { |
154 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | 276 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
155 | int ret; | 277 | const struct adm1275_data *data = to_adm1275_data(info); |
156 | 278 | ||
157 | ret = pmbus_do_remove(client); | 279 | pmbus_do_remove(client); |
158 | kfree(info); | 280 | kfree(data); |
159 | return ret; | 281 | return 0; |
160 | } | 282 | } |
161 | 283 | ||
162 | static const struct i2c_device_id adm1275_id[] = { | 284 | static const struct i2c_device_id adm1275_id[] = { |
163 | {"adm1275", 0}, | 285 | { "adm1275", adm1275 }, |
286 | { "adm1276", adm1276 }, | ||
164 | { } | 287 | { } |
165 | }; | 288 | }; |
166 | MODULE_DEVICE_TABLE(i2c, adm1275_id); | 289 | MODULE_DEVICE_TABLE(i2c, adm1275_id); |
@@ -185,7 +308,7 @@ static void __exit adm1275_exit(void) | |||
185 | } | 308 | } |
186 | 309 | ||
187 | MODULE_AUTHOR("Guenter Roeck"); | 310 | MODULE_AUTHOR("Guenter Roeck"); |
188 | MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275"); | 311 | MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275 and compatibles"); |
189 | MODULE_LICENSE("GPL"); | 312 | MODULE_LICENSE("GPL"); |
190 | module_init(adm1275_init); | 313 | module_init(adm1275_init); |
191 | module_exit(adm1275_exit); | 314 | module_exit(adm1275_exit); |
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index ac254fba551b..84a37f0c8db6 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c | |||
@@ -57,7 +57,7 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
57 | int ret; | 57 | int ret; |
58 | 58 | ||
59 | if (page > 1) | 59 | if (page > 1) |
60 | return -EINVAL; | 60 | return -ENXIO; |
61 | 61 | ||
62 | /* Map READ_VAUX into READ_VOUT register on page 1 */ | 62 | /* Map READ_VAUX into READ_VOUT register on page 1 */ |
63 | if (page == 1) { | 63 | if (page == 1) { |
@@ -85,7 +85,7 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) | |||
85 | break; | 85 | break; |
86 | default: | 86 | default: |
87 | /* No other valid registers on page 1 */ | 87 | /* No other valid registers on page 1 */ |
88 | ret = -EINVAL; | 88 | ret = -ENXIO; |
89 | break; | 89 | break; |
90 | } | 90 | } |
91 | goto done; | 91 | goto done; |
@@ -138,7 +138,7 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | |||
138 | int ret; | 138 | int ret; |
139 | 139 | ||
140 | if (page > 1) | 140 | if (page > 1) |
141 | return -EINVAL; | 141 | return -ENXIO; |
142 | 142 | ||
143 | switch (reg) { | 143 | switch (reg) { |
144 | case PMBUS_IIN_OC_WARN_LIMIT: | 144 | case PMBUS_IIN_OC_WARN_LIMIT: |
@@ -164,10 +164,10 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, | |||
164 | static int lm25066_write_byte(struct i2c_client *client, int page, u8 value) | 164 | static int lm25066_write_byte(struct i2c_client *client, int page, u8 value) |
165 | { | 165 | { |
166 | if (page > 1) | 166 | if (page > 1) |
167 | return -EINVAL; | 167 | return -ENXIO; |
168 | 168 | ||
169 | if (page == 0) | 169 | if (page <= 0) |
170 | return pmbus_write_byte(client, 0, value); | 170 | return pmbus_write_byte(client, page, value); |
171 | 171 | ||
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
@@ -309,11 +309,10 @@ static int lm25066_remove(struct i2c_client *client) | |||
309 | { | 309 | { |
310 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | 310 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
311 | const struct lm25066_data *data = to_lm25066_data(info); | 311 | const struct lm25066_data *data = to_lm25066_data(info); |
312 | int ret; | ||
313 | 312 | ||
314 | ret = pmbus_do_remove(client); | 313 | pmbus_do_remove(client); |
315 | kfree(data); | 314 | kfree(data); |
316 | return ret; | 315 | return 0; |
317 | } | 316 | } |
318 | 317 | ||
319 | static const struct i2c_device_id lm25066_id[] = { | 318 | static const struct i2c_device_id lm25066_id[] = { |
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c new file mode 100644 index 000000000000..820fff48910b --- /dev/null +++ b/drivers/hwmon/pmbus/ltc2978.c | |||
@@ -0,0 +1,408 @@ | |||
1 | /* | ||
2 | * Hardware monitoring driver for LTC2978 and LTC3880 | ||
3 | * | ||
4 | * Copyright (c) 2011 Ericsson AB. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include "pmbus.h" | ||
28 | |||
29 | enum chips { ltc2978, ltc3880 }; | ||
30 | |||
31 | /* LTC2978 and LTC3880 */ | ||
32 | #define LTC2978_MFR_VOUT_PEAK 0xdd | ||
33 | #define LTC2978_MFR_VIN_PEAK 0xde | ||
34 | #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf | ||
35 | #define LTC2978_MFR_SPECIAL_ID 0xe7 | ||
36 | |||
37 | /* LTC2978 only */ | ||
38 | #define LTC2978_MFR_VOUT_MIN 0xfb | ||
39 | #define LTC2978_MFR_VIN_MIN 0xfc | ||
40 | #define LTC2978_MFR_TEMPERATURE_MIN 0xfd | ||
41 | |||
42 | /* LTC3880 only */ | ||
43 | #define LTC3880_MFR_IOUT_PEAK 0xd7 | ||
44 | #define LTC3880_MFR_CLEAR_PEAKS 0xe3 | ||
45 | #define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4 | ||
46 | |||
47 | #define LTC2978_ID_REV1 0x0121 | ||
48 | #define LTC2978_ID_REV2 0x0122 | ||
49 | #define LTC3880_ID 0x4000 | ||
50 | #define LTC3880_ID_MASK 0xff00 | ||
51 | |||
52 | /* | ||
53 | * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which | ||
54 | * happens pretty much each time chip data is updated. Raw peak data therefore | ||
55 | * does not provide much value. To be able to provide useful peak data, keep an | ||
56 | * internal cache of measured peak data, which is only cleared if an explicit | ||
57 | * "clear peak" command is executed for the sensor in question. | ||
58 | */ | ||
59 | struct ltc2978_data { | ||
60 | enum chips id; | ||
61 | int vin_min, vin_max; | ||
62 | int temp_min, temp_max; | ||
63 | int vout_min[8], vout_max[8]; | ||
64 | int iout_max[2]; | ||
65 | int temp2_max[2]; | ||
66 | struct pmbus_driver_info info; | ||
67 | }; | ||
68 | |||
69 | #define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info) | ||
70 | |||
71 | static inline int lin11_to_val(int data) | ||
72 | { | ||
73 | s16 e = ((s16)data) >> 11; | ||
74 | s32 m = (((s16)(data << 5)) >> 5); | ||
75 | |||
76 | /* | ||
77 | * mantissa is 10 bit + sign, exponent adds up to 15 bit. | ||
78 | * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31). | ||
79 | */ | ||
80 | e += 6; | ||
81 | return (e < 0 ? m >> -e : m << e); | ||
82 | } | ||
83 | |||
84 | static int ltc2978_read_word_data_common(struct i2c_client *client, int page, | ||
85 | int reg) | ||
86 | { | ||
87 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
88 | struct ltc2978_data *data = to_ltc2978_data(info); | ||
89 | int ret; | ||
90 | |||
91 | switch (reg) { | ||
92 | case PMBUS_VIRT_READ_VIN_MAX: | ||
93 | ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_PEAK); | ||
94 | if (ret >= 0) { | ||
95 | if (lin11_to_val(ret) > lin11_to_val(data->vin_max)) | ||
96 | data->vin_max = ret; | ||
97 | ret = data->vin_max; | ||
98 | } | ||
99 | break; | ||
100 | case PMBUS_VIRT_READ_VOUT_MAX: | ||
101 | ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK); | ||
102 | if (ret >= 0) { | ||
103 | /* | ||
104 | * VOUT is 16 bit unsigned with fixed exponent, | ||
105 | * so we can compare it directly | ||
106 | */ | ||
107 | if (ret > data->vout_max[page]) | ||
108 | data->vout_max[page] = ret; | ||
109 | ret = data->vout_max[page]; | ||
110 | } | ||
111 | break; | ||
112 | case PMBUS_VIRT_READ_TEMP_MAX: | ||
113 | ret = pmbus_read_word_data(client, page, | ||
114 | LTC2978_MFR_TEMPERATURE_PEAK); | ||
115 | if (ret >= 0) { | ||
116 | if (lin11_to_val(ret) > lin11_to_val(data->temp_max)) | ||
117 | data->temp_max = ret; | ||
118 | ret = data->temp_max; | ||
119 | } | ||
120 | break; | ||
121 | case PMBUS_VIRT_RESET_VOUT_HISTORY: | ||
122 | case PMBUS_VIRT_RESET_VIN_HISTORY: | ||
123 | case PMBUS_VIRT_RESET_TEMP_HISTORY: | ||
124 | ret = 0; | ||
125 | break; | ||
126 | default: | ||
127 | ret = -ENODATA; | ||
128 | break; | ||
129 | } | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg) | ||
134 | { | ||
135 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
136 | struct ltc2978_data *data = to_ltc2978_data(info); | ||
137 | int ret; | ||
138 | |||
139 | switch (reg) { | ||
140 | case PMBUS_VIRT_READ_VIN_MIN: | ||
141 | ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_MIN); | ||
142 | if (ret >= 0) { | ||
143 | if (lin11_to_val(ret) < lin11_to_val(data->vin_min)) | ||
144 | data->vin_min = ret; | ||
145 | ret = data->vin_min; | ||
146 | } | ||
147 | break; | ||
148 | case PMBUS_VIRT_READ_VOUT_MIN: | ||
149 | ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_MIN); | ||
150 | if (ret >= 0) { | ||
151 | /* | ||
152 | * VOUT_MIN is known to not be supported on some lots | ||
153 | * of LTC2978 revision 1, and will return the maximum | ||
154 | * possible voltage if read. If VOUT_MAX is valid and | ||
155 | * lower than the reading of VOUT_MIN, use it instead. | ||
156 | */ | ||
157 | if (data->vout_max[page] && ret > data->vout_max[page]) | ||
158 | ret = data->vout_max[page]; | ||
159 | if (ret < data->vout_min[page]) | ||
160 | data->vout_min[page] = ret; | ||
161 | ret = data->vout_min[page]; | ||
162 | } | ||
163 | break; | ||
164 | case PMBUS_VIRT_READ_TEMP_MIN: | ||
165 | ret = pmbus_read_word_data(client, page, | ||
166 | LTC2978_MFR_TEMPERATURE_MIN); | ||
167 | if (ret >= 0) { | ||
168 | if (lin11_to_val(ret) | ||
169 | < lin11_to_val(data->temp_min)) | ||
170 | data->temp_min = ret; | ||
171 | ret = data->temp_min; | ||
172 | } | ||
173 | break; | ||
174 | case PMBUS_VIRT_READ_IOUT_MAX: | ||
175 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | ||
176 | case PMBUS_VIRT_READ_TEMP2_MAX: | ||
177 | case PMBUS_VIRT_RESET_TEMP2_HISTORY: | ||
178 | ret = -ENXIO; | ||
179 | break; | ||
180 | default: | ||
181 | ret = ltc2978_read_word_data_common(client, page, reg); | ||
182 | break; | ||
183 | } | ||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) | ||
188 | { | ||
189 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
190 | struct ltc2978_data *data = to_ltc2978_data(info); | ||
191 | int ret; | ||
192 | |||
193 | switch (reg) { | ||
194 | case PMBUS_VIRT_READ_IOUT_MAX: | ||
195 | ret = pmbus_read_word_data(client, page, LTC3880_MFR_IOUT_PEAK); | ||
196 | if (ret >= 0) { | ||
197 | if (lin11_to_val(ret) | ||
198 | > lin11_to_val(data->iout_max[page])) | ||
199 | data->iout_max[page] = ret; | ||
200 | ret = data->iout_max[page]; | ||
201 | } | ||
202 | break; | ||
203 | case PMBUS_VIRT_READ_TEMP2_MAX: | ||
204 | ret = pmbus_read_word_data(client, page, | ||
205 | LTC3880_MFR_TEMPERATURE2_PEAK); | ||
206 | if (ret >= 0) { | ||
207 | if (lin11_to_val(ret) | ||
208 | > lin11_to_val(data->temp2_max[page])) | ||
209 | data->temp2_max[page] = ret; | ||
210 | ret = data->temp2_max[page]; | ||
211 | } | ||
212 | break; | ||
213 | case PMBUS_VIRT_READ_VIN_MIN: | ||
214 | case PMBUS_VIRT_READ_VOUT_MIN: | ||
215 | case PMBUS_VIRT_READ_TEMP_MIN: | ||
216 | ret = -ENXIO; | ||
217 | break; | ||
218 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | ||
219 | case PMBUS_VIRT_RESET_TEMP2_HISTORY: | ||
220 | ret = 0; | ||
221 | break; | ||
222 | default: | ||
223 | ret = ltc2978_read_word_data_common(client, page, reg); | ||
224 | break; | ||
225 | } | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | static int ltc2978_clear_peaks(struct i2c_client *client, int page, | ||
230 | enum chips id) | ||
231 | { | ||
232 | int ret; | ||
233 | |||
234 | if (id == ltc2978) | ||
235 | ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); | ||
236 | else | ||
237 | ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS); | ||
238 | |||
239 | return ret; | ||
240 | } | ||
241 | |||
242 | static int ltc2978_write_word_data(struct i2c_client *client, int page, | ||
243 | int reg, u16 word) | ||
244 | { | ||
245 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
246 | struct ltc2978_data *data = to_ltc2978_data(info); | ||
247 | int ret; | ||
248 | |||
249 | switch (reg) { | ||
250 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | ||
251 | data->iout_max[page] = 0x7fff; | ||
252 | ret = ltc2978_clear_peaks(client, page, data->id); | ||
253 | break; | ||
254 | case PMBUS_VIRT_RESET_TEMP2_HISTORY: | ||
255 | data->temp2_max[page] = 0x7fff; | ||
256 | ret = ltc2978_clear_peaks(client, page, data->id); | ||
257 | break; | ||
258 | case PMBUS_VIRT_RESET_VOUT_HISTORY: | ||
259 | data->vout_min[page] = 0xffff; | ||
260 | data->vout_max[page] = 0; | ||
261 | ret = ltc2978_clear_peaks(client, page, data->id); | ||
262 | break; | ||
263 | case PMBUS_VIRT_RESET_VIN_HISTORY: | ||
264 | data->vin_min = 0x7bff; | ||
265 | data->vin_max = 0; | ||
266 | ret = ltc2978_clear_peaks(client, page, data->id); | ||
267 | break; | ||
268 | case PMBUS_VIRT_RESET_TEMP_HISTORY: | ||
269 | data->temp_min = 0x7bff; | ||
270 | data->temp_max = 0x7fff; | ||
271 | ret = ltc2978_clear_peaks(client, page, data->id); | ||
272 | break; | ||
273 | default: | ||
274 | ret = -ENODATA; | ||
275 | break; | ||
276 | } | ||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | static const struct i2c_device_id ltc2978_id[] = { | ||
281 | {"ltc2978", ltc2978}, | ||
282 | {"ltc3880", ltc3880}, | ||
283 | {} | ||
284 | }; | ||
285 | MODULE_DEVICE_TABLE(i2c, ltc2978_id); | ||
286 | |||
287 | static int ltc2978_probe(struct i2c_client *client, | ||
288 | const struct i2c_device_id *id) | ||
289 | { | ||
290 | int chip_id, ret, i; | ||
291 | struct ltc2978_data *data; | ||
292 | struct pmbus_driver_info *info; | ||
293 | |||
294 | if (!i2c_check_functionality(client->adapter, | ||
295 | I2C_FUNC_SMBUS_READ_WORD_DATA)) | ||
296 | return -ENODEV; | ||
297 | |||
298 | data = kzalloc(sizeof(struct ltc2978_data), GFP_KERNEL); | ||
299 | if (!data) | ||
300 | return -ENOMEM; | ||
301 | |||
302 | chip_id = i2c_smbus_read_word_data(client, LTC2978_MFR_SPECIAL_ID); | ||
303 | if (chip_id < 0) { | ||
304 | ret = chip_id; | ||
305 | goto err_mem; | ||
306 | } | ||
307 | |||
308 | if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) { | ||
309 | data->id = ltc2978; | ||
310 | } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) { | ||
311 | data->id = ltc3880; | ||
312 | } else { | ||
313 | dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id); | ||
314 | ret = -ENODEV; | ||
315 | goto err_mem; | ||
316 | } | ||
317 | if (data->id != id->driver_data) | ||
318 | dev_warn(&client->dev, | ||
319 | "Device mismatch: Configured %s, detected %s\n", | ||
320 | id->name, | ||
321 | ltc2978_id[data->id].name); | ||
322 | |||
323 | info = &data->info; | ||
324 | info->write_word_data = ltc2978_write_word_data; | ||
325 | |||
326 | data->vout_min[0] = 0xffff; | ||
327 | data->vin_min = 0x7bff; | ||
328 | data->temp_min = 0x7bff; | ||
329 | data->temp_max = 0x7fff; | ||
330 | |||
331 | switch (id->driver_data) { | ||
332 | case ltc2978: | ||
333 | info->read_word_data = ltc2978_read_word_data; | ||
334 | info->pages = 8; | ||
335 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | ||
336 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
337 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | ||
338 | for (i = 1; i < 8; i++) { | ||
339 | info->func[i] = PMBUS_HAVE_VOUT | ||
340 | | PMBUS_HAVE_STATUS_VOUT; | ||
341 | data->vout_min[i] = 0xffff; | ||
342 | } | ||
343 | break; | ||
344 | case ltc3880: | ||
345 | info->read_word_data = ltc3880_read_word_data; | ||
346 | info->pages = 2; | ||
347 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | ||
348 | | PMBUS_HAVE_STATUS_INPUT | ||
349 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
350 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | ||
351 | | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | ||
352 | | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | ||
353 | info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
354 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | ||
355 | | PMBUS_HAVE_POUT | ||
356 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | ||
357 | data->vout_min[1] = 0xffff; | ||
358 | break; | ||
359 | default: | ||
360 | ret = -ENODEV; | ||
361 | goto err_mem; | ||
362 | } | ||
363 | |||
364 | ret = pmbus_do_probe(client, id, info); | ||
365 | if (ret) | ||
366 | goto err_mem; | ||
367 | return 0; | ||
368 | |||
369 | err_mem: | ||
370 | kfree(data); | ||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static int ltc2978_remove(struct i2c_client *client) | ||
375 | { | ||
376 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
377 | const struct ltc2978_data *data = to_ltc2978_data(info); | ||
378 | |||
379 | pmbus_do_remove(client); | ||
380 | kfree(data); | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | /* This is the driver that will be inserted */ | ||
385 | static struct i2c_driver ltc2978_driver = { | ||
386 | .driver = { | ||
387 | .name = "ltc2978", | ||
388 | }, | ||
389 | .probe = ltc2978_probe, | ||
390 | .remove = ltc2978_remove, | ||
391 | .id_table = ltc2978_id, | ||
392 | }; | ||
393 | |||
394 | static int __init ltc2978_init(void) | ||
395 | { | ||
396 | return i2c_add_driver(<c2978_driver); | ||
397 | } | ||
398 | |||
399 | static void __exit ltc2978_exit(void) | ||
400 | { | ||
401 | i2c_del_driver(<c2978_driver); | ||
402 | } | ||
403 | |||
404 | MODULE_AUTHOR("Guenter Roeck"); | ||
405 | MODULE_DESCRIPTION("PMBus driver for LTC2978 and LTC3880"); | ||
406 | MODULE_LICENSE("GPL"); | ||
407 | module_init(ltc2978_init); | ||
408 | module_exit(ltc2978_exit); | ||
diff --git a/drivers/hwmon/pmbus/max16064.c b/drivers/hwmon/pmbus/max16064.c index e50b296e8db4..1d77cf4d2d44 100644 --- a/drivers/hwmon/pmbus/max16064.c +++ b/drivers/hwmon/pmbus/max16064.c | |||
@@ -105,7 +105,8 @@ static int max16064_probe(struct i2c_client *client, | |||
105 | 105 | ||
106 | static int max16064_remove(struct i2c_client *client) | 106 | static int max16064_remove(struct i2c_client *client) |
107 | { | 107 | { |
108 | return pmbus_do_remove(client); | 108 | pmbus_do_remove(client); |
109 | return 0; | ||
109 | } | 110 | } |
110 | 111 | ||
111 | static const struct i2c_device_id max16064_id[] = { | 112 | static const struct i2c_device_id max16064_id[] = { |
diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c index fda621d2e458..beaf5a8d9c45 100644 --- a/drivers/hwmon/pmbus/max34440.c +++ b/drivers/hwmon/pmbus/max34440.c | |||
@@ -93,12 +93,14 @@ static int max34440_write_word_data(struct i2c_client *client, int page, | |||
93 | 93 | ||
94 | static int max34440_read_byte_data(struct i2c_client *client, int page, int reg) | 94 | static int max34440_read_byte_data(struct i2c_client *client, int page, int reg) |
95 | { | 95 | { |
96 | int ret; | 96 | int ret = 0; |
97 | int mfg_status; | 97 | int mfg_status; |
98 | 98 | ||
99 | ret = pmbus_set_page(client, page); | 99 | if (page >= 0) { |
100 | if (ret < 0) | 100 | ret = pmbus_set_page(client, page); |
101 | return ret; | 101 | if (ret < 0) |
102 | return ret; | ||
103 | } | ||
102 | 104 | ||
103 | switch (reg) { | 105 | switch (reg) { |
104 | case PMBUS_STATUS_IOUT: | 106 | case PMBUS_STATUS_IOUT: |
@@ -224,7 +226,8 @@ static int max34440_probe(struct i2c_client *client, | |||
224 | 226 | ||
225 | static int max34440_remove(struct i2c_client *client) | 227 | static int max34440_remove(struct i2c_client *client) |
226 | { | 228 | { |
227 | return pmbus_do_remove(client); | 229 | pmbus_do_remove(client); |
230 | return 0; | ||
228 | } | 231 | } |
229 | 232 | ||
230 | static const struct i2c_device_id max34440_id[] = { | 233 | static const struct i2c_device_id max34440_id[] = { |
diff --git a/drivers/hwmon/pmbus/max8688.c b/drivers/hwmon/pmbus/max8688.c index c3e72f1a3cfb..e2b74bb399ba 100644 --- a/drivers/hwmon/pmbus/max8688.c +++ b/drivers/hwmon/pmbus/max8688.c | |||
@@ -45,7 +45,7 @@ static int max8688_read_word_data(struct i2c_client *client, int page, int reg) | |||
45 | int ret; | 45 | int ret; |
46 | 46 | ||
47 | if (page) | 47 | if (page) |
48 | return -EINVAL; | 48 | return -ENXIO; |
49 | 49 | ||
50 | switch (reg) { | 50 | switch (reg) { |
51 | case PMBUS_VIRT_READ_VOUT_MAX: | 51 | case PMBUS_VIRT_READ_VOUT_MAX: |
@@ -101,8 +101,8 @@ static int max8688_read_byte_data(struct i2c_client *client, int page, int reg) | |||
101 | int ret = 0; | 101 | int ret = 0; |
102 | int mfg_status; | 102 | int mfg_status; |
103 | 103 | ||
104 | if (page) | 104 | if (page > 0) |
105 | return -EINVAL; | 105 | return -ENXIO; |
106 | 106 | ||
107 | switch (reg) { | 107 | switch (reg) { |
108 | case PMBUS_STATUS_VOUT: | 108 | case PMBUS_STATUS_VOUT: |
@@ -182,7 +182,8 @@ static int max8688_probe(struct i2c_client *client, | |||
182 | 182 | ||
183 | static int max8688_remove(struct i2c_client *client) | 183 | static int max8688_remove(struct i2c_client *client) |
184 | { | 184 | { |
185 | return pmbus_do_remove(client); | 185 | pmbus_do_remove(client); |
186 | return 0; | ||
186 | } | 187 | } |
187 | 188 | ||
188 | static const struct i2c_device_id max8688_id[] = { | 189 | static const struct i2c_device_id max8688_id[] = { |
diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c index 73de9f1f3194..995e873197e3 100644 --- a/drivers/hwmon/pmbus/pmbus.c +++ b/drivers/hwmon/pmbus/pmbus.c | |||
@@ -187,13 +187,12 @@ out: | |||
187 | 187 | ||
188 | static int pmbus_remove(struct i2c_client *client) | 188 | static int pmbus_remove(struct i2c_client *client) |
189 | { | 189 | { |
190 | int ret; | ||
191 | const struct pmbus_driver_info *info; | 190 | const struct pmbus_driver_info *info; |
192 | 191 | ||
193 | info = pmbus_get_driver_info(client); | 192 | info = pmbus_get_driver_info(client); |
194 | ret = pmbus_do_remove(client); | 193 | pmbus_do_remove(client); |
195 | kfree(info); | 194 | kfree(info); |
196 | return ret; | 195 | return 0; |
197 | } | 196 | } |
198 | 197 | ||
199 | /* | 198 | /* |
@@ -205,10 +204,13 @@ static const struct i2c_device_id pmbus_id[] = { | |||
205 | {"bmr451", 1}, | 204 | {"bmr451", 1}, |
206 | {"bmr453", 1}, | 205 | {"bmr453", 1}, |
207 | {"bmr454", 1}, | 206 | {"bmr454", 1}, |
208 | {"ltc2978", 8}, | ||
209 | {"ncp4200", 1}, | 207 | {"ncp4200", 1}, |
210 | {"ncp4208", 1}, | 208 | {"ncp4208", 1}, |
209 | {"pdt003", 1}, | ||
210 | {"pdt006", 1}, | ||
211 | {"pdt012", 1}, | ||
211 | {"pmbus", 0}, | 212 | {"pmbus", 0}, |
213 | {"udt020", 1}, | ||
212 | {} | 214 | {} |
213 | }; | 215 | }; |
214 | 216 | ||
diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index a6ae20ffef6b..5d31d1c2c0f5 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h | |||
@@ -134,8 +134,16 @@ | |||
134 | * Semantics: | 134 | * Semantics: |
135 | * Virtual registers are all word size. | 135 | * Virtual registers are all word size. |
136 | * READ registers are read-only; writes are either ignored or return an error. | 136 | * READ registers are read-only; writes are either ignored or return an error. |
137 | * RESET registers are read/write. Reading returns zero (used for detection), | 137 | * RESET registers are read/write. Reading reset registers returns zero |
138 | * writing any value causes the associated history to be reset. | 138 | * (used for detection), writing any value causes the associated history to be |
139 | * reset. | ||
140 | * Virtual registers have to be handled in device specific driver code. Chip | ||
141 | * driver code returns non-negative register values if a virtual register is | ||
142 | * supported, or a negative error code if not. The chip driver may return | ||
143 | * -ENODATA or any other error code in this case, though an error code other | ||
144 | * than -ENODATA is handled more efficiently and thus preferred. Either case, | ||
145 | * the calling PMBus core code will abort if the chip driver returns an error | ||
146 | * code when reading or writing virtual registers. | ||
139 | */ | 147 | */ |
140 | #define PMBUS_VIRT_BASE 0x100 | 148 | #define PMBUS_VIRT_BASE 0x100 |
141 | #define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 0) | 149 | #define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 0) |
@@ -160,6 +168,9 @@ | |||
160 | #define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 19) | 168 | #define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 19) |
161 | #define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 20) | 169 | #define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 20) |
162 | #define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 21) | 170 | #define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 21) |
171 | #define PMBUS_VIRT_READ_TEMP2_MIN (PMBUS_VIRT_BASE + 22) | ||
172 | #define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 23) | ||
173 | #define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 24) | ||
163 | 174 | ||
164 | /* | 175 | /* |
165 | * CAPABILITY | 176 | * CAPABILITY |
@@ -320,6 +331,12 @@ struct pmbus_driver_info { | |||
320 | * The following functions map manufacturing specific register values | 331 | * The following functions map manufacturing specific register values |
321 | * to PMBus standard register values. Specify only if mapping is | 332 | * to PMBus standard register values. Specify only if mapping is |
322 | * necessary. | 333 | * necessary. |
334 | * Functions return the register value (read) or zero (write) if | ||
335 | * successful. A return value of -ENODATA indicates that there is no | ||
336 | * manufacturer specific register, but that a standard PMBus register | ||
337 | * may exist. Any other negative return value indicates that the | ||
338 | * register does not exist, and that no attempt should be made to read | ||
339 | * the standard register. | ||
323 | */ | 340 | */ |
324 | int (*read_byte_data)(struct i2c_client *client, int page, int reg); | 341 | int (*read_byte_data)(struct i2c_client *client, int page, int reg); |
325 | int (*read_word_data)(struct i2c_client *client, int page, int reg); | 342 | int (*read_word_data)(struct i2c_client *client, int page, int reg); |
@@ -347,7 +364,7 @@ bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); | |||
347 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); | 364 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); |
348 | int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, | 365 | int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, |
349 | struct pmbus_driver_info *info); | 366 | struct pmbus_driver_info *info); |
350 | int pmbus_do_remove(struct i2c_client *client); | 367 | void pmbus_do_remove(struct i2c_client *client); |
351 | const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client | 368 | const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client |
352 | *client); | 369 | *client); |
353 | 370 | ||
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 397fc59b5682..00460d8d8423 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
@@ -160,7 +160,7 @@ int pmbus_set_page(struct i2c_client *client, u8 page) | |||
160 | rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); | 160 | rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); |
161 | newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE); | 161 | newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE); |
162 | if (newpage != page) | 162 | if (newpage != page) |
163 | rv = -EINVAL; | 163 | rv = -EIO; |
164 | else | 164 | else |
165 | data->currpage = page; | 165 | data->currpage = page; |
166 | } | 166 | } |
@@ -229,7 +229,7 @@ static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, | |||
229 | return status; | 229 | return status; |
230 | } | 230 | } |
231 | if (reg >= PMBUS_VIRT_BASE) | 231 | if (reg >= PMBUS_VIRT_BASE) |
232 | return -EINVAL; | 232 | return -ENXIO; |
233 | return pmbus_write_word_data(client, page, reg, word); | 233 | return pmbus_write_word_data(client, page, reg, word); |
234 | } | 234 | } |
235 | 235 | ||
@@ -261,7 +261,7 @@ static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg) | |||
261 | return status; | 261 | return status; |
262 | } | 262 | } |
263 | if (reg >= PMBUS_VIRT_BASE) | 263 | if (reg >= PMBUS_VIRT_BASE) |
264 | return -EINVAL; | 264 | return -ENXIO; |
265 | return pmbus_read_word_data(client, page, reg); | 265 | return pmbus_read_word_data(client, page, reg); |
266 | } | 266 | } |
267 | 267 | ||
@@ -316,11 +316,11 @@ static int pmbus_check_status_cml(struct i2c_client *client) | |||
316 | { | 316 | { |
317 | int status, status2; | 317 | int status, status2; |
318 | 318 | ||
319 | status = pmbus_read_byte_data(client, -1, PMBUS_STATUS_BYTE); | 319 | status = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_BYTE); |
320 | if (status < 0 || (status & PB_STATUS_CML)) { | 320 | if (status < 0 || (status & PB_STATUS_CML)) { |
321 | status2 = pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); | 321 | status2 = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); |
322 | if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND)) | 322 | if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND)) |
323 | return -EINVAL; | 323 | return -EIO; |
324 | } | 324 | } |
325 | return 0; | 325 | return 0; |
326 | } | 326 | } |
@@ -371,8 +371,8 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) | |||
371 | 371 | ||
372 | for (i = 0; i < info->pages; i++) | 372 | for (i = 0; i < info->pages; i++) |
373 | data->status[PB_STATUS_BASE + i] | 373 | data->status[PB_STATUS_BASE + i] |
374 | = pmbus_read_byte_data(client, i, | 374 | = _pmbus_read_byte_data(client, i, |
375 | PMBUS_STATUS_BYTE); | 375 | PMBUS_STATUS_BYTE); |
376 | for (i = 0; i < info->pages; i++) { | 376 | for (i = 0; i < info->pages; i++) { |
377 | if (!(info->func[i] & PMBUS_HAVE_STATUS_VOUT)) | 377 | if (!(info->func[i] & PMBUS_HAVE_STATUS_VOUT)) |
378 | continue; | 378 | continue; |
@@ -445,13 +445,8 @@ static long pmbus_reg2data_linear(struct pmbus_data *data, | |||
445 | exponent = data->exponent; | 445 | exponent = data->exponent; |
446 | mantissa = (u16) sensor->data; | 446 | mantissa = (u16) sensor->data; |
447 | } else { /* LINEAR11 */ | 447 | } else { /* LINEAR11 */ |
448 | exponent = (sensor->data >> 11) & 0x001f; | 448 | exponent = ((s16)sensor->data) >> 11; |
449 | mantissa = sensor->data & 0x07ff; | 449 | mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5; |
450 | |||
451 | if (exponent > 0x0f) | ||
452 | exponent |= 0xffe0; /* sign extend exponent */ | ||
453 | if (mantissa > 0x03ff) | ||
454 | mantissa |= 0xfffff800; /* sign extend mantissa */ | ||
455 | } | 450 | } |
456 | 451 | ||
457 | val = mantissa; | 452 | val = mantissa; |
@@ -1401,7 +1396,42 @@ static const struct pmbus_limit_attr temp_limit_attrs[] = { | |||
1401 | } | 1396 | } |
1402 | }; | 1397 | }; |
1403 | 1398 | ||
1404 | static const struct pmbus_limit_attr temp_limit_attrs23[] = { | 1399 | static const struct pmbus_limit_attr temp_limit_attrs2[] = { |
1400 | { | ||
1401 | .reg = PMBUS_UT_WARN_LIMIT, | ||
1402 | .low = true, | ||
1403 | .attr = "min", | ||
1404 | .alarm = "min_alarm", | ||
1405 | .sbit = PB_TEMP_UT_WARNING, | ||
1406 | }, { | ||
1407 | .reg = PMBUS_UT_FAULT_LIMIT, | ||
1408 | .low = true, | ||
1409 | .attr = "lcrit", | ||
1410 | .alarm = "lcrit_alarm", | ||
1411 | .sbit = PB_TEMP_UT_FAULT, | ||
1412 | }, { | ||
1413 | .reg = PMBUS_OT_WARN_LIMIT, | ||
1414 | .attr = "max", | ||
1415 | .alarm = "max_alarm", | ||
1416 | .sbit = PB_TEMP_OT_WARNING, | ||
1417 | }, { | ||
1418 | .reg = PMBUS_OT_FAULT_LIMIT, | ||
1419 | .attr = "crit", | ||
1420 | .alarm = "crit_alarm", | ||
1421 | .sbit = PB_TEMP_OT_FAULT, | ||
1422 | }, { | ||
1423 | .reg = PMBUS_VIRT_READ_TEMP2_MIN, | ||
1424 | .attr = "lowest", | ||
1425 | }, { | ||
1426 | .reg = PMBUS_VIRT_READ_TEMP2_MAX, | ||
1427 | .attr = "highest", | ||
1428 | }, { | ||
1429 | .reg = PMBUS_VIRT_RESET_TEMP2_HISTORY, | ||
1430 | .attr = "reset_history", | ||
1431 | } | ||
1432 | }; | ||
1433 | |||
1434 | static const struct pmbus_limit_attr temp_limit_attrs3[] = { | ||
1405 | { | 1435 | { |
1406 | .reg = PMBUS_UT_WARN_LIMIT, | 1436 | .reg = PMBUS_UT_WARN_LIMIT, |
1407 | .low = true, | 1437 | .low = true, |
@@ -1450,8 +1480,8 @@ static const struct pmbus_sensor_attr temp_attributes[] = { | |||
1450 | .sfunc = PMBUS_HAVE_STATUS_TEMP, | 1480 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
1451 | .sbase = PB_STATUS_TEMP_BASE, | 1481 | .sbase = PB_STATUS_TEMP_BASE, |
1452 | .gbit = PB_STATUS_TEMPERATURE, | 1482 | .gbit = PB_STATUS_TEMPERATURE, |
1453 | .limit = temp_limit_attrs23, | 1483 | .limit = temp_limit_attrs2, |
1454 | .nlimit = ARRAY_SIZE(temp_limit_attrs23), | 1484 | .nlimit = ARRAY_SIZE(temp_limit_attrs2), |
1455 | }, { | 1485 | }, { |
1456 | .reg = PMBUS_READ_TEMPERATURE_3, | 1486 | .reg = PMBUS_READ_TEMPERATURE_3, |
1457 | .class = PSC_TEMPERATURE, | 1487 | .class = PSC_TEMPERATURE, |
@@ -1462,8 +1492,8 @@ static const struct pmbus_sensor_attr temp_attributes[] = { | |||
1462 | .sfunc = PMBUS_HAVE_STATUS_TEMP, | 1492 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
1463 | .sbase = PB_STATUS_TEMP_BASE, | 1493 | .sbase = PB_STATUS_TEMP_BASE, |
1464 | .gbit = PB_STATUS_TEMPERATURE, | 1494 | .gbit = PB_STATUS_TEMPERATURE, |
1465 | .limit = temp_limit_attrs23, | 1495 | .limit = temp_limit_attrs3, |
1466 | .nlimit = ARRAY_SIZE(temp_limit_attrs23), | 1496 | .nlimit = ARRAY_SIZE(temp_limit_attrs3), |
1467 | } | 1497 | } |
1468 | }; | 1498 | }; |
1469 | 1499 | ||
@@ -1593,10 +1623,10 @@ static void pmbus_find_attributes(struct i2c_client *client, | |||
1593 | static int pmbus_identify_common(struct i2c_client *client, | 1623 | static int pmbus_identify_common(struct i2c_client *client, |
1594 | struct pmbus_data *data) | 1624 | struct pmbus_data *data) |
1595 | { | 1625 | { |
1596 | int vout_mode = -1, exponent; | 1626 | int vout_mode = -1; |
1597 | 1627 | ||
1598 | if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) | 1628 | if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) |
1599 | vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); | 1629 | vout_mode = _pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); |
1600 | if (vout_mode >= 0 && vout_mode != 0xff) { | 1630 | if (vout_mode >= 0 && vout_mode != 0xff) { |
1601 | /* | 1631 | /* |
1602 | * Not all chips support the VOUT_MODE command, | 1632 | * Not all chips support the VOUT_MODE command, |
@@ -1607,11 +1637,7 @@ static int pmbus_identify_common(struct i2c_client *client, | |||
1607 | if (data->info->format[PSC_VOLTAGE_OUT] != linear) | 1637 | if (data->info->format[PSC_VOLTAGE_OUT] != linear) |
1608 | return -ENODEV; | 1638 | return -ENODEV; |
1609 | 1639 | ||
1610 | exponent = vout_mode & 0x1f; | 1640 | data->exponent = ((s8)(vout_mode << 3)) >> 3; |
1611 | /* and sign-extend it */ | ||
1612 | if (exponent & 0x10) | ||
1613 | exponent |= ~0x1f; | ||
1614 | data->exponent = exponent; | ||
1615 | break; | 1641 | break; |
1616 | case 1: /* VID mode */ | 1642 | case 1: /* VID mode */ |
1617 | if (data->info->format[PSC_VOLTAGE_OUT] != vid) | 1643 | if (data->info->format[PSC_VOLTAGE_OUT] != vid) |
@@ -1682,7 +1708,7 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, | |||
1682 | if (info->pages <= 0 || info->pages > PMBUS_PAGES) { | 1708 | if (info->pages <= 0 || info->pages > PMBUS_PAGES) { |
1683 | dev_err(&client->dev, "Bad number of PMBus pages: %d\n", | 1709 | dev_err(&client->dev, "Bad number of PMBus pages: %d\n", |
1684 | info->pages); | 1710 | info->pages); |
1685 | ret = -EINVAL; | 1711 | ret = -ENODEV; |
1686 | goto out_data; | 1712 | goto out_data; |
1687 | } | 1713 | } |
1688 | 1714 | ||
@@ -1764,7 +1790,7 @@ out_data: | |||
1764 | } | 1790 | } |
1765 | EXPORT_SYMBOL_GPL(pmbus_do_probe); | 1791 | EXPORT_SYMBOL_GPL(pmbus_do_probe); |
1766 | 1792 | ||
1767 | int pmbus_do_remove(struct i2c_client *client) | 1793 | void pmbus_do_remove(struct i2c_client *client) |
1768 | { | 1794 | { |
1769 | struct pmbus_data *data = i2c_get_clientdata(client); | 1795 | struct pmbus_data *data = i2c_get_clientdata(client); |
1770 | hwmon_device_unregister(data->hwmon_dev); | 1796 | hwmon_device_unregister(data->hwmon_dev); |
@@ -1774,7 +1800,6 @@ int pmbus_do_remove(struct i2c_client *client) | |||
1774 | kfree(data->booleans); | 1800 | kfree(data->booleans); |
1775 | kfree(data->sensors); | 1801 | kfree(data->sensors); |
1776 | kfree(data); | 1802 | kfree(data); |
1777 | return 0; | ||
1778 | } | 1803 | } |
1779 | EXPORT_SYMBOL_GPL(pmbus_do_remove); | 1804 | EXPORT_SYMBOL_GPL(pmbus_do_remove); |
1780 | 1805 | ||
diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c index d0ddb60155c9..4ff6cf289f85 100644 --- a/drivers/hwmon/pmbus/ucd9000.c +++ b/drivers/hwmon/pmbus/ucd9000.c | |||
@@ -74,8 +74,8 @@ static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg) | |||
74 | 74 | ||
75 | switch (reg) { | 75 | switch (reg) { |
76 | case PMBUS_FAN_CONFIG_12: | 76 | case PMBUS_FAN_CONFIG_12: |
77 | if (page) | 77 | if (page > 0) |
78 | return -EINVAL; | 78 | return -ENXIO; |
79 | 79 | ||
80 | ret = ucd9000_get_fan_config(client, 0); | 80 | ret = ucd9000_get_fan_config(client, 0); |
81 | if (ret < 0) | 81 | if (ret < 0) |
@@ -88,8 +88,8 @@ static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg) | |||
88 | ret = fan_config; | 88 | ret = fan_config; |
89 | break; | 89 | break; |
90 | case PMBUS_FAN_CONFIG_34: | 90 | case PMBUS_FAN_CONFIG_34: |
91 | if (page) | 91 | if (page > 0) |
92 | return -EINVAL; | 92 | return -ENXIO; |
93 | 93 | ||
94 | ret = ucd9000_get_fan_config(client, 2); | 94 | ret = ucd9000_get_fan_config(client, 2); |
95 | if (ret < 0) | 95 | if (ret < 0) |
@@ -239,13 +239,12 @@ out: | |||
239 | 239 | ||
240 | static int ucd9000_remove(struct i2c_client *client) | 240 | static int ucd9000_remove(struct i2c_client *client) |
241 | { | 241 | { |
242 | int ret; | ||
243 | struct ucd9000_data *data; | 242 | struct ucd9000_data *data; |
244 | 243 | ||
245 | data = to_ucd9000_data(pmbus_get_driver_info(client)); | 244 | data = to_ucd9000_data(pmbus_get_driver_info(client)); |
246 | ret = pmbus_do_remove(client); | 245 | pmbus_do_remove(client); |
247 | kfree(data); | 246 | kfree(data); |
248 | return ret; | 247 | return 0; |
249 | } | 248 | } |
250 | 249 | ||
251 | 250 | ||
diff --git a/drivers/hwmon/pmbus/ucd9200.c b/drivers/hwmon/pmbus/ucd9200.c index c65e9da707cc..6e1c1a80ab85 100644 --- a/drivers/hwmon/pmbus/ucd9200.c +++ b/drivers/hwmon/pmbus/ucd9200.c | |||
@@ -171,13 +171,12 @@ out: | |||
171 | 171 | ||
172 | static int ucd9200_remove(struct i2c_client *client) | 172 | static int ucd9200_remove(struct i2c_client *client) |
173 | { | 173 | { |
174 | int ret; | ||
175 | const struct pmbus_driver_info *info; | 174 | const struct pmbus_driver_info *info; |
176 | 175 | ||
177 | info = pmbus_get_driver_info(client); | 176 | info = pmbus_get_driver_info(client); |
178 | ret = pmbus_do_remove(client); | 177 | pmbus_do_remove(client); |
179 | kfree(info); | 178 | kfree(info); |
180 | return ret; | 179 | return 0; |
181 | } | 180 | } |
182 | 181 | ||
183 | 182 | ||
diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c new file mode 100644 index 000000000000..2bc980006f83 --- /dev/null +++ b/drivers/hwmon/pmbus/zl6100.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /* | ||
2 | * Hardware monitoring driver for ZL6100 and compatibles | ||
3 | * | ||
4 | * Copyright (c) 2011 Ericsson AB. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/ktime.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include "pmbus.h" | ||
30 | |||
31 | enum chips { zl2004, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105 }; | ||
32 | |||
33 | struct zl6100_data { | ||
34 | int id; | ||
35 | ktime_t access; /* chip access time */ | ||
36 | struct pmbus_driver_info info; | ||
37 | }; | ||
38 | |||
39 | #define to_zl6100_data(x) container_of(x, struct zl6100_data, info) | ||
40 | |||
41 | #define ZL6100_DEVICE_ID 0xe4 | ||
42 | |||
43 | #define ZL6100_WAIT_TIME 1000 /* uS */ | ||
44 | |||
45 | static ushort delay = ZL6100_WAIT_TIME; | ||
46 | module_param(delay, ushort, 0644); | ||
47 | MODULE_PARM_DESC(delay, "Delay between chip accesses in uS"); | ||
48 | |||
49 | /* Some chips need a delay between accesses */ | ||
50 | static inline void zl6100_wait(const struct zl6100_data *data) | ||
51 | { | ||
52 | if (delay) { | ||
53 | s64 delta = ktime_us_delta(ktime_get(), data->access); | ||
54 | if (delta < delay) | ||
55 | udelay(delay - delta); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | static int zl6100_read_word_data(struct i2c_client *client, int page, int reg) | ||
60 | { | ||
61 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
62 | struct zl6100_data *data = to_zl6100_data(info); | ||
63 | int ret; | ||
64 | |||
65 | if (page || reg >= PMBUS_VIRT_BASE) | ||
66 | return -ENXIO; | ||
67 | |||
68 | zl6100_wait(data); | ||
69 | ret = pmbus_read_word_data(client, page, reg); | ||
70 | data->access = ktime_get(); | ||
71 | |||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | static int zl6100_read_byte_data(struct i2c_client *client, int page, int reg) | ||
76 | { | ||
77 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
78 | struct zl6100_data *data = to_zl6100_data(info); | ||
79 | int ret; | ||
80 | |||
81 | if (page > 0) | ||
82 | return -ENXIO; | ||
83 | |||
84 | zl6100_wait(data); | ||
85 | ret = pmbus_read_byte_data(client, page, reg); | ||
86 | data->access = ktime_get(); | ||
87 | |||
88 | return ret; | ||
89 | } | ||
90 | |||
91 | static int zl6100_write_word_data(struct i2c_client *client, int page, int reg, | ||
92 | u16 word) | ||
93 | { | ||
94 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
95 | struct zl6100_data *data = to_zl6100_data(info); | ||
96 | int ret; | ||
97 | |||
98 | if (page || reg >= PMBUS_VIRT_BASE) | ||
99 | return -ENXIO; | ||
100 | |||
101 | zl6100_wait(data); | ||
102 | ret = pmbus_write_word_data(client, page, reg, word); | ||
103 | data->access = ktime_get(); | ||
104 | |||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | static int zl6100_write_byte(struct i2c_client *client, int page, u8 value) | ||
109 | { | ||
110 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
111 | struct zl6100_data *data = to_zl6100_data(info); | ||
112 | int ret; | ||
113 | |||
114 | if (page > 0) | ||
115 | return -ENXIO; | ||
116 | |||
117 | zl6100_wait(data); | ||
118 | ret = pmbus_write_byte(client, page, value); | ||
119 | data->access = ktime_get(); | ||
120 | |||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | static const struct i2c_device_id zl6100_id[] = { | ||
125 | {"zl2004", zl2004}, | ||
126 | {"zl2006", zl2006}, | ||
127 | {"zl2008", zl2008}, | ||
128 | {"zl2105", zl2105}, | ||
129 | {"zl2106", zl2106}, | ||
130 | {"zl6100", zl6100}, | ||
131 | {"zl6105", zl6105}, | ||
132 | { } | ||
133 | }; | ||
134 | MODULE_DEVICE_TABLE(i2c, zl6100_id); | ||
135 | |||
136 | static int zl6100_probe(struct i2c_client *client, | ||
137 | const struct i2c_device_id *id) | ||
138 | { | ||
139 | int ret; | ||
140 | struct zl6100_data *data; | ||
141 | struct pmbus_driver_info *info; | ||
142 | u8 device_id[I2C_SMBUS_BLOCK_MAX + 1]; | ||
143 | const struct i2c_device_id *mid; | ||
144 | |||
145 | if (!i2c_check_functionality(client->adapter, | ||
146 | I2C_FUNC_SMBUS_READ_BYTE_DATA | ||
147 | | I2C_FUNC_SMBUS_READ_BLOCK_DATA)) | ||
148 | return -ENODEV; | ||
149 | |||
150 | ret = i2c_smbus_read_block_data(client, ZL6100_DEVICE_ID, | ||
151 | device_id); | ||
152 | if (ret < 0) { | ||
153 | dev_err(&client->dev, "Failed to read device ID\n"); | ||
154 | return ret; | ||
155 | } | ||
156 | device_id[ret] = '\0'; | ||
157 | dev_info(&client->dev, "Device ID %s\n", device_id); | ||
158 | |||
159 | mid = NULL; | ||
160 | for (mid = zl6100_id; mid->name[0]; mid++) { | ||
161 | if (!strncasecmp(mid->name, device_id, strlen(mid->name))) | ||
162 | break; | ||
163 | } | ||
164 | if (!mid->name[0]) { | ||
165 | dev_err(&client->dev, "Unsupported device\n"); | ||
166 | return -ENODEV; | ||
167 | } | ||
168 | if (id->driver_data != mid->driver_data) | ||
169 | dev_notice(&client->dev, | ||
170 | "Device mismatch: Configured %s, detected %s\n", | ||
171 | id->name, mid->name); | ||
172 | |||
173 | data = kzalloc(sizeof(struct zl6100_data), GFP_KERNEL); | ||
174 | if (!data) | ||
175 | return -ENOMEM; | ||
176 | |||
177 | data->id = mid->driver_data; | ||
178 | |||
179 | /* | ||
180 | * ZL2008, ZL2105, and ZL6100 are known to require a wait time | ||
181 | * between I2C accesses. ZL2004 and ZL6105 are known to be safe. | ||
182 | * | ||
183 | * Only clear the wait time for chips known to be safe. The wait time | ||
184 | * can be cleared later for additional chips if tests show that it | ||
185 | * is not needed (in other words, better be safe than sorry). | ||
186 | */ | ||
187 | if (data->id == zl2004 || data->id == zl6105) | ||
188 | delay = 0; | ||
189 | |||
190 | /* | ||
191 | * Since there was a direct I2C device access above, wait before | ||
192 | * accessing the chip again. | ||
193 | * Set the timestamp, wait, then set it again. This should provide | ||
194 | * enough buffer time to be safe. | ||
195 | */ | ||
196 | data->access = ktime_get(); | ||
197 | zl6100_wait(data); | ||
198 | data->access = ktime_get(); | ||
199 | |||
200 | info = &data->info; | ||
201 | |||
202 | info->pages = 1; | ||
203 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | ||
204 | | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
205 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | ||
206 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | ||
207 | |||
208 | info->read_word_data = zl6100_read_word_data; | ||
209 | info->read_byte_data = zl6100_read_byte_data; | ||
210 | info->write_word_data = zl6100_write_word_data; | ||
211 | info->write_byte = zl6100_write_byte; | ||
212 | |||
213 | ret = pmbus_do_probe(client, mid, info); | ||
214 | if (ret) | ||
215 | goto err_mem; | ||
216 | return 0; | ||
217 | |||
218 | err_mem: | ||
219 | kfree(data); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static int zl6100_remove(struct i2c_client *client) | ||
224 | { | ||
225 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
226 | const struct zl6100_data *data = to_zl6100_data(info); | ||
227 | |||
228 | pmbus_do_remove(client); | ||
229 | kfree(data); | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static struct i2c_driver zl6100_driver = { | ||
234 | .driver = { | ||
235 | .name = "zl6100", | ||
236 | }, | ||
237 | .probe = zl6100_probe, | ||
238 | .remove = zl6100_remove, | ||
239 | .id_table = zl6100_id, | ||
240 | }; | ||
241 | |||
242 | static int __init zl6100_init(void) | ||
243 | { | ||
244 | return i2c_add_driver(&zl6100_driver); | ||
245 | } | ||
246 | |||
247 | static void __exit zl6100_exit(void) | ||
248 | { | ||
249 | i2c_del_driver(&zl6100_driver); | ||
250 | } | ||
251 | |||
252 | MODULE_AUTHOR("Guenter Roeck"); | ||
253 | MODULE_DESCRIPTION("PMBus driver for ZL6100 and compatibles"); | ||
254 | MODULE_LICENSE("GPL"); | ||
255 | module_init(zl6100_init); | ||
256 | module_exit(zl6100_exit); | ||
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c index 1c8c9812f244..15398780cc00 100644 --- a/drivers/hwmon/sht21.c +++ b/drivers/hwmon/sht21.c | |||
@@ -83,25 +83,6 @@ static inline int sht21_rh_ticks_to_per_cent_mille(int ticks) | |||
83 | } | 83 | } |
84 | 84 | ||
85 | /** | 85 | /** |
86 | * sht21_read_word_data() - read word from register | ||
87 | * @client: I2C client device | ||
88 | * @reg: I2C command byte | ||
89 | * | ||
90 | * Returns value, negative errno on error. | ||
91 | */ | ||
92 | static inline int sht21_read_word_data(struct i2c_client *client, u8 reg) | ||
93 | { | ||
94 | int ret = i2c_smbus_read_word_data(client, reg); | ||
95 | if (ret < 0) | ||
96 | return ret; | ||
97 | /* | ||
98 | * SMBus specifies low byte first, but the SHT21 returns MSB | ||
99 | * first, so we have to swab16 the values | ||
100 | */ | ||
101 | return swab16(ret); | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * sht21_update_measurements() - get updated measurements from device | 86 | * sht21_update_measurements() - get updated measurements from device |
106 | * @client: I2C client device | 87 | * @client: I2C client device |
107 | * | 88 | * |
@@ -119,12 +100,13 @@ static int sht21_update_measurements(struct i2c_client *client) | |||
119 | * maximum two measurements per second at 12bit accuracy shall be made. | 100 | * maximum two measurements per second at 12bit accuracy shall be made. |
120 | */ | 101 | */ |
121 | if (time_after(jiffies, sht21->last_update + HZ / 2) || !sht21->valid) { | 102 | if (time_after(jiffies, sht21->last_update + HZ / 2) || !sht21->valid) { |
122 | ret = sht21_read_word_data(client, SHT21_TRIG_T_MEASUREMENT_HM); | 103 | ret = i2c_smbus_read_word_swapped(client, |
104 | SHT21_TRIG_T_MEASUREMENT_HM); | ||
123 | if (ret < 0) | 105 | if (ret < 0) |
124 | goto out; | 106 | goto out; |
125 | sht21->temperature = sht21_temp_ticks_to_millicelsius(ret); | 107 | sht21->temperature = sht21_temp_ticks_to_millicelsius(ret); |
126 | ret = sht21_read_word_data(client, | 108 | ret = i2c_smbus_read_word_swapped(client, |
127 | SHT21_TRIG_RH_MEASUREMENT_HM); | 109 | SHT21_TRIG_RH_MEASUREMENT_HM); |
128 | if (ret < 0) | 110 | if (ret < 0) |
129 | goto out; | 111 | goto out; |
130 | sht21->humidity = sht21_rh_ticks_to_per_cent_mille(ret); | 112 | sht21->humidity = sht21_rh_ticks_to_per_cent_mille(ret); |
diff --git a/drivers/hwmon/smm665.c b/drivers/hwmon/smm665.c index 425df5bccd45..411638181fd8 100644 --- a/drivers/hwmon/smm665.c +++ b/drivers/hwmon/smm665.c | |||
@@ -214,33 +214,26 @@ static int smm665_read_adc(struct smm665_data *data, int adc) | |||
214 | * | 214 | * |
215 | * Neither i2c_smbus_read_byte() nor | 215 | * Neither i2c_smbus_read_byte() nor |
216 | * i2c_smbus_read_block_data() worked here, | 216 | * i2c_smbus_read_block_data() worked here, |
217 | * so use i2c_smbus_read_word_data() instead. | 217 | * so use i2c_smbus_read_word_swapped() instead. |
218 | * We could also try to use i2c_master_recv(), | 218 | * We could also try to use i2c_master_recv(), |
219 | * but that is not always supported. | 219 | * but that is not always supported. |
220 | */ | 220 | */ |
221 | rv = i2c_smbus_read_word_data(client, 0); | 221 | rv = i2c_smbus_read_word_swapped(client, 0); |
222 | if (rv < 0) { | 222 | if (rv < 0) { |
223 | dev_dbg(&client->dev, "Failed to read ADC value: error %d", rv); | 223 | dev_dbg(&client->dev, "Failed to read ADC value: error %d", rv); |
224 | return -1; | 224 | return -1; |
225 | } | 225 | } |
226 | /* | 226 | /* |
227 | * Validate/verify readback adc channel (in bit 11..14). | 227 | * Validate/verify readback adc channel (in bit 11..14). |
228 | * High byte is in lower 8 bit of rv, so only shift by 3. | ||
229 | */ | 228 | */ |
230 | radc = (rv >> 3) & 0x0f; | 229 | radc = (rv >> 11) & 0x0f; |
231 | if (radc != adc) { | 230 | if (radc != adc) { |
232 | dev_dbg(&client->dev, "Unexpected RADC: Expected %d got %d", | 231 | dev_dbg(&client->dev, "Unexpected RADC: Expected %d got %d", |
233 | adc, radc); | 232 | adc, radc); |
234 | return -EIO; | 233 | return -EIO; |
235 | } | 234 | } |
236 | /* | ||
237 | * Chip replies with H/L, while SMBus expects L/H. | ||
238 | * Thus, byte order is reversed, and we have to swap | ||
239 | * the result. | ||
240 | */ | ||
241 | rv = swab16(rv) & SMM665_ADC_MASK; | ||
242 | 235 | ||
243 | return rv; | 236 | return rv & SMM665_ADC_MASK; |
244 | } | 237 | } |
245 | 238 | ||
246 | static struct smm665_data *smm665_update_device(struct device *dev) | 239 | static struct smm665_data *smm665_update_device(struct device *dev) |
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 9fb7516e6f45..65c88ff5645a 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c | |||
@@ -113,7 +113,7 @@ struct smsc47b397_data { | |||
113 | u8 temp[4]; | 113 | u8 temp[4]; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | static int smsc47b397_read_value(struct smsc47b397_data* data, u8 reg) | 116 | static int smsc47b397_read_value(struct smsc47b397_data *data, u8 reg) |
117 | { | 117 | { |
118 | int res; | 118 | int res; |
119 | 119 | ||
@@ -265,7 +265,8 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) | |||
265 | return -EBUSY; | 265 | return -EBUSY; |
266 | } | 266 | } |
267 | 267 | ||
268 | if (!(data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) { | 268 | data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL); |
269 | if (!data) { | ||
269 | err = -ENOMEM; | 270 | err = -ENOMEM; |
270 | goto error_release; | 271 | goto error_release; |
271 | } | 272 | } |
@@ -276,7 +277,8 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) | |||
276 | mutex_init(&data->update_lock); | 277 | mutex_init(&data->update_lock); |
277 | platform_set_drvdata(pdev, data); | 278 | platform_set_drvdata(pdev, data); |
278 | 279 | ||
279 | if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group))) | 280 | err = sysfs_create_group(&dev->kobj, &smsc47b397_group); |
281 | if (err) | ||
280 | goto error_free; | 282 | goto error_free; |
281 | 283 | ||
282 | data->hwmon_dev = hwmon_device_register(dev); | 284 | data->hwmon_dev = hwmon_device_register(dev); |
@@ -345,7 +347,7 @@ static int __init smsc47b397_find(unsigned short *addr) | |||
345 | superio_enter(); | 347 | superio_enter(); |
346 | id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); | 348 | id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); |
347 | 349 | ||
348 | switch(id) { | 350 | switch (id) { |
349 | case 0x81: | 351 | case 0x81: |
350 | name = "SCH5307-NS"; | 352 | name = "SCH5307-NS"; |
351 | break; | 353 | break; |
@@ -379,7 +381,8 @@ static int __init smsc47b397_init(void) | |||
379 | unsigned short address; | 381 | unsigned short address; |
380 | int ret; | 382 | int ret; |
381 | 383 | ||
382 | if ((ret = smsc47b397_find(&address))) | 384 | ret = smsc47b397_find(&address); |
385 | if (ret) | ||
383 | return ret; | 386 | return ret; |
384 | 387 | ||
385 | ret = platform_driver_register(&smsc47b397_driver); | 388 | ret = platform_driver_register(&smsc47b397_driver); |
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 5bd194968801..643aa8c94535 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c | |||
@@ -55,19 +55,6 @@ struct tmp102 { | |||
55 | int temp[3]; | 55 | int temp[3]; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | /* SMBus specifies low byte first, but the TMP102 returns high byte first, | ||
59 | * so we have to swab16 the values */ | ||
60 | static inline int tmp102_read_reg(struct i2c_client *client, u8 reg) | ||
61 | { | ||
62 | int result = i2c_smbus_read_word_data(client, reg); | ||
63 | return result < 0 ? result : swab16(result); | ||
64 | } | ||
65 | |||
66 | static inline int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) | ||
67 | { | ||
68 | return i2c_smbus_write_word_data(client, reg, swab16(val)); | ||
69 | } | ||
70 | |||
71 | /* convert left adjusted 13-bit TMP102 register value to milliCelsius */ | 58 | /* convert left adjusted 13-bit TMP102 register value to milliCelsius */ |
72 | static inline int tmp102_reg_to_mC(s16 val) | 59 | static inline int tmp102_reg_to_mC(s16 val) |
73 | { | 60 | { |
@@ -94,7 +81,8 @@ static struct tmp102 *tmp102_update_device(struct i2c_client *client) | |||
94 | if (time_after(jiffies, tmp102->last_update + HZ / 3)) { | 81 | if (time_after(jiffies, tmp102->last_update + HZ / 3)) { |
95 | int i; | 82 | int i; |
96 | for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { | 83 | for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { |
97 | int status = tmp102_read_reg(client, tmp102_reg[i]); | 84 | int status = i2c_smbus_read_word_swapped(client, |
85 | tmp102_reg[i]); | ||
98 | if (status > -1) | 86 | if (status > -1) |
99 | tmp102->temp[i] = tmp102_reg_to_mC(status); | 87 | tmp102->temp[i] = tmp102_reg_to_mC(status); |
100 | } | 88 | } |
@@ -130,8 +118,8 @@ static ssize_t tmp102_set_temp(struct device *dev, | |||
130 | 118 | ||
131 | mutex_lock(&tmp102->lock); | 119 | mutex_lock(&tmp102->lock); |
132 | tmp102->temp[sda->index] = val; | 120 | tmp102->temp[sda->index] = val; |
133 | status = tmp102_write_reg(client, tmp102_reg[sda->index], | 121 | status = i2c_smbus_write_word_swapped(client, tmp102_reg[sda->index], |
134 | tmp102_mC_to_reg(val)); | 122 | tmp102_mC_to_reg(val)); |
135 | mutex_unlock(&tmp102->lock); | 123 | mutex_unlock(&tmp102->lock); |
136 | return status ? : count; | 124 | return status ? : count; |
137 | } | 125 | } |
@@ -178,18 +166,19 @@ static int __devinit tmp102_probe(struct i2c_client *client, | |||
178 | } | 166 | } |
179 | i2c_set_clientdata(client, tmp102); | 167 | i2c_set_clientdata(client, tmp102); |
180 | 168 | ||
181 | status = tmp102_read_reg(client, TMP102_CONF_REG); | 169 | status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); |
182 | if (status < 0) { | 170 | if (status < 0) { |
183 | dev_err(&client->dev, "error reading config register\n"); | 171 | dev_err(&client->dev, "error reading config register\n"); |
184 | goto fail_free; | 172 | goto fail_free; |
185 | } | 173 | } |
186 | tmp102->config_orig = status; | 174 | tmp102->config_orig = status; |
187 | status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); | 175 | status = i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, |
176 | TMP102_CONFIG); | ||
188 | if (status < 0) { | 177 | if (status < 0) { |
189 | dev_err(&client->dev, "error writing config register\n"); | 178 | dev_err(&client->dev, "error writing config register\n"); |
190 | goto fail_restore_config; | 179 | goto fail_restore_config; |
191 | } | 180 | } |
192 | status = tmp102_read_reg(client, TMP102_CONF_REG); | 181 | status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); |
193 | if (status < 0) { | 182 | if (status < 0) { |
194 | dev_err(&client->dev, "error reading config register\n"); | 183 | dev_err(&client->dev, "error reading config register\n"); |
195 | goto fail_restore_config; | 184 | goto fail_restore_config; |
@@ -222,7 +211,8 @@ static int __devinit tmp102_probe(struct i2c_client *client, | |||
222 | fail_remove_sysfs: | 211 | fail_remove_sysfs: |
223 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); | 212 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); |
224 | fail_restore_config: | 213 | fail_restore_config: |
225 | tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig); | 214 | i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, |
215 | tmp102->config_orig); | ||
226 | fail_free: | 216 | fail_free: |
227 | kfree(tmp102); | 217 | kfree(tmp102); |
228 | 218 | ||
@@ -240,10 +230,10 @@ static int __devexit tmp102_remove(struct i2c_client *client) | |||
240 | if (tmp102->config_orig & TMP102_CONF_SD) { | 230 | if (tmp102->config_orig & TMP102_CONF_SD) { |
241 | int config; | 231 | int config; |
242 | 232 | ||
243 | config = tmp102_read_reg(client, TMP102_CONF_REG); | 233 | config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); |
244 | if (config >= 0) | 234 | if (config >= 0) |
245 | tmp102_write_reg(client, TMP102_CONF_REG, | 235 | i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, |
246 | config | TMP102_CONF_SD); | 236 | config | TMP102_CONF_SD); |
247 | } | 237 | } |
248 | 238 | ||
249 | kfree(tmp102); | 239 | kfree(tmp102); |
@@ -257,12 +247,12 @@ static int tmp102_suspend(struct device *dev) | |||
257 | struct i2c_client *client = to_i2c_client(dev); | 247 | struct i2c_client *client = to_i2c_client(dev); |
258 | int config; | 248 | int config; |
259 | 249 | ||
260 | config = tmp102_read_reg(client, TMP102_CONF_REG); | 250 | config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); |
261 | if (config < 0) | 251 | if (config < 0) |
262 | return config; | 252 | return config; |
263 | 253 | ||
264 | config |= TMP102_CONF_SD; | 254 | config |= TMP102_CONF_SD; |
265 | return tmp102_write_reg(client, TMP102_CONF_REG, config); | 255 | return i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config); |
266 | } | 256 | } |
267 | 257 | ||
268 | static int tmp102_resume(struct device *dev) | 258 | static int tmp102_resume(struct device *dev) |
@@ -270,12 +260,12 @@ static int tmp102_resume(struct device *dev) | |||
270 | struct i2c_client *client = to_i2c_client(dev); | 260 | struct i2c_client *client = to_i2c_client(dev); |
271 | int config; | 261 | int config; |
272 | 262 | ||
273 | config = tmp102_read_reg(client, TMP102_CONF_REG); | 263 | config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); |
274 | if (config < 0) | 264 | if (config < 0) |
275 | return config; | 265 | return config; |
276 | 266 | ||
277 | config &= ~TMP102_CONF_SD; | 267 | config &= ~TMP102_CONF_SD; |
278 | return tmp102_write_reg(client, TMP102_CONF_REG, config); | 268 | return i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config); |
279 | } | 269 | } |
280 | 270 | ||
281 | static const struct dev_pm_ops tmp102_dev_pm_ops = { | 271 | static const struct dev_pm_ops tmp102_dev_pm_ops = { |
diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index 27a62711e0a6..3cd07bf42dca 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/module.h> | ||
9 | #include <linux/of_device.h> | 10 | #include <linux/of_device.h> |
10 | #include <linux/io.h> | 11 | #include <linux/io.h> |
11 | #include <linux/hwmon.h> | 12 | #include <linux/hwmon.h> |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 36d7f270b14d..93f5fc7d6059 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | w83627ehf - Driver for the hardware monitoring functionality of | 2 | w83627ehf - Driver for the hardware monitoring functionality of |
3 | the Winbond W83627EHF Super-I/O chip | 3 | the Winbond W83627EHF Super-I/O chip |
4 | Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | 4 | Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org> |
5 | Copyright (C) 2006 Yuan Mu (Winbond), | 5 | Copyright (C) 2006 Yuan Mu (Winbond), |
6 | Rudolf Marek <r.marek@assembler.cz> | 6 | Rudolf Marek <r.marek@assembler.cz> |
7 | David Hubbard <david.c.hubbard@gmail.com> | 7 | David Hubbard <david.c.hubbard@gmail.com> |
@@ -39,6 +39,7 @@ | |||
39 | 0x8860 0xa1 | 39 | 0x8860 0xa1 |
40 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 | 40 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 |
41 | w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 | 41 | w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 |
42 | w83627uhg 8 2 2 2 0xa230 0xc1 0x5ca3 | ||
42 | w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 | 43 | w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 |
43 | w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 | 44 | w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 |
44 | nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 | 45 | nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 |
@@ -61,14 +62,17 @@ | |||
61 | #include <linux/io.h> | 62 | #include <linux/io.h> |
62 | #include "lm75.h" | 63 | #include "lm75.h" |
63 | 64 | ||
64 | enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg, w83667hg_b, nct6775, | 65 | enum kinds { |
65 | nct6776 }; | 66 | w83627ehf, w83627dhg, w83627dhg_p, w83627uhg, |
67 | w83667hg, w83667hg_b, nct6775, nct6776, | ||
68 | }; | ||
66 | 69 | ||
67 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ | 70 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ |
68 | static const char * const w83627ehf_device_names[] = { | 71 | static const char * const w83627ehf_device_names[] = { |
69 | "w83627ehf", | 72 | "w83627ehf", |
70 | "w83627dhg", | 73 | "w83627dhg", |
71 | "w83627dhg", | 74 | "w83627dhg", |
75 | "w83627uhg", | ||
72 | "w83667hg", | 76 | "w83667hg", |
73 | "w83667hg", | 77 | "w83667hg", |
74 | "nct6775", | 78 | "nct6775", |
@@ -104,6 +108,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal"); | |||
104 | #define SIO_W83627EHG_ID 0x8860 | 108 | #define SIO_W83627EHG_ID 0x8860 |
105 | #define SIO_W83627DHG_ID 0xa020 | 109 | #define SIO_W83627DHG_ID 0xa020 |
106 | #define SIO_W83627DHG_P_ID 0xb070 | 110 | #define SIO_W83627DHG_P_ID 0xb070 |
111 | #define SIO_W83627UHG_ID 0xa230 | ||
107 | #define SIO_W83667HG_ID 0xa510 | 112 | #define SIO_W83667HG_ID 0xa510 |
108 | #define SIO_W83667HG_B_ID 0xb350 | 113 | #define SIO_W83667HG_B_ID 0xb350 |
109 | #define SIO_NCT6775_ID 0xb470 | 114 | #define SIO_NCT6775_ID 0xb470 |
@@ -197,6 +202,9 @@ static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0, 0x152, 0x252, 0 }; | |||
197 | #define W83627EHF_REG_ALARM2 0x45A | 202 | #define W83627EHF_REG_ALARM2 0x45A |
198 | #define W83627EHF_REG_ALARM3 0x45B | 203 | #define W83627EHF_REG_ALARM3 0x45B |
199 | 204 | ||
205 | #define W83627EHF_REG_CASEOPEN_DET 0x42 /* SMI STATUS #2 */ | ||
206 | #define W83627EHF_REG_CASEOPEN_CLR 0x46 /* SMI MASK #3 */ | ||
207 | |||
200 | /* SmartFan registers */ | 208 | /* SmartFan registers */ |
201 | #define W83627EHF_REG_FAN_STEPUP_TIME 0x0f | 209 | #define W83627EHF_REG_FAN_STEPUP_TIME 0x0f |
202 | #define W83627EHF_REG_FAN_STEPDOWN_TIME 0x0e | 210 | #define W83627EHF_REG_FAN_STEPDOWN_TIME 0x0e |
@@ -316,7 +324,7 @@ static const char *const nct6776_temp_label[] = { | |||
316 | 324 | ||
317 | #define NUM_REG_TEMP ARRAY_SIZE(NCT6775_REG_TEMP) | 325 | #define NUM_REG_TEMP ARRAY_SIZE(NCT6775_REG_TEMP) |
318 | 326 | ||
319 | static inline int is_word_sized(u16 reg) | 327 | static int is_word_sized(u16 reg) |
320 | { | 328 | { |
321 | return ((((reg & 0xff00) == 0x100 | 329 | return ((((reg & 0xff00) == 0x100 |
322 | || (reg & 0xff00) == 0x200) | 330 | || (reg & 0xff00) == 0x200) |
@@ -385,35 +393,23 @@ div_from_reg(u8 reg) | |||
385 | return 1 << reg; | 393 | return 1 << reg; |
386 | } | 394 | } |
387 | 395 | ||
388 | static inline int | 396 | /* Some of the voltage inputs have internal scaling, the tables below |
389 | temp_from_reg(u16 reg, s16 regval) | 397 | * contain 8 (the ADC LSB in mV) * scaling factor * 100 */ |
390 | { | 398 | static const u16 scale_in_common[10] = { |
391 | if (is_word_sized(reg)) | 399 | 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800 |
392 | return LM75_TEMP_FROM_REG(regval); | 400 | }; |
393 | return ((s8)regval) * 1000; | 401 | static const u16 scale_in_w83627uhg[9] = { |
394 | } | 402 | 800, 800, 3328, 3424, 800, 800, 0, 3328, 3400 |
395 | 403 | }; | |
396 | static inline u16 | ||
397 | temp_to_reg(u16 reg, long temp) | ||
398 | { | ||
399 | if (is_word_sized(reg)) | ||
400 | return LM75_TEMP_TO_REG(temp); | ||
401 | return (s8)DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, -127000, 128000), | ||
402 | 1000); | ||
403 | } | ||
404 | |||
405 | /* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */ | ||
406 | |||
407 | static u8 scale_in[10] = { 8, 8, 16, 16, 8, 8, 8, 16, 16, 8 }; | ||
408 | 404 | ||
409 | static inline long in_from_reg(u8 reg, u8 nr) | 405 | static inline long in_from_reg(u8 reg, u8 nr, const u16 *scale_in) |
410 | { | 406 | { |
411 | return reg * scale_in[nr]; | 407 | return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100); |
412 | } | 408 | } |
413 | 409 | ||
414 | static inline u8 in_to_reg(u32 val, u8 nr) | 410 | static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scale_in) |
415 | { | 411 | { |
416 | return SENSORS_LIMIT(((val + (scale_in[nr] / 2)) / scale_in[nr]), 0, | 412 | return SENSORS_LIMIT(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, |
417 | 255); | 413 | 255); |
418 | } | 414 | } |
419 | 415 | ||
@@ -444,6 +440,7 @@ struct w83627ehf_data { | |||
444 | const u16 *REG_FAN_STOP_TIME; | 440 | const u16 *REG_FAN_STOP_TIME; |
445 | const u16 *REG_FAN_MAX_OUTPUT; | 441 | const u16 *REG_FAN_MAX_OUTPUT; |
446 | const u16 *REG_FAN_STEP_OUTPUT; | 442 | const u16 *REG_FAN_STEP_OUTPUT; |
443 | const u16 *scale_in; | ||
447 | 444 | ||
448 | unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); | 445 | unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); |
449 | unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); | 446 | unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); |
@@ -469,6 +466,7 @@ struct w83627ehf_data { | |||
469 | s16 temp_max[9]; | 466 | s16 temp_max[9]; |
470 | s16 temp_max_hyst[9]; | 467 | s16 temp_max_hyst[9]; |
471 | u32 alarms; | 468 | u32 alarms; |
469 | u8 caseopen; | ||
472 | 470 | ||
473 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ | 471 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ |
474 | u8 pwm_enable[4]; /* 1->manual | 472 | u8 pwm_enable[4]; /* 1->manual |
@@ -494,7 +492,8 @@ struct w83627ehf_data { | |||
494 | u8 vrm; | 492 | u8 vrm; |
495 | 493 | ||
496 | u16 have_temp; | 494 | u16 have_temp; |
497 | u8 in6_skip; | 495 | u8 in6_skip:1; |
496 | u8 temp3_val_only:1; | ||
498 | }; | 497 | }; |
499 | 498 | ||
500 | struct w83627ehf_sio_data { | 499 | struct w83627ehf_sio_data { |
@@ -557,6 +556,26 @@ static int w83627ehf_write_value(struct w83627ehf_data *data, u16 reg, | |||
557 | return 0; | 556 | return 0; |
558 | } | 557 | } |
559 | 558 | ||
559 | /* We left-align 8-bit temperature values to make the code simpler */ | ||
560 | static u16 w83627ehf_read_temp(struct w83627ehf_data *data, u16 reg) | ||
561 | { | ||
562 | u16 res; | ||
563 | |||
564 | res = w83627ehf_read_value(data, reg); | ||
565 | if (!is_word_sized(reg)) | ||
566 | res <<= 8; | ||
567 | |||
568 | return res; | ||
569 | } | ||
570 | |||
571 | static int w83627ehf_write_temp(struct w83627ehf_data *data, u16 reg, | ||
572 | u16 value) | ||
573 | { | ||
574 | if (!is_word_sized(reg)) | ||
575 | value >>= 8; | ||
576 | return w83627ehf_write_value(data, reg, value); | ||
577 | } | ||
578 | |||
560 | /* This function assumes that the caller holds data->update_lock */ | 579 | /* This function assumes that the caller holds data->update_lock */ |
561 | static void nct6775_write_fan_div(struct w83627ehf_data *data, int nr) | 580 | static void nct6775_write_fan_div(struct w83627ehf_data *data, int nr) |
562 | { | 581 | { |
@@ -771,6 +790,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
771 | 790 | ||
772 | /* Measured voltages and limits */ | 791 | /* Measured voltages and limits */ |
773 | for (i = 0; i < data->in_num; i++) { | 792 | for (i = 0; i < data->in_num; i++) { |
793 | if ((i == 6) && data->in6_skip) | ||
794 | continue; | ||
795 | |||
774 | data->in[i] = w83627ehf_read_value(data, | 796 | data->in[i] = w83627ehf_read_value(data, |
775 | W83627EHF_REG_IN(i)); | 797 | W83627EHF_REG_IN(i)); |
776 | data->in_min[i] = w83627ehf_read_value(data, | 798 | data->in_min[i] = w83627ehf_read_value(data, |
@@ -855,15 +877,15 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
855 | for (i = 0; i < NUM_REG_TEMP; i++) { | 877 | for (i = 0; i < NUM_REG_TEMP; i++) { |
856 | if (!(data->have_temp & (1 << i))) | 878 | if (!(data->have_temp & (1 << i))) |
857 | continue; | 879 | continue; |
858 | data->temp[i] = w83627ehf_read_value(data, | 880 | data->temp[i] = w83627ehf_read_temp(data, |
859 | data->reg_temp[i]); | 881 | data->reg_temp[i]); |
860 | if (data->reg_temp_over[i]) | 882 | if (data->reg_temp_over[i]) |
861 | data->temp_max[i] | 883 | data->temp_max[i] |
862 | = w83627ehf_read_value(data, | 884 | = w83627ehf_read_temp(data, |
863 | data->reg_temp_over[i]); | 885 | data->reg_temp_over[i]); |
864 | if (data->reg_temp_hyst[i]) | 886 | if (data->reg_temp_hyst[i]) |
865 | data->temp_max_hyst[i] | 887 | data->temp_max_hyst[i] |
866 | = w83627ehf_read_value(data, | 888 | = w83627ehf_read_temp(data, |
867 | data->reg_temp_hyst[i]); | 889 | data->reg_temp_hyst[i]); |
868 | } | 890 | } |
869 | 891 | ||
@@ -874,6 +896,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
874 | (w83627ehf_read_value(data, | 896 | (w83627ehf_read_value(data, |
875 | W83627EHF_REG_ALARM3) << 16); | 897 | W83627EHF_REG_ALARM3) << 16); |
876 | 898 | ||
899 | data->caseopen = w83627ehf_read_value(data, | ||
900 | W83627EHF_REG_CASEOPEN_DET); | ||
901 | |||
877 | data->last_updated = jiffies; | 902 | data->last_updated = jiffies; |
878 | data->valid = 1; | 903 | data->valid = 1; |
879 | } | 904 | } |
@@ -894,7 +919,8 @@ show_##reg(struct device *dev, struct device_attribute *attr, \ | |||
894 | struct sensor_device_attribute *sensor_attr = \ | 919 | struct sensor_device_attribute *sensor_attr = \ |
895 | to_sensor_dev_attr(attr); \ | 920 | to_sensor_dev_attr(attr); \ |
896 | int nr = sensor_attr->index; \ | 921 | int nr = sensor_attr->index; \ |
897 | return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr)); \ | 922 | return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr, \ |
923 | data->scale_in)); \ | ||
898 | } | 924 | } |
899 | show_in_reg(in) | 925 | show_in_reg(in) |
900 | show_in_reg(in_min) | 926 | show_in_reg(in_min) |
@@ -915,7 +941,7 @@ store_in_##reg(struct device *dev, struct device_attribute *attr, \ | |||
915 | if (err < 0) \ | 941 | if (err < 0) \ |
916 | return err; \ | 942 | return err; \ |
917 | mutex_lock(&data->update_lock); \ | 943 | mutex_lock(&data->update_lock); \ |
918 | data->in_##reg[nr] = in_to_reg(val, nr); \ | 944 | data->in_##reg[nr] = in_to_reg(val, nr, data->scale_in); \ |
919 | w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \ | 945 | w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \ |
920 | data->in_##reg[nr]); \ | 946 | data->in_##reg[nr]); \ |
921 | mutex_unlock(&data->update_lock); \ | 947 | mutex_unlock(&data->update_lock); \ |
@@ -1156,8 +1182,7 @@ show_##reg(struct device *dev, struct device_attribute *attr, \ | |||
1156 | struct sensor_device_attribute *sensor_attr = \ | 1182 | struct sensor_device_attribute *sensor_attr = \ |
1157 | to_sensor_dev_attr(attr); \ | 1183 | to_sensor_dev_attr(attr); \ |
1158 | int nr = sensor_attr->index; \ | 1184 | int nr = sensor_attr->index; \ |
1159 | return sprintf(buf, "%d\n", \ | 1185 | return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->reg[nr])); \ |
1160 | temp_from_reg(data->addr[nr], data->reg[nr])); \ | ||
1161 | } | 1186 | } |
1162 | show_temp_reg(reg_temp, temp); | 1187 | show_temp_reg(reg_temp, temp); |
1163 | show_temp_reg(reg_temp_over, temp_max); | 1188 | show_temp_reg(reg_temp_over, temp_max); |
@@ -1178,9 +1203,8 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ | |||
1178 | if (err < 0) \ | 1203 | if (err < 0) \ |
1179 | return err; \ | 1204 | return err; \ |
1180 | mutex_lock(&data->update_lock); \ | 1205 | mutex_lock(&data->update_lock); \ |
1181 | data->reg[nr] = temp_to_reg(data->addr[nr], val); \ | 1206 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ |
1182 | w83627ehf_write_value(data, data->addr[nr], \ | 1207 | w83627ehf_write_temp(data, data->addr[nr], data->reg[nr]); \ |
1183 | data->reg[nr]); \ | ||
1184 | mutex_unlock(&data->update_lock); \ | 1208 | mutex_unlock(&data->update_lock); \ |
1185 | return count; \ | 1209 | return count; \ |
1186 | } | 1210 | } |
@@ -1606,25 +1630,28 @@ static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { | |||
1606 | store_fan_step_output, 3), | 1630 | store_fan_step_output, 3), |
1607 | }; | 1631 | }; |
1608 | 1632 | ||
1633 | static struct sensor_device_attribute sda_sf3_arrays_fan3[] = { | ||
1634 | SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | ||
1635 | store_fan_stop_time, 2), | ||
1636 | SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, | ||
1637 | store_fan_start_output, 2), | ||
1638 | SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, | ||
1639 | store_fan_stop_output, 2), | ||
1640 | }; | ||
1641 | |||
1609 | static struct sensor_device_attribute sda_sf3_arrays[] = { | 1642 | static struct sensor_device_attribute sda_sf3_arrays[] = { |
1610 | SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | 1643 | SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
1611 | store_fan_stop_time, 0), | 1644 | store_fan_stop_time, 0), |
1612 | SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | 1645 | SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
1613 | store_fan_stop_time, 1), | 1646 | store_fan_stop_time, 1), |
1614 | SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | ||
1615 | store_fan_stop_time, 2), | ||
1616 | SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, | 1647 | SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, |
1617 | store_fan_start_output, 0), | 1648 | store_fan_start_output, 0), |
1618 | SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, | 1649 | SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, |
1619 | store_fan_start_output, 1), | 1650 | store_fan_start_output, 1), |
1620 | SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output, | ||
1621 | store_fan_start_output, 2), | ||
1622 | SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, | 1651 | SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, |
1623 | store_fan_stop_output, 0), | 1652 | store_fan_stop_output, 0), |
1624 | SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, | 1653 | SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, |
1625 | store_fan_stop_output, 1), | 1654 | store_fan_stop_output, 1), |
1626 | SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, | ||
1627 | store_fan_stop_output, 2), | ||
1628 | }; | 1655 | }; |
1629 | 1656 | ||
1630 | 1657 | ||
@@ -1655,6 +1682,48 @@ show_vid(struct device *dev, struct device_attribute *attr, char *buf) | |||
1655 | } | 1682 | } |
1656 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | 1683 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); |
1657 | 1684 | ||
1685 | |||
1686 | /* Case open detection */ | ||
1687 | |||
1688 | static ssize_t | ||
1689 | show_caseopen(struct device *dev, struct device_attribute *attr, char *buf) | ||
1690 | { | ||
1691 | struct w83627ehf_data *data = w83627ehf_update_device(dev); | ||
1692 | |||
1693 | return sprintf(buf, "%d\n", | ||
1694 | !!(data->caseopen & to_sensor_dev_attr_2(attr)->index)); | ||
1695 | } | ||
1696 | |||
1697 | static ssize_t | ||
1698 | clear_caseopen(struct device *dev, struct device_attribute *attr, | ||
1699 | const char *buf, size_t count) | ||
1700 | { | ||
1701 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
1702 | unsigned long val; | ||
1703 | u16 reg, mask; | ||
1704 | |||
1705 | if (strict_strtoul(buf, 10, &val) || val != 0) | ||
1706 | return -EINVAL; | ||
1707 | |||
1708 | mask = to_sensor_dev_attr_2(attr)->nr; | ||
1709 | |||
1710 | mutex_lock(&data->update_lock); | ||
1711 | reg = w83627ehf_read_value(data, W83627EHF_REG_CASEOPEN_CLR); | ||
1712 | w83627ehf_write_value(data, W83627EHF_REG_CASEOPEN_CLR, reg | mask); | ||
1713 | w83627ehf_write_value(data, W83627EHF_REG_CASEOPEN_CLR, reg & ~mask); | ||
1714 | data->valid = 0; /* Force cache refresh */ | ||
1715 | mutex_unlock(&data->update_lock); | ||
1716 | |||
1717 | return count; | ||
1718 | } | ||
1719 | |||
1720 | static struct sensor_device_attribute_2 sda_caseopen[] = { | ||
1721 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_caseopen, | ||
1722 | clear_caseopen, 0x80, 0x10), | ||
1723 | SENSOR_ATTR_2(intrusion1_alarm, S_IWUSR | S_IRUGO, show_caseopen, | ||
1724 | clear_caseopen, 0x40, 0x40), | ||
1725 | }; | ||
1726 | |||
1658 | /* | 1727 | /* |
1659 | * Driver and device management | 1728 | * Driver and device management |
1660 | */ | 1729 | */ |
@@ -1675,6 +1744,8 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1675 | data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff) | 1744 | data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff) |
1676 | device_remove_file(dev, &attr->dev_attr); | 1745 | device_remove_file(dev, &attr->dev_attr); |
1677 | } | 1746 | } |
1747 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++) | ||
1748 | device_remove_file(dev, &sda_sf3_arrays_fan3[i].dev_attr); | ||
1678 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | 1749 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) |
1679 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | 1750 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); |
1680 | for (i = 0; i < data->in_num; i++) { | 1751 | for (i = 0; i < data->in_num; i++) { |
@@ -1703,6 +1774,8 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1703 | continue; | 1774 | continue; |
1704 | device_remove_file(dev, &sda_temp_input[i].dev_attr); | 1775 | device_remove_file(dev, &sda_temp_input[i].dev_attr); |
1705 | device_remove_file(dev, &sda_temp_label[i].dev_attr); | 1776 | device_remove_file(dev, &sda_temp_label[i].dev_attr); |
1777 | if (i == 2 && data->temp3_val_only) | ||
1778 | continue; | ||
1706 | device_remove_file(dev, &sda_temp_max[i].dev_attr); | 1779 | device_remove_file(dev, &sda_temp_max[i].dev_attr); |
1707 | device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr); | 1780 | device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr); |
1708 | if (i > 2) | 1781 | if (i > 2) |
@@ -1711,6 +1784,9 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1711 | device_remove_file(dev, &sda_temp_type[i].dev_attr); | 1784 | device_remove_file(dev, &sda_temp_type[i].dev_attr); |
1712 | } | 1785 | } |
1713 | 1786 | ||
1787 | device_remove_file(dev, &sda_caseopen[0].dev_attr); | ||
1788 | device_remove_file(dev, &sda_caseopen[1].dev_attr); | ||
1789 | |||
1714 | device_remove_file(dev, &dev_attr_name); | 1790 | device_remove_file(dev, &dev_attr_name); |
1715 | device_remove_file(dev, &dev_attr_cpu0_vid); | 1791 | device_remove_file(dev, &dev_attr_cpu0_vid); |
1716 | } | 1792 | } |
@@ -1752,11 +1828,24 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data, | |||
1752 | case w83627ehf: | 1828 | case w83627ehf: |
1753 | diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); | 1829 | diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); |
1754 | break; | 1830 | break; |
1831 | case w83627uhg: | ||
1832 | diode = 0x00; | ||
1833 | break; | ||
1755 | default: | 1834 | default: |
1756 | diode = 0x70; | 1835 | diode = 0x70; |
1757 | } | 1836 | } |
1758 | for (i = 0; i < 3; i++) { | 1837 | for (i = 0; i < 3; i++) { |
1759 | if ((tmp & (0x02 << i))) | 1838 | const char *label = NULL; |
1839 | |||
1840 | if (data->temp_label) | ||
1841 | label = data->temp_label[data->temp_src[i]]; | ||
1842 | |||
1843 | /* Digital source overrides analog type */ | ||
1844 | if (label && strncmp(label, "PECI", 4) == 0) | ||
1845 | data->temp_type[i] = 6; | ||
1846 | else if (label && strncmp(label, "AMD", 3) == 0) | ||
1847 | data->temp_type[i] = 5; | ||
1848 | else if ((tmp & (0x02 << i))) | ||
1760 | data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3; | 1849 | data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3; |
1761 | else | 1850 | else |
1762 | data->temp_type[i] = 4; /* thermistor */ | 1851 | data->temp_type[i] = 4; /* thermistor */ |
@@ -1789,13 +1878,98 @@ static void w82627ehf_swap_tempreg(struct w83627ehf_data *data, | |||
1789 | data->reg_temp_config[r2] = tmp; | 1878 | data->reg_temp_config[r2] = tmp; |
1790 | } | 1879 | } |
1791 | 1880 | ||
1881 | static void __devinit | ||
1882 | w83627ehf_set_temp_reg_ehf(struct w83627ehf_data *data, int n_temp) | ||
1883 | { | ||
1884 | int i; | ||
1885 | |||
1886 | for (i = 0; i < n_temp; i++) { | ||
1887 | data->reg_temp[i] = W83627EHF_REG_TEMP[i]; | ||
1888 | data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i]; | ||
1889 | data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i]; | ||
1890 | data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i]; | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | static void __devinit | ||
1895 | w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data, | ||
1896 | struct w83627ehf_data *data) | ||
1897 | { | ||
1898 | int fan3pin, fan4pin, fan4min, fan5pin, regval; | ||
1899 | |||
1900 | /* The W83627UHG is simple, only two fan inputs, no config */ | ||
1901 | if (sio_data->kind == w83627uhg) { | ||
1902 | data->has_fan = 0x03; /* fan1 and fan2 */ | ||
1903 | data->has_fan_min = 0x03; | ||
1904 | return; | ||
1905 | } | ||
1906 | |||
1907 | superio_enter(sio_data->sioreg); | ||
1908 | |||
1909 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ | ||
1910 | if (sio_data->kind == nct6775) { | ||
1911 | /* On NCT6775, fan4 shares pins with the fdc interface */ | ||
1912 | fan3pin = 1; | ||
1913 | fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80); | ||
1914 | fan4min = 0; | ||
1915 | fan5pin = 0; | ||
1916 | } else if (sio_data->kind == nct6776) { | ||
1917 | fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); | ||
1918 | fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01); | ||
1919 | fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02); | ||
1920 | fan4min = fan4pin; | ||
1921 | } else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) { | ||
1922 | fan3pin = 1; | ||
1923 | fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40; | ||
1924 | fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20; | ||
1925 | fan4min = fan4pin; | ||
1926 | } else { | ||
1927 | fan3pin = 1; | ||
1928 | fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06); | ||
1929 | fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02); | ||
1930 | fan4min = fan4pin; | ||
1931 | } | ||
1932 | |||
1933 | superio_exit(sio_data->sioreg); | ||
1934 | |||
1935 | data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */ | ||
1936 | data->has_fan |= (fan3pin << 2); | ||
1937 | data->has_fan_min |= (fan3pin << 2); | ||
1938 | |||
1939 | if (sio_data->kind == nct6775 || sio_data->kind == nct6776) { | ||
1940 | /* | ||
1941 | * NCT6775F and NCT6776F don't have the W83627EHF_REG_FANDIV1 | ||
1942 | * register | ||
1943 | */ | ||
1944 | data->has_fan |= (fan4pin << 3) | (fan5pin << 4); | ||
1945 | data->has_fan_min |= (fan4min << 3) | (fan5pin << 4); | ||
1946 | } else { | ||
1947 | /* | ||
1948 | * It looks like fan4 and fan5 pins can be alternatively used | ||
1949 | * as fan on/off switches, but fan5 control is write only :/ | ||
1950 | * We assume that if the serial interface is disabled, designers | ||
1951 | * connected fan5 as input unless they are emitting log 1, which | ||
1952 | * is not the default. | ||
1953 | */ | ||
1954 | regval = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); | ||
1955 | if ((regval & (1 << 2)) && fan4pin) { | ||
1956 | data->has_fan |= (1 << 3); | ||
1957 | data->has_fan_min |= (1 << 3); | ||
1958 | } | ||
1959 | if (!(regval & (1 << 1)) && fan5pin) { | ||
1960 | data->has_fan |= (1 << 4); | ||
1961 | data->has_fan_min |= (1 << 4); | ||
1962 | } | ||
1963 | } | ||
1964 | } | ||
1965 | |||
1792 | static int __devinit w83627ehf_probe(struct platform_device *pdev) | 1966 | static int __devinit w83627ehf_probe(struct platform_device *pdev) |
1793 | { | 1967 | { |
1794 | struct device *dev = &pdev->dev; | 1968 | struct device *dev = &pdev->dev; |
1795 | struct w83627ehf_sio_data *sio_data = dev->platform_data; | 1969 | struct w83627ehf_sio_data *sio_data = dev->platform_data; |
1796 | struct w83627ehf_data *data; | 1970 | struct w83627ehf_data *data; |
1797 | struct resource *res; | 1971 | struct resource *res; |
1798 | u8 fan3pin, fan4pin, fan4min, fan5pin, en_vrm10; | 1972 | u8 en_vrm10; |
1799 | int i, err = 0; | 1973 | int i, err = 0; |
1800 | 1974 | ||
1801 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1975 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
@@ -1821,23 +1995,24 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1821 | 1995 | ||
1822 | /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ | 1996 | /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ |
1823 | data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9; | 1997 | data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9; |
1824 | /* 667HG, NCT6775F, and NCT6776F have 3 pwms */ | 1998 | /* 667HG, NCT6775F, and NCT6776F have 3 pwms, and 627UHG has only 2 */ |
1825 | data->pwm_num = (sio_data->kind == w83667hg | 1999 | switch (sio_data->kind) { |
1826 | || sio_data->kind == w83667hg_b | 2000 | default: |
1827 | || sio_data->kind == nct6775 | 2001 | data->pwm_num = 4; |
1828 | || sio_data->kind == nct6776) ? 3 : 4; | 2002 | break; |
2003 | case w83667hg: | ||
2004 | case w83667hg_b: | ||
2005 | case nct6775: | ||
2006 | case nct6776: | ||
2007 | data->pwm_num = 3; | ||
2008 | break; | ||
2009 | case w83627uhg: | ||
2010 | data->pwm_num = 2; | ||
2011 | break; | ||
2012 | } | ||
1829 | 2013 | ||
2014 | /* Default to 3 temperature inputs, code below will adjust as needed */ | ||
1830 | data->have_temp = 0x07; | 2015 | data->have_temp = 0x07; |
1831 | /* Check temp3 configuration bit for 667HG */ | ||
1832 | if (sio_data->kind == w83667hg) { | ||
1833 | u8 reg; | ||
1834 | |||
1835 | reg = w83627ehf_read_value(data, W83627EHF_REG_TEMP_CONFIG[2]); | ||
1836 | if (reg & 0x01) | ||
1837 | data->have_temp &= ~(1 << 2); | ||
1838 | else | ||
1839 | data->in6_skip = 1; /* either temp3 or in6 */ | ||
1840 | } | ||
1841 | 2016 | ||
1842 | /* Deal with temperature register setup first. */ | 2017 | /* Deal with temperature register setup first. */ |
1843 | if (sio_data->kind == nct6775 || sio_data->kind == nct6776) { | 2018 | if (sio_data->kind == nct6775 || sio_data->kind == nct6776) { |
@@ -1914,16 +2089,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1914 | } else if (sio_data->kind == w83667hg_b) { | 2089 | } else if (sio_data->kind == w83667hg_b) { |
1915 | u8 reg; | 2090 | u8 reg; |
1916 | 2091 | ||
2092 | w83627ehf_set_temp_reg_ehf(data, 4); | ||
2093 | |||
1917 | /* | 2094 | /* |
1918 | * Temperature sources are selected with bank 0, registers 0x49 | 2095 | * Temperature sources are selected with bank 0, registers 0x49 |
1919 | * and 0x4a. | 2096 | * and 0x4a. |
1920 | */ | 2097 | */ |
1921 | for (i = 0; i < ARRAY_SIZE(W83627EHF_REG_TEMP); i++) { | ||
1922 | data->reg_temp[i] = W83627EHF_REG_TEMP[i]; | ||
1923 | data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i]; | ||
1924 | data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i]; | ||
1925 | data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i]; | ||
1926 | } | ||
1927 | reg = w83627ehf_read_value(data, 0x4a); | 2098 | reg = w83627ehf_read_value(data, 0x4a); |
1928 | data->temp_src[0] = reg >> 5; | 2099 | data->temp_src[0] = reg >> 5; |
1929 | reg = w83627ehf_read_value(data, 0x49); | 2100 | reg = w83627ehf_read_value(data, 0x49); |
@@ -1957,13 +2128,60 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1957 | data->in6_skip = 1; | 2128 | data->in6_skip = 1; |
1958 | 2129 | ||
1959 | data->temp_label = w83667hg_b_temp_label; | 2130 | data->temp_label = w83667hg_b_temp_label; |
2131 | } else if (sio_data->kind == w83627uhg) { | ||
2132 | u8 reg; | ||
2133 | |||
2134 | w83627ehf_set_temp_reg_ehf(data, 3); | ||
2135 | |||
2136 | /* | ||
2137 | * Temperature sources for temp1 and temp2 are selected with | ||
2138 | * bank 0, registers 0x49 and 0x4a. | ||
2139 | */ | ||
2140 | data->temp_src[0] = 0; /* SYSTIN */ | ||
2141 | reg = w83627ehf_read_value(data, 0x49) & 0x07; | ||
2142 | /* Adjust to have the same mapping as other source registers */ | ||
2143 | if (reg == 0) | ||
2144 | data->temp_src[1]++; | ||
2145 | else if (reg >= 2 && reg <= 5) | ||
2146 | data->temp_src[1] += 2; | ||
2147 | else /* should never happen */ | ||
2148 | data->have_temp &= ~(1 << 1); | ||
2149 | reg = w83627ehf_read_value(data, 0x4a); | ||
2150 | data->temp_src[2] = reg >> 5; | ||
2151 | |||
2152 | /* | ||
2153 | * Skip temp3 if source is invalid or the same as temp1 | ||
2154 | * or temp2. | ||
2155 | */ | ||
2156 | if (data->temp_src[2] == 2 || data->temp_src[2] == 3 || | ||
2157 | data->temp_src[2] == data->temp_src[0] || | ||
2158 | ((data->have_temp & (1 << 1)) && | ||
2159 | data->temp_src[2] == data->temp_src[1])) | ||
2160 | data->have_temp &= ~(1 << 2); | ||
2161 | else | ||
2162 | data->temp3_val_only = 1; /* No limit regs */ | ||
2163 | |||
2164 | data->in6_skip = 1; /* No VIN3 */ | ||
2165 | |||
2166 | data->temp_label = w83667hg_b_temp_label; | ||
1960 | } else { | 2167 | } else { |
2168 | w83627ehf_set_temp_reg_ehf(data, 3); | ||
2169 | |||
1961 | /* Temperature sources are fixed */ | 2170 | /* Temperature sources are fixed */ |
1962 | for (i = 0; i < 3; i++) { | 2171 | |
1963 | data->reg_temp[i] = W83627EHF_REG_TEMP[i]; | 2172 | if (sio_data->kind == w83667hg) { |
1964 | data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i]; | 2173 | u8 reg; |
1965 | data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i]; | 2174 | |
1966 | data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i]; | 2175 | /* |
2176 | * Chip supports either AUXTIN or VIN3. Try to find | ||
2177 | * out which one. | ||
2178 | */ | ||
2179 | reg = w83627ehf_read_value(data, | ||
2180 | W83627EHF_REG_TEMP_CONFIG[2]); | ||
2181 | if (reg & 0x01) | ||
2182 | data->have_temp &= ~(1 << 2); | ||
2183 | else | ||
2184 | data->in6_skip = 1; | ||
1967 | } | 2185 | } |
1968 | } | 2186 | } |
1969 | 2187 | ||
@@ -2023,6 +2241,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2023 | W83627EHF_REG_FAN_STEP_OUTPUT_COMMON; | 2241 | W83627EHF_REG_FAN_STEP_OUTPUT_COMMON; |
2024 | } | 2242 | } |
2025 | 2243 | ||
2244 | /* Setup input voltage scaling factors */ | ||
2245 | if (sio_data->kind == w83627uhg) | ||
2246 | data->scale_in = scale_in_w83627uhg; | ||
2247 | else | ||
2248 | data->scale_in = scale_in_common; | ||
2249 | |||
2026 | /* Initialize the chip */ | 2250 | /* Initialize the chip */ |
2027 | w83627ehf_init_device(data, sio_data->kind); | 2251 | w83627ehf_init_device(data, sio_data->kind); |
2028 | 2252 | ||
@@ -2039,7 +2263,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2039 | err = device_create_file(dev, &dev_attr_cpu0_vid); | 2263 | err = device_create_file(dev, &dev_attr_cpu0_vid); |
2040 | if (err) | 2264 | if (err) |
2041 | goto exit_release; | 2265 | goto exit_release; |
2042 | } else { | 2266 | } else if (sio_data->kind != w83627uhg) { |
2043 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); | 2267 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); |
2044 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { | 2268 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { |
2045 | /* Set VID input sensibility if needed. In theory the | 2269 | /* Set VID input sensibility if needed. In theory the |
@@ -2080,30 +2304,6 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2080 | } | 2304 | } |
2081 | } | 2305 | } |
2082 | 2306 | ||
2083 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ | ||
2084 | if (sio_data->kind == nct6775) { | ||
2085 | /* On NCT6775, fan4 shares pins with the fdc interface */ | ||
2086 | fan3pin = 1; | ||
2087 | fan4pin = !(superio_inb(sio_data->sioreg, 0x2A) & 0x80); | ||
2088 | fan4min = 0; | ||
2089 | fan5pin = 0; | ||
2090 | } else if (sio_data->kind == nct6776) { | ||
2091 | fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40); | ||
2092 | fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01); | ||
2093 | fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02); | ||
2094 | fan4min = fan4pin; | ||
2095 | } else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) { | ||
2096 | fan3pin = 1; | ||
2097 | fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40; | ||
2098 | fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20; | ||
2099 | fan4min = fan4pin; | ||
2100 | } else { | ||
2101 | fan3pin = 1; | ||
2102 | fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06); | ||
2103 | fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02); | ||
2104 | fan4min = fan4pin; | ||
2105 | } | ||
2106 | |||
2107 | if (fan_debounce && | 2307 | if (fan_debounce && |
2108 | (sio_data->kind == nct6775 || sio_data->kind == nct6776)) { | 2308 | (sio_data->kind == nct6775 || sio_data->kind == nct6776)) { |
2109 | u8 tmp; | 2309 | u8 tmp; |
@@ -2121,34 +2321,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2121 | 2321 | ||
2122 | superio_exit(sio_data->sioreg); | 2322 | superio_exit(sio_data->sioreg); |
2123 | 2323 | ||
2124 | /* It looks like fan4 and fan5 pins can be alternatively used | 2324 | w83627ehf_check_fan_inputs(sio_data, data); |
2125 | as fan on/off switches, but fan5 control is write only :/ | ||
2126 | We assume that if the serial interface is disabled, designers | ||
2127 | connected fan5 as input unless they are emitting log 1, which | ||
2128 | is not the default. */ | ||
2129 | |||
2130 | data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */ | ||
2131 | |||
2132 | data->has_fan |= (fan3pin << 2); | ||
2133 | data->has_fan_min |= (fan3pin << 2); | ||
2134 | |||
2135 | /* | ||
2136 | * NCT6775F and NCT6776F don't have the W83627EHF_REG_FANDIV1 register | ||
2137 | */ | ||
2138 | if (sio_data->kind == nct6775 || sio_data->kind == nct6776) { | ||
2139 | data->has_fan |= (fan4pin << 3) | (fan5pin << 4); | ||
2140 | data->has_fan_min |= (fan4min << 3) | (fan5pin << 4); | ||
2141 | } else { | ||
2142 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); | ||
2143 | if ((i & (1 << 2)) && fan4pin) { | ||
2144 | data->has_fan |= (1 << 3); | ||
2145 | data->has_fan_min |= (1 << 3); | ||
2146 | } | ||
2147 | if (!(i & (1 << 1)) && fan5pin) { | ||
2148 | data->has_fan |= (1 << 4); | ||
2149 | data->has_fan_min |= (1 << 4); | ||
2150 | } | ||
2151 | } | ||
2152 | 2325 | ||
2153 | /* Read fan clock dividers immediately */ | 2326 | /* Read fan clock dividers immediately */ |
2154 | w83627ehf_update_fan_div_common(dev, data); | 2327 | w83627ehf_update_fan_div_common(dev, data); |
@@ -2180,7 +2353,14 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2180 | goto exit_remove; | 2353 | goto exit_remove; |
2181 | } | 2354 | } |
2182 | } | 2355 | } |
2183 | /* if fan4 is enabled create the sf3 files for it */ | 2356 | /* if fan3 and fan4 are enabled create the sf3 files for them */ |
2357 | if ((data->has_fan & (1 << 2)) && data->pwm_num >= 3) | ||
2358 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++) { | ||
2359 | err = device_create_file(dev, | ||
2360 | &sda_sf3_arrays_fan3[i].dev_attr); | ||
2361 | if (err) | ||
2362 | goto exit_remove; | ||
2363 | } | ||
2184 | if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4) | 2364 | if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4) |
2185 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { | 2365 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { |
2186 | err = device_create_file(dev, | 2366 | err = device_create_file(dev, |
@@ -2248,6 +2428,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2248 | if (err) | 2428 | if (err) |
2249 | goto exit_remove; | 2429 | goto exit_remove; |
2250 | } | 2430 | } |
2431 | if (i == 2 && data->temp3_val_only) | ||
2432 | continue; | ||
2251 | if (data->reg_temp_over[i]) { | 2433 | if (data->reg_temp_over[i]) { |
2252 | err = device_create_file(dev, | 2434 | err = device_create_file(dev, |
2253 | &sda_temp_max[i].dev_attr); | 2435 | &sda_temp_max[i].dev_attr); |
@@ -2269,6 +2451,16 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2269 | goto exit_remove; | 2451 | goto exit_remove; |
2270 | } | 2452 | } |
2271 | 2453 | ||
2454 | err = device_create_file(dev, &sda_caseopen[0].dev_attr); | ||
2455 | if (err) | ||
2456 | goto exit_remove; | ||
2457 | |||
2458 | if (sio_data->kind == nct6776) { | ||
2459 | err = device_create_file(dev, &sda_caseopen[1].dev_attr); | ||
2460 | if (err) | ||
2461 | goto exit_remove; | ||
2462 | } | ||
2463 | |||
2272 | err = device_create_file(dev, &dev_attr_name); | 2464 | err = device_create_file(dev, &dev_attr_name); |
2273 | if (err) | 2465 | if (err) |
2274 | goto exit_remove; | 2466 | goto exit_remove; |
@@ -2321,6 +2513,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | |||
2321 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; | 2513 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; |
2322 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; | 2514 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; |
2323 | static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P"; | 2515 | static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P"; |
2516 | static const char __initdata sio_name_W83627UHG[] = "W83627UHG"; | ||
2324 | static const char __initdata sio_name_W83667HG[] = "W83667HG"; | 2517 | static const char __initdata sio_name_W83667HG[] = "W83667HG"; |
2325 | static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B"; | 2518 | static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B"; |
2326 | static const char __initdata sio_name_NCT6775[] = "NCT6775F"; | 2519 | static const char __initdata sio_name_NCT6775[] = "NCT6775F"; |
@@ -2353,6 +2546,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | |||
2353 | sio_data->kind = w83627dhg_p; | 2546 | sio_data->kind = w83627dhg_p; |
2354 | sio_name = sio_name_W83627DHG_P; | 2547 | sio_name = sio_name_W83627DHG_P; |
2355 | break; | 2548 | break; |
2549 | case SIO_W83627UHG_ID: | ||
2550 | sio_data->kind = w83627uhg; | ||
2551 | sio_name = sio_name_W83627UHG; | ||
2552 | break; | ||
2356 | case SIO_W83667HG_ID: | 2553 | case SIO_W83667HG_ID: |
2357 | sio_data->kind = w83667hg; | 2554 | sio_data->kind = w83667hg; |
2358 | sio_name = sio_name_W83667HG; | 2555 | sio_name = sio_name_W83667HG; |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index eed43a008be1..65b685e2c7b7 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -1245,17 +1245,17 @@ w83781d_read_value_i2c(struct w83781d_data *data, u16 reg) | |||
1245 | /* convert from ISA to LM75 I2C addresses */ | 1245 | /* convert from ISA to LM75 I2C addresses */ |
1246 | switch (reg & 0xff) { | 1246 | switch (reg & 0xff) { |
1247 | case 0x50: /* TEMP */ | 1247 | case 0x50: /* TEMP */ |
1248 | res = swab16(i2c_smbus_read_word_data(cl, 0)); | 1248 | res = i2c_smbus_read_word_swapped(cl, 0); |
1249 | break; | 1249 | break; |
1250 | case 0x52: /* CONFIG */ | 1250 | case 0x52: /* CONFIG */ |
1251 | res = i2c_smbus_read_byte_data(cl, 1); | 1251 | res = i2c_smbus_read_byte_data(cl, 1); |
1252 | break; | 1252 | break; |
1253 | case 0x53: /* HYST */ | 1253 | case 0x53: /* HYST */ |
1254 | res = swab16(i2c_smbus_read_word_data(cl, 2)); | 1254 | res = i2c_smbus_read_word_swapped(cl, 2); |
1255 | break; | 1255 | break; |
1256 | case 0x55: /* OVER */ | 1256 | case 0x55: /* OVER */ |
1257 | default: | 1257 | default: |
1258 | res = swab16(i2c_smbus_read_word_data(cl, 3)); | 1258 | res = i2c_smbus_read_word_swapped(cl, 3); |
1259 | break; | 1259 | break; |
1260 | } | 1260 | } |
1261 | } | 1261 | } |
@@ -1289,10 +1289,10 @@ w83781d_write_value_i2c(struct w83781d_data *data, u16 reg, u16 value) | |||
1289 | i2c_smbus_write_byte_data(cl, 1, value & 0xff); | 1289 | i2c_smbus_write_byte_data(cl, 1, value & 0xff); |
1290 | break; | 1290 | break; |
1291 | case 0x53: /* HYST */ | 1291 | case 0x53: /* HYST */ |
1292 | i2c_smbus_write_word_data(cl, 2, swab16(value)); | 1292 | i2c_smbus_write_word_swapped(cl, 2, value); |
1293 | break; | 1293 | break; |
1294 | case 0x55: /* OVER */ | 1294 | case 0x55: /* OVER */ |
1295 | i2c_smbus_write_word_data(cl, 3, swab16(value)); | 1295 | i2c_smbus_write_word_swapped(cl, 3, value); |
1296 | break; | 1296 | break; |
1297 | } | 1297 | } |
1298 | } | 1298 | } |