2017-09-07 6 views
1

Auf meiner x86_64-Platine kommt der i2c-Bus aus einem MFD-Gerät. Auf diesem i2c-Bus befinden sich Geräte. Ich kann diese Geräte mit dem i2cdetect-Programm erkennen.Hinzufügen von i2c-Client-Geräten auf x86_64

# i2cdetect -y 0 
    0 1 2 3 4 5 6 7 8 9 a b c d e f 
00:   -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- 4c -- -- -- 
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --       

brauche ich den Kernel diese Geräte automatisch zu erkennen, also habe ich versucht, das Schreiben i2c_board_info wie unten Code in gegeben, aber immer noch der Kern ist nicht in der Lage, diese Geräte automatisch zu erkennen.

#include <linux/init.h> 
#include <linux/i2c.h> 

#define BUS_NUMBER  0 

static struct __init i2c_board_info tst_i2c0_board_info[] = {     
    { 
     I2C_BOARD_INFO("ltc2990", 0x4c), 
    }, 
    { 
     I2C_BOARD_INFO("24c128", 0x57), 
    }, 
}; 

static int tst_i2c_board_setup(void) 
{ 
    int ret=-1; 
    ret = i2c_register_board_info(BUS_NUMBER, tst_i2c0_board_info, ARRAY_SIZE(tst_i2c0_board_info)); 
    return ret; 
} 
device_initcall(tst_i2c_board_setup); 

Irgendwelche Vorschläge, wie kann ich das lösen?

+0

wird tst_i2c_board_setup() nach I2C-Bus 0-Registrierung aufgerufen – Ash

+1

@Ash Ich habe für beide Szenarien testen, dh vor und nach Bus 0 Anmeldung aufrufen; indem Sie device_initcall in arch_initcall ändern. Es hilft nicht – rk1825

+2

Sie müssen ACPI dafür verwenden. Ich würde dies mit Beispielen nach meinem Urlaub beantworten, für jetzt google für * meta-acpi * Projekt auf Github, um die ursprüngliche Idee zu bekommen. – 0andriy

Antwort

1

Da Sie eine ACPI-fähige Plattform haben, ist der beste Ansatz, die ASL-Auszüge für bestimmte Geräte bereitzustellen.

Aufgrund der Intel Galileo-Plattform für das Internet der Dinge die Atmel 24 Serie EEPROM seine eigene ACPI-ID und ein Auszug einfach sein wird erhalten hat:

DefinitionBlock ("at24.aml", "SSDT", 5, "", "AT24", 1) 
{ 
    External (_SB_.PCI0.I2C2, DeviceObj) 

    Scope (\_SB.PCI0.I2C2) 
    { 
     Device (EEP0) { 
      Name (_HID, "INT3499") 
      Name (_DDN, "Atmel AT24 compatible EEPROM") 
      Name (_CRS, ResourceTemplate() { 
       I2cSerialBusV2 (
        0x0057,    // I2C Slave Address 
        ControllerInitiated, 
        400000,    // Bus speed 
        AddressingMode7Bit, 
        "\\_SB.PCI0.I2C2", // Link to ACPI I2C host controller 
        0 
       ) 
      }) 

      Name (_DSD, Package() { 
       ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 
       Package() { 
        Package() {"size", 1024}, 
        Package() {"pagesize", 32}, 
       } 
      }) 
     } 
    } 
} 

Hinweis, die Größe Eigenschaft hinzugefügt wird in einer pending patch series Serie (Patches dt-bindings: add eeprom "size" property und eeprom: at24: add support to fetch eeprom device property "size").

Hinweis, die Adressbreite ist 8-Bit, wie fest codiert. Wenn Sie 16-Bit benötigen, müssen Sie ähnliche Patches wie oben erwähnt erstellen.

Für LTC2990 Leistungsmonitor Sie den folgenden Auszug benötigen:

DefinitionBlock ("ltc2990.aml", "SSDT", 5, "", "PMON", 1) 
{ 
    External (\_SB_.PCI0.I2C2, DeviceObj) 

    Scope (\_SB.PCI0.I2C2) 
    { 
     Device (PMON) 
     { 
      Name (_HID, "PRP0001") 
      Name (_DDN, "Linear Technology LTC2990 power monitor") 
      Name (_CRS, ResourceTemplate() { 
       I2cSerialBus (
        0x4c,     // Bus address 
        ControllerInitiated, // Don't care 
        400000,     // Fast mode (400 kHz) 
        AddressingMode7Bit,  // 7-bit addressing 
        "\\_SB.PCI0.I2C2",  // I2C host controller 
        0      // Must be 0 
       ) 
      }) 

      Name (_DSD, Package() { 
       ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 
       Package() { 
        Package() {"compatible", "lltc,ltc2990"}, 
       } 
      }) 
     } 
    } 
} 

Hinweis, leider gibt es keine kompatiblen Zeichenfolge im Treiber, so muss man es wie it's done here hinzuzufügen.

In den obigen Beispielen ist \\_SB.PCI0.I2C2 ein absoluter Pfad zum I2C-Host-Controller.

Wie diese Dateien angewendet werden:

  • aller ersten,
mkdir -p kernel/firmware/acpi 
  • speichern Dateien unter den Namen erwähnt im DefinitionBlock() Makro in diesem Ordner
  • einen Ordner erstellen Erstellen Sie das unkomprimierte CPIO-Archiv und verketten Sie die ursprüngliche initrd oben:
find kernel | cpio -H newc --create > /boot/instrumented_initrd 
cat /boot/initrd >> /boot/instrumented_initrd 

Weitere Details sind in ssdt-overlays.txt verfügbar.

Die anderen Beispiele und Beschreibung der Idee dahinter finden Sie unter meta-acpi GitHub page, einige Materialien, von denen hier kopiert werden.

0

Nachdem man durch Documentation/i2c/instantiating-devices, ich verstehe, gibt es mehrere Methoden, das gleiche zu tun (z. Als 0andriy usng acpi Tisch vorgeschlagen usw.), I „i2c_new_probed_device“ -Methode verwendet. Unten ist der verwendete Code:

#include <linux/init.h> 
#include <linux/i2c.h> 

#define BUS_NUMBER  0 
#define NUM_DEVICE  2 

static const unsigned short normal_i2c[][2] = { 
    {0x4c, I2C_CLIENT_END}, 
    {0x57, I2C_CLIENT_END}, 
}; 

static struct i2c_board_info tst_i2c0_board_info[2] = { 
     {I2C_BOARD_INFO("ltc2990", 0x4c), }, 
     {I2C_BOARD_INFO("24c128", 0x57), }, 
}; 

static int tst_i2c_board_setup(void) 
{ 
    int i = 0; 
    struct i2c_adapter *i2c_adap; 

    i2c_adap = i2c_get_adapter(BUS_NUMBER); 
    for(i = 0; i < NUM_DEVICE; i++) 
     i2c_new_probed_device(i2c_adap, &tst_i2c0_board_info[i], 
          normal_i2c[i], NULL); 
    i2c_put_adapter(i2c_adap); 

    return 0; 
} 
late_initcall(tst_i2c_board_setup); 
+2

Während es funktioniert, ist dies ein Missbrauch von ACPI-fähigen Plattformen. – 0andriy

+1

Ich stimme zu, das ist in Eile behoben. Ich werde ACPI-basierte Methode verwenden. – rk1825

Verwandte Themen