diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-03 14:09:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-03 14:09:43 -0400 |
commit | f456205265a61f1d649f8378eceaa163850cba4e (patch) | |
tree | c974aafac8fad9bf1322f2ec66aaf01d01adfaf8 /drivers/hwmon | |
parent | 8f5759aeb88a47448cd92ab55a016d013b154a98 (diff) | |
parent | 9d311eddf3565ed0e05b3cb5a22db41fa74d9d86 (diff) |
Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging into next
Pull hwmon updates from Guenter Roeck:
"New driver for NCT6683D
New chip support to existing drivers:
- add support for STTS2004 and AT30TSE004 to jc42 driver
- add support for EMC1402/EMC1412/EMC1422 to emc1403 driver
Other notable changes:
- document hwmon kernel API
- convert jc42, lm70, lm75, lm77, lm83, lm92, max1619, tmp421, and
tmp102 drivers to use new hwmon API functions
- replace function macros in lm80, lm92, and jc42 drivers with real
code
- convert emc1403 driver to use regmap, add support for additional
attributes, and add device IDs for EMC1412, EMC1413, and EMC1414
- various additional cleanup and minor bug fixes in several drivers"
* tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (60 commits)
hwmon: (nct6775) Fix probe unwind paths to properly unregister platform devices
hwmon: (nct6683) Fix probe unwind paths to properly unregister platform devices
hwmon: (ultra45_env) Introduce managed version of kzalloc
hwmon: Driver for NCT6683D
hwmon: (lm80) Rearrange code to avoid forward declarations
hwmon: (lm80) Convert fan display function macros into functions
hwmon: (lm80) Convert voltage display function macros into functions
hwmon: (lm80) Convert temperature display function macros into functions
hwmon: (lm80) Normalize all temperature values to 16 bit
hwmon: (lm80) Simplify TEMP_FROM_REG
hwmon: (lm83) Convert to use devm_hwmon_device_register_with_groups
hwmon: (lm83) Rearange code to avoid forward declarations
hwmon: (lm83) Drop FSF address
hwmon: (max1619) Convert to use devm_hwmon_device_register_with_groups
hwmon: (max1619) Drop function macros
hwmon: (max1619) Rearrange code to avoid forward declarations
hwmon: (max1619) Drop FSF address
hwmon: (max1619) Fix critical alarm display
hwmon: (jc42) Add support for STTS2004 and AT30TSE004
hwmon: (jc42) Convert function macros into functions
...
Diffstat (limited to 'drivers/hwmon')
29 files changed, 2633 insertions, 1408 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4af0da96c2e2..00343166feb1 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -1065,6 +1065,16 @@ config SENSORS_NTC_THERMISTOR | |||
1065 | This driver can also be built as a module. If so, the module | 1065 | This driver can also be built as a module. If so, the module |
1066 | will be called ntc-thermistor. | 1066 | will be called ntc-thermistor. |
1067 | 1067 | ||
1068 | config SENSORS_NCT6683 | ||
1069 | tristate "Nuvoton NCT6683D" | ||
1070 | depends on !PPC | ||
1071 | help | ||
1072 | If you say yes here you get support for the hardware monitoring | ||
1073 | functionality of the Nuvoton NCT6683D eSIO chip. | ||
1074 | |||
1075 | This driver can also be built as a module. If so, the module | ||
1076 | will be called nct6683. | ||
1077 | |||
1068 | config SENSORS_NCT6775 | 1078 | config SENSORS_NCT6775 |
1069 | tristate "Nuvoton NCT6775F and compatibles" | 1079 | tristate "Nuvoton NCT6775F and compatibles" |
1070 | depends on !PPC | 1080 | depends on !PPC |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index c48f9873ac73..11798ad7e801 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -114,6 +114,7 @@ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | |||
114 | obj-$(CONFIG_SENSORS_MAX6697) += max6697.o | 114 | obj-$(CONFIG_SENSORS_MAX6697) += max6697.o |
115 | obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o | 115 | obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o |
116 | obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o | 116 | obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o |
117 | obj-$(CONFIG_SENSORS_NCT6683) += nct6683.o | ||
117 | obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o | 118 | obj-$(CONFIG_SENSORS_NCT6775) += nct6775.o |
118 | obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o | 119 | obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o |
119 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 120 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index d19c790e410a..78339e880bd6 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * adm1029.c - Part of lm_sensors, Linux kernel modules for hardware monitoring | 2 | * adm1029.c - Part of lm_sensors, Linux kernel modules for hardware monitoring |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Corentin LABBE <corentin.labbe@geomatys.fr> | 4 | * Copyright (C) 2006 Corentin LABBE <clabbe.montjoie@gmail.com> |
5 | * | 5 | * |
6 | * Based on LM83 Driver by Jean Delvare <jdelvare@suse.de> | 6 | * Based on LM83 Driver by Jean Delvare <jdelvare@suse.de> |
7 | * | 7 | * |
@@ -449,6 +449,6 @@ static struct adm1029_data *adm1029_update_device(struct device *dev) | |||
449 | 449 | ||
450 | module_i2c_driver(adm1029_driver); | 450 | module_i2c_driver(adm1029_driver); |
451 | 451 | ||
452 | MODULE_AUTHOR("Corentin LABBE <corentin.labbe@geomatys.fr>"); | 452 | MODULE_AUTHOR("Corentin LABBE <clabbe.montjoie@gmail.com>"); |
453 | MODULE_DESCRIPTION("adm1029 driver"); | 453 | MODULE_DESCRIPTION("adm1029 driver"); |
454 | MODULE_LICENSE("GPL v2"); | 454 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index 01723f04fe45..a37b2204a418 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c | |||
@@ -18,9 +18,6 @@ | |||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | 18 | * with this program; if not, write to the Free Software Foundation, Inc., |
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | 19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
20 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 20 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
21 | * | ||
22 | * TODO | ||
23 | * - cache alarm and critical limit registers | ||
24 | */ | 21 | */ |
25 | 22 | ||
26 | #include <linux/module.h> | 23 | #include <linux/module.h> |
@@ -32,22 +29,18 @@ | |||
32 | #include <linux/err.h> | 29 | #include <linux/err.h> |
33 | #include <linux/sysfs.h> | 30 | #include <linux/sysfs.h> |
34 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
35 | #include <linux/jiffies.h> | 32 | #include <linux/regmap.h> |
36 | 33 | ||
37 | #define THERMAL_PID_REG 0xfd | 34 | #define THERMAL_PID_REG 0xfd |
38 | #define THERMAL_SMSC_ID_REG 0xfe | 35 | #define THERMAL_SMSC_ID_REG 0xfe |
39 | #define THERMAL_REVISION_REG 0xff | 36 | #define THERMAL_REVISION_REG 0xff |
40 | 37 | ||
38 | enum emc1403_chip { emc1402, emc1403, emc1404 }; | ||
39 | |||
41 | struct thermal_data { | 40 | struct thermal_data { |
42 | struct i2c_client *client; | 41 | struct regmap *regmap; |
43 | const struct attribute_group *groups[3]; | ||
44 | struct mutex mutex; | 42 | struct mutex mutex; |
45 | /* | 43 | const struct attribute_group *groups[4]; |
46 | * Cache the hyst value so we don't keep re-reading it. In theory | ||
47 | * we could cache it forever as nobody else should be writing it. | ||
48 | */ | ||
49 | u8 cached_hyst; | ||
50 | unsigned long hyst_valid; | ||
51 | }; | 44 | }; |
52 | 45 | ||
53 | static ssize_t show_temp(struct device *dev, | 46 | static ssize_t show_temp(struct device *dev, |
@@ -55,12 +48,13 @@ static ssize_t show_temp(struct device *dev, | |||
55 | { | 48 | { |
56 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | 49 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); |
57 | struct thermal_data *data = dev_get_drvdata(dev); | 50 | struct thermal_data *data = dev_get_drvdata(dev); |
51 | unsigned int val; | ||
58 | int retval; | 52 | int retval; |
59 | 53 | ||
60 | retval = i2c_smbus_read_byte_data(data->client, sda->index); | 54 | retval = regmap_read(data->regmap, sda->index, &val); |
61 | if (retval < 0) | 55 | if (retval < 0) |
62 | return retval; | 56 | return retval; |
63 | return sprintf(buf, "%d000\n", retval); | 57 | return sprintf(buf, "%d000\n", val); |
64 | } | 58 | } |
65 | 59 | ||
66 | static ssize_t show_bit(struct device *dev, | 60 | static ssize_t show_bit(struct device *dev, |
@@ -68,12 +62,13 @@ static ssize_t show_bit(struct device *dev, | |||
68 | { | 62 | { |
69 | struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); | 63 | struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); |
70 | struct thermal_data *data = dev_get_drvdata(dev); | 64 | struct thermal_data *data = dev_get_drvdata(dev); |
65 | unsigned int val; | ||
71 | int retval; | 66 | int retval; |
72 | 67 | ||
73 | retval = i2c_smbus_read_byte_data(data->client, sda->nr); | 68 | retval = regmap_read(data->regmap, sda->nr, &val); |
74 | if (retval < 0) | 69 | if (retval < 0) |
75 | return retval; | 70 | return retval; |
76 | return sprintf(buf, "%d\n", !!(retval & sda->index)); | 71 | return sprintf(buf, "%d\n", !!(val & sda->index)); |
77 | } | 72 | } |
78 | 73 | ||
79 | static ssize_t store_temp(struct device *dev, | 74 | static ssize_t store_temp(struct device *dev, |
@@ -86,8 +81,8 @@ static ssize_t store_temp(struct device *dev, | |||
86 | 81 | ||
87 | if (kstrtoul(buf, 10, &val)) | 82 | if (kstrtoul(buf, 10, &val)) |
88 | return -EINVAL; | 83 | return -EINVAL; |
89 | retval = i2c_smbus_write_byte_data(data->client, sda->index, | 84 | retval = regmap_write(data->regmap, sda->index, |
90 | DIV_ROUND_CLOSEST(val, 1000)); | 85 | DIV_ROUND_CLOSEST(val, 1000)); |
91 | if (retval < 0) | 86 | if (retval < 0) |
92 | return retval; | 87 | return retval; |
93 | return count; | 88 | return count; |
@@ -98,51 +93,51 @@ static ssize_t store_bit(struct device *dev, | |||
98 | { | 93 | { |
99 | struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); | 94 | struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); |
100 | struct thermal_data *data = dev_get_drvdata(dev); | 95 | struct thermal_data *data = dev_get_drvdata(dev); |
101 | struct i2c_client *client = data->client; | ||
102 | unsigned long val; | 96 | unsigned long val; |
103 | int retval; | 97 | int retval; |
104 | 98 | ||
105 | if (kstrtoul(buf, 10, &val)) | 99 | if (kstrtoul(buf, 10, &val)) |
106 | return -EINVAL; | 100 | return -EINVAL; |
107 | 101 | ||
108 | mutex_lock(&data->mutex); | 102 | retval = regmap_update_bits(data->regmap, sda->nr, sda->index, |
109 | retval = i2c_smbus_read_byte_data(client, sda->nr); | 103 | val ? sda->index : 0); |
110 | if (retval < 0) | 104 | if (retval < 0) |
111 | goto fail; | 105 | return retval; |
112 | 106 | return count; | |
113 | retval &= ~sda->index; | ||
114 | if (val) | ||
115 | retval |= sda->index; | ||
116 | |||
117 | retval = i2c_smbus_write_byte_data(client, sda->index, retval); | ||
118 | if (retval == 0) | ||
119 | retval = count; | ||
120 | fail: | ||
121 | mutex_unlock(&data->mutex); | ||
122 | return retval; | ||
123 | } | 107 | } |
124 | 108 | ||
125 | static ssize_t show_hyst(struct device *dev, | 109 | static ssize_t show_hyst_common(struct device *dev, |
126 | struct device_attribute *attr, char *buf) | 110 | struct device_attribute *attr, char *buf, |
111 | bool is_min) | ||
127 | { | 112 | { |
128 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | 113 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); |
129 | struct thermal_data *data = dev_get_drvdata(dev); | 114 | struct thermal_data *data = dev_get_drvdata(dev); |
130 | struct i2c_client *client = data->client; | 115 | struct regmap *regmap = data->regmap; |
116 | unsigned int limit; | ||
117 | unsigned int hyst; | ||
131 | int retval; | 118 | int retval; |
132 | int hyst; | ||
133 | 119 | ||
134 | retval = i2c_smbus_read_byte_data(client, sda->index); | 120 | retval = regmap_read(regmap, sda->index, &limit); |
135 | if (retval < 0) | 121 | if (retval < 0) |
136 | return retval; | 122 | return retval; |
137 | 123 | ||
138 | if (time_after(jiffies, data->hyst_valid)) { | 124 | retval = regmap_read(regmap, 0x21, &hyst); |
139 | hyst = i2c_smbus_read_byte_data(client, 0x21); | 125 | if (retval < 0) |
140 | if (hyst < 0) | 126 | return retval; |
141 | return retval; | 127 | |
142 | data->cached_hyst = hyst; | 128 | return sprintf(buf, "%d000\n", is_min ? limit + hyst : limit - hyst); |
143 | data->hyst_valid = jiffies + HZ; | 129 | } |
144 | } | 130 | |
145 | return sprintf(buf, "%d000\n", retval - data->cached_hyst); | 131 | static ssize_t show_hyst(struct device *dev, |
132 | struct device_attribute *attr, char *buf) | ||
133 | { | ||
134 | return show_hyst_common(dev, attr, buf, false); | ||
135 | } | ||
136 | |||
137 | static ssize_t show_min_hyst(struct device *dev, | ||
138 | struct device_attribute *attr, char *buf) | ||
139 | { | ||
140 | return show_hyst_common(dev, attr, buf, true); | ||
146 | } | 141 | } |
147 | 142 | ||
148 | static ssize_t store_hyst(struct device *dev, | 143 | static ssize_t store_hyst(struct device *dev, |
@@ -150,7 +145,8 @@ static ssize_t store_hyst(struct device *dev, | |||
150 | { | 145 | { |
151 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | 146 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); |
152 | struct thermal_data *data = dev_get_drvdata(dev); | 147 | struct thermal_data *data = dev_get_drvdata(dev); |
153 | struct i2c_client *client = data->client; | 148 | struct regmap *regmap = data->regmap; |
149 | unsigned int limit; | ||
154 | int retval; | 150 | int retval; |
155 | int hyst; | 151 | int hyst; |
156 | unsigned long val; | 152 | unsigned long val; |
@@ -159,23 +155,15 @@ static ssize_t store_hyst(struct device *dev, | |||
159 | return -EINVAL; | 155 | return -EINVAL; |
160 | 156 | ||
161 | mutex_lock(&data->mutex); | 157 | mutex_lock(&data->mutex); |
162 | retval = i2c_smbus_read_byte_data(client, sda->index); | 158 | retval = regmap_read(regmap, sda->index, &limit); |
163 | if (retval < 0) | 159 | if (retval < 0) |
164 | goto fail; | 160 | goto fail; |
165 | 161 | ||
166 | hyst = retval * 1000 - val; | 162 | hyst = limit * 1000 - val; |
167 | hyst = DIV_ROUND_CLOSEST(hyst, 1000); | 163 | hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 255); |
168 | if (hyst < 0 || hyst > 255) { | 164 | retval = regmap_write(regmap, 0x21, hyst); |
169 | retval = -ERANGE; | 165 | if (retval == 0) |
170 | goto fail; | ||
171 | } | ||
172 | |||
173 | retval = i2c_smbus_write_byte_data(client, 0x21, hyst); | ||
174 | if (retval == 0) { | ||
175 | retval = count; | 166 | retval = count; |
176 | data->cached_hyst = hyst; | ||
177 | data->hyst_valid = jiffies + HZ; | ||
178 | } | ||
179 | fail: | 167 | fail: |
180 | mutex_unlock(&data->mutex); | 168 | mutex_unlock(&data->mutex); |
181 | return retval; | 169 | return retval; |
@@ -198,6 +186,8 @@ static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, | |||
198 | show_bit, NULL, 0x35, 0x01); | 186 | show_bit, NULL, 0x35, 0x01); |
199 | static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, | 187 | static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, |
200 | show_bit, NULL, 0x37, 0x01); | 188 | show_bit, NULL, 0x37, 0x01); |
189 | static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_min_hyst, NULL, 0x06); | ||
190 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_hyst, NULL, 0x05); | ||
201 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO | S_IWUSR, | 191 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO | S_IWUSR, |
202 | show_hyst, store_hyst, 0x20); | 192 | show_hyst, store_hyst, 0x20); |
203 | 193 | ||
@@ -208,14 +198,16 @@ static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, | |||
208 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO | S_IWUSR, | 198 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO | S_IWUSR, |
209 | show_temp, store_temp, 0x19); | 199 | show_temp, store_temp, 0x19); |
210 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0x01); | 200 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0x01); |
201 | static SENSOR_DEVICE_ATTR_2(temp2_fault, S_IRUGO, show_bit, NULL, 0x1b, 0x02); | ||
211 | static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, | 202 | static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, |
212 | show_bit, NULL, 0x36, 0x02); | 203 | show_bit, NULL, 0x36, 0x02); |
213 | static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, | 204 | static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, |
214 | show_bit, NULL, 0x35, 0x02); | 205 | show_bit, NULL, 0x35, 0x02); |
215 | static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, | 206 | static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, |
216 | show_bit, NULL, 0x37, 0x02); | 207 | show_bit, NULL, 0x37, 0x02); |
217 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO | S_IWUSR, | 208 | static SENSOR_DEVICE_ATTR(temp2_min_hyst, S_IRUGO, show_min_hyst, NULL, 0x08); |
218 | show_hyst, store_hyst, 0x19); | 209 | static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO, show_hyst, NULL, 0x07); |
210 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_hyst, NULL, 0x19); | ||
219 | 211 | ||
220 | static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO | S_IWUSR, | 212 | static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO | S_IWUSR, |
221 | show_temp, store_temp, 0x16); | 213 | show_temp, store_temp, 0x16); |
@@ -224,14 +216,16 @@ static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR, | |||
224 | static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO | S_IWUSR, | 216 | static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO | S_IWUSR, |
225 | show_temp, store_temp, 0x1A); | 217 | show_temp, store_temp, 0x1A); |
226 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 0x23); | 218 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 0x23); |
219 | static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_bit, NULL, 0x1b, 0x04); | ||
227 | static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, | 220 | static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, |
228 | show_bit, NULL, 0x36, 0x04); | 221 | show_bit, NULL, 0x36, 0x04); |
229 | static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, | 222 | static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, |
230 | show_bit, NULL, 0x35, 0x04); | 223 | show_bit, NULL, 0x35, 0x04); |
231 | static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, | 224 | static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, |
232 | show_bit, NULL, 0x37, 0x04); | 225 | show_bit, NULL, 0x37, 0x04); |
233 | static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO | S_IWUSR, | 226 | static SENSOR_DEVICE_ATTR(temp3_min_hyst, S_IRUGO, show_min_hyst, NULL, 0x16); |
234 | show_hyst, store_hyst, 0x1A); | 227 | static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO, show_hyst, NULL, 0x15); |
228 | static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO, show_hyst, NULL, 0x1A); | ||
235 | 229 | ||
236 | static SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO | S_IWUSR, | 230 | static SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO | S_IWUSR, |
237 | show_temp, store_temp, 0x2D); | 231 | show_temp, store_temp, 0x2D); |
@@ -240,44 +234,66 @@ static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO | S_IWUSR, | |||
240 | static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO | S_IWUSR, | 234 | static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO | S_IWUSR, |
241 | show_temp, store_temp, 0x30); | 235 | show_temp, store_temp, 0x30); |
242 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 0x2A); | 236 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 0x2A); |
237 | static SENSOR_DEVICE_ATTR_2(temp4_fault, S_IRUGO, show_bit, NULL, 0x1b, 0x08); | ||
243 | static SENSOR_DEVICE_ATTR_2(temp4_min_alarm, S_IRUGO, | 238 | static SENSOR_DEVICE_ATTR_2(temp4_min_alarm, S_IRUGO, |
244 | show_bit, NULL, 0x36, 0x08); | 239 | show_bit, NULL, 0x36, 0x08); |
245 | static SENSOR_DEVICE_ATTR_2(temp4_max_alarm, S_IRUGO, | 240 | static SENSOR_DEVICE_ATTR_2(temp4_max_alarm, S_IRUGO, |
246 | show_bit, NULL, 0x35, 0x08); | 241 | show_bit, NULL, 0x35, 0x08); |
247 | static SENSOR_DEVICE_ATTR_2(temp4_crit_alarm, S_IRUGO, | 242 | static SENSOR_DEVICE_ATTR_2(temp4_crit_alarm, S_IRUGO, |
248 | show_bit, NULL, 0x37, 0x08); | 243 | show_bit, NULL, 0x37, 0x08); |
249 | static SENSOR_DEVICE_ATTR(temp4_crit_hyst, S_IRUGO | S_IWUSR, | 244 | static SENSOR_DEVICE_ATTR(temp4_min_hyst, S_IRUGO, show_min_hyst, NULL, 0x2D); |
250 | show_hyst, store_hyst, 0x30); | 245 | static SENSOR_DEVICE_ATTR(temp4_max_hyst, S_IRUGO, show_hyst, NULL, 0x2C); |
246 | static SENSOR_DEVICE_ATTR(temp4_crit_hyst, S_IRUGO, show_hyst, NULL, 0x30); | ||
251 | 247 | ||
252 | static SENSOR_DEVICE_ATTR_2(power_state, S_IRUGO | S_IWUSR, | 248 | static SENSOR_DEVICE_ATTR_2(power_state, S_IRUGO | S_IWUSR, |
253 | show_bit, store_bit, 0x03, 0x40); | 249 | show_bit, store_bit, 0x03, 0x40); |
254 | 250 | ||
255 | static struct attribute *emc1403_attrs[] = { | 251 | static struct attribute *emc1402_attrs[] = { |
256 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 252 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
257 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 253 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
258 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | 254 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
259 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 255 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
260 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | 256 | &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, |
261 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 257 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
262 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
263 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, | 258 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, |
259 | |||
264 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 260 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
265 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 261 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
266 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | 262 | &sensor_dev_attr_temp2_crit.dev_attr.attr, |
267 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 263 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
264 | &sensor_dev_attr_temp2_min_hyst.dev_attr.attr, | ||
265 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, | ||
266 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | ||
267 | |||
268 | &sensor_dev_attr_power_state.dev_attr.attr, | ||
269 | NULL | ||
270 | }; | ||
271 | |||
272 | static const struct attribute_group emc1402_group = { | ||
273 | .attrs = emc1402_attrs, | ||
274 | }; | ||
275 | |||
276 | static struct attribute *emc1403_attrs[] = { | ||
277 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | ||
278 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
279 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
280 | |||
281 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
268 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, | 282 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, |
269 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 283 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
270 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | 284 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, |
271 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, | 285 | |
272 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 286 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
273 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 287 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
274 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | 288 | &sensor_dev_attr_temp3_crit.dev_attr.attr, |
275 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 289 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
290 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
276 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, | 291 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, |
277 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, | 292 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, |
278 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, | 293 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, |
294 | &sensor_dev_attr_temp3_min_hyst.dev_attr.attr, | ||
295 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, | ||
279 | &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, | 296 | &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, |
280 | &sensor_dev_attr_power_state.dev_attr.attr, | ||
281 | NULL | 297 | NULL |
282 | }; | 298 | }; |
283 | 299 | ||
@@ -290,9 +306,12 @@ static struct attribute *emc1404_attrs[] = { | |||
290 | &sensor_dev_attr_temp4_max.dev_attr.attr, | 306 | &sensor_dev_attr_temp4_max.dev_attr.attr, |
291 | &sensor_dev_attr_temp4_crit.dev_attr.attr, | 307 | &sensor_dev_attr_temp4_crit.dev_attr.attr, |
292 | &sensor_dev_attr_temp4_input.dev_attr.attr, | 308 | &sensor_dev_attr_temp4_input.dev_attr.attr, |
309 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | ||
293 | &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, | 310 | &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, |
294 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, | 311 | &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, |
295 | &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, | 312 | &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, |
313 | &sensor_dev_attr_temp4_min_hyst.dev_attr.attr, | ||
314 | &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, | ||
296 | &sensor_dev_attr_temp4_crit_hyst.dev_attr.attr, | 315 | &sensor_dev_attr_temp4_crit_hyst.dev_attr.attr, |
297 | NULL | 316 | NULL |
298 | }; | 317 | }; |
@@ -301,6 +320,39 @@ static const struct attribute_group emc1404_group = { | |||
301 | .attrs = emc1404_attrs, | 320 | .attrs = emc1404_attrs, |
302 | }; | 321 | }; |
303 | 322 | ||
323 | /* | ||
324 | * EMC14x2 uses a different register and different bits to report alarm and | ||
325 | * fault status. For simplicity, provide a separate attribute group for this | ||
326 | * chip series. | ||
327 | * Since we can not re-use the same attribute names, create a separate attribute | ||
328 | * array. | ||
329 | */ | ||
330 | static struct sensor_device_attribute_2 emc1402_alarms[] = { | ||
331 | SENSOR_ATTR_2(temp1_min_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x20), | ||
332 | SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x40), | ||
333 | SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x01), | ||
334 | |||
335 | SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_bit, NULL, 0x02, 0x04), | ||
336 | SENSOR_ATTR_2(temp2_min_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x08), | ||
337 | SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x10), | ||
338 | SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_bit, NULL, 0x02, 0x02), | ||
339 | }; | ||
340 | |||
341 | static struct attribute *emc1402_alarm_attrs[] = { | ||
342 | &emc1402_alarms[0].dev_attr.attr, | ||
343 | &emc1402_alarms[1].dev_attr.attr, | ||
344 | &emc1402_alarms[2].dev_attr.attr, | ||
345 | &emc1402_alarms[3].dev_attr.attr, | ||
346 | &emc1402_alarms[4].dev_attr.attr, | ||
347 | &emc1402_alarms[5].dev_attr.attr, | ||
348 | &emc1402_alarms[6].dev_attr.attr, | ||
349 | NULL, | ||
350 | }; | ||
351 | |||
352 | static const struct attribute_group emc1402_alarm_group = { | ||
353 | .attrs = emc1402_alarm_attrs, | ||
354 | }; | ||
355 | |||
304 | static int emc1403_detect(struct i2c_client *client, | 356 | static int emc1403_detect(struct i2c_client *client, |
305 | struct i2c_board_info *info) | 357 | struct i2c_board_info *info) |
306 | { | 358 | { |
@@ -313,9 +365,15 @@ static int emc1403_detect(struct i2c_client *client, | |||
313 | 365 | ||
314 | id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG); | 366 | id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG); |
315 | switch (id) { | 367 | switch (id) { |
368 | case 0x20: | ||
369 | strlcpy(info->type, "emc1402", I2C_NAME_SIZE); | ||
370 | break; | ||
316 | case 0x21: | 371 | case 0x21: |
317 | strlcpy(info->type, "emc1403", I2C_NAME_SIZE); | 372 | strlcpy(info->type, "emc1403", I2C_NAME_SIZE); |
318 | break; | 373 | break; |
374 | case 0x22: | ||
375 | strlcpy(info->type, "emc1422", I2C_NAME_SIZE); | ||
376 | break; | ||
319 | case 0x23: | 377 | case 0x23: |
320 | strlcpy(info->type, "emc1423", I2C_NAME_SIZE); | 378 | strlcpy(info->type, "emc1423", I2C_NAME_SIZE); |
321 | break; | 379 | break; |
@@ -336,6 +394,35 @@ static int emc1403_detect(struct i2c_client *client, | |||
336 | return 0; | 394 | return 0; |
337 | } | 395 | } |
338 | 396 | ||
397 | static bool emc1403_regmap_is_volatile(struct device *dev, unsigned int reg) | ||
398 | { | ||
399 | switch (reg) { | ||
400 | case 0x00: /* internal diode high byte */ | ||
401 | case 0x01: /* external diode 1 high byte */ | ||
402 | case 0x02: /* status */ | ||
403 | case 0x10: /* external diode 1 low byte */ | ||
404 | case 0x1b: /* external diode fault */ | ||
405 | case 0x23: /* external diode 2 high byte */ | ||
406 | case 0x24: /* external diode 2 low byte */ | ||
407 | case 0x29: /* internal diode low byte */ | ||
408 | case 0x2a: /* externl diode 3 high byte */ | ||
409 | case 0x2b: /* external diode 3 low byte */ | ||
410 | case 0x35: /* high limit status */ | ||
411 | case 0x36: /* low limit status */ | ||
412 | case 0x37: /* therm limit status */ | ||
413 | return true; | ||
414 | default: | ||
415 | return false; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | static struct regmap_config emc1403_regmap_config = { | ||
420 | .reg_bits = 8, | ||
421 | .val_bits = 8, | ||
422 | .cache_type = REGCACHE_RBTREE, | ||
423 | .volatile_reg = emc1403_regmap_is_volatile, | ||
424 | }; | ||
425 | |||
339 | static int emc1403_probe(struct i2c_client *client, | 426 | static int emc1403_probe(struct i2c_client *client, |
340 | const struct i2c_device_id *id) | 427 | const struct i2c_device_id *id) |
341 | { | 428 | { |
@@ -347,13 +434,23 @@ static int emc1403_probe(struct i2c_client *client, | |||
347 | if (data == NULL) | 434 | if (data == NULL) |
348 | return -ENOMEM; | 435 | return -ENOMEM; |
349 | 436 | ||
350 | data->client = client; | 437 | data->regmap = devm_regmap_init_i2c(client, &emc1403_regmap_config); |
438 | if (IS_ERR(data->regmap)) | ||
439 | return PTR_ERR(data->regmap); | ||
440 | |||
351 | mutex_init(&data->mutex); | 441 | mutex_init(&data->mutex); |
352 | data->hyst_valid = jiffies - 1; /* Expired */ | ||
353 | 442 | ||
354 | data->groups[0] = &emc1403_group; | 443 | switch (id->driver_data) { |
355 | if (id->driver_data) | 444 | case emc1404: |
356 | data->groups[1] = &emc1404_group; | 445 | data->groups[2] = &emc1404_group; |
446 | case emc1403: | ||
447 | data->groups[1] = &emc1403_group; | ||
448 | case emc1402: | ||
449 | data->groups[0] = &emc1402_group; | ||
450 | } | ||
451 | |||
452 | if (id->driver_data == emc1402) | ||
453 | data->groups[1] = &emc1402_alarm_group; | ||
357 | 454 | ||
358 | hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, | 455 | hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, |
359 | client->name, data, | 456 | client->name, data, |
@@ -366,14 +463,20 @@ static int emc1403_probe(struct i2c_client *client, | |||
366 | } | 463 | } |
367 | 464 | ||
368 | static const unsigned short emc1403_address_list[] = { | 465 | static const unsigned short emc1403_address_list[] = { |
369 | 0x18, 0x29, 0x4c, 0x4d, I2C_CLIENT_END | 466 | 0x18, 0x1c, 0x29, 0x4c, 0x4d, 0x5c, I2C_CLIENT_END |
370 | }; | 467 | }; |
371 | 468 | ||
469 | /* Last digit of chip name indicates number of channels */ | ||
372 | static const struct i2c_device_id emc1403_idtable[] = { | 470 | static const struct i2c_device_id emc1403_idtable[] = { |
373 | { "emc1403", 0 }, | 471 | { "emc1402", emc1402 }, |
374 | { "emc1404", 1 }, | 472 | { "emc1403", emc1403 }, |
375 | { "emc1423", 0 }, | 473 | { "emc1404", emc1404 }, |
376 | { "emc1424", 1 }, | 474 | { "emc1412", emc1402 }, |
475 | { "emc1413", emc1403 }, | ||
476 | { "emc1414", emc1404 }, | ||
477 | { "emc1422", emc1402 }, | ||
478 | { "emc1423", emc1403 }, | ||
479 | { "emc1424", emc1404 }, | ||
377 | { } | 480 | { } |
378 | }; | 481 | }; |
379 | MODULE_DEVICE_TABLE(i2c, emc1403_idtable); | 482 | MODULE_DEVICE_TABLE(i2c, emc1403_idtable); |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 32f5132c4652..9e57b77ecd34 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c | |||
@@ -1387,10 +1387,8 @@ static int f71805f_probe(struct platform_device *pdev) | |||
1387 | 1387 | ||
1388 | data = devm_kzalloc(&pdev->dev, sizeof(struct f71805f_data), | 1388 | data = devm_kzalloc(&pdev->dev, sizeof(struct f71805f_data), |
1389 | GFP_KERNEL); | 1389 | GFP_KERNEL); |
1390 | if (!data) { | 1390 | if (!data) |
1391 | pr_err("Out of memory\n"); | ||
1392 | return -ENOMEM; | 1391 | return -ENOMEM; |
1393 | } | ||
1394 | 1392 | ||
1395 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1393 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1396 | if (!devm_request_region(&pdev->dev, res->start + ADDR_REG_OFFSET, 2, | 1394 | if (!devm_request_region(&pdev->dev, res->start + ADDR_REG_OFFSET, 2, |
diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c index b4b8b5bef718..98a8618d8fbf 100644 --- a/drivers/hwmon/g762.c +++ b/drivers/hwmon/g762.c | |||
@@ -586,7 +586,7 @@ static int do_set_fan_startv(struct device *dev, unsigned long val) | |||
586 | */ | 586 | */ |
587 | 587 | ||
588 | #ifdef CONFIG_OF | 588 | #ifdef CONFIG_OF |
589 | static struct of_device_id g762_dt_match[] = { | 589 | static const struct of_device_id g762_dt_match[] = { |
590 | { .compatible = "gmt,g762" }, | 590 | { .compatible = "gmt,g762" }, |
591 | { .compatible = "gmt,g763" }, | 591 | { .compatible = "gmt,g763" }, |
592 | { }, | 592 | { }, |
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index 73181be5b30b..ba35e4d530b5 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c | |||
@@ -482,7 +482,7 @@ static int gpio_fan_get_of_pdata(struct device *dev, | |||
482 | return 0; | 482 | return 0; |
483 | } | 483 | } |
484 | 484 | ||
485 | static struct of_device_id of_gpio_fan_match[] = { | 485 | static const struct of_device_id of_gpio_fan_match[] = { |
486 | { .compatible = "gpio-fan", }, | 486 | { .compatible = "gpio-fan", }, |
487 | {}, | 487 | {}, |
488 | }; | 488 | }; |
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 20ab0fb85395..030e7ff589be 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c | |||
@@ -463,10 +463,8 @@ static void ibmpex_register_bmc(int iface, struct device *dev) | |||
463 | int err; | 463 | int err; |
464 | 464 | ||
465 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 465 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
466 | if (!data) { | 466 | if (!data) |
467 | dev_err(dev, "Insufficient memory for BMC interface.\n"); | ||
468 | return; | 467 | return; |
469 | } | ||
470 | 468 | ||
471 | data->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | 469 | data->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; |
472 | data->address.channel = IPMI_BMC_CHANNEL; | 470 | data->address.channel = IPMI_BMC_CHANNEL; |
diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c index 9fbb1b1fdff3..14c82daab019 100644 --- a/drivers/hwmon/iio_hwmon.c +++ b/drivers/hwmon/iio_hwmon.c | |||
@@ -163,7 +163,7 @@ static int iio_hwmon_remove(struct platform_device *pdev) | |||
163 | return 0; | 163 | return 0; |
164 | } | 164 | } |
165 | 165 | ||
166 | static struct of_device_id iio_hwmon_of_match[] = { | 166 | static const struct of_device_id iio_hwmon_of_match[] = { |
167 | { .compatible = "iio-hwmon", }, | 167 | { .compatible = "iio-hwmon", }, |
168 | { } | 168 | { } |
169 | }; | 169 | }; |
diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 6013611e4f21..388f8bcd898e 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c | |||
@@ -65,6 +65,7 @@ static const unsigned short normal_i2c[] = { | |||
65 | /* Manufacturer IDs */ | 65 | /* Manufacturer IDs */ |
66 | #define ADT_MANID 0x11d4 /* Analog Devices */ | 66 | #define ADT_MANID 0x11d4 /* Analog Devices */ |
67 | #define ATMEL_MANID 0x001f /* Atmel */ | 67 | #define ATMEL_MANID 0x001f /* Atmel */ |
68 | #define ATMEL_MANID2 0x1114 /* Atmel */ | ||
68 | #define MAX_MANID 0x004d /* Maxim */ | 69 | #define MAX_MANID 0x004d /* Maxim */ |
69 | #define IDT_MANID 0x00b3 /* IDT */ | 70 | #define IDT_MANID 0x00b3 /* IDT */ |
70 | #define MCP_MANID 0x0054 /* Microchip */ | 71 | #define MCP_MANID 0x0054 /* Microchip */ |
@@ -82,6 +83,9 @@ static const unsigned short normal_i2c[] = { | |||
82 | #define AT30TS00_DEVID 0x8201 | 83 | #define AT30TS00_DEVID 0x8201 |
83 | #define AT30TS00_DEVID_MASK 0xffff | 84 | #define AT30TS00_DEVID_MASK 0xffff |
84 | 85 | ||
86 | #define AT30TSE004_DEVID 0x2200 | ||
87 | #define AT30TSE004_DEVID_MASK 0xffff | ||
88 | |||
85 | /* IDT */ | 89 | /* IDT */ |
86 | #define TS3000B3_DEVID 0x2903 /* Also matches TSE2002B3 */ | 90 | #define TS3000B3_DEVID 0x2903 /* Also matches TSE2002B3 */ |
87 | #define TS3000B3_DEVID_MASK 0xffff | 91 | #define TS3000B3_DEVID_MASK 0xffff |
@@ -130,6 +134,9 @@ static const unsigned short normal_i2c[] = { | |||
130 | #define STTS2002_DEVID 0x0300 | 134 | #define STTS2002_DEVID 0x0300 |
131 | #define STTS2002_DEVID_MASK 0xffff | 135 | #define STTS2002_DEVID_MASK 0xffff |
132 | 136 | ||
137 | #define STTS2004_DEVID 0x2201 | ||
138 | #define STTS2004_DEVID_MASK 0xffff | ||
139 | |||
133 | #define STTS3000_DEVID 0x0200 | 140 | #define STTS3000_DEVID 0x0200 |
134 | #define STTS3000_DEVID_MASK 0xffff | 141 | #define STTS3000_DEVID_MASK 0xffff |
135 | 142 | ||
@@ -144,6 +151,7 @@ struct jc42_chips { | |||
144 | static struct jc42_chips jc42_chips[] = { | 151 | static struct jc42_chips jc42_chips[] = { |
145 | { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK }, | 152 | { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK }, |
146 | { ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK }, | 153 | { ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK }, |
154 | { ATMEL_MANID2, AT30TSE004_DEVID, AT30TSE004_DEVID_MASK }, | ||
147 | { IDT_MANID, TS3000B3_DEVID, TS3000B3_DEVID_MASK }, | 155 | { IDT_MANID, TS3000B3_DEVID, TS3000B3_DEVID_MASK }, |
148 | { IDT_MANID, TS3000GB2_DEVID, TS3000GB2_DEVID_MASK }, | 156 | { IDT_MANID, TS3000GB2_DEVID, TS3000GB2_DEVID_MASK }, |
149 | { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK }, | 157 | { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK }, |
@@ -158,9 +166,25 @@ static struct jc42_chips jc42_chips[] = { | |||
158 | { STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK }, | 166 | { STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK }, |
159 | { STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK }, | 167 | { STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK }, |
160 | { STM_MANID, STTS2002_DEVID, STTS2002_DEVID_MASK }, | 168 | { STM_MANID, STTS2002_DEVID, STTS2002_DEVID_MASK }, |
169 | { STM_MANID, STTS2004_DEVID, STTS2004_DEVID_MASK }, | ||
161 | { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, | 170 | { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, |
162 | }; | 171 | }; |
163 | 172 | ||
173 | enum temp_index { | ||
174 | t_input = 0, | ||
175 | t_crit, | ||
176 | t_min, | ||
177 | t_max, | ||
178 | t_num_temp | ||
179 | }; | ||
180 | |||
181 | static const u8 temp_regs[t_num_temp] = { | ||
182 | [t_input] = JC42_REG_TEMP, | ||
183 | [t_crit] = JC42_REG_TEMP_CRITICAL, | ||
184 | [t_min] = JC42_REG_TEMP_LOWER, | ||
185 | [t_max] = JC42_REG_TEMP_UPPER, | ||
186 | }; | ||
187 | |||
164 | /* Each client has this additional data */ | 188 | /* Each client has this additional data */ |
165 | struct jc42_data { | 189 | struct jc42_data { |
166 | struct i2c_client *client; | 190 | struct i2c_client *client; |
@@ -170,69 +194,7 @@ struct jc42_data { | |||
170 | unsigned long last_updated; /* In jiffies */ | 194 | unsigned long last_updated; /* In jiffies */ |
171 | u16 orig_config; /* original configuration */ | 195 | u16 orig_config; /* original configuration */ |
172 | u16 config; /* current configuration */ | 196 | u16 config; /* current configuration */ |
173 | u16 temp_input; /* Temperatures */ | 197 | u16 temp[t_num_temp];/* Temperatures */ |
174 | u16 temp_crit; | ||
175 | u16 temp_min; | ||
176 | u16 temp_max; | ||
177 | }; | ||
178 | |||
179 | static int jc42_probe(struct i2c_client *client, | ||
180 | const struct i2c_device_id *id); | ||
181 | static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info); | ||
182 | static int jc42_remove(struct i2c_client *client); | ||
183 | |||
184 | static struct jc42_data *jc42_update_device(struct device *dev); | ||
185 | |||
186 | static const struct i2c_device_id jc42_id[] = { | ||
187 | { "jc42", 0 }, | ||
188 | { } | ||
189 | }; | ||
190 | MODULE_DEVICE_TABLE(i2c, jc42_id); | ||
191 | |||
192 | #ifdef CONFIG_PM | ||
193 | |||
194 | static int jc42_suspend(struct device *dev) | ||
195 | { | ||
196 | struct jc42_data *data = dev_get_drvdata(dev); | ||
197 | |||
198 | data->config |= JC42_CFG_SHUTDOWN; | ||
199 | i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, | ||
200 | data->config); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int jc42_resume(struct device *dev) | ||
205 | { | ||
206 | struct jc42_data *data = dev_get_drvdata(dev); | ||
207 | |||
208 | data->config &= ~JC42_CFG_SHUTDOWN; | ||
209 | i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, | ||
210 | data->config); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static const struct dev_pm_ops jc42_dev_pm_ops = { | ||
215 | .suspend = jc42_suspend, | ||
216 | .resume = jc42_resume, | ||
217 | }; | ||
218 | |||
219 | #define JC42_DEV_PM_OPS (&jc42_dev_pm_ops) | ||
220 | #else | ||
221 | #define JC42_DEV_PM_OPS NULL | ||
222 | #endif /* CONFIG_PM */ | ||
223 | |||
224 | /* This is the driver that will be inserted */ | ||
225 | static struct i2c_driver jc42_driver = { | ||
226 | .class = I2C_CLASS_SPD, | ||
227 | .driver = { | ||
228 | .name = "jc42", | ||
229 | .pm = JC42_DEV_PM_OPS, | ||
230 | }, | ||
231 | .probe = jc42_probe, | ||
232 | .remove = jc42_remove, | ||
233 | .id_table = jc42_id, | ||
234 | .detect = jc42_detect, | ||
235 | .address_list = normal_i2c, | ||
236 | }; | 198 | }; |
237 | 199 | ||
238 | #define JC42_TEMP_MIN_EXTENDED (-40000) | 200 | #define JC42_TEMP_MIN_EXTENDED (-40000) |
@@ -261,79 +223,81 @@ static int jc42_temp_from_reg(s16 reg) | |||
261 | return reg * 125 / 2; | 223 | return reg * 125 / 2; |
262 | } | 224 | } |
263 | 225 | ||
264 | /* sysfs stuff */ | 226 | static struct jc42_data *jc42_update_device(struct device *dev) |
265 | 227 | { | |
266 | /* read routines for temperature limits */ | 228 | struct jc42_data *data = dev_get_drvdata(dev); |
267 | #define show(value) \ | 229 | struct i2c_client *client = data->client; |
268 | static ssize_t show_##value(struct device *dev, \ | 230 | struct jc42_data *ret = data; |
269 | struct device_attribute *attr, \ | 231 | int i, val; |
270 | char *buf) \ | 232 | |
271 | { \ | 233 | mutex_lock(&data->update_lock); |
272 | struct jc42_data *data = jc42_update_device(dev); \ | 234 | |
273 | if (IS_ERR(data)) \ | 235 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { |
274 | return PTR_ERR(data); \ | 236 | for (i = 0; i < t_num_temp; i++) { |
275 | return sprintf(buf, "%d\n", jc42_temp_from_reg(data->value)); \ | 237 | val = i2c_smbus_read_word_swapped(client, temp_regs[i]); |
238 | if (val < 0) { | ||
239 | ret = ERR_PTR(val); | ||
240 | goto abort; | ||
241 | } | ||
242 | data->temp[i] = val; | ||
243 | } | ||
244 | data->last_updated = jiffies; | ||
245 | data->valid = true; | ||
246 | } | ||
247 | abort: | ||
248 | mutex_unlock(&data->update_lock); | ||
249 | return ret; | ||
276 | } | 250 | } |
277 | 251 | ||
278 | show(temp_input); | 252 | /* sysfs functions */ |
279 | show(temp_crit); | ||
280 | show(temp_min); | ||
281 | show(temp_max); | ||
282 | 253 | ||
283 | /* read routines for hysteresis values */ | 254 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, |
284 | static ssize_t show_temp_crit_hyst(struct device *dev, | 255 | char *buf) |
285 | struct device_attribute *attr, char *buf) | ||
286 | { | 256 | { |
257 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
287 | struct jc42_data *data = jc42_update_device(dev); | 258 | struct jc42_data *data = jc42_update_device(dev); |
288 | int temp, hyst; | ||
289 | |||
290 | if (IS_ERR(data)) | 259 | if (IS_ERR(data)) |
291 | return PTR_ERR(data); | 260 | return PTR_ERR(data); |
292 | 261 | return sprintf(buf, "%d\n", | |
293 | temp = jc42_temp_from_reg(data->temp_crit); | 262 | jc42_temp_from_reg(data->temp[attr->index])); |
294 | hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) | ||
295 | >> JC42_CFG_HYST_SHIFT]; | ||
296 | return sprintf(buf, "%d\n", temp - hyst); | ||
297 | } | 263 | } |
298 | 264 | ||
299 | static ssize_t show_temp_max_hyst(struct device *dev, | 265 | static ssize_t show_temp_hyst(struct device *dev, |
300 | struct device_attribute *attr, char *buf) | 266 | struct device_attribute *devattr, char *buf) |
301 | { | 267 | { |
268 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
302 | struct jc42_data *data = jc42_update_device(dev); | 269 | struct jc42_data *data = jc42_update_device(dev); |
303 | int temp, hyst; | 270 | int temp, hyst; |
304 | 271 | ||
305 | if (IS_ERR(data)) | 272 | if (IS_ERR(data)) |
306 | return PTR_ERR(data); | 273 | return PTR_ERR(data); |
307 | 274 | ||
308 | temp = jc42_temp_from_reg(data->temp_max); | 275 | temp = jc42_temp_from_reg(data->temp[attr->index]); |
309 | hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) | 276 | hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) |
310 | >> JC42_CFG_HYST_SHIFT]; | 277 | >> JC42_CFG_HYST_SHIFT]; |
311 | return sprintf(buf, "%d\n", temp - hyst); | 278 | return sprintf(buf, "%d\n", temp - hyst); |
312 | } | 279 | } |
313 | 280 | ||
314 | /* write routines */ | 281 | static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, |
315 | #define set(value, reg) \ | 282 | const char *buf, size_t count) |
316 | static ssize_t set_##value(struct device *dev, \ | 283 | { |
317 | struct device_attribute *attr, \ | 284 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
318 | const char *buf, size_t count) \ | 285 | struct jc42_data *data = dev_get_drvdata(dev); |
319 | { \ | 286 | int err, ret = count; |
320 | struct jc42_data *data = dev_get_drvdata(dev); \ | 287 | int nr = attr->index; |
321 | int err, ret = count; \ | 288 | long val; |
322 | long val; \ | ||
323 | if (kstrtol(buf, 10, &val) < 0) \ | ||
324 | return -EINVAL; \ | ||
325 | mutex_lock(&data->update_lock); \ | ||
326 | data->value = jc42_temp_to_reg(val, data->extended); \ | ||
327 | err = i2c_smbus_write_word_swapped(data->client, reg, data->value); \ | ||
328 | if (err < 0) \ | ||
329 | ret = err; \ | ||
330 | mutex_unlock(&data->update_lock); \ | ||
331 | return ret; \ | ||
332 | } | ||
333 | 289 | ||
334 | set(temp_min, JC42_REG_TEMP_LOWER); | 290 | if (kstrtol(buf, 10, &val) < 0) |
335 | set(temp_max, JC42_REG_TEMP_UPPER); | 291 | return -EINVAL; |
336 | set(temp_crit, JC42_REG_TEMP_CRITICAL); | 292 | mutex_lock(&data->update_lock); |
293 | data->temp[nr] = jc42_temp_to_reg(val, data->extended); | ||
294 | err = i2c_smbus_write_word_swapped(data->client, temp_regs[nr], | ||
295 | data->temp[nr]); | ||
296 | if (err < 0) | ||
297 | ret = err; | ||
298 | mutex_unlock(&data->update_lock); | ||
299 | return ret; | ||
300 | } | ||
337 | 301 | ||
338 | /* | 302 | /* |
339 | * JC42.4 compliant chips only support four hysteresis values. | 303 | * JC42.4 compliant chips only support four hysteresis values. |
@@ -352,7 +316,7 @@ static ssize_t set_temp_crit_hyst(struct device *dev, | |||
352 | if (kstrtoul(buf, 10, &val) < 0) | 316 | if (kstrtoul(buf, 10, &val) < 0) |
353 | return -EINVAL; | 317 | return -EINVAL; |
354 | 318 | ||
355 | diff = jc42_temp_from_reg(data->temp_crit) - val; | 319 | diff = jc42_temp_from_reg(data->temp[t_crit]) - val; |
356 | hyst = 0; | 320 | hyst = 0; |
357 | if (diff > 0) { | 321 | if (diff > 0) { |
358 | if (diff < 2250) | 322 | if (diff < 2250) |
@@ -384,25 +348,20 @@ static ssize_t show_alarm(struct device *dev, | |||
384 | if (IS_ERR(data)) | 348 | if (IS_ERR(data)) |
385 | return PTR_ERR(data); | 349 | return PTR_ERR(data); |
386 | 350 | ||
387 | val = data->temp_input; | 351 | val = data->temp[t_input]; |
388 | if (bit != JC42_ALARM_CRIT_BIT && (data->config & JC42_CFG_CRIT_ONLY)) | 352 | if (bit != JC42_ALARM_CRIT_BIT && (data->config & JC42_CFG_CRIT_ONLY)) |
389 | val = 0; | 353 | val = 0; |
390 | return sprintf(buf, "%u\n", (val >> bit) & 1); | 354 | return sprintf(buf, "%u\n", (val >> bit) & 1); |
391 | } | 355 | } |
392 | 356 | ||
393 | static DEVICE_ATTR(temp1_input, S_IRUGO, | 357 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input); |
394 | show_temp_input, NULL); | 358 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, set_temp, t_crit); |
395 | static DEVICE_ATTR(temp1_crit, S_IRUGO, | 359 | static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp, set_temp, t_min); |
396 | show_temp_crit, set_temp_crit); | 360 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, set_temp, t_max); |
397 | static DEVICE_ATTR(temp1_min, S_IRUGO, | ||
398 | show_temp_min, set_temp_min); | ||
399 | static DEVICE_ATTR(temp1_max, S_IRUGO, | ||
400 | show_temp_max, set_temp_max); | ||
401 | 361 | ||
402 | static DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, | 362 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_hyst, |
403 | show_temp_crit_hyst, set_temp_crit_hyst); | 363 | set_temp_crit_hyst, t_crit); |
404 | static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, | 364 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp_hyst, NULL, t_max); |
405 | show_temp_max_hyst, NULL); | ||
406 | 365 | ||
407 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, | 366 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, |
408 | JC42_ALARM_CRIT_BIT); | 367 | JC42_ALARM_CRIT_BIT); |
@@ -412,12 +371,12 @@ static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, | |||
412 | JC42_ALARM_MAX_BIT); | 371 | JC42_ALARM_MAX_BIT); |
413 | 372 | ||
414 | static struct attribute *jc42_attributes[] = { | 373 | static struct attribute *jc42_attributes[] = { |
415 | &dev_attr_temp1_input.attr, | 374 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
416 | &dev_attr_temp1_crit.attr, | 375 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
417 | &dev_attr_temp1_min.attr, | 376 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
418 | &dev_attr_temp1_max.attr, | 377 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
419 | &dev_attr_temp1_crit_hyst.attr, | 378 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, |
420 | &dev_attr_temp1_max_hyst.attr, | 379 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
421 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 380 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
422 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | 381 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, |
423 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 382 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
@@ -432,12 +391,12 @@ static umode_t jc42_attribute_mode(struct kobject *kobj, | |||
432 | unsigned int config = data->config; | 391 | unsigned int config = data->config; |
433 | bool readonly; | 392 | bool readonly; |
434 | 393 | ||
435 | if (attr == &dev_attr_temp1_crit.attr) | 394 | if (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr) |
436 | readonly = config & JC42_CFG_TCRIT_LOCK; | 395 | readonly = config & JC42_CFG_TCRIT_LOCK; |
437 | else if (attr == &dev_attr_temp1_min.attr || | 396 | else if (attr == &sensor_dev_attr_temp1_min.dev_attr.attr || |
438 | attr == &dev_attr_temp1_max.attr) | 397 | attr == &sensor_dev_attr_temp1_max.dev_attr.attr) |
439 | readonly = config & JC42_CFG_EVENT_LOCK; | 398 | readonly = config & JC42_CFG_EVENT_LOCK; |
440 | else if (attr == &dev_attr_temp1_crit_hyst.attr) | 399 | else if (attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr) |
441 | readonly = config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK); | 400 | readonly = config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK); |
442 | else | 401 | else |
443 | readonly = true; | 402 | readonly = true; |
@@ -537,52 +496,56 @@ static int jc42_remove(struct i2c_client *client) | |||
537 | return 0; | 496 | return 0; |
538 | } | 497 | } |
539 | 498 | ||
540 | static struct jc42_data *jc42_update_device(struct device *dev) | 499 | #ifdef CONFIG_PM |
500 | |||
501 | static int jc42_suspend(struct device *dev) | ||
541 | { | 502 | { |
542 | struct jc42_data *data = dev_get_drvdata(dev); | 503 | struct jc42_data *data = dev_get_drvdata(dev); |
543 | struct i2c_client *client = data->client; | ||
544 | struct jc42_data *ret = data; | ||
545 | int val; | ||
546 | 504 | ||
547 | mutex_lock(&data->update_lock); | 505 | data->config |= JC42_CFG_SHUTDOWN; |
506 | i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, | ||
507 | data->config); | ||
508 | return 0; | ||
509 | } | ||
548 | 510 | ||
549 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 511 | static int jc42_resume(struct device *dev) |
550 | val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP); | 512 | { |
551 | if (val < 0) { | 513 | struct jc42_data *data = dev_get_drvdata(dev); |
552 | ret = ERR_PTR(val); | ||
553 | goto abort; | ||
554 | } | ||
555 | data->temp_input = val; | ||
556 | 514 | ||
557 | val = i2c_smbus_read_word_swapped(client, | 515 | data->config &= ~JC42_CFG_SHUTDOWN; |
558 | JC42_REG_TEMP_CRITICAL); | 516 | i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, |
559 | if (val < 0) { | 517 | data->config); |
560 | ret = ERR_PTR(val); | 518 | return 0; |
561 | goto abort; | 519 | } |
562 | } | ||
563 | data->temp_crit = val; | ||
564 | 520 | ||
565 | val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_LOWER); | 521 | static const struct dev_pm_ops jc42_dev_pm_ops = { |
566 | if (val < 0) { | 522 | .suspend = jc42_suspend, |
567 | ret = ERR_PTR(val); | 523 | .resume = jc42_resume, |
568 | goto abort; | 524 | }; |
569 | } | ||
570 | data->temp_min = val; | ||
571 | 525 | ||
572 | val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_UPPER); | 526 | #define JC42_DEV_PM_OPS (&jc42_dev_pm_ops) |
573 | if (val < 0) { | 527 | #else |
574 | ret = ERR_PTR(val); | 528 | #define JC42_DEV_PM_OPS NULL |
575 | goto abort; | 529 | #endif /* CONFIG_PM */ |
576 | } | ||
577 | data->temp_max = val; | ||
578 | 530 | ||
579 | data->last_updated = jiffies; | 531 | static const struct i2c_device_id jc42_id[] = { |
580 | data->valid = true; | 532 | { "jc42", 0 }, |
581 | } | 533 | { } |
582 | abort: | 534 | }; |
583 | mutex_unlock(&data->update_lock); | 535 | MODULE_DEVICE_TABLE(i2c, jc42_id); |
584 | return ret; | 536 | |
585 | } | 537 | static struct i2c_driver jc42_driver = { |
538 | .class = I2C_CLASS_SPD, | ||
539 | .driver = { | ||
540 | .name = "jc42", | ||
541 | .pm = JC42_DEV_PM_OPS, | ||
542 | }, | ||
543 | .probe = jc42_probe, | ||
544 | .remove = jc42_remove, | ||
545 | .id_table = jc42_id, | ||
546 | .detect = jc42_detect, | ||
547 | .address_list = normal_i2c, | ||
548 | }; | ||
586 | 549 | ||
587 | module_i2c_driver(jc42_driver); | 550 | module_i2c_driver(jc42_driver); |
588 | 551 | ||
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index 505a59e100b0..97204dce162d 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #define LM70_CHIP_LM74 3 /* NS LM74 */ | 47 | #define LM70_CHIP_LM74 3 /* NS LM74 */ |
48 | 48 | ||
49 | struct lm70 { | 49 | struct lm70 { |
50 | struct device *hwmon_dev; | 50 | struct spi_device *spi; |
51 | struct mutex lock; | 51 | struct mutex lock; |
52 | unsigned int chip; | 52 | unsigned int chip; |
53 | }; | 53 | }; |
@@ -56,11 +56,11 @@ struct lm70 { | |||
56 | static ssize_t lm70_sense_temp(struct device *dev, | 56 | static ssize_t lm70_sense_temp(struct device *dev, |
57 | struct device_attribute *attr, char *buf) | 57 | struct device_attribute *attr, char *buf) |
58 | { | 58 | { |
59 | struct spi_device *spi = to_spi_device(dev); | 59 | struct lm70 *p_lm70 = dev_get_drvdata(dev); |
60 | struct spi_device *spi = p_lm70->spi; | ||
60 | int status, val = 0; | 61 | int status, val = 0; |
61 | u8 rxbuf[2]; | 62 | u8 rxbuf[2]; |
62 | s16 raw = 0; | 63 | s16 raw = 0; |
63 | struct lm70 *p_lm70 = spi_get_drvdata(spi); | ||
64 | 64 | ||
65 | if (mutex_lock_interruptible(&p_lm70->lock)) | 65 | if (mutex_lock_interruptible(&p_lm70->lock)) |
66 | return -ERESTARTSYS; | 66 | return -ERESTARTSYS; |
@@ -121,21 +121,20 @@ out: | |||
121 | 121 | ||
122 | static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL); | 122 | static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL); |
123 | 123 | ||
124 | static ssize_t lm70_show_name(struct device *dev, struct device_attribute | 124 | static struct attribute *lm70_attrs[] = { |
125 | *devattr, char *buf) | 125 | &dev_attr_temp1_input.attr, |
126 | { | 126 | NULL |
127 | return sprintf(buf, "%s\n", to_spi_device(dev)->modalias); | 127 | }; |
128 | } | ||
129 | 128 | ||
130 | static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL); | 129 | ATTRIBUTE_GROUPS(lm70); |
131 | 130 | ||
132 | /*----------------------------------------------------------------------*/ | 131 | /*----------------------------------------------------------------------*/ |
133 | 132 | ||
134 | static int lm70_probe(struct spi_device *spi) | 133 | static int lm70_probe(struct spi_device *spi) |
135 | { | 134 | { |
136 | int chip = spi_get_device_id(spi)->driver_data; | 135 | int chip = spi_get_device_id(spi)->driver_data; |
136 | struct device *hwmon_dev; | ||
137 | struct lm70 *p_lm70; | 137 | struct lm70 *p_lm70; |
138 | int status; | ||
139 | 138 | ||
140 | /* signaling is SPI_MODE_0 */ | 139 | /* signaling is SPI_MODE_0 */ |
141 | if (spi->mode & (SPI_CPOL | SPI_CPHA)) | 140 | if (spi->mode & (SPI_CPOL | SPI_CPHA)) |
@@ -149,46 +148,14 @@ static int lm70_probe(struct spi_device *spi) | |||
149 | 148 | ||
150 | mutex_init(&p_lm70->lock); | 149 | mutex_init(&p_lm70->lock); |
151 | p_lm70->chip = chip; | 150 | p_lm70->chip = chip; |
151 | p_lm70->spi = spi; | ||
152 | 152 | ||
153 | spi_set_drvdata(spi, p_lm70); | 153 | hwmon_dev = devm_hwmon_device_register_with_groups(&spi->dev, |
154 | 154 | spi->modalias, | |
155 | status = device_create_file(&spi->dev, &dev_attr_temp1_input); | 155 | p_lm70, lm70_groups); |
156 | if (status) | 156 | return PTR_ERR_OR_ZERO(hwmon_dev); |
157 | goto out_dev_create_temp_file_failed; | ||
158 | status = device_create_file(&spi->dev, &dev_attr_name); | ||
159 | if (status) | ||
160 | goto out_dev_create_file_failed; | ||
161 | |||
162 | /* sysfs hook */ | ||
163 | p_lm70->hwmon_dev = hwmon_device_register(&spi->dev); | ||
164 | if (IS_ERR(p_lm70->hwmon_dev)) { | ||
165 | dev_dbg(&spi->dev, "hwmon_device_register failed.\n"); | ||
166 | status = PTR_ERR(p_lm70->hwmon_dev); | ||
167 | goto out_dev_reg_failed; | ||
168 | } | ||
169 | |||
170 | return 0; | ||
171 | |||
172 | out_dev_reg_failed: | ||
173 | device_remove_file(&spi->dev, &dev_attr_name); | ||
174 | out_dev_create_file_failed: | ||
175 | device_remove_file(&spi->dev, &dev_attr_temp1_input); | ||
176 | out_dev_create_temp_file_failed: | ||
177 | return status; | ||
178 | } | 157 | } |
179 | 158 | ||
180 | static int lm70_remove(struct spi_device *spi) | ||
181 | { | ||
182 | struct lm70 *p_lm70 = spi_get_drvdata(spi); | ||
183 | |||
184 | hwmon_device_unregister(p_lm70->hwmon_dev); | ||
185 | device_remove_file(&spi->dev, &dev_attr_temp1_input); | ||
186 | device_remove_file(&spi->dev, &dev_attr_name); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | |||
192 | static const struct spi_device_id lm70_ids[] = { | 159 | static const struct spi_device_id lm70_ids[] = { |
193 | { "lm70", LM70_CHIP_LM70 }, | 160 | { "lm70", LM70_CHIP_LM70 }, |
194 | { "tmp121", LM70_CHIP_TMP121 }, | 161 | { "tmp121", LM70_CHIP_TMP121 }, |
@@ -205,7 +172,6 @@ static struct spi_driver lm70_driver = { | |||
205 | }, | 172 | }, |
206 | .id_table = lm70_ids, | 173 | .id_table = lm70_ids, |
207 | .probe = lm70_probe, | 174 | .probe = lm70_probe, |
208 | .remove = lm70_remove, | ||
209 | }; | 175 | }; |
210 | 176 | ||
211 | module_spi_driver(lm70_driver); | 177 | module_spi_driver(lm70_driver); |
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 84a55eacd903..479ffbeed3f8 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -72,6 +72,7 @@ static const u8 LM75_REG_TEMP[3] = { | |||
72 | 72 | ||
73 | /* Each client has this additional data */ | 73 | /* Each client has this additional data */ |
74 | struct lm75_data { | 74 | struct lm75_data { |
75 | struct i2c_client *client; | ||
75 | struct device *hwmon_dev; | 76 | struct device *hwmon_dev; |
76 | struct thermal_zone_device *tz; | 77 | struct thermal_zone_device *tz; |
77 | struct mutex update_lock; | 78 | struct mutex update_lock; |
@@ -130,8 +131,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, | |||
130 | const char *buf, size_t count) | 131 | const char *buf, size_t count) |
131 | { | 132 | { |
132 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 133 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
133 | struct i2c_client *client = to_i2c_client(dev); | 134 | struct lm75_data *data = dev_get_drvdata(dev); |
134 | struct lm75_data *data = i2c_get_clientdata(client); | 135 | struct i2c_client *client = data->client; |
135 | int nr = attr->index; | 136 | int nr = attr->index; |
136 | long temp; | 137 | long temp; |
137 | int error; | 138 | int error; |
@@ -165,17 +166,14 @@ static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, | |||
165 | show_temp, set_temp, 2); | 166 | show_temp, set_temp, 2); |
166 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | 167 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); |
167 | 168 | ||
168 | static struct attribute *lm75_attributes[] = { | 169 | static struct attribute *lm75_attrs[] = { |
169 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 170 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
170 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 171 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
171 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | 172 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
172 | 173 | ||
173 | NULL | 174 | NULL |
174 | }; | 175 | }; |
175 | 176 | ATTRIBUTE_GROUPS(lm75); | |
176 | static const struct attribute_group lm75_group = { | ||
177 | .attrs = lm75_attributes, | ||
178 | }; | ||
179 | 177 | ||
180 | /*-----------------------------------------------------------------------*/ | 178 | /*-----------------------------------------------------------------------*/ |
181 | 179 | ||
@@ -184,6 +182,7 @@ static const struct attribute_group lm75_group = { | |||
184 | static int | 182 | static int |
185 | lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | 183 | lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) |
186 | { | 184 | { |
185 | struct device *dev = &client->dev; | ||
187 | struct lm75_data *data; | 186 | struct lm75_data *data; |
188 | int status; | 187 | int status; |
189 | u8 set_mask, clr_mask; | 188 | u8 set_mask, clr_mask; |
@@ -194,10 +193,11 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
194 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) | 193 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) |
195 | return -EIO; | 194 | return -EIO; |
196 | 195 | ||
197 | data = devm_kzalloc(&client->dev, sizeof(struct lm75_data), GFP_KERNEL); | 196 | data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); |
198 | if (!data) | 197 | if (!data) |
199 | return -ENOMEM; | 198 | return -ENOMEM; |
200 | 199 | ||
200 | data->client = client; | ||
201 | i2c_set_clientdata(client, data); | 201 | i2c_set_clientdata(client, data); |
202 | mutex_init(&data->update_lock); | 202 | mutex_init(&data->update_lock); |
203 | 203 | ||
@@ -269,7 +269,7 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
269 | /* configure as specified */ | 269 | /* configure as specified */ |
270 | status = lm75_read_value(client, LM75_REG_CONF); | 270 | status = lm75_read_value(client, LM75_REG_CONF); |
271 | if (status < 0) { | 271 | if (status < 0) { |
272 | dev_dbg(&client->dev, "Can't read config? %d\n", status); | 272 | dev_dbg(dev, "Can't read config? %d\n", status); |
273 | return status; | 273 | return status; |
274 | } | 274 | } |
275 | data->orig_conf = status; | 275 | data->orig_conf = status; |
@@ -277,43 +277,32 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
277 | new |= set_mask; | 277 | new |= set_mask; |
278 | if (status != new) | 278 | if (status != new) |
279 | lm75_write_value(client, LM75_REG_CONF, new); | 279 | lm75_write_value(client, LM75_REG_CONF, new); |
280 | dev_dbg(&client->dev, "Config %02x\n", new); | 280 | dev_dbg(dev, "Config %02x\n", new); |
281 | 281 | ||
282 | /* Register sysfs hooks */ | 282 | data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, |
283 | status = sysfs_create_group(&client->dev.kobj, &lm75_group); | 283 | data, lm75_groups); |
284 | if (status) | 284 | if (IS_ERR(data->hwmon_dev)) |
285 | return status; | 285 | return PTR_ERR(data->hwmon_dev); |
286 | 286 | ||
287 | data->hwmon_dev = hwmon_device_register(&client->dev); | 287 | data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, |
288 | if (IS_ERR(data->hwmon_dev)) { | ||
289 | status = PTR_ERR(data->hwmon_dev); | ||
290 | goto exit_remove; | ||
291 | } | ||
292 | |||
293 | data->tz = thermal_zone_of_sensor_register(&client->dev, | ||
294 | 0, | 288 | 0, |
295 | &client->dev, | 289 | data->hwmon_dev, |
296 | lm75_read_temp, NULL); | 290 | lm75_read_temp, NULL); |
297 | if (IS_ERR(data->tz)) | 291 | if (IS_ERR(data->tz)) |
298 | data->tz = NULL; | 292 | data->tz = NULL; |
299 | 293 | ||
300 | dev_info(&client->dev, "%s: sensor '%s'\n", | 294 | dev_info(dev, "%s: sensor '%s'\n", |
301 | dev_name(data->hwmon_dev), client->name); | 295 | dev_name(data->hwmon_dev), client->name); |
302 | 296 | ||
303 | return 0; | 297 | return 0; |
304 | |||
305 | exit_remove: | ||
306 | sysfs_remove_group(&client->dev.kobj, &lm75_group); | ||
307 | return status; | ||
308 | } | 298 | } |
309 | 299 | ||
310 | static int lm75_remove(struct i2c_client *client) | 300 | static int lm75_remove(struct i2c_client *client) |
311 | { | 301 | { |
312 | struct lm75_data *data = i2c_get_clientdata(client); | 302 | struct lm75_data *data = i2c_get_clientdata(client); |
313 | 303 | ||
314 | thermal_zone_of_sensor_unregister(&client->dev, data->tz); | 304 | thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz); |
315 | hwmon_device_unregister(data->hwmon_dev); | 305 | hwmon_device_unregister(data->hwmon_dev); |
316 | sysfs_remove_group(&client->dev.kobj, &lm75_group); | ||
317 | lm75_write_value(client, LM75_REG_CONF, data->orig_conf); | 306 | lm75_write_value(client, LM75_REG_CONF, data->orig_conf); |
318 | return 0; | 307 | return 0; |
319 | } | 308 | } |
@@ -507,8 +496,8 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) | |||
507 | 496 | ||
508 | static struct lm75_data *lm75_update_device(struct device *dev) | 497 | static struct lm75_data *lm75_update_device(struct device *dev) |
509 | { | 498 | { |
510 | struct i2c_client *client = to_i2c_client(dev); | 499 | struct lm75_data *data = dev_get_drvdata(dev); |
511 | struct lm75_data *data = i2c_get_clientdata(client); | 500 | struct i2c_client *client = data->client; |
512 | struct lm75_data *ret = data; | 501 | struct lm75_data *ret = data; |
513 | 502 | ||
514 | mutex_lock(&data->update_lock); | 503 | mutex_lock(&data->update_lock); |
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 502771c06fd9..5ceb443b938d 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c | |||
@@ -19,10 +19,6 @@ | |||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | * GNU General Public License for more details. | 21 | * GNU General Public License for more details. |
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | */ | 22 | */ |
27 | 23 | ||
28 | #include <linux/module.h> | 24 | #include <linux/module.h> |
@@ -47,50 +43,33 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, | |||
47 | #define LM77_REG_TEMP_MIN 0x04 | 43 | #define LM77_REG_TEMP_MIN 0x04 |
48 | #define LM77_REG_TEMP_MAX 0x05 | 44 | #define LM77_REG_TEMP_MAX 0x05 |
49 | 45 | ||
46 | enum temp_index { | ||
47 | t_input = 0, | ||
48 | t_crit, | ||
49 | t_min, | ||
50 | t_max, | ||
51 | t_hyst, | ||
52 | t_num_temp | ||
53 | }; | ||
54 | |||
55 | static const u8 temp_regs[t_num_temp] = { | ||
56 | [t_input] = LM77_REG_TEMP, | ||
57 | [t_min] = LM77_REG_TEMP_MIN, | ||
58 | [t_max] = LM77_REG_TEMP_MAX, | ||
59 | [t_crit] = LM77_REG_TEMP_CRIT, | ||
60 | [t_hyst] = LM77_REG_TEMP_HYST, | ||
61 | }; | ||
62 | |||
50 | /* Each client has this additional data */ | 63 | /* Each client has this additional data */ |
51 | struct lm77_data { | 64 | struct lm77_data { |
52 | struct device *hwmon_dev; | 65 | struct i2c_client *client; |
53 | struct mutex update_lock; | 66 | struct mutex update_lock; |
54 | char valid; | 67 | char valid; |
55 | unsigned long last_updated; /* In jiffies */ | 68 | unsigned long last_updated; /* In jiffies */ |
56 | int temp_input; /* Temperatures */ | 69 | int temp[t_num_temp]; /* index using temp_index */ |
57 | int temp_crit; | ||
58 | int temp_min; | ||
59 | int temp_max; | ||
60 | int temp_hyst; | ||
61 | u8 alarms; | 70 | u8 alarms; |
62 | }; | 71 | }; |
63 | 72 | ||
64 | static int lm77_probe(struct i2c_client *client, | ||
65 | const struct i2c_device_id *id); | ||
66 | static int lm77_detect(struct i2c_client *client, struct i2c_board_info *info); | ||
67 | static void lm77_init_client(struct i2c_client *client); | ||
68 | static int lm77_remove(struct i2c_client *client); | ||
69 | static u16 lm77_read_value(struct i2c_client *client, u8 reg); | ||
70 | static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value); | ||
71 | |||
72 | static struct lm77_data *lm77_update_device(struct device *dev); | ||
73 | |||
74 | |||
75 | static const struct i2c_device_id lm77_id[] = { | ||
76 | { "lm77", 0 }, | ||
77 | { } | ||
78 | }; | ||
79 | MODULE_DEVICE_TABLE(i2c, lm77_id); | ||
80 | |||
81 | /* This is the driver that will be inserted */ | ||
82 | static struct i2c_driver lm77_driver = { | ||
83 | .class = I2C_CLASS_HWMON, | ||
84 | .driver = { | ||
85 | .name = "lm77", | ||
86 | }, | ||
87 | .probe = lm77_probe, | ||
88 | .remove = lm77_remove, | ||
89 | .id_table = lm77_id, | ||
90 | .detect = lm77_detect, | ||
91 | .address_list = normal_i2c, | ||
92 | }; | ||
93 | |||
94 | /* straight from the datasheet */ | 73 | /* straight from the datasheet */ |
95 | #define LM77_TEMP_MIN (-55000) | 74 | #define LM77_TEMP_MIN (-55000) |
96 | #define LM77_TEMP_MAX 125000 | 75 | #define LM77_TEMP_MAX 125000 |
@@ -110,97 +89,109 @@ static inline int LM77_TEMP_FROM_REG(s16 reg) | |||
110 | return (reg / 8) * 500; | 89 | return (reg / 8) * 500; |
111 | } | 90 | } |
112 | 91 | ||
113 | /* sysfs stuff */ | 92 | /* |
114 | 93 | * All registers are word-sized, except for the configuration register. | |
115 | /* read routines for temperature limits */ | 94 | * The LM77 uses the high-byte first convention. |
116 | #define show(value) \ | 95 | */ |
117 | static ssize_t show_##value(struct device *dev, \ | 96 | static u16 lm77_read_value(struct i2c_client *client, u8 reg) |
118 | struct device_attribute *attr, \ | 97 | { |
119 | char *buf) \ | 98 | if (reg == LM77_REG_CONF) |
120 | { \ | 99 | return i2c_smbus_read_byte_data(client, reg); |
121 | struct lm77_data *data = lm77_update_device(dev); \ | 100 | else |
122 | return sprintf(buf, "%d\n", data->value); \ | 101 | return i2c_smbus_read_word_swapped(client, reg); |
123 | } | 102 | } |
124 | 103 | ||
125 | show(temp_input); | 104 | static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value) |
126 | show(temp_crit); | 105 | { |
127 | show(temp_min); | 106 | if (reg == LM77_REG_CONF) |
128 | show(temp_max); | 107 | return i2c_smbus_write_byte_data(client, reg, value); |
108 | else | ||
109 | return i2c_smbus_write_word_swapped(client, reg, value); | ||
110 | } | ||
129 | 111 | ||
130 | /* read routines for hysteresis values */ | 112 | static struct lm77_data *lm77_update_device(struct device *dev) |
131 | static ssize_t show_temp_crit_hyst(struct device *dev, | ||
132 | struct device_attribute *attr, char *buf) | ||
133 | { | 113 | { |
134 | struct lm77_data *data = lm77_update_device(dev); | 114 | struct lm77_data *data = dev_get_drvdata(dev); |
135 | return sprintf(buf, "%d\n", data->temp_crit - data->temp_hyst); | 115 | struct i2c_client *client = data->client; |
116 | int i; | ||
117 | |||
118 | mutex_lock(&data->update_lock); | ||
119 | |||
120 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | ||
121 | || !data->valid) { | ||
122 | dev_dbg(&client->dev, "Starting lm77 update\n"); | ||
123 | for (i = 0; i < t_num_temp; i++) { | ||
124 | data->temp[i] = | ||
125 | LM77_TEMP_FROM_REG(lm77_read_value(client, | ||
126 | temp_regs[i])); | ||
127 | } | ||
128 | data->alarms = | ||
129 | lm77_read_value(client, LM77_REG_TEMP) & 0x0007; | ||
130 | data->last_updated = jiffies; | ||
131 | data->valid = 1; | ||
132 | } | ||
133 | |||
134 | mutex_unlock(&data->update_lock); | ||
135 | |||
136 | return data; | ||
136 | } | 137 | } |
137 | static ssize_t show_temp_min_hyst(struct device *dev, | 138 | |
138 | struct device_attribute *attr, char *buf) | 139 | /* sysfs stuff */ |
140 | |||
141 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
142 | char *buf) | ||
139 | { | 143 | { |
144 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
140 | struct lm77_data *data = lm77_update_device(dev); | 145 | struct lm77_data *data = lm77_update_device(dev); |
141 | return sprintf(buf, "%d\n", data->temp_min + data->temp_hyst); | 146 | |
147 | return sprintf(buf, "%d\n", data->temp[attr->index]); | ||
142 | } | 148 | } |
143 | static ssize_t show_temp_max_hyst(struct device *dev, | 149 | |
144 | struct device_attribute *attr, char *buf) | 150 | static ssize_t show_temp_hyst(struct device *dev, |
151 | struct device_attribute *devattr, char *buf) | ||
145 | { | 152 | { |
153 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
146 | struct lm77_data *data = lm77_update_device(dev); | 154 | struct lm77_data *data = lm77_update_device(dev); |
147 | return sprintf(buf, "%d\n", data->temp_max - data->temp_hyst); | 155 | int nr = attr->index; |
148 | } | 156 | int temp; |
149 | 157 | ||
150 | /* write routines */ | 158 | temp = nr == t_min ? data->temp[nr] + data->temp[t_hyst] : |
151 | #define set(value, reg) \ | 159 | data->temp[nr] - data->temp[t_hyst]; |
152 | static ssize_t set_##value(struct device *dev, struct device_attribute *attr, \ | ||
153 | const char *buf, size_t count) \ | ||
154 | { \ | ||
155 | struct i2c_client *client = to_i2c_client(dev); \ | ||
156 | struct lm77_data *data = i2c_get_clientdata(client); \ | ||
157 | long val; \ | ||
158 | int err = kstrtol(buf, 10, &val); \ | ||
159 | if (err) \ | ||
160 | return err; \ | ||
161 | \ | ||
162 | mutex_lock(&data->update_lock); \ | ||
163 | data->value = val; \ | ||
164 | lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value)); \ | ||
165 | mutex_unlock(&data->update_lock); \ | ||
166 | return count; \ | ||
167 | } | ||
168 | 160 | ||
169 | set(temp_min, LM77_REG_TEMP_MIN); | 161 | return sprintf(buf, "%d\n", temp); |
170 | set(temp_max, LM77_REG_TEMP_MAX); | 162 | } |
171 | 163 | ||
172 | /* | 164 | static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, |
173 | * hysteresis is stored as a relative value on the chip, so it has to be | 165 | const char *buf, size_t count) |
174 | * converted first | ||
175 | */ | ||
176 | static ssize_t set_temp_crit_hyst(struct device *dev, | ||
177 | struct device_attribute *attr, | ||
178 | const char *buf, size_t count) | ||
179 | { | 166 | { |
180 | struct i2c_client *client = to_i2c_client(dev); | 167 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
181 | struct lm77_data *data = i2c_get_clientdata(client); | 168 | struct lm77_data *data = dev_get_drvdata(dev); |
182 | unsigned long val; | 169 | struct i2c_client *client = data->client; |
170 | int nr = attr->index; | ||
171 | long val; | ||
183 | int err; | 172 | int err; |
184 | 173 | ||
185 | err = kstrtoul(buf, 10, &val); | 174 | err = kstrtol(buf, 10, &val); |
186 | if (err) | 175 | if (err) |
187 | return err; | 176 | return err; |
188 | 177 | ||
189 | mutex_lock(&data->update_lock); | 178 | mutex_lock(&data->update_lock); |
190 | data->temp_hyst = data->temp_crit - val; | 179 | data->temp[nr] = val; |
191 | lm77_write_value(client, LM77_REG_TEMP_HYST, | 180 | lm77_write_value(client, temp_regs[nr], LM77_TEMP_TO_REG(val)); |
192 | LM77_TEMP_TO_REG(data->temp_hyst)); | ||
193 | mutex_unlock(&data->update_lock); | 181 | mutex_unlock(&data->update_lock); |
194 | return count; | 182 | return count; |
195 | } | 183 | } |
196 | 184 | ||
197 | /* preserve hysteresis when setting T_crit */ | 185 | /* |
198 | static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, | 186 | * hysteresis is stored as a relative value on the chip, so it has to be |
187 | * converted first. | ||
188 | */ | ||
189 | static ssize_t set_temp_hyst(struct device *dev, | ||
190 | struct device_attribute *devattr, | ||
199 | const char *buf, size_t count) | 191 | const char *buf, size_t count) |
200 | { | 192 | { |
201 | struct i2c_client *client = to_i2c_client(dev); | 193 | struct lm77_data *data = dev_get_drvdata(dev); |
202 | struct lm77_data *data = i2c_get_clientdata(client); | 194 | struct i2c_client *client = data->client; |
203 | int oldcrithyst; | ||
204 | unsigned long val; | 195 | unsigned long val; |
205 | int err; | 196 | int err; |
206 | 197 | ||
@@ -209,13 +200,9 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, | |||
209 | return err; | 200 | return err; |
210 | 201 | ||
211 | mutex_lock(&data->update_lock); | 202 | mutex_lock(&data->update_lock); |
212 | oldcrithyst = data->temp_crit - data->temp_hyst; | 203 | data->temp[t_hyst] = data->temp[t_crit] - val; |
213 | data->temp_crit = val; | ||
214 | data->temp_hyst = data->temp_crit - oldcrithyst; | ||
215 | lm77_write_value(client, LM77_REG_TEMP_CRIT, | ||
216 | LM77_TEMP_TO_REG(data->temp_crit)); | ||
217 | lm77_write_value(client, LM77_REG_TEMP_HYST, | 204 | lm77_write_value(client, LM77_REG_TEMP_HYST, |
218 | LM77_TEMP_TO_REG(data->temp_hyst)); | 205 | LM77_TEMP_TO_REG(data->temp[t_hyst])); |
219 | mutex_unlock(&data->update_lock); | 206 | mutex_unlock(&data->update_lock); |
220 | return count; | 207 | return count; |
221 | } | 208 | } |
@@ -228,43 +215,37 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | |||
228 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); | 215 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); |
229 | } | 216 | } |
230 | 217 | ||
231 | static DEVICE_ATTR(temp1_input, S_IRUGO, | 218 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input); |
232 | show_temp_input, NULL); | 219 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp, set_temp, |
233 | static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, | 220 | t_crit); |
234 | show_temp_crit, set_temp_crit); | 221 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp, set_temp, |
235 | static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, | 222 | t_min); |
236 | show_temp_min, set_temp_min); | 223 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp, set_temp, |
237 | static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | 224 | t_max); |
238 | show_temp_max, set_temp_max); | 225 | |
239 | 226 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst, | |
240 | static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, | 227 | set_temp_hyst, t_crit); |
241 | show_temp_crit_hyst, set_temp_crit_hyst); | 228 | static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_temp_hyst, NULL, t_min); |
242 | static DEVICE_ATTR(temp1_min_hyst, S_IRUGO, | 229 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp_hyst, NULL, t_max); |
243 | show_temp_min_hyst, NULL); | ||
244 | static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, | ||
245 | show_temp_max_hyst, NULL); | ||
246 | 230 | ||
247 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2); | 231 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2); |
248 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0); | 232 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0); |
249 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); | 233 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); |
250 | 234 | ||
251 | static struct attribute *lm77_attributes[] = { | 235 | static struct attribute *lm77_attrs[] = { |
252 | &dev_attr_temp1_input.attr, | 236 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
253 | &dev_attr_temp1_crit.attr, | 237 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
254 | &dev_attr_temp1_min.attr, | 238 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
255 | &dev_attr_temp1_max.attr, | 239 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
256 | &dev_attr_temp1_crit_hyst.attr, | 240 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, |
257 | &dev_attr_temp1_min_hyst.attr, | 241 | &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, |
258 | &dev_attr_temp1_max_hyst.attr, | 242 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
259 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 243 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
260 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | 244 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, |
261 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 245 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
262 | NULL | 246 | NULL |
263 | }; | 247 | }; |
264 | 248 | ATTRIBUTE_GROUPS(lm77); | |
265 | static const struct attribute_group lm77_group = { | ||
266 | .attrs = lm77_attributes, | ||
267 | }; | ||
268 | 249 | ||
269 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 250 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
270 | static int lm77_detect(struct i2c_client *client, struct i2c_board_info *info) | 251 | static int lm77_detect(struct i2c_client *client, struct i2c_board_info *info) |
@@ -337,111 +318,52 @@ static int lm77_detect(struct i2c_client *client, struct i2c_board_info *info) | |||
337 | return 0; | 318 | return 0; |
338 | } | 319 | } |
339 | 320 | ||
321 | static void lm77_init_client(struct i2c_client *client) | ||
322 | { | ||
323 | /* Initialize the LM77 chip - turn off shutdown mode */ | ||
324 | int conf = lm77_read_value(client, LM77_REG_CONF); | ||
325 | if (conf & 1) | ||
326 | lm77_write_value(client, LM77_REG_CONF, conf & 0xfe); | ||
327 | } | ||
328 | |||
340 | static int lm77_probe(struct i2c_client *client, const struct i2c_device_id *id) | 329 | static int lm77_probe(struct i2c_client *client, const struct i2c_device_id *id) |
341 | { | 330 | { |
342 | struct device *dev = &client->dev; | 331 | struct device *dev = &client->dev; |
332 | struct device *hwmon_dev; | ||
343 | struct lm77_data *data; | 333 | struct lm77_data *data; |
344 | int err; | ||
345 | 334 | ||
346 | data = devm_kzalloc(dev, sizeof(struct lm77_data), GFP_KERNEL); | 335 | data = devm_kzalloc(dev, sizeof(struct lm77_data), GFP_KERNEL); |
347 | if (!data) | 336 | if (!data) |
348 | return -ENOMEM; | 337 | return -ENOMEM; |
349 | 338 | ||
350 | i2c_set_clientdata(client, data); | 339 | data->client = client; |
351 | mutex_init(&data->update_lock); | 340 | mutex_init(&data->update_lock); |
352 | 341 | ||
353 | /* Initialize the LM77 chip */ | 342 | /* Initialize the LM77 chip */ |
354 | lm77_init_client(client); | 343 | lm77_init_client(client); |
355 | 344 | ||
356 | /* Register sysfs hooks */ | 345 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, |
357 | err = sysfs_create_group(&dev->kobj, &lm77_group); | 346 | data, lm77_groups); |
358 | if (err) | 347 | return PTR_ERR_OR_ZERO(hwmon_dev); |
359 | return err; | ||
360 | |||
361 | data->hwmon_dev = hwmon_device_register(dev); | ||
362 | if (IS_ERR(data->hwmon_dev)) { | ||
363 | err = PTR_ERR(data->hwmon_dev); | ||
364 | goto exit_remove; | ||
365 | } | ||
366 | |||
367 | return 0; | ||
368 | |||
369 | exit_remove: | ||
370 | sysfs_remove_group(&dev->kobj, &lm77_group); | ||
371 | return err; | ||
372 | } | 348 | } |
373 | 349 | ||
374 | static int lm77_remove(struct i2c_client *client) | 350 | static const struct i2c_device_id lm77_id[] = { |
375 | { | 351 | { "lm77", 0 }, |
376 | struct lm77_data *data = i2c_get_clientdata(client); | 352 | { } |
377 | hwmon_device_unregister(data->hwmon_dev); | 353 | }; |
378 | sysfs_remove_group(&client->dev.kobj, &lm77_group); | 354 | MODULE_DEVICE_TABLE(i2c, lm77_id); |
379 | return 0; | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | * All registers are word-sized, except for the configuration register. | ||
384 | * The LM77 uses the high-byte first convention. | ||
385 | */ | ||
386 | static u16 lm77_read_value(struct i2c_client *client, u8 reg) | ||
387 | { | ||
388 | if (reg == LM77_REG_CONF) | ||
389 | return i2c_smbus_read_byte_data(client, reg); | ||
390 | else | ||
391 | return i2c_smbus_read_word_swapped(client, reg); | ||
392 | } | ||
393 | |||
394 | static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value) | ||
395 | { | ||
396 | if (reg == LM77_REG_CONF) | ||
397 | return i2c_smbus_write_byte_data(client, reg, value); | ||
398 | else | ||
399 | return i2c_smbus_write_word_swapped(client, reg, value); | ||
400 | } | ||
401 | |||
402 | static void lm77_init_client(struct i2c_client *client) | ||
403 | { | ||
404 | /* Initialize the LM77 chip - turn off shutdown mode */ | ||
405 | int conf = lm77_read_value(client, LM77_REG_CONF); | ||
406 | if (conf & 1) | ||
407 | lm77_write_value(client, LM77_REG_CONF, conf & 0xfe); | ||
408 | } | ||
409 | |||
410 | static struct lm77_data *lm77_update_device(struct device *dev) | ||
411 | { | ||
412 | struct i2c_client *client = to_i2c_client(dev); | ||
413 | struct lm77_data *data = i2c_get_clientdata(client); | ||
414 | |||
415 | mutex_lock(&data->update_lock); | ||
416 | |||
417 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | ||
418 | || !data->valid) { | ||
419 | dev_dbg(&client->dev, "Starting lm77 update\n"); | ||
420 | data->temp_input = | ||
421 | LM77_TEMP_FROM_REG(lm77_read_value(client, | ||
422 | LM77_REG_TEMP)); | ||
423 | data->temp_hyst = | ||
424 | LM77_TEMP_FROM_REG(lm77_read_value(client, | ||
425 | LM77_REG_TEMP_HYST)); | ||
426 | data->temp_crit = | ||
427 | LM77_TEMP_FROM_REG(lm77_read_value(client, | ||
428 | LM77_REG_TEMP_CRIT)); | ||
429 | data->temp_min = | ||
430 | LM77_TEMP_FROM_REG(lm77_read_value(client, | ||
431 | LM77_REG_TEMP_MIN)); | ||
432 | data->temp_max = | ||
433 | LM77_TEMP_FROM_REG(lm77_read_value(client, | ||
434 | LM77_REG_TEMP_MAX)); | ||
435 | data->alarms = | ||
436 | lm77_read_value(client, LM77_REG_TEMP) & 0x0007; | ||
437 | data->last_updated = jiffies; | ||
438 | data->valid = 1; | ||
439 | } | ||
440 | |||
441 | mutex_unlock(&data->update_lock); | ||
442 | 355 | ||
443 | return data; | 356 | /* This is the driver that will be inserted */ |
444 | } | 357 | static struct i2c_driver lm77_driver = { |
358 | .class = I2C_CLASS_HWMON, | ||
359 | .driver = { | ||
360 | .name = "lm77", | ||
361 | }, | ||
362 | .probe = lm77_probe, | ||
363 | .id_table = lm77_id, | ||
364 | .detect = lm77_detect, | ||
365 | .address_list = normal_i2c, | ||
366 | }; | ||
445 | 367 | ||
446 | module_i2c_driver(lm77_driver); | 368 | module_i2c_driver(lm77_driver); |
447 | 369 | ||
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index bd0a1ebbf867..4bcd9b882948 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c | |||
@@ -86,26 +86,41 @@ static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div) | |||
86 | #define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \ | 86 | #define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \ |
87 | (val) == 255 ? 0 : 1350000/((div) * (val))) | 87 | (val) == 255 ? 0 : 1350000/((div) * (val))) |
88 | 88 | ||
89 | static inline long TEMP_FROM_REG(u16 temp) | 89 | #define TEMP_FROM_REG(reg) ((reg) * 125 / 32) |
90 | { | 90 | #define TEMP_TO_REG(temp) (DIV_ROUND_CLOSEST(clamp_val((temp), \ |
91 | long res; | 91 | -128000, 127000), 1000) << 8) |
92 | 92 | ||
93 | temp >>= 4; | 93 | #define DIV_FROM_REG(val) (1 << (val)) |
94 | if (temp < 0x0800) | ||
95 | res = 625 * (long) temp; | ||
96 | else | ||
97 | res = ((long) temp - 0x01000) * 625; | ||
98 | 94 | ||
99 | return res / 10; | 95 | enum temp_index { |
100 | } | 96 | t_input = 0, |
97 | t_hot_max, | ||
98 | t_hot_hyst, | ||
99 | t_os_max, | ||
100 | t_os_hyst, | ||
101 | t_num_temp | ||
102 | }; | ||
101 | 103 | ||
102 | #define TEMP_LIMIT_FROM_REG(val) (((val) > 0x80 ? \ | 104 | static const u8 temp_regs[t_num_temp] = { |
103 | (val) - 0x100 : (val)) * 1000) | 105 | [t_input] = LM80_REG_TEMP, |
106 | [t_hot_max] = LM80_REG_TEMP_HOT_MAX, | ||
107 | [t_hot_hyst] = LM80_REG_TEMP_HOT_HYST, | ||
108 | [t_os_max] = LM80_REG_TEMP_OS_MAX, | ||
109 | [t_os_hyst] = LM80_REG_TEMP_OS_HYST, | ||
110 | }; | ||
104 | 111 | ||
105 | #define TEMP_LIMIT_TO_REG(val) clamp_val((val) < 0 ? \ | 112 | enum in_index { |
106 | ((val) - 500) / 1000 : ((val) + 500) / 1000, 0, 255) | 113 | i_input = 0, |
114 | i_max, | ||
115 | i_min, | ||
116 | i_num_in | ||
117 | }; | ||
107 | 118 | ||
108 | #define DIV_FROM_REG(val) (1 << (val)) | 119 | enum fan_index { |
120 | f_input, | ||
121 | f_min, | ||
122 | f_num_fan | ||
123 | }; | ||
109 | 124 | ||
110 | /* | 125 | /* |
111 | * Client data (each client gets its own) | 126 | * Client data (each client gets its own) |
@@ -118,106 +133,187 @@ struct lm80_data { | |||
118 | char valid; /* !=0 if following fields are valid */ | 133 | char valid; /* !=0 if following fields are valid */ |
119 | unsigned long last_updated; /* In jiffies */ | 134 | unsigned long last_updated; /* In jiffies */ |
120 | 135 | ||
121 | u8 in[7]; /* Register value */ | 136 | u8 in[i_num_in][7]; /* Register value, 1st index is enum in_index */ |
122 | u8 in_max[7]; /* Register value */ | 137 | u8 fan[f_num_fan][2]; /* Register value, 1st index enum fan_index */ |
123 | u8 in_min[7]; /* Register value */ | ||
124 | u8 fan[2]; /* Register value */ | ||
125 | u8 fan_min[2]; /* Register value */ | ||
126 | u8 fan_div[2]; /* Register encoding, shifted right */ | 138 | u8 fan_div[2]; /* Register encoding, shifted right */ |
127 | u16 temp; /* Register values, shifted right */ | 139 | s16 temp[t_num_temp]; /* Register values, normalized to 16 bit */ |
128 | u8 temp_hot_max; /* Register value */ | ||
129 | u8 temp_hot_hyst; /* Register value */ | ||
130 | u8 temp_os_max; /* Register value */ | ||
131 | u8 temp_os_hyst; /* Register value */ | ||
132 | u16 alarms; /* Register encoding, combined */ | 140 | u16 alarms; /* Register encoding, combined */ |
133 | }; | 141 | }; |
134 | 142 | ||
135 | /* | 143 | static int lm80_read_value(struct i2c_client *client, u8 reg) |
136 | * Functions declaration | 144 | { |
137 | */ | 145 | return i2c_smbus_read_byte_data(client, reg); |
146 | } | ||
138 | 147 | ||
139 | static int lm80_probe(struct i2c_client *client, | 148 | static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value) |
140 | const struct i2c_device_id *id); | 149 | { |
141 | static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info); | 150 | return i2c_smbus_write_byte_data(client, reg, value); |
142 | static void lm80_init_client(struct i2c_client *client); | 151 | } |
143 | static struct lm80_data *lm80_update_device(struct device *dev); | ||
144 | static int lm80_read_value(struct i2c_client *client, u8 reg); | ||
145 | static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); | ||
146 | 152 | ||
147 | /* | 153 | /* Called when we have found a new LM80 and after read errors */ |
148 | * Driver data (common to all clients) | 154 | static void lm80_init_client(struct i2c_client *client) |
149 | */ | 155 | { |
156 | /* | ||
157 | * Reset all except Watchdog values and last conversion values | ||
158 | * This sets fan-divs to 2, among others. This makes most other | ||
159 | * initializations unnecessary | ||
160 | */ | ||
161 | lm80_write_value(client, LM80_REG_CONFIG, 0x80); | ||
162 | /* Set 11-bit temperature resolution */ | ||
163 | lm80_write_value(client, LM80_REG_RES, 0x08); | ||
150 | 164 | ||
151 | static const struct i2c_device_id lm80_id[] = { | 165 | /* Start monitoring */ |
152 | { "lm80", 0 }, | 166 | lm80_write_value(client, LM80_REG_CONFIG, 0x01); |
153 | { "lm96080", 1 }, | 167 | } |
154 | { } | ||
155 | }; | ||
156 | MODULE_DEVICE_TABLE(i2c, lm80_id); | ||
157 | 168 | ||
158 | static struct i2c_driver lm80_driver = { | 169 | static struct lm80_data *lm80_update_device(struct device *dev) |
159 | .class = I2C_CLASS_HWMON, | 170 | { |
160 | .driver = { | 171 | struct lm80_data *data = dev_get_drvdata(dev); |
161 | .name = "lm80", | 172 | struct i2c_client *client = data->client; |
162 | }, | 173 | int i; |
163 | .probe = lm80_probe, | 174 | int rv; |
164 | .id_table = lm80_id, | 175 | int prev_rv; |
165 | .detect = lm80_detect, | 176 | struct lm80_data *ret = data; |
166 | .address_list = normal_i2c, | 177 | |
167 | }; | 178 | mutex_lock(&data->update_lock); |
179 | |||
180 | if (data->error) | ||
181 | lm80_init_client(client); | ||
182 | |||
183 | if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { | ||
184 | dev_dbg(dev, "Starting lm80 update\n"); | ||
185 | for (i = 0; i <= 6; i++) { | ||
186 | rv = lm80_read_value(client, LM80_REG_IN(i)); | ||
187 | if (rv < 0) | ||
188 | goto abort; | ||
189 | data->in[i_input][i] = rv; | ||
190 | |||
191 | rv = lm80_read_value(client, LM80_REG_IN_MIN(i)); | ||
192 | if (rv < 0) | ||
193 | goto abort; | ||
194 | data->in[i_min][i] = rv; | ||
195 | |||
196 | rv = lm80_read_value(client, LM80_REG_IN_MAX(i)); | ||
197 | if (rv < 0) | ||
198 | goto abort; | ||
199 | data->in[i_max][i] = rv; | ||
200 | } | ||
201 | |||
202 | rv = lm80_read_value(client, LM80_REG_FAN1); | ||
203 | if (rv < 0) | ||
204 | goto abort; | ||
205 | data->fan[f_input][0] = rv; | ||
206 | |||
207 | rv = lm80_read_value(client, LM80_REG_FAN_MIN(1)); | ||
208 | if (rv < 0) | ||
209 | goto abort; | ||
210 | data->fan[f_min][0] = rv; | ||
211 | |||
212 | rv = lm80_read_value(client, LM80_REG_FAN2); | ||
213 | if (rv < 0) | ||
214 | goto abort; | ||
215 | data->fan[f_input][1] = rv; | ||
216 | |||
217 | rv = lm80_read_value(client, LM80_REG_FAN_MIN(2)); | ||
218 | if (rv < 0) | ||
219 | goto abort; | ||
220 | data->fan[f_min][1] = rv; | ||
221 | |||
222 | prev_rv = rv = lm80_read_value(client, LM80_REG_TEMP); | ||
223 | if (rv < 0) | ||
224 | goto abort; | ||
225 | rv = lm80_read_value(client, LM80_REG_RES); | ||
226 | if (rv < 0) | ||
227 | goto abort; | ||
228 | data->temp[t_input] = (prev_rv << 8) | (rv & 0xf0); | ||
229 | |||
230 | for (i = t_input + 1; i < t_num_temp; i++) { | ||
231 | rv = lm80_read_value(client, temp_regs[i]); | ||
232 | if (rv < 0) | ||
233 | goto abort; | ||
234 | data->temp[i] = rv << 8; | ||
235 | } | ||
236 | |||
237 | rv = lm80_read_value(client, LM80_REG_FANDIV); | ||
238 | if (rv < 0) | ||
239 | goto abort; | ||
240 | data->fan_div[0] = (rv >> 2) & 0x03; | ||
241 | data->fan_div[1] = (rv >> 4) & 0x03; | ||
242 | |||
243 | prev_rv = rv = lm80_read_value(client, LM80_REG_ALARM1); | ||
244 | if (rv < 0) | ||
245 | goto abort; | ||
246 | rv = lm80_read_value(client, LM80_REG_ALARM2); | ||
247 | if (rv < 0) | ||
248 | goto abort; | ||
249 | data->alarms = prev_rv + (rv << 8); | ||
250 | |||
251 | data->last_updated = jiffies; | ||
252 | data->valid = 1; | ||
253 | data->error = 0; | ||
254 | } | ||
255 | goto done; | ||
256 | |||
257 | abort: | ||
258 | ret = ERR_PTR(rv); | ||
259 | data->valid = 0; | ||
260 | data->error = 1; | ||
261 | |||
262 | done: | ||
263 | mutex_unlock(&data->update_lock); | ||
264 | |||
265 | return ret; | ||
266 | } | ||
168 | 267 | ||
169 | /* | 268 | /* |
170 | * Sysfs stuff | 269 | * Sysfs stuff |
171 | */ | 270 | */ |
172 | 271 | ||
173 | #define show_in(suffix, value) \ | 272 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
174 | static ssize_t show_in_##suffix(struct device *dev, \ | 273 | char *buf) |
175 | struct device_attribute *attr, char *buf) \ | 274 | { |
176 | { \ | 275 | struct lm80_data *data = lm80_update_device(dev); |
177 | int nr = to_sensor_dev_attr(attr)->index; \ | 276 | int index = to_sensor_dev_attr_2(attr)->index; |
178 | struct lm80_data *data = lm80_update_device(dev); \ | 277 | int nr = to_sensor_dev_attr_2(attr)->nr; |
179 | if (IS_ERR(data)) \ | 278 | |
180 | return PTR_ERR(data); \ | 279 | if (IS_ERR(data)) |
181 | return sprintf(buf, "%d\n", IN_FROM_REG(data->value[nr])); \ | 280 | return PTR_ERR(data); |
281 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr][index])); | ||
182 | } | 282 | } |
183 | show_in(min, in_min) | 283 | |
184 | show_in(max, in_max) | 284 | static ssize_t set_in(struct device *dev, struct device_attribute *attr, |
185 | show_in(input, in) | 285 | const char *buf, size_t count) |
186 | 286 | { | |
187 | #define set_in(suffix, value, reg) \ | 287 | struct lm80_data *data = dev_get_drvdata(dev); |
188 | static ssize_t set_in_##suffix(struct device *dev, \ | 288 | struct i2c_client *client = data->client; |
189 | struct device_attribute *attr, const char *buf, size_t count) \ | 289 | int index = to_sensor_dev_attr_2(attr)->index; |
190 | { \ | 290 | int nr = to_sensor_dev_attr_2(attr)->nr; |
191 | int nr = to_sensor_dev_attr(attr)->index; \ | 291 | long val; |
192 | struct lm80_data *data = dev_get_drvdata(dev); \ | 292 | u8 reg; |
193 | struct i2c_client *client = data->client; \ | 293 | int err = kstrtol(buf, 10, &val); |
194 | long val; \ | 294 | if (err < 0) |
195 | int err = kstrtol(buf, 10, &val); \ | 295 | return err; |
196 | if (err < 0) \ | 296 | |
197 | return err; \ | 297 | reg = nr == i_min ? LM80_REG_IN_MIN(index) : LM80_REG_IN_MAX(index); |
198 | \ | 298 | |
199 | mutex_lock(&data->update_lock);\ | 299 | mutex_lock(&data->update_lock); |
200 | data->value[nr] = IN_TO_REG(val); \ | 300 | data->in[nr][index] = IN_TO_REG(val); |
201 | lm80_write_value(client, reg(nr), data->value[nr]); \ | 301 | lm80_write_value(client, reg, data->in[nr][index]); |
202 | mutex_unlock(&data->update_lock);\ | 302 | mutex_unlock(&data->update_lock); |
203 | return count; \ | 303 | return count; |
204 | } | 304 | } |
205 | set_in(min, in_min, LM80_REG_IN_MIN) | 305 | |
206 | set_in(max, in_max, LM80_REG_IN_MAX) | 306 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, |
207 | 307 | char *buf) | |
208 | #define show_fan(suffix, value) \ | 308 | { |
209 | static ssize_t show_fan_##suffix(struct device *dev, \ | 309 | int index = to_sensor_dev_attr_2(attr)->index; |
210 | struct device_attribute *attr, char *buf) \ | 310 | int nr = to_sensor_dev_attr_2(attr)->nr; |
211 | { \ | 311 | struct lm80_data *data = lm80_update_device(dev); |
212 | int nr = to_sensor_dev_attr(attr)->index; \ | 312 | if (IS_ERR(data)) |
213 | struct lm80_data *data = lm80_update_device(dev); \ | 313 | return PTR_ERR(data); |
214 | if (IS_ERR(data)) \ | 314 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr][index], |
215 | return PTR_ERR(data); \ | 315 | DIV_FROM_REG(data->fan_div[index]))); |
216 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->value[nr], \ | ||
217 | DIV_FROM_REG(data->fan_div[nr]))); \ | ||
218 | } | 316 | } |
219 | show_fan(min, fan_min) | ||
220 | show_fan(input, fan) | ||
221 | 317 | ||
222 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, | 318 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, |
223 | char *buf) | 319 | char *buf) |
@@ -232,7 +328,8 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, | |||
232 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | 328 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, |
233 | const char *buf, size_t count) | 329 | const char *buf, size_t count) |
234 | { | 330 | { |
235 | int nr = to_sensor_dev_attr(attr)->index; | 331 | int index = to_sensor_dev_attr_2(attr)->index; |
332 | int nr = to_sensor_dev_attr_2(attr)->nr; | ||
236 | struct lm80_data *data = dev_get_drvdata(dev); | 333 | struct lm80_data *data = dev_get_drvdata(dev); |
237 | struct i2c_client *client = data->client; | 334 | struct i2c_client *client = data->client; |
238 | unsigned long val; | 335 | unsigned long val; |
@@ -241,8 +338,10 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
241 | return err; | 338 | return err; |
242 | 339 | ||
243 | mutex_lock(&data->update_lock); | 340 | mutex_lock(&data->update_lock); |
244 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 341 | data->fan[nr][index] = FAN_TO_REG(val, |
245 | lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]); | 342 | DIV_FROM_REG(data->fan_div[index])); |
343 | lm80_write_value(client, LM80_REG_FAN_MIN(index + 1), | ||
344 | data->fan[nr][index]); | ||
246 | mutex_unlock(&data->update_lock); | 345 | mutex_unlock(&data->update_lock); |
247 | return count; | 346 | return count; |
248 | } | 347 | } |
@@ -267,7 +366,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
267 | 366 | ||
268 | /* Save fan_min */ | 367 | /* Save fan_min */ |
269 | mutex_lock(&data->update_lock); | 368 | mutex_lock(&data->update_lock); |
270 | min = FAN_FROM_REG(data->fan_min[nr], | 369 | min = FAN_FROM_REG(data->fan[f_min][nr], |
271 | DIV_FROM_REG(data->fan_div[nr])); | 370 | DIV_FROM_REG(data->fan_div[nr])); |
272 | 371 | ||
273 | switch (val) { | 372 | switch (val) { |
@@ -291,62 +390,47 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
291 | return -EINVAL; | 390 | return -EINVAL; |
292 | } | 391 | } |
293 | 392 | ||
294 | reg = (lm80_read_value(client, LM80_REG_FANDIV) & ~(3 << (2 * (nr + 1)))) | 393 | reg = (lm80_read_value(client, LM80_REG_FANDIV) & |
295 | | (data->fan_div[nr] << (2 * (nr + 1))); | 394 | ~(3 << (2 * (nr + 1)))) | (data->fan_div[nr] << (2 * (nr + 1))); |
296 | lm80_write_value(client, LM80_REG_FANDIV, reg); | 395 | lm80_write_value(client, LM80_REG_FANDIV, reg); |
297 | 396 | ||
298 | /* Restore fan_min */ | 397 | /* Restore fan_min */ |
299 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 398 | data->fan[f_min][nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
300 | lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]); | 399 | lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), |
400 | data->fan[f_min][nr]); | ||
301 | mutex_unlock(&data->update_lock); | 401 | mutex_unlock(&data->update_lock); |
302 | 402 | ||
303 | return count; | 403 | return count; |
304 | } | 404 | } |
305 | 405 | ||
306 | static ssize_t show_temp_input1(struct device *dev, | 406 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, |
307 | struct device_attribute *attr, char *buf) | 407 | char *buf) |
308 | { | 408 | { |
409 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
309 | struct lm80_data *data = lm80_update_device(dev); | 410 | struct lm80_data *data = lm80_update_device(dev); |
310 | if (IS_ERR(data)) | 411 | if (IS_ERR(data)) |
311 | return PTR_ERR(data); | 412 | return PTR_ERR(data); |
312 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp)); | 413 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index])); |
313 | } | 414 | } |
314 | 415 | ||
315 | #define show_temp(suffix, value) \ | 416 | static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, |
316 | static ssize_t show_temp_##suffix(struct device *dev, \ | 417 | const char *buf, size_t count) |
317 | struct device_attribute *attr, char *buf) \ | 418 | { |
318 | { \ | 419 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
319 | struct lm80_data *data = lm80_update_device(dev); \ | 420 | struct lm80_data *data = dev_get_drvdata(dev); |
320 | if (IS_ERR(data)) \ | 421 | struct i2c_client *client = data->client; |
321 | return PTR_ERR(data); \ | 422 | int nr = attr->index; |
322 | return sprintf(buf, "%d\n", TEMP_LIMIT_FROM_REG(data->value)); \ | 423 | long val; |
323 | } | 424 | int err = kstrtol(buf, 10, &val); |
324 | show_temp(hot_max, temp_hot_max); | 425 | if (err < 0) |
325 | show_temp(hot_hyst, temp_hot_hyst); | 426 | return err; |
326 | show_temp(os_max, temp_os_max); | 427 | |
327 | show_temp(os_hyst, temp_os_hyst); | 428 | mutex_lock(&data->update_lock); |
328 | 429 | data->temp[nr] = TEMP_TO_REG(val); | |
329 | #define set_temp(suffix, value, reg) \ | 430 | lm80_write_value(client, temp_regs[nr], data->temp[nr] >> 8); |
330 | static ssize_t set_temp_##suffix(struct device *dev, \ | 431 | mutex_unlock(&data->update_lock); |
331 | struct device_attribute *attr, const char *buf, size_t count) \ | 432 | return count; |
332 | { \ | ||
333 | struct lm80_data *data = dev_get_drvdata(dev); \ | ||
334 | struct i2c_client *client = data->client; \ | ||
335 | long val; \ | ||
336 | int err = kstrtol(buf, 10, &val); \ | ||
337 | if (err < 0) \ | ||
338 | return err; \ | ||
339 | \ | ||
340 | mutex_lock(&data->update_lock); \ | ||
341 | data->value = TEMP_LIMIT_TO_REG(val); \ | ||
342 | lm80_write_value(client, reg, data->value); \ | ||
343 | mutex_unlock(&data->update_lock); \ | ||
344 | return count; \ | ||
345 | } | 433 | } |
346 | set_temp(hot_max, temp_hot_max, LM80_REG_TEMP_HOT_MAX); | ||
347 | set_temp(hot_hyst, temp_hot_hyst, LM80_REG_TEMP_HOT_HYST); | ||
348 | set_temp(os_max, temp_os_max, LM80_REG_TEMP_OS_MAX); | ||
349 | set_temp(os_hyst, temp_os_hyst, LM80_REG_TEMP_OS_HYST); | ||
350 | 434 | ||
351 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | 435 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, |
352 | char *buf) | 436 | char *buf) |
@@ -367,60 +451,60 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | |||
367 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); | 451 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); |
368 | } | 452 | } |
369 | 453 | ||
370 | static SENSOR_DEVICE_ATTR(in0_min, S_IWUSR | S_IRUGO, | 454 | static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, |
371 | show_in_min, set_in_min, 0); | 455 | show_in, set_in, i_min, 0); |
372 | static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, | 456 | static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, |
373 | show_in_min, set_in_min, 1); | 457 | show_in, set_in, i_min, 1); |
374 | static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, | 458 | static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, |
375 | show_in_min, set_in_min, 2); | 459 | show_in, set_in, i_min, 2); |
376 | static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, | 460 | static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, |
377 | show_in_min, set_in_min, 3); | 461 | show_in, set_in, i_min, 3); |
378 | static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, | 462 | static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, |
379 | show_in_min, set_in_min, 4); | 463 | show_in, set_in, i_min, 4); |
380 | static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, | 464 | static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, |
381 | show_in_min, set_in_min, 5); | 465 | show_in, set_in, i_min, 5); |
382 | static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, | 466 | static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, |
383 | show_in_min, set_in_min, 6); | 467 | show_in, set_in, i_min, 6); |
384 | static SENSOR_DEVICE_ATTR(in0_max, S_IWUSR | S_IRUGO, | 468 | static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, |
385 | show_in_max, set_in_max, 0); | 469 | show_in, set_in, i_max, 0); |
386 | static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, | 470 | static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, |
387 | show_in_max, set_in_max, 1); | 471 | show_in, set_in, i_max, 1); |
388 | static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, | 472 | static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, |
389 | show_in_max, set_in_max, 2); | 473 | show_in, set_in, i_max, 2); |
390 | static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, | 474 | static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, |
391 | show_in_max, set_in_max, 3); | 475 | show_in, set_in, i_max, 3); |
392 | static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, | 476 | static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, |
393 | show_in_max, set_in_max, 4); | 477 | show_in, set_in, i_max, 4); |
394 | static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, | 478 | static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, |
395 | show_in_max, set_in_max, 5); | 479 | show_in, set_in, i_max, 5); |
396 | static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, | 480 | static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, |
397 | show_in_max, set_in_max, 6); | 481 | show_in, set_in, i_max, 6); |
398 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in_input, NULL, 0); | 482 | static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, i_input, 0); |
399 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in_input, NULL, 1); | 483 | static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, i_input, 1); |
400 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in_input, NULL, 2); | 484 | static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, i_input, 2); |
401 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in_input, NULL, 3); | 485 | static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, i_input, 3); |
402 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in_input, NULL, 4); | 486 | static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, i_input, 4); |
403 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in_input, NULL, 5); | 487 | static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, i_input, 5); |
404 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in_input, NULL, 6); | 488 | static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in, NULL, i_input, 6); |
405 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, | 489 | static SENSOR_DEVICE_ATTR_2(fan1_min, S_IWUSR | S_IRUGO, |
406 | show_fan_min, set_fan_min, 0); | 490 | show_fan, set_fan_min, f_min, 0); |
407 | static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, | 491 | static SENSOR_DEVICE_ATTR_2(fan2_min, S_IWUSR | S_IRUGO, |
408 | show_fan_min, set_fan_min, 1); | 492 | show_fan, set_fan_min, f_min, 1); |
409 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0); | 493 | static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, f_input, 0); |
410 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1); | 494 | static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, f_input, 1); |
411 | static SENSOR_DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, | 495 | static SENSOR_DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, |
412 | show_fan_div, set_fan_div, 0); | 496 | show_fan_div, set_fan_div, 0); |
413 | static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, | 497 | static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, |
414 | show_fan_div, set_fan_div, 1); | 498 | show_fan_div, set_fan_div, 1); |
415 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); | 499 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input); |
416 | static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_hot_max, | 500 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp, |
417 | set_temp_hot_max); | 501 | set_temp, t_hot_max); |
418 | static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hot_hyst, | 502 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp, |
419 | set_temp_hot_hyst); | 503 | set_temp, t_hot_hyst); |
420 | static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_os_max, | 504 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp, |
421 | set_temp_os_max); | 505 | set_temp, t_os_max); |
422 | static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_os_hyst, | 506 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp, |
423 | set_temp_os_hyst); | 507 | set_temp, t_os_hyst); |
424 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 508 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
425 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | 509 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); |
426 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | 510 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); |
@@ -466,11 +550,11 @@ static struct attribute *lm80_attrs[] = { | |||
466 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 550 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
467 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 551 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
468 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 552 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
469 | &dev_attr_temp1_input.attr, | 553 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
470 | &dev_attr_temp1_max.attr, | 554 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
471 | &dev_attr_temp1_max_hyst.attr, | 555 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
472 | &dev_attr_temp1_crit.attr, | 556 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
473 | &dev_attr_temp1_crit_hyst.attr, | 557 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, |
474 | &dev_attr_alarms.attr, | 558 | &dev_attr_alarms.attr, |
475 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | 559 | &sensor_dev_attr_in0_alarm.dev_attr.attr, |
476 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | 560 | &sensor_dev_attr_in1_alarm.dev_attr.attr, |
@@ -551,8 +635,8 @@ static int lm80_probe(struct i2c_client *client, | |||
551 | lm80_init_client(client); | 635 | lm80_init_client(client); |
552 | 636 | ||
553 | /* A few vars need to be filled upon startup */ | 637 | /* A few vars need to be filled upon startup */ |
554 | data->fan_min[0] = lm80_read_value(client, LM80_REG_FAN_MIN(1)); | 638 | data->fan[f_min][0] = lm80_read_value(client, LM80_REG_FAN_MIN(1)); |
555 | data->fan_min[1] = lm80_read_value(client, LM80_REG_FAN_MIN(2)); | 639 | data->fan[f_min][1] = lm80_read_value(client, LM80_REG_FAN_MIN(2)); |
556 | 640 | ||
557 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, | 641 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, |
558 | data, lm80_groups); | 642 | data, lm80_groups); |
@@ -560,143 +644,27 @@ static int lm80_probe(struct i2c_client *client, | |||
560 | return PTR_ERR_OR_ZERO(hwmon_dev); | 644 | return PTR_ERR_OR_ZERO(hwmon_dev); |
561 | } | 645 | } |
562 | 646 | ||
563 | static int lm80_read_value(struct i2c_client *client, u8 reg) | 647 | /* |
564 | { | 648 | * Driver data (common to all clients) |
565 | return i2c_smbus_read_byte_data(client, reg); | 649 | */ |
566 | } | ||
567 | |||
568 | static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
569 | { | ||
570 | return i2c_smbus_write_byte_data(client, reg, value); | ||
571 | } | ||
572 | |||
573 | /* Called when we have found a new LM80. */ | ||
574 | static void lm80_init_client(struct i2c_client *client) | ||
575 | { | ||
576 | /* | ||
577 | * Reset all except Watchdog values and last conversion values | ||
578 | * This sets fan-divs to 2, among others. This makes most other | ||
579 | * initializations unnecessary | ||
580 | */ | ||
581 | lm80_write_value(client, LM80_REG_CONFIG, 0x80); | ||
582 | /* Set 11-bit temperature resolution */ | ||
583 | lm80_write_value(client, LM80_REG_RES, 0x08); | ||
584 | |||
585 | /* Start monitoring */ | ||
586 | lm80_write_value(client, LM80_REG_CONFIG, 0x01); | ||
587 | } | ||
588 | |||
589 | static struct lm80_data *lm80_update_device(struct device *dev) | ||
590 | { | ||
591 | struct lm80_data *data = dev_get_drvdata(dev); | ||
592 | struct i2c_client *client = data->client; | ||
593 | int i; | ||
594 | int rv; | ||
595 | int prev_rv; | ||
596 | struct lm80_data *ret = data; | ||
597 | |||
598 | mutex_lock(&data->update_lock); | ||
599 | |||
600 | if (data->error) | ||
601 | lm80_init_client(client); | ||
602 | |||
603 | if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { | ||
604 | dev_dbg(dev, "Starting lm80 update\n"); | ||
605 | for (i = 0; i <= 6; i++) { | ||
606 | rv = lm80_read_value(client, LM80_REG_IN(i)); | ||
607 | if (rv < 0) | ||
608 | goto abort; | ||
609 | data->in[i] = rv; | ||
610 | |||
611 | rv = lm80_read_value(client, LM80_REG_IN_MIN(i)); | ||
612 | if (rv < 0) | ||
613 | goto abort; | ||
614 | data->in_min[i] = rv; | ||
615 | |||
616 | rv = lm80_read_value(client, LM80_REG_IN_MAX(i)); | ||
617 | if (rv < 0) | ||
618 | goto abort; | ||
619 | data->in_max[i] = rv; | ||
620 | } | ||
621 | |||
622 | rv = lm80_read_value(client, LM80_REG_FAN1); | ||
623 | if (rv < 0) | ||
624 | goto abort; | ||
625 | data->fan[0] = rv; | ||
626 | |||
627 | rv = lm80_read_value(client, LM80_REG_FAN_MIN(1)); | ||
628 | if (rv < 0) | ||
629 | goto abort; | ||
630 | data->fan_min[0] = rv; | ||
631 | |||
632 | rv = lm80_read_value(client, LM80_REG_FAN2); | ||
633 | if (rv < 0) | ||
634 | goto abort; | ||
635 | data->fan[1] = rv; | ||
636 | |||
637 | rv = lm80_read_value(client, LM80_REG_FAN_MIN(2)); | ||
638 | if (rv < 0) | ||
639 | goto abort; | ||
640 | data->fan_min[1] = rv; | ||
641 | |||
642 | prev_rv = rv = lm80_read_value(client, LM80_REG_TEMP); | ||
643 | if (rv < 0) | ||
644 | goto abort; | ||
645 | rv = lm80_read_value(client, LM80_REG_RES); | ||
646 | if (rv < 0) | ||
647 | goto abort; | ||
648 | data->temp = (prev_rv << 8) | (rv & 0xf0); | ||
649 | |||
650 | rv = lm80_read_value(client, LM80_REG_TEMP_OS_MAX); | ||
651 | if (rv < 0) | ||
652 | goto abort; | ||
653 | data->temp_os_max = rv; | ||
654 | |||
655 | rv = lm80_read_value(client, LM80_REG_TEMP_OS_HYST); | ||
656 | if (rv < 0) | ||
657 | goto abort; | ||
658 | data->temp_os_hyst = rv; | ||
659 | |||
660 | rv = lm80_read_value(client, LM80_REG_TEMP_HOT_MAX); | ||
661 | if (rv < 0) | ||
662 | goto abort; | ||
663 | data->temp_hot_max = rv; | ||
664 | |||
665 | rv = lm80_read_value(client, LM80_REG_TEMP_HOT_HYST); | ||
666 | if (rv < 0) | ||
667 | goto abort; | ||
668 | data->temp_hot_hyst = rv; | ||
669 | |||
670 | rv = lm80_read_value(client, LM80_REG_FANDIV); | ||
671 | if (rv < 0) | ||
672 | goto abort; | ||
673 | data->fan_div[0] = (rv >> 2) & 0x03; | ||
674 | data->fan_div[1] = (rv >> 4) & 0x03; | ||
675 | |||
676 | prev_rv = rv = lm80_read_value(client, LM80_REG_ALARM1); | ||
677 | if (rv < 0) | ||
678 | goto abort; | ||
679 | rv = lm80_read_value(client, LM80_REG_ALARM2); | ||
680 | if (rv < 0) | ||
681 | goto abort; | ||
682 | data->alarms = prev_rv + (rv << 8); | ||
683 | |||
684 | data->last_updated = jiffies; | ||
685 | data->valid = 1; | ||
686 | data->error = 0; | ||
687 | } | ||
688 | goto done; | ||
689 | |||
690 | abort: | ||
691 | ret = ERR_PTR(rv); | ||
692 | data->valid = 0; | ||
693 | data->error = 1; | ||
694 | 650 | ||
695 | done: | 651 | static const struct i2c_device_id lm80_id[] = { |
696 | mutex_unlock(&data->update_lock); | 652 | { "lm80", 0 }, |
653 | { "lm96080", 1 }, | ||
654 | { } | ||
655 | }; | ||
656 | MODULE_DEVICE_TABLE(i2c, lm80_id); | ||
697 | 657 | ||
698 | return ret; | 658 | static struct i2c_driver lm80_driver = { |
699 | } | 659 | .class = I2C_CLASS_HWMON, |
660 | .driver = { | ||
661 | .name = "lm80", | ||
662 | }, | ||
663 | .probe = lm80_probe, | ||
664 | .id_table = lm80_id, | ||
665 | .detect = lm80_detect, | ||
666 | .address_list = normal_i2c, | ||
667 | }; | ||
700 | 668 | ||
701 | module_i2c_driver(lm80_driver); | 669 | module_i2c_driver(lm80_driver); |
702 | 670 | ||
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index be02155788c3..9e4d0e1d3c4b 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c | |||
@@ -25,10 +25,6 @@ | |||
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
27 | * GNU General Public License for more details. | 27 | * GNU General Public License for more details. |
28 | * | ||
29 | * You should have received a copy of the GNU General Public License | ||
30 | * along with this program; if not, write to the Free Software | ||
31 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
32 | */ | 28 | */ |
33 | 29 | ||
34 | #include <linux/module.h> | 30 | #include <linux/module.h> |
@@ -111,45 +107,12 @@ static const u8 LM83_REG_W_HIGH[] = { | |||
111 | }; | 107 | }; |
112 | 108 | ||
113 | /* | 109 | /* |
114 | * Functions declaration | ||
115 | */ | ||
116 | |||
117 | static int lm83_detect(struct i2c_client *new_client, | ||
118 | struct i2c_board_info *info); | ||
119 | static int lm83_probe(struct i2c_client *client, | ||
120 | const struct i2c_device_id *id); | ||
121 | static int lm83_remove(struct i2c_client *client); | ||
122 | static struct lm83_data *lm83_update_device(struct device *dev); | ||
123 | |||
124 | /* | ||
125 | * Driver data (common to all clients) | ||
126 | */ | ||
127 | |||
128 | static const struct i2c_device_id lm83_id[] = { | ||
129 | { "lm83", lm83 }, | ||
130 | { "lm82", lm82 }, | ||
131 | { } | ||
132 | }; | ||
133 | MODULE_DEVICE_TABLE(i2c, lm83_id); | ||
134 | |||
135 | static struct i2c_driver lm83_driver = { | ||
136 | .class = I2C_CLASS_HWMON, | ||
137 | .driver = { | ||
138 | .name = "lm83", | ||
139 | }, | ||
140 | .probe = lm83_probe, | ||
141 | .remove = lm83_remove, | ||
142 | .id_table = lm83_id, | ||
143 | .detect = lm83_detect, | ||
144 | .address_list = normal_i2c, | ||
145 | }; | ||
146 | |||
147 | /* | ||
148 | * Client data (each client gets its own) | 110 | * Client data (each client gets its own) |
149 | */ | 111 | */ |
150 | 112 | ||
151 | struct lm83_data { | 113 | struct lm83_data { |
152 | struct device *hwmon_dev; | 114 | struct i2c_client *client; |
115 | const struct attribute_group *groups[3]; | ||
153 | struct mutex update_lock; | 116 | struct mutex update_lock; |
154 | char valid; /* zero until following fields are valid */ | 117 | char valid; /* zero until following fields are valid */ |
155 | unsigned long last_updated; /* in jiffies */ | 118 | unsigned long last_updated; /* in jiffies */ |
@@ -161,6 +124,36 @@ struct lm83_data { | |||
161 | u16 alarms; /* bitvector, combined */ | 124 | u16 alarms; /* bitvector, combined */ |
162 | }; | 125 | }; |
163 | 126 | ||
127 | static struct lm83_data *lm83_update_device(struct device *dev) | ||
128 | { | ||
129 | struct lm83_data *data = dev_get_drvdata(dev); | ||
130 | struct i2c_client *client = data->client; | ||
131 | |||
132 | mutex_lock(&data->update_lock); | ||
133 | |||
134 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | ||
135 | int nr; | ||
136 | |||
137 | dev_dbg(&client->dev, "Updating lm83 data.\n"); | ||
138 | for (nr = 0; nr < 9; nr++) { | ||
139 | data->temp[nr] = | ||
140 | i2c_smbus_read_byte_data(client, | ||
141 | LM83_REG_R_TEMP[nr]); | ||
142 | } | ||
143 | data->alarms = | ||
144 | i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1) | ||
145 | + (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2) | ||
146 | << 8); | ||
147 | |||
148 | data->last_updated = jiffies; | ||
149 | data->valid = 1; | ||
150 | } | ||
151 | |||
152 | mutex_unlock(&data->update_lock); | ||
153 | |||
154 | return data; | ||
155 | } | ||
156 | |||
164 | /* | 157 | /* |
165 | * Sysfs stuff | 158 | * Sysfs stuff |
166 | */ | 159 | */ |
@@ -177,8 +170,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, | |||
177 | const char *buf, size_t count) | 170 | const char *buf, size_t count) |
178 | { | 171 | { |
179 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 172 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
180 | struct i2c_client *client = to_i2c_client(dev); | 173 | struct lm83_data *data = dev_get_drvdata(dev); |
181 | struct lm83_data *data = i2c_get_clientdata(client); | 174 | struct i2c_client *client = data->client; |
182 | long val; | 175 | long val; |
183 | int nr = attr->index; | 176 | int nr = attr->index; |
184 | int err; | 177 | int err; |
@@ -340,15 +333,15 @@ static int lm83_detect(struct i2c_client *new_client, | |||
340 | static int lm83_probe(struct i2c_client *new_client, | 333 | static int lm83_probe(struct i2c_client *new_client, |
341 | const struct i2c_device_id *id) | 334 | const struct i2c_device_id *id) |
342 | { | 335 | { |
336 | struct device *hwmon_dev; | ||
343 | struct lm83_data *data; | 337 | struct lm83_data *data; |
344 | int err; | ||
345 | 338 | ||
346 | data = devm_kzalloc(&new_client->dev, sizeof(struct lm83_data), | 339 | data = devm_kzalloc(&new_client->dev, sizeof(struct lm83_data), |
347 | GFP_KERNEL); | 340 | GFP_KERNEL); |
348 | if (!data) | 341 | if (!data) |
349 | return -ENOMEM; | 342 | return -ENOMEM; |
350 | 343 | ||
351 | i2c_set_clientdata(new_client, data); | 344 | data->client = new_client; |
352 | mutex_init(&data->update_lock); | 345 | mutex_init(&data->update_lock); |
353 | 346 | ||
354 | /* | 347 | /* |
@@ -357,72 +350,37 @@ static int lm83_probe(struct i2c_client *new_client, | |||
357 | * at the same register as the LM83 temp3 entry - so we | 350 | * at the same register as the LM83 temp3 entry - so we |
358 | * declare 1 and 3 common, and then 2 and 4 only for the LM83. | 351 | * declare 1 and 3 common, and then 2 and 4 only for the LM83. |
359 | */ | 352 | */ |
360 | 353 | data->groups[0] = &lm83_group; | |
361 | err = sysfs_create_group(&new_client->dev.kobj, &lm83_group); | 354 | if (id->driver_data == lm83) |
362 | if (err) | 355 | data->groups[1] = &lm83_group_opt; |
363 | return err; | 356 | |
364 | 357 | hwmon_dev = devm_hwmon_device_register_with_groups(&new_client->dev, | |
365 | if (id->driver_data == lm83) { | 358 | new_client->name, |
366 | err = sysfs_create_group(&new_client->dev.kobj, | 359 | data, data->groups); |
367 | &lm83_group_opt); | 360 | return PTR_ERR_OR_ZERO(hwmon_dev); |
368 | if (err) | ||
369 | goto exit_remove_files; | ||
370 | } | ||
371 | |||
372 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
373 | if (IS_ERR(data->hwmon_dev)) { | ||
374 | err = PTR_ERR(data->hwmon_dev); | ||
375 | goto exit_remove_files; | ||
376 | } | ||
377 | |||
378 | return 0; | ||
379 | |||
380 | exit_remove_files: | ||
381 | sysfs_remove_group(&new_client->dev.kobj, &lm83_group); | ||
382 | sysfs_remove_group(&new_client->dev.kobj, &lm83_group_opt); | ||
383 | return err; | ||
384 | } | ||
385 | |||
386 | static int lm83_remove(struct i2c_client *client) | ||
387 | { | ||
388 | struct lm83_data *data = i2c_get_clientdata(client); | ||
389 | |||
390 | hwmon_device_unregister(data->hwmon_dev); | ||
391 | sysfs_remove_group(&client->dev.kobj, &lm83_group); | ||
392 | sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); | ||
393 | |||
394 | return 0; | ||
395 | } | 361 | } |
396 | 362 | ||
397 | static struct lm83_data *lm83_update_device(struct device *dev) | 363 | /* |
398 | { | 364 | * Driver data (common to all clients) |
399 | struct i2c_client *client = to_i2c_client(dev); | 365 | */ |
400 | struct lm83_data *data = i2c_get_clientdata(client); | ||
401 | |||
402 | mutex_lock(&data->update_lock); | ||
403 | |||
404 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | ||
405 | int nr; | ||
406 | |||
407 | dev_dbg(&client->dev, "Updating lm83 data.\n"); | ||
408 | for (nr = 0; nr < 9; nr++) { | ||
409 | data->temp[nr] = | ||
410 | i2c_smbus_read_byte_data(client, | ||
411 | LM83_REG_R_TEMP[nr]); | ||
412 | } | ||
413 | data->alarms = | ||
414 | i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1) | ||
415 | + (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2) | ||
416 | << 8); | ||
417 | |||
418 | data->last_updated = jiffies; | ||
419 | data->valid = 1; | ||
420 | } | ||
421 | 366 | ||
422 | mutex_unlock(&data->update_lock); | 367 | static const struct i2c_device_id lm83_id[] = { |
368 | { "lm83", lm83 }, | ||
369 | { "lm82", lm82 }, | ||
370 | { } | ||
371 | }; | ||
372 | MODULE_DEVICE_TABLE(i2c, lm83_id); | ||
423 | 373 | ||
424 | return data; | 374 | static struct i2c_driver lm83_driver = { |
425 | } | 375 | .class = I2C_CLASS_HWMON, |
376 | .driver = { | ||
377 | .name = "lm83", | ||
378 | }, | ||
379 | .probe = lm83_probe, | ||
380 | .id_table = lm83_id, | ||
381 | .detect = lm83_detect, | ||
382 | .address_list = normal_i2c, | ||
383 | }; | ||
426 | 384 | ||
427 | module_i2c_driver(lm83_driver); | 385 | module_i2c_driver(lm83_driver); |
428 | 386 | ||
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index b9022db6511a..d2060e245ff5 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c | |||
@@ -34,10 +34,6 @@ | |||
34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
36 | * GNU General Public License for more details. | 36 | * GNU General Public License for more details. |
37 | * | ||
38 | * You should have received a copy of the GNU General Public License | ||
39 | * along with this program; if not, write to the Free Software | ||
40 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
41 | */ | 37 | */ |
42 | 38 | ||
43 | #include <linux/module.h> | 39 | #include <linux/module.h> |
@@ -93,46 +89,53 @@ static inline u8 ALARMS_FROM_REG(s16 reg) | |||
93 | return reg & 0x0007; | 89 | return reg & 0x0007; |
94 | } | 90 | } |
95 | 91 | ||
96 | /* Driver data (common to all clients) */ | 92 | enum temp_index { |
97 | static struct i2c_driver lm92_driver; | 93 | t_input, |
94 | t_crit, | ||
95 | t_min, | ||
96 | t_max, | ||
97 | t_hyst, | ||
98 | t_num_regs | ||
99 | }; | ||
100 | |||
101 | static const u8 regs[t_num_regs] = { | ||
102 | [t_input] = LM92_REG_TEMP, | ||
103 | [t_crit] = LM92_REG_TEMP_CRIT, | ||
104 | [t_min] = LM92_REG_TEMP_LOW, | ||
105 | [t_max] = LM92_REG_TEMP_HIGH, | ||
106 | [t_hyst] = LM92_REG_TEMP_HYST, | ||
107 | }; | ||
98 | 108 | ||
99 | /* Client data (each client gets its own) */ | 109 | /* Client data (each client gets its own) */ |
100 | struct lm92_data { | 110 | struct lm92_data { |
101 | struct device *hwmon_dev; | 111 | struct i2c_client *client; |
102 | struct mutex update_lock; | 112 | struct mutex update_lock; |
103 | char valid; /* zero until following fields are valid */ | 113 | char valid; /* zero until following fields are valid */ |
104 | unsigned long last_updated; /* in jiffies */ | 114 | unsigned long last_updated; /* in jiffies */ |
105 | 115 | ||
106 | /* registers values */ | 116 | /* registers values */ |
107 | s16 temp1_input, temp1_crit, temp1_min, temp1_max, temp1_hyst; | 117 | s16 temp[t_num_regs]; /* index with enum temp_index */ |
108 | }; | 118 | }; |
109 | 119 | ||
110 | |||
111 | /* | 120 | /* |
112 | * Sysfs attributes and callback functions | 121 | * Sysfs attributes and callback functions |
113 | */ | 122 | */ |
114 | 123 | ||
115 | static struct lm92_data *lm92_update_device(struct device *dev) | 124 | static struct lm92_data *lm92_update_device(struct device *dev) |
116 | { | 125 | { |
117 | struct i2c_client *client = to_i2c_client(dev); | 126 | struct lm92_data *data = dev_get_drvdata(dev); |
118 | struct lm92_data *data = i2c_get_clientdata(client); | 127 | struct i2c_client *client = data->client; |
128 | int i; | ||
119 | 129 | ||
120 | mutex_lock(&data->update_lock); | 130 | mutex_lock(&data->update_lock); |
121 | 131 | ||
122 | if (time_after(jiffies, data->last_updated + HZ) | 132 | if (time_after(jiffies, data->last_updated + HZ) |
123 | || !data->valid) { | 133 | || !data->valid) { |
124 | dev_dbg(&client->dev, "Updating lm92 data\n"); | 134 | dev_dbg(&client->dev, "Updating lm92 data\n"); |
125 | data->temp1_input = i2c_smbus_read_word_swapped(client, | 135 | for (i = 0; i < t_num_regs; i++) { |
126 | LM92_REG_TEMP); | 136 | data->temp[i] = |
127 | data->temp1_hyst = i2c_smbus_read_word_swapped(client, | 137 | i2c_smbus_read_word_swapped(client, regs[i]); |
128 | LM92_REG_TEMP_HYST); | 138 | } |
129 | data->temp1_crit = i2c_smbus_read_word_swapped(client, | ||
130 | LM92_REG_TEMP_CRIT); | ||
131 | data->temp1_min = i2c_smbus_read_word_swapped(client, | ||
132 | LM92_REG_TEMP_LOW); | ||
133 | data->temp1_max = i2c_smbus_read_word_swapped(client, | ||
134 | LM92_REG_TEMP_HIGH); | ||
135 | |||
136 | data->last_updated = jiffies; | 139 | data->last_updated = jiffies; |
137 | data->valid = 1; | 140 | data->valid = 1; |
138 | } | 141 | } |
@@ -142,68 +145,60 @@ static struct lm92_data *lm92_update_device(struct device *dev) | |||
142 | return data; | 145 | return data; |
143 | } | 146 | } |
144 | 147 | ||
145 | #define show_temp(value) \ | 148 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, |
146 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, \ | 149 | char *buf) |
147 | char *buf) \ | 150 | { |
148 | { \ | 151 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
149 | struct lm92_data *data = lm92_update_device(dev); \ | 152 | struct lm92_data *data = lm92_update_device(dev); |
150 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \ | 153 | |
151 | } | 154 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index])); |
152 | show_temp(temp1_input); | ||
153 | show_temp(temp1_crit); | ||
154 | show_temp(temp1_min); | ||
155 | show_temp(temp1_max); | ||
156 | |||
157 | #define set_temp(value, reg) \ | ||
158 | static ssize_t set_##value(struct device *dev, struct device_attribute *attr, \ | ||
159 | const char *buf, \ | ||
160 | size_t count) \ | ||
161 | { \ | ||
162 | struct i2c_client *client = to_i2c_client(dev); \ | ||
163 | struct lm92_data *data = i2c_get_clientdata(client); \ | ||
164 | long val; \ | ||
165 | int err = kstrtol(buf, 10, &val); \ | ||
166 | if (err) \ | ||
167 | return err; \ | ||
168 | \ | ||
169 | mutex_lock(&data->update_lock); \ | ||
170 | data->value = TEMP_TO_REG(val); \ | ||
171 | i2c_smbus_write_word_swapped(client, reg, data->value); \ | ||
172 | mutex_unlock(&data->update_lock); \ | ||
173 | return count; \ | ||
174 | } | 155 | } |
175 | set_temp(temp1_crit, LM92_REG_TEMP_CRIT); | ||
176 | set_temp(temp1_min, LM92_REG_TEMP_LOW); | ||
177 | set_temp(temp1_max, LM92_REG_TEMP_HIGH); | ||
178 | 156 | ||
179 | static ssize_t show_temp1_crit_hyst(struct device *dev, | 157 | static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, |
180 | struct device_attribute *attr, char *buf) | 158 | const char *buf, size_t count) |
181 | { | 159 | { |
182 | struct lm92_data *data = lm92_update_device(dev); | 160 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
183 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_crit) | 161 | struct lm92_data *data = dev_get_drvdata(dev); |
184 | - TEMP_FROM_REG(data->temp1_hyst)); | 162 | struct i2c_client *client = data->client; |
163 | int nr = attr->index; | ||
164 | long val; | ||
165 | int err; | ||
166 | |||
167 | err = kstrtol(buf, 10, &val); | ||
168 | if (err) | ||
169 | return err; | ||
170 | |||
171 | mutex_lock(&data->update_lock); | ||
172 | data->temp[nr] = TEMP_TO_REG(val); | ||
173 | i2c_smbus_write_word_swapped(client, regs[nr], data->temp[nr]); | ||
174 | mutex_unlock(&data->update_lock); | ||
175 | return count; | ||
185 | } | 176 | } |
186 | static ssize_t show_temp1_max_hyst(struct device *dev, | 177 | |
187 | struct device_attribute *attr, char *buf) | 178 | static ssize_t show_temp_hyst(struct device *dev, |
179 | struct device_attribute *devattr, char *buf) | ||
188 | { | 180 | { |
181 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
189 | struct lm92_data *data = lm92_update_device(dev); | 182 | struct lm92_data *data = lm92_update_device(dev); |
190 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_max) | 183 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]) |
191 | - TEMP_FROM_REG(data->temp1_hyst)); | 184 | - TEMP_FROM_REG(data->temp[t_hyst])); |
192 | } | 185 | } |
193 | static ssize_t show_temp1_min_hyst(struct device *dev, | 186 | |
194 | struct device_attribute *attr, char *buf) | 187 | static ssize_t show_temp_min_hyst(struct device *dev, |
188 | struct device_attribute *attr, char *buf) | ||
195 | { | 189 | { |
196 | struct lm92_data *data = lm92_update_device(dev); | 190 | struct lm92_data *data = lm92_update_device(dev); |
197 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_min) | 191 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[t_min]) |
198 | + TEMP_FROM_REG(data->temp1_hyst)); | 192 | + TEMP_FROM_REG(data->temp[t_hyst])); |
199 | } | 193 | } |
200 | 194 | ||
201 | static ssize_t set_temp1_crit_hyst(struct device *dev, | 195 | static ssize_t set_temp_hyst(struct device *dev, |
202 | struct device_attribute *attr, | 196 | struct device_attribute *devattr, |
203 | const char *buf, size_t count) | 197 | const char *buf, size_t count) |
204 | { | 198 | { |
205 | struct i2c_client *client = to_i2c_client(dev); | 199 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
206 | struct lm92_data *data = i2c_get_clientdata(client); | 200 | struct lm92_data *data = dev_get_drvdata(dev); |
201 | struct i2c_client *client = data->client; | ||
207 | long val; | 202 | long val; |
208 | int err; | 203 | int err; |
209 | 204 | ||
@@ -212,9 +207,9 @@ static ssize_t set_temp1_crit_hyst(struct device *dev, | |||
212 | return err; | 207 | return err; |
213 | 208 | ||
214 | mutex_lock(&data->update_lock); | 209 | mutex_lock(&data->update_lock); |
215 | data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val; | 210 | data->temp[t_hyst] = TEMP_FROM_REG(data->temp[attr->index]) - val; |
216 | i2c_smbus_write_word_swapped(client, LM92_REG_TEMP_HYST, | 211 | i2c_smbus_write_word_swapped(client, LM92_REG_TEMP_HYST, |
217 | TEMP_TO_REG(data->temp1_hyst)); | 212 | TEMP_TO_REG(data->temp[t_hyst])); |
218 | mutex_unlock(&data->update_lock); | 213 | mutex_unlock(&data->update_lock); |
219 | return count; | 214 | return count; |
220 | } | 215 | } |
@@ -223,7 +218,7 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | |||
223 | char *buf) | 218 | char *buf) |
224 | { | 219 | { |
225 | struct lm92_data *data = lm92_update_device(dev); | 220 | struct lm92_data *data = lm92_update_device(dev); |
226 | return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input)); | 221 | return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp[t_input])); |
227 | } | 222 | } |
228 | 223 | ||
229 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | 224 | static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, |
@@ -231,26 +226,25 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | |||
231 | { | 226 | { |
232 | int bitnr = to_sensor_dev_attr(attr)->index; | 227 | int bitnr = to_sensor_dev_attr(attr)->index; |
233 | struct lm92_data *data = lm92_update_device(dev); | 228 | struct lm92_data *data = lm92_update_device(dev); |
234 | return sprintf(buf, "%d\n", (data->temp1_input >> bitnr) & 1); | 229 | return sprintf(buf, "%d\n", (data->temp[t_input] >> bitnr) & 1); |
235 | } | 230 | } |
236 | 231 | ||
237 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL); | 232 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input); |
238 | static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp1_crit, | 233 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp, set_temp, |
239 | set_temp1_crit); | 234 | t_crit); |
240 | static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp1_crit_hyst, | 235 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst, |
241 | set_temp1_crit_hyst); | 236 | set_temp_hyst, t_crit); |
242 | static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp1_min, | 237 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp, set_temp, |
243 | set_temp1_min); | 238 | t_min); |
244 | static DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_temp1_min_hyst, NULL); | 239 | static DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_temp_min_hyst, NULL); |
245 | static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_max, | 240 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp, set_temp, |
246 | set_temp1_max); | 241 | t_max); |
247 | static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp1_max_hyst, NULL); | 242 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp_hyst, NULL, t_max); |
248 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 243 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
249 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2); | 244 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2); |
250 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0); | 245 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0); |
251 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); | 246 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); |
252 | 247 | ||
253 | |||
254 | /* | 248 | /* |
255 | * Detection and registration | 249 | * Detection and registration |
256 | */ | 250 | */ |
@@ -322,24 +316,21 @@ static int max6635_check(struct i2c_client *client) | |||
322 | return 1; | 316 | return 1; |
323 | } | 317 | } |
324 | 318 | ||
325 | static struct attribute *lm92_attributes[] = { | 319 | static struct attribute *lm92_attrs[] = { |
326 | &dev_attr_temp1_input.attr, | 320 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
327 | &dev_attr_temp1_crit.attr, | 321 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
328 | &dev_attr_temp1_crit_hyst.attr, | 322 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, |
329 | &dev_attr_temp1_min.attr, | 323 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
330 | &dev_attr_temp1_min_hyst.attr, | 324 | &dev_attr_temp1_min_hyst.attr, |
331 | &dev_attr_temp1_max.attr, | 325 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
332 | &dev_attr_temp1_max_hyst.attr, | 326 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
333 | &dev_attr_alarms.attr, | 327 | &dev_attr_alarms.attr, |
334 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 328 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
335 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, | 329 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, |
336 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 330 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
337 | NULL | 331 | NULL |
338 | }; | 332 | }; |
339 | 333 | ATTRIBUTE_GROUPS(lm92); | |
340 | static const struct attribute_group lm92_group = { | ||
341 | .attrs = lm92_attributes, | ||
342 | }; | ||
343 | 334 | ||
344 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 335 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
345 | static int lm92_detect(struct i2c_client *new_client, | 336 | static int lm92_detect(struct i2c_client *new_client, |
@@ -371,46 +362,24 @@ static int lm92_detect(struct i2c_client *new_client, | |||
371 | static int lm92_probe(struct i2c_client *new_client, | 362 | static int lm92_probe(struct i2c_client *new_client, |
372 | const struct i2c_device_id *id) | 363 | const struct i2c_device_id *id) |
373 | { | 364 | { |
365 | struct device *hwmon_dev; | ||
374 | struct lm92_data *data; | 366 | struct lm92_data *data; |
375 | int err; | ||
376 | 367 | ||
377 | data = devm_kzalloc(&new_client->dev, sizeof(struct lm92_data), | 368 | data = devm_kzalloc(&new_client->dev, sizeof(struct lm92_data), |
378 | GFP_KERNEL); | 369 | GFP_KERNEL); |
379 | if (!data) | 370 | if (!data) |
380 | return -ENOMEM; | 371 | return -ENOMEM; |
381 | 372 | ||
382 | i2c_set_clientdata(new_client, data); | 373 | data->client = new_client; |
383 | mutex_init(&data->update_lock); | 374 | mutex_init(&data->update_lock); |
384 | 375 | ||
385 | /* Initialize the chipset */ | 376 | /* Initialize the chipset */ |
386 | lm92_init_client(new_client); | 377 | lm92_init_client(new_client); |
387 | 378 | ||
388 | /* Register sysfs hooks */ | 379 | hwmon_dev = devm_hwmon_device_register_with_groups(&new_client->dev, |
389 | err = sysfs_create_group(&new_client->dev.kobj, &lm92_group); | 380 | new_client->name, |
390 | if (err) | 381 | data, lm92_groups); |
391 | return err; | 382 | return PTR_ERR_OR_ZERO(hwmon_dev); |
392 | |||
393 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
394 | if (IS_ERR(data->hwmon_dev)) { | ||
395 | err = PTR_ERR(data->hwmon_dev); | ||
396 | goto exit_remove; | ||
397 | } | ||
398 | |||
399 | return 0; | ||
400 | |||
401 | exit_remove: | ||
402 | sysfs_remove_group(&new_client->dev.kobj, &lm92_group); | ||
403 | return err; | ||
404 | } | ||
405 | |||
406 | static int lm92_remove(struct i2c_client *client) | ||
407 | { | ||
408 | struct lm92_data *data = i2c_get_clientdata(client); | ||
409 | |||
410 | hwmon_device_unregister(data->hwmon_dev); | ||
411 | sysfs_remove_group(&client->dev.kobj, &lm92_group); | ||
412 | |||
413 | return 0; | ||
414 | } | 383 | } |
415 | 384 | ||
416 | 385 | ||
@@ -431,7 +400,6 @@ static struct i2c_driver lm92_driver = { | |||
431 | .name = "lm92", | 400 | .name = "lm92", |
432 | }, | 401 | }, |
433 | .probe = lm92_probe, | 402 | .probe = lm92_probe, |
434 | .remove = lm92_remove, | ||
435 | .id_table = lm92_id, | 403 | .id_table = lm92_id, |
436 | .detect = lm92_detect, | 404 | .detect = lm92_detect, |
437 | .address_list = normal_i2c, | 405 | .address_list = normal_i2c, |
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index adf23165a6a7..6c2df576f253 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c | |||
@@ -2747,10 +2747,8 @@ static int lm93_probe(struct i2c_client *client, | |||
2747 | } | 2747 | } |
2748 | 2748 | ||
2749 | data = devm_kzalloc(&client->dev, sizeof(struct lm93_data), GFP_KERNEL); | 2749 | data = devm_kzalloc(&client->dev, sizeof(struct lm93_data), GFP_KERNEL); |
2750 | if (!data) { | 2750 | if (!data) |
2751 | dev_dbg(&client->dev, "out of memory!\n"); | ||
2752 | return -ENOMEM; | 2751 | return -ENOMEM; |
2753 | } | ||
2754 | i2c_set_clientdata(client, data); | 2752 | i2c_set_clientdata(client, data); |
2755 | 2753 | ||
2756 | /* housekeeping */ | 2754 | /* housekeeping */ |
diff --git a/drivers/hwmon/ltc2945.c b/drivers/hwmon/ltc2945.c index c9cddf5f056b..3701b329b6ae 100644 --- a/drivers/hwmon/ltc2945.c +++ b/drivers/hwmon/ltc2945.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for Linear Technology LTC2945 I2C Power Monitor | 2 | * Driver for Linear Technology LTC2945 I2C Power Monitor |
3 | * | 3 | * |
4 | * Copyright (c) 2014 Guenter Roeck | 4 | * Copyright (c) 2014 Guenter Roeck |
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index eda077de8a9f..f67d71ee8386 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c | |||
@@ -192,10 +192,8 @@ static int max1111_probe(struct spi_device *spi) | |||
192 | return err; | 192 | return err; |
193 | 193 | ||
194 | data = devm_kzalloc(&spi->dev, sizeof(struct max1111_data), GFP_KERNEL); | 194 | data = devm_kzalloc(&spi->dev, sizeof(struct max1111_data), GFP_KERNEL); |
195 | if (data == NULL) { | 195 | if (data == NULL) |
196 | dev_err(&spi->dev, "failed to allocate memory\n"); | ||
197 | return -ENOMEM; | 196 | return -ENOMEM; |
198 | } | ||
199 | 197 | ||
200 | switch (chip) { | 198 | switch (chip) { |
201 | case max1110: | 199 | case max1110: |
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 4c23afe113e2..eda9cf599685 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c | |||
@@ -19,13 +19,8 @@ | |||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | * GNU General Public License for more details. | 21 | * GNU General Public License for more details. |
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | */ | 22 | */ |
27 | 23 | ||
28 | |||
29 | #include <linux/module.h> | 24 | #include <linux/module.h> |
30 | #include <linux/init.h> | 25 | #include <linux/init.h> |
31 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
@@ -76,38 +71,14 @@ static int temp_to_reg(int val) | |||
76 | return (val < 0 ? val+0x100*1000 : val) / 1000; | 71 | return (val < 0 ? val+0x100*1000 : val) / 1000; |
77 | } | 72 | } |
78 | 73 | ||
79 | /* | 74 | enum temp_index { |
80 | * Functions declaration | 75 | t_input1 = 0, |
81 | */ | 76 | t_input2, |
82 | 77 | t_low2, | |
83 | static int max1619_probe(struct i2c_client *client, | 78 | t_high2, |
84 | const struct i2c_device_id *id); | 79 | t_crit2, |
85 | static int max1619_detect(struct i2c_client *client, | 80 | t_hyst2, |
86 | struct i2c_board_info *info); | 81 | t_num_regs |
87 | static void max1619_init_client(struct i2c_client *client); | ||
88 | static int max1619_remove(struct i2c_client *client); | ||
89 | static struct max1619_data *max1619_update_device(struct device *dev); | ||
90 | |||
91 | /* | ||
92 | * Driver data (common to all clients) | ||
93 | */ | ||
94 | |||
95 | static const struct i2c_device_id max1619_id[] = { | ||
96 | { "max1619", 0 }, | ||
97 | { } | ||
98 | }; | ||
99 | MODULE_DEVICE_TABLE(i2c, max1619_id); | ||
100 | |||
101 | static struct i2c_driver max1619_driver = { | ||
102 | .class = I2C_CLASS_HWMON, | ||
103 | .driver = { | ||
104 | .name = "max1619", | ||
105 | }, | ||
106 | .probe = max1619_probe, | ||
107 | .remove = max1619_remove, | ||
108 | .id_table = max1619_id, | ||
109 | .detect = max1619_detect, | ||
110 | .address_list = normal_i2c, | ||
111 | }; | 82 | }; |
112 | 83 | ||
113 | /* | 84 | /* |
@@ -115,60 +86,92 @@ static struct i2c_driver max1619_driver = { | |||
115 | */ | 86 | */ |
116 | 87 | ||
117 | struct max1619_data { | 88 | struct max1619_data { |
118 | struct device *hwmon_dev; | 89 | struct i2c_client *client; |
119 | struct mutex update_lock; | 90 | struct mutex update_lock; |
120 | char valid; /* zero until following fields are valid */ | 91 | char valid; /* zero until following fields are valid */ |
121 | unsigned long last_updated; /* in jiffies */ | 92 | unsigned long last_updated; /* in jiffies */ |
122 | 93 | ||
123 | /* registers values */ | 94 | /* registers values */ |
124 | u8 temp_input1; /* local */ | 95 | u8 temp[t_num_regs]; /* index with enum temp_index */ |
125 | u8 temp_input2, temp_low2, temp_high2; /* remote */ | ||
126 | u8 temp_crit2; | ||
127 | u8 temp_hyst2; | ||
128 | u8 alarms; | 96 | u8 alarms; |
129 | }; | 97 | }; |
130 | 98 | ||
99 | static const u8 regs_read[t_num_regs] = { | ||
100 | [t_input1] = MAX1619_REG_R_LOCAL_TEMP, | ||
101 | [t_input2] = MAX1619_REG_R_REMOTE_TEMP, | ||
102 | [t_low2] = MAX1619_REG_R_REMOTE_LOW, | ||
103 | [t_high2] = MAX1619_REG_R_REMOTE_HIGH, | ||
104 | [t_crit2] = MAX1619_REG_R_REMOTE_CRIT, | ||
105 | [t_hyst2] = MAX1619_REG_R_TCRIT_HYST, | ||
106 | }; | ||
107 | |||
108 | static const u8 regs_write[t_num_regs] = { | ||
109 | [t_low2] = MAX1619_REG_W_REMOTE_LOW, | ||
110 | [t_high2] = MAX1619_REG_W_REMOTE_HIGH, | ||
111 | [t_crit2] = MAX1619_REG_W_REMOTE_CRIT, | ||
112 | [t_hyst2] = MAX1619_REG_W_TCRIT_HYST, | ||
113 | }; | ||
114 | |||
115 | static struct max1619_data *max1619_update_device(struct device *dev) | ||
116 | { | ||
117 | struct max1619_data *data = dev_get_drvdata(dev); | ||
118 | struct i2c_client *client = data->client; | ||
119 | int config, i; | ||
120 | |||
121 | mutex_lock(&data->update_lock); | ||
122 | |||
123 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | ||
124 | dev_dbg(&client->dev, "Updating max1619 data.\n"); | ||
125 | for (i = 0; i < t_num_regs; i++) | ||
126 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
127 | regs_read[i]); | ||
128 | data->alarms = i2c_smbus_read_byte_data(client, | ||
129 | MAX1619_REG_R_STATUS); | ||
130 | /* If OVERT polarity is low, reverse alarm bit */ | ||
131 | config = i2c_smbus_read_byte_data(client, MAX1619_REG_R_CONFIG); | ||
132 | if (!(config & 0x20)) | ||
133 | data->alarms ^= 0x02; | ||
134 | |||
135 | data->last_updated = jiffies; | ||
136 | data->valid = 1; | ||
137 | } | ||
138 | |||
139 | mutex_unlock(&data->update_lock); | ||
140 | |||
141 | return data; | ||
142 | } | ||
143 | |||
131 | /* | 144 | /* |
132 | * Sysfs stuff | 145 | * Sysfs stuff |
133 | */ | 146 | */ |
134 | 147 | ||
135 | #define show_temp(value) \ | 148 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, |
136 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, \ | 149 | char *buf) |
137 | char *buf) \ | 150 | { |
138 | { \ | 151 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
139 | struct max1619_data *data = max1619_update_device(dev); \ | 152 | struct max1619_data *data = max1619_update_device(dev); |
140 | return sprintf(buf, "%d\n", temp_from_reg(data->value)); \ | 153 | |
141 | } | 154 | return sprintf(buf, "%d\n", temp_from_reg(data->temp[attr->index])); |
142 | show_temp(temp_input1); | ||
143 | show_temp(temp_input2); | ||
144 | show_temp(temp_low2); | ||
145 | show_temp(temp_high2); | ||
146 | show_temp(temp_crit2); | ||
147 | show_temp(temp_hyst2); | ||
148 | |||
149 | #define set_temp2(value, reg) \ | ||
150 | static ssize_t set_##value(struct device *dev, struct device_attribute *attr, \ | ||
151 | const char *buf, \ | ||
152 | size_t count) \ | ||
153 | { \ | ||
154 | struct i2c_client *client = to_i2c_client(dev); \ | ||
155 | struct max1619_data *data = i2c_get_clientdata(client); \ | ||
156 | long val; \ | ||
157 | int err = kstrtol(buf, 10, &val); \ | ||
158 | if (err) \ | ||
159 | return err; \ | ||
160 | \ | ||
161 | mutex_lock(&data->update_lock); \ | ||
162 | data->value = temp_to_reg(val); \ | ||
163 | i2c_smbus_write_byte_data(client, reg, data->value); \ | ||
164 | mutex_unlock(&data->update_lock); \ | ||
165 | return count; \ | ||
166 | } | 155 | } |
167 | 156 | ||
168 | set_temp2(temp_low2, MAX1619_REG_W_REMOTE_LOW); | 157 | static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, |
169 | set_temp2(temp_high2, MAX1619_REG_W_REMOTE_HIGH); | 158 | const char *buf, size_t count) |
170 | set_temp2(temp_crit2, MAX1619_REG_W_REMOTE_CRIT); | 159 | { |
171 | set_temp2(temp_hyst2, MAX1619_REG_W_TCRIT_HYST); | 160 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
161 | struct max1619_data *data = dev_get_drvdata(dev); | ||
162 | struct i2c_client *client = data->client; | ||
163 | long val; | ||
164 | int err = kstrtol(buf, 10, &val); | ||
165 | if (err) | ||
166 | return err; | ||
167 | |||
168 | mutex_lock(&data->update_lock); | ||
169 | data->temp[attr->index] = temp_to_reg(val); | ||
170 | i2c_smbus_write_byte_data(client, regs_write[attr->index], | ||
171 | data->temp[attr->index]); | ||
172 | mutex_unlock(&data->update_lock); | ||
173 | return count; | ||
174 | } | ||
172 | 175 | ||
173 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | 176 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, |
174 | char *buf) | 177 | char *buf) |
@@ -185,29 +188,30 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, | |||
185 | return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); | 188 | return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); |
186 | } | 189 | } |
187 | 190 | ||
188 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); | 191 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input1); |
189 | static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL); | 192 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, t_input2); |
190 | static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2, | 193 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp, set_temp, |
191 | set_temp_low2); | 194 | t_low2); |
192 | static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_high2, | 195 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp, set_temp, |
193 | set_temp_high2); | 196 | t_high2); |
194 | static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2, | 197 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp, set_temp, |
195 | set_temp_crit2); | 198 | t_crit2); |
196 | static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst2, | 199 | static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp, |
197 | set_temp_hyst2); | 200 | set_temp, t_hyst2); |
201 | |||
198 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 202 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
199 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | 203 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); |
200 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); | 204 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); |
201 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); | 205 | static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); |
202 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | 206 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); |
203 | 207 | ||
204 | static struct attribute *max1619_attributes[] = { | 208 | static struct attribute *max1619_attrs[] = { |
205 | &dev_attr_temp1_input.attr, | 209 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
206 | &dev_attr_temp2_input.attr, | 210 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
207 | &dev_attr_temp2_min.attr, | 211 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
208 | &dev_attr_temp2_max.attr, | 212 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
209 | &dev_attr_temp2_crit.attr, | 213 | &sensor_dev_attr_temp2_crit.dev_attr.attr, |
210 | &dev_attr_temp2_crit_hyst.attr, | 214 | &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, |
211 | 215 | ||
212 | &dev_attr_alarms.attr, | 216 | &dev_attr_alarms.attr, |
213 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, | 217 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, |
@@ -216,14 +220,7 @@ static struct attribute *max1619_attributes[] = { | |||
216 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 220 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
217 | NULL | 221 | NULL |
218 | }; | 222 | }; |
219 | 223 | ATTRIBUTE_GROUPS(max1619); | |
220 | static const struct attribute_group max1619_group = { | ||
221 | .attrs = max1619_attributes, | ||
222 | }; | ||
223 | |||
224 | /* | ||
225 | * Real code | ||
226 | */ | ||
227 | 224 | ||
228 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 225 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
229 | static int max1619_detect(struct i2c_client *client, | 226 | static int max1619_detect(struct i2c_client *client, |
@@ -261,41 +258,6 @@ static int max1619_detect(struct i2c_client *client, | |||
261 | return 0; | 258 | return 0; |
262 | } | 259 | } |
263 | 260 | ||
264 | static int max1619_probe(struct i2c_client *new_client, | ||
265 | const struct i2c_device_id *id) | ||
266 | { | ||
267 | struct max1619_data *data; | ||
268 | int err; | ||
269 | |||
270 | data = devm_kzalloc(&new_client->dev, sizeof(struct max1619_data), | ||
271 | GFP_KERNEL); | ||
272 | if (!data) | ||
273 | return -ENOMEM; | ||
274 | |||
275 | i2c_set_clientdata(new_client, data); | ||
276 | mutex_init(&data->update_lock); | ||
277 | |||
278 | /* Initialize the MAX1619 chip */ | ||
279 | max1619_init_client(new_client); | ||
280 | |||
281 | /* Register sysfs hooks */ | ||
282 | err = sysfs_create_group(&new_client->dev.kobj, &max1619_group); | ||
283 | if (err) | ||
284 | return err; | ||
285 | |||
286 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
287 | if (IS_ERR(data->hwmon_dev)) { | ||
288 | err = PTR_ERR(data->hwmon_dev); | ||
289 | goto exit_remove_files; | ||
290 | } | ||
291 | |||
292 | return 0; | ||
293 | |||
294 | exit_remove_files: | ||
295 | sysfs_remove_group(&new_client->dev.kobj, &max1619_group); | ||
296 | return err; | ||
297 | } | ||
298 | |||
299 | static void max1619_init_client(struct i2c_client *client) | 261 | static void max1619_init_client(struct i2c_client *client) |
300 | { | 262 | { |
301 | u8 config; | 263 | u8 config; |
@@ -311,48 +273,46 @@ static void max1619_init_client(struct i2c_client *client) | |||
311 | config & 0xBF); /* run */ | 273 | config & 0xBF); /* run */ |
312 | } | 274 | } |
313 | 275 | ||
314 | static int max1619_remove(struct i2c_client *client) | 276 | static int max1619_probe(struct i2c_client *new_client, |
277 | const struct i2c_device_id *id) | ||
315 | { | 278 | { |
316 | struct max1619_data *data = i2c_get_clientdata(client); | 279 | struct max1619_data *data; |
317 | 280 | struct device *hwmon_dev; | |
318 | hwmon_device_unregister(data->hwmon_dev); | ||
319 | sysfs_remove_group(&client->dev.kobj, &max1619_group); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | 281 | ||
324 | static struct max1619_data *max1619_update_device(struct device *dev) | 282 | data = devm_kzalloc(&new_client->dev, sizeof(struct max1619_data), |
325 | { | 283 | GFP_KERNEL); |
326 | struct i2c_client *client = to_i2c_client(dev); | 284 | if (!data) |
327 | struct max1619_data *data = i2c_get_clientdata(client); | 285 | return -ENOMEM; |
328 | 286 | ||
329 | mutex_lock(&data->update_lock); | 287 | data->client = new_client; |
288 | mutex_init(&data->update_lock); | ||
330 | 289 | ||
331 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | 290 | /* Initialize the MAX1619 chip */ |
332 | dev_dbg(&client->dev, "Updating max1619 data.\n"); | 291 | max1619_init_client(new_client); |
333 | data->temp_input1 = i2c_smbus_read_byte_data(client, | ||
334 | MAX1619_REG_R_LOCAL_TEMP); | ||
335 | data->temp_input2 = i2c_smbus_read_byte_data(client, | ||
336 | MAX1619_REG_R_REMOTE_TEMP); | ||
337 | data->temp_high2 = i2c_smbus_read_byte_data(client, | ||
338 | MAX1619_REG_R_REMOTE_HIGH); | ||
339 | data->temp_low2 = i2c_smbus_read_byte_data(client, | ||
340 | MAX1619_REG_R_REMOTE_LOW); | ||
341 | data->temp_crit2 = i2c_smbus_read_byte_data(client, | ||
342 | MAX1619_REG_R_REMOTE_CRIT); | ||
343 | data->temp_hyst2 = i2c_smbus_read_byte_data(client, | ||
344 | MAX1619_REG_R_TCRIT_HYST); | ||
345 | data->alarms = i2c_smbus_read_byte_data(client, | ||
346 | MAX1619_REG_R_STATUS); | ||
347 | 292 | ||
348 | data->last_updated = jiffies; | 293 | hwmon_dev = devm_hwmon_device_register_with_groups(&new_client->dev, |
349 | data->valid = 1; | 294 | new_client->name, |
350 | } | 295 | data, |
296 | max1619_groups); | ||
297 | return PTR_ERR_OR_ZERO(hwmon_dev); | ||
298 | } | ||
351 | 299 | ||
352 | mutex_unlock(&data->update_lock); | 300 | static const struct i2c_device_id max1619_id[] = { |
301 | { "max1619", 0 }, | ||
302 | { } | ||
303 | }; | ||
304 | MODULE_DEVICE_TABLE(i2c, max1619_id); | ||
353 | 305 | ||
354 | return data; | 306 | static struct i2c_driver max1619_driver = { |
355 | } | 307 | .class = I2C_CLASS_HWMON, |
308 | .driver = { | ||
309 | .name = "max1619", | ||
310 | }, | ||
311 | .probe = max1619_probe, | ||
312 | .id_table = max1619_id, | ||
313 | .detect = max1619_detect, | ||
314 | .address_list = normal_i2c, | ||
315 | }; | ||
356 | 316 | ||
357 | module_i2c_driver(max1619_driver); | 317 | module_i2c_driver(max1619_driver); |
358 | 318 | ||
diff --git a/drivers/hwmon/max197.c b/drivers/hwmon/max197.c index 96dccaf919d1..82128ad79a91 100644 --- a/drivers/hwmon/max197.c +++ b/drivers/hwmon/max197.c | |||
@@ -275,10 +275,8 @@ static int max197_probe(struct platform_device *pdev) | |||
275 | } | 275 | } |
276 | 276 | ||
277 | data = devm_kzalloc(&pdev->dev, sizeof(struct max197_data), GFP_KERNEL); | 277 | data = devm_kzalloc(&pdev->dev, sizeof(struct max197_data), GFP_KERNEL); |
278 | if (!data) { | 278 | if (!data) |
279 | dev_err(&pdev->dev, "devm_kzalloc failed\n"); | ||
280 | return -ENOMEM; | 279 | return -ENOMEM; |
281 | } | ||
282 | 280 | ||
283 | data->pdata = pdata; | 281 | data->pdata = pdata; |
284 | mutex_init(&data->lock); | 282 | mutex_init(&data->lock); |
diff --git a/drivers/hwmon/nct6683.c b/drivers/hwmon/nct6683.c new file mode 100644 index 000000000000..7710f4694ba1 --- /dev/null +++ b/drivers/hwmon/nct6683.c | |||
@@ -0,0 +1,1457 @@ | |||
1 | /* | ||
2 | * nct6683 - Driver for the hardware monitoring functionality of | ||
3 | * Nuvoton NCT6683D eSIO | ||
4 | * | ||
5 | * Copyright (C) 2013 Guenter Roeck <linux@roeck-us.net> | ||
6 | * | ||
7 | * Derived from nct6775 driver | ||
8 | * Copyright (C) 2012, 2013 Guenter Roeck <linux@roeck-us.net> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * Supports the following chips: | ||
21 | * | ||
22 | * Chip #vin #fan #pwm #temp chip ID | ||
23 | * nct6683d 21(1) 16 8 32(1) 0xc730 | ||
24 | * | ||
25 | * Notes: | ||
26 | * (1) Total number of vin and temp inputs is 32. | ||
27 | */ | ||
28 | |||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
30 | |||
31 | #include <linux/acpi.h> | ||
32 | #include <linux/dmi.h> | ||
33 | #include <linux/err.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/io.h> | ||
36 | #include <linux/jiffies.h> | ||
37 | #include <linux/hwmon.h> | ||
38 | #include <linux/hwmon-sysfs.h> | ||
39 | #include <linux/module.h> | ||
40 | #include <linux/mutex.h> | ||
41 | #include <linux/platform_device.h> | ||
42 | #include <linux/slab.h> | ||
43 | |||
44 | enum kinds { nct6683 }; | ||
45 | |||
46 | static bool force; | ||
47 | module_param(force, bool, 0); | ||
48 | MODULE_PARM_DESC(force, "Set to one to enable detection on non-Intel boards"); | ||
49 | |||
50 | static const char * const nct6683_device_names[] = { | ||
51 | "nct6683", | ||
52 | }; | ||
53 | |||
54 | static const char * const nct6683_chip_names[] = { | ||
55 | "NCT6683D", | ||
56 | }; | ||
57 | |||
58 | #define DRVNAME "nct6683" | ||
59 | |||
60 | /* | ||
61 | * Super-I/O constants and functions | ||
62 | */ | ||
63 | |||
64 | #define NCT6683_LD_ACPI 0x0a | ||
65 | #define NCT6683_LD_HWM 0x0b | ||
66 | #define NCT6683_LD_VID 0x0d | ||
67 | |||
68 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | ||
69 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | ||
70 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | ||
71 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | ||
72 | |||
73 | #define SIO_NCT6681_ID 0xb270 /* for later */ | ||
74 | #define SIO_NCT6683_ID 0xc730 | ||
75 | #define SIO_ID_MASK 0xFFF0 | ||
76 | |||
77 | static inline void | ||
78 | superio_outb(int ioreg, int reg, int val) | ||
79 | { | ||
80 | outb(reg, ioreg); | ||
81 | outb(val, ioreg + 1); | ||
82 | } | ||
83 | |||
84 | static inline int | ||
85 | superio_inb(int ioreg, int reg) | ||
86 | { | ||
87 | outb(reg, ioreg); | ||
88 | return inb(ioreg + 1); | ||
89 | } | ||
90 | |||
91 | static inline void | ||
92 | superio_select(int ioreg, int ld) | ||
93 | { | ||
94 | outb(SIO_REG_LDSEL, ioreg); | ||
95 | outb(ld, ioreg + 1); | ||
96 | } | ||
97 | |||
98 | static inline int | ||
99 | superio_enter(int ioreg) | ||
100 | { | ||
101 | /* | ||
102 | * Try to reserve <ioreg> and <ioreg + 1> for exclusive access. | ||
103 | */ | ||
104 | if (!request_muxed_region(ioreg, 2, DRVNAME)) | ||
105 | return -EBUSY; | ||
106 | |||
107 | outb(0x87, ioreg); | ||
108 | outb(0x87, ioreg); | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static inline void | ||
114 | superio_exit(int ioreg) | ||
115 | { | ||
116 | outb(0xaa, ioreg); | ||
117 | outb(0x02, ioreg); | ||
118 | outb(0x02, ioreg + 1); | ||
119 | release_region(ioreg, 2); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * ISA constants | ||
124 | */ | ||
125 | |||
126 | #define IOREGION_ALIGNMENT (~7) | ||
127 | #define IOREGION_OFFSET 4 /* Use EC port 1 */ | ||
128 | #define IOREGION_LENGTH 4 | ||
129 | |||
130 | #define EC_PAGE_REG 0 | ||
131 | #define EC_INDEX_REG 1 | ||
132 | #define EC_DATA_REG 2 | ||
133 | #define EC_EVENT_REG 3 | ||
134 | |||
135 | /* Common and NCT6683 specific data */ | ||
136 | |||
137 | #define NCT6683_NUM_REG_MON 32 | ||
138 | #define NCT6683_NUM_REG_FAN 16 | ||
139 | #define NCT6683_NUM_REG_PWM 8 | ||
140 | |||
141 | #define NCT6683_REG_MON(x) (0x100 + (x) * 2) | ||
142 | #define NCT6683_REG_FAN_RPM(x) (0x140 + (x) * 2) | ||
143 | #define NCT6683_REG_PWM(x) (0x160 + (x)) | ||
144 | |||
145 | #define NCT6683_REG_MON_STS(x) (0x174 + (x)) | ||
146 | #define NCT6683_REG_IDLE(x) (0x178 + (x)) | ||
147 | |||
148 | #define NCT6683_REG_FAN_STS(x) (0x17c + (x)) | ||
149 | #define NCT6683_REG_FAN_ERRSTS 0x17e | ||
150 | #define NCT6683_REG_FAN_INITSTS 0x17f | ||
151 | |||
152 | #define NCT6683_HWM_CFG 0x180 | ||
153 | |||
154 | #define NCT6683_REG_MON_CFG(x) (0x1a0 + (x)) | ||
155 | #define NCT6683_REG_FANIN_CFG(x) (0x1c0 + (x)) | ||
156 | #define NCT6683_REG_FANOUT_CFG(x) (0x1d0 + (x)) | ||
157 | |||
158 | #define NCT6683_REG_INTEL_TEMP_MAX(x) (0x901 + (x) * 16) | ||
159 | #define NCT6683_REG_INTEL_TEMP_CRIT(x) (0x90d + (x) * 16) | ||
160 | |||
161 | #define NCT6683_REG_TEMP_HYST(x) (0x330 + (x)) /* 8 bit */ | ||
162 | #define NCT6683_REG_TEMP_MAX(x) (0x350 + (x)) /* 8 bit */ | ||
163 | #define NCT6683_REG_MON_HIGH(x) (0x370 + (x) * 2) /* 8 bit */ | ||
164 | #define NCT6683_REG_MON_LOW(x) (0x371 + (x) * 2) /* 8 bit */ | ||
165 | |||
166 | #define NCT6683_REG_FAN_MIN(x) (0x3b8 + (x) * 2) /* 16 bit */ | ||
167 | |||
168 | #define NCT6683_REG_CUSTOMER_ID 0x602 | ||
169 | #define NCT6683_CUSTOMER_ID_INTEL 0x805 | ||
170 | |||
171 | #define NCT6683_REG_BUILD_YEAR 0x604 | ||
172 | #define NCT6683_REG_BUILD_MONTH 0x605 | ||
173 | #define NCT6683_REG_BUILD_DAY 0x606 | ||
174 | #define NCT6683_REG_SERIAL 0x607 | ||
175 | #define NCT6683_REG_VERSION_HI 0x608 | ||
176 | #define NCT6683_REG_VERSION_LO 0x609 | ||
177 | |||
178 | #define NCT6683_REG_CR_CASEOPEN 0xe8 | ||
179 | #define NCT6683_CR_CASEOPEN_MASK (1 << 7) | ||
180 | |||
181 | #define NCT6683_REG_CR_BEEP 0xe0 | ||
182 | #define NCT6683_CR_BEEP_MASK (1 << 6) | ||
183 | |||
184 | static const char *const nct6683_mon_label[] = { | ||
185 | NULL, /* disabled */ | ||
186 | "Local", | ||
187 | "Diode 0 (curr)", | ||
188 | "Diode 1 (curr)", | ||
189 | "Diode 2 (curr)", | ||
190 | "Diode 0 (volt)", | ||
191 | "Diode 1 (volt)", | ||
192 | "Diode 2 (volt)", | ||
193 | "Thermistor 14", | ||
194 | "Thermistor 15", | ||
195 | "Thermistor 16", | ||
196 | "Thermistor 0", | ||
197 | "Thermistor 1", | ||
198 | "Thermistor 2", | ||
199 | "Thermistor 3", | ||
200 | "Thermistor 4", | ||
201 | "Thermistor 5", /* 0x10 */ | ||
202 | "Thermistor 6", | ||
203 | "Thermistor 7", | ||
204 | "Thermistor 8", | ||
205 | "Thermistor 9", | ||
206 | "Thermistor 10", | ||
207 | "Thermistor 11", | ||
208 | "Thermistor 12", | ||
209 | "Thermistor 13", | ||
210 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, | ||
211 | "PECI 0.0", /* 0x20 */ | ||
212 | "PECI 1.0", | ||
213 | "PECI 2.0", | ||
214 | "PECI 3.0", | ||
215 | "PECI 0.1", | ||
216 | "PECI 1.1", | ||
217 | "PECI 2.1", | ||
218 | "PECI 3.1", | ||
219 | "PECI DIMM 0", | ||
220 | "PECI DIMM 1", | ||
221 | "PECI DIMM 2", | ||
222 | "PECI DIMM 3", | ||
223 | NULL, NULL, NULL, NULL, | ||
224 | "PCH CPU", /* 0x30 */ | ||
225 | "PCH CHIP", | ||
226 | "PCH CHIP CPU MAX", | ||
227 | "PCH MCH", | ||
228 | "PCH DIMM 0", | ||
229 | "PCH DIMM 1", | ||
230 | "PCH DIMM 2", | ||
231 | "PCH DIMM 3", | ||
232 | "SMBus 0", | ||
233 | "SMBus 1", | ||
234 | "SMBus 2", | ||
235 | "SMBus 3", | ||
236 | "SMBus 4", | ||
237 | "SMBus 5", | ||
238 | "DIMM 0", | ||
239 | "DIMM 1", | ||
240 | "DIMM 2", /* 0x40 */ | ||
241 | "DIMM 3", | ||
242 | "AMD TSI Addr 90h", | ||
243 | "AMD TSI Addr 92h", | ||
244 | "AMD TSI Addr 94h", | ||
245 | "AMD TSI Addr 96h", | ||
246 | "AMD TSI Addr 98h", | ||
247 | "AMD TSI Addr 9ah", | ||
248 | "AMD TSI Addr 9ch", | ||
249 | "AMD TSI Addr 9dh", | ||
250 | NULL, NULL, NULL, NULL, NULL, NULL, | ||
251 | "Virtual 0", /* 0x50 */ | ||
252 | "Virtual 1", | ||
253 | "Virtual 2", | ||
254 | "Virtual 3", | ||
255 | "Virtual 4", | ||
256 | "Virtual 5", | ||
257 | "Virtual 6", | ||
258 | "Virtual 7", | ||
259 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | ||
260 | "VCC", /* 0x60 voltage sensors */ | ||
261 | "VSB", | ||
262 | "AVSB", | ||
263 | "VTT", | ||
264 | "VBAT", | ||
265 | "VREF", | ||
266 | "VIN0", | ||
267 | "VIN1", | ||
268 | "VIN2", | ||
269 | "VIN3", | ||
270 | "VIN4", | ||
271 | "VIN5", | ||
272 | "VIN6", | ||
273 | "VIN7", | ||
274 | "VIN8", | ||
275 | "VIN9", | ||
276 | "VIN10", | ||
277 | "VIN11", | ||
278 | "VIN12", | ||
279 | "VIN13", | ||
280 | "VIN14", | ||
281 | "VIN15", | ||
282 | "VIN16", | ||
283 | }; | ||
284 | |||
285 | #define NUM_MON_LABELS ARRAY_SIZE(nct6683_mon_label) | ||
286 | #define MON_VOLTAGE_START 0x60 | ||
287 | |||
288 | /* ------------------------------------------------------- */ | ||
289 | |||
290 | struct nct6683_data { | ||
291 | int addr; /* IO base of EC space */ | ||
292 | int sioreg; /* SIO register */ | ||
293 | enum kinds kind; | ||
294 | u16 customer_id; | ||
295 | |||
296 | struct device *hwmon_dev; | ||
297 | const struct attribute_group *groups[6]; | ||
298 | |||
299 | int temp_num; /* number of temperature attributes */ | ||
300 | u8 temp_index[NCT6683_NUM_REG_MON]; | ||
301 | u8 temp_src[NCT6683_NUM_REG_MON]; | ||
302 | |||
303 | u8 in_num; /* number of voltage attributes */ | ||
304 | u8 in_index[NCT6683_NUM_REG_MON]; | ||
305 | u8 in_src[NCT6683_NUM_REG_MON]; | ||
306 | |||
307 | struct mutex update_lock; /* used to protect sensor updates */ | ||
308 | bool valid; /* true if following fields are valid */ | ||
309 | unsigned long last_updated; /* In jiffies */ | ||
310 | |||
311 | /* Voltage attribute values */ | ||
312 | u8 in[3][NCT6683_NUM_REG_MON]; /* [0]=in, [1]=in_max, [2]=in_min */ | ||
313 | |||
314 | /* Temperature attribute values */ | ||
315 | s16 temp_in[NCT6683_NUM_REG_MON]; | ||
316 | s8 temp[4][NCT6683_NUM_REG_MON];/* [0]=min, [1]=max, [2]=hyst, | ||
317 | * [3]=crit | ||
318 | */ | ||
319 | |||
320 | /* Fan attribute values */ | ||
321 | unsigned int rpm[NCT6683_NUM_REG_FAN]; | ||
322 | u16 fan_min[NCT6683_NUM_REG_FAN]; | ||
323 | u8 fanin_cfg[NCT6683_NUM_REG_FAN]; | ||
324 | u8 fanout_cfg[NCT6683_NUM_REG_FAN]; | ||
325 | u16 have_fan; /* some fan inputs can be disabled */ | ||
326 | |||
327 | u8 have_pwm; | ||
328 | u8 pwm[NCT6683_NUM_REG_PWM]; | ||
329 | |||
330 | #ifdef CONFIG_PM | ||
331 | /* Remember extra register values over suspend/resume */ | ||
332 | u8 hwm_cfg; | ||
333 | #endif | ||
334 | }; | ||
335 | |||
336 | struct nct6683_sio_data { | ||
337 | int sioreg; | ||
338 | enum kinds kind; | ||
339 | }; | ||
340 | |||
341 | struct sensor_device_template { | ||
342 | struct device_attribute dev_attr; | ||
343 | union { | ||
344 | struct { | ||
345 | u8 nr; | ||
346 | u8 index; | ||
347 | } s; | ||
348 | int index; | ||
349 | } u; | ||
350 | bool s2; /* true if both index and nr are used */ | ||
351 | }; | ||
352 | |||
353 | struct sensor_device_attr_u { | ||
354 | union { | ||
355 | struct sensor_device_attribute a1; | ||
356 | struct sensor_device_attribute_2 a2; | ||
357 | } u; | ||
358 | char name[32]; | ||
359 | }; | ||
360 | |||
361 | #define __TEMPLATE_ATTR(_template, _mode, _show, _store) { \ | ||
362 | .attr = {.name = _template, .mode = _mode }, \ | ||
363 | .show = _show, \ | ||
364 | .store = _store, \ | ||
365 | } | ||
366 | |||
367 | #define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index) \ | ||
368 | { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \ | ||
369 | .u.index = _index, \ | ||
370 | .s2 = false } | ||
371 | |||
372 | #define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \ | ||
373 | _nr, _index) \ | ||
374 | { .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \ | ||
375 | .u.s.index = _index, \ | ||
376 | .u.s.nr = _nr, \ | ||
377 | .s2 = true } | ||
378 | |||
379 | #define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index) \ | ||
380 | static struct sensor_device_template sensor_dev_template_##_name \ | ||
381 | = SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, \ | ||
382 | _index) | ||
383 | |||
384 | #define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store, \ | ||
385 | _nr, _index) \ | ||
386 | static struct sensor_device_template sensor_dev_template_##_name \ | ||
387 | = SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \ | ||
388 | _nr, _index) | ||
389 | |||
390 | struct sensor_template_group { | ||
391 | struct sensor_device_template **templates; | ||
392 | umode_t (*is_visible)(struct kobject *, struct attribute *, int); | ||
393 | int base; | ||
394 | }; | ||
395 | |||
396 | static struct attribute_group * | ||
397 | nct6683_create_attr_group(struct device *dev, struct sensor_template_group *tg, | ||
398 | int repeat) | ||
399 | { | ||
400 | struct sensor_device_attribute_2 *a2; | ||
401 | struct sensor_device_attribute *a; | ||
402 | struct sensor_device_template **t; | ||
403 | struct sensor_device_attr_u *su; | ||
404 | struct attribute_group *group; | ||
405 | struct attribute **attrs; | ||
406 | int i, j, count; | ||
407 | |||
408 | if (repeat <= 0) | ||
409 | return ERR_PTR(-EINVAL); | ||
410 | |||
411 | t = tg->templates; | ||
412 | for (count = 0; *t; t++, count++) | ||
413 | ; | ||
414 | |||
415 | if (count == 0) | ||
416 | return ERR_PTR(-EINVAL); | ||
417 | |||
418 | group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL); | ||
419 | if (group == NULL) | ||
420 | return ERR_PTR(-ENOMEM); | ||
421 | |||
422 | attrs = devm_kzalloc(dev, sizeof(*attrs) * (repeat * count + 1), | ||
423 | GFP_KERNEL); | ||
424 | if (attrs == NULL) | ||
425 | return ERR_PTR(-ENOMEM); | ||
426 | |||
427 | su = devm_kzalloc(dev, sizeof(*su) * repeat * count, | ||
428 | GFP_KERNEL); | ||
429 | if (su == NULL) | ||
430 | return ERR_PTR(-ENOMEM); | ||
431 | |||
432 | group->attrs = attrs; | ||
433 | group->is_visible = tg->is_visible; | ||
434 | |||
435 | for (i = 0; i < repeat; i++) { | ||
436 | t = tg->templates; | ||
437 | for (j = 0; *t != NULL; j++) { | ||
438 | snprintf(su->name, sizeof(su->name), | ||
439 | (*t)->dev_attr.attr.name, tg->base + i); | ||
440 | if ((*t)->s2) { | ||
441 | a2 = &su->u.a2; | ||
442 | a2->dev_attr.attr.name = su->name; | ||
443 | a2->nr = (*t)->u.s.nr + i; | ||
444 | a2->index = (*t)->u.s.index; | ||
445 | a2->dev_attr.attr.mode = | ||
446 | (*t)->dev_attr.attr.mode; | ||
447 | a2->dev_attr.show = (*t)->dev_attr.show; | ||
448 | a2->dev_attr.store = (*t)->dev_attr.store; | ||
449 | *attrs = &a2->dev_attr.attr; | ||
450 | } else { | ||
451 | a = &su->u.a1; | ||
452 | a->dev_attr.attr.name = su->name; | ||
453 | a->index = (*t)->u.index + i; | ||
454 | a->dev_attr.attr.mode = | ||
455 | (*t)->dev_attr.attr.mode; | ||
456 | a->dev_attr.show = (*t)->dev_attr.show; | ||
457 | a->dev_attr.store = (*t)->dev_attr.store; | ||
458 | *attrs = &a->dev_attr.attr; | ||
459 | } | ||
460 | attrs++; | ||
461 | su++; | ||
462 | t++; | ||
463 | } | ||
464 | } | ||
465 | |||
466 | return group; | ||
467 | } | ||
468 | |||
469 | /* LSB is 16 mV, except for the following sources, where it is 32 mV */ | ||
470 | #define MON_SRC_VCC 0x60 | ||
471 | #define MON_SRC_VSB 0x61 | ||
472 | #define MON_SRC_AVSB 0x62 | ||
473 | #define MON_SRC_VBAT 0x64 | ||
474 | |||
475 | static inline long in_from_reg(u16 reg, u8 src) | ||
476 | { | ||
477 | int scale = 16; | ||
478 | |||
479 | if (src == MON_SRC_VCC || src == MON_SRC_VSB || src == MON_SRC_AVSB || | ||
480 | src == MON_SRC_VBAT) | ||
481 | scale <<= 1; | ||
482 | return reg * scale; | ||
483 | } | ||
484 | |||
485 | static inline u16 in_to_reg(u32 val, u8 src) | ||
486 | { | ||
487 | int scale = 16; | ||
488 | |||
489 | if (src == MON_SRC_VCC || src == MON_SRC_VSB || src == MON_SRC_AVSB || | ||
490 | src == MON_SRC_VBAT) | ||
491 | scale <<= 1; | ||
492 | |||
493 | return clamp_val(DIV_ROUND_CLOSEST(val, scale), 0, 127); | ||
494 | } | ||
495 | |||
496 | static u16 nct6683_read(struct nct6683_data *data, u16 reg) | ||
497 | { | ||
498 | int res; | ||
499 | |||
500 | outb_p(0xff, data->addr + EC_PAGE_REG); /* unlock */ | ||
501 | outb_p(reg >> 8, data->addr + EC_PAGE_REG); | ||
502 | outb_p(reg & 0xff, data->addr + EC_INDEX_REG); | ||
503 | res = inb_p(data->addr + EC_DATA_REG); | ||
504 | return res; | ||
505 | } | ||
506 | |||
507 | static u16 nct6683_read16(struct nct6683_data *data, u16 reg) | ||
508 | { | ||
509 | return (nct6683_read(data, reg) << 8) | nct6683_read(data, reg + 1); | ||
510 | } | ||
511 | |||
512 | static void nct6683_write(struct nct6683_data *data, u16 reg, u16 value) | ||
513 | { | ||
514 | outb_p(0xff, data->addr + EC_PAGE_REG); /* unlock */ | ||
515 | outb_p(reg >> 8, data->addr + EC_PAGE_REG); | ||
516 | outb_p(reg & 0xff, data->addr + EC_INDEX_REG); | ||
517 | outb_p(value & 0xff, data->addr + EC_DATA_REG); | ||
518 | } | ||
519 | |||
520 | static int get_in_reg(struct nct6683_data *data, int nr, int index) | ||
521 | { | ||
522 | int ch = data->in_index[index]; | ||
523 | int reg = -EINVAL; | ||
524 | |||
525 | switch (nr) { | ||
526 | case 0: | ||
527 | reg = NCT6683_REG_MON(ch); | ||
528 | break; | ||
529 | case 1: | ||
530 | if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL) | ||
531 | reg = NCT6683_REG_MON_LOW(ch); | ||
532 | break; | ||
533 | case 2: | ||
534 | if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL) | ||
535 | reg = NCT6683_REG_MON_HIGH(ch); | ||
536 | break; | ||
537 | default: | ||
538 | break; | ||
539 | } | ||
540 | return reg; | ||
541 | } | ||
542 | |||
543 | static int get_temp_reg(struct nct6683_data *data, int nr, int index) | ||
544 | { | ||
545 | int ch = data->temp_index[index]; | ||
546 | int reg = -EINVAL; | ||
547 | |||
548 | switch (data->customer_id) { | ||
549 | case NCT6683_CUSTOMER_ID_INTEL: | ||
550 | switch (nr) { | ||
551 | default: | ||
552 | case 1: /* max */ | ||
553 | reg = NCT6683_REG_INTEL_TEMP_MAX(ch); | ||
554 | break; | ||
555 | case 3: /* crit */ | ||
556 | reg = NCT6683_REG_INTEL_TEMP_CRIT(ch); | ||
557 | break; | ||
558 | } | ||
559 | break; | ||
560 | default: | ||
561 | switch (nr) { | ||
562 | default: | ||
563 | case 0: /* min */ | ||
564 | reg = NCT6683_REG_MON_LOW(ch); | ||
565 | break; | ||
566 | case 1: /* max */ | ||
567 | reg = NCT6683_REG_TEMP_MAX(ch); | ||
568 | break; | ||
569 | case 2: /* hyst */ | ||
570 | reg = NCT6683_REG_TEMP_HYST(ch); | ||
571 | break; | ||
572 | case 3: /* crit */ | ||
573 | reg = NCT6683_REG_MON_HIGH(ch); | ||
574 | break; | ||
575 | } | ||
576 | break; | ||
577 | } | ||
578 | return reg; | ||
579 | } | ||
580 | |||
581 | static void nct6683_update_pwm(struct device *dev) | ||
582 | { | ||
583 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
584 | int i; | ||
585 | |||
586 | for (i = 0; i < NCT6683_NUM_REG_PWM; i++) { | ||
587 | if (!(data->have_pwm & (1 << i))) | ||
588 | continue; | ||
589 | data->pwm[i] = nct6683_read(data, NCT6683_REG_PWM(i)); | ||
590 | } | ||
591 | } | ||
592 | |||
593 | static struct nct6683_data *nct6683_update_device(struct device *dev) | ||
594 | { | ||
595 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
596 | int i, j; | ||
597 | |||
598 | mutex_lock(&data->update_lock); | ||
599 | |||
600 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
601 | /* Measured voltages and limits */ | ||
602 | for (i = 0; i < data->in_num; i++) { | ||
603 | for (j = 0; j < 3; j++) { | ||
604 | int reg = get_in_reg(data, j, i); | ||
605 | |||
606 | if (reg >= 0) | ||
607 | data->in[j][i] = | ||
608 | nct6683_read(data, reg); | ||
609 | } | ||
610 | } | ||
611 | |||
612 | /* Measured temperatures and limits */ | ||
613 | for (i = 0; i < data->temp_num; i++) { | ||
614 | u8 ch = data->temp_index[i]; | ||
615 | |||
616 | data->temp_in[i] = nct6683_read16(data, | ||
617 | NCT6683_REG_MON(ch)); | ||
618 | for (j = 0; j < 4; j++) { | ||
619 | int reg = get_temp_reg(data, j, i); | ||
620 | |||
621 | if (reg >= 0) | ||
622 | data->temp[j][i] = | ||
623 | nct6683_read(data, reg); | ||
624 | } | ||
625 | } | ||
626 | |||
627 | /* Measured fan speeds and limits */ | ||
628 | for (i = 0; i < ARRAY_SIZE(data->rpm); i++) { | ||
629 | if (!(data->have_fan & (1 << i))) | ||
630 | continue; | ||
631 | |||
632 | data->rpm[i] = nct6683_read16(data, | ||
633 | NCT6683_REG_FAN_RPM(i)); | ||
634 | data->fan_min[i] = nct6683_read16(data, | ||
635 | NCT6683_REG_FAN_MIN(i)); | ||
636 | } | ||
637 | |||
638 | nct6683_update_pwm(dev); | ||
639 | |||
640 | data->last_updated = jiffies; | ||
641 | data->valid = true; | ||
642 | } | ||
643 | |||
644 | mutex_unlock(&data->update_lock); | ||
645 | return data; | ||
646 | } | ||
647 | |||
648 | /* | ||
649 | * Sysfs callback functions | ||
650 | */ | ||
651 | static ssize_t | ||
652 | show_in_label(struct device *dev, struct device_attribute *attr, char *buf) | ||
653 | { | ||
654 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
655 | struct nct6683_data *data = nct6683_update_device(dev); | ||
656 | int nr = sattr->index; | ||
657 | |||
658 | return sprintf(buf, "%s\n", nct6683_mon_label[data->in_src[nr]]); | ||
659 | } | ||
660 | |||
661 | static ssize_t | ||
662 | show_in_reg(struct device *dev, struct device_attribute *attr, char *buf) | ||
663 | { | ||
664 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
665 | struct nct6683_data *data = nct6683_update_device(dev); | ||
666 | int index = sattr->index; | ||
667 | int nr = sattr->nr; | ||
668 | |||
669 | return sprintf(buf, "%ld\n", | ||
670 | in_from_reg(data->in[index][nr], data->in_index[index])); | ||
671 | } | ||
672 | |||
673 | static umode_t nct6683_in_is_visible(struct kobject *kobj, | ||
674 | struct attribute *attr, int index) | ||
675 | { | ||
676 | struct device *dev = container_of(kobj, struct device, kobj); | ||
677 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
678 | int nr = index % 4; /* attribute */ | ||
679 | |||
680 | /* | ||
681 | * Voltage limits exist for Intel boards, | ||
682 | * but register location and encoding is unknown | ||
683 | */ | ||
684 | if ((nr == 2 || nr == 3) && | ||
685 | data->customer_id == NCT6683_CUSTOMER_ID_INTEL) | ||
686 | return 0; | ||
687 | |||
688 | return attr->mode; | ||
689 | } | ||
690 | |||
691 | SENSOR_TEMPLATE(in_label, "in%d_label", S_IRUGO, show_in_label, NULL, 0); | ||
692 | SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0); | ||
693 | SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IRUGO, show_in_reg, NULL, 0, 1); | ||
694 | SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IRUGO, show_in_reg, NULL, 0, 2); | ||
695 | |||
696 | static struct sensor_device_template *nct6683_attributes_in_template[] = { | ||
697 | &sensor_dev_template_in_label, | ||
698 | &sensor_dev_template_in_input, | ||
699 | &sensor_dev_template_in_min, | ||
700 | &sensor_dev_template_in_max, | ||
701 | NULL | ||
702 | }; | ||
703 | |||
704 | static struct sensor_template_group nct6683_in_template_group = { | ||
705 | .templates = nct6683_attributes_in_template, | ||
706 | .is_visible = nct6683_in_is_visible, | ||
707 | }; | ||
708 | |||
709 | static ssize_t | ||
710 | show_fan(struct device *dev, struct device_attribute *attr, char *buf) | ||
711 | { | ||
712 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
713 | struct nct6683_data *data = nct6683_update_device(dev); | ||
714 | |||
715 | return sprintf(buf, "%d\n", data->rpm[sattr->index]); | ||
716 | } | ||
717 | |||
718 | static ssize_t | ||
719 | show_fan_min(struct device *dev, struct device_attribute *attr, char *buf) | ||
720 | { | ||
721 | struct nct6683_data *data = nct6683_update_device(dev); | ||
722 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
723 | int nr = sattr->index; | ||
724 | |||
725 | return sprintf(buf, "%d\n", data->fan_min[nr]); | ||
726 | } | ||
727 | |||
728 | static ssize_t | ||
729 | show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf) | ||
730 | { | ||
731 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
732 | struct nct6683_data *data = nct6683_update_device(dev); | ||
733 | |||
734 | return sprintf(buf, "%d\n", | ||
735 | ((data->fanin_cfg[sattr->index] >> 5) & 0x03) + 1); | ||
736 | } | ||
737 | |||
738 | static umode_t nct6683_fan_is_visible(struct kobject *kobj, | ||
739 | struct attribute *attr, int index) | ||
740 | { | ||
741 | struct device *dev = container_of(kobj, struct device, kobj); | ||
742 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
743 | int fan = index / 3; /* fan index */ | ||
744 | int nr = index % 3; /* attribute index */ | ||
745 | |||
746 | if (!(data->have_fan & (1 << fan))) | ||
747 | return 0; | ||
748 | |||
749 | /* | ||
750 | * Intel may have minimum fan speed limits, | ||
751 | * but register location and encoding are unknown. | ||
752 | */ | ||
753 | if (nr == 2 && data->customer_id == NCT6683_CUSTOMER_ID_INTEL) | ||
754 | return 0; | ||
755 | |||
756 | return attr->mode; | ||
757 | } | ||
758 | |||
759 | SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0); | ||
760 | SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IRUGO, show_fan_pulses, NULL, 0); | ||
761 | SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IRUGO, show_fan_min, NULL, 0); | ||
762 | |||
763 | /* | ||
764 | * nct6683_fan_is_visible uses the index into the following array | ||
765 | * to determine if attributes should be created or not. | ||
766 | * Any change in order or content must be matched. | ||
767 | */ | ||
768 | static struct sensor_device_template *nct6683_attributes_fan_template[] = { | ||
769 | &sensor_dev_template_fan_input, | ||
770 | &sensor_dev_template_fan_pulses, | ||
771 | &sensor_dev_template_fan_min, | ||
772 | NULL | ||
773 | }; | ||
774 | |||
775 | static struct sensor_template_group nct6683_fan_template_group = { | ||
776 | .templates = nct6683_attributes_fan_template, | ||
777 | .is_visible = nct6683_fan_is_visible, | ||
778 | .base = 1, | ||
779 | }; | ||
780 | |||
781 | static ssize_t | ||
782 | show_temp_label(struct device *dev, struct device_attribute *attr, char *buf) | ||
783 | { | ||
784 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
785 | struct nct6683_data *data = nct6683_update_device(dev); | ||
786 | int nr = sattr->index; | ||
787 | |||
788 | return sprintf(buf, "%s\n", nct6683_mon_label[data->temp_src[nr]]); | ||
789 | } | ||
790 | |||
791 | static ssize_t | ||
792 | show_temp8(struct device *dev, struct device_attribute *attr, char *buf) | ||
793 | { | ||
794 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
795 | struct nct6683_data *data = nct6683_update_device(dev); | ||
796 | int index = sattr->index; | ||
797 | int nr = sattr->nr; | ||
798 | |||
799 | return sprintf(buf, "%d\n", data->temp[index][nr] * 1000); | ||
800 | } | ||
801 | |||
802 | static ssize_t | ||
803 | show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf) | ||
804 | { | ||
805 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
806 | struct nct6683_data *data = nct6683_update_device(dev); | ||
807 | int nr = sattr->index; | ||
808 | int temp = data->temp[1][nr] - data->temp[2][nr]; | ||
809 | |||
810 | return sprintf(buf, "%d\n", temp * 1000); | ||
811 | } | ||
812 | |||
813 | static ssize_t | ||
814 | show_temp16(struct device *dev, struct device_attribute *attr, char *buf) | ||
815 | { | ||
816 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
817 | struct nct6683_data *data = nct6683_update_device(dev); | ||
818 | int index = sattr->index; | ||
819 | |||
820 | return sprintf(buf, "%d\n", (data->temp_in[index] / 128) * 500); | ||
821 | } | ||
822 | |||
823 | /* | ||
824 | * Temperature sensor type is determined by temperature source | ||
825 | * and can not be modified. | ||
826 | * 0x02..0x07: Thermal diode | ||
827 | * 0x08..0x18: Thermistor | ||
828 | * 0x20..0x2b: Intel PECI | ||
829 | * 0x42..0x49: AMD TSI | ||
830 | * Others are unspecified (not visible) | ||
831 | */ | ||
832 | |||
833 | static int get_temp_type(u8 src) | ||
834 | { | ||
835 | if (src >= 0x02 && src <= 0x07) | ||
836 | return 3; /* thermal diode */ | ||
837 | else if (src >= 0x08 && src <= 0x18) | ||
838 | return 4; /* thermistor */ | ||
839 | else if (src >= 0x20 && src <= 0x2b) | ||
840 | return 6; /* PECI */ | ||
841 | else if (src >= 0x42 && src <= 0x49) | ||
842 | return 5; | ||
843 | |||
844 | return 0; | ||
845 | } | ||
846 | |||
847 | static ssize_t | ||
848 | show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) | ||
849 | { | ||
850 | struct nct6683_data *data = nct6683_update_device(dev); | ||
851 | struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr); | ||
852 | int nr = sattr->index; | ||
853 | return sprintf(buf, "%d\n", get_temp_type(data->temp_src[nr])); | ||
854 | } | ||
855 | |||
856 | static umode_t nct6683_temp_is_visible(struct kobject *kobj, | ||
857 | struct attribute *attr, int index) | ||
858 | { | ||
859 | struct device *dev = container_of(kobj, struct device, kobj); | ||
860 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
861 | int temp = index / 7; /* temp index */ | ||
862 | int nr = index % 7; /* attribute index */ | ||
863 | |||
864 | /* | ||
865 | * Intel does not have low temperature limits or temperature hysteresis | ||
866 | * registers, or at least register location and encoding is unknown. | ||
867 | */ | ||
868 | if ((nr == 2 || nr == 4) && | ||
869 | data->customer_id == NCT6683_CUSTOMER_ID_INTEL) | ||
870 | return 0; | ||
871 | |||
872 | if (nr == 6 && get_temp_type(data->temp_src[temp]) == 0) | ||
873 | return 0; /* type */ | ||
874 | |||
875 | return attr->mode; | ||
876 | } | ||
877 | |||
878 | SENSOR_TEMPLATE(temp_input, "temp%d_input", S_IRUGO, show_temp16, NULL, 0); | ||
879 | SENSOR_TEMPLATE(temp_label, "temp%d_label", S_IRUGO, show_temp_label, NULL, 0); | ||
880 | SENSOR_TEMPLATE_2(temp_min, "temp%d_min", S_IRUGO, show_temp8, NULL, 0, 0); | ||
881 | SENSOR_TEMPLATE_2(temp_max, "temp%d_max", S_IRUGO, show_temp8, NULL, 0, 1); | ||
882 | SENSOR_TEMPLATE(temp_max_hyst, "temp%d_max_hyst", S_IRUGO, show_temp_hyst, NULL, | ||
883 | 0); | ||
884 | SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", S_IRUGO, show_temp8, NULL, 0, 3); | ||
885 | SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO, show_temp_type, NULL, 0); | ||
886 | |||
887 | /* | ||
888 | * nct6683_temp_is_visible uses the index into the following array | ||
889 | * to determine if attributes should be created or not. | ||
890 | * Any change in order or content must be matched. | ||
891 | */ | ||
892 | static struct sensor_device_template *nct6683_attributes_temp_template[] = { | ||
893 | &sensor_dev_template_temp_input, | ||
894 | &sensor_dev_template_temp_label, | ||
895 | &sensor_dev_template_temp_min, /* 2 */ | ||
896 | &sensor_dev_template_temp_max, /* 3 */ | ||
897 | &sensor_dev_template_temp_max_hyst, /* 4 */ | ||
898 | &sensor_dev_template_temp_crit, /* 5 */ | ||
899 | &sensor_dev_template_temp_type, /* 6 */ | ||
900 | NULL | ||
901 | }; | ||
902 | |||
903 | static struct sensor_template_group nct6683_temp_template_group = { | ||
904 | .templates = nct6683_attributes_temp_template, | ||
905 | .is_visible = nct6683_temp_is_visible, | ||
906 | .base = 1, | ||
907 | }; | ||
908 | |||
909 | static ssize_t | ||
910 | show_pwm(struct device *dev, struct device_attribute *attr, char *buf) | ||
911 | { | ||
912 | struct nct6683_data *data = nct6683_update_device(dev); | ||
913 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); | ||
914 | int index = sattr->index; | ||
915 | |||
916 | return sprintf(buf, "%d\n", data->pwm[index]); | ||
917 | } | ||
918 | |||
919 | SENSOR_TEMPLATE(pwm, "pwm%d", S_IRUGO, show_pwm, NULL, 0); | ||
920 | |||
921 | static umode_t nct6683_pwm_is_visible(struct kobject *kobj, | ||
922 | struct attribute *attr, int index) | ||
923 | { | ||
924 | struct device *dev = container_of(kobj, struct device, kobj); | ||
925 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
926 | int pwm = index; /* pwm index */ | ||
927 | |||
928 | if (!(data->have_pwm & (1 << pwm))) | ||
929 | return 0; | ||
930 | |||
931 | return attr->mode; | ||
932 | } | ||
933 | |||
934 | static struct sensor_device_template *nct6683_attributes_pwm_template[] = { | ||
935 | &sensor_dev_template_pwm, | ||
936 | NULL | ||
937 | }; | ||
938 | |||
939 | static struct sensor_template_group nct6683_pwm_template_group = { | ||
940 | .templates = nct6683_attributes_pwm_template, | ||
941 | .is_visible = nct6683_pwm_is_visible, | ||
942 | .base = 1, | ||
943 | }; | ||
944 | |||
945 | static ssize_t | ||
946 | show_global_beep(struct device *dev, struct device_attribute *attr, char *buf) | ||
947 | { | ||
948 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
949 | int ret; | ||
950 | u8 reg; | ||
951 | |||
952 | mutex_lock(&data->update_lock); | ||
953 | |||
954 | ret = superio_enter(data->sioreg); | ||
955 | if (ret) | ||
956 | goto error; | ||
957 | superio_select(data->sioreg, NCT6683_LD_HWM); | ||
958 | reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP); | ||
959 | superio_exit(data->sioreg); | ||
960 | |||
961 | mutex_unlock(&data->update_lock); | ||
962 | |||
963 | return sprintf(buf, "%u\n", !!(reg & NCT6683_CR_BEEP_MASK)); | ||
964 | |||
965 | error: | ||
966 | mutex_unlock(&data->update_lock); | ||
967 | return ret; | ||
968 | } | ||
969 | |||
970 | static ssize_t | ||
971 | store_global_beep(struct device *dev, struct device_attribute *attr, | ||
972 | const char *buf, size_t count) | ||
973 | { | ||
974 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
975 | unsigned long val; | ||
976 | u8 reg; | ||
977 | int ret; | ||
978 | |||
979 | if (kstrtoul(buf, 10, &val) || (val != 0 && val != 1)) | ||
980 | return -EINVAL; | ||
981 | |||
982 | mutex_lock(&data->update_lock); | ||
983 | |||
984 | ret = superio_enter(data->sioreg); | ||
985 | if (ret) { | ||
986 | count = ret; | ||
987 | goto error; | ||
988 | } | ||
989 | |||
990 | superio_select(data->sioreg, NCT6683_LD_HWM); | ||
991 | reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP); | ||
992 | if (val) | ||
993 | reg |= NCT6683_CR_BEEP_MASK; | ||
994 | else | ||
995 | reg &= ~NCT6683_CR_BEEP_MASK; | ||
996 | superio_outb(data->sioreg, NCT6683_REG_CR_BEEP, reg); | ||
997 | superio_exit(data->sioreg); | ||
998 | error: | ||
999 | mutex_unlock(&data->update_lock); | ||
1000 | return count; | ||
1001 | } | ||
1002 | |||
1003 | /* Case open detection */ | ||
1004 | |||
1005 | static ssize_t | ||
1006 | show_caseopen(struct device *dev, struct device_attribute *attr, char *buf) | ||
1007 | { | ||
1008 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
1009 | int ret; | ||
1010 | u8 reg; | ||
1011 | |||
1012 | mutex_lock(&data->update_lock); | ||
1013 | |||
1014 | ret = superio_enter(data->sioreg); | ||
1015 | if (ret) | ||
1016 | goto error; | ||
1017 | superio_select(data->sioreg, NCT6683_LD_ACPI); | ||
1018 | reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN); | ||
1019 | superio_exit(data->sioreg); | ||
1020 | |||
1021 | mutex_unlock(&data->update_lock); | ||
1022 | |||
1023 | return sprintf(buf, "%u\n", !(reg & NCT6683_CR_CASEOPEN_MASK)); | ||
1024 | |||
1025 | error: | ||
1026 | mutex_unlock(&data->update_lock); | ||
1027 | return ret; | ||
1028 | } | ||
1029 | |||
1030 | static ssize_t | ||
1031 | clear_caseopen(struct device *dev, struct device_attribute *attr, | ||
1032 | const char *buf, size_t count) | ||
1033 | { | ||
1034 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
1035 | unsigned long val; | ||
1036 | u8 reg; | ||
1037 | int ret; | ||
1038 | |||
1039 | if (kstrtoul(buf, 10, &val) || val != 0) | ||
1040 | return -EINVAL; | ||
1041 | |||
1042 | mutex_lock(&data->update_lock); | ||
1043 | |||
1044 | /* | ||
1045 | * Use CR registers to clear caseopen status. | ||
1046 | * Caseopen is activ low, clear by writing 1 into the register. | ||
1047 | */ | ||
1048 | |||
1049 | ret = superio_enter(data->sioreg); | ||
1050 | if (ret) { | ||
1051 | count = ret; | ||
1052 | goto error; | ||
1053 | } | ||
1054 | |||
1055 | superio_select(data->sioreg, NCT6683_LD_ACPI); | ||
1056 | reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN); | ||
1057 | reg |= NCT6683_CR_CASEOPEN_MASK; | ||
1058 | superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg); | ||
1059 | reg &= ~NCT6683_CR_CASEOPEN_MASK; | ||
1060 | superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg); | ||
1061 | superio_exit(data->sioreg); | ||
1062 | |||
1063 | data->valid = false; /* Force cache refresh */ | ||
1064 | error: | ||
1065 | mutex_unlock(&data->update_lock); | ||
1066 | return count; | ||
1067 | } | ||
1068 | |||
1069 | static DEVICE_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_caseopen, | ||
1070 | clear_caseopen); | ||
1071 | static DEVICE_ATTR(beep_enable, S_IWUSR | S_IRUGO, show_global_beep, | ||
1072 | store_global_beep); | ||
1073 | |||
1074 | static struct attribute *nct6683_attributes_other[] = { | ||
1075 | &dev_attr_intrusion0_alarm.attr, | ||
1076 | &dev_attr_beep_enable.attr, | ||
1077 | NULL | ||
1078 | }; | ||
1079 | |||
1080 | static const struct attribute_group nct6683_group_other = { | ||
1081 | .attrs = nct6683_attributes_other, | ||
1082 | }; | ||
1083 | |||
1084 | /* Get the monitoring functions started */ | ||
1085 | static inline void nct6683_init_device(struct nct6683_data *data) | ||
1086 | { | ||
1087 | u8 tmp; | ||
1088 | |||
1089 | /* Start hardware monitoring if needed */ | ||
1090 | tmp = nct6683_read(data, NCT6683_HWM_CFG); | ||
1091 | if (!(tmp & 0x80)) | ||
1092 | nct6683_write(data, NCT6683_HWM_CFG, tmp | 0x80); | ||
1093 | } | ||
1094 | |||
1095 | /* | ||
1096 | * There are a total of 24 fan inputs. Each can be configured as input | ||
1097 | * or as output. A maximum of 16 inputs and 8 outputs is configurable. | ||
1098 | */ | ||
1099 | static void | ||
1100 | nct6683_setup_fans(struct nct6683_data *data) | ||
1101 | { | ||
1102 | int i; | ||
1103 | u8 reg; | ||
1104 | |||
1105 | for (i = 0; i < NCT6683_NUM_REG_FAN; i++) { | ||
1106 | reg = nct6683_read(data, NCT6683_REG_FANIN_CFG(i)); | ||
1107 | if (reg & 0x80) | ||
1108 | data->have_fan |= 1 << i; | ||
1109 | data->fanin_cfg[i] = reg; | ||
1110 | } | ||
1111 | for (i = 0; i < NCT6683_NUM_REG_PWM; i++) { | ||
1112 | reg = nct6683_read(data, NCT6683_REG_FANOUT_CFG(i)); | ||
1113 | if (reg & 0x80) | ||
1114 | data->have_pwm |= 1 << i; | ||
1115 | data->fanout_cfg[i] = reg; | ||
1116 | } | ||
1117 | } | ||
1118 | |||
1119 | /* | ||
1120 | * Translation from monitoring register to temperature and voltage attributes | ||
1121 | * ========================================================================== | ||
1122 | * | ||
1123 | * There are a total of 32 monitoring registers. Each can be assigned to either | ||
1124 | * a temperature or voltage monitoring source. | ||
1125 | * NCT6683_REG_MON_CFG(x) defines assignment for each monitoring source. | ||
1126 | * | ||
1127 | * Temperature and voltage attribute mapping is determined by walking through | ||
1128 | * the NCT6683_REG_MON_CFG registers. If the assigned source is | ||
1129 | * a temperature, temp_index[n] is set to the monitor register index, and | ||
1130 | * temp_src[n] is set to the temperature source. If the assigned source is | ||
1131 | * a voltage, the respective values are stored in in_index[] and in_src[], | ||
1132 | * respectively. | ||
1133 | */ | ||
1134 | |||
1135 | static void nct6683_setup_sensors(struct nct6683_data *data) | ||
1136 | { | ||
1137 | u8 reg; | ||
1138 | int i; | ||
1139 | |||
1140 | data->temp_num = 0; | ||
1141 | data->in_num = 0; | ||
1142 | for (i = 0; i < NCT6683_NUM_REG_MON; i++) { | ||
1143 | reg = nct6683_read(data, NCT6683_REG_MON_CFG(i)) & 0x7f; | ||
1144 | /* Ignore invalid assignments */ | ||
1145 | if (reg >= NUM_MON_LABELS) | ||
1146 | continue; | ||
1147 | /* Skip if disabled or reserved */ | ||
1148 | if (nct6683_mon_label[reg] == NULL) | ||
1149 | continue; | ||
1150 | if (reg < MON_VOLTAGE_START) { | ||
1151 | data->temp_index[data->temp_num] = i; | ||
1152 | data->temp_src[data->temp_num] = reg; | ||
1153 | data->temp_num++; | ||
1154 | } else { | ||
1155 | data->in_index[data->in_num] = i; | ||
1156 | data->in_src[data->in_num] = reg; | ||
1157 | data->in_num++; | ||
1158 | } | ||
1159 | } | ||
1160 | } | ||
1161 | |||
1162 | static int nct6683_probe(struct platform_device *pdev) | ||
1163 | { | ||
1164 | struct device *dev = &pdev->dev; | ||
1165 | struct nct6683_sio_data *sio_data = dev->platform_data; | ||
1166 | struct attribute_group *group; | ||
1167 | struct nct6683_data *data; | ||
1168 | struct device *hwmon_dev; | ||
1169 | struct resource *res; | ||
1170 | int groups = 0; | ||
1171 | |||
1172 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
1173 | if (!devm_request_region(dev, res->start, IOREGION_LENGTH, DRVNAME)) | ||
1174 | return -EBUSY; | ||
1175 | |||
1176 | data = devm_kzalloc(dev, sizeof(struct nct6683_data), GFP_KERNEL); | ||
1177 | if (!data) | ||
1178 | return -ENOMEM; | ||
1179 | |||
1180 | data->kind = sio_data->kind; | ||
1181 | data->sioreg = sio_data->sioreg; | ||
1182 | data->addr = res->start; | ||
1183 | mutex_init(&data->update_lock); | ||
1184 | platform_set_drvdata(pdev, data); | ||
1185 | |||
1186 | data->customer_id = nct6683_read16(data, NCT6683_REG_CUSTOMER_ID); | ||
1187 | |||
1188 | nct6683_init_device(data); | ||
1189 | nct6683_setup_fans(data); | ||
1190 | nct6683_setup_sensors(data); | ||
1191 | |||
1192 | /* Register sysfs hooks */ | ||
1193 | |||
1194 | if (data->have_pwm) { | ||
1195 | group = nct6683_create_attr_group(dev, | ||
1196 | &nct6683_pwm_template_group, | ||
1197 | fls(data->have_pwm)); | ||
1198 | if (IS_ERR(group)) | ||
1199 | return PTR_ERR(group); | ||
1200 | data->groups[groups++] = group; | ||
1201 | } | ||
1202 | |||
1203 | if (data->in_num) { | ||
1204 | group = nct6683_create_attr_group(dev, | ||
1205 | &nct6683_in_template_group, | ||
1206 | data->in_num); | ||
1207 | if (IS_ERR(group)) | ||
1208 | return PTR_ERR(group); | ||
1209 | data->groups[groups++] = group; | ||
1210 | } | ||
1211 | |||
1212 | if (data->have_fan) { | ||
1213 | group = nct6683_create_attr_group(dev, | ||
1214 | &nct6683_fan_template_group, | ||
1215 | fls(data->have_fan)); | ||
1216 | if (IS_ERR(group)) | ||
1217 | return PTR_ERR(group); | ||
1218 | data->groups[groups++] = group; | ||
1219 | } | ||
1220 | |||
1221 | if (data->temp_num) { | ||
1222 | group = nct6683_create_attr_group(dev, | ||
1223 | &nct6683_temp_template_group, | ||
1224 | data->temp_num); | ||
1225 | if (IS_ERR(group)) | ||
1226 | return PTR_ERR(group); | ||
1227 | data->groups[groups++] = group; | ||
1228 | } | ||
1229 | data->groups[groups++] = &nct6683_group_other; | ||
1230 | |||
1231 | dev_info(dev, "%s EC firmware version %d.%d build %02x/%02x/%02x\n", | ||
1232 | nct6683_chip_names[data->kind], | ||
1233 | nct6683_read(data, NCT6683_REG_VERSION_HI), | ||
1234 | nct6683_read(data, NCT6683_REG_VERSION_LO), | ||
1235 | nct6683_read(data, NCT6683_REG_BUILD_MONTH), | ||
1236 | nct6683_read(data, NCT6683_REG_BUILD_DAY), | ||
1237 | nct6683_read(data, NCT6683_REG_BUILD_YEAR)); | ||
1238 | |||
1239 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, | ||
1240 | nct6683_device_names[data->kind], data, data->groups); | ||
1241 | return PTR_ERR_OR_ZERO(hwmon_dev); | ||
1242 | } | ||
1243 | |||
1244 | #ifdef CONFIG_PM | ||
1245 | static int nct6683_suspend(struct device *dev) | ||
1246 | { | ||
1247 | struct nct6683_data *data = nct6683_update_device(dev); | ||
1248 | |||
1249 | mutex_lock(&data->update_lock); | ||
1250 | data->hwm_cfg = nct6683_read(data, NCT6683_HWM_CFG); | ||
1251 | mutex_unlock(&data->update_lock); | ||
1252 | |||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | static int nct6683_resume(struct device *dev) | ||
1257 | { | ||
1258 | struct nct6683_data *data = dev_get_drvdata(dev); | ||
1259 | |||
1260 | mutex_lock(&data->update_lock); | ||
1261 | |||
1262 | nct6683_write(data, NCT6683_HWM_CFG, data->hwm_cfg); | ||
1263 | |||
1264 | /* Force re-reading all values */ | ||
1265 | data->valid = false; | ||
1266 | mutex_unlock(&data->update_lock); | ||
1267 | |||
1268 | return 0; | ||
1269 | } | ||
1270 | |||
1271 | static const struct dev_pm_ops nct6683_dev_pm_ops = { | ||
1272 | .suspend = nct6683_suspend, | ||
1273 | .resume = nct6683_resume, | ||
1274 | .freeze = nct6683_suspend, | ||
1275 | .restore = nct6683_resume, | ||
1276 | }; | ||
1277 | |||
1278 | #define NCT6683_DEV_PM_OPS (&nct6683_dev_pm_ops) | ||
1279 | #else | ||
1280 | #define NCT6683_DEV_PM_OPS NULL | ||
1281 | #endif /* CONFIG_PM */ | ||
1282 | |||
1283 | static struct platform_driver nct6683_driver = { | ||
1284 | .driver = { | ||
1285 | .owner = THIS_MODULE, | ||
1286 | .name = DRVNAME, | ||
1287 | .pm = NCT6683_DEV_PM_OPS, | ||
1288 | }, | ||
1289 | .probe = nct6683_probe, | ||
1290 | }; | ||
1291 | |||
1292 | static int __init nct6683_find(int sioaddr, struct nct6683_sio_data *sio_data) | ||
1293 | { | ||
1294 | const char *board_vendor; | ||
1295 | int addr; | ||
1296 | u16 val; | ||
1297 | int err; | ||
1298 | |||
1299 | /* | ||
1300 | * Only run on Intel boards unless the 'force' module parameter is set | ||
1301 | */ | ||
1302 | if (!force) { | ||
1303 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | ||
1304 | if (!board_vendor || strcmp(board_vendor, "Intel Corporation")) | ||
1305 | return -ENODEV; | ||
1306 | } | ||
1307 | |||
1308 | err = superio_enter(sioaddr); | ||
1309 | if (err) | ||
1310 | return err; | ||
1311 | |||
1312 | val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | ||
1313 | | superio_inb(sioaddr, SIO_REG_DEVID + 1); | ||
1314 | |||
1315 | switch (val & SIO_ID_MASK) { | ||
1316 | case SIO_NCT6683_ID: | ||
1317 | sio_data->kind = nct6683; | ||
1318 | break; | ||
1319 | default: | ||
1320 | if (val != 0xffff) | ||
1321 | pr_debug("unsupported chip ID: 0x%04x\n", val); | ||
1322 | goto fail; | ||
1323 | } | ||
1324 | |||
1325 | /* We have a known chip, find the HWM I/O address */ | ||
1326 | superio_select(sioaddr, NCT6683_LD_HWM); | ||
1327 | val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8) | ||
1328 | | superio_inb(sioaddr, SIO_REG_ADDR + 1); | ||
1329 | addr = val & IOREGION_ALIGNMENT; | ||
1330 | if (addr == 0) { | ||
1331 | pr_err("EC base I/O port unconfigured\n"); | ||
1332 | goto fail; | ||
1333 | } | ||
1334 | |||
1335 | /* Activate logical device if needed */ | ||
1336 | val = superio_inb(sioaddr, SIO_REG_ENABLE); | ||
1337 | if (!(val & 0x01)) { | ||
1338 | pr_err("EC is disabled\n"); | ||
1339 | goto fail; | ||
1340 | } | ||
1341 | |||
1342 | superio_exit(sioaddr); | ||
1343 | pr_info("Found %s or compatible chip at %#x:%#x\n", | ||
1344 | nct6683_chip_names[sio_data->kind], sioaddr, addr); | ||
1345 | sio_data->sioreg = sioaddr; | ||
1346 | |||
1347 | return addr; | ||
1348 | |||
1349 | fail: | ||
1350 | superio_exit(sioaddr); | ||
1351 | return -ENODEV; | ||
1352 | } | ||
1353 | |||
1354 | /* | ||
1355 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
1356 | * bus will manage the lifetime of the device and this module will only keep | ||
1357 | * track of the nct6683 driver. But since we use platform_device_alloc(), we | ||
1358 | * must keep track of the device | ||
1359 | */ | ||
1360 | static struct platform_device *pdev[2]; | ||
1361 | |||
1362 | static int __init sensors_nct6683_init(void) | ||
1363 | { | ||
1364 | struct nct6683_sio_data sio_data; | ||
1365 | int sioaddr[2] = { 0x2e, 0x4e }; | ||
1366 | struct resource res; | ||
1367 | bool found = false; | ||
1368 | int address; | ||
1369 | int i, err; | ||
1370 | |||
1371 | err = platform_driver_register(&nct6683_driver); | ||
1372 | if (err) | ||
1373 | return err; | ||
1374 | |||
1375 | /* | ||
1376 | * initialize sio_data->kind and sio_data->sioreg. | ||
1377 | * | ||
1378 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
1379 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a | ||
1380 | * nct6683 hardware monitor, and call probe() | ||
1381 | */ | ||
1382 | for (i = 0; i < ARRAY_SIZE(pdev); i++) { | ||
1383 | address = nct6683_find(sioaddr[i], &sio_data); | ||
1384 | if (address <= 0) | ||
1385 | continue; | ||
1386 | |||
1387 | found = true; | ||
1388 | |||
1389 | pdev[i] = platform_device_alloc(DRVNAME, address); | ||
1390 | if (!pdev[i]) { | ||
1391 | err = -ENOMEM; | ||
1392 | goto exit_device_unregister; | ||
1393 | } | ||
1394 | |||
1395 | err = platform_device_add_data(pdev[i], &sio_data, | ||
1396 | sizeof(struct nct6683_sio_data)); | ||
1397 | if (err) | ||
1398 | goto exit_device_put; | ||
1399 | |||
1400 | memset(&res, 0, sizeof(res)); | ||
1401 | res.name = DRVNAME; | ||
1402 | res.start = address + IOREGION_OFFSET; | ||
1403 | res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; | ||
1404 | res.flags = IORESOURCE_IO; | ||
1405 | |||
1406 | err = acpi_check_resource_conflict(&res); | ||
1407 | if (err) { | ||
1408 | platform_device_put(pdev[i]); | ||
1409 | pdev[i] = NULL; | ||
1410 | continue; | ||
1411 | } | ||
1412 | |||
1413 | err = platform_device_add_resources(pdev[i], &res, 1); | ||
1414 | if (err) | ||
1415 | goto exit_device_put; | ||
1416 | |||
1417 | /* platform_device_add calls probe() */ | ||
1418 | err = platform_device_add(pdev[i]); | ||
1419 | if (err) | ||
1420 | goto exit_device_put; | ||
1421 | } | ||
1422 | if (!found) { | ||
1423 | err = -ENODEV; | ||
1424 | goto exit_unregister; | ||
1425 | } | ||
1426 | |||
1427 | return 0; | ||
1428 | |||
1429 | exit_device_put: | ||
1430 | platform_device_put(pdev[i]); | ||
1431 | exit_device_unregister: | ||
1432 | while (--i >= 0) { | ||
1433 | if (pdev[i]) | ||
1434 | platform_device_unregister(pdev[i]); | ||
1435 | } | ||
1436 | exit_unregister: | ||
1437 | platform_driver_unregister(&nct6683_driver); | ||
1438 | return err; | ||
1439 | } | ||
1440 | |||
1441 | static void __exit sensors_nct6683_exit(void) | ||
1442 | { | ||
1443 | int i; | ||
1444 | |||
1445 | for (i = 0; i < ARRAY_SIZE(pdev); i++) { | ||
1446 | if (pdev[i]) | ||
1447 | platform_device_unregister(pdev[i]); | ||
1448 | } | ||
1449 | platform_driver_unregister(&nct6683_driver); | ||
1450 | } | ||
1451 | |||
1452 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); | ||
1453 | MODULE_DESCRIPTION("NCT6683D driver"); | ||
1454 | MODULE_LICENSE("GPL"); | ||
1455 | |||
1456 | module_init(sensors_nct6683_init); | ||
1457 | module_exit(sensors_nct6683_exit); | ||
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 38d5a6334053..59d9a3fc96b7 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -4160,7 +4160,7 @@ static int __init sensors_nct6775_init(void) | |||
4160 | pdev[i] = platform_device_alloc(DRVNAME, address); | 4160 | pdev[i] = platform_device_alloc(DRVNAME, address); |
4161 | if (!pdev[i]) { | 4161 | if (!pdev[i]) { |
4162 | err = -ENOMEM; | 4162 | err = -ENOMEM; |
4163 | goto exit_device_put; | 4163 | goto exit_device_unregister; |
4164 | } | 4164 | } |
4165 | 4165 | ||
4166 | err = platform_device_add_data(pdev[i], &sio_data, | 4166 | err = platform_device_add_data(pdev[i], &sio_data, |
@@ -4198,9 +4198,11 @@ static int __init sensors_nct6775_init(void) | |||
4198 | return 0; | 4198 | return 0; |
4199 | 4199 | ||
4200 | exit_device_put: | 4200 | exit_device_put: |
4201 | for (i = 0; i < ARRAY_SIZE(pdev); i++) { | 4201 | platform_device_put(pdev[i]); |
4202 | exit_device_unregister: | ||
4203 | while (--i >= 0) { | ||
4202 | if (pdev[i]) | 4204 | if (pdev[i]) |
4203 | platform_device_put(pdev[i]); | 4205 | platform_device_unregister(pdev[i]); |
4204 | } | 4206 | } |
4205 | exit_unregister: | 4207 | exit_unregister: |
4206 | platform_driver_unregister(&nct6775_driver); | 4208 | platform_driver_unregister(&nct6775_driver); |
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index d847e0a084e0..9e4684e747ea 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c | |||
@@ -1081,10 +1081,8 @@ static int pc87427_probe(struct platform_device *pdev) | |||
1081 | 1081 | ||
1082 | data = devm_kzalloc(&pdev->dev, sizeof(struct pc87427_data), | 1082 | data = devm_kzalloc(&pdev->dev, sizeof(struct pc87427_data), |
1083 | GFP_KERNEL); | 1083 | GFP_KERNEL); |
1084 | if (!data) { | 1084 | if (!data) |
1085 | pr_err("Out of memory\n"); | ||
1086 | return -ENOMEM; | 1085 | return -ENOMEM; |
1087 | } | ||
1088 | 1086 | ||
1089 | data->address[0] = sio_data->address[0]; | 1087 | data->address[0] = sio_data->address[0]; |
1090 | data->address[1] = sio_data->address[1]; | 1088 | data->address[1] = sio_data->address[1]; |
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index 73bd64e8c30a..0674c13bbd4b 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c | |||
@@ -285,10 +285,8 @@ static int s3c_hwmon_probe(struct platform_device *dev) | |||
285 | } | 285 | } |
286 | 286 | ||
287 | hwmon = devm_kzalloc(&dev->dev, sizeof(struct s3c_hwmon), GFP_KERNEL); | 287 | hwmon = devm_kzalloc(&dev->dev, sizeof(struct s3c_hwmon), GFP_KERNEL); |
288 | if (hwmon == NULL) { | 288 | if (hwmon == NULL) |
289 | dev_err(&dev->dev, "no memory\n"); | ||
290 | return -ENOMEM; | 289 | return -ENOMEM; |
291 | } | ||
292 | 290 | ||
293 | platform_set_drvdata(dev, hwmon); | 291 | platform_set_drvdata(dev, hwmon); |
294 | 292 | ||
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 6748b4583e7b..51719956cc03 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #define TMP102_THIGH_REG 0x03 | 51 | #define TMP102_THIGH_REG 0x03 |
52 | 52 | ||
53 | struct tmp102 { | 53 | struct tmp102 { |
54 | struct i2c_client *client; | ||
54 | struct device *hwmon_dev; | 55 | struct device *hwmon_dev; |
55 | struct thermal_zone_device *tz; | 56 | struct thermal_zone_device *tz; |
56 | struct mutex lock; | 57 | struct mutex lock; |
@@ -77,9 +78,10 @@ static const u8 tmp102_reg[] = { | |||
77 | TMP102_THIGH_REG, | 78 | TMP102_THIGH_REG, |
78 | }; | 79 | }; |
79 | 80 | ||
80 | static struct tmp102 *tmp102_update_device(struct i2c_client *client) | 81 | static struct tmp102 *tmp102_update_device(struct device *dev) |
81 | { | 82 | { |
82 | struct tmp102 *tmp102 = i2c_get_clientdata(client); | 83 | struct tmp102 *tmp102 = dev_get_drvdata(dev); |
84 | struct i2c_client *client = tmp102->client; | ||
83 | 85 | ||
84 | mutex_lock(&tmp102->lock); | 86 | mutex_lock(&tmp102->lock); |
85 | if (time_after(jiffies, tmp102->last_update + HZ / 3)) { | 87 | if (time_after(jiffies, tmp102->last_update + HZ / 3)) { |
@@ -98,7 +100,7 @@ static struct tmp102 *tmp102_update_device(struct i2c_client *client) | |||
98 | 100 | ||
99 | static int tmp102_read_temp(void *dev, long *temp) | 101 | static int tmp102_read_temp(void *dev, long *temp) |
100 | { | 102 | { |
101 | struct tmp102 *tmp102 = tmp102_update_device(to_i2c_client(dev)); | 103 | struct tmp102 *tmp102 = tmp102_update_device(dev); |
102 | 104 | ||
103 | *temp = tmp102->temp[0]; | 105 | *temp = tmp102->temp[0]; |
104 | 106 | ||
@@ -110,7 +112,7 @@ static ssize_t tmp102_show_temp(struct device *dev, | |||
110 | char *buf) | 112 | char *buf) |
111 | { | 113 | { |
112 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | 114 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); |
113 | struct tmp102 *tmp102 = tmp102_update_device(to_i2c_client(dev)); | 115 | struct tmp102 *tmp102 = tmp102_update_device(dev); |
114 | 116 | ||
115 | return sprintf(buf, "%d\n", tmp102->temp[sda->index]); | 117 | return sprintf(buf, "%d\n", tmp102->temp[sda->index]); |
116 | } | 118 | } |
@@ -120,8 +122,8 @@ static ssize_t tmp102_set_temp(struct device *dev, | |||
120 | const char *buf, size_t count) | 122 | const char *buf, size_t count) |
121 | { | 123 | { |
122 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); | 124 | struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); |
123 | struct i2c_client *client = to_i2c_client(dev); | 125 | struct tmp102 *tmp102 = dev_get_drvdata(dev); |
124 | struct tmp102 *tmp102 = i2c_get_clientdata(client); | 126 | struct i2c_client *client = tmp102->client; |
125 | long val; | 127 | long val; |
126 | int status; | 128 | int status; |
127 | 129 | ||
@@ -145,16 +147,13 @@ static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, tmp102_show_temp, | |||
145 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp102_show_temp, | 147 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp102_show_temp, |
146 | tmp102_set_temp, 2); | 148 | tmp102_set_temp, 2); |
147 | 149 | ||
148 | static struct attribute *tmp102_attributes[] = { | 150 | static struct attribute *tmp102_attrs[] = { |
149 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 151 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
150 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | 152 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
151 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 153 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
152 | NULL | 154 | NULL |
153 | }; | 155 | }; |
154 | 156 | ATTRIBUTE_GROUPS(tmp102); | |
155 | static const struct attribute_group tmp102_attr_group = { | ||
156 | .attrs = tmp102_attributes, | ||
157 | }; | ||
158 | 157 | ||
159 | #define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) | 158 | #define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) |
160 | #define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) | 159 | #define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) |
@@ -162,72 +161,68 @@ static const struct attribute_group tmp102_attr_group = { | |||
162 | static int tmp102_probe(struct i2c_client *client, | 161 | static int tmp102_probe(struct i2c_client *client, |
163 | const struct i2c_device_id *id) | 162 | const struct i2c_device_id *id) |
164 | { | 163 | { |
164 | struct device *dev = &client->dev; | ||
165 | struct device *hwmon_dev; | ||
165 | struct tmp102 *tmp102; | 166 | struct tmp102 *tmp102; |
166 | int status; | 167 | int status; |
167 | 168 | ||
168 | if (!i2c_check_functionality(client->adapter, | 169 | if (!i2c_check_functionality(client->adapter, |
169 | I2C_FUNC_SMBUS_WORD_DATA)) { | 170 | I2C_FUNC_SMBUS_WORD_DATA)) { |
170 | dev_err(&client->dev, | 171 | dev_err(dev, |
171 | "adapter doesn't support SMBus word transactions\n"); | 172 | "adapter doesn't support SMBus word transactions\n"); |
172 | return -ENODEV; | 173 | return -ENODEV; |
173 | } | 174 | } |
174 | 175 | ||
175 | tmp102 = devm_kzalloc(&client->dev, sizeof(*tmp102), GFP_KERNEL); | 176 | tmp102 = devm_kzalloc(dev, sizeof(*tmp102), GFP_KERNEL); |
176 | if (!tmp102) | 177 | if (!tmp102) |
177 | return -ENOMEM; | 178 | return -ENOMEM; |
178 | 179 | ||
179 | i2c_set_clientdata(client, tmp102); | 180 | i2c_set_clientdata(client, tmp102); |
181 | tmp102->client = client; | ||
180 | 182 | ||
181 | status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); | 183 | status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); |
182 | if (status < 0) { | 184 | if (status < 0) { |
183 | dev_err(&client->dev, "error reading config register\n"); | 185 | dev_err(dev, "error reading config register\n"); |
184 | return status; | 186 | return status; |
185 | } | 187 | } |
186 | tmp102->config_orig = status; | 188 | tmp102->config_orig = status; |
187 | status = i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, | 189 | status = i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, |
188 | TMP102_CONFIG); | 190 | TMP102_CONFIG); |
189 | if (status < 0) { | 191 | if (status < 0) { |
190 | dev_err(&client->dev, "error writing config register\n"); | 192 | dev_err(dev, "error writing config register\n"); |
191 | goto fail_restore_config; | 193 | goto fail_restore_config; |
192 | } | 194 | } |
193 | status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); | 195 | status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); |
194 | if (status < 0) { | 196 | if (status < 0) { |
195 | dev_err(&client->dev, "error reading config register\n"); | 197 | dev_err(dev, "error reading config register\n"); |
196 | goto fail_restore_config; | 198 | goto fail_restore_config; |
197 | } | 199 | } |
198 | status &= ~TMP102_CONFIG_RD_ONLY; | 200 | status &= ~TMP102_CONFIG_RD_ONLY; |
199 | if (status != TMP102_CONFIG) { | 201 | if (status != TMP102_CONFIG) { |
200 | dev_err(&client->dev, "config settings did not stick\n"); | 202 | dev_err(dev, "config settings did not stick\n"); |
201 | status = -ENODEV; | 203 | status = -ENODEV; |
202 | goto fail_restore_config; | 204 | goto fail_restore_config; |
203 | } | 205 | } |
204 | tmp102->last_update = jiffies - HZ; | 206 | tmp102->last_update = jiffies - HZ; |
205 | mutex_init(&tmp102->lock); | 207 | mutex_init(&tmp102->lock); |
206 | 208 | ||
207 | status = sysfs_create_group(&client->dev.kobj, &tmp102_attr_group); | 209 | hwmon_dev = hwmon_device_register_with_groups(dev, client->name, |
208 | if (status) { | 210 | tmp102, tmp102_groups); |
209 | dev_dbg(&client->dev, "could not create sysfs files\n"); | 211 | if (IS_ERR(hwmon_dev)) { |
212 | dev_dbg(dev, "unable to register hwmon device\n"); | ||
213 | status = PTR_ERR(hwmon_dev); | ||
210 | goto fail_restore_config; | 214 | goto fail_restore_config; |
211 | } | 215 | } |
212 | tmp102->hwmon_dev = hwmon_device_register(&client->dev); | 216 | tmp102->hwmon_dev = hwmon_dev; |
213 | if (IS_ERR(tmp102->hwmon_dev)) { | 217 | tmp102->tz = thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev, |
214 | dev_dbg(&client->dev, "unable to register hwmon device\n"); | ||
215 | status = PTR_ERR(tmp102->hwmon_dev); | ||
216 | goto fail_remove_sysfs; | ||
217 | } | ||
218 | |||
219 | tmp102->tz = thermal_zone_of_sensor_register(&client->dev, 0, | ||
220 | &client->dev, | ||
221 | tmp102_read_temp, NULL); | 218 | tmp102_read_temp, NULL); |
222 | if (IS_ERR(tmp102->tz)) | 219 | if (IS_ERR(tmp102->tz)) |
223 | tmp102->tz = NULL; | 220 | tmp102->tz = NULL; |
224 | 221 | ||
225 | dev_info(&client->dev, "initialized\n"); | 222 | dev_info(dev, "initialized\n"); |
226 | 223 | ||
227 | return 0; | 224 | return 0; |
228 | 225 | ||
229 | fail_remove_sysfs: | ||
230 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); | ||
231 | fail_restore_config: | 226 | fail_restore_config: |
232 | i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, | 227 | i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, |
233 | tmp102->config_orig); | 228 | tmp102->config_orig); |
@@ -238,9 +233,8 @@ static int tmp102_remove(struct i2c_client *client) | |||
238 | { | 233 | { |
239 | struct tmp102 *tmp102 = i2c_get_clientdata(client); | 234 | struct tmp102 *tmp102 = i2c_get_clientdata(client); |
240 | 235 | ||
241 | thermal_zone_of_sensor_unregister(&client->dev, tmp102->tz); | 236 | thermal_zone_of_sensor_unregister(tmp102->hwmon_dev, tmp102->tz); |
242 | hwmon_device_unregister(tmp102->hwmon_dev); | 237 | hwmon_device_unregister(tmp102->hwmon_dev); |
243 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); | ||
244 | 238 | ||
245 | /* Stop monitoring if device was stopped originally */ | 239 | /* Stop monitoring if device was stopped originally */ |
246 | if (tmp102->config_orig & TMP102_CONF_SD) { | 240 | if (tmp102->config_orig & TMP102_CONF_SD) { |
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index ae26b06fa819..7bab7a9bedc6 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c | |||
@@ -69,7 +69,7 @@ static const struct i2c_device_id tmp421_id[] = { | |||
69 | MODULE_DEVICE_TABLE(i2c, tmp421_id); | 69 | MODULE_DEVICE_TABLE(i2c, tmp421_id); |
70 | 70 | ||
71 | struct tmp421_data { | 71 | struct tmp421_data { |
72 | struct device *hwmon_dev; | 72 | struct i2c_client *client; |
73 | struct mutex update_lock; | 73 | struct mutex update_lock; |
74 | char valid; | 74 | char valid; |
75 | unsigned long last_updated; | 75 | unsigned long last_updated; |
@@ -99,8 +99,8 @@ static int temp_from_u16(u16 reg) | |||
99 | 99 | ||
100 | static struct tmp421_data *tmp421_update_device(struct device *dev) | 100 | static struct tmp421_data *tmp421_update_device(struct device *dev) |
101 | { | 101 | { |
102 | struct i2c_client *client = to_i2c_client(dev); | 102 | struct tmp421_data *data = dev_get_drvdata(dev); |
103 | struct tmp421_data *data = i2c_get_clientdata(client); | 103 | struct i2c_client *client = data->client; |
104 | int i; | 104 | int i; |
105 | 105 | ||
106 | mutex_lock(&data->update_lock); | 106 | mutex_lock(&data->update_lock); |
@@ -198,6 +198,11 @@ static const struct attribute_group tmp421_group = { | |||
198 | .is_visible = tmp421_is_visible, | 198 | .is_visible = tmp421_is_visible, |
199 | }; | 199 | }; |
200 | 200 | ||
201 | static const struct attribute_group *tmp421_groups[] = { | ||
202 | &tmp421_group, | ||
203 | NULL | ||
204 | }; | ||
205 | |||
201 | static int tmp421_init_client(struct i2c_client *client) | 206 | static int tmp421_init_client(struct i2c_client *client) |
202 | { | 207 | { |
203 | int config, config_orig; | 208 | int config, config_orig; |
@@ -264,47 +269,26 @@ static int tmp421_detect(struct i2c_client *client, | |||
264 | static int tmp421_probe(struct i2c_client *client, | 269 | static int tmp421_probe(struct i2c_client *client, |
265 | const struct i2c_device_id *id) | 270 | const struct i2c_device_id *id) |
266 | { | 271 | { |
272 | struct device *dev = &client->dev; | ||
273 | struct device *hwmon_dev; | ||
267 | struct tmp421_data *data; | 274 | struct tmp421_data *data; |
268 | int err; | 275 | int err; |
269 | 276 | ||
270 | data = devm_kzalloc(&client->dev, sizeof(struct tmp421_data), | 277 | data = devm_kzalloc(dev, sizeof(struct tmp421_data), GFP_KERNEL); |
271 | GFP_KERNEL); | ||
272 | if (!data) | 278 | if (!data) |
273 | return -ENOMEM; | 279 | return -ENOMEM; |
274 | 280 | ||
275 | i2c_set_clientdata(client, data); | ||
276 | mutex_init(&data->update_lock); | 281 | mutex_init(&data->update_lock); |
277 | data->channels = id->driver_data; | 282 | data->channels = id->driver_data; |
283 | data->client = client; | ||
278 | 284 | ||
279 | err = tmp421_init_client(client); | 285 | err = tmp421_init_client(client); |
280 | if (err) | 286 | if (err) |
281 | return err; | 287 | return err; |
282 | 288 | ||
283 | err = sysfs_create_group(&client->dev.kobj, &tmp421_group); | 289 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, |
284 | if (err) | 290 | data, tmp421_groups); |
285 | return err; | 291 | return PTR_ERR_OR_ZERO(hwmon_dev); |
286 | |||
287 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
288 | if (IS_ERR(data->hwmon_dev)) { | ||
289 | err = PTR_ERR(data->hwmon_dev); | ||
290 | data->hwmon_dev = NULL; | ||
291 | goto exit_remove; | ||
292 | } | ||
293 | return 0; | ||
294 | |||
295 | exit_remove: | ||
296 | sysfs_remove_group(&client->dev.kobj, &tmp421_group); | ||
297 | return err; | ||
298 | } | ||
299 | |||
300 | static int tmp421_remove(struct i2c_client *client) | ||
301 | { | ||
302 | struct tmp421_data *data = i2c_get_clientdata(client); | ||
303 | |||
304 | hwmon_device_unregister(data->hwmon_dev); | ||
305 | sysfs_remove_group(&client->dev.kobj, &tmp421_group); | ||
306 | |||
307 | return 0; | ||
308 | } | 292 | } |
309 | 293 | ||
310 | static struct i2c_driver tmp421_driver = { | 294 | static struct i2c_driver tmp421_driver = { |
@@ -313,7 +297,6 @@ static struct i2c_driver tmp421_driver = { | |||
313 | .name = "tmp421", | 297 | .name = "tmp421", |
314 | }, | 298 | }, |
315 | .probe = tmp421_probe, | 299 | .probe = tmp421_probe, |
316 | .remove = tmp421_remove, | ||
317 | .id_table = tmp421_id, | 300 | .id_table = tmp421_id, |
318 | .detect = tmp421_detect, | 301 | .detect = tmp421_detect, |
319 | .address_list = normal_i2c, | 302 | .address_list = normal_i2c, |
diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index fb3e69341c1b..7d4658636064 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c | |||
@@ -252,7 +252,7 @@ static const struct attribute_group env_group = { | |||
252 | 252 | ||
253 | static int env_probe(struct platform_device *op) | 253 | static int env_probe(struct platform_device *op) |
254 | { | 254 | { |
255 | struct env *p = kzalloc(sizeof(*p), GFP_KERNEL); | 255 | struct env *p = devm_kzalloc(&op->dev, sizeof(*p), GFP_KERNEL); |
256 | int err = -ENOMEM; | 256 | int err = -ENOMEM; |
257 | 257 | ||
258 | if (!p) | 258 | if (!p) |
@@ -262,7 +262,7 @@ static int env_probe(struct platform_device *op) | |||
262 | 262 | ||
263 | p->regs = of_ioremap(&op->resource[0], 0, REG_SIZE, "pic16f747"); | 263 | p->regs = of_ioremap(&op->resource[0], 0, REG_SIZE, "pic16f747"); |
264 | if (!p->regs) | 264 | if (!p->regs) |
265 | goto out_free; | 265 | goto out; |
266 | 266 | ||
267 | err = sysfs_create_group(&op->dev.kobj, &env_group); | 267 | err = sysfs_create_group(&op->dev.kobj, &env_group); |
268 | if (err) | 268 | if (err) |
@@ -286,8 +286,6 @@ out_sysfs_remove_group: | |||
286 | out_iounmap: | 286 | out_iounmap: |
287 | of_iounmap(&op->resource[0], p->regs, REG_SIZE); | 287 | of_iounmap(&op->resource[0], p->regs, REG_SIZE); |
288 | 288 | ||
289 | out_free: | ||
290 | kfree(p); | ||
291 | goto out; | 289 | goto out; |
292 | } | 290 | } |
293 | 291 | ||
@@ -299,7 +297,6 @@ static int env_remove(struct platform_device *op) | |||
299 | sysfs_remove_group(&op->dev.kobj, &env_group); | 297 | sysfs_remove_group(&op->dev.kobj, &env_group); |
300 | hwmon_device_unregister(p->hwmon_dev); | 298 | hwmon_device_unregister(p->hwmon_dev); |
301 | of_iounmap(&op->resource[0], p->regs, REG_SIZE); | 299 | of_iounmap(&op->resource[0], p->regs, REG_SIZE); |
302 | kfree(p); | ||
303 | } | 300 | } |
304 | 301 | ||
305 | return 0; | 302 | return 0; |
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index 6b2f1a42b3ff..344b22ec2553 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c | |||
@@ -1152,10 +1152,8 @@ static int vt1211_probe(struct platform_device *pdev) | |||
1152 | int i, err; | 1152 | int i, err; |
1153 | 1153 | ||
1154 | data = devm_kzalloc(dev, sizeof(struct vt1211_data), GFP_KERNEL); | 1154 | data = devm_kzalloc(dev, sizeof(struct vt1211_data), GFP_KERNEL); |
1155 | if (!data) { | 1155 | if (!data) |
1156 | dev_err(dev, "Out of memory\n"); | ||
1157 | return -ENOMEM; | 1156 | return -ENOMEM; |
1158 | } | ||
1159 | 1157 | ||
1160 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1158 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1161 | if (!devm_request_region(dev, res->start, resource_size(res), | 1159 | if (!devm_request_region(dev, res->start, resource_size(res), |