1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2015 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <i2c.h>
11 #include <dm/lists.h>
12 #include <dm/root.h>
13 
14 DECLARE_GLOBAL_DATA_PTR;
15 
16 /**
17  * struct i2c_mux: Information the uclass stores about an I2C mux
18  *
19  * @selected:	Currently selected mux, or -1 for none
20  * @i2c_bus: I2C bus to use for communcation
21  */
22 struct i2c_mux {
23 	int selected;
24 	struct udevice *i2c_bus;
25 };
26 
27 /**
28  * struct i2c_mux_bus: Information about each bus the mux controls
29  *
30  * @channel: Channel number used to select this bus
31  */
32 struct i2c_mux_bus {
33 	uint channel;
34 };
35 
36 /* Find out the mux channel number */
37 static int i2c_mux_child_post_bind(struct udevice *dev)
38 {
39 	struct i2c_mux_bus *plat = dev_get_parent_platdata(dev);
40 	int channel;
41 
42 	channel = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
43 	if (channel < 0)
44 		return -EINVAL;
45 	plat->channel = channel;
46 
47 	return 0;
48 }
49 
50 /* Find the I2C buses selected by this mux */
51 static int i2c_mux_post_bind(struct udevice *mux)
52 {
53 	ofnode node;
54 	int ret;
55 
56 	debug("%s: %s\n", __func__, mux->name);
57 	/*
58 	 * There is no compatible string in the sub-nodes, so we must manually
59 	 * bind these
60 	 */
61 	dev_for_each_subnode(node, mux) {
62 		struct udevice *dev;
63 		const char *name;
64 
65 		name = ofnode_get_name(node);
66 		ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", name,
67 						 node, &dev);
68 		debug("   - bind ret=%d, %s\n", ret, dev ? dev->name : NULL);
69 		if (ret)
70 			return ret;
71 	}
72 
73 	return 0;
74 }
75 
76 /* Set up the mux ready for use */
77 static int i2c_mux_post_probe(struct udevice *mux)
78 {
79 	struct i2c_mux *priv = dev_get_uclass_priv(mux);
80 	int ret;
81 
82 	debug("%s: %s\n", __func__, mux->name);
83 	priv->selected = -1;
84 
85 	/* if parent is of i2c uclass already, we'll take that, otherwise
86 	 * look if we find an i2c-parent phandle
87 	 */
88 	if (UCLASS_I2C == device_get_uclass_id(mux->parent)) {
89 		priv->i2c_bus = dev_get_parent(mux);
90 		debug("%s: bus=%p/%s\n", __func__, priv->i2c_bus,
91 		      priv->i2c_bus->name);
92 		return 0;
93 	}
94 
95 	ret = uclass_get_device_by_phandle(UCLASS_I2C, mux, "i2c-parent",
96 					   &priv->i2c_bus);
97 	if (ret)
98 		return ret;
99 	debug("%s: bus=%p/%s\n", __func__, priv->i2c_bus, priv->i2c_bus->name);
100 
101 	return 0;
102 }
103 
104 int i2c_mux_select(struct udevice *dev)
105 {
106 	struct i2c_mux_bus *plat = dev_get_parent_platdata(dev);
107 	struct udevice *mux = dev->parent;
108 	struct i2c_mux_ops *ops = i2c_mux_get_ops(mux);
109 
110 	if (!ops->select)
111 		return -ENOSYS;
112 
113 	return ops->select(mux, dev, plat->channel);
114 }
115 
116 int i2c_mux_deselect(struct udevice *dev)
117 {
118 	struct i2c_mux_bus *plat = dev_get_parent_platdata(dev);
119 	struct udevice *mux = dev->parent;
120 	struct i2c_mux_ops *ops = i2c_mux_get_ops(mux);
121 
122 	if (!ops->deselect)
123 		return -ENOSYS;
124 
125 	return ops->deselect(mux, dev, plat->channel);
126 }
127 
128 static int i2c_mux_bus_set_bus_speed(struct udevice *dev, unsigned int speed)
129 {
130 	struct udevice *mux = dev->parent;
131 	struct i2c_mux *priv = dev_get_uclass_priv(mux);
132 	int ret, ret2;
133 
134 	ret = i2c_mux_select(dev);
135 	if (ret)
136 		return ret;
137 	ret = dm_i2c_set_bus_speed(priv->i2c_bus, speed);
138 	ret2 = i2c_mux_deselect(dev);
139 
140 	return ret ? ret : ret2;
141 }
142 
143 static int i2c_mux_bus_probe(struct udevice *dev, uint chip_addr,
144 			     uint chip_flags)
145 {
146 	struct udevice *mux = dev->parent;
147 	struct i2c_mux *priv = dev_get_uclass_priv(mux);
148 	struct dm_i2c_ops *ops = i2c_get_ops(priv->i2c_bus);
149 	int ret, ret2;
150 
151 	debug("%s: %s, bus %s\n", __func__, dev->name, priv->i2c_bus->name);
152 	if (!ops->probe_chip)
153 		return -ENOSYS;
154 	ret = i2c_mux_select(dev);
155 	if (ret)
156 		return ret;
157 	ret = ops->probe_chip(priv->i2c_bus, chip_addr, chip_flags);
158 	ret2 = i2c_mux_deselect(dev);
159 
160 	return ret ? ret : ret2;
161 }
162 
163 static int i2c_mux_bus_xfer(struct udevice *dev, struct i2c_msg *msg,
164 			    int nmsgs)
165 {
166 	struct udevice *mux = dev->parent;
167 	struct i2c_mux *priv = dev_get_uclass_priv(mux);
168 	struct dm_i2c_ops *ops = i2c_get_ops(priv->i2c_bus);
169 	int ret, ret2;
170 
171 	debug("%s: %s, bus %s\n", __func__, dev->name, priv->i2c_bus->name);
172 	if (!ops->xfer)
173 		return -ENOSYS;
174 	ret = i2c_mux_select(dev);
175 	if (ret)
176 		return ret;
177 	ret = ops->xfer(priv->i2c_bus, msg, nmsgs);
178 	ret2 = i2c_mux_deselect(dev);
179 
180 	return ret ? ret : ret2;
181 }
182 
183 static const struct dm_i2c_ops i2c_mux_bus_ops = {
184 	.xfer		= i2c_mux_bus_xfer,
185 	.probe_chip	= i2c_mux_bus_probe,
186 	.set_bus_speed	= i2c_mux_bus_set_bus_speed,
187 };
188 
189 U_BOOT_DRIVER(i2c_mux_bus) = {
190 	.name		= "i2c_mux_bus_drv",
191 	.id		= UCLASS_I2C,
192 	.ops	= &i2c_mux_bus_ops,
193 };
194 
195 UCLASS_DRIVER(i2c_mux) = {
196 	.id		= UCLASS_I2C_MUX,
197 	.name		= "i2c_mux",
198 	.post_bind	= i2c_mux_post_bind,
199 	.post_probe	= i2c_mux_post_probe,
200 	.per_device_auto_alloc_size = sizeof(struct i2c_mux),
201 	.per_child_platdata_auto_alloc_size = sizeof(struct i2c_mux_bus),
202 	.child_post_bind = i2c_mux_child_post_bind,
203 };
204