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 | ||