aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-03-30 15:46:44 -0400
committerJean Delvare <khali@linux-fr.org>2009-03-30 15:46:44 -0400
commitfa5bfab7128e58c31448fca83a288a86e7d476cc (patch)
treede05e1b02bed9414ebeab03f4ee15d6052c70017 /drivers/i2c/busses
parente7a19c5624c66afa8118b10cd59f87ee407646bc (diff)
i2c-i801: Instantiate FSC hardware montioring chips
Detect various FSC hwmon IC's based on DMI tables and then let the i2c-i801 driver instantiate the i2c client devices. Note that some of the info in the added table is indentical for all rows, still this is kept in the table to keep the code general and thus (hopefully) easily extensible in the future. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/busses')
-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