diff options
Diffstat (limited to 'drivers/hwmon/abituguru.c')
-rw-r--r-- | drivers/hwmon/abituguru.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index bede4d990ea6..2317f4bb9c92 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c | |||
@@ -16,9 +16,9 @@ | |||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
17 | */ | 17 | */ |
18 | /* | 18 | /* |
19 | This driver supports the sensor part of the custom Abit uGuru chip found | 19 | This driver supports the sensor part of the first and second revision of |
20 | on Abit uGuru motherboards. Note: because of lack of specs the CPU / RAM / | 20 | the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because |
21 | etc voltage & frequency control is not supported! | 21 | of lack of specs the CPU/RAM voltage & frequency control is not supported! |
22 | */ | 22 | */ |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/hwmon.h> | 32 | #include <linux/hwmon.h> |
33 | #include <linux/hwmon-sysfs.h> | 33 | #include <linux/hwmon-sysfs.h> |
34 | #include <linux/dmi.h> | ||
34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
35 | 36 | ||
36 | /* Banks */ | 37 | /* Banks */ |
@@ -418,7 +419,7 @@ static int __devinit | |||
418 | abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | 419 | abituguru_detect_bank1_sensor_type(struct abituguru_data *data, |
419 | u8 sensor_addr) | 420 | u8 sensor_addr) |
420 | { | 421 | { |
421 | u8 val, buf[3]; | 422 | u8 val, test_flag, buf[3]; |
422 | int i, ret = -ENODEV; /* error is the most common used retval :| */ | 423 | int i, ret = -ENODEV; /* error is the most common used retval :| */ |
423 | 424 | ||
424 | /* If overriden by the user return the user selected type */ | 425 | /* If overriden by the user return the user selected type */ |
@@ -436,7 +437,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | |||
436 | return -ENODEV; | 437 | return -ENODEV; |
437 | 438 | ||
438 | /* Test val is sane / usable for sensor type detection. */ | 439 | /* Test val is sane / usable for sensor type detection. */ |
439 | if ((val < 10u) || (val > 240u)) { | 440 | if ((val < 10u) || (val > 250u)) { |
440 | printk(KERN_WARNING ABIT_UGURU_NAME | 441 | printk(KERN_WARNING ABIT_UGURU_NAME |
441 | ": bank1-sensor: %d reading (%d) too close to limits, " | 442 | ": bank1-sensor: %d reading (%d) too close to limits, " |
442 | "unable to determine sensor type, skipping sensor\n", | 443 | "unable to determine sensor type, skipping sensor\n", |
@@ -449,10 +450,20 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | |||
449 | 450 | ||
450 | ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); | 451 | ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); |
451 | /* Volt sensor test, enable volt low alarm, set min value ridicously | 452 | /* Volt sensor test, enable volt low alarm, set min value ridicously |
452 | high. If its a volt sensor this should always give us an alarm. */ | 453 | high, or vica versa if the reading is very high. If its a volt |
453 | buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; | 454 | sensor this should always give us an alarm. */ |
454 | buf[1] = 245; | 455 | if (val <= 240u) { |
455 | buf[2] = 250; | 456 | buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; |
457 | buf[1] = 245; | ||
458 | buf[2] = 250; | ||
459 | test_flag = ABIT_UGURU_VOLT_LOW_ALARM_FLAG; | ||
460 | } else { | ||
461 | buf[0] = ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE; | ||
462 | buf[1] = 5; | ||
463 | buf[2] = 10; | ||
464 | test_flag = ABIT_UGURU_VOLT_HIGH_ALARM_FLAG; | ||
465 | } | ||
466 | |||
456 | if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, | 467 | if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, |
457 | buf, 3) != 3) | 468 | buf, 3) != 3) |
458 | goto abituguru_detect_bank1_sensor_type_exit; | 469 | goto abituguru_detect_bank1_sensor_type_exit; |
@@ -469,13 +480,13 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, | |||
469 | sensor_addr, buf, 3, | 480 | sensor_addr, buf, 3, |
470 | ABIT_UGURU_MAX_RETRIES) != 3) | 481 | ABIT_UGURU_MAX_RETRIES) != 3) |
471 | goto abituguru_detect_bank1_sensor_type_exit; | 482 | goto abituguru_detect_bank1_sensor_type_exit; |
472 | if (buf[0] & ABIT_UGURU_VOLT_LOW_ALARM_FLAG) { | 483 | if (buf[0] & test_flag) { |
473 | ABIT_UGURU_DEBUG(2, " found volt sensor\n"); | 484 | ABIT_UGURU_DEBUG(2, " found volt sensor\n"); |
474 | ret = ABIT_UGURU_IN_SENSOR; | 485 | ret = ABIT_UGURU_IN_SENSOR; |
475 | goto abituguru_detect_bank1_sensor_type_exit; | 486 | goto abituguru_detect_bank1_sensor_type_exit; |
476 | } else | 487 | } else |
477 | ABIT_UGURU_DEBUG(2, " alarm raised during volt " | 488 | ABIT_UGURU_DEBUG(2, " alarm raised during volt " |
478 | "sensor test, but volt low flag not set\n"); | 489 | "sensor test, but volt range flag not set\n"); |
479 | } else | 490 | } else |
480 | ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " | 491 | ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " |
481 | "test\n"); | 492 | "test\n"); |
@@ -1287,6 +1298,7 @@ abituguru_probe_error: | |||
1287 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) | 1298 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) |
1288 | device_remove_file(&pdev->dev, | 1299 | device_remove_file(&pdev->dev, |
1289 | &abituguru_sysfs_attr[i].dev_attr); | 1300 | &abituguru_sysfs_attr[i].dev_attr); |
1301 | platform_set_drvdata(pdev, NULL); | ||
1290 | kfree(data); | 1302 | kfree(data); |
1291 | return res; | 1303 | return res; |
1292 | } | 1304 | } |
@@ -1296,13 +1308,13 @@ static int __devexit abituguru_remove(struct platform_device *pdev) | |||
1296 | int i; | 1308 | int i; |
1297 | struct abituguru_data *data = platform_get_drvdata(pdev); | 1309 | struct abituguru_data *data = platform_get_drvdata(pdev); |
1298 | 1310 | ||
1299 | platform_set_drvdata(pdev, NULL); | ||
1300 | hwmon_device_unregister(data->class_dev); | 1311 | hwmon_device_unregister(data->class_dev); |
1301 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) | 1312 | for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) |
1302 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); | 1313 | device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); |
1303 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) | 1314 | for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) |
1304 | device_remove_file(&pdev->dev, | 1315 | device_remove_file(&pdev->dev, |
1305 | &abituguru_sysfs_attr[i].dev_attr); | 1316 | &abituguru_sysfs_attr[i].dev_attr); |
1317 | platform_set_drvdata(pdev, NULL); | ||
1306 | kfree(data); | 1318 | kfree(data); |
1307 | 1319 | ||
1308 | return 0; | 1320 | return 0; |
@@ -1436,6 +1448,15 @@ static int __init abituguru_init(void) | |||
1436 | int address, err; | 1448 | int address, err; |
1437 | struct resource res = { .flags = IORESOURCE_IO }; | 1449 | struct resource res = { .flags = IORESOURCE_IO }; |
1438 | 1450 | ||
1451 | #ifdef CONFIG_DMI | ||
1452 | const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | ||
1453 | |||
1454 | /* safety check, refuse to load on non Abit motherboards */ | ||
1455 | if (!force && (!board_vendor || | ||
1456 | strcmp(board_vendor, "http://www.abit.com.tw/"))) | ||
1457 | return -ENODEV; | ||
1458 | #endif | ||
1459 | |||
1439 | address = abituguru_detect(); | 1460 | address = abituguru_detect(); |
1440 | if (address < 0) | 1461 | if (address < 0) |
1441 | return address; | 1462 | return address; |