Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Back-port I2C ATR (Address translator) #2536

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions Documentation/i2c/i2c-address-translators.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.. SPDX-License-Identifier: GPL-2.0

=======================
I2C Address Translators
=======================

Author: Luca Ceresoli <[email protected]>
Author: Tomi Valkeinen <[email protected]>

Description
-----------

An I2C Address Translator (ATR) is a device with an I2C slave parent
("upstream") port and N I2C master child ("downstream") ports, and
forwards transactions from upstream to the appropriate downstream port
with a modified slave address. The address used on the parent bus is
called the "alias" and is (potentially) different from the physical
slave address of the child bus. Address translation is done by the
hardware.

An ATR looks similar to an i2c-mux except:
- the address on the parent and child busses can be different
- there is normally no need to select the child port; the alias used on the
parent bus implies it

The ATR functionality can be provided by a chip with many other features.
The kernel i2c-atr provides a helper to implement an ATR within a driver.

The ATR creates a new I2C "child" adapter on each child bus. Adding
devices on the child bus ends up in invoking the driver code to select
an available alias. Maintaining an appropriate pool of available aliases
and picking one for each new device is up to the driver implementer. The
ATR maintains a table of currently assigned alias and uses it to modify
all I2C transactions directed to devices on the child buses.

A typical example follows.

Topology::

Slave X @ 0x10
.-----. |
.-----. | |---+---- B
| CPU |--A--| ATR |
`-----' | |---+---- C
`-----' |
Slave Y @ 0x10

Alias table:

A, B and C are three physical I2C busses, electrically independent from
each other. The ATR receives the transactions initiated on bus A and
propagates them on bus B or bus C or none depending on the device address
in the transaction and based on the alias table.

Alias table:

.. table::

=============== =====
Client Alias
=============== =====
X (bus B, 0x10) 0x20
Y (bus C, 0x10) 0x30
=============== =====

Transaction:

- Slave X driver requests a transaction (on adapter B), slave address 0x10
- ATR driver finds slave X is on bus B and has alias 0x20, rewrites
messages with address 0x20, forwards to adapter A
- Physical I2C transaction on bus A, slave address 0x20
- ATR chip detects transaction on address 0x20, finds it in table,
propagates transaction on bus B with address translated to 0x10,
keeps clock streched on bus A waiting for reply
- Slave X chip (on bus B) detects transaction at its own physical
address 0x10 and replies normally
- ATR chip stops clock stretching and forwards reply on bus A,
with address translated back to 0x20
- ATR driver receives the reply, rewrites messages with address 0x10
as they were initially
- Slave X driver gets back the msgs[], with reply and address 0x10

Usage:

1. In the driver (typically in the probe function) add an ATR by
calling i2c_atr_new() passing attach/detach callbacks
2. When the attach callback is called pick an appropriate alias,
configure it in the chip and return the chosen alias in the
alias_id parameter
3. When the detach callback is called, deconfigure the alias from
the chip and put the alias back in the pool for later usage

I2C ATR functions and data structures
-------------------------------------

.. kernel-doc:: include/linux/i2c-atr.h
1 change: 1 addition & 0 deletions Documentation/i2c/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Introduction
i2c-topology
muxes/i2c-mux-gpio
i2c-sysfs
i2c-address-translators

Writing device drivers
======================
Expand Down
8 changes: 8 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -9667,6 +9667,14 @@ L: [email protected]
S: Maintained
F: drivers/i2c/i2c-core-acpi.c

I2C ADDRESS TRANSLATOR (ATR)
M: Tomi Valkeinen <[email protected]>
R: Luca Ceresoli <[email protected]>
L: [email protected]
S: Maintained
F: drivers/i2c/i2c-atr.c
F: include/linux/i2c-atr.h

I2C CONTROLLER DRIVER FOR NVIDIA GPU
M: Ajay Gupta <[email protected]>
L: [email protected]
Expand Down
9 changes: 9 additions & 0 deletions drivers/i2c/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ config I2C_MUX

source "drivers/i2c/muxes/Kconfig"

config I2C_ATR
tristate "I2C Address Translator (ATR) support"
help
Enable support for I2C Address Translator (ATR) chips.

An ATR allows accessing multiple I2C busses from a single
physical bus via address translation instead of bus selection as
i2c-muxes do.

config I2C_HELPER_AUTO
bool "Autoselect pertinent helper modules"
default y
Expand Down
1 change: 1 addition & 0 deletions drivers/i2c/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ i2c-core-$(CONFIG_OF) += i2c-core-of.o
obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o
obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
obj-$(CONFIG_I2C_MUX) += i2c-mux.o
obj-$(CONFIG_I2C_ATR) += i2c-atr.o
obj-y += algos/ busses/ muxes/
obj-$(CONFIG_I2C_STUB) += i2c-stub.o
obj-$(CONFIG_I2C_SLAVE_EEPROM) += i2c-slave-eeprom.o
Expand Down
Loading
Loading