2017-09-07 22 views
1

私のx86_64ボードには、MFDデバイスからi2cバスが出ています。このi2cバスにはデバイスがあります。私はこれらのデバイスをi2cdetectプログラムを使って検出することができます。x86_64にi2cクライアントデバイスを追加する

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

私は、コードの下に与えられたのようにi2c_board_info書いてみましたが、それでも、カーネルが自動的にこれらのデバイスを検出することができない、自動的にこれらのデバイスを検出するために、カーネルが必要なので。

#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); 

どのように私はこれを解決できますか? Documentation/i2c/instantiating-devicesを通過した後

+0

I2Cバス0の登録後にtst_i2c_board_setup()が呼び出されます – Ash

+1

@Ash私は両方のシナリオ、つまりバス0の登録前と後の呼び出しをテストしました。 device_initcallをarch_initcallに変更します。それは助けません – rk1825

+2

あなたはそれのためにACPIを使用する必要があります。私は休暇後の例でこれに答えるでしょう、元のアイデアを得るためにGithubの* meta-acpi *プロジェクトのgoogleを使ってください。 – 0andriy

答えて

1

ACPI対応プラットフォームを使用しているため、最適な方法は特定のデバイスにASLの抜粋を提供することです。

ためのIoTインテルガリレオプラットフォームのアトメル24シリーズのEEPROMは、独自のACPIのIDを持っているとの抜粋は簡単になります。

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}, 
       } 
      }) 
     } 
    } 
} 

注意、サイズプロパティはpending patch seriesに追加されていますシリーズ(パッチdt-bindings: add eeprom "size" propertyおよびeeprom: at24: add support to fetch eeprom device property "size")。

注意してください。アドレスの幅は8ビットで、現在はハードコードされています。場合は、上記のように同様のパッチを作成する必要が16ビットを持っている必要があります。 LTC2990のパワーあなたは次の抜粋を必要とするモニター用

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"}, 
       } 
      }) 
     } 
    } 
} 

注意、残念ながら1はit's done hereのようにそれを追加する必要があり、そこにドライバには互換性のある文字列ではありませんので。

上記の例では、\\_SB.PCI0.I2C2は、I2Cホストコントローラへの絶対パスです。これらのファイルが適用されますする方法

  • まず、そのフォルダ
  • DefinitionBlock()マクロで述べた名前でフォルダのファイルの保存
mkdir -p kernel/firmware/acpi 
  • を作成圧縮されていないcpioアーカイブを作成し、元のinitrdを上に連結してください:
find kernel | cpio -H newc --create > /boot/instrumented_initrd 
cat /boot/initrd >> /boot/instrumented_initrd 

詳細はssdt-overlays.txtでご利用いただけます。

背後にあるアイデアの他の例と説明は、meta-acpi GitHub pageにあります。その一部の資料はここにコピーされています。

0

は、私は同じことを行うには、いくつかの方法があります理解して(例えば。0andriyは、ACPIテーブルなどをUSNG示唆したように)、私は「i2c_new_probed_device」メソッドを使用していました。使用されているコードは次のとおりです。

#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

動作している間、これはACPI対応プラットフォームの悪用です。 – 0andriy

+1

私は同意します、これは急いで固定されています。私はACPIベースの方法を使用します。 – rk1825

関連する問題