diff options
Diffstat (limited to 'drivers/hwmon/pc87360.c')
-rw-r--r-- | drivers/hwmon/pc87360.c | 852 |
1 files changed, 436 insertions, 416 deletions
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index fa4032d53b79..cf2a35799c7c 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -38,23 +38,19 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/jiffies.h> | 39 | #include <linux/jiffies.h> |
40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
41 | #include <linux/i2c-sensor.h> | 41 | #include <linux/i2c-isa.h> |
42 | #include <linux/i2c-vid.h> | 42 | #include <linux/hwmon.h> |
43 | #include <linux/hwmon-sysfs.h> | ||
44 | #include <linux/hwmon-vid.h> | ||
45 | #include <linux/err.h> | ||
43 | #include <asm/io.h> | 46 | #include <asm/io.h> |
44 | 47 | ||
45 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
46 | static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END }; | ||
47 | static struct i2c_force_data forces[] = {{ NULL }}; | ||
48 | static u8 devid; | 48 | static u8 devid; |
49 | static unsigned int extra_isa[3]; | 49 | static unsigned short address; |
50 | static unsigned short extra_isa[3]; | ||
50 | static u8 confreg[4]; | 51 | static u8 confreg[4]; |
51 | 52 | ||
52 | enum chips { any_chip, pc87360, pc87363, pc87364, pc87365, pc87366 }; | 53 | enum chips { any_chip, pc87360, pc87363, pc87364, pc87365, pc87366 }; |
53 | static struct i2c_address_data addr_data = { | ||
54 | .normal_i2c = normal_i2c, | ||
55 | .normal_isa = normal_isa, | ||
56 | .forces = forces, | ||
57 | }; | ||
58 | 54 | ||
59 | static int init = 1; | 55 | static int init = 1; |
60 | module_param(init, int, 0); | 56 | module_param(init, int, 0); |
@@ -186,6 +182,7 @@ static inline u8 PWM_TO_REG(int val, int inv) | |||
186 | 182 | ||
187 | struct pc87360_data { | 183 | struct pc87360_data { |
188 | struct i2c_client client; | 184 | struct i2c_client client; |
185 | struct class_device *class_dev; | ||
189 | struct semaphore lock; | 186 | struct semaphore lock; |
190 | struct semaphore update_lock; | 187 | struct semaphore update_lock; |
191 | char valid; /* !=0 if following fields are valid */ | 188 | char valid; /* !=0 if following fields are valid */ |
@@ -224,8 +221,7 @@ struct pc87360_data { | |||
224 | * Functions declaration | 221 | * Functions declaration |
225 | */ | 222 | */ |
226 | 223 | ||
227 | static int pc87360_attach_adapter(struct i2c_adapter *adapter); | 224 | static int pc87360_detect(struct i2c_adapter *adapter); |
228 | static int pc87360_detect(struct i2c_adapter *adapter, int address, int kind); | ||
229 | static int pc87360_detach_client(struct i2c_client *client); | 225 | static int pc87360_detach_client(struct i2c_client *client); |
230 | 226 | ||
231 | static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, | 227 | static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, |
@@ -242,8 +238,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev); | |||
242 | static struct i2c_driver pc87360_driver = { | 238 | static struct i2c_driver pc87360_driver = { |
243 | .owner = THIS_MODULE, | 239 | .owner = THIS_MODULE, |
244 | .name = "pc87360", | 240 | .name = "pc87360", |
245 | .flags = I2C_DF_NOTIFY, | 241 | .attach_adapter = pc87360_detect, |
246 | .attach_adapter = pc87360_attach_adapter, | ||
247 | .detach_client = pc87360_detach_client, | 242 | .detach_client = pc87360_detach_client, |
248 | }; | 243 | }; |
249 | 244 | ||
@@ -251,168 +246,178 @@ static struct i2c_driver pc87360_driver = { | |||
251 | * Sysfs stuff | 246 | * Sysfs stuff |
252 | */ | 247 | */ |
253 | 248 | ||
254 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 249 | static ssize_t show_fan_input(struct device *dev, struct device_attribute *devattr, char *buf) |
255 | size_t count, int nr) | 250 | { |
251 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
252 | struct pc87360_data *data = pc87360_update_device(dev); | ||
253 | return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan[attr->index], | ||
254 | FAN_DIV_FROM_REG(data->fan_status[attr->index]))); | ||
255 | } | ||
256 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *devattr, char *buf) | ||
257 | { | ||
258 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
259 | struct pc87360_data *data = pc87360_update_device(dev); | ||
260 | return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan_min[attr->index], | ||
261 | FAN_DIV_FROM_REG(data->fan_status[attr->index]))); | ||
262 | } | ||
263 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf) | ||
264 | { | ||
265 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
266 | struct pc87360_data *data = pc87360_update_device(dev); | ||
267 | return sprintf(buf, "%u\n", | ||
268 | FAN_DIV_FROM_REG(data->fan_status[attr->index])); | ||
269 | } | ||
270 | static ssize_t show_fan_status(struct device *dev, struct device_attribute *devattr, char *buf) | ||
256 | { | 271 | { |
272 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
273 | struct pc87360_data *data = pc87360_update_device(dev); | ||
274 | return sprintf(buf, "%u\n", | ||
275 | FAN_STATUS_FROM_REG(data->fan_status[attr->index])); | ||
276 | } | ||
277 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
278 | size_t count) | ||
279 | { | ||
280 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
257 | struct i2c_client *client = to_i2c_client(dev); | 281 | struct i2c_client *client = to_i2c_client(dev); |
258 | struct pc87360_data *data = i2c_get_clientdata(client); | 282 | struct pc87360_data *data = i2c_get_clientdata(client); |
259 | long fan_min = simple_strtol(buf, NULL, 10); | 283 | long fan_min = simple_strtol(buf, NULL, 10); |
260 | 284 | ||
261 | down(&data->update_lock); | 285 | down(&data->update_lock); |
262 | fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[nr])); | 286 | fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[attr->index])); |
263 | 287 | ||
264 | /* If it wouldn't fit, change clock divisor */ | 288 | /* If it wouldn't fit, change clock divisor */ |
265 | while (fan_min > 255 | 289 | while (fan_min > 255 |
266 | && (data->fan_status[nr] & 0x60) != 0x60) { | 290 | && (data->fan_status[attr->index] & 0x60) != 0x60) { |
267 | fan_min >>= 1; | 291 | fan_min >>= 1; |
268 | data->fan[nr] >>= 1; | 292 | data->fan[attr->index] >>= 1; |
269 | data->fan_status[nr] += 0x20; | 293 | data->fan_status[attr->index] += 0x20; |
270 | } | 294 | } |
271 | data->fan_min[nr] = fan_min > 255 ? 255 : fan_min; | 295 | data->fan_min[attr->index] = fan_min > 255 ? 255 : fan_min; |
272 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_MIN(nr), | 296 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_MIN(attr->index), |
273 | data->fan_min[nr]); | 297 | data->fan_min[attr->index]); |
274 | 298 | ||
275 | /* Write new divider, preserve alarm bits */ | 299 | /* Write new divider, preserve alarm bits */ |
276 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(nr), | 300 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(attr->index), |
277 | data->fan_status[nr] & 0xF9); | 301 | data->fan_status[attr->index] & 0xF9); |
278 | up(&data->update_lock); | 302 | up(&data->update_lock); |
279 | 303 | ||
280 | return count; | 304 | return count; |
281 | } | 305 | } |
282 | 306 | ||
283 | #define show_and_set_fan(offset) \ | 307 | #define show_and_set_fan(offset) \ |
284 | static ssize_t show_fan##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \ | 308 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
285 | { \ | 309 | show_fan_input, NULL, offset-1); \ |
286 | struct pc87360_data *data = pc87360_update_device(dev); \ | 310 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IWUSR | S_IRUGO, \ |
287 | return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan[offset-1], \ | 311 | show_fan_min, set_fan_min, offset-1); \ |
288 | FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \ | 312 | static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ |
289 | } \ | 313 | show_fan_div, NULL, offset-1); \ |
290 | static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \ | 314 | static SENSOR_DEVICE_ATTR(fan##offset##_status, S_IRUGO, \ |
291 | { \ | 315 | show_fan_status, NULL, offset-1); |
292 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
293 | return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan_min[offset-1], \ | ||
294 | FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \ | ||
295 | } \ | ||
296 | static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
297 | { \ | ||
298 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
299 | return sprintf(buf, "%u\n", \ | ||
300 | FAN_DIV_FROM_REG(data->fan_status[offset-1])); \ | ||
301 | } \ | ||
302 | static ssize_t show_fan##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
303 | { \ | ||
304 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
305 | return sprintf(buf, "%u\n", \ | ||
306 | FAN_STATUS_FROM_REG(data->fan_status[offset-1])); \ | ||
307 | } \ | ||
308 | static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
309 | size_t count) \ | ||
310 | { \ | ||
311 | return set_fan_min(dev, buf, count, offset-1); \ | ||
312 | } \ | ||
313 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
314 | show_fan##offset##_input, NULL); \ | ||
315 | static DEVICE_ATTR(fan##offset##_min, S_IWUSR | S_IRUGO, \ | ||
316 | show_fan##offset##_min, set_fan##offset##_min); \ | ||
317 | static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ | ||
318 | show_fan##offset##_div, NULL); \ | ||
319 | static DEVICE_ATTR(fan##offset##_status, S_IRUGO, \ | ||
320 | show_fan##offset##_status, NULL); | ||
321 | show_and_set_fan(1) | 316 | show_and_set_fan(1) |
322 | show_and_set_fan(2) | 317 | show_and_set_fan(2) |
323 | show_and_set_fan(3) | 318 | show_and_set_fan(3) |
324 | 319 | ||
320 | static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf) | ||
321 | { | ||
322 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
323 | struct pc87360_data *data = pc87360_update_device(dev); | ||
324 | return sprintf(buf, "%u\n", | ||
325 | PWM_FROM_REG(data->pwm[attr->index], | ||
326 | FAN_CONFIG_INVERT(data->fan_conf, | ||
327 | attr->index))); | ||
328 | } | ||
329 | static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
330 | size_t count) | ||
331 | { | ||
332 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
333 | struct i2c_client *client = to_i2c_client(dev); | ||
334 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
335 | long val = simple_strtol(buf, NULL, 10); | ||
336 | |||
337 | down(&data->update_lock); | ||
338 | data->pwm[attr->index] = PWM_TO_REG(val, | ||
339 | FAN_CONFIG_INVERT(data->fan_conf, attr->index)); | ||
340 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(attr->index), | ||
341 | data->pwm[attr->index]); | ||
342 | up(&data->update_lock); | ||
343 | return count; | ||
344 | } | ||
345 | |||
325 | #define show_and_set_pwm(offset) \ | 346 | #define show_and_set_pwm(offset) \ |
326 | static ssize_t show_pwm##offset(struct device *dev, struct device_attribute *attr, char *buf) \ | 347 | static SENSOR_DEVICE_ATTR(pwm##offset, S_IWUSR | S_IRUGO, \ |
327 | { \ | 348 | show_pwm, set_pwm, offset-1); |
328 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
329 | return sprintf(buf, "%u\n", \ | ||
330 | PWM_FROM_REG(data->pwm[offset-1], \ | ||
331 | FAN_CONFIG_INVERT(data->fan_conf, \ | ||
332 | offset-1))); \ | ||
333 | } \ | ||
334 | static ssize_t set_pwm##offset(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
335 | size_t count) \ | ||
336 | { \ | ||
337 | struct i2c_client *client = to_i2c_client(dev); \ | ||
338 | struct pc87360_data *data = i2c_get_clientdata(client); \ | ||
339 | long val = simple_strtol(buf, NULL, 10); \ | ||
340 | \ | ||
341 | down(&data->update_lock); \ | ||
342 | data->pwm[offset-1] = PWM_TO_REG(val, \ | ||
343 | FAN_CONFIG_INVERT(data->fan_conf, offset-1)); \ | ||
344 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(offset-1), \ | ||
345 | data->pwm[offset-1]); \ | ||
346 | up(&data->update_lock); \ | ||
347 | return count; \ | ||
348 | } \ | ||
349 | static DEVICE_ATTR(pwm##offset, S_IWUSR | S_IRUGO, \ | ||
350 | show_pwm##offset, set_pwm##offset); | ||
351 | show_and_set_pwm(1) | 349 | show_and_set_pwm(1) |
352 | show_and_set_pwm(2) | 350 | show_and_set_pwm(2) |
353 | show_and_set_pwm(3) | 351 | show_and_set_pwm(3) |
354 | 352 | ||
353 | static ssize_t show_in_input(struct device *dev, struct device_attribute *devattr, char *buf) | ||
354 | { | ||
355 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
356 | struct pc87360_data *data = pc87360_update_device(dev); | ||
357 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in[attr->index], | ||
358 | data->in_vref)); | ||
359 | } | ||
360 | static ssize_t show_in_min(struct device *dev, struct device_attribute *devattr, char *buf) | ||
361 | { | ||
362 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
363 | struct pc87360_data *data = pc87360_update_device(dev); | ||
364 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[attr->index], | ||
365 | data->in_vref)); | ||
366 | } | ||
367 | static ssize_t show_in_max(struct device *dev, struct device_attribute *devattr, char *buf) | ||
368 | { | ||
369 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
370 | struct pc87360_data *data = pc87360_update_device(dev); | ||
371 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[attr->index], | ||
372 | data->in_vref)); | ||
373 | } | ||
374 | static ssize_t show_in_status(struct device *dev, struct device_attribute *devattr, char *buf) | ||
375 | { | ||
376 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
377 | struct pc87360_data *data = pc87360_update_device(dev); | ||
378 | return sprintf(buf, "%u\n", data->in_status[attr->index]); | ||
379 | } | ||
380 | static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
381 | size_t count) | ||
382 | { | ||
383 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
384 | struct i2c_client *client = to_i2c_client(dev); | ||
385 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
386 | long val = simple_strtol(buf, NULL, 10); | ||
387 | |||
388 | down(&data->update_lock); | ||
389 | data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); | ||
390 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MIN, | ||
391 | data->in_min[attr->index]); | ||
392 | up(&data->update_lock); | ||
393 | return count; | ||
394 | } | ||
395 | static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
396 | size_t count) | ||
397 | { | ||
398 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
399 | struct i2c_client *client = to_i2c_client(dev); | ||
400 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
401 | long val = simple_strtol(buf, NULL, 10); | ||
402 | |||
403 | down(&data->update_lock); | ||
404 | data->in_max[attr->index] = IN_TO_REG(val, | ||
405 | data->in_vref); | ||
406 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MAX, | ||
407 | data->in_max[attr->index]); | ||
408 | up(&data->update_lock); | ||
409 | return count; | ||
410 | } | ||
411 | |||
355 | #define show_and_set_in(offset) \ | 412 | #define show_and_set_in(offset) \ |
356 | static ssize_t show_in##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \ | 413 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
357 | { \ | 414 | show_in_input, NULL, offset); \ |
358 | struct pc87360_data *data = pc87360_update_device(dev); \ | 415 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \ |
359 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \ | 416 | show_in_min, set_in_min, offset); \ |
360 | data->in_vref)); \ | 417 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IWUSR | S_IRUGO, \ |
361 | } \ | 418 | show_in_max, set_in_max, offset); \ |
362 | static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \ | 419 | static SENSOR_DEVICE_ATTR(in##offset##_status, S_IRUGO, \ |
363 | { \ | 420 | show_in_status, NULL, offset); |
364 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
365 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \ | ||
366 | data->in_vref)); \ | ||
367 | } \ | ||
368 | static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
369 | { \ | ||
370 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
371 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \ | ||
372 | data->in_vref)); \ | ||
373 | } \ | ||
374 | static ssize_t show_in##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
375 | { \ | ||
376 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
377 | return sprintf(buf, "%u\n", data->in_status[offset]); \ | ||
378 | } \ | ||
379 | static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
380 | size_t count) \ | ||
381 | { \ | ||
382 | struct i2c_client *client = to_i2c_client(dev); \ | ||
383 | struct pc87360_data *data = i2c_get_clientdata(client); \ | ||
384 | long val = simple_strtol(buf, NULL, 10); \ | ||
385 | \ | ||
386 | down(&data->update_lock); \ | ||
387 | data->in_min[offset] = IN_TO_REG(val, data->in_vref); \ | ||
388 | pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MIN, \ | ||
389 | data->in_min[offset]); \ | ||
390 | up(&data->update_lock); \ | ||
391 | return count; \ | ||
392 | } \ | ||
393 | static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
394 | size_t count) \ | ||
395 | { \ | ||
396 | struct i2c_client *client = to_i2c_client(dev); \ | ||
397 | struct pc87360_data *data = i2c_get_clientdata(client); \ | ||
398 | long val = simple_strtol(buf, NULL, 10); \ | ||
399 | \ | ||
400 | down(&data->update_lock); \ | ||
401 | data->in_max[offset] = IN_TO_REG(val, \ | ||
402 | data->in_vref); \ | ||
403 | pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MAX, \ | ||
404 | data->in_max[offset]); \ | ||
405 | up(&data->update_lock); \ | ||
406 | return count; \ | ||
407 | } \ | ||
408 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ | ||
409 | show_in##offset##_input, NULL); \ | ||
410 | static DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \ | ||
411 | show_in##offset##_min, set_in##offset##_min); \ | ||
412 | static DEVICE_ATTR(in##offset##_max, S_IWUSR | S_IRUGO, \ | ||
413 | show_in##offset##_max, set_in##offset##_max); \ | ||
414 | static DEVICE_ATTR(in##offset##_status, S_IRUGO, \ | ||
415 | show_in##offset##_status, NULL); | ||
416 | show_and_set_in(0) | 421 | show_and_set_in(0) |
417 | show_and_set_in(1) | 422 | show_and_set_in(1) |
418 | show_and_set_in(2) | 423 | show_and_set_in(2) |
@@ -425,88 +430,97 @@ show_and_set_in(8) | |||
425 | show_and_set_in(9) | 430 | show_and_set_in(9) |
426 | show_and_set_in(10) | 431 | show_and_set_in(10) |
427 | 432 | ||
433 | static ssize_t show_therm_input(struct device *dev, struct device_attribute *devattr, char *buf) | ||
434 | { | ||
435 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
436 | struct pc87360_data *data = pc87360_update_device(dev); | ||
437 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in[attr->index], | ||
438 | data->in_vref)); | ||
439 | } | ||
440 | static ssize_t show_therm_min(struct device *dev, struct device_attribute *devattr, char *buf) | ||
441 | { | ||
442 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
443 | struct pc87360_data *data = pc87360_update_device(dev); | ||
444 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[attr->index], | ||
445 | data->in_vref)); | ||
446 | } | ||
447 | static ssize_t show_therm_max(struct device *dev, struct device_attribute *devattr, char *buf) | ||
448 | { | ||
449 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
450 | struct pc87360_data *data = pc87360_update_device(dev); | ||
451 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[attr->index], | ||
452 | data->in_vref)); | ||
453 | } | ||
454 | static ssize_t show_therm_crit(struct device *dev, struct device_attribute *devattr, char *buf) | ||
455 | { | ||
456 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
457 | struct pc87360_data *data = pc87360_update_device(dev); | ||
458 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_crit[attr->index-11], | ||
459 | data->in_vref)); | ||
460 | } | ||
461 | static ssize_t show_therm_status(struct device *dev, struct device_attribute *devattr, char *buf) | ||
462 | { | ||
463 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
464 | struct pc87360_data *data = pc87360_update_device(dev); | ||
465 | return sprintf(buf, "%u\n", data->in_status[attr->index]); | ||
466 | } | ||
467 | static ssize_t set_therm_min(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
468 | size_t count) | ||
469 | { | ||
470 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
471 | struct i2c_client *client = to_i2c_client(dev); | ||
472 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
473 | long val = simple_strtol(buf, NULL, 10); | ||
474 | |||
475 | down(&data->update_lock); | ||
476 | data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); | ||
477 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MIN, | ||
478 | data->in_min[attr->index]); | ||
479 | up(&data->update_lock); | ||
480 | return count; | ||
481 | } | ||
482 | static ssize_t set_therm_max(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
483 | size_t count) | ||
484 | { | ||
485 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
486 | struct i2c_client *client = to_i2c_client(dev); | ||
487 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
488 | long val = simple_strtol(buf, NULL, 10); | ||
489 | |||
490 | down(&data->update_lock); | ||
491 | data->in_max[attr->index] = IN_TO_REG(val, data->in_vref); | ||
492 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MAX, | ||
493 | data->in_max[attr->index]); | ||
494 | up(&data->update_lock); | ||
495 | return count; | ||
496 | } | ||
497 | static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
498 | size_t count) | ||
499 | { | ||
500 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
501 | struct i2c_client *client = to_i2c_client(dev); | ||
502 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
503 | long val = simple_strtol(buf, NULL, 10); | ||
504 | |||
505 | down(&data->update_lock); | ||
506 | data->in_crit[attr->index-11] = IN_TO_REG(val, data->in_vref); | ||
507 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_CRIT, | ||
508 | data->in_crit[attr->index-11]); | ||
509 | up(&data->update_lock); | ||
510 | return count; | ||
511 | } | ||
512 | |||
428 | #define show_and_set_therm(offset) \ | 513 | #define show_and_set_therm(offset) \ |
429 | static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \ | 514 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
430 | { \ | 515 | show_therm_input, NULL, 11+offset-4); \ |
431 | struct pc87360_data *data = pc87360_update_device(dev); \ | 516 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \ |
432 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset+7], \ | 517 | show_therm_min, set_therm_min, 11+offset-4); \ |
433 | data->in_vref)); \ | 518 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \ |
434 | } \ | 519 | show_therm_max, set_therm_max, 11+offset-4); \ |
435 | static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \ | 520 | static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \ |
436 | { \ | 521 | show_therm_crit, set_therm_crit, 11+offset-4); \ |
437 | struct pc87360_data *data = pc87360_update_device(dev); \ | 522 | static SENSOR_DEVICE_ATTR(temp##offset##_status, S_IRUGO, \ |
438 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset+7], \ | 523 | show_therm_status, NULL, 11+offset-4); |
439 | data->in_vref)); \ | ||
440 | } \ | ||
441 | static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
442 | { \ | ||
443 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
444 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset+7], \ | ||
445 | data->in_vref)); \ | ||
446 | } \ | ||
447 | static ssize_t show_temp##offset##_crit(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
448 | { \ | ||
449 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
450 | return sprintf(buf, "%u\n", IN_FROM_REG(data->in_crit[offset-4], \ | ||
451 | data->in_vref)); \ | ||
452 | } \ | ||
453 | static ssize_t show_temp##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
454 | { \ | ||
455 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
456 | return sprintf(buf, "%u\n", data->in_status[offset+7]); \ | ||
457 | } \ | ||
458 | static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
459 | size_t count) \ | ||
460 | { \ | ||
461 | struct i2c_client *client = to_i2c_client(dev); \ | ||
462 | struct pc87360_data *data = i2c_get_clientdata(client); \ | ||
463 | long val = simple_strtol(buf, NULL, 10); \ | ||
464 | \ | ||
465 | down(&data->update_lock); \ | ||
466 | data->in_min[offset+7] = IN_TO_REG(val, data->in_vref); \ | ||
467 | pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MIN, \ | ||
468 | data->in_min[offset+7]); \ | ||
469 | up(&data->update_lock); \ | ||
470 | return count; \ | ||
471 | } \ | ||
472 | static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
473 | size_t count) \ | ||
474 | { \ | ||
475 | struct i2c_client *client = to_i2c_client(dev); \ | ||
476 | struct pc87360_data *data = i2c_get_clientdata(client); \ | ||
477 | long val = simple_strtol(buf, NULL, 10); \ | ||
478 | \ | ||
479 | down(&data->update_lock); \ | ||
480 | data->in_max[offset+7] = IN_TO_REG(val, data->in_vref); \ | ||
481 | pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MAX, \ | ||
482 | data->in_max[offset+7]); \ | ||
483 | up(&data->update_lock); \ | ||
484 | return count; \ | ||
485 | } \ | ||
486 | static ssize_t set_temp##offset##_crit(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
487 | size_t count) \ | ||
488 | { \ | ||
489 | struct i2c_client *client = to_i2c_client(dev); \ | ||
490 | struct pc87360_data *data = i2c_get_clientdata(client); \ | ||
491 | long val = simple_strtol(buf, NULL, 10); \ | ||
492 | \ | ||
493 | down(&data->update_lock); \ | ||
494 | data->in_crit[offset-4] = IN_TO_REG(val, data->in_vref); \ | ||
495 | pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_CRIT, \ | ||
496 | data->in_crit[offset-4]); \ | ||
497 | up(&data->update_lock); \ | ||
498 | return count; \ | ||
499 | } \ | ||
500 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | ||
501 | show_temp##offset##_input, NULL); \ | ||
502 | static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \ | ||
503 | show_temp##offset##_min, set_temp##offset##_min); \ | ||
504 | static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \ | ||
505 | show_temp##offset##_max, set_temp##offset##_max); \ | ||
506 | static DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \ | ||
507 | show_temp##offset##_crit, set_temp##offset##_crit); \ | ||
508 | static DEVICE_ATTR(temp##offset##_status, S_IRUGO, \ | ||
509 | show_temp##offset##_status, NULL); | ||
510 | show_and_set_therm(4) | 524 | show_and_set_therm(4) |
511 | show_and_set_therm(5) | 525 | show_and_set_therm(5) |
512 | show_and_set_therm(6) | 526 | show_and_set_therm(6) |
@@ -539,84 +553,93 @@ static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, | |||
539 | } | 553 | } |
540 | static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL); | 554 | static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL); |
541 | 555 | ||
556 | static ssize_t show_temp_input(struct device *dev, struct device_attribute *devattr, char *buf) | ||
557 | { | ||
558 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
559 | struct pc87360_data *data = pc87360_update_device(dev); | ||
560 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index])); | ||
561 | } | ||
562 | static ssize_t show_temp_min(struct device *dev, struct device_attribute *devattr, char *buf) | ||
563 | { | ||
564 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
565 | struct pc87360_data *data = pc87360_update_device(dev); | ||
566 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[attr->index])); | ||
567 | } | ||
568 | static ssize_t show_temp_max(struct device *dev, struct device_attribute *devattr, char *buf) | ||
569 | { | ||
570 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
571 | struct pc87360_data *data = pc87360_update_device(dev); | ||
572 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[attr->index])); | ||
573 | } | ||
574 | static ssize_t show_temp_crit(struct device *dev, struct device_attribute *devattr, char *buf) | ||
575 | { | ||
576 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
577 | struct pc87360_data *data = pc87360_update_device(dev); | ||
578 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[attr->index])); | ||
579 | } | ||
580 | static ssize_t show_temp_status(struct device *dev, struct device_attribute *devattr, char *buf) | ||
581 | { | ||
582 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
583 | struct pc87360_data *data = pc87360_update_device(dev); | ||
584 | return sprintf(buf, "%d\n", data->temp_status[attr->index]); | ||
585 | } | ||
586 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
587 | size_t count) | ||
588 | { | ||
589 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
590 | struct i2c_client *client = to_i2c_client(dev); | ||
591 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
592 | long val = simple_strtol(buf, NULL, 10); | ||
593 | |||
594 | down(&data->update_lock); | ||
595 | data->temp_min[attr->index] = TEMP_TO_REG(val); | ||
596 | pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MIN, | ||
597 | data->temp_min[attr->index]); | ||
598 | up(&data->update_lock); | ||
599 | return count; | ||
600 | } | ||
601 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
602 | size_t count) | ||
603 | { | ||
604 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
605 | struct i2c_client *client = to_i2c_client(dev); | ||
606 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
607 | long val = simple_strtol(buf, NULL, 10); | ||
608 | |||
609 | down(&data->update_lock); | ||
610 | data->temp_max[attr->index] = TEMP_TO_REG(val); | ||
611 | pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MAX, | ||
612 | data->temp_max[attr->index]); | ||
613 | up(&data->update_lock); | ||
614 | return count; | ||
615 | } | ||
616 | static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf, | ||
617 | size_t count) | ||
618 | { | ||
619 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
620 | struct i2c_client *client = to_i2c_client(dev); | ||
621 | struct pc87360_data *data = i2c_get_clientdata(client); | ||
622 | long val = simple_strtol(buf, NULL, 10); | ||
623 | |||
624 | down(&data->update_lock); | ||
625 | data->temp_crit[attr->index] = TEMP_TO_REG(val); | ||
626 | pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_CRIT, | ||
627 | data->temp_crit[attr->index]); | ||
628 | up(&data->update_lock); | ||
629 | return count; | ||
630 | } | ||
631 | |||
542 | #define show_and_set_temp(offset) \ | 632 | #define show_and_set_temp(offset) \ |
543 | static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \ | 633 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
544 | { \ | 634 | show_temp_input, NULL, offset-1); \ |
545 | struct pc87360_data *data = pc87360_update_device(dev); \ | 635 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \ |
546 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \ | 636 | show_temp_min, set_temp_min, offset-1); \ |
547 | } \ | 637 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \ |
548 | static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \ | 638 | show_temp_max, set_temp_max, offset-1); \ |
549 | { \ | 639 | static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \ |
550 | struct pc87360_data *data = pc87360_update_device(dev); \ | 640 | show_temp_crit, set_temp_crit, offset-1); \ |
551 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[offset-1])); \ | 641 | static SENSOR_DEVICE_ATTR(temp##offset##_status, S_IRUGO, \ |
552 | } \ | 642 | show_temp_status, NULL, offset-1); |
553 | static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
554 | { \ | ||
555 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
556 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[offset-1])); \ | ||
557 | }\ | ||
558 | static ssize_t show_temp##offset##_crit(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
559 | { \ | ||
560 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
561 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[offset-1])); \ | ||
562 | }\ | ||
563 | static ssize_t show_temp##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
564 | { \ | ||
565 | struct pc87360_data *data = pc87360_update_device(dev); \ | ||
566 | return sprintf(buf, "%d\n", data->temp_status[offset-1]); \ | ||
567 | }\ | ||
568 | static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
569 | size_t count) \ | ||
570 | { \ | ||
571 | struct i2c_client *client = to_i2c_client(dev); \ | ||
572 | struct pc87360_data *data = i2c_get_clientdata(client); \ | ||
573 | long val = simple_strtol(buf, NULL, 10); \ | ||
574 | \ | ||
575 | down(&data->update_lock); \ | ||
576 | data->temp_min[offset-1] = TEMP_TO_REG(val); \ | ||
577 | pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MIN, \ | ||
578 | data->temp_min[offset-1]); \ | ||
579 | up(&data->update_lock); \ | ||
580 | return count; \ | ||
581 | } \ | ||
582 | static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
583 | size_t count) \ | ||
584 | { \ | ||
585 | struct i2c_client *client = to_i2c_client(dev); \ | ||
586 | struct pc87360_data *data = i2c_get_clientdata(client); \ | ||
587 | long val = simple_strtol(buf, NULL, 10); \ | ||
588 | \ | ||
589 | down(&data->update_lock); \ | ||
590 | data->temp_max[offset-1] = TEMP_TO_REG(val); \ | ||
591 | pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MAX, \ | ||
592 | data->temp_max[offset-1]); \ | ||
593 | up(&data->update_lock); \ | ||
594 | return count; \ | ||
595 | } \ | ||
596 | static ssize_t set_temp##offset##_crit(struct device *dev, struct device_attribute *attr, const char *buf, \ | ||
597 | size_t count) \ | ||
598 | { \ | ||
599 | struct i2c_client *client = to_i2c_client(dev); \ | ||
600 | struct pc87360_data *data = i2c_get_clientdata(client); \ | ||
601 | long val = simple_strtol(buf, NULL, 10); \ | ||
602 | \ | ||
603 | down(&data->update_lock); \ | ||
604 | data->temp_crit[offset-1] = TEMP_TO_REG(val); \ | ||
605 | pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_CRIT, \ | ||
606 | data->temp_crit[offset-1]); \ | ||
607 | up(&data->update_lock); \ | ||
608 | return count; \ | ||
609 | } \ | ||
610 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | ||
611 | show_temp##offset##_input, NULL); \ | ||
612 | static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \ | ||
613 | show_temp##offset##_min, set_temp##offset##_min); \ | ||
614 | static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \ | ||
615 | show_temp##offset##_max, set_temp##offset##_max); \ | ||
616 | static DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \ | ||
617 | show_temp##offset##_crit, set_temp##offset##_crit); \ | ||
618 | static DEVICE_ATTR(temp##offset##_status, S_IRUGO, \ | ||
619 | show_temp##offset##_status, NULL); | ||
620 | show_and_set_temp(1) | 643 | show_and_set_temp(1) |
621 | show_and_set_temp(2) | 644 | show_and_set_temp(2) |
622 | show_and_set_temp(3) | 645 | show_and_set_temp(3) |
@@ -632,12 +655,7 @@ static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL); | |||
632 | * Device detection, registration and update | 655 | * Device detection, registration and update |
633 | */ | 656 | */ |
634 | 657 | ||
635 | static int pc87360_attach_adapter(struct i2c_adapter *adapter) | 658 | static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses) |
636 | { | ||
637 | return i2c_detect(adapter, &addr_data, pc87360_detect); | ||
638 | } | ||
639 | |||
640 | static int pc87360_find(int sioaddr, u8 *devid, int *address) | ||
641 | { | 659 | { |
642 | u16 val; | 660 | u16 val; |
643 | int i; | 661 | int i; |
@@ -683,7 +701,7 @@ static int pc87360_find(int sioaddr, u8 *devid, int *address) | |||
683 | continue; | 701 | continue; |
684 | } | 702 | } |
685 | 703 | ||
686 | address[i] = val; | 704 | addresses[i] = val; |
687 | 705 | ||
688 | if (i==0) { /* Fans */ | 706 | if (i==0) { /* Fans */ |
689 | confreg[0] = superio_inb(sioaddr, 0xF0); | 707 | confreg[0] = superio_inb(sioaddr, 0xF0); |
@@ -727,9 +745,7 @@ static int pc87360_find(int sioaddr, u8 *devid, int *address) | |||
727 | return 0; | 745 | return 0; |
728 | } | 746 | } |
729 | 747 | ||
730 | /* We don't really care about the address. | 748 | static int pc87360_detect(struct i2c_adapter *adapter) |
731 | Read from extra_isa instead. */ | ||
732 | int pc87360_detect(struct i2c_adapter *adapter, int address, int kind) | ||
733 | { | 749 | { |
734 | int i; | 750 | int i; |
735 | struct i2c_client *new_client; | 751 | struct i2c_client *new_client; |
@@ -738,9 +754,6 @@ int pc87360_detect(struct i2c_adapter *adapter, int address, int kind) | |||
738 | const char *name = "pc87360"; | 754 | const char *name = "pc87360"; |
739 | int use_thermistors = 0; | 755 | int use_thermistors = 0; |
740 | 756 | ||
741 | if (!i2c_is_isa_adapter(adapter)) | ||
742 | return -ENODEV; | ||
743 | |||
744 | if (!(data = kmalloc(sizeof(struct pc87360_data), GFP_KERNEL))) | 757 | if (!(data = kmalloc(sizeof(struct pc87360_data), GFP_KERNEL))) |
745 | return -ENOMEM; | 758 | return -ENOMEM; |
746 | memset(data, 0x00, sizeof(struct pc87360_data)); | 759 | memset(data, 0x00, sizeof(struct pc87360_data)); |
@@ -838,51 +851,57 @@ int pc87360_detect(struct i2c_adapter *adapter, int address, int kind) | |||
838 | } | 851 | } |
839 | 852 | ||
840 | /* Register sysfs hooks */ | 853 | /* Register sysfs hooks */ |
854 | data->class_dev = hwmon_device_register(&new_client->dev); | ||
855 | if (IS_ERR(data->class_dev)) { | ||
856 | err = PTR_ERR(data->class_dev); | ||
857 | goto ERROR3; | ||
858 | } | ||
859 | |||
841 | if (data->innr) { | 860 | if (data->innr) { |
842 | device_create_file(&new_client->dev, &dev_attr_in0_input); | 861 | device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr); |
843 | device_create_file(&new_client->dev, &dev_attr_in1_input); | 862 | device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr); |
844 | device_create_file(&new_client->dev, &dev_attr_in2_input); | 863 | device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr); |
845 | device_create_file(&new_client->dev, &dev_attr_in3_input); | 864 | device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr); |
846 | device_create_file(&new_client->dev, &dev_attr_in4_input); | 865 | device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr); |
847 | device_create_file(&new_client->dev, &dev_attr_in5_input); | 866 | device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr); |
848 | device_create_file(&new_client->dev, &dev_attr_in6_input); | 867 | device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr); |
849 | device_create_file(&new_client->dev, &dev_attr_in7_input); | 868 | device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr); |
850 | device_create_file(&new_client->dev, &dev_attr_in8_input); | 869 | device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr); |
851 | device_create_file(&new_client->dev, &dev_attr_in9_input); | 870 | device_create_file(&new_client->dev, &sensor_dev_attr_in9_input.dev_attr); |
852 | device_create_file(&new_client->dev, &dev_attr_in10_input); | 871 | device_create_file(&new_client->dev, &sensor_dev_attr_in10_input.dev_attr); |
853 | device_create_file(&new_client->dev, &dev_attr_in0_min); | 872 | device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr); |
854 | device_create_file(&new_client->dev, &dev_attr_in1_min); | 873 | device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr); |
855 | device_create_file(&new_client->dev, &dev_attr_in2_min); | 874 | device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr); |
856 | device_create_file(&new_client->dev, &dev_attr_in3_min); | 875 | device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr); |
857 | device_create_file(&new_client->dev, &dev_attr_in4_min); | 876 | device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr); |
858 | device_create_file(&new_client->dev, &dev_attr_in5_min); | 877 | device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr); |
859 | device_create_file(&new_client->dev, &dev_attr_in6_min); | 878 | device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr); |
860 | device_create_file(&new_client->dev, &dev_attr_in7_min); | 879 | device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr); |
861 | device_create_file(&new_client->dev, &dev_attr_in8_min); | 880 | device_create_file(&new_client->dev, &sensor_dev_attr_in8_min.dev_attr); |
862 | device_create_file(&new_client->dev, &dev_attr_in9_min); | 881 | device_create_file(&new_client->dev, &sensor_dev_attr_in9_min.dev_attr); |
863 | device_create_file(&new_client->dev, &dev_attr_in10_min); | 882 | device_create_file(&new_client->dev, &sensor_dev_attr_in10_min.dev_attr); |
864 | device_create_file(&new_client->dev, &dev_attr_in0_max); | 883 | device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr); |
865 | device_create_file(&new_client->dev, &dev_attr_in1_max); | 884 | device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr); |
866 | device_create_file(&new_client->dev, &dev_attr_in2_max); | 885 | device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr); |
867 | device_create_file(&new_client->dev, &dev_attr_in3_max); | 886 | device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr); |
868 | device_create_file(&new_client->dev, &dev_attr_in4_max); | 887 | device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr); |
869 | device_create_file(&new_client->dev, &dev_attr_in5_max); | 888 | device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr); |
870 | device_create_file(&new_client->dev, &dev_attr_in6_max); | 889 | device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr); |
871 | device_create_file(&new_client->dev, &dev_attr_in7_max); | 890 | device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr); |
872 | device_create_file(&new_client->dev, &dev_attr_in8_max); | 891 | device_create_file(&new_client->dev, &sensor_dev_attr_in8_max.dev_attr); |
873 | device_create_file(&new_client->dev, &dev_attr_in9_max); | 892 | device_create_file(&new_client->dev, &sensor_dev_attr_in9_max.dev_attr); |
874 | device_create_file(&new_client->dev, &dev_attr_in10_max); | 893 | device_create_file(&new_client->dev, &sensor_dev_attr_in10_max.dev_attr); |
875 | device_create_file(&new_client->dev, &dev_attr_in0_status); | 894 | device_create_file(&new_client->dev, &sensor_dev_attr_in0_status.dev_attr); |
876 | device_create_file(&new_client->dev, &dev_attr_in1_status); | 895 | device_create_file(&new_client->dev, &sensor_dev_attr_in1_status.dev_attr); |
877 | device_create_file(&new_client->dev, &dev_attr_in2_status); | 896 | device_create_file(&new_client->dev, &sensor_dev_attr_in2_status.dev_attr); |
878 | device_create_file(&new_client->dev, &dev_attr_in3_status); | 897 | device_create_file(&new_client->dev, &sensor_dev_attr_in3_status.dev_attr); |
879 | device_create_file(&new_client->dev, &dev_attr_in4_status); | 898 | device_create_file(&new_client->dev, &sensor_dev_attr_in4_status.dev_attr); |
880 | device_create_file(&new_client->dev, &dev_attr_in5_status); | 899 | device_create_file(&new_client->dev, &sensor_dev_attr_in5_status.dev_attr); |
881 | device_create_file(&new_client->dev, &dev_attr_in6_status); | 900 | device_create_file(&new_client->dev, &sensor_dev_attr_in6_status.dev_attr); |
882 | device_create_file(&new_client->dev, &dev_attr_in7_status); | 901 | device_create_file(&new_client->dev, &sensor_dev_attr_in7_status.dev_attr); |
883 | device_create_file(&new_client->dev, &dev_attr_in8_status); | 902 | device_create_file(&new_client->dev, &sensor_dev_attr_in8_status.dev_attr); |
884 | device_create_file(&new_client->dev, &dev_attr_in9_status); | 903 | device_create_file(&new_client->dev, &sensor_dev_attr_in9_status.dev_attr); |
885 | device_create_file(&new_client->dev, &dev_attr_in10_status); | 904 | device_create_file(&new_client->dev, &sensor_dev_attr_in10_status.dev_attr); |
886 | 905 | ||
887 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); | 906 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); |
888 | device_create_file(&new_client->dev, &dev_attr_vrm); | 907 | device_create_file(&new_client->dev, &dev_attr_vrm); |
@@ -890,90 +909,92 @@ int pc87360_detect(struct i2c_adapter *adapter, int address, int kind) | |||
890 | } | 909 | } |
891 | 910 | ||
892 | if (data->tempnr) { | 911 | if (data->tempnr) { |
893 | device_create_file(&new_client->dev, &dev_attr_temp1_input); | 912 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr); |
894 | device_create_file(&new_client->dev, &dev_attr_temp2_input); | 913 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr); |
895 | device_create_file(&new_client->dev, &dev_attr_temp1_min); | 914 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr); |
896 | device_create_file(&new_client->dev, &dev_attr_temp2_min); | 915 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr); |
897 | device_create_file(&new_client->dev, &dev_attr_temp1_max); | 916 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr); |
898 | device_create_file(&new_client->dev, &dev_attr_temp2_max); | 917 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr); |
899 | device_create_file(&new_client->dev, &dev_attr_temp1_crit); | 918 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_crit.dev_attr); |
900 | device_create_file(&new_client->dev, &dev_attr_temp2_crit); | 919 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_crit.dev_attr); |
901 | device_create_file(&new_client->dev, &dev_attr_temp1_status); | 920 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_status.dev_attr); |
902 | device_create_file(&new_client->dev, &dev_attr_temp2_status); | 921 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_status.dev_attr); |
903 | 922 | ||
904 | device_create_file(&new_client->dev, &dev_attr_alarms_temp); | 923 | device_create_file(&new_client->dev, &dev_attr_alarms_temp); |
905 | } | 924 | } |
906 | if (data->tempnr == 3) { | 925 | if (data->tempnr == 3) { |
907 | device_create_file(&new_client->dev, &dev_attr_temp3_input); | 926 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr); |
908 | device_create_file(&new_client->dev, &dev_attr_temp3_min); | 927 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr); |
909 | device_create_file(&new_client->dev, &dev_attr_temp3_max); | 928 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr); |
910 | device_create_file(&new_client->dev, &dev_attr_temp3_crit); | 929 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_crit.dev_attr); |
911 | device_create_file(&new_client->dev, &dev_attr_temp3_status); | 930 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_status.dev_attr); |
912 | } | 931 | } |
913 | if (data->innr == 14) { | 932 | if (data->innr == 14) { |
914 | device_create_file(&new_client->dev, &dev_attr_temp4_input); | 933 | device_create_file(&new_client->dev, &sensor_dev_attr_temp4_input.dev_attr); |
915 | device_create_file(&new_client->dev, &dev_attr_temp5_input); | 934 | device_create_file(&new_client->dev, &sensor_dev_attr_temp5_input.dev_attr); |
916 | device_create_file(&new_client->dev, &dev_attr_temp6_input); | 935 | device_create_file(&new_client->dev, &sensor_dev_attr_temp6_input.dev_attr); |
917 | device_create_file(&new_client->dev, &dev_attr_temp4_min); | 936 | device_create_file(&new_client->dev, &sensor_dev_attr_temp4_min.dev_attr); |
918 | device_create_file(&new_client->dev, &dev_attr_temp5_min); | 937 | device_create_file(&new_client->dev, &sensor_dev_attr_temp5_min.dev_attr); |
919 | device_create_file(&new_client->dev, &dev_attr_temp6_min); | 938 | device_create_file(&new_client->dev, &sensor_dev_attr_temp6_min.dev_attr); |
920 | device_create_file(&new_client->dev, &dev_attr_temp4_max); | 939 | device_create_file(&new_client->dev, &sensor_dev_attr_temp4_max.dev_attr); |
921 | device_create_file(&new_client->dev, &dev_attr_temp5_max); | 940 | device_create_file(&new_client->dev, &sensor_dev_attr_temp5_max.dev_attr); |
922 | device_create_file(&new_client->dev, &dev_attr_temp6_max); | 941 | device_create_file(&new_client->dev, &sensor_dev_attr_temp6_max.dev_attr); |
923 | device_create_file(&new_client->dev, &dev_attr_temp4_crit); | 942 | device_create_file(&new_client->dev, &sensor_dev_attr_temp4_crit.dev_attr); |
924 | device_create_file(&new_client->dev, &dev_attr_temp5_crit); | 943 | device_create_file(&new_client->dev, &sensor_dev_attr_temp5_crit.dev_attr); |
925 | device_create_file(&new_client->dev, &dev_attr_temp6_crit); | 944 | device_create_file(&new_client->dev, &sensor_dev_attr_temp6_crit.dev_attr); |
926 | device_create_file(&new_client->dev, &dev_attr_temp4_status); | 945 | device_create_file(&new_client->dev, &sensor_dev_attr_temp4_status.dev_attr); |
927 | device_create_file(&new_client->dev, &dev_attr_temp5_status); | 946 | device_create_file(&new_client->dev, &sensor_dev_attr_temp5_status.dev_attr); |
928 | device_create_file(&new_client->dev, &dev_attr_temp6_status); | 947 | device_create_file(&new_client->dev, &sensor_dev_attr_temp6_status.dev_attr); |
929 | } | 948 | } |
930 | 949 | ||
931 | if (data->fannr) { | 950 | if (data->fannr) { |
932 | if (FAN_CONFIG_MONITOR(data->fan_conf, 0)) { | 951 | if (FAN_CONFIG_MONITOR(data->fan_conf, 0)) { |
933 | device_create_file(&new_client->dev, | 952 | device_create_file(&new_client->dev, |
934 | &dev_attr_fan1_input); | 953 | &sensor_dev_attr_fan1_input.dev_attr); |
935 | device_create_file(&new_client->dev, | 954 | device_create_file(&new_client->dev, |
936 | &dev_attr_fan1_min); | 955 | &sensor_dev_attr_fan1_min.dev_attr); |
937 | device_create_file(&new_client->dev, | 956 | device_create_file(&new_client->dev, |
938 | &dev_attr_fan1_div); | 957 | &sensor_dev_attr_fan1_div.dev_attr); |
939 | device_create_file(&new_client->dev, | 958 | device_create_file(&new_client->dev, |
940 | &dev_attr_fan1_status); | 959 | &sensor_dev_attr_fan1_status.dev_attr); |
941 | } | 960 | } |
942 | 961 | ||
943 | if (FAN_CONFIG_MONITOR(data->fan_conf, 1)) { | 962 | if (FAN_CONFIG_MONITOR(data->fan_conf, 1)) { |
944 | device_create_file(&new_client->dev, | 963 | device_create_file(&new_client->dev, |
945 | &dev_attr_fan2_input); | 964 | &sensor_dev_attr_fan2_input.dev_attr); |
946 | device_create_file(&new_client->dev, | 965 | device_create_file(&new_client->dev, |
947 | &dev_attr_fan2_min); | 966 | &sensor_dev_attr_fan2_min.dev_attr); |
948 | device_create_file(&new_client->dev, | 967 | device_create_file(&new_client->dev, |
949 | &dev_attr_fan2_div); | 968 | &sensor_dev_attr_fan2_div.dev_attr); |
950 | device_create_file(&new_client->dev, | 969 | device_create_file(&new_client->dev, |
951 | &dev_attr_fan2_status); | 970 | &sensor_dev_attr_fan2_status.dev_attr); |
952 | } | 971 | } |
953 | 972 | ||
954 | if (FAN_CONFIG_CONTROL(data->fan_conf, 0)) | 973 | if (FAN_CONFIG_CONTROL(data->fan_conf, 0)) |
955 | device_create_file(&new_client->dev, &dev_attr_pwm1); | 974 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm1.dev_attr); |
956 | if (FAN_CONFIG_CONTROL(data->fan_conf, 1)) | 975 | if (FAN_CONFIG_CONTROL(data->fan_conf, 1)) |
957 | device_create_file(&new_client->dev, &dev_attr_pwm2); | 976 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm2.dev_attr); |
958 | } | 977 | } |
959 | if (data->fannr == 3) { | 978 | if (data->fannr == 3) { |
960 | if (FAN_CONFIG_MONITOR(data->fan_conf, 2)) { | 979 | if (FAN_CONFIG_MONITOR(data->fan_conf, 2)) { |
961 | device_create_file(&new_client->dev, | 980 | device_create_file(&new_client->dev, |
962 | &dev_attr_fan3_input); | 981 | &sensor_dev_attr_fan3_input.dev_attr); |
963 | device_create_file(&new_client->dev, | 982 | device_create_file(&new_client->dev, |
964 | &dev_attr_fan3_min); | 983 | &sensor_dev_attr_fan3_min.dev_attr); |
965 | device_create_file(&new_client->dev, | 984 | device_create_file(&new_client->dev, |
966 | &dev_attr_fan3_div); | 985 | &sensor_dev_attr_fan3_div.dev_attr); |
967 | device_create_file(&new_client->dev, | 986 | device_create_file(&new_client->dev, |
968 | &dev_attr_fan3_status); | 987 | &sensor_dev_attr_fan3_status.dev_attr); |
969 | } | 988 | } |
970 | 989 | ||
971 | if (FAN_CONFIG_CONTROL(data->fan_conf, 2)) | 990 | if (FAN_CONFIG_CONTROL(data->fan_conf, 2)) |
972 | device_create_file(&new_client->dev, &dev_attr_pwm3); | 991 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr); |
973 | } | 992 | } |
974 | 993 | ||
975 | return 0; | 994 | return 0; |
976 | 995 | ||
996 | ERROR3: | ||
997 | i2c_detach_client(new_client); | ||
977 | ERROR2: | 998 | ERROR2: |
978 | for (i = 0; i < 3; i++) { | 999 | for (i = 0; i < 3; i++) { |
979 | if (data->address[i]) { | 1000 | if (data->address[i]) { |
@@ -990,11 +1011,10 @@ static int pc87360_detach_client(struct i2c_client *client) | |||
990 | struct pc87360_data *data = i2c_get_clientdata(client); | 1011 | struct pc87360_data *data = i2c_get_clientdata(client); |
991 | int i; | 1012 | int i; |
992 | 1013 | ||
993 | if ((i = i2c_detach_client(client))) { | 1014 | hwmon_device_unregister(data->class_dev); |
994 | dev_err(&client->dev, "Client deregistration failed, " | 1015 | |
995 | "client not detached.\n"); | 1016 | if ((i = i2c_detach_client(client))) |
996 | return i; | 1017 | return i; |
997 | } | ||
998 | 1018 | ||
999 | for (i = 0; i < 3; i++) { | 1019 | for (i = 0; i < 3; i++) { |
1000 | if (data->address[i]) { | 1020 | if (data->address[i]) { |
@@ -1320,23 +1340,23 @@ static int __init pc87360_init(void) | |||
1320 | /* Arbitrarily pick one of the addresses */ | 1340 | /* Arbitrarily pick one of the addresses */ |
1321 | for (i = 0; i < 3; i++) { | 1341 | for (i = 0; i < 3; i++) { |
1322 | if (extra_isa[i] != 0x0000) { | 1342 | if (extra_isa[i] != 0x0000) { |
1323 | normal_isa[0] = extra_isa[i]; | 1343 | address = extra_isa[i]; |
1324 | break; | 1344 | break; |
1325 | } | 1345 | } |
1326 | } | 1346 | } |
1327 | 1347 | ||
1328 | if (normal_isa[0] == 0x0000) { | 1348 | if (address == 0x0000) { |
1329 | printk(KERN_WARNING "pc87360: No active logical device, " | 1349 | printk(KERN_WARNING "pc87360: No active logical device, " |
1330 | "module not inserted.\n"); | 1350 | "module not inserted.\n"); |
1331 | return -ENODEV; | 1351 | return -ENODEV; |
1332 | } | 1352 | } |
1333 | 1353 | ||
1334 | return i2c_add_driver(&pc87360_driver); | 1354 | return i2c_isa_add_driver(&pc87360_driver); |
1335 | } | 1355 | } |
1336 | 1356 | ||
1337 | static void __exit pc87360_exit(void) | 1357 | static void __exit pc87360_exit(void) |
1338 | { | 1358 | { |
1339 | i2c_del_driver(&pc87360_driver); | 1359 | i2c_isa_del_driver(&pc87360_driver); |
1340 | } | 1360 | } |
1341 | 1361 | ||
1342 | 1362 | ||