我正在构建一个PCB,它将通过i2c总线与运行ubuntu 18.04的UDOO x86通信,带有两个可访问的i2c总线和多个GPIO
该设备上有3个i2c芯片i2c-mux-pca954x
每个都有一个内核驱动模块(i2c-mux-pca954x,spi-sc18is602,sc16is7xx)
SC18IS602B和SC16IS741A都连接到PCA9543的一个通道和相应的中断。尚未指定其他设备的第二个通道。
SPI总线连接到4个TPS92518HV-Q1(可编程双电流驱动器),UART连接到8个TPS92662-Q1(LED矩阵控制器)(它使用的寻址形式的uart看起来类似于RS-485但我不熟悉确定)
UDOO x86最初只是标准的Ubuntu服务器18.04.2,没有设备树。
我对此不太熟悉,不知道从哪里开始。
我现在需要以某种方式指定3个芯片的i2c地址和来自PCA9543的中断所连接的GPIO。
然后我想我需要为组合产生一个组合的“驱动器”,它封装了各个i2c芯片驱动器以及当前的驱动器和led矩阵控制器。
我相信我理论上可以使用acpi来做到这一点(https://www.kernel.org/doc/Documentation/acpi/enumeration.txt)
谁能给我一个粗略的轮廓和/或如何解决这个问题的例子
--
使用组合
我有以下粗略的模板
adding i2c client devices on x86_64
虽然我不认为这是完全正确的,并且缺少PCA9543的GPIO中断,但我不确定如何定义SC18IS602B和SC16IS741A(或TPS92518HV-Q1和TPS92662-Q1)提供的SPI和UART总线他们有司机)
很高兴你选择正确的解决方法!现在,问题。
首先,让我描述你如何理解它的原理图(如果我错了,请纠正我)。
https://www.kernel.org/doc/Documentation/acpi/i2c-muxes.txt
当所有设备都坐在同一条总线上时,它比通常的情况要复杂一些,但让我们继续使用它。
考虑你的ACPI摘录我看到的错误:
现在让我们在解决问题后再看一下。
DefinitionBlock ("fbsLedCon.aml", "SSDT", 5, "", "FBLEDC01", 1)
{
External (_SB_.PCI0.I2C0, DeviceObj) // Define Correct I2C controller
Scope (\_SB.PCI0.I2C0)
{
Device (SMB1)
{
Name (_HID, "FBLEDC01")
Device (MUX0)
{
Name (_HID, "PCA9542A")
Name (_DDN, "NXP PCA9542A I2C bus switch")
Name (_CRS, ResourceTemplate () {
I2cSerialBus (
0x70, // I2C Address
ControllerInitiated,
I2C_SPEED, // Bus Speed
AddressingMode7Bit,
"^SMB1",
0x00,
ResourceConsumer,,)
}
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "nxp,pca9542"},
}
})
Device (CH00)
{
Name (_ADR, 0)
}
Device (CH01)
{
Name (_ADR, 1)
Device (CLI1A)
{
Name (_HID, "SC18IS602B")
Name (_DDN, "NXP SC18IS602B i2c to SPI Bus master")
Name (_CRS, ResourceTemplate () {
I2cSerialBus (
0x50, //I2C Address
ControllerInitiated,
I2C_SPEED, //Bus Speed
AddressingMode7Bit,
"^CH01",
0x00,
ResourceConsumer,,)
}
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "nxp,sc18is602b"},
}
})
}
Device (CLI1B)
{
Name (_HID, "SC16IS741A")
Name (_DDN, "NXP SC16IS741A I2C to UART")
Name (_CRS, ResourceTemplate () {
I2cSerialBus (
0x50, //I2C Address
ControllerInitiated,
I2C_SPEED, //Bus Speed
AddressingMode7Bit,
"^CH01",
0x00,
ResourceConsumer,,)
}
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "nxp,sc16is741"},
}
})
}
}
}
}
}
}
免责声明:我一生中从未处理过I2C多路复用器,因此,上面仍然可能包含不确定性。
现在根据 I2C
+-------------+ +------------+ bus +-----------+
| | | +--------> |
| | | <--------+ Some chip |
| | I2C | | | |
| HOST | bus | | +-----------+
| UDOO X86 +----------> PCA9543 |
| <----------+ I2C | I2C
| | | switch | bus +-----------+
| | | +-----+--> |
| GPIO IRQ +<---------+ <--+-----+ SC16IS741A|
| | | | | | | |
+-------------+ +------------+ | | +-----------+
| |
| | +-----------+
| +--> |
+-----+ SC18IS602B|
| |
+-----------+
考虑各个驱动程序的代码。
I2C多路复用器PCA954x。不幸的是,驱动程序是以OF为中心的,应该稍加修补以使其在基于ACPI的环境中工作。
举个例子,你可以看看1。注意,你需要用相应的I2cSerialBusV2()
替换几乎每个#define I2C_SPEED 100000
DefinitionBlock ("fbsLedCon.aml", "SSDT", 5, "", "FBLEDC01", 1)
{
External (_SB_.PCI0.I2C0, DeviceObj) // Define Correct I2C controller
Scope (\_SB.PCI0.I2C0)
{
Device (MUX0)
{
Name (_HID, "PRP0001")
Name (_DDN, "NXP PCA9542A I2C bus switch")
Name (_CRS, ResourceTemplate () {
I2cSerialBus (
0x70, // I2C Address
ControllerInitiated,
I2C_SPEED, // Bus Speed
AddressingMode7Bit,
"\\_SB.PCI0.I2C0",
0x00,
ResourceConsumer,,)
}
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "nxp,pca9543"},
}
})
Device (CH00)
{
Name (_ADR, 0)
}
Device (CH01)
{
Name (_ADR, 1)
Device (I2SM)
{
Name (_HID, "PRP0001")
Name (_DDN, "NXP SC18IS602B i2c to SPI Bus master")
Name (_CRS, ResourceTemplate () {
I2cSerialBus (
0x50, //I2C Address
ControllerInitiated,
I2C_SPEED, //Bus Speed
AddressingMode7Bit,
"^CH01",
0x00,
ResourceConsumer,,)
}
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "nxp,sc18is602b"},
}
})
}
Device (I2UM)
{
Name (_HID, "PRP0001")
Name (_DDN, "NXP SC16IS741A I2C to UART")
Name (_CRS, ResourceTemplate () {
I2cSerialBus (
0x4d, //I2C Address
ControllerInitiated,
I2C_SPEED, //Bus Speed
AddressingMode7Bit,
"^CH01",
0x00,
ResourceConsumer,,)
}
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "nxp,sc16is741"},
}
})
}
}
}
}
}
API调用。
类似适用于您需要的其他驱动程序。
对你来说幸运的是,之前有人对I2C到串口转换器的支持感兴趣,因此Elixir( 尚未应用 将成为新内核的一部分)已发布与相应的this patch。
后一代码具有使用GPIO IRQ的设备的示例。