Skip to content

Commit a076a86

Browse files
lucaceresolimchehab
authored andcommitted
media: i2c: add I2C Address Translator (ATR) support
An ATR is a device that looks similar to an i2c-mux: it has an I2C slave "upstream" port and N master "downstream" ports, and forwards transactions from upstream to the appropriate downstream port. But it is different in that the forwarded transaction has a different slave address. The address used on the upstream bus is called the "alias" and is (potentially) different from the physical slave address of the downstream chip. Add a helper file (just like i2c-mux.c for a mux or switch) to allow implementing ATR features in a device driver. The helper takes care of adapter creation/destruction and translates addresses at each transaction. Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Wolfram Sang <wsa@kernel.org> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
1 parent 86251cf commit a076a86

File tree

7 files changed

+941
-0
lines changed

7 files changed

+941
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
=======================
4+
I2C Address Translators
5+
=======================
6+
7+
Author: Luca Ceresoli <luca@lucaceresoli.net>
8+
Author: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
9+
10+
Description
11+
-----------
12+
13+
An I2C Address Translator (ATR) is a device with an I2C slave parent
14+
("upstream") port and N I2C master child ("downstream") ports, and
15+
forwards transactions from upstream to the appropriate downstream port
16+
with a modified slave address. The address used on the parent bus is
17+
called the "alias" and is (potentially) different from the physical
18+
slave address of the child bus. Address translation is done by the
19+
hardware.
20+
21+
An ATR looks similar to an i2c-mux except:
22+
- the address on the parent and child busses can be different
23+
- there is normally no need to select the child port; the alias used on the
24+
parent bus implies it
25+
26+
The ATR functionality can be provided by a chip with many other features.
27+
The kernel i2c-atr provides a helper to implement an ATR within a driver.
28+
29+
The ATR creates a new I2C "child" adapter on each child bus. Adding
30+
devices on the child bus ends up in invoking the driver code to select
31+
an available alias. Maintaining an appropriate pool of available aliases
32+
and picking one for each new device is up to the driver implementer. The
33+
ATR maintains a table of currently assigned alias and uses it to modify
34+
all I2C transactions directed to devices on the child buses.
35+
36+
A typical example follows.
37+
38+
Topology::
39+
40+
Slave X @ 0x10
41+
.-----. |
42+
.-----. | |---+---- B
43+
| CPU |--A--| ATR |
44+
`-----' | |---+---- C
45+
`-----' |
46+
Slave Y @ 0x10
47+
48+
Alias table:
49+
50+
A, B and C are three physical I2C busses, electrically independent from
51+
each other. The ATR receives the transactions initiated on bus A and
52+
propagates them on bus B or bus C or none depending on the device address
53+
in the transaction and based on the alias table.
54+
55+
Alias table:
56+
57+
.. table::
58+
59+
=============== =====
60+
Client Alias
61+
=============== =====
62+
X (bus B, 0x10) 0x20
63+
Y (bus C, 0x10) 0x30
64+
=============== =====
65+
66+
Transaction:
67+
68+
- Slave X driver requests a transaction (on adapter B), slave address 0x10
69+
- ATR driver finds slave X is on bus B and has alias 0x20, rewrites
70+
messages with address 0x20, forwards to adapter A
71+
- Physical I2C transaction on bus A, slave address 0x20
72+
- ATR chip detects transaction on address 0x20, finds it in table,
73+
propagates transaction on bus B with address translated to 0x10,
74+
keeps clock streched on bus A waiting for reply
75+
- Slave X chip (on bus B) detects transaction at its own physical
76+
address 0x10 and replies normally
77+
- ATR chip stops clock stretching and forwards reply on bus A,
78+
with address translated back to 0x20
79+
- ATR driver receives the reply, rewrites messages with address 0x10
80+
as they were initially
81+
- Slave X driver gets back the msgs[], with reply and address 0x10
82+
83+
Usage:
84+
85+
1. In the driver (typically in the probe function) add an ATR by
86+
calling i2c_atr_new() passing attach/detach callbacks
87+
2. When the attach callback is called pick an appropriate alias,
88+
configure it in the chip and return the chosen alias in the
89+
alias_id parameter
90+
3. When the detach callback is called, deconfigure the alias from
91+
the chip and put the alias back in the pool for later usage
92+
93+
I2C ATR functions and data structures
94+
-------------------------------------
95+
96+
.. kernel-doc:: include/linux/i2c-atr.h

Documentation/i2c/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Introduction
1818
i2c-topology
1919
muxes/i2c-mux-gpio
2020
i2c-sysfs
21+
i2c-address-translators
2122

2223
Writing device drivers
2324
======================

MAINTAINERS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9670,6 +9670,14 @@ L: linux-acpi@vger.kernel.org
96709670
S: Maintained
96719671
F: drivers/i2c/i2c-core-acpi.c
96729672

9673+
I2C ADDRESS TRANSLATOR (ATR)
9674+
M: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
9675+
R: Luca Ceresoli <luca.ceresoli@bootlin.com>
9676+
L: linux-i2c@vger.kernel.org
9677+
S: Maintained
9678+
F: drivers/i2c/i2c-atr.c
9679+
F: include/linux/i2c-atr.h
9680+
96739681
I2C CONTROLLER DRIVER FOR NVIDIA GPU
96749682
M: Ajay Gupta <ajayg@nvidia.com>
96759683
L: linux-i2c@vger.kernel.org

drivers/i2c/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ config I2C_MUX
7171

7272
source "drivers/i2c/muxes/Kconfig"
7373

74+
config I2C_ATR
75+
tristate "I2C Address Translator (ATR) support"
76+
help
77+
Enable support for I2C Address Translator (ATR) chips.
78+
79+
An ATR allows accessing multiple I2C busses from a single
80+
physical bus via address translation instead of bus selection as
81+
i2c-muxes do.
82+
7483
config I2C_HELPER_AUTO
7584
bool "Autoselect pertinent helper modules"
7685
default y

drivers/i2c/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ i2c-core-$(CONFIG_OF) += i2c-core-of.o
1313
obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o
1414
obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
1515
obj-$(CONFIG_I2C_MUX) += i2c-mux.o
16+
obj-$(CONFIG_I2C_ATR) += i2c-atr.o
1617
obj-y += algos/ busses/ muxes/
1718
obj-$(CONFIG_I2C_STUB) += i2c-stub.o
1819
obj-$(CONFIG_I2C_SLAVE_EEPROM) += i2c-slave-eeprom.o

0 commit comments

Comments
 (0)