diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 148 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 10 | ||||
-rw-r--r-- | drivers/hwmon/abituguru.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/abituguru3.c | 79 | ||||
-rw-r--r-- | drivers/hwmon/applesmc.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/dme1737.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/f71805f.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/hdaps.c | 3 | ||||
-rw-r--r-- | drivers/hwmon/hwmon-vid.c | 10 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/lm78.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/lm85.c | 32 | ||||
-rw-r--r-- | drivers/hwmon/pc87360.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/pc87427.c | 8 | ||||
-rw-r--r-- | drivers/hwmon/s3c-hwmon.c | 405 | ||||
-rw-r--r-- | drivers/hwmon/sis5595.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/smsc47b397.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/smsc47m1.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/tmp421.c | 347 | ||||
-rw-r--r-- | drivers/hwmon/via686a.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/vt1211.c | 8 | ||||
-rw-r--r-- | drivers/hwmon/vt8231.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/w83627hf.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/w83781d.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/wm831x-hwmon.c | 226 | ||||
-rw-r--r-- | drivers/hwmon/wm8350-hwmon.c | 151 |
27 files changed, 1345 insertions, 112 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 2d5016691d40..ed7711d11ae8 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -28,6 +28,17 @@ config HWMON_VID | |||
28 | tristate | 28 | tristate |
29 | default n | 29 | default n |
30 | 30 | ||
31 | config HWMON_DEBUG_CHIP | ||
32 | bool "Hardware Monitoring Chip debugging messages" | ||
33 | default n | ||
34 | help | ||
35 | Say Y here if you want the I2C chip drivers to produce a bunch of | ||
36 | debug messages to the system log. Select this if you are having | ||
37 | a problem with I2C support and want to see more of what is going | ||
38 | on. | ||
39 | |||
40 | comment "Native drivers" | ||
41 | |||
31 | config SENSORS_ABITUGURU | 42 | config SENSORS_ABITUGURU |
32 | tristate "Abit uGuru (rev 1 & 2)" | 43 | tristate "Abit uGuru (rev 1 & 2)" |
33 | depends on X86 && EXPERIMENTAL | 44 | depends on X86 && EXPERIMENTAL |
@@ -248,18 +259,6 @@ config SENSORS_ASB100 | |||
248 | This driver can also be built as a module. If so, the module | 259 | This driver can also be built as a module. If so, the module |
249 | will be called asb100. | 260 | will be called asb100. |
250 | 261 | ||
251 | config SENSORS_ATK0110 | ||
252 | tristate "ASUS ATK0110 ACPI hwmon" | ||
253 | depends on X86 && ACPI && EXPERIMENTAL | ||
254 | help | ||
255 | If you say yes here you get support for the ACPI hardware | ||
256 | monitoring interface found in many ASUS motherboards. This | ||
257 | driver will provide readings of fans, voltages and temperatures | ||
258 | through the system firmware. | ||
259 | |||
260 | This driver can also be built as a module. If so, the module | ||
261 | will be called asus_atk0110. | ||
262 | |||
263 | config SENSORS_ATXP1 | 262 | config SENSORS_ATXP1 |
264 | tristate "Attansic ATXP1 VID controller" | 263 | tristate "Attansic ATXP1 VID controller" |
265 | depends on I2C && EXPERIMENTAL | 264 | depends on I2C && EXPERIMENTAL |
@@ -702,6 +701,23 @@ config SENSORS_SHT15 | |||
702 | This driver can also be built as a module. If so, the module | 701 | This driver can also be built as a module. If so, the module |
703 | will be called sht15. | 702 | will be called sht15. |
704 | 703 | ||
704 | config SENSORS_S3C | ||
705 | tristate "S3C24XX/S3C64XX Inbuilt ADC" | ||
706 | depends on ARCH_S3C2410 || ARCH_S3C64XX | ||
707 | help | ||
708 | If you say yes here you get support for the on-board ADCs of | ||
709 | the Samsung S3C24XX or S3C64XX series of SoC | ||
710 | |||
711 | This driver can also be built as a module. If so, the module | ||
712 | will be called s3c-hwmo. | ||
713 | |||
714 | config SENSORS_S3C_RAW | ||
715 | bool "Include raw channel attributes in sysfs" | ||
716 | depends on SENSORS_S3C | ||
717 | help | ||
718 | Say Y here if you want to include raw copies of all the ADC | ||
719 | channels in sysfs. | ||
720 | |||
705 | config SENSORS_SIS5595 | 721 | config SENSORS_SIS5595 |
706 | tristate "Silicon Integrated Systems Corp. SiS5595" | 722 | tristate "Silicon Integrated Systems Corp. SiS5595" |
707 | depends on PCI | 723 | depends on PCI |
@@ -797,6 +813,16 @@ config SENSORS_TMP401 | |||
797 | This driver can also be built as a module. If so, the module | 813 | This driver can also be built as a module. If so, the module |
798 | will be called tmp401. | 814 | will be called tmp401. |
799 | 815 | ||
816 | config SENSORS_TMP421 | ||
817 | tristate "Texas Instruments TMP421 and compatible" | ||
818 | depends on I2C && EXPERIMENTAL | ||
819 | help | ||
820 | If you say yes here you get support for Texas Instruments TMP421, | ||
821 | TMP422 and TMP423 temperature sensor chips. | ||
822 | |||
823 | This driver can also be built as a module. If so, the module | ||
824 | will be called tmp421. | ||
825 | |||
800 | config SENSORS_VIA686A | 826 | config SENSORS_VIA686A |
801 | tristate "VIA686A" | 827 | tristate "VIA686A" |
802 | depends on PCI | 828 | depends on PCI |
@@ -920,6 +946,27 @@ config SENSORS_W83627EHF | |||
920 | This driver can also be built as a module. If so, the module | 946 | This driver can also be built as a module. If so, the module |
921 | will be called w83627ehf. | 947 | will be called w83627ehf. |
922 | 948 | ||
949 | config SENSORS_WM831X | ||
950 | tristate "WM831x PMICs" | ||
951 | depends on MFD_WM831X | ||
952 | help | ||
953 | If you say yes here you get support for the hardware | ||
954 | monitoring functionality of the Wolfson Microelectronics | ||
955 | WM831x series of PMICs. | ||
956 | |||
957 | This driver can also be built as a module. If so, the module | ||
958 | will be called wm831x-hwmon. | ||
959 | |||
960 | config SENSORS_WM8350 | ||
961 | tristate "Wolfson Microelectronics WM835x" | ||
962 | depends on MFD_WM8350 | ||
963 | help | ||
964 | If you say yes here you get support for the hardware | ||
965 | monitoring features of the WM835x series of PMICs. | ||
966 | |||
967 | This driver can also be built as a module. If so, the module | ||
968 | will be called wm8350-hwmon. | ||
969 | |||
923 | config SENSORS_ULTRA45 | 970 | config SENSORS_ULTRA45 |
924 | tristate "Sun Ultra45 PIC16F747" | 971 | tristate "Sun Ultra45 PIC16F747" |
925 | depends on SPARC64 | 972 | depends on SPARC64 |
@@ -947,34 +994,6 @@ config SENSORS_HDAPS | |||
947 | Say Y here if you have an applicable laptop and want to experience | 994 | Say Y here if you have an applicable laptop and want to experience |
948 | the awesome power of hdaps. | 995 | the awesome power of hdaps. |
949 | 996 | ||
950 | config SENSORS_LIS3LV02D | ||
951 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer" | ||
952 | depends on ACPI && INPUT | ||
953 | select INPUT_POLLDEV | ||
954 | select NEW_LEDS | ||
955 | select LEDS_CLASS | ||
956 | default n | ||
957 | help | ||
958 | This driver provides support for the LIS3LV02Dx accelerometer. In | ||
959 | particular, it can be found in a number of HP laptops, which have the | ||
960 | "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such | ||
961 | systems the driver should load automatically (via ACPI). The | ||
962 | accelerometer might also be found in other systems, connected via SPI | ||
963 | or I2C. The accelerometer data is readable via | ||
964 | /sys/devices/platform/lis3lv02d. | ||
965 | |||
966 | This driver also provides an absolute input class device, allowing | ||
967 | the laptop to act as a pinball machine-esque joystick. On HP laptops, | ||
968 | if the led infrastructure is activated, support for a led indicating | ||
969 | disk protection will be provided as hp:red:hddprotection. | ||
970 | |||
971 | This driver can also be built as modules. If so, the core module | ||
972 | will be called lis3lv02d and a specific module for HP laptops will be | ||
973 | called hp_accel. | ||
974 | |||
975 | Say Y here if you have an applicable laptop and want to experience | ||
976 | the awesome power of lis3lv02d. | ||
977 | |||
978 | config SENSORS_LIS3_SPI | 997 | config SENSORS_LIS3_SPI |
979 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)" | 998 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)" |
980 | depends on !ACPI && SPI_MASTER && INPUT | 999 | depends on !ACPI && SPI_MASTER && INPUT |
@@ -1017,13 +1036,50 @@ config SENSORS_APPLESMC | |||
1017 | Say Y here if you have an applicable laptop and want to experience | 1036 | Say Y here if you have an applicable laptop and want to experience |
1018 | the awesome power of applesmc. | 1037 | the awesome power of applesmc. |
1019 | 1038 | ||
1020 | config HWMON_DEBUG_CHIP | 1039 | if ACPI |
1021 | bool "Hardware Monitoring Chip debugging messages" | 1040 | |
1041 | comment "ACPI drivers" | ||
1042 | |||
1043 | config SENSORS_ATK0110 | ||
1044 | tristate "ASUS ATK0110" | ||
1045 | depends on X86 && EXPERIMENTAL | ||
1046 | help | ||
1047 | If you say yes here you get support for the ACPI hardware | ||
1048 | monitoring interface found in many ASUS motherboards. This | ||
1049 | driver will provide readings of fans, voltages and temperatures | ||
1050 | through the system firmware. | ||
1051 | |||
1052 | This driver can also be built as a module. If so, the module | ||
1053 | will be called asus_atk0110. | ||
1054 | |||
1055 | config SENSORS_LIS3LV02D | ||
1056 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer" | ||
1057 | depends on INPUT | ||
1058 | select INPUT_POLLDEV | ||
1059 | select NEW_LEDS | ||
1060 | select LEDS_CLASS | ||
1022 | default n | 1061 | default n |
1023 | help | 1062 | help |
1024 | Say Y here if you want the I2C chip drivers to produce a bunch of | 1063 | This driver provides support for the LIS3LV02Dx accelerometer. In |
1025 | debug messages to the system log. Select this if you are having | 1064 | particular, it can be found in a number of HP laptops, which have the |
1026 | a problem with I2C support and want to see more of what is going | 1065 | "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such |
1027 | on. | 1066 | systems the driver should load automatically (via ACPI). The |
1067 | accelerometer might also be found in other systems, connected via SPI | ||
1068 | or I2C. The accelerometer data is readable via | ||
1069 | /sys/devices/platform/lis3lv02d. | ||
1070 | |||
1071 | This driver also provides an absolute input class device, allowing | ||
1072 | the laptop to act as a pinball machine-esque joystick. On HP laptops, | ||
1073 | if the led infrastructure is activated, support for a led indicating | ||
1074 | disk protection will be provided as hp:red:hddprotection. | ||
1075 | |||
1076 | This driver can also be built as modules. If so, the core module | ||
1077 | will be called lis3lv02d and a specific module for HP laptops will be | ||
1078 | called hp_accel. | ||
1079 | |||
1080 | Say Y here if you have an applicable laptop and want to experience | ||
1081 | the awesome power of lis3lv02d. | ||
1082 | |||
1083 | endif # ACPI | ||
1028 | 1084 | ||
1029 | endif # HWMON | 1085 | endif # HWMON |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index b793dce6bed5..bcf73a9bb619 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -5,6 +5,10 @@ | |||
5 | obj-$(CONFIG_HWMON) += hwmon.o | 5 | obj-$(CONFIG_HWMON) += hwmon.o |
6 | obj-$(CONFIG_HWMON_VID) += hwmon-vid.o | 6 | obj-$(CONFIG_HWMON_VID) += hwmon-vid.o |
7 | 7 | ||
8 | # APCI drivers | ||
9 | obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o | ||
10 | |||
11 | # Native drivers | ||
8 | # asb100, then w83781d go first, as they can override other drivers' addresses. | 12 | # asb100, then w83781d go first, as they can override other drivers' addresses. |
9 | obj-$(CONFIG_SENSORS_ASB100) += asb100.o | 13 | obj-$(CONFIG_SENSORS_ASB100) += asb100.o |
10 | obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o | 14 | obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o |
@@ -29,10 +33,8 @@ obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o | |||
29 | obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o | 33 | obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o |
30 | obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o | 34 | obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o |
31 | obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o | 35 | obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o |
32 | |||
33 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o | 36 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o |
34 | obj-$(CONFIG_SENSORS_AMS) += ams/ | 37 | obj-$(CONFIG_SENSORS_AMS) += ams/ |
35 | obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o | ||
36 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 38 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
37 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o | 39 | obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o |
38 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o | 40 | obj-$(CONFIG_SENSORS_DME1737) += dme1737.o |
@@ -76,6 +78,7 @@ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | |||
76 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 78 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
77 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o | 79 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o |
78 | obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o | 80 | obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o |
81 | obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o | ||
79 | obj-$(CONFIG_SENSORS_SHT15) += sht15.o | 82 | obj-$(CONFIG_SENSORS_SHT15) += sht15.o |
80 | obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o | 83 | obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o |
81 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o | 84 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o |
@@ -83,12 +86,15 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o | |||
83 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o | 86 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o |
84 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o | 87 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o |
85 | obj-$(CONFIG_SENSORS_TMP401) += tmp401.o | 88 | obj-$(CONFIG_SENSORS_TMP401) += tmp401.o |
89 | obj-$(CONFIG_SENSORS_TMP421) += tmp421.o | ||
86 | obj-$(CONFIG_SENSORS_VIA686A) += via686a.o | 90 | obj-$(CONFIG_SENSORS_VIA686A) += via686a.o |
87 | obj-$(CONFIG_SENSORS_VT1211) += vt1211.o | 91 | obj-$(CONFIG_SENSORS_VT1211) += vt1211.o |
88 | obj-$(CONFIG_SENSORS_VT8231) += vt8231.o | 92 | obj-$(CONFIG_SENSORS_VT8231) += vt8231.o |
89 | obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o | 93 | obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o |
90 | obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o | 94 | obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o |
91 | obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o | 95 | obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o |
96 | obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o | ||
97 | obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o | ||
92 | 98 | ||
93 | ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) | 99 | ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) |
94 | EXTRA_CFLAGS += -DDEBUG | 100 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 4dbdb81ea3b1..03694cc17a32 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/hwmon.h> | 32 | #include <linux/hwmon.h> |
33 | #include <linux/hwmon-sysfs.h> | 33 | #include <linux/hwmon-sysfs.h> |
34 | #include <linux/dmi.h> | 34 | #include <linux/dmi.h> |
35 | #include <asm/io.h> | 35 | #include <linux/io.h> |
36 | 36 | ||
37 | /* Banks */ | 37 | /* Banks */ |
38 | #define ABIT_UGURU_ALARM_BANK 0x20 /* 1x 3 bytes */ | 38 | #define ABIT_UGURU_ALARM_BANK 0x20 /* 1x 3 bytes */ |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 7d3f15d32fdf..3cf28af614b5 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/hwmon.h> | 34 | #include <linux/hwmon.h> |
35 | #include <linux/hwmon-sysfs.h> | 35 | #include <linux/hwmon-sysfs.h> |
36 | #include <linux/dmi.h> | 36 | #include <linux/dmi.h> |
37 | #include <asm/io.h> | 37 | #include <linux/io.h> |
38 | 38 | ||
39 | /* uGuru3 bank addresses */ | 39 | /* uGuru3 bank addresses */ |
40 | #define ABIT_UGURU3_SETTINGS_BANK 0x01 | 40 | #define ABIT_UGURU3_SETTINGS_BANK 0x01 |
@@ -117,9 +117,12 @@ struct abituguru3_sensor_info { | |||
117 | int offset; | 117 | int offset; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | /* Avoid use of flexible array members */ | ||
121 | #define ABIT_UGURU3_MAX_DMI_NAMES 2 | ||
122 | |||
120 | struct abituguru3_motherboard_info { | 123 | struct abituguru3_motherboard_info { |
121 | u16 id; | 124 | u16 id; |
122 | const char *dmi_name; | 125 | const char *dmi_name[ABIT_UGURU3_MAX_DMI_NAMES + 1]; |
123 | /* + 1 -> end of sensors indicated by a sensor with name == NULL */ | 126 | /* + 1 -> end of sensors indicated by a sensor with name == NULL */ |
124 | struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; | 127 | struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; |
125 | }; | 128 | }; |
@@ -164,7 +167,7 @@ struct abituguru3_data { | |||
164 | 167 | ||
165 | /* Constants */ | 168 | /* Constants */ |
166 | static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | 169 | static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { |
167 | { 0x000C, NULL /* Unknown, need DMI string */, { | 170 | { 0x000C, { NULL } /* Unknown, need DMI string */, { |
168 | { "CPU Core", 0, 0, 10, 1, 0 }, | 171 | { "CPU Core", 0, 0, 10, 1, 0 }, |
169 | { "DDR", 1, 0, 10, 1, 0 }, | 172 | { "DDR", 1, 0, 10, 1, 0 }, |
170 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 173 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -186,7 +189,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
186 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | 189 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, |
187 | { NULL, 0, 0, 0, 0, 0 } } | 190 | { NULL, 0, 0, 0, 0, 0 } } |
188 | }, | 191 | }, |
189 | { 0x000D, NULL /* Abit AW8, need DMI string */, { | 192 | { 0x000D, { NULL } /* Abit AW8, need DMI string */, { |
190 | { "CPU Core", 0, 0, 10, 1, 0 }, | 193 | { "CPU Core", 0, 0, 10, 1, 0 }, |
191 | { "DDR", 1, 0, 10, 1, 0 }, | 194 | { "DDR", 1, 0, 10, 1, 0 }, |
192 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 195 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -215,7 +218,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
215 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | 218 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, |
216 | { NULL, 0, 0, 0, 0, 0 } } | 219 | { NULL, 0, 0, 0, 0, 0 } } |
217 | }, | 220 | }, |
218 | { 0x000E, NULL /* AL-8, need DMI string */, { | 221 | { 0x000E, { NULL } /* AL-8, need DMI string */, { |
219 | { "CPU Core", 0, 0, 10, 1, 0 }, | 222 | { "CPU Core", 0, 0, 10, 1, 0 }, |
220 | { "DDR", 1, 0, 10, 1, 0 }, | 223 | { "DDR", 1, 0, 10, 1, 0 }, |
221 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 224 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -236,7 +239,8 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
236 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 239 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
237 | { NULL, 0, 0, 0, 0, 0 } } | 240 | { NULL, 0, 0, 0, 0, 0 } } |
238 | }, | 241 | }, |
239 | { 0x000F, NULL /* Unknown, need DMI string */, { | 242 | { 0x000F, { NULL } /* Unknown, need DMI string */, { |
243 | |||
240 | { "CPU Core", 0, 0, 10, 1, 0 }, | 244 | { "CPU Core", 0, 0, 10, 1, 0 }, |
241 | { "DDR", 1, 0, 10, 1, 0 }, | 245 | { "DDR", 1, 0, 10, 1, 0 }, |
242 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 246 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -257,7 +261,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
257 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 261 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
258 | { NULL, 0, 0, 0, 0, 0 } } | 262 | { NULL, 0, 0, 0, 0, 0 } } |
259 | }, | 263 | }, |
260 | { 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, { | 264 | { 0x0010, { NULL } /* Abit NI8 SLI GR, need DMI string */, { |
261 | { "CPU Core", 0, 0, 10, 1, 0 }, | 265 | { "CPU Core", 0, 0, 10, 1, 0 }, |
262 | { "DDR", 1, 0, 10, 1, 0 }, | 266 | { "DDR", 1, 0, 10, 1, 0 }, |
263 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 267 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -279,7 +283,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
279 | { "OTES1 Fan", 36, 2, 60, 1, 0 }, | 283 | { "OTES1 Fan", 36, 2, 60, 1, 0 }, |
280 | { NULL, 0, 0, 0, 0, 0 } } | 284 | { NULL, 0, 0, 0, 0, 0 } } |
281 | }, | 285 | }, |
282 | { 0x0011, "AT8 32X", { | 286 | { 0x0011, { "AT8 32X", NULL }, { |
283 | { "CPU Core", 0, 0, 10, 1, 0 }, | 287 | { "CPU Core", 0, 0, 10, 1, 0 }, |
284 | { "DDR", 1, 0, 20, 1, 0 }, | 288 | { "DDR", 1, 0, 20, 1, 0 }, |
285 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 289 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -306,7 +310,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
306 | { "AUX3 Fan", 37, 2, 60, 1, 0 }, | 310 | { "AUX3 Fan", 37, 2, 60, 1, 0 }, |
307 | { NULL, 0, 0, 0, 0, 0 } } | 311 | { NULL, 0, 0, 0, 0, 0 } } |
308 | }, | 312 | }, |
309 | { 0x0012, NULL /* Abit AN8 32X, need DMI string */, { | 313 | { 0x0012, { NULL } /* Abit AN8 32X, need DMI string */, { |
310 | { "CPU Core", 0, 0, 10, 1, 0 }, | 314 | { "CPU Core", 0, 0, 10, 1, 0 }, |
311 | { "DDR", 1, 0, 20, 1, 0 }, | 315 | { "DDR", 1, 0, 20, 1, 0 }, |
312 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 316 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -328,7 +332,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
328 | { "AUX1 Fan", 36, 2, 60, 1, 0 }, | 332 | { "AUX1 Fan", 36, 2, 60, 1, 0 }, |
329 | { NULL, 0, 0, 0, 0, 0 } } | 333 | { NULL, 0, 0, 0, 0, 0 } } |
330 | }, | 334 | }, |
331 | { 0x0013, NULL /* Abit AW8D, need DMI string */, { | 335 | { 0x0013, { NULL } /* Abit AW8D, need DMI string */, { |
332 | { "CPU Core", 0, 0, 10, 1, 0 }, | 336 | { "CPU Core", 0, 0, 10, 1, 0 }, |
333 | { "DDR", 1, 0, 10, 1, 0 }, | 337 | { "DDR", 1, 0, 10, 1, 0 }, |
334 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 338 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -357,7 +361,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
357 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | 361 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, |
358 | { NULL, 0, 0, 0, 0, 0 } } | 362 | { NULL, 0, 0, 0, 0, 0 } } |
359 | }, | 363 | }, |
360 | { 0x0014, "AB9", /* + AB9 Pro */ { | 364 | { 0x0014, { "AB9", "AB9 Pro", NULL }, { |
361 | { "CPU Core", 0, 0, 10, 1, 0 }, | 365 | { "CPU Core", 0, 0, 10, 1, 0 }, |
362 | { "DDR", 1, 0, 10, 1, 0 }, | 366 | { "DDR", 1, 0, 10, 1, 0 }, |
363 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 367 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -378,7 +382,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
378 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 382 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
379 | { NULL, 0, 0, 0, 0, 0 } } | 383 | { NULL, 0, 0, 0, 0, 0 } } |
380 | }, | 384 | }, |
381 | { 0x0015, NULL /* Unknown, need DMI string */, { | 385 | { 0x0015, { NULL } /* Unknown, need DMI string */, { |
382 | { "CPU Core", 0, 0, 10, 1, 0 }, | 386 | { "CPU Core", 0, 0, 10, 1, 0 }, |
383 | { "DDR", 1, 0, 20, 1, 0 }, | 387 | { "DDR", 1, 0, 20, 1, 0 }, |
384 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 388 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -402,7 +406,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
402 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 406 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
403 | { NULL, 0, 0, 0, 0, 0 } } | 407 | { NULL, 0, 0, 0, 0, 0 } } |
404 | }, | 408 | }, |
405 | { 0x0016, "AW9D-MAX", { | 409 | { 0x0016, { "AW9D-MAX", NULL }, { |
406 | { "CPU Core", 0, 0, 10, 1, 0 }, | 410 | { "CPU Core", 0, 0, 10, 1, 0 }, |
407 | { "DDR2", 1, 0, 20, 1, 0 }, | 411 | { "DDR2", 1, 0, 20, 1, 0 }, |
408 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 412 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -430,7 +434,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
430 | { "OTES1 Fan", 38, 2, 60, 1, 0 }, | 434 | { "OTES1 Fan", 38, 2, 60, 1, 0 }, |
431 | { NULL, 0, 0, 0, 0, 0 } } | 435 | { NULL, 0, 0, 0, 0, 0 } } |
432 | }, | 436 | }, |
433 | { 0x0017, NULL /* Unknown, need DMI string */, { | 437 | { 0x0017, { NULL } /* Unknown, need DMI string */, { |
434 | { "CPU Core", 0, 0, 10, 1, 0 }, | 438 | { "CPU Core", 0, 0, 10, 1, 0 }, |
435 | { "DDR2", 1, 0, 20, 1, 0 }, | 439 | { "DDR2", 1, 0, 20, 1, 0 }, |
436 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 440 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -455,7 +459,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
455 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, | 459 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, |
456 | { NULL, 0, 0, 0, 0, 0 } } | 460 | { NULL, 0, 0, 0, 0, 0 } } |
457 | }, | 461 | }, |
458 | { 0x0018, "AB9 QuadGT", { | 462 | { 0x0018, { "AB9 QuadGT", NULL }, { |
459 | { "CPU Core", 0, 0, 10, 1, 0 }, | 463 | { "CPU Core", 0, 0, 10, 1, 0 }, |
460 | { "DDR2", 1, 0, 20, 1, 0 }, | 464 | { "DDR2", 1, 0, 20, 1, 0 }, |
461 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 465 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -482,7 +486,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
482 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 486 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
483 | { NULL, 0, 0, 0, 0, 0 } } | 487 | { NULL, 0, 0, 0, 0, 0 } } |
484 | }, | 488 | }, |
485 | { 0x0019, "IN9 32X MAX", { | 489 | { 0x0019, { "IN9 32X MAX", NULL }, { |
486 | { "CPU Core", 7, 0, 10, 1, 0 }, | 490 | { "CPU Core", 7, 0, 10, 1, 0 }, |
487 | { "DDR2", 13, 0, 20, 1, 0 }, | 491 | { "DDR2", 13, 0, 20, 1, 0 }, |
488 | { "DDR2 VTT", 14, 0, 10, 1, 0 }, | 492 | { "DDR2 VTT", 14, 0, 10, 1, 0 }, |
@@ -509,7 +513,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
509 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, | 513 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, |
510 | { NULL, 0, 0, 0, 0, 0 } } | 514 | { NULL, 0, 0, 0, 0, 0 } } |
511 | }, | 515 | }, |
512 | { 0x001A, "IP35 Pro", { | 516 | { 0x001A, { "IP35 Pro", "IP35 Pro XE", NULL }, { |
513 | { "CPU Core", 0, 0, 10, 1, 0 }, | 517 | { "CPU Core", 0, 0, 10, 1, 0 }, |
514 | { "DDR2", 1, 0, 20, 1, 0 }, | 518 | { "DDR2", 1, 0, 20, 1, 0 }, |
515 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 519 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -537,7 +541,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
537 | { "AUX4 Fan", 37, 2, 60, 1, 0 }, | 541 | { "AUX4 Fan", 37, 2, 60, 1, 0 }, |
538 | { NULL, 0, 0, 0, 0, 0 } } | 542 | { NULL, 0, 0, 0, 0, 0 } } |
539 | }, | 543 | }, |
540 | { 0x001B, NULL /* Unknown, need DMI string */, { | 544 | { 0x001B, { NULL } /* Unknown, need DMI string */, { |
541 | { "CPU Core", 0, 0, 10, 1, 0 }, | 545 | { "CPU Core", 0, 0, 10, 1, 0 }, |
542 | { "DDR3", 1, 0, 20, 1, 0 }, | 546 | { "DDR3", 1, 0, 20, 1, 0 }, |
543 | { "DDR3 VTT", 2, 0, 10, 1, 0 }, | 547 | { "DDR3 VTT", 2, 0, 10, 1, 0 }, |
@@ -564,7 +568,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
564 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 568 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
565 | { NULL, 0, 0, 0, 0, 0 } } | 569 | { NULL, 0, 0, 0, 0, 0 } } |
566 | }, | 570 | }, |
567 | { 0x001C, "IX38 QuadGT", { | 571 | { 0x001C, { "IX38 QuadGT", NULL }, { |
568 | { "CPU Core", 0, 0, 10, 1, 0 }, | 572 | { "CPU Core", 0, 0, 10, 1, 0 }, |
569 | { "DDR2", 1, 0, 20, 1, 0 }, | 573 | { "DDR2", 1, 0, 20, 1, 0 }, |
570 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 574 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -591,7 +595,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
591 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 595 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
592 | { NULL, 0, 0, 0, 0, 0 } } | 596 | { NULL, 0, 0, 0, 0, 0 } } |
593 | }, | 597 | }, |
594 | { 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } } | 598 | { 0x0000, { NULL }, { { NULL, 0, 0, 0, 0, 0 } } } |
595 | }; | 599 | }; |
596 | 600 | ||
597 | 601 | ||
@@ -946,15 +950,6 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) | |||
946 | printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " | 950 | printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " |
947 | "ID: %04X\n", (unsigned int)id); | 951 | "ID: %04X\n", (unsigned int)id); |
948 | 952 | ||
949 | #ifdef CONFIG_DMI | ||
950 | if (!abituguru3_motherboards[i].dmi_name) { | ||
951 | printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was " | ||
952 | "not detected using DMI. Please send the output of " | ||
953 | "\"dmidecode\" to the abituguru3 maintainer " | ||
954 | "(see MAINTAINERS)\n"); | ||
955 | } | ||
956 | #endif | ||
957 | |||
958 | /* Fill the sysfs attr array */ | 953 | /* Fill the sysfs attr array */ |
959 | sysfs_attr_i = 0; | 954 | sysfs_attr_i = 0; |
960 | sysfs_filename = data->sysfs_names; | 955 | sysfs_filename = data->sysfs_names; |
@@ -1131,6 +1126,7 @@ static int __init abituguru3_dmi_detect(void) | |||
1131 | { | 1126 | { |
1132 | const char *board_vendor, *board_name; | 1127 | const char *board_vendor, *board_name; |
1133 | int i, err = (force) ? 1 : -ENODEV; | 1128 | int i, err = (force) ? 1 : -ENODEV; |
1129 | const char *const *dmi_name; | ||
1134 | size_t sublen; | 1130 | size_t sublen; |
1135 | 1131 | ||
1136 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | 1132 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); |
@@ -1151,17 +1147,17 @@ static int __init abituguru3_dmi_detect(void) | |||
1151 | sublen--; | 1147 | sublen--; |
1152 | 1148 | ||
1153 | for (i = 0; abituguru3_motherboards[i].id; i++) { | 1149 | for (i = 0; abituguru3_motherboards[i].id; i++) { |
1154 | const char *dmi_name = abituguru3_motherboards[i].dmi_name; | 1150 | dmi_name = abituguru3_motherboards[i].dmi_name; |
1155 | if (!dmi_name || strlen(dmi_name) != sublen) | 1151 | for ( ; *dmi_name; dmi_name++) { |
1156 | continue; | 1152 | if (strlen(*dmi_name) != sublen) |
1157 | if (!strncasecmp(board_name, dmi_name, sublen)) | 1153 | continue; |
1158 | break; | 1154 | if (!strncasecmp(board_name, *dmi_name, sublen)) |
1155 | return 0; | ||
1156 | } | ||
1159 | } | 1157 | } |
1160 | 1158 | ||
1161 | if (!abituguru3_motherboards[i].id) | 1159 | /* No match found */ |
1162 | return 1; | 1160 | return 1; |
1163 | |||
1164 | return 0; | ||
1165 | } | 1161 | } |
1166 | 1162 | ||
1167 | #else /* !CONFIG_DMI */ | 1163 | #else /* !CONFIG_DMI */ |
@@ -1221,6 +1217,13 @@ static int __init abituguru3_init(void) | |||
1221 | err = abituguru3_detect(); | 1217 | err = abituguru3_detect(); |
1222 | if (err) | 1218 | if (err) |
1223 | return err; | 1219 | return err; |
1220 | |||
1221 | #ifdef CONFIG_DMI | ||
1222 | printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was " | ||
1223 | "not detected using DMI. Please send the output of " | ||
1224 | "\"dmidecode\" to the abituguru3 maintainer " | ||
1225 | "(see MAINTAINERS)\n"); | ||
1226 | #endif | ||
1224 | } | 1227 | } |
1225 | 1228 | ||
1226 | err = platform_driver_register(&abituguru3_driver); | 1229 | err = platform_driver_register(&abituguru3_driver); |
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 678e34b01e52..753b34885f9d 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/dmi.h> | 35 | #include <linux/dmi.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/hwmon-sysfs.h> | 37 | #include <linux/hwmon-sysfs.h> |
38 | #include <asm/io.h> | 38 | #include <linux/io.h> |
39 | #include <linux/leds.h> | 39 | #include <linux/leds.h> |
40 | #include <linux/hwmon.h> | 40 | #include <linux/hwmon.h> |
41 | #include <linux/workqueue.h> | 41 | #include <linux/workqueue.h> |
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 3df202a9ad72..9814d51b3af4 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/err.h> | 35 | #include <linux/err.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/acpi.h> | 37 | #include <linux/acpi.h> |
38 | #include <asm/io.h> | 38 | #include <linux/io.h> |
39 | 39 | ||
40 | /* ISA device, if found */ | 40 | /* ISA device, if found */ |
41 | static struct platform_device *pdev; | 41 | static struct platform_device *pdev; |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 899876579253..525a00bd70b1 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <linux/sysfs.h> | 40 | #include <linux/sysfs.h> |
41 | #include <linux/ioport.h> | 41 | #include <linux/ioport.h> |
42 | #include <linux/acpi.h> | 42 | #include <linux/acpi.h> |
43 | #include <asm/io.h> | 43 | #include <linux/io.h> |
44 | 44 | ||
45 | static unsigned short force_id; | 45 | static unsigned short force_id; |
46 | module_param(force_id, ushort, 0); | 46 | module_param(force_id, ushort, 0); |
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index d3612a1f1981..be2d131e405c 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
@@ -35,8 +35,7 @@ | |||
35 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
36 | #include <linux/dmi.h> | 36 | #include <linux/dmi.h> |
37 | #include <linux/jiffies.h> | 37 | #include <linux/jiffies.h> |
38 | 38 | #include <linux/io.h> | |
39 | #include <asm/io.h> | ||
40 | 39 | ||
41 | #define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ | 40 | #define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ |
42 | #define HDAPS_NR_PORTS 0x30 /* number of ports: 0x1600 - 0x162f */ | 41 | #define HDAPS_NR_PORTS 0x30 /* number of ports: 0x1600 - 0x162f */ |
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index bfc296145bba..bf0862a803c0 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c | |||
@@ -179,8 +179,14 @@ struct vrm_model { | |||
179 | static struct vrm_model vrm_models[] = { | 179 | static struct vrm_model vrm_models[] = { |
180 | {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ | 180 | {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ |
181 | {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ | 181 | {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ |
182 | {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* NPT family 0Fh */ | 182 | /* In theory, all NPT family 0Fh processors have 6 VID pins and should |
183 | thus use vrm 25, however in practice not all mainboards route the | ||
184 | 6th VID pin because it is never needed. So we use the 5 VID pin | ||
185 | variant (vrm 24) for the models which exist today. */ | ||
186 | {X86_VENDOR_AMD, 0xF, 0x7F, ANY, 24}, /* NPT family 0Fh */ | ||
187 | {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* future fam. 0Fh */ | ||
183 | {X86_VENDOR_AMD, 0x10, ANY, ANY, 25}, /* NPT family 10h */ | 188 | {X86_VENDOR_AMD, 0x10, ANY, ANY, 25}, /* NPT family 10h */ |
189 | |||
184 | {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ | 190 | {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ |
185 | {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ | 191 | {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ |
186 | {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ | 192 | {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ |
@@ -191,12 +197,14 @@ static struct vrm_model vrm_models[] = { | |||
191 | {X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */ | 197 | {X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */ |
192 | {X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */ | 198 | {X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */ |
193 | {X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */ | 199 | {X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */ |
200 | |||
194 | {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */ | 201 | {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */ |
195 | {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */ | 202 | {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */ |
196 | {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */ | 203 | {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */ |
197 | {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */ | 204 | {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */ |
198 | {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */ | 205 | {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */ |
199 | {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */ | 206 | {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */ |
207 | |||
200 | {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ | 208 | {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ |
201 | }; | 209 | }; |
202 | 210 | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 9157247fed8e..ffeb2a10e1a7 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include <linux/string.h> | 50 | #include <linux/string.h> |
51 | #include <linux/dmi.h> | 51 | #include <linux/dmi.h> |
52 | #include <linux/acpi.h> | 52 | #include <linux/acpi.h> |
53 | #include <asm/io.h> | 53 | #include <linux/io.h> |
54 | 54 | ||
55 | #define DRVNAME "it87" | 55 | #define DRVNAME "it87" |
56 | 56 | ||
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index a1787fdf5b9f..f7e70163e016 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/hwmon-sysfs.h> | 31 | #include <linux/hwmon-sysfs.h> |
32 | #include <linux/err.h> | 32 | #include <linux/err.h> |
33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
34 | #include <asm/io.h> | 34 | #include <linux/io.h> |
35 | 35 | ||
36 | /* ISA device, if found */ | 36 | /* ISA device, if found */ |
37 | static struct platform_device *pdev; | 37 | static struct platform_device *pdev; |
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index b251d8674b41..6c53d987de10 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -75,6 +75,8 @@ I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100, | |||
75 | #define LM85_VERSTEP_GENERIC2 0x70 | 75 | #define LM85_VERSTEP_GENERIC2 0x70 |
76 | #define LM85_VERSTEP_LM85C 0x60 | 76 | #define LM85_VERSTEP_LM85C 0x60 |
77 | #define LM85_VERSTEP_LM85B 0x62 | 77 | #define LM85_VERSTEP_LM85B 0x62 |
78 | #define LM85_VERSTEP_LM96000_1 0x68 | ||
79 | #define LM85_VERSTEP_LM96000_2 0x69 | ||
78 | #define LM85_VERSTEP_ADM1027 0x60 | 80 | #define LM85_VERSTEP_ADM1027 0x60 |
79 | #define LM85_VERSTEP_ADT7463 0x62 | 81 | #define LM85_VERSTEP_ADT7463 0x62 |
80 | #define LM85_VERSTEP_ADT7463C 0x6A | 82 | #define LM85_VERSTEP_ADT7463C 0x6A |
@@ -1133,6 +1135,26 @@ static void lm85_init_client(struct i2c_client *client) | |||
1133 | dev_warn(&client->dev, "Device is not ready\n"); | 1135 | dev_warn(&client->dev, "Device is not ready\n"); |
1134 | } | 1136 | } |
1135 | 1137 | ||
1138 | static int lm85_is_fake(struct i2c_client *client) | ||
1139 | { | ||
1140 | /* | ||
1141 | * Differenciate between real LM96000 and Winbond WPCD377I. The latter | ||
1142 | * emulate the former except that it has no hardware monitoring function | ||
1143 | * so the readings are always 0. | ||
1144 | */ | ||
1145 | int i; | ||
1146 | u8 in_temp, fan; | ||
1147 | |||
1148 | for (i = 0; i < 8; i++) { | ||
1149 | in_temp = i2c_smbus_read_byte_data(client, 0x20 + i); | ||
1150 | fan = i2c_smbus_read_byte_data(client, 0x28 + i); | ||
1151 | if (in_temp != 0x00 || fan != 0xff) | ||
1152 | return 0; | ||
1153 | } | ||
1154 | |||
1155 | return 1; | ||
1156 | } | ||
1157 | |||
1136 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 1158 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1137 | static int lm85_detect(struct i2c_client *client, int kind, | 1159 | static int lm85_detect(struct i2c_client *client, int kind, |
1138 | struct i2c_board_info *info) | 1160 | struct i2c_board_info *info) |
@@ -1173,6 +1195,16 @@ static int lm85_detect(struct i2c_client *client, int kind, | |||
1173 | case LM85_VERSTEP_LM85B: | 1195 | case LM85_VERSTEP_LM85B: |
1174 | kind = lm85b; | 1196 | kind = lm85b; |
1175 | break; | 1197 | break; |
1198 | case LM85_VERSTEP_LM96000_1: | ||
1199 | case LM85_VERSTEP_LM96000_2: | ||
1200 | /* Check for Winbond WPCD377I */ | ||
1201 | if (lm85_is_fake(client)) { | ||
1202 | dev_dbg(&adapter->dev, | ||
1203 | "Found Winbond WPCD377I, " | ||
1204 | "ignoring\n"); | ||
1205 | return -ENODEV; | ||
1206 | } | ||
1207 | break; | ||
1176 | } | 1208 | } |
1177 | } else if (company == LM85_COMPANY_ANALOG_DEV) { | 1209 | } else if (company == LM85_COMPANY_ANALOG_DEV) { |
1178 | switch (verstep) { | 1210 | switch (verstep) { |
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index fb052fea3744..4a64b85d4ec9 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #include <linux/err.h> | 44 | #include <linux/err.h> |
45 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
46 | #include <linux/acpi.h> | 46 | #include <linux/acpi.h> |
47 | #include <asm/io.h> | 47 | #include <linux/io.h> |
48 | 48 | ||
49 | static u8 devid; | 49 | static u8 devid; |
50 | static struct platform_device *pdev; | 50 | static struct platform_device *pdev; |
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 3a8a0f7a7736..3170b26d2443 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/sysfs.h> | 33 | #include <linux/sysfs.h> |
34 | #include <linux/ioport.h> | 34 | #include <linux/ioport.h> |
35 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
36 | #include <asm/io.h> | 36 | #include <linux/io.h> |
37 | 37 | ||
38 | static unsigned short force_id; | 38 | static unsigned short force_id; |
39 | module_param(force_id, ushort, 0); | 39 | module_param(force_id, ushort, 0); |
@@ -435,7 +435,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev) | |||
435 | /* This will need to be revisited when we add support for | 435 | /* This will need to be revisited when we add support for |
436 | temperature and voltage monitoring. */ | 436 | temperature and voltage monitoring. */ |
437 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 437 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
438 | if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) { | 438 | if (!request_region(res->start, resource_size(res), DRVNAME)) { |
439 | err = -EBUSY; | 439 | err = -EBUSY; |
440 | dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", | 440 | dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", |
441 | (unsigned long)res->start, (unsigned long)res->end); | 441 | (unsigned long)res->start, (unsigned long)res->end); |
@@ -475,7 +475,7 @@ exit_remove_files: | |||
475 | sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); | 475 | sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); |
476 | } | 476 | } |
477 | exit_release_region: | 477 | exit_release_region: |
478 | release_region(res->start, res->end - res->start + 1); | 478 | release_region(res->start, resource_size(res)); |
479 | exit_kfree: | 479 | exit_kfree: |
480 | platform_set_drvdata(pdev, NULL); | 480 | platform_set_drvdata(pdev, NULL); |
481 | kfree(data); | 481 | kfree(data); |
@@ -500,7 +500,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev) | |||
500 | kfree(data); | 500 | kfree(data); |
501 | 501 | ||
502 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 502 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
503 | release_region(res->start, res->end - res->start + 1); | 503 | release_region(res->start, resource_size(res)); |
504 | 504 | ||
505 | return 0; | 505 | return 0; |
506 | } | 506 | } |
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c new file mode 100644 index 000000000000..3a524f2fe493 --- /dev/null +++ b/drivers/hwmon/s3c-hwmon.c | |||
@@ -0,0 +1,405 @@ | |||
1 | /* linux/drivers/hwmon/s3c-hwmon.c | ||
2 | * | ||
3 | * Copyright (C) 2005, 2008, 2009 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C24XX/S3C64XX ADC hwmon support | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/err.h> | ||
29 | #include <linux/clk.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | |||
33 | #include <linux/hwmon.h> | ||
34 | #include <linux/hwmon-sysfs.h> | ||
35 | |||
36 | #include <plat/adc.h> | ||
37 | #include <plat/hwmon.h> | ||
38 | |||
39 | struct s3c_hwmon_attr { | ||
40 | struct sensor_device_attribute in; | ||
41 | struct sensor_device_attribute label; | ||
42 | char in_name[12]; | ||
43 | char label_name[12]; | ||
44 | }; | ||
45 | |||
46 | /** | ||
47 | * struct s3c_hwmon - ADC hwmon client information | ||
48 | * @lock: Access lock to serialise the conversions. | ||
49 | * @client: The client we registered with the S3C ADC core. | ||
50 | * @hwmon_dev: The hwmon device we created. | ||
51 | * @attr: The holders for the channel attributes. | ||
52 | */ | ||
53 | struct s3c_hwmon { | ||
54 | struct semaphore lock; | ||
55 | struct s3c_adc_client *client; | ||
56 | struct device *hwmon_dev; | ||
57 | |||
58 | struct s3c_hwmon_attr attrs[8]; | ||
59 | }; | ||
60 | |||
61 | /** | ||
62 | * s3c_hwmon_read_ch - read a value from a given adc channel. | ||
63 | * @dev: The device. | ||
64 | * @hwmon: Our state. | ||
65 | * @channel: The channel we're reading from. | ||
66 | * | ||
67 | * Read a value from the @channel with the proper locking and sleep until | ||
68 | * either the read completes or we timeout awaiting the ADC core to get | ||
69 | * back to us. | ||
70 | */ | ||
71 | static int s3c_hwmon_read_ch(struct device *dev, | ||
72 | struct s3c_hwmon *hwmon, int channel) | ||
73 | { | ||
74 | int ret; | ||
75 | |||
76 | ret = down_interruptible(&hwmon->lock); | ||
77 | if (ret < 0) | ||
78 | return ret; | ||
79 | |||
80 | dev_dbg(dev, "reading channel %d\n", channel); | ||
81 | |||
82 | ret = s3c_adc_read(hwmon->client, channel); | ||
83 | up(&hwmon->lock); | ||
84 | |||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | #ifdef CONFIG_SENSORS_S3C_RAW | ||
89 | /** | ||
90 | * s3c_hwmon_show_raw - show a conversion from the raw channel number. | ||
91 | * @dev: The device that the attribute belongs to. | ||
92 | * @attr: The attribute being read. | ||
93 | * @buf: The result buffer. | ||
94 | * | ||
95 | * This show deals with the raw attribute, registered for each possible | ||
96 | * ADC channel. This does a conversion and returns the raw (un-scaled) | ||
97 | * value returned from the hardware. | ||
98 | */ | ||
99 | static ssize_t s3c_hwmon_show_raw(struct device *dev, | ||
100 | struct device_attribute *attr, char *buf) | ||
101 | { | ||
102 | struct s3c_hwmon *adc = platform_get_drvdata(to_platform_device(dev)); | ||
103 | struct sensor_device_attribute *sa = to_sensor_dev_attr(attr); | ||
104 | int ret; | ||
105 | |||
106 | ret = s3c_hwmon_read_ch(dev, adc, sa->index); | ||
107 | |||
108 | return (ret < 0) ? ret : snprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
109 | } | ||
110 | |||
111 | #define DEF_ADC_ATTR(x) \ | ||
112 | static SENSOR_DEVICE_ATTR(adc##x##_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, x) | ||
113 | |||
114 | DEF_ADC_ATTR(0); | ||
115 | DEF_ADC_ATTR(1); | ||
116 | DEF_ADC_ATTR(2); | ||
117 | DEF_ADC_ATTR(3); | ||
118 | DEF_ADC_ATTR(4); | ||
119 | DEF_ADC_ATTR(5); | ||
120 | DEF_ADC_ATTR(6); | ||
121 | DEF_ADC_ATTR(7); | ||
122 | |||
123 | static struct attribute *s3c_hwmon_attrs[9] = { | ||
124 | &sensor_dev_attr_adc0_raw.dev_attr.attr, | ||
125 | &sensor_dev_attr_adc1_raw.dev_attr.attr, | ||
126 | &sensor_dev_attr_adc2_raw.dev_attr.attr, | ||
127 | &sensor_dev_attr_adc3_raw.dev_attr.attr, | ||
128 | &sensor_dev_attr_adc4_raw.dev_attr.attr, | ||
129 | &sensor_dev_attr_adc5_raw.dev_attr.attr, | ||
130 | &sensor_dev_attr_adc6_raw.dev_attr.attr, | ||
131 | &sensor_dev_attr_adc7_raw.dev_attr.attr, | ||
132 | NULL, | ||
133 | }; | ||
134 | |||
135 | static struct attribute_group s3c_hwmon_attrgroup = { | ||
136 | .attrs = s3c_hwmon_attrs, | ||
137 | }; | ||
138 | |||
139 | static inline int s3c_hwmon_add_raw(struct device *dev) | ||
140 | { | ||
141 | return sysfs_create_group(&dev->kobj, &s3c_hwmon_attrgroup); | ||
142 | } | ||
143 | |||
144 | static inline void s3c_hwmon_remove_raw(struct device *dev) | ||
145 | { | ||
146 | sysfs_remove_group(&dev->kobj, &s3c_hwmon_attrgroup); | ||
147 | } | ||
148 | |||
149 | #else | ||
150 | |||
151 | static inline int s3c_hwmon_add_raw(struct device *dev) { return 0; } | ||
152 | static inline void s3c_hwmon_remove_raw(struct device *dev) { } | ||
153 | |||
154 | #endif /* CONFIG_SENSORS_S3C_RAW */ | ||
155 | |||
156 | /** | ||
157 | * s3c_hwmon_ch_show - show value of a given channel | ||
158 | * @dev: The device that the attribute belongs to. | ||
159 | * @attr: The attribute being read. | ||
160 | * @buf: The result buffer. | ||
161 | * | ||
162 | * Read a value from the ADC and scale it before returning it to the | ||
163 | * caller. The scale factor is gained from the channel configuration | ||
164 | * passed via the platform data when the device was registered. | ||
165 | */ | ||
166 | static ssize_t s3c_hwmon_ch_show(struct device *dev, | ||
167 | struct device_attribute *attr, | ||
168 | char *buf) | ||
169 | { | ||
170 | struct sensor_device_attribute *sen_attr = to_sensor_dev_attr(attr); | ||
171 | struct s3c_hwmon *hwmon = platform_get_drvdata(to_platform_device(dev)); | ||
172 | struct s3c_hwmon_pdata *pdata = dev->platform_data; | ||
173 | struct s3c_hwmon_chcfg *cfg; | ||
174 | int ret; | ||
175 | |||
176 | cfg = pdata->in[sen_attr->index]; | ||
177 | |||
178 | ret = s3c_hwmon_read_ch(dev, hwmon, sen_attr->index); | ||
179 | if (ret < 0) | ||
180 | return ret; | ||
181 | |||
182 | ret *= cfg->mult; | ||
183 | ret = DIV_ROUND_CLOSEST(ret, cfg->div); | ||
184 | |||
185 | return snprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * s3c_hwmon_label_show - show label name of the given channel. | ||
190 | * @dev: The device that the attribute belongs to. | ||
191 | * @attr: The attribute being read. | ||
192 | * @buf: The result buffer. | ||
193 | * | ||
194 | * Return the label name of a given channel | ||
195 | */ | ||
196 | static ssize_t s3c_hwmon_label_show(struct device *dev, | ||
197 | struct device_attribute *attr, | ||
198 | char *buf) | ||
199 | { | ||
200 | struct sensor_device_attribute *sen_attr = to_sensor_dev_attr(attr); | ||
201 | struct s3c_hwmon_pdata *pdata = dev->platform_data; | ||
202 | struct s3c_hwmon_chcfg *cfg; | ||
203 | |||
204 | cfg = pdata->in[sen_attr->index]; | ||
205 | |||
206 | return snprintf(buf, PAGE_SIZE, "%s\n", cfg->name); | ||
207 | } | ||
208 | |||
209 | /** | ||
210 | * s3c_hwmon_create_attr - create hwmon attribute for given channel. | ||
211 | * @dev: The device to create the attribute on. | ||
212 | * @cfg: The channel configuration passed from the platform data. | ||
213 | * @channel: The ADC channel number to process. | ||
214 | * | ||
215 | * Create the scaled attribute for use with hwmon from the specified | ||
216 | * platform data in @pdata. The sysfs entry is handled by the routine | ||
217 | * s3c_hwmon_ch_show(). | ||
218 | * | ||
219 | * The attribute name is taken from the configuration data if present | ||
220 | * otherwise the name is taken by concatenating in_ with the channel | ||
221 | * number. | ||
222 | */ | ||
223 | static int s3c_hwmon_create_attr(struct device *dev, | ||
224 | struct s3c_hwmon_chcfg *cfg, | ||
225 | struct s3c_hwmon_attr *attrs, | ||
226 | int channel) | ||
227 | { | ||
228 | struct sensor_device_attribute *attr; | ||
229 | int ret; | ||
230 | |||
231 | snprintf(attrs->in_name, sizeof(attrs->in_name), "in%d_input", channel); | ||
232 | |||
233 | attr = &attrs->in; | ||
234 | attr->index = channel; | ||
235 | attr->dev_attr.attr.name = attrs->in_name; | ||
236 | attr->dev_attr.attr.mode = S_IRUGO; | ||
237 | attr->dev_attr.attr.owner = THIS_MODULE; | ||
238 | attr->dev_attr.show = s3c_hwmon_ch_show; | ||
239 | |||
240 | ret = device_create_file(dev, &attr->dev_attr); | ||
241 | if (ret < 0) { | ||
242 | dev_err(dev, "failed to create input attribute\n"); | ||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | /* if this has a name, add a label */ | ||
247 | if (cfg->name) { | ||
248 | snprintf(attrs->label_name, sizeof(attrs->label_name), | ||
249 | "in%d_label", channel); | ||
250 | |||
251 | attr = &attrs->label; | ||
252 | attr->index = channel; | ||
253 | attr->dev_attr.attr.name = attrs->label_name; | ||
254 | attr->dev_attr.attr.mode = S_IRUGO; | ||
255 | attr->dev_attr.attr.owner = THIS_MODULE; | ||
256 | attr->dev_attr.show = s3c_hwmon_label_show; | ||
257 | |||
258 | ret = device_create_file(dev, &attr->dev_attr); | ||
259 | if (ret < 0) { | ||
260 | device_remove_file(dev, &attrs->in.dev_attr); | ||
261 | dev_err(dev, "failed to create label attribute\n"); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | static void s3c_hwmon_remove_attr(struct device *dev, | ||
269 | struct s3c_hwmon_attr *attrs) | ||
270 | { | ||
271 | device_remove_file(dev, &attrs->in.dev_attr); | ||
272 | device_remove_file(dev, &attrs->label.dev_attr); | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | * s3c_hwmon_probe - device probe entry. | ||
277 | * @dev: The device being probed. | ||
278 | */ | ||
279 | static int __devinit s3c_hwmon_probe(struct platform_device *dev) | ||
280 | { | ||
281 | struct s3c_hwmon_pdata *pdata = dev->dev.platform_data; | ||
282 | struct s3c_hwmon *hwmon; | ||
283 | int ret = 0; | ||
284 | int i; | ||
285 | |||
286 | if (!pdata) { | ||
287 | dev_err(&dev->dev, "no platform data supplied\n"); | ||
288 | return -EINVAL; | ||
289 | } | ||
290 | |||
291 | hwmon = kzalloc(sizeof(struct s3c_hwmon), GFP_KERNEL); | ||
292 | if (hwmon == NULL) { | ||
293 | dev_err(&dev->dev, "no memory\n"); | ||
294 | return -ENOMEM; | ||
295 | } | ||
296 | |||
297 | platform_set_drvdata(dev, hwmon); | ||
298 | |||
299 | init_MUTEX(&hwmon->lock); | ||
300 | |||
301 | /* Register with the core ADC driver. */ | ||
302 | |||
303 | hwmon->client = s3c_adc_register(dev, NULL, NULL, 0); | ||
304 | if (IS_ERR(hwmon->client)) { | ||
305 | dev_err(&dev->dev, "cannot register adc\n"); | ||
306 | ret = PTR_ERR(hwmon->client); | ||
307 | goto err_mem; | ||
308 | } | ||
309 | |||
310 | /* add attributes for our adc devices. */ | ||
311 | |||
312 | ret = s3c_hwmon_add_raw(&dev->dev); | ||
313 | if (ret) | ||
314 | goto err_registered; | ||
315 | |||
316 | /* register with the hwmon core */ | ||
317 | |||
318 | hwmon->hwmon_dev = hwmon_device_register(&dev->dev); | ||
319 | if (IS_ERR(hwmon->hwmon_dev)) { | ||
320 | dev_err(&dev->dev, "error registering with hwmon\n"); | ||
321 | ret = PTR_ERR(hwmon->hwmon_dev); | ||
322 | goto err_raw_attribute; | ||
323 | } | ||
324 | |||
325 | for (i = 0; i < ARRAY_SIZE(pdata->in); i++) { | ||
326 | if (!pdata->in[i]) | ||
327 | continue; | ||
328 | |||
329 | if (pdata->in[i]->mult >= 0x10000) | ||
330 | dev_warn(&dev->dev, | ||
331 | "channel %d multiplier too large\n", | ||
332 | i); | ||
333 | |||
334 | ret = s3c_hwmon_create_attr(&dev->dev, pdata->in[i], | ||
335 | &hwmon->attrs[i], i); | ||
336 | if (ret) { | ||
337 | dev_err(&dev->dev, | ||
338 | "error creating channel %d\n", i); | ||
339 | |||
340 | for (i--; i >= 0; i--) | ||
341 | s3c_hwmon_remove_attr(&dev->dev, | ||
342 | &hwmon->attrs[i]); | ||
343 | |||
344 | goto err_hwmon_register; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | return 0; | ||
349 | |||
350 | err_hwmon_register: | ||
351 | hwmon_device_unregister(hwmon->hwmon_dev); | ||
352 | |||
353 | err_raw_attribute: | ||
354 | s3c_hwmon_remove_raw(&dev->dev); | ||
355 | |||
356 | err_registered: | ||
357 | s3c_adc_release(hwmon->client); | ||
358 | |||
359 | err_mem: | ||
360 | kfree(hwmon); | ||
361 | return ret; | ||
362 | } | ||
363 | |||
364 | static int __devexit s3c_hwmon_remove(struct platform_device *dev) | ||
365 | { | ||
366 | struct s3c_hwmon *hwmon = platform_get_drvdata(dev); | ||
367 | int i; | ||
368 | |||
369 | s3c_hwmon_remove_raw(&dev->dev); | ||
370 | |||
371 | for (i = 0; i < ARRAY_SIZE(hwmon->attrs); i++) | ||
372 | s3c_hwmon_remove_attr(&dev->dev, &hwmon->attrs[i]); | ||
373 | |||
374 | hwmon_device_unregister(hwmon->hwmon_dev); | ||
375 | s3c_adc_release(hwmon->client); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static struct platform_driver s3c_hwmon_driver = { | ||
381 | .driver = { | ||
382 | .name = "s3c-hwmon", | ||
383 | .owner = THIS_MODULE, | ||
384 | }, | ||
385 | .probe = s3c_hwmon_probe, | ||
386 | .remove = __devexit_p(s3c_hwmon_remove), | ||
387 | }; | ||
388 | |||
389 | static int __init s3c_hwmon_init(void) | ||
390 | { | ||
391 | return platform_driver_register(&s3c_hwmon_driver); | ||
392 | } | ||
393 | |||
394 | static void __exit s3c_hwmon_exit(void) | ||
395 | { | ||
396 | platform_driver_unregister(&s3c_hwmon_driver); | ||
397 | } | ||
398 | |||
399 | module_init(s3c_hwmon_init); | ||
400 | module_exit(s3c_hwmon_exit); | ||
401 | |||
402 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
403 | MODULE_DESCRIPTION("S3C ADC HWMon driver"); | ||
404 | MODULE_LICENSE("GPL v2"); | ||
405 | MODULE_ALIAS("platform:s3c-hwmon"); | ||
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index aa2e8318f167..12f2e7086560 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
@@ -63,7 +63,7 @@ | |||
63 | #include <linux/mutex.h> | 63 | #include <linux/mutex.h> |
64 | #include <linux/sysfs.h> | 64 | #include <linux/sysfs.h> |
65 | #include <linux/acpi.h> | 65 | #include <linux/acpi.h> |
66 | #include <asm/io.h> | 66 | #include <linux/io.h> |
67 | 67 | ||
68 | 68 | ||
69 | /* If force_addr is set to anything different from 0, we forcibly enable | 69 | /* If force_addr is set to anything different from 0, we forcibly enable |
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 6f6d52b4fb64..f46d936c12da 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/acpi.h> | 39 | #include <linux/acpi.h> |
40 | #include <asm/io.h> | 40 | #include <linux/io.h> |
41 | 41 | ||
42 | static unsigned short force_id; | 42 | static unsigned short force_id; |
43 | module_param(force_id, ushort, 0); | 43 | module_param(force_id, ushort, 0); |
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index ba75bfcf14ce..8ad50fdba00d 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/sysfs.h> | 39 | #include <linux/sysfs.h> |
40 | #include <linux/acpi.h> | 40 | #include <linux/acpi.h> |
41 | #include <asm/io.h> | 41 | #include <linux/io.h> |
42 | 42 | ||
43 | static unsigned short force_id; | 43 | static unsigned short force_id; |
44 | module_param(force_id, ushort, 0); | 44 | module_param(force_id, ushort, 0); |
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c new file mode 100644 index 000000000000..20924343431b --- /dev/null +++ b/drivers/hwmon/tmp421.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* tmp421.c | ||
2 | * | ||
3 | * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de> | ||
4 | * Preliminary support by: | ||
5 | * Melvin Rook, Raymond Ng | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Driver for the Texas Instruments TMP421 SMBus temperature sensor IC. | ||
24 | * Supported models: TMP421, TMP422, TMP423 | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/jiffies.h> | ||
31 | #include <linux/i2c.h> | ||
32 | #include <linux/hwmon.h> | ||
33 | #include <linux/hwmon-sysfs.h> | ||
34 | #include <linux/err.h> | ||
35 | #include <linux/mutex.h> | ||
36 | #include <linux/sysfs.h> | ||
37 | |||
38 | /* Addresses to scan */ | ||
39 | static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f, | ||
40 | I2C_CLIENT_END }; | ||
41 | |||
42 | /* Insmod parameters */ | ||
43 | I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423); | ||
44 | |||
45 | /* The TMP421 registers */ | ||
46 | #define TMP421_CONFIG_REG_1 0x09 | ||
47 | #define TMP421_CONVERSION_RATE_REG 0x0B | ||
48 | #define TMP421_MANUFACTURER_ID_REG 0xFE | ||
49 | #define TMP421_DEVICE_ID_REG 0xFF | ||
50 | |||
51 | static const u8 TMP421_TEMP_MSB[4] = { 0x00, 0x01, 0x02, 0x03 }; | ||
52 | static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 }; | ||
53 | |||
54 | /* Flags */ | ||
55 | #define TMP421_CONFIG_SHUTDOWN 0x40 | ||
56 | #define TMP421_CONFIG_RANGE 0x04 | ||
57 | |||
58 | /* Manufacturer / Device ID's */ | ||
59 | #define TMP421_MANUFACTURER_ID 0x55 | ||
60 | #define TMP421_DEVICE_ID 0x21 | ||
61 | #define TMP422_DEVICE_ID 0x22 | ||
62 | #define TMP423_DEVICE_ID 0x23 | ||
63 | |||
64 | static const struct i2c_device_id tmp421_id[] = { | ||
65 | { "tmp421", tmp421 }, | ||
66 | { "tmp422", tmp422 }, | ||
67 | { "tmp423", tmp423 }, | ||
68 | { } | ||
69 | }; | ||
70 | MODULE_DEVICE_TABLE(i2c, tmp421_id); | ||
71 | |||
72 | struct tmp421_data { | ||
73 | struct device *hwmon_dev; | ||
74 | struct mutex update_lock; | ||
75 | char valid; | ||
76 | unsigned long last_updated; | ||
77 | int kind; | ||
78 | u8 config; | ||
79 | s16 temp[4]; | ||
80 | }; | ||
81 | |||
82 | static int temp_from_s16(s16 reg) | ||
83 | { | ||
84 | int temp = reg; | ||
85 | |||
86 | return (temp * 1000 + 128) / 256; | ||
87 | } | ||
88 | |||
89 | static int temp_from_u16(u16 reg) | ||
90 | { | ||
91 | int temp = reg; | ||
92 | |||
93 | /* Add offset for extended temperature range. */ | ||
94 | temp -= 64 * 256; | ||
95 | |||
96 | return (temp * 1000 + 128) / 256; | ||
97 | } | ||
98 | |||
99 | static struct tmp421_data *tmp421_update_device(struct device *dev) | ||
100 | { | ||
101 | struct i2c_client *client = to_i2c_client(dev); | ||
102 | struct tmp421_data *data = i2c_get_clientdata(client); | ||
103 | int i; | ||
104 | |||
105 | mutex_lock(&data->update_lock); | ||
106 | |||
107 | if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { | ||
108 | data->config = i2c_smbus_read_byte_data(client, | ||
109 | TMP421_CONFIG_REG_1); | ||
110 | |||
111 | for (i = 0; i <= data->kind; i++) { | ||
112 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
113 | TMP421_TEMP_MSB[i]) << 8; | ||
114 | data->temp[i] |= i2c_smbus_read_byte_data(client, | ||
115 | TMP421_TEMP_LSB[i]); | ||
116 | } | ||
117 | data->last_updated = jiffies; | ||
118 | data->valid = 1; | ||
119 | } | ||
120 | |||
121 | mutex_unlock(&data->update_lock); | ||
122 | |||
123 | return data; | ||
124 | } | ||
125 | |||
126 | static ssize_t show_temp_value(struct device *dev, | ||
127 | struct device_attribute *devattr, char *buf) | ||
128 | { | ||
129 | int index = to_sensor_dev_attr(devattr)->index; | ||
130 | struct tmp421_data *data = tmp421_update_device(dev); | ||
131 | int temp; | ||
132 | |||
133 | mutex_lock(&data->update_lock); | ||
134 | if (data->config & TMP421_CONFIG_RANGE) | ||
135 | temp = temp_from_u16(data->temp[index]); | ||
136 | else | ||
137 | temp = temp_from_s16(data->temp[index]); | ||
138 | mutex_unlock(&data->update_lock); | ||
139 | |||
140 | return sprintf(buf, "%d\n", temp); | ||
141 | } | ||
142 | |||
143 | static ssize_t show_fault(struct device *dev, | ||
144 | struct device_attribute *devattr, char *buf) | ||
145 | { | ||
146 | int index = to_sensor_dev_attr(devattr)->index; | ||
147 | struct tmp421_data *data = tmp421_update_device(dev); | ||
148 | |||
149 | /* | ||
150 | * The OPEN bit signals a fault. This is bit 0 of the temperature | ||
151 | * register (low byte). | ||
152 | */ | ||
153 | if (data->temp[index] & 0x01) | ||
154 | return sprintf(buf, "1\n"); | ||
155 | else | ||
156 | return sprintf(buf, "0\n"); | ||
157 | } | ||
158 | |||
159 | static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, | ||
160 | int n) | ||
161 | { | ||
162 | struct device *dev = container_of(kobj, struct device, kobj); | ||
163 | struct tmp421_data *data = dev_get_drvdata(dev); | ||
164 | struct device_attribute *devattr; | ||
165 | unsigned int index; | ||
166 | |||
167 | devattr = container_of(a, struct device_attribute, attr); | ||
168 | index = to_sensor_dev_attr(devattr)->index; | ||
169 | |||
170 | if (data->kind > index) | ||
171 | return a->mode; | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0); | ||
177 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1); | ||
178 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1); | ||
179 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2); | ||
180 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2); | ||
181 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3); | ||
182 | static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3); | ||
183 | |||
184 | static struct attribute *tmp421_attr[] = { | ||
185 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
186 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
187 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
188 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
189 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
190 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
191 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | ||
192 | NULL | ||
193 | }; | ||
194 | |||
195 | static const struct attribute_group tmp421_group = { | ||
196 | .attrs = tmp421_attr, | ||
197 | .is_visible = tmp421_is_visible, | ||
198 | }; | ||
199 | |||
200 | static int tmp421_init_client(struct i2c_client *client) | ||
201 | { | ||
202 | int config, config_orig; | ||
203 | |||
204 | /* Set the conversion rate to 2 Hz */ | ||
205 | i2c_smbus_write_byte_data(client, TMP421_CONVERSION_RATE_REG, 0x05); | ||
206 | |||
207 | /* Start conversions (disable shutdown if necessary) */ | ||
208 | config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1); | ||
209 | if (config < 0) { | ||
210 | dev_err(&client->dev, "Could not read configuration" | ||
211 | " register (%d)\n", config); | ||
212 | return -ENODEV; | ||
213 | } | ||
214 | |||
215 | config_orig = config; | ||
216 | config &= ~TMP421_CONFIG_SHUTDOWN; | ||
217 | |||
218 | if (config != config_orig) { | ||
219 | dev_info(&client->dev, "Enable monitoring chip\n"); | ||
220 | i2c_smbus_write_byte_data(client, TMP421_CONFIG_REG_1, config); | ||
221 | } | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int tmp421_detect(struct i2c_client *client, int kind, | ||
227 | struct i2c_board_info *info) | ||
228 | { | ||
229 | struct i2c_adapter *adapter = client->adapter; | ||
230 | const char *names[] = { "TMP421", "TMP422", "TMP423" }; | ||
231 | |||
232 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
233 | return -ENODEV; | ||
234 | |||
235 | if (kind <= 0) { | ||
236 | u8 reg; | ||
237 | |||
238 | reg = i2c_smbus_read_byte_data(client, | ||
239 | TMP421_MANUFACTURER_ID_REG); | ||
240 | if (reg != TMP421_MANUFACTURER_ID) | ||
241 | return -ENODEV; | ||
242 | |||
243 | reg = i2c_smbus_read_byte_data(client, | ||
244 | TMP421_DEVICE_ID_REG); | ||
245 | switch (reg) { | ||
246 | case TMP421_DEVICE_ID: | ||
247 | kind = tmp421; | ||
248 | break; | ||
249 | case TMP422_DEVICE_ID: | ||
250 | kind = tmp422; | ||
251 | break; | ||
252 | case TMP423_DEVICE_ID: | ||
253 | kind = tmp423; | ||
254 | break; | ||
255 | default: | ||
256 | return -ENODEV; | ||
257 | } | ||
258 | } | ||
259 | strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE); | ||
260 | dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n", | ||
261 | names[kind - 1], client->addr); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int tmp421_probe(struct i2c_client *client, | ||
267 | const struct i2c_device_id *id) | ||
268 | { | ||
269 | struct tmp421_data *data; | ||
270 | int err; | ||
271 | |||
272 | data = kzalloc(sizeof(struct tmp421_data), GFP_KERNEL); | ||
273 | if (!data) | ||
274 | return -ENOMEM; | ||
275 | |||
276 | i2c_set_clientdata(client, data); | ||
277 | mutex_init(&data->update_lock); | ||
278 | data->kind = id->driver_data; | ||
279 | |||
280 | err = tmp421_init_client(client); | ||
281 | if (err) | ||
282 | goto exit_free; | ||
283 | |||
284 | err = sysfs_create_group(&client->dev.kobj, &tmp421_group); | ||
285 | if (err) | ||
286 | goto exit_free; | ||
287 | |||
288 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
289 | if (IS_ERR(data->hwmon_dev)) { | ||
290 | err = PTR_ERR(data->hwmon_dev); | ||
291 | data->hwmon_dev = NULL; | ||
292 | goto exit_remove; | ||
293 | } | ||
294 | return 0; | ||
295 | |||
296 | exit_remove: | ||
297 | sysfs_remove_group(&client->dev.kobj, &tmp421_group); | ||
298 | |||
299 | exit_free: | ||
300 | i2c_set_clientdata(client, NULL); | ||
301 | kfree(data); | ||
302 | |||
303 | return err; | ||
304 | } | ||
305 | |||
306 | static int tmp421_remove(struct i2c_client *client) | ||
307 | { | ||
308 | struct tmp421_data *data = i2c_get_clientdata(client); | ||
309 | |||
310 | hwmon_device_unregister(data->hwmon_dev); | ||
311 | sysfs_remove_group(&client->dev.kobj, &tmp421_group); | ||
312 | |||
313 | i2c_set_clientdata(client, NULL); | ||
314 | kfree(data); | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static struct i2c_driver tmp421_driver = { | ||
320 | .class = I2C_CLASS_HWMON, | ||
321 | .driver = { | ||
322 | .name = "tmp421", | ||
323 | }, | ||
324 | .probe = tmp421_probe, | ||
325 | .remove = tmp421_remove, | ||
326 | .id_table = tmp421_id, | ||
327 | .detect = tmp421_detect, | ||
328 | .address_data = &addr_data, | ||
329 | }; | ||
330 | |||
331 | static int __init tmp421_init(void) | ||
332 | { | ||
333 | return i2c_add_driver(&tmp421_driver); | ||
334 | } | ||
335 | |||
336 | static void __exit tmp421_exit(void) | ||
337 | { | ||
338 | i2c_del_driver(&tmp421_driver); | ||
339 | } | ||
340 | |||
341 | MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>"); | ||
342 | MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor" | ||
343 | " driver"); | ||
344 | MODULE_LICENSE("GPL"); | ||
345 | |||
346 | module_init(tmp421_init); | ||
347 | module_exit(tmp421_exit); | ||
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index a022aedcaacb..39e82a492f26 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
43 | #include <linux/sysfs.h> | 43 | #include <linux/sysfs.h> |
44 | #include <linux/acpi.h> | 44 | #include <linux/acpi.h> |
45 | #include <asm/io.h> | 45 | #include <linux/io.h> |
46 | 46 | ||
47 | 47 | ||
48 | /* If force_addr is set to anything different from 0, we forcibly enable | 48 | /* If force_addr is set to anything different from 0, we forcibly enable |
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index 73f77a9b8b18..ae33bbb577c7 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
34 | #include <linux/ioport.h> | 34 | #include <linux/ioport.h> |
35 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
36 | #include <asm/io.h> | 36 | #include <linux/io.h> |
37 | 37 | ||
38 | static int uch_config = -1; | 38 | static int uch_config = -1; |
39 | module_param(uch_config, int, 0); | 39 | module_param(uch_config, int, 0); |
@@ -1136,7 +1136,7 @@ static int __devinit vt1211_probe(struct platform_device *pdev) | |||
1136 | } | 1136 | } |
1137 | 1137 | ||
1138 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1138 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1139 | if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) { | 1139 | if (!request_region(res->start, resource_size(res), DRVNAME)) { |
1140 | err = -EBUSY; | 1140 | err = -EBUSY; |
1141 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", | 1141 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", |
1142 | (unsigned long)res->start, (unsigned long)res->end); | 1142 | (unsigned long)res->start, (unsigned long)res->end); |
@@ -1209,7 +1209,7 @@ EXIT_DEV_REMOVE: | |||
1209 | dev_err(dev, "Sysfs interface creation failed (%d)\n", err); | 1209 | dev_err(dev, "Sysfs interface creation failed (%d)\n", err); |
1210 | EXIT_DEV_REMOVE_SILENT: | 1210 | EXIT_DEV_REMOVE_SILENT: |
1211 | vt1211_remove_sysfs(pdev); | 1211 | vt1211_remove_sysfs(pdev); |
1212 | release_region(res->start, res->end - res->start + 1); | 1212 | release_region(res->start, resource_size(res)); |
1213 | EXIT_KFREE: | 1213 | EXIT_KFREE: |
1214 | platform_set_drvdata(pdev, NULL); | 1214 | platform_set_drvdata(pdev, NULL); |
1215 | kfree(data); | 1215 | kfree(data); |
@@ -1228,7 +1228,7 @@ static int __devexit vt1211_remove(struct platform_device *pdev) | |||
1228 | kfree(data); | 1228 | kfree(data); |
1229 | 1229 | ||
1230 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1230 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1231 | release_region(res->start, res->end - res->start + 1); | 1231 | release_region(res->start, resource_size(res)); |
1232 | 1232 | ||
1233 | return 0; | 1233 | return 0; |
1234 | } | 1234 | } |
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 9982b45fbb14..470a1226ba2b 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/err.h> | 36 | #include <linux/err.h> |
37 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
38 | #include <linux/acpi.h> | 38 | #include <linux/acpi.h> |
39 | #include <asm/io.h> | 39 | #include <linux/io.h> |
40 | 40 | ||
41 | static int force_addr; | 41 | static int force_addr; |
42 | module_param(force_addr, int, 0); | 42 | module_param(force_addr, int, 0); |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 0e9746913d2b..bb5e78748783 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include <linux/err.h> | 51 | #include <linux/err.h> |
52 | #include <linux/mutex.h> | 52 | #include <linux/mutex.h> |
53 | #include <linux/acpi.h> | 53 | #include <linux/acpi.h> |
54 | #include <asm/io.h> | 54 | #include <linux/io.h> |
55 | #include "lm75.h" | 55 | #include "lm75.h" |
56 | 56 | ||
57 | enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg }; | 57 | enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg }; |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 389150ba30d3..2be28ac4ede0 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include <linux/mutex.h> | 51 | #include <linux/mutex.h> |
52 | #include <linux/ioport.h> | 52 | #include <linux/ioport.h> |
53 | #include <linux/acpi.h> | 53 | #include <linux/acpi.h> |
54 | #include <asm/io.h> | 54 | #include <linux/io.h> |
55 | #include "lm75.h" | 55 | #include "lm75.h" |
56 | 56 | ||
57 | static struct platform_device *pdev; | 57 | static struct platform_device *pdev; |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 0bdab959b736..d27ed1bac002 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #ifdef CONFIG_ISA | 48 | #ifdef CONFIG_ISA |
49 | #include <linux/platform_device.h> | 49 | #include <linux/platform_device.h> |
50 | #include <linux/ioport.h> | 50 | #include <linux/ioport.h> |
51 | #include <asm/io.h> | 51 | #include <linux/io.h> |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #include "lm75.h" | 54 | #include "lm75.h" |
diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c new file mode 100644 index 000000000000..c16e9e74c356 --- /dev/null +++ b/drivers/hwmon/wm831x-hwmon.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | * drivers/hwmon/wm831x-hwmon.c - Wolfson Microelectronics WM831x PMIC | ||
3 | * hardware monitoring features. | ||
4 | * | ||
5 | * Copyright (C) 2009 Wolfson Microelectronics plc | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License v2 as published by the | ||
9 | * Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/hwmon.h> | ||
26 | #include <linux/hwmon-sysfs.h> | ||
27 | |||
28 | #include <linux/mfd/wm831x/core.h> | ||
29 | #include <linux/mfd/wm831x/auxadc.h> | ||
30 | |||
31 | struct wm831x_hwmon { | ||
32 | struct wm831x *wm831x; | ||
33 | struct device *classdev; | ||
34 | }; | ||
35 | |||
36 | static ssize_t show_name(struct device *dev, | ||
37 | struct device_attribute *attr, char *buf) | ||
38 | { | ||
39 | return sprintf(buf, "wm831x\n"); | ||
40 | } | ||
41 | |||
42 | static const char *input_names[] = { | ||
43 | [WM831X_AUX_SYSVDD] = "SYSVDD", | ||
44 | [WM831X_AUX_USB] = "USB", | ||
45 | [WM831X_AUX_BKUP_BATT] = "Backup battery", | ||
46 | [WM831X_AUX_BATT] = "Battery", | ||
47 | [WM831X_AUX_WALL] = "WALL", | ||
48 | [WM831X_AUX_CHIP_TEMP] = "PMIC", | ||
49 | [WM831X_AUX_BATT_TEMP] = "Battery", | ||
50 | }; | ||
51 | |||
52 | |||
53 | static ssize_t show_voltage(struct device *dev, | ||
54 | struct device_attribute *attr, char *buf) | ||
55 | { | ||
56 | struct wm831x_hwmon *hwmon = dev_get_drvdata(dev); | ||
57 | int channel = to_sensor_dev_attr(attr)->index; | ||
58 | int ret; | ||
59 | |||
60 | ret = wm831x_auxadc_read_uv(hwmon->wm831x, channel); | ||
61 | if (ret < 0) | ||
62 | return ret; | ||
63 | |||
64 | return sprintf(buf, "%d\n", DIV_ROUND_CLOSEST(ret, 1000)); | ||
65 | } | ||
66 | |||
67 | static ssize_t show_chip_temp(struct device *dev, | ||
68 | struct device_attribute *attr, char *buf) | ||
69 | { | ||
70 | struct wm831x_hwmon *hwmon = dev_get_drvdata(dev); | ||
71 | int channel = to_sensor_dev_attr(attr)->index; | ||
72 | int ret; | ||
73 | |||
74 | ret = wm831x_auxadc_read(hwmon->wm831x, channel); | ||
75 | if (ret < 0) | ||
76 | return ret; | ||
77 | |||
78 | /* Degrees celsius = (512.18-ret) / 1.0983 */ | ||
79 | ret = 512180 - (ret * 1000); | ||
80 | ret = DIV_ROUND_CLOSEST(ret * 10000, 10983); | ||
81 | |||
82 | return sprintf(buf, "%d\n", ret); | ||
83 | } | ||
84 | |||
85 | static ssize_t show_label(struct device *dev, | ||
86 | struct device_attribute *attr, char *buf) | ||
87 | { | ||
88 | int channel = to_sensor_dev_attr(attr)->index; | ||
89 | |||
90 | return sprintf(buf, "%s\n", input_names[channel]); | ||
91 | } | ||
92 | |||
93 | #define WM831X_VOLTAGE(id, name) \ | ||
94 | static SENSOR_DEVICE_ATTR(in##id##_input, S_IRUGO, show_voltage, \ | ||
95 | NULL, name) | ||
96 | |||
97 | #define WM831X_NAMED_VOLTAGE(id, name) \ | ||
98 | WM831X_VOLTAGE(id, name); \ | ||
99 | static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label, \ | ||
100 | NULL, name) | ||
101 | |||
102 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
103 | |||
104 | WM831X_VOLTAGE(0, WM831X_AUX_AUX1); | ||
105 | WM831X_VOLTAGE(1, WM831X_AUX_AUX2); | ||
106 | WM831X_VOLTAGE(2, WM831X_AUX_AUX3); | ||
107 | WM831X_VOLTAGE(3, WM831X_AUX_AUX4); | ||
108 | |||
109 | WM831X_NAMED_VOLTAGE(4, WM831X_AUX_SYSVDD); | ||
110 | WM831X_NAMED_VOLTAGE(5, WM831X_AUX_USB); | ||
111 | WM831X_NAMED_VOLTAGE(6, WM831X_AUX_BATT); | ||
112 | WM831X_NAMED_VOLTAGE(7, WM831X_AUX_WALL); | ||
113 | WM831X_NAMED_VOLTAGE(8, WM831X_AUX_BKUP_BATT); | ||
114 | |||
115 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_chip_temp, NULL, | ||
116 | WM831X_AUX_CHIP_TEMP); | ||
117 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_label, NULL, | ||
118 | WM831X_AUX_CHIP_TEMP); | ||
119 | /* Report as a voltage since conversion depends on external components | ||
120 | * and that's what the ABI wants. */ | ||
121 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_voltage, NULL, | ||
122 | WM831X_AUX_BATT_TEMP); | ||
123 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL, | ||
124 | WM831X_AUX_BATT_TEMP); | ||
125 | |||
126 | static struct attribute *wm831x_attributes[] = { | ||
127 | &dev_attr_name.attr, | ||
128 | |||
129 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
130 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
131 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
132 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
133 | |||
134 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
135 | &sensor_dev_attr_in4_label.dev_attr.attr, | ||
136 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
137 | &sensor_dev_attr_in5_label.dev_attr.attr, | ||
138 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
139 | &sensor_dev_attr_in6_label.dev_attr.attr, | ||
140 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
141 | &sensor_dev_attr_in7_label.dev_attr.attr, | ||
142 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
143 | &sensor_dev_attr_in8_label.dev_attr.attr, | ||
144 | |||
145 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
146 | &sensor_dev_attr_temp1_label.dev_attr.attr, | ||
147 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
148 | &sensor_dev_attr_temp2_label.dev_attr.attr, | ||
149 | |||
150 | NULL | ||
151 | }; | ||
152 | |||
153 | static const struct attribute_group wm831x_attr_group = { | ||
154 | .attrs = wm831x_attributes, | ||
155 | }; | ||
156 | |||
157 | static int __devinit wm831x_hwmon_probe(struct platform_device *pdev) | ||
158 | { | ||
159 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | ||
160 | struct wm831x_hwmon *hwmon; | ||
161 | int ret; | ||
162 | |||
163 | hwmon = kzalloc(sizeof(struct wm831x_hwmon), GFP_KERNEL); | ||
164 | if (!hwmon) | ||
165 | return -ENOMEM; | ||
166 | |||
167 | hwmon->wm831x = wm831x; | ||
168 | |||
169 | ret = sysfs_create_group(&pdev->dev.kobj, &wm831x_attr_group); | ||
170 | if (ret) | ||
171 | goto err; | ||
172 | |||
173 | hwmon->classdev = hwmon_device_register(&pdev->dev); | ||
174 | if (IS_ERR(hwmon->classdev)) { | ||
175 | ret = PTR_ERR(hwmon->classdev); | ||
176 | goto err_sysfs; | ||
177 | } | ||
178 | |||
179 | platform_set_drvdata(pdev, hwmon); | ||
180 | |||
181 | return 0; | ||
182 | |||
183 | err_sysfs: | ||
184 | sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group); | ||
185 | err: | ||
186 | kfree(hwmon); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | static int __devexit wm831x_hwmon_remove(struct platform_device *pdev) | ||
191 | { | ||
192 | struct wm831x_hwmon *hwmon = platform_get_drvdata(pdev); | ||
193 | |||
194 | hwmon_device_unregister(hwmon->classdev); | ||
195 | sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group); | ||
196 | platform_set_drvdata(pdev, NULL); | ||
197 | kfree(hwmon); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static struct platform_driver wm831x_hwmon_driver = { | ||
203 | .probe = wm831x_hwmon_probe, | ||
204 | .remove = __devexit_p(wm831x_hwmon_remove), | ||
205 | .driver = { | ||
206 | .name = "wm831x-hwmon", | ||
207 | .owner = THIS_MODULE, | ||
208 | }, | ||
209 | }; | ||
210 | |||
211 | static int __init wm831x_hwmon_init(void) | ||
212 | { | ||
213 | return platform_driver_register(&wm831x_hwmon_driver); | ||
214 | } | ||
215 | module_init(wm831x_hwmon_init); | ||
216 | |||
217 | static void __exit wm831x_hwmon_exit(void) | ||
218 | { | ||
219 | platform_driver_unregister(&wm831x_hwmon_driver); | ||
220 | } | ||
221 | module_exit(wm831x_hwmon_exit); | ||
222 | |||
223 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
224 | MODULE_DESCRIPTION("WM831x Hardware Monitoring"); | ||
225 | MODULE_LICENSE("GPL"); | ||
226 | MODULE_ALIAS("platform:wm831x-hwmon"); | ||
diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c new file mode 100644 index 000000000000..13290595ca86 --- /dev/null +++ b/drivers/hwmon/wm8350-hwmon.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * drivers/hwmon/wm8350-hwmon.c - Wolfson Microelectronics WM8350 PMIC | ||
3 | * hardware monitoring features. | ||
4 | * | ||
5 | * Copyright (C) 2009 Wolfson Microelectronics plc | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License v2 as published by the | ||
9 | * Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/hwmon.h> | ||
26 | #include <linux/hwmon-sysfs.h> | ||
27 | |||
28 | #include <linux/mfd/wm8350/core.h> | ||
29 | #include <linux/mfd/wm8350/comparator.h> | ||
30 | |||
31 | static ssize_t show_name(struct device *dev, | ||
32 | struct device_attribute *attr, char *buf) | ||
33 | { | ||
34 | return sprintf(buf, "wm8350\n"); | ||
35 | } | ||
36 | |||
37 | static const char *input_names[] = { | ||
38 | [WM8350_AUXADC_USB] = "USB", | ||
39 | [WM8350_AUXADC_LINE] = "Line", | ||
40 | [WM8350_AUXADC_BATT] = "Battery", | ||
41 | }; | ||
42 | |||
43 | |||
44 | static ssize_t show_voltage(struct device *dev, | ||
45 | struct device_attribute *attr, char *buf) | ||
46 | { | ||
47 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
48 | int channel = to_sensor_dev_attr(attr)->index; | ||
49 | int val; | ||
50 | |||
51 | val = wm8350_read_auxadc(wm8350, channel, 0, 0) * WM8350_AUX_COEFF; | ||
52 | val = DIV_ROUND_CLOSEST(val, 1000); | ||
53 | |||
54 | return sprintf(buf, "%d\n", val); | ||
55 | } | ||
56 | |||
57 | static ssize_t show_label(struct device *dev, | ||
58 | struct device_attribute *attr, char *buf) | ||
59 | { | ||
60 | int channel = to_sensor_dev_attr(attr)->index; | ||
61 | |||
62 | return sprintf(buf, "%s\n", input_names[channel]); | ||
63 | } | ||
64 | |||
65 | #define WM8350_NAMED_VOLTAGE(id, name) \ | ||
66 | static SENSOR_DEVICE_ATTR(in##id##_input, S_IRUGO, show_voltage,\ | ||
67 | NULL, name); \ | ||
68 | static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label, \ | ||
69 | NULL, name) | ||
70 | |||
71 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
72 | |||
73 | WM8350_NAMED_VOLTAGE(0, WM8350_AUXADC_USB); | ||
74 | WM8350_NAMED_VOLTAGE(1, WM8350_AUXADC_BATT); | ||
75 | WM8350_NAMED_VOLTAGE(2, WM8350_AUXADC_LINE); | ||
76 | |||
77 | static struct attribute *wm8350_attributes[] = { | ||
78 | &dev_attr_name.attr, | ||
79 | |||
80 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
81 | &sensor_dev_attr_in0_label.dev_attr.attr, | ||
82 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
83 | &sensor_dev_attr_in1_label.dev_attr.attr, | ||
84 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
85 | &sensor_dev_attr_in2_label.dev_attr.attr, | ||
86 | |||
87 | NULL, | ||
88 | }; | ||
89 | |||
90 | static const struct attribute_group wm8350_attr_group = { | ||
91 | .attrs = wm8350_attributes, | ||
92 | }; | ||
93 | |||
94 | static int __devinit wm8350_hwmon_probe(struct platform_device *pdev) | ||
95 | { | ||
96 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | ||
97 | int ret; | ||
98 | |||
99 | ret = sysfs_create_group(&pdev->dev.kobj, &wm8350_attr_group); | ||
100 | if (ret) | ||
101 | goto err; | ||
102 | |||
103 | wm8350->hwmon.classdev = hwmon_device_register(&pdev->dev); | ||
104 | if (IS_ERR(wm8350->hwmon.classdev)) { | ||
105 | ret = PTR_ERR(wm8350->hwmon.classdev); | ||
106 | goto err_group; | ||
107 | } | ||
108 | |||
109 | return 0; | ||
110 | |||
111 | err_group: | ||
112 | sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group); | ||
113 | err: | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | static int __devexit wm8350_hwmon_remove(struct platform_device *pdev) | ||
118 | { | ||
119 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | ||
120 | |||
121 | hwmon_device_unregister(wm8350->hwmon.classdev); | ||
122 | sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static struct platform_driver wm8350_hwmon_driver = { | ||
128 | .probe = wm8350_hwmon_probe, | ||
129 | .remove = __devexit_p(wm8350_hwmon_remove), | ||
130 | .driver = { | ||
131 | .name = "wm8350-hwmon", | ||
132 | .owner = THIS_MODULE, | ||
133 | }, | ||
134 | }; | ||
135 | |||
136 | static int __init wm8350_hwmon_init(void) | ||
137 | { | ||
138 | return platform_driver_register(&wm8350_hwmon_driver); | ||
139 | } | ||
140 | module_init(wm8350_hwmon_init); | ||
141 | |||
142 | static void __exit wm8350_hwmon_exit(void) | ||
143 | { | ||
144 | platform_driver_unregister(&wm8350_hwmon_driver); | ||
145 | } | ||
146 | module_exit(wm8350_hwmon_exit); | ||
147 | |||
148 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
149 | MODULE_DESCRIPTION("WM8350 Hardware Monitoring"); | ||
150 | MODULE_LICENSE("GPL"); | ||
151 | MODULE_ALIAS("platform:wm8350-hwmon"); | ||