diff options
Diffstat (limited to 'drivers/hwmon/adm9240.c')
-rw-r--r-- | drivers/hwmon/adm9240.c | 429 |
1 files changed, 212 insertions, 217 deletions
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index bc7faef162f7..11dc95f8a17e 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/module.h> | 45 | #include <linux/module.h> |
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/i2c.h> | 47 | #include <linux/i2c.h> |
48 | #include <linux/hwmon-sysfs.h> | ||
48 | #include <linux/hwmon.h> | 49 | #include <linux/hwmon.h> |
49 | #include <linux/hwmon-vid.h> | 50 | #include <linux/hwmon-vid.h> |
50 | #include <linux/err.h> | 51 | #include <linux/err.h> |
@@ -69,8 +70,7 @@ I2C_CLIENT_INSMOD_3(adm9240, ds1780, lm81); | |||
69 | #define ADM9240_REG_INT(nr) (0x41 + (nr)) | 70 | #define ADM9240_REG_INT(nr) (0x41 + (nr)) |
70 | #define ADM9240_REG_INT_MASK(nr) (0x43 + (nr)) | 71 | #define ADM9240_REG_INT_MASK(nr) (0x43 + (nr)) |
71 | #define ADM9240_REG_TEMP 0x27 | 72 | #define ADM9240_REG_TEMP 0x27 |
72 | #define ADM9240_REG_TEMP_HIGH 0x39 | 73 | #define ADM9240_REG_TEMP_MAX(nr) (0x39 + (nr)) /* 0, 1 = high, hyst */ |
73 | #define ADM9240_REG_TEMP_HYST 0x3a | ||
74 | #define ADM9240_REG_ANALOG_OUT 0x19 | 74 | #define ADM9240_REG_ANALOG_OUT 0x19 |
75 | #define ADM9240_REG_CHASSIS_CLEAR 0x46 | 75 | #define ADM9240_REG_CHASSIS_CLEAR 0x46 |
76 | #define ADM9240_REG_VID_FAN_DIV 0x47 | 76 | #define ADM9240_REG_VID_FAN_DIV 0x47 |
@@ -162,177 +162,155 @@ struct adm9240_data { | |||
162 | u8 fan_min[2]; /* rw fan1_min */ | 162 | u8 fan_min[2]; /* rw fan1_min */ |
163 | u8 fan_div[2]; /* rw fan1_div, read-only accessor */ | 163 | u8 fan_div[2]; /* rw fan1_div, read-only accessor */ |
164 | s16 temp; /* ro temp1_input, 9-bit sign-extended */ | 164 | s16 temp; /* ro temp1_input, 9-bit sign-extended */ |
165 | s8 temp_high; /* rw temp1_max */ | 165 | s8 temp_max[2]; /* rw 0 -> temp_max, 1 -> temp_max_hyst */ |
166 | s8 temp_hyst; /* rw temp1_max_hyst */ | ||
167 | u16 alarms; /* ro alarms */ | 166 | u16 alarms; /* ro alarms */ |
168 | u8 aout; /* rw aout_output */ | 167 | u8 aout; /* rw aout_output */ |
169 | u8 vid; /* ro vid */ | 168 | u8 vid; /* ro vid */ |
170 | u8 vrm; /* -- vrm set on startup, no accessor */ | 169 | u8 vrm; /* -- vrm set on startup, no accessor */ |
171 | }; | 170 | }; |
172 | 171 | ||
173 | /* i2c byte read/write interface */ | 172 | /*** sysfs accessors ***/ |
174 | static int adm9240_read_value(struct i2c_client *client, u8 reg) | 173 | |
174 | /* temperature */ | ||
175 | static ssize_t show_temp(struct device *dev, struct device_attribute *dummy, | ||
176 | char *buf) | ||
175 | { | 177 | { |
176 | return i2c_smbus_read_byte_data(client, reg); | 178 | struct adm9240_data *data = adm9240_update_device(dev); |
179 | return sprintf(buf, "%d\n", data->temp * 500); /* 9-bit value */ | ||
177 | } | 180 | } |
178 | 181 | ||
179 | static int adm9240_write_value(struct i2c_client *client, u8 reg, u8 value) | 182 | static ssize_t show_max(struct device *dev, struct device_attribute *devattr, |
183 | char *buf) | ||
180 | { | 184 | { |
181 | return i2c_smbus_write_byte_data(client, reg, value); | 185 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
186 | struct adm9240_data *data = adm9240_update_device(dev); | ||
187 | return sprintf(buf, "%d\n", data->temp_max[attr->index] * 1000); | ||
182 | } | 188 | } |
183 | 189 | ||
184 | /*** sysfs accessors ***/ | 190 | static ssize_t set_max(struct device *dev, struct device_attribute *devattr, |
191 | const char *buf, size_t count) | ||
192 | { | ||
193 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
194 | struct i2c_client *client = to_i2c_client(dev); | ||
195 | struct adm9240_data *data = i2c_get_clientdata(client); | ||
196 | long val = simple_strtol(buf, NULL, 10); | ||
197 | |||
198 | down(&data->update_lock); | ||
199 | data->temp_max[attr->index] = TEMP_TO_REG(val); | ||
200 | i2c_smbus_write_byte_data(client, ADM9240_REG_TEMP_MAX(attr->index), | ||
201 | data->temp_max[attr->index]); | ||
202 | up(&data->update_lock); | ||
203 | return count; | ||
204 | } | ||
185 | 205 | ||
186 | /* temperature */ | ||
187 | #define show_temp(value, scale) \ | ||
188 | static ssize_t show_##value(struct device *dev, \ | ||
189 | struct device_attribute *attr, \ | ||
190 | char *buf) \ | ||
191 | { \ | ||
192 | struct adm9240_data *data = adm9240_update_device(dev); \ | ||
193 | return sprintf(buf, "%d\n", data->value * scale); \ | ||
194 | } | ||
195 | show_temp(temp_high, 1000); | ||
196 | show_temp(temp_hyst, 1000); | ||
197 | show_temp(temp, 500); /* 0.5'C per bit */ | ||
198 | |||
199 | #define set_temp(value, reg) \ | ||
200 | static ssize_t set_##value(struct device *dev, \ | ||
201 | struct device_attribute *attr, \ | ||
202 | const char *buf, size_t count) \ | ||
203 | { \ | ||
204 | struct i2c_client *client = to_i2c_client(dev); \ | ||
205 | struct adm9240_data *data = adm9240_update_device(dev); \ | ||
206 | long temp = simple_strtoul(buf, NULL, 10); \ | ||
207 | \ | ||
208 | down(&data->update_lock); \ | ||
209 | data->value = TEMP_TO_REG(temp); \ | ||
210 | adm9240_write_value(client, reg, data->value); \ | ||
211 | up(&data->update_lock); \ | ||
212 | return count; \ | ||
213 | } | ||
214 | |||
215 | set_temp(temp_high, ADM9240_REG_TEMP_HIGH); | ||
216 | set_temp(temp_hyst, ADM9240_REG_TEMP_HYST); | ||
217 | |||
218 | static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | ||
219 | show_temp_high, set_temp_high); | ||
220 | static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, | ||
221 | show_temp_hyst, set_temp_hyst); | ||
222 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); | 206 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); |
207 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, | ||
208 | show_max, set_max, 0); | ||
209 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, | ||
210 | show_max, set_max, 1); | ||
223 | 211 | ||
224 | /* voltage */ | 212 | /* voltage */ |
225 | static ssize_t show_in(struct device *dev, char *buf, int nr) | 213 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, |
214 | char *buf) | ||
226 | { | 215 | { |
216 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
227 | struct adm9240_data *data = adm9240_update_device(dev); | 217 | struct adm9240_data *data = adm9240_update_device(dev); |
228 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr)); | 218 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index], |
219 | attr->index)); | ||
229 | } | 220 | } |
230 | 221 | ||
231 | static ssize_t show_in_min(struct device *dev, char *buf, int nr) | 222 | static ssize_t show_in_min(struct device *dev, |
223 | struct device_attribute *devattr, char *buf) | ||
232 | { | 224 | { |
225 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
233 | struct adm9240_data *data = adm9240_update_device(dev); | 226 | struct adm9240_data *data = adm9240_update_device(dev); |
234 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr)); | 227 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index], |
228 | attr->index)); | ||
235 | } | 229 | } |
236 | 230 | ||
237 | static ssize_t show_in_max(struct device *dev, char *buf, int nr) | 231 | static ssize_t show_in_max(struct device *dev, |
232 | struct device_attribute *devattr, char *buf) | ||
238 | { | 233 | { |
234 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
239 | struct adm9240_data *data = adm9240_update_device(dev); | 235 | struct adm9240_data *data = adm9240_update_device(dev); |
240 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr)); | 236 | return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index], |
237 | attr->index)); | ||
241 | } | 238 | } |
242 | 239 | ||
243 | static ssize_t set_in_min(struct device *dev, const char *buf, | 240 | static ssize_t set_in_min(struct device *dev, |
244 | size_t count, int nr) | 241 | struct device_attribute *devattr, |
242 | const char *buf, size_t count) | ||
245 | { | 243 | { |
244 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
246 | struct i2c_client *client = to_i2c_client(dev); | 245 | struct i2c_client *client = to_i2c_client(dev); |
247 | struct adm9240_data *data = i2c_get_clientdata(client); | 246 | struct adm9240_data *data = i2c_get_clientdata(client); |
248 | unsigned long val = simple_strtoul(buf, NULL, 10); | 247 | unsigned long val = simple_strtoul(buf, NULL, 10); |
249 | 248 | ||
250 | down(&data->update_lock); | 249 | down(&data->update_lock); |
251 | data->in_min[nr] = IN_TO_REG(val, nr); | 250 | data->in_min[attr->index] = IN_TO_REG(val, attr->index); |
252 | adm9240_write_value(client, ADM9240_REG_IN_MIN(nr), data->in_min[nr]); | 251 | i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(attr->index), |
252 | data->in_min[attr->index]); | ||
253 | up(&data->update_lock); | 253 | up(&data->update_lock); |
254 | return count; | 254 | return count; |
255 | } | 255 | } |
256 | 256 | ||
257 | static ssize_t set_in_max(struct device *dev, const char *buf, | 257 | static ssize_t set_in_max(struct device *dev, |
258 | size_t count, int nr) | 258 | struct device_attribute *devattr, |
259 | const char *buf, size_t count) | ||
259 | { | 260 | { |
261 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
260 | struct i2c_client *client = to_i2c_client(dev); | 262 | struct i2c_client *client = to_i2c_client(dev); |
261 | struct adm9240_data *data = i2c_get_clientdata(client); | 263 | struct adm9240_data *data = i2c_get_clientdata(client); |
262 | unsigned long val = simple_strtoul(buf, NULL, 10); | 264 | unsigned long val = simple_strtoul(buf, NULL, 10); |
263 | 265 | ||
264 | down(&data->update_lock); | 266 | down(&data->update_lock); |
265 | data->in_max[nr] = IN_TO_REG(val, nr); | 267 | data->in_max[attr->index] = IN_TO_REG(val, attr->index); |
266 | adm9240_write_value(client, ADM9240_REG_IN_MAX(nr), data->in_max[nr]); | 268 | i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(attr->index), |
269 | data->in_max[attr->index]); | ||
267 | up(&data->update_lock); | 270 | up(&data->update_lock); |
268 | return count; | 271 | return count; |
269 | } | 272 | } |
270 | 273 | ||
271 | #define show_in_offset(offset) \ | 274 | #define vin(nr) \ |
272 | static ssize_t show_in##offset(struct device *dev, \ | 275 | static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO, \ |
273 | struct device_attribute *attr, \ | 276 | show_in, NULL, nr); \ |
274 | char *buf) \ | 277 | static SENSOR_DEVICE_ATTR(in##nr##_min, S_IRUGO | S_IWUSR, \ |
275 | { \ | 278 | show_in_min, set_in_min, nr); \ |
276 | return show_in(dev, buf, offset); \ | 279 | static SENSOR_DEVICE_ATTR(in##nr##_max, S_IRUGO | S_IWUSR, \ |
277 | } \ | 280 | show_in_max, set_in_max, nr); |
278 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL); \ | 281 | |
279 | static ssize_t show_in##offset##_min(struct device *dev, \ | 282 | vin(0); |
280 | struct device_attribute *attr, \ | 283 | vin(1); |
281 | char *buf) \ | 284 | vin(2); |
282 | { \ | 285 | vin(3); |
283 | return show_in_min(dev, buf, offset); \ | 286 | vin(4); |
284 | } \ | 287 | vin(5); |
285 | static ssize_t show_in##offset##_max(struct device *dev, \ | ||
286 | struct device_attribute *attr, \ | ||
287 | char *buf) \ | ||
288 | { \ | ||
289 | return show_in_max(dev, buf, offset); \ | ||
290 | } \ | ||
291 | static ssize_t \ | ||
292 | set_in##offset##_min(struct device *dev, \ | ||
293 | struct device_attribute *attr, const char *buf, \ | ||
294 | size_t count) \ | ||
295 | { \ | ||
296 | return set_in_min(dev, buf, count, offset); \ | ||
297 | } \ | ||
298 | static ssize_t \ | ||
299 | set_in##offset##_max(struct device *dev, \ | ||
300 | struct device_attribute *attr, const char *buf, \ | ||
301 | size_t count) \ | ||
302 | { \ | ||
303 | return set_in_max(dev, buf, count, offset); \ | ||
304 | } \ | ||
305 | static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
306 | show_in##offset##_min, set_in##offset##_min); \ | ||
307 | static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
308 | show_in##offset##_max, set_in##offset##_max); | ||
309 | |||
310 | show_in_offset(0); | ||
311 | show_in_offset(1); | ||
312 | show_in_offset(2); | ||
313 | show_in_offset(3); | ||
314 | show_in_offset(4); | ||
315 | show_in_offset(5); | ||
316 | 288 | ||
317 | /* fans */ | 289 | /* fans */ |
318 | static ssize_t show_fan(struct device *dev, char *buf, int nr) | 290 | static ssize_t show_fan(struct device *dev, |
291 | struct device_attribute *devattr, char *buf) | ||
319 | { | 292 | { |
293 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
320 | struct adm9240_data *data = adm9240_update_device(dev); | 294 | struct adm9240_data *data = adm9240_update_device(dev); |
321 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], | 295 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index], |
322 | 1 << data->fan_div[nr])); | 296 | 1 << data->fan_div[attr->index])); |
323 | } | 297 | } |
324 | 298 | ||
325 | static ssize_t show_fan_min(struct device *dev, char *buf, int nr) | 299 | static ssize_t show_fan_min(struct device *dev, |
300 | struct device_attribute *devattr, char *buf) | ||
326 | { | 301 | { |
302 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
327 | struct adm9240_data *data = adm9240_update_device(dev); | 303 | struct adm9240_data *data = adm9240_update_device(dev); |
328 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], | 304 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[attr->index], |
329 | 1 << data->fan_div[nr])); | 305 | 1 << data->fan_div[attr->index])); |
330 | } | 306 | } |
331 | 307 | ||
332 | static ssize_t show_fan_div(struct device *dev, char *buf, int nr) | 308 | static ssize_t show_fan_div(struct device *dev, |
309 | struct device_attribute *devattr, char *buf) | ||
333 | { | 310 | { |
311 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
334 | struct adm9240_data *data = adm9240_update_device(dev); | 312 | struct adm9240_data *data = adm9240_update_device(dev); |
335 | return sprintf(buf, "%d\n", 1 << data->fan_div[nr]); | 313 | return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]); |
336 | } | 314 | } |
337 | 315 | ||
338 | /* write new fan div, callers must hold data->update_lock */ | 316 | /* write new fan div, callers must hold data->update_lock */ |
@@ -341,16 +319,16 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr, | |||
341 | { | 319 | { |
342 | u8 reg, old, shift = (nr + 2) * 2; | 320 | u8 reg, old, shift = (nr + 2) * 2; |
343 | 321 | ||
344 | reg = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV); | 322 | reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); |
345 | old = (reg >> shift) & 3; | 323 | old = (reg >> shift) & 3; |
346 | reg &= ~(3 << shift); | 324 | reg &= ~(3 << shift); |
347 | reg |= (fan_div << shift); | 325 | reg |= (fan_div << shift); |
348 | adm9240_write_value(client, ADM9240_REG_VID_FAN_DIV, reg); | 326 | i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg); |
349 | dev_dbg(&client->dev, "fan%d clock divider changed from %u " | 327 | dev_dbg(&client->dev, "fan%d clock divider changed from %u " |
350 | "to %u\n", nr + 1, 1 << old, 1 << fan_div); | 328 | "to %u\n", nr + 1, 1 << old, 1 << fan_div); |
351 | } | 329 | } |
352 | 330 | ||
353 | /* | 331 | /* |
354 | * set fan speed low limit: | 332 | * set fan speed low limit: |
355 | * | 333 | * |
356 | * - value is zero: disable fan speed low limit alarm | 334 | * - value is zero: disable fan speed low limit alarm |
@@ -361,12 +339,15 @@ static void adm9240_write_fan_div(struct i2c_client *client, int nr, | |||
361 | * - otherwise: select fan clock divider to suit fan speed low limit, | 339 | * - otherwise: select fan clock divider to suit fan speed low limit, |
362 | * measurement code may adjust registers to ensure fan speed reading | 340 | * measurement code may adjust registers to ensure fan speed reading |
363 | */ | 341 | */ |
364 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 342 | static ssize_t set_fan_min(struct device *dev, |
365 | size_t count, int nr) | 343 | struct device_attribute *devattr, |
344 | const char *buf, size_t count) | ||
366 | { | 345 | { |
346 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
367 | struct i2c_client *client = to_i2c_client(dev); | 347 | struct i2c_client *client = to_i2c_client(dev); |
368 | struct adm9240_data *data = i2c_get_clientdata(client); | 348 | struct adm9240_data *data = i2c_get_clientdata(client); |
369 | unsigned long val = simple_strtoul(buf, NULL, 10); | 349 | unsigned long val = simple_strtoul(buf, NULL, 10); |
350 | int nr = attr->index; | ||
370 | u8 new_div; | 351 | u8 new_div; |
371 | 352 | ||
372 | down(&data->update_lock); | 353 | down(&data->update_lock); |
@@ -406,50 +387,27 @@ static ssize_t set_fan_min(struct device *dev, const char *buf, | |||
406 | data->fan_div[nr] = new_div; | 387 | data->fan_div[nr] = new_div; |
407 | adm9240_write_fan_div(client, nr, new_div); | 388 | adm9240_write_fan_div(client, nr, new_div); |
408 | } | 389 | } |
409 | adm9240_write_value(client, ADM9240_REG_FAN_MIN(nr), | 390 | i2c_smbus_write_byte_data(client, ADM9240_REG_FAN_MIN(nr), |
410 | data->fan_min[nr]); | 391 | data->fan_min[nr]); |
411 | 392 | ||
412 | up(&data->update_lock); | 393 | up(&data->update_lock); |
413 | return count; | 394 | return count; |
414 | } | 395 | } |
415 | 396 | ||
416 | #define show_fan_offset(offset) \ | 397 | #define fan(nr) \ |
417 | static ssize_t show_fan_##offset (struct device *dev, \ | 398 | static SENSOR_DEVICE_ATTR(fan##nr##_input, S_IRUGO, \ |
418 | struct device_attribute *attr, \ | 399 | show_fan, NULL, nr - 1); \ |
419 | char *buf) \ | 400 | static SENSOR_DEVICE_ATTR(fan##nr##_div, S_IRUGO, \ |
420 | { \ | 401 | show_fan_div, NULL, nr - 1); \ |
421 | return show_fan(dev, buf, offset - 1); \ | 402 | static SENSOR_DEVICE_ATTR(fan##nr##_min, S_IRUGO | S_IWUSR, \ |
422 | } \ | 403 | show_fan_min, set_fan_min, nr - 1); |
423 | static ssize_t show_fan_##offset##_div (struct device *dev, \ | 404 | |
424 | struct device_attribute *attr, \ | 405 | fan(1); |
425 | char *buf) \ | 406 | fan(2); |
426 | { \ | ||
427 | return show_fan_div(dev, buf, offset - 1); \ | ||
428 | } \ | ||
429 | static ssize_t show_fan_##offset##_min (struct device *dev, \ | ||
430 | struct device_attribute *attr, \ | ||
431 | char *buf) \ | ||
432 | { \ | ||
433 | return show_fan_min(dev, buf, offset - 1); \ | ||
434 | } \ | ||
435 | static ssize_t set_fan_##offset##_min (struct device *dev, \ | ||
436 | struct device_attribute *attr, \ | ||
437 | const char *buf, size_t count) \ | ||
438 | { \ | ||
439 | return set_fan_min(dev, buf, count, offset - 1); \ | ||
440 | } \ | ||
441 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
442 | show_fan_##offset, NULL); \ | ||
443 | static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ | ||
444 | show_fan_##offset##_div, NULL); \ | ||
445 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
446 | show_fan_##offset##_min, set_fan_##offset##_min); | ||
447 | |||
448 | show_fan_offset(1); | ||
449 | show_fan_offset(2); | ||
450 | 407 | ||
451 | /* alarms */ | 408 | /* alarms */ |
452 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) | 409 | static ssize_t show_alarms(struct device *dev, |
410 | struct device_attribute *attr, char *buf) | ||
453 | { | 411 | { |
454 | struct adm9240_data *data = adm9240_update_device(dev); | 412 | struct adm9240_data *data = adm9240_update_device(dev); |
455 | return sprintf(buf, "%u\n", data->alarms); | 413 | return sprintf(buf, "%u\n", data->alarms); |
@@ -457,7 +415,8 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch | |||
457 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 415 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
458 | 416 | ||
459 | /* vid */ | 417 | /* vid */ |
460 | static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) | 418 | static ssize_t show_vid(struct device *dev, |
419 | struct device_attribute *attr, char *buf) | ||
461 | { | 420 | { |
462 | struct adm9240_data *data = adm9240_update_device(dev); | 421 | struct adm9240_data *data = adm9240_update_device(dev); |
463 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); | 422 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); |
@@ -465,13 +424,16 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char | |||
465 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | 424 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); |
466 | 425 | ||
467 | /* analog output */ | 426 | /* analog output */ |
468 | static ssize_t show_aout(struct device *dev, struct device_attribute *attr, char *buf) | 427 | static ssize_t show_aout(struct device *dev, |
428 | struct device_attribute *attr, char *buf) | ||
469 | { | 429 | { |
470 | struct adm9240_data *data = adm9240_update_device(dev); | 430 | struct adm9240_data *data = adm9240_update_device(dev); |
471 | return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout)); | 431 | return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout)); |
472 | } | 432 | } |
473 | 433 | ||
474 | static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 434 | static ssize_t set_aout(struct device *dev, |
435 | struct device_attribute *attr, | ||
436 | const char *buf, size_t count) | ||
475 | { | 437 | { |
476 | struct i2c_client *client = to_i2c_client(dev); | 438 | struct i2c_client *client = to_i2c_client(dev); |
477 | struct adm9240_data *data = i2c_get_clientdata(client); | 439 | struct adm9240_data *data = i2c_get_clientdata(client); |
@@ -479,20 +441,23 @@ static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const | |||
479 | 441 | ||
480 | down(&data->update_lock); | 442 | down(&data->update_lock); |
481 | data->aout = AOUT_TO_REG(val); | 443 | data->aout = AOUT_TO_REG(val); |
482 | adm9240_write_value(client, ADM9240_REG_ANALOG_OUT, data->aout); | 444 | i2c_smbus_write_byte_data(client, ADM9240_REG_ANALOG_OUT, data->aout); |
483 | up(&data->update_lock); | 445 | up(&data->update_lock); |
484 | return count; | 446 | return count; |
485 | } | 447 | } |
486 | static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); | 448 | static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout); |
487 | 449 | ||
488 | /* chassis_clear */ | 450 | /* chassis_clear */ |
489 | static ssize_t chassis_clear(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 451 | static ssize_t chassis_clear(struct device *dev, |
452 | struct device_attribute *attr, | ||
453 | const char *buf, size_t count) | ||
490 | { | 454 | { |
491 | struct i2c_client *client = to_i2c_client(dev); | 455 | struct i2c_client *client = to_i2c_client(dev); |
492 | unsigned long val = simple_strtol(buf, NULL, 10); | 456 | unsigned long val = simple_strtol(buf, NULL, 10); |
493 | 457 | ||
494 | if (val == 1) { | 458 | if (val == 1) { |
495 | adm9240_write_value(client, ADM9240_REG_CHASSIS_CLEAR, 0x80); | 459 | i2c_smbus_write_byte_data(client, |
460 | ADM9240_REG_CHASSIS_CLEAR, 0x80); | ||
496 | dev_dbg(&client->dev, "chassis intrusion latch cleared\n"); | 461 | dev_dbg(&client->dev, "chassis intrusion latch cleared\n"); |
497 | } | 462 | } |
498 | return count; | 463 | return count; |
@@ -513,11 +478,10 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
513 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 478 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
514 | goto exit; | 479 | goto exit; |
515 | 480 | ||
516 | if (!(data = kmalloc(sizeof(struct adm9240_data), GFP_KERNEL))) { | 481 | if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) { |
517 | err = -ENOMEM; | 482 | err = -ENOMEM; |
518 | goto exit; | 483 | goto exit; |
519 | } | 484 | } |
520 | memset(data, 0, sizeof(struct adm9240_data)); | ||
521 | 485 | ||
522 | new_client = &data->client; | 486 | new_client = &data->client; |
523 | i2c_set_clientdata(new_client, data); | 487 | i2c_set_clientdata(new_client, data); |
@@ -533,7 +497,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
533 | if (kind < 0) { | 497 | if (kind < 0) { |
534 | 498 | ||
535 | /* verify chip: reg address should match i2c address */ | 499 | /* verify chip: reg address should match i2c address */ |
536 | if (adm9240_read_value(new_client, ADM9240_REG_I2C_ADDR) | 500 | if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR) |
537 | != address) { | 501 | != address) { |
538 | dev_err(&adapter->dev, "detect fail: address match, " | 502 | dev_err(&adapter->dev, "detect fail: address match, " |
539 | "0x%02x\n", address); | 503 | "0x%02x\n", address); |
@@ -541,8 +505,8 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
541 | } | 505 | } |
542 | 506 | ||
543 | /* check known chip manufacturer */ | 507 | /* check known chip manufacturer */ |
544 | man_id = adm9240_read_value(new_client, ADM9240_REG_MAN_ID); | 508 | man_id = i2c_smbus_read_byte_data(new_client, |
545 | 509 | ADM9240_REG_MAN_ID); | |
546 | if (man_id == 0x23) { | 510 | if (man_id == 0x23) { |
547 | kind = adm9240; | 511 | kind = adm9240; |
548 | } else if (man_id == 0xda) { | 512 | } else if (man_id == 0xda) { |
@@ -556,7 +520,8 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
556 | } | 520 | } |
557 | 521 | ||
558 | /* successful detect, print chip info */ | 522 | /* successful detect, print chip info */ |
559 | die_rev = adm9240_read_value(new_client, ADM9240_REG_DIE_REV); | 523 | die_rev = i2c_smbus_read_byte_data(new_client, |
524 | ADM9240_REG_DIE_REV); | ||
560 | dev_info(&adapter->dev, "found %s revision %u\n", | 525 | dev_info(&adapter->dev, "found %s revision %u\n", |
561 | man_id == 0x23 ? "ADM9240" : | 526 | man_id == 0x23 ? "ADM9240" : |
562 | man_id == 0xda ? "DS1780" : "LM81", die_rev); | 527 | man_id == 0xda ? "DS1780" : "LM81", die_rev); |
@@ -588,33 +553,59 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
588 | goto exit_detach; | 553 | goto exit_detach; |
589 | } | 554 | } |
590 | 555 | ||
591 | device_create_file(&new_client->dev, &dev_attr_in0_input); | 556 | device_create_file(&new_client->dev, |
592 | device_create_file(&new_client->dev, &dev_attr_in0_min); | 557 | &sensor_dev_attr_in0_input.dev_attr); |
593 | device_create_file(&new_client->dev, &dev_attr_in0_max); | 558 | device_create_file(&new_client->dev, |
594 | device_create_file(&new_client->dev, &dev_attr_in1_input); | 559 | &sensor_dev_attr_in0_min.dev_attr); |
595 | device_create_file(&new_client->dev, &dev_attr_in1_min); | 560 | device_create_file(&new_client->dev, |
596 | device_create_file(&new_client->dev, &dev_attr_in1_max); | 561 | &sensor_dev_attr_in0_max.dev_attr); |
597 | device_create_file(&new_client->dev, &dev_attr_in2_input); | 562 | device_create_file(&new_client->dev, |
598 | device_create_file(&new_client->dev, &dev_attr_in2_min); | 563 | &sensor_dev_attr_in1_input.dev_attr); |
599 | device_create_file(&new_client->dev, &dev_attr_in2_max); | 564 | device_create_file(&new_client->dev, |
600 | device_create_file(&new_client->dev, &dev_attr_in3_input); | 565 | &sensor_dev_attr_in1_min.dev_attr); |
601 | device_create_file(&new_client->dev, &dev_attr_in3_min); | 566 | device_create_file(&new_client->dev, |
602 | device_create_file(&new_client->dev, &dev_attr_in3_max); | 567 | &sensor_dev_attr_in1_max.dev_attr); |
603 | device_create_file(&new_client->dev, &dev_attr_in4_input); | 568 | device_create_file(&new_client->dev, |
604 | device_create_file(&new_client->dev, &dev_attr_in4_min); | 569 | &sensor_dev_attr_in2_input.dev_attr); |
605 | device_create_file(&new_client->dev, &dev_attr_in4_max); | 570 | device_create_file(&new_client->dev, |
606 | device_create_file(&new_client->dev, &dev_attr_in5_input); | 571 | &sensor_dev_attr_in2_min.dev_attr); |
607 | device_create_file(&new_client->dev, &dev_attr_in5_min); | 572 | device_create_file(&new_client->dev, |
608 | device_create_file(&new_client->dev, &dev_attr_in5_max); | 573 | &sensor_dev_attr_in2_max.dev_attr); |
609 | device_create_file(&new_client->dev, &dev_attr_temp1_max); | 574 | device_create_file(&new_client->dev, |
610 | device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); | 575 | &sensor_dev_attr_in3_input.dev_attr); |
576 | device_create_file(&new_client->dev, | ||
577 | &sensor_dev_attr_in3_min.dev_attr); | ||
578 | device_create_file(&new_client->dev, | ||
579 | &sensor_dev_attr_in3_max.dev_attr); | ||
580 | device_create_file(&new_client->dev, | ||
581 | &sensor_dev_attr_in4_input.dev_attr); | ||
582 | device_create_file(&new_client->dev, | ||
583 | &sensor_dev_attr_in4_min.dev_attr); | ||
584 | device_create_file(&new_client->dev, | ||
585 | &sensor_dev_attr_in4_max.dev_attr); | ||
586 | device_create_file(&new_client->dev, | ||
587 | &sensor_dev_attr_in5_input.dev_attr); | ||
588 | device_create_file(&new_client->dev, | ||
589 | &sensor_dev_attr_in5_min.dev_attr); | ||
590 | device_create_file(&new_client->dev, | ||
591 | &sensor_dev_attr_in5_max.dev_attr); | ||
611 | device_create_file(&new_client->dev, &dev_attr_temp1_input); | 592 | device_create_file(&new_client->dev, &dev_attr_temp1_input); |
612 | device_create_file(&new_client->dev, &dev_attr_fan1_input); | 593 | device_create_file(&new_client->dev, |
613 | device_create_file(&new_client->dev, &dev_attr_fan1_div); | 594 | &sensor_dev_attr_temp1_max.dev_attr); |
614 | device_create_file(&new_client->dev, &dev_attr_fan1_min); | 595 | device_create_file(&new_client->dev, |
615 | device_create_file(&new_client->dev, &dev_attr_fan2_input); | 596 | &sensor_dev_attr_temp1_max_hyst.dev_attr); |
616 | device_create_file(&new_client->dev, &dev_attr_fan2_div); | 597 | device_create_file(&new_client->dev, |
617 | device_create_file(&new_client->dev, &dev_attr_fan2_min); | 598 | &sensor_dev_attr_fan1_input.dev_attr); |
599 | device_create_file(&new_client->dev, | ||
600 | &sensor_dev_attr_fan1_div.dev_attr); | ||
601 | device_create_file(&new_client->dev, | ||
602 | &sensor_dev_attr_fan1_min.dev_attr); | ||
603 | device_create_file(&new_client->dev, | ||
604 | &sensor_dev_attr_fan2_input.dev_attr); | ||
605 | device_create_file(&new_client->dev, | ||
606 | &sensor_dev_attr_fan2_div.dev_attr); | ||
607 | device_create_file(&new_client->dev, | ||
608 | &sensor_dev_attr_fan2_min.dev_attr); | ||
618 | device_create_file(&new_client->dev, &dev_attr_alarms); | 609 | device_create_file(&new_client->dev, &dev_attr_alarms); |
619 | device_create_file(&new_client->dev, &dev_attr_aout_output); | 610 | device_create_file(&new_client->dev, &dev_attr_aout_output); |
620 | device_create_file(&new_client->dev, &dev_attr_chassis_clear); | 611 | device_create_file(&new_client->dev, &dev_attr_chassis_clear); |
@@ -654,8 +645,8 @@ static int adm9240_detach_client(struct i2c_client *client) | |||
654 | static void adm9240_init_client(struct i2c_client *client) | 645 | static void adm9240_init_client(struct i2c_client *client) |
655 | { | 646 | { |
656 | struct adm9240_data *data = i2c_get_clientdata(client); | 647 | struct adm9240_data *data = i2c_get_clientdata(client); |
657 | u8 conf = adm9240_read_value(client, ADM9240_REG_CONFIG); | 648 | u8 conf = i2c_smbus_read_byte_data(client, ADM9240_REG_CONFIG); |
658 | u8 mode = adm9240_read_value(client, ADM9240_REG_TEMP_CONF) & 3; | 649 | u8 mode = i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP_CONF) & 3; |
659 | 650 | ||
660 | data->vrm = vid_which_vrm(); /* need this to report vid as mV */ | 651 | data->vrm = vid_which_vrm(); /* need this to report vid as mV */ |
661 | 652 | ||
@@ -672,18 +663,22 @@ static void adm9240_init_client(struct i2c_client *client) | |||
672 | 663 | ||
673 | for (i = 0; i < 6; i++) | 664 | for (i = 0; i < 6; i++) |
674 | { | 665 | { |
675 | adm9240_write_value(client, | 666 | i2c_smbus_write_byte_data(client, |
676 | ADM9240_REG_IN_MIN(i), 0); | 667 | ADM9240_REG_IN_MIN(i), 0); |
677 | adm9240_write_value(client, | 668 | i2c_smbus_write_byte_data(client, |
678 | ADM9240_REG_IN_MAX(i), 255); | 669 | ADM9240_REG_IN_MAX(i), 255); |
679 | } | 670 | } |
680 | adm9240_write_value(client, ADM9240_REG_FAN_MIN(0), 255); | 671 | i2c_smbus_write_byte_data(client, |
681 | adm9240_write_value(client, ADM9240_REG_FAN_MIN(1), 255); | 672 | ADM9240_REG_FAN_MIN(0), 255); |
682 | adm9240_write_value(client, ADM9240_REG_TEMP_HIGH, 127); | 673 | i2c_smbus_write_byte_data(client, |
683 | adm9240_write_value(client, ADM9240_REG_TEMP_HYST, 127); | 674 | ADM9240_REG_FAN_MIN(1), 255); |
675 | i2c_smbus_write_byte_data(client, | ||
676 | ADM9240_REG_TEMP_MAX(0), 127); | ||
677 | i2c_smbus_write_byte_data(client, | ||
678 | ADM9240_REG_TEMP_MAX(1), 127); | ||
684 | 679 | ||
685 | /* start measurement cycle */ | 680 | /* start measurement cycle */ |
686 | adm9240_write_value(client, ADM9240_REG_CONFIG, 1); | 681 | i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1); |
687 | 682 | ||
688 | dev_info(&client->dev, "cold start: config was 0x%02x " | 683 | dev_info(&client->dev, "cold start: config was 0x%02x " |
689 | "mode %u\n", conf, mode); | 684 | "mode %u\n", conf, mode); |
@@ -704,25 +699,25 @@ static struct adm9240_data *adm9240_update_device(struct device *dev) | |||
704 | 699 | ||
705 | for (i = 0; i < 6; i++) /* read voltages */ | 700 | for (i = 0; i < 6; i++) /* read voltages */ |
706 | { | 701 | { |
707 | data->in[i] = adm9240_read_value(client, | 702 | data->in[i] = i2c_smbus_read_byte_data(client, |
708 | ADM9240_REG_IN(i)); | 703 | ADM9240_REG_IN(i)); |
709 | } | 704 | } |
710 | data->alarms = adm9240_read_value(client, | 705 | data->alarms = i2c_smbus_read_byte_data(client, |
711 | ADM9240_REG_INT(0)) | | 706 | ADM9240_REG_INT(0)) | |
712 | adm9240_read_value(client, | 707 | i2c_smbus_read_byte_data(client, |
713 | ADM9240_REG_INT(1)) << 8; | 708 | ADM9240_REG_INT(1)) << 8; |
714 | 709 | ||
715 | /* read temperature: assume temperature changes less than | 710 | /* read temperature: assume temperature changes less than |
716 | * 0.5'C per two measurement cycles thus ignore possible | 711 | * 0.5'C per two measurement cycles thus ignore possible |
717 | * but unlikely aliasing error on lsb reading. --Grant */ | 712 | * but unlikely aliasing error on lsb reading. --Grant */ |
718 | data->temp = ((adm9240_read_value(client, | 713 | data->temp = ((i2c_smbus_read_byte_data(client, |
719 | ADM9240_REG_TEMP) << 8) | | 714 | ADM9240_REG_TEMP) << 8) | |
720 | adm9240_read_value(client, | 715 | i2c_smbus_read_byte_data(client, |
721 | ADM9240_REG_TEMP_CONF)) / 128; | 716 | ADM9240_REG_TEMP_CONF)) / 128; |
722 | 717 | ||
723 | for (i = 0; i < 2; i++) /* read fans */ | 718 | for (i = 0; i < 2; i++) /* read fans */ |
724 | { | 719 | { |
725 | data->fan[i] = adm9240_read_value(client, | 720 | data->fan[i] = i2c_smbus_read_byte_data(client, |
726 | ADM9240_REG_FAN(i)); | 721 | ADM9240_REG_FAN(i)); |
727 | 722 | ||
728 | /* adjust fan clock divider on overflow */ | 723 | /* adjust fan clock divider on overflow */ |
@@ -747,30 +742,30 @@ static struct adm9240_data *adm9240_update_device(struct device *dev) | |||
747 | 742 | ||
748 | for (i = 0; i < 6; i++) | 743 | for (i = 0; i < 6; i++) |
749 | { | 744 | { |
750 | data->in_min[i] = adm9240_read_value(client, | 745 | data->in_min[i] = i2c_smbus_read_byte_data(client, |
751 | ADM9240_REG_IN_MIN(i)); | 746 | ADM9240_REG_IN_MIN(i)); |
752 | data->in_max[i] = adm9240_read_value(client, | 747 | data->in_max[i] = i2c_smbus_read_byte_data(client, |
753 | ADM9240_REG_IN_MAX(i)); | 748 | ADM9240_REG_IN_MAX(i)); |
754 | } | 749 | } |
755 | for (i = 0; i < 2; i++) | 750 | for (i = 0; i < 2; i++) |
756 | { | 751 | { |
757 | data->fan_min[i] = adm9240_read_value(client, | 752 | data->fan_min[i] = i2c_smbus_read_byte_data(client, |
758 | ADM9240_REG_FAN_MIN(i)); | 753 | ADM9240_REG_FAN_MIN(i)); |
759 | } | 754 | } |
760 | data->temp_high = adm9240_read_value(client, | 755 | data->temp_max[0] = i2c_smbus_read_byte_data(client, |
761 | ADM9240_REG_TEMP_HIGH); | 756 | ADM9240_REG_TEMP_MAX(0)); |
762 | data->temp_hyst = adm9240_read_value(client, | 757 | data->temp_max[1] = i2c_smbus_read_byte_data(client, |
763 | ADM9240_REG_TEMP_HYST); | 758 | ADM9240_REG_TEMP_MAX(1)); |
764 | 759 | ||
765 | /* read fan divs and 5-bit VID */ | 760 | /* read fan divs and 5-bit VID */ |
766 | i = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV); | 761 | i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); |
767 | data->fan_div[0] = (i >> 4) & 3; | 762 | data->fan_div[0] = (i >> 4) & 3; |
768 | data->fan_div[1] = (i >> 6) & 3; | 763 | data->fan_div[1] = (i >> 6) & 3; |
769 | data->vid = i & 0x0f; | 764 | data->vid = i & 0x0f; |
770 | data->vid |= (adm9240_read_value(client, | 765 | data->vid |= (i2c_smbus_read_byte_data(client, |
771 | ADM9240_REG_VID4) & 1) << 4; | 766 | ADM9240_REG_VID4) & 1) << 4; |
772 | /* read analog out */ | 767 | /* read analog out */ |
773 | data->aout = adm9240_read_value(client, | 768 | data->aout = i2c_smbus_read_byte_data(client, |
774 | ADM9240_REG_ANALOG_OUT); | 769 | ADM9240_REG_ANALOG_OUT); |
775 | 770 | ||
776 | data->last_updated_config = jiffies; | 771 | data->last_updated_config = jiffies; |