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