aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/i2c-i801.c77
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)
616static void __init input_apanel_init(void) {} 617static void __init input_apanel_init(void) {}
617#endif 618#endif
618 619
620#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
621struct dmi_onboard_device_info {
622 const char *name;
623 u8 type;
624 unsigned short i2c_addr;
625 const char *i2c_type;
626};
627
628static 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
634static 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 */
658static 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
619static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) 688static 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