diff options
| -rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 230238df56c4..10411848fd70 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
| @@ -65,6 +65,7 @@ | |||
| 65 | #include <linux/i2c.h> | 65 | #include <linux/i2c.h> |
| 66 | #include <linux/acpi.h> | 66 | #include <linux/acpi.h> |
| 67 | #include <linux/io.h> | 67 | #include <linux/io.h> |
| 68 | #include <linux/dmi.h> | ||
| 68 | 69 | ||
| 69 | /* I801 SMBus address offsets */ | 70 | /* I801 SMBus address offsets */ |
| 70 | #define SMBHSTSTS (0 + i801_smba) | 71 | #define SMBHSTSTS (0 + i801_smba) |
| @@ -616,10 +617,81 @@ static void __init input_apanel_init(void) | |||
| 616 | static void __init input_apanel_init(void) {} | 617 | static void __init input_apanel_init(void) {} |
| 617 | #endif | 618 | #endif |
| 618 | 619 | ||
| 620 | #if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE | ||
| 621 | struct dmi_onboard_device_info { | ||
| 622 | const char *name; | ||
| 623 | u8 type; | ||
| 624 | unsigned short i2c_addr; | ||
| 625 | const char *i2c_type; | ||
| 626 | }; | ||
| 627 | |||
| 628 | static struct dmi_onboard_device_info __devinitdata dmi_devices[] = { | ||
| 629 | { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" }, | ||
| 630 | { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" }, | ||
| 631 | { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" }, | ||
| 632 | }; | ||
| 633 | |||
| 634 | static void __devinit dmi_check_onboard_device(u8 type, const char *name, | ||
| 635 | struct i2c_adapter *adap) | ||
| 636 | { | ||
| 637 | int i; | ||
| 638 | struct i2c_board_info info; | ||
| 639 | |||
| 640 | for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) { | ||
| 641 | /* & ~0x80, ignore enabled/disabled bit */ | ||
| 642 | if ((type & ~0x80) != dmi_devices[i].type) | ||
| 643 | continue; | ||
| 644 | if (strcmp(name, dmi_devices[i].name)) | ||
| 645 | continue; | ||
| 646 | |||
| 647 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
| 648 | info.addr = dmi_devices[i].i2c_addr; | ||
| 649 | strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE); | ||
| 650 | i2c_new_device(adap, &info); | ||
| 651 | break; | ||
| 652 | } | ||
| 653 | } | ||
| 654 | |||
| 655 | /* We use our own function to check for onboard devices instead of | ||
| 656 | dmi_find_device() as some buggy BIOS's have the devices we are interested | ||
| 657 | in marked as disabled */ | ||
| 658 | static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm, | ||
| 659 | void *adap) | ||
| 660 | { | ||
| 661 | int i, count; | ||
| 662 | |||
| 663 | if (dm->type != 10) | ||
| 664 | return; | ||
| 665 | |||
| 666 | count = (dm->length - sizeof(struct dmi_header)) / 2; | ||
| 667 | for (i = 0; i < count; i++) { | ||
| 668 | const u8 *d = (char *)(dm + 1) + (i * 2); | ||
| 669 | const char *name = ((char *) dm) + dm->length; | ||
| 670 | u8 type = d[0]; | ||
| 671 | u8 s = d[1]; | ||
| 672 | |||
| 673 | if (!s) | ||
| 674 | continue; | ||
| 675 | s--; | ||
| 676 | while (s > 0 && name[0]) { | ||
| 677 | name += strlen(name) + 1; | ||
| 678 | s--; | ||
| 679 | } | ||
| 680 | if (name[0] == 0) /* Bogus string reference */ | ||
| 681 | continue; | ||
| 682 | |||
| 683 | dmi_check_onboard_device(type, name, adap); | ||
| 684 | } | ||
| 685 | } | ||
| 686 | #endif | ||
| 687 | |||
| 619 | static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) | 688 | static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) |
| 620 | { | 689 | { |
| 621 | unsigned char temp; | 690 | unsigned char temp; |
| 622 | int err; | 691 | int err; |
| 692 | #if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE | ||
| 693 | const char *vendor; | ||
| 694 | #endif | ||
| 623 | 695 | ||
| 624 | I801_dev = dev; | 696 | I801_dev = dev; |
| 625 | i801_features = 0; | 697 | i801_features = 0; |
| @@ -712,6 +784,11 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
| 712 | i2c_new_device(&i801_adapter, &info); | 784 | i2c_new_device(&i801_adapter, &info); |
| 713 | } | 785 | } |
| 714 | #endif | 786 | #endif |
| 787 | #if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE | ||
| 788 | vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | ||
| 789 | if (vendor && !strcmp(vendor, "FUJITSU SIEMENS")) | ||
| 790 | dmi_walk(dmi_check_onboard_devices, &i801_adapter); | ||
| 791 | #endif | ||
| 715 | 792 | ||
| 716 | return 0; | 793 | return 0; |
| 717 | 794 | ||
