xref: /linux/include/linux/i2c-atr.h (revision 883e3c9f40814377a239ca0becbcc77deab5ffe5)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * I2C Address Translator
4  *
5  * Copyright (c) 2019,2022 Luca Ceresoli <luca@lucaceresoli.net>
6  * Copyright (c) 2022,2023 Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
7  *
8  * Based on i2c-mux.h
9  */
10 
11 #ifndef _LINUX_I2C_ATR_H
12 #define _LINUX_I2C_ATR_H
13 
14 #include <linux/i2c.h>
15 #include <linux/types.h>
16 
17 struct device;
18 struct fwnode_handle;
19 struct i2c_atr;
20 
21 /**
22  * enum i2c_atr_flags - Flags for an I2C ATR driver
23  *
24  * @I2C_ATR_F_STATIC: ATR does not support dynamic mapping, use static mapping.
25  *                    Mappings will only be added or removed as a result of
26  *                    devices being added or removed from a child bus.
27  *                    The ATR pool will have to be big enough to accomodate all
28  *                    devices expected to be added to the child buses.
29  * @I2C_ATR_F_PASSTHROUGH: Allow unmapped incoming addresses to pass through
30  */
31 enum i2c_atr_flags {
32 	I2C_ATR_F_STATIC = BIT(0),
33 	I2C_ATR_F_PASSTHROUGH = BIT(1),
34 };
35 
36 /**
37  * struct i2c_atr_ops - Callbacks from ATR to the device driver.
38  * @attach_addr: Notify the driver of a new device connected on a child
39  *               bus, with the alias assigned to it. The driver must
40  *               configure the hardware to use the alias.
41  * @detach_addr: Notify the driver of a device getting disconnected. The
42  *               driver must configure the hardware to stop using the
43  *               alias.
44  *
45  * All these functions return 0 on success, a negative error code otherwise.
46  */
47 struct i2c_atr_ops {
48 	int (*attach_addr)(struct i2c_atr *atr, u32 chan_id,
49 			   u16 addr, u16 alias);
50 	void (*detach_addr)(struct i2c_atr *atr, u32 chan_id,
51 			    u16 addr);
52 };
53 
54 /**
55  * struct i2c_atr_adap_desc - An ATR downstream bus descriptor
56  * @chan_id:        Index of the new adapter (0 .. max_adapters-1).  This value is
57  *                  passed to the callbacks in `struct i2c_atr_ops`.
58  * @parent:         The device used as the parent of the new i2c adapter, or NULL
59  *                  to use the i2c-atr device as the parent.
60  * @bus_handle:     The fwnode handle that points to the adapter's i2c
61  *                  peripherals, or NULL.
62  * @num_aliases:    The number of aliases in this adapter's private alias pool. Set
63  *                  to zero if this adapter uses the ATR's global alias pool.
64  * @aliases:        An optional array of private aliases used by the adapter
65  *                  instead of the ATR's global pool of aliases. Must contain
66  *                  exactly num_aliases entries if num_aliases > 0, is ignored
67  *                  otherwise.
68  */
69 struct i2c_atr_adap_desc {
70 	u32 chan_id;
71 	struct device *parent;
72 	struct fwnode_handle *bus_handle;
73 	size_t num_aliases;
74 	u16 *aliases;
75 };
76 
77 /**
78  * i2c_atr_new() - Allocate and initialize an I2C ATR helper.
79  * @parent:       The parent (upstream) adapter
80  * @dev:          The device acting as an ATR
81  * @ops:          Driver-specific callbacks
82  * @max_adapters: Maximum number of child adapters
83  * @flags:        Flags for ATR
84  *
85  * The new ATR helper is connected to the parent adapter but has no child
86  * adapters. Call i2c_atr_add_adapter() to add some.
87  *
88  * Call i2c_atr_delete() to remove.
89  *
90  * Return: pointer to the new ATR helper object, or ERR_PTR
91  */
92 struct i2c_atr *i2c_atr_new(struct i2c_adapter *parent, struct device *dev,
93 			    const struct i2c_atr_ops *ops, int max_adapters,
94 			    u32 flags);
95 
96 /**
97  * i2c_atr_delete - Delete an I2C ATR helper.
98  * @atr: I2C ATR helper to be deleted.
99  *
100  * Precondition: all the adapters added with i2c_atr_add_adapter() must be
101  * removed by calling i2c_atr_del_adapter().
102  */
103 void i2c_atr_delete(struct i2c_atr *atr);
104 
105 /**
106  * i2c_atr_add_adapter - Create a child ("downstream") I2C bus.
107  * @atr:        The I2C ATR
108  * @desc:       An ATR adapter descriptor
109  *
110  * After calling this function a new i2c bus will appear. Adding and removing
111  * devices on the downstream bus will result in calls to the
112  * &i2c_atr_ops->attach_client and &i2c_atr_ops->detach_client callbacks for the
113  * driver to assign an alias to the device.
114  *
115  * The adapter's fwnode is set to @bus_handle, or if @bus_handle is NULL the
116  * function looks for a child node whose 'reg' property matches the chan_id
117  * under the i2c-atr device's 'i2c-atr' node.
118  *
119  * Call i2c_atr_del_adapter() to remove the adapter.
120  *
121  * Return: 0 on success, a negative error code otherwise.
122  */
123 int i2c_atr_add_adapter(struct i2c_atr *atr, struct i2c_atr_adap_desc *desc);
124 
125 /**
126  * i2c_atr_del_adapter - Remove a child ("downstream") I2C bus added by
127  *                       i2c_atr_add_adapter(). If no I2C bus has been added
128  *                       this function is a no-op.
129  * @atr:     The I2C ATR
130  * @chan_id: Index of the adapter to be removed (0 .. max_adapters-1)
131  */
132 void i2c_atr_del_adapter(struct i2c_atr *atr, u32 chan_id);
133 
134 /**
135  * i2c_atr_set_driver_data - Set private driver data to the i2c-atr instance.
136  * @atr:  The I2C ATR
137  * @data: Pointer to the data to store
138  */
139 void i2c_atr_set_driver_data(struct i2c_atr *atr, void *data);
140 
141 /**
142  * i2c_atr_get_driver_data - Get the stored drive data.
143  * @atr:     The I2C ATR
144  *
145  * Return: Pointer to the stored data
146  */
147 void *i2c_atr_get_driver_data(struct i2c_atr *atr);
148 
149 #endif /* _LINUX_I2C_ATR_H */
150