Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
836 views
in Technique[技术] by (71.8m points)

ubuntu - Building a i2c device controller

I am building a PCB that will communicate via a i2c bus with a UDOO x86 running ubuntu 18.04 with two accesible i2c buses and multiple GPIO

the device has 3 i2c chips on it i2c-mux-pca954x

  • PCA9543 - level shifting bus switch
  • SC18IS602B - i2c to SPI Bus master
  • SC16IS741A - i2c to uart

each of which has a kernel driver module(i2c-mux-pca954x,spi-sc18is602,sc16is7xx)

both the SC18IS602B and SC16IS741A are connected to one channel of the PCA9543 and corresponding interrupt. the second channel for additional devices yet to be specified.

the SPI bus connects to a 4 TPS92518HV-Q1 (programmable dual current drivers) the UART connects to 8 TPS92662-Q1 (Led Matrix Controllers) (It uses a addressed form of uart that looks similar to RS-485 but im not familiar enough to be sure)

the UDOO x86 is initially just standard Ubuntu server 18.04.2 and has no device tree.

I am not very familiar with this and am not sure where to start.

I now i need to somehow specify the i2c addresses of the 3 chips and the GPIO that the interrupt from the PCA9543 is connected.

Then i think i need to produce a combined "driver" for the combination that encapsulates the individual i2c chip drivers plus the current drivers and led matrix controllers.

i believe i can in theory use acpi to do this (https://www.kernel.org/doc/Documentation/acpi/enumeration.txt)

can anyone give me a rough outline and/or examples of how to go about this

--

using a combination of

i have the following rough template

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

Though i don't think this is entirely correct and is missing the GPIO Interrupt from the PCA9543, and im not sure how to define the SPI and UART bus provided by the SC18IS602B and the SC16IS741A (or the TPS92518HV-Q1 and TPS92662-Q1 assuming they had drivers)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Nice you choose the correct way of solving this up! Now, to the question.

First of all, let me describe the schematic of what you have how I understand it (correct me if I'm wrong).

                                         I2C
+-------------+          +------------+  bus   +-----------+
|             |          |            +-------->           |
|             |          |            <--------+ Some chip |
|             |   I2C    |            |        |           |
|    HOST     |   bus    |            |        +-----------+
|  UDOO X86   +---------->   PCA9543  |
|             <----------+     I2C    |  I2C
|             |          |    switch  |  bus   +-----------+
|             |          |            +-----+-->           |
|  GPIO IRQ   +<---------+            <--+-----+ SC16IS741A|
|             |          |            |  |  |  |           |
+-------------+          +------------+  |  |  +-----------+
                                         |  |
                                         |  |  +-----------+
                                         |  +-->           |
                                         +-----+ SC18IS602B|
                                               |           |
                                               +-----------+

It's a bit more complicated than the usual case when all devices are sitting on the same bus, but let's go with it.

Consider your ACPI excerpt the mistakes I see:

  • The identifiers in ACPI are only 4 characters long: CLI1A, CLI1B, etc are wrong names
  • The device SMB1 is not needed. What did you try to put there?
  • The _HID for the devices that are not yet have a properly allocated ACPI IDs must be PRP0001 (Note Revert "Add ACPI support for pca954x" as well)
  • The MUX chip compatible is pca9543 as you stated
  • ASL reference objects either pathes or references (in a format of <LEVEL_UP>, where <LEVEL_UP> is exact amount of '^' characters to which level you want go up followed by 4 characters object ). This is described by chapter 5.3 of the specification. Though, for I2cSerialBusV2() type of resources, the ResourceSource field is supposed to be a string with a reference
  • UPDATE Just noticed that you have two devices on the same bus with the same address, it wouldn't work, so, I fixed the address of I2C-to-Serial converted to be the same as in excerpt I below have referred to.

Now let look at it after fixing the issues.

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

Disclaimer: I have never dealt with I2C muxes in my life, so, above still may contain uncertainties.

Now consider the code of individual drivers as per Elixir.

I2C mux PCA954x. The driver, unfortunately, is OF-centric and should be slightly patched to get it working in ACPI-based environments.

As an example, you may look at Make use of device properties which is now part of upstream kernel.

Similar applies to the rest of the drivers you need.

Fortunately for you, someone earlier had an interest in I2C-to-Serial convertor support, thus the patch series (not yet applied will be part of new kernel soon) had been published with a corresponding ASL excerpt.

The latter code has an example of the device with GPIO IRQ in use.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...