Then moved to industry where I worked on SCSI controller designs on FPGA, then at Xilinx (USA) worked on FPGA to ASIC conversions. I have significant RTL design/verification experience at Cisco (USA) while working on L3 switching ASICs for cat6K group. Since then managing technical teams at Freescale/NXP. Altium TechDocs are online documentation for Altium products, providing the basic information you need to get the most out of our tools. Discover features you didn't know existed and get the most out of those you already know about.
Unlike PCI or USB devices, I2C devices are not enumerated at the hardwarelevel. Instead, the software must know which devices are connected on eachI2C bus segment, and what address these devices are using. For thisreason, the kernel code must instantiate I2C devices explicitly. There areseveral ways to achieve this, depending on the context and requirements.
This method is appropriate when the I2C bus is a system bus as is the casefor many embedded systems. On such systems, each I2C bus has a number whichis known in advance. It is thus possible to pre-declare the I2C deviceswhich live on this bus.
This information is provided to the kernel in a different way on differentarchitectures: device tree, ACPI or board files.
When the I2C bus in question is registered, the I2C devices will beinstantiated automatically by i2c-core. The devices will be automaticallyunbound and destroyed when the I2C bus they sit on goes away (if ever).
On platforms using devicetree, the declaration of I2C devices is done insubnodes of the master controller.
Example:
Here, two devices are attached to the bus using a speed of 100kHz. Foradditional properties which might be needed to set up the device, please referto its devicetree documentation in Documentation/devicetree/bindings/.
ACPI can also describe I2C devices. There is special documentation for thiswhich is currently located at ACPI Based Device Enumeration.
In many embedded architectures, devicetree has replaced the old hardwaredescription based on board files, but the latter are still used in oldcode. Instantiating I2C devices via board files is done with an array ofstructi2c_board_info
which is registered by callingi2c_register_board_info()
.
Example (from omap2 h4):
The above code declares 3 devices on I2C bus 1, including their respectiveaddresses and custom data needed by their drivers.
This method is appropriate when a larger device uses an I2C bus forinternal communication. A typical case is TV adapters. These can have atuner, a video decoder, an audio decoder, etc. usually connected to themain chip by the means of an I2C bus. You won’t know the number of the I2Cbus in advance, so the method 1 described above can’t be used. Instead,you can instantiate your I2C devices explicitly. This is done by fillinga structi2c_board_info
and calling i2c_new_client_device()
.
Example (from the sfe4001 network driver):
The above code instantiates 1 I2C device on the I2C bus which is on thenetwork adapter in question.
A variant of this is when you don’t know for sure if an I2C device ispresent or not (for example for an optional feature which is not presenton cheap variants of a board but you have no way to tell them apart), orit may have different addresses from one board to the next (manufacturerchanging its design without notice). In this case, you can calli2c_new_scanned_device() instead of i2c_new_client_device()
.
Example (from the nxp OHCI driver):
The above code instantiates up to 1 I2C device on the I2C bus which is onthe OHCI adapter in question. It first tries at address 0x2c, if nothingis found there it tries address 0x2d, and if still nothing is found, itsimply gives up.
The driver which instantiated the I2C device is responsible for destroyingit on cleanup. This is done by calling i2c_unregister_device()
on thepointer that was earlier returned by i2c_new_client_device()
ori2c_new_scanned_device().
Sometimes you do not have enough information about an I2C device, not evento call i2c_new_scanned_device(). The typical case is hardware monitoringchips on PC mainboards. There are several dozen models, which can liveat 25 different addresses. Given the huge number of mainboards out there,it is next to impossible to build an exhaustive list of the hardwaremonitoring chips being used. Fortunately, most of these chips havemanufacturer and device ID registers, so they can be identified byprobing.
In that case, I2C devices are neither declared nor instantiatedexplicitly. Instead, i2c-core will probe for such devices as soon as theirdrivers are loaded, and if any is found, an I2C device will beinstantiated automatically. In order to prevent any misbehavior of thismechanism, the following restrictions apply:
Example:See lm90_driver and lm90_detect() in drivers/hwmon/lm90.c Samsung sound cards & media devices driver download for windows 10.
I2C devices instantiated as a result of such a successful probe will bedestroyed automatically when the driver which detected them is removed,or when the underlying I2C bus is itself destroyed, whichever happensfirst.
Those of you familiar with the I2C subsystem of 2.4 kernels and early 2.6kernels will find out that this method 3 is essentially similar to whatwas done there. Two significant differences are:
Once again, method 3 should be avoided wherever possible. Explicit deviceinstantiation (methods 1 and 2) is much preferred for it is safer andfaster.
In general, the kernel should know which I2C devices are connected andwhat addresses they live at. However, in certain cases, it does not, so asysfs interface was added to let the user provide the information. Thisinterface is made of 2 attribute files which are created in every I2C busdirectory: new_device
and delete_device
. Both files are writeonly and you must write the right parameters to them in order to properlyinstantiate, respectively delete, an I2C device.
File new_device
takes 2 parameters: the name of the I2C device (astring) and the address of the I2C device (a number, typically expressedin hexadecimal starting with 0x, but can also be expressed in decimal.)
File delete_device
takes a single parameter: the address of the I2Cdevice. As no two devices can live at the same address on a given I2Csegment, the address is sufficient to uniquely identify the device to bedeleted.
Example:
While this interface should only be used when in-kernel device declarationcan’t be done, there is a variety of cases where it can be helpful:
This interface is a replacement for the force_* module parameters some I2Cdrivers implement. Being implemented in i2c-core rather than in eachdevice driver individually, it is much more efficient, and also has theadvantage that you do not have to reload the driver to change a setting.You can also instantiate the device before the driver is loaded or evenavailable, and you don’t need to know what driver the device needs.