Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later 2 : : /* 3 : : * Linux I2C core OF support code 4 : : * 5 : : * Copyright (C) 2008 Jochen Friedrich <jochen@scram.de> 6 : : * based on a previous patch from Jon Smirl <jonsmirl@gmail.com> 7 : : * 8 : : * Copyright (C) 2013, 2018 Wolfram Sang <wsa@the-dreams.de> 9 : : */ 10 : : 11 : : #include <dt-bindings/i2c/i2c.h> 12 : : #include <linux/device.h> 13 : : #include <linux/err.h> 14 : : #include <linux/i2c.h> 15 : : #include <linux/module.h> 16 : : #include <linux/of.h> 17 : : #include <linux/of_device.h> 18 : : #include <linux/sysfs.h> 19 : : 20 : : #include "i2c-core.h" 21 : : 22 : 0 : int of_i2c_get_board_info(struct device *dev, struct device_node *node, 23 : : struct i2c_board_info *info) 24 : : { 25 : : u32 addr; 26 : : int ret; 27 : : 28 : 0 : memset(info, 0, sizeof(*info)); 29 : : 30 : 0 : if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { 31 : 0 : dev_err(dev, "of_i2c: modalias failure on %pOF\n", node); 32 : 0 : return -EINVAL; 33 : : } 34 : : 35 : : ret = of_property_read_u32(node, "reg", &addr); 36 : 0 : if (ret) { 37 : 0 : dev_err(dev, "of_i2c: invalid reg on %pOF\n", node); 38 : 0 : return ret; 39 : : } 40 : : 41 : 0 : if (addr & I2C_TEN_BIT_ADDRESS) { 42 : 0 : addr &= ~I2C_TEN_BIT_ADDRESS; 43 : 0 : info->flags |= I2C_CLIENT_TEN; 44 : : } 45 : : 46 : 0 : if (addr & I2C_OWN_SLAVE_ADDRESS) { 47 : 0 : addr &= ~I2C_OWN_SLAVE_ADDRESS; 48 : 0 : info->flags |= I2C_CLIENT_SLAVE; 49 : : } 50 : : 51 : 0 : info->addr = addr; 52 : 0 : info->of_node = node; 53 : : 54 : 0 : if (of_property_read_bool(node, "host-notify")) 55 : 0 : info->flags |= I2C_CLIENT_HOST_NOTIFY; 56 : : 57 : 0 : if (of_get_property(node, "wakeup-source", NULL)) 58 : 0 : info->flags |= I2C_CLIENT_WAKE; 59 : : 60 : : return 0; 61 : : } 62 : : EXPORT_SYMBOL_GPL(of_i2c_get_board_info); 63 : : 64 : 0 : static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, 65 : : struct device_node *node) 66 : : { 67 : : struct i2c_client *client; 68 : : struct i2c_board_info info; 69 : : int ret; 70 : : 71 : : dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node); 72 : : 73 : 0 : ret = of_i2c_get_board_info(&adap->dev, node, &info); 74 : 0 : if (ret) 75 : 0 : return ERR_PTR(ret); 76 : : 77 : 0 : client = i2c_new_device(adap, &info); 78 : 0 : if (!client) { 79 : 0 : dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node); 80 : 0 : return ERR_PTR(-EINVAL); 81 : : } 82 : : return client; 83 : : } 84 : : 85 : 0 : void of_i2c_register_devices(struct i2c_adapter *adap) 86 : : { 87 : : struct device_node *bus, *node; 88 : : struct i2c_client *client; 89 : : 90 : : /* Only register child devices if the adapter has a node pointer set */ 91 : 0 : if (!adap->dev.of_node) 92 : 0 : return; 93 : : 94 : : dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); 95 : : 96 : 0 : bus = of_get_child_by_name(adap->dev.of_node, "i2c-bus"); 97 : 0 : if (!bus) 98 : 0 : bus = of_node_get(adap->dev.of_node); 99 : : 100 : 0 : for_each_available_child_of_node(bus, node) { 101 : 0 : if (of_node_test_and_set_flag(node, OF_POPULATED)) 102 : 0 : continue; 103 : : 104 : 0 : client = of_i2c_register_device(adap, node); 105 : 0 : if (IS_ERR(client)) { 106 : 0 : dev_err(&adap->dev, 107 : : "Failed to create I2C device for %pOF\n", 108 : : node); 109 : : of_node_clear_flag(node, OF_POPULATED); 110 : : } 111 : : } 112 : : 113 : 0 : of_node_put(bus); 114 : : } 115 : : 116 : 0 : static int of_dev_or_parent_node_match(struct device *dev, const void *data) 117 : : { 118 : 0 : if (dev->of_node == data) 119 : : return 1; 120 : : 121 : 0 : if (dev->parent) 122 : 0 : return dev->parent->of_node == data; 123 : : 124 : : return 0; 125 : : } 126 : : 127 : : /* must call put_device() when done with returned i2c_client device */ 128 : 0 : struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) 129 : : { 130 : : struct device *dev; 131 : : struct i2c_client *client; 132 : : 133 : : dev = bus_find_device_by_of_node(&i2c_bus_type, node); 134 : 0 : if (!dev) 135 : : return NULL; 136 : : 137 : 0 : client = i2c_verify_client(dev); 138 : 0 : if (!client) 139 : 0 : put_device(dev); 140 : : 141 : 0 : return client; 142 : : } 143 : : EXPORT_SYMBOL(of_find_i2c_device_by_node); 144 : : 145 : : /* must call put_device() when done with returned i2c_adapter device */ 146 : 0 : struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) 147 : : { 148 : : struct device *dev; 149 : : struct i2c_adapter *adapter; 150 : : 151 : 0 : dev = bus_find_device(&i2c_bus_type, NULL, node, 152 : : of_dev_or_parent_node_match); 153 : 0 : if (!dev) 154 : : return NULL; 155 : : 156 : 0 : adapter = i2c_verify_adapter(dev); 157 : 0 : if (!adapter) 158 : 0 : put_device(dev); 159 : : 160 : 0 : return adapter; 161 : : } 162 : : EXPORT_SYMBOL(of_find_i2c_adapter_by_node); 163 : : 164 : : /* must call i2c_put_adapter() when done with returned i2c_adapter device */ 165 : 0 : struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node) 166 : : { 167 : : struct i2c_adapter *adapter; 168 : : 169 : 0 : adapter = of_find_i2c_adapter_by_node(node); 170 : 0 : if (!adapter) 171 : : return NULL; 172 : : 173 : 0 : if (!try_module_get(adapter->owner)) { 174 : 0 : put_device(&adapter->dev); 175 : : adapter = NULL; 176 : : } 177 : : 178 : 0 : return adapter; 179 : : } 180 : : EXPORT_SYMBOL(of_get_i2c_adapter_by_node); 181 : : 182 : : static const struct of_device_id* 183 : 0 : i2c_of_match_device_sysfs(const struct of_device_id *matches, 184 : : struct i2c_client *client) 185 : : { 186 : : const char *name; 187 : : 188 : 0 : for (; matches->compatible[0]; matches++) { 189 : : /* 190 : : * Adding devices through the i2c sysfs interface provides us 191 : : * a string to match which may be compatible with the device 192 : : * tree compatible strings, however with no actual of_node the 193 : : * of_match_device() will not match 194 : : */ 195 : 0 : if (sysfs_streq(client->name, matches->compatible)) 196 : 0 : return matches; 197 : : 198 : 0 : name = strchr(matches->compatible, ','); 199 : 0 : if (!name) 200 : : name = matches->compatible; 201 : : else 202 : 0 : name++; 203 : : 204 : 0 : if (sysfs_streq(client->name, name)) 205 : 0 : return matches; 206 : : } 207 : : 208 : : return NULL; 209 : : } 210 : : 211 : : const struct of_device_id 212 : 0 : *i2c_of_match_device(const struct of_device_id *matches, 213 : : struct i2c_client *client) 214 : : { 215 : : const struct of_device_id *match; 216 : : 217 : 0 : if (!(client && matches)) 218 : : return NULL; 219 : : 220 : 0 : match = of_match_device(matches, &client->dev); 221 : 0 : if (match) 222 : : return match; 223 : : 224 : 0 : return i2c_of_match_device_sysfs(matches, client); 225 : : } 226 : : EXPORT_SYMBOL_GPL(i2c_of_match_device); 227 : : 228 : : #if IS_ENABLED(CONFIG_OF_DYNAMIC) 229 : 0 : static int of_i2c_notify(struct notifier_block *nb, unsigned long action, 230 : : void *arg) 231 : : { 232 : : struct of_reconfig_data *rd = arg; 233 : : struct i2c_adapter *adap; 234 : : struct i2c_client *client; 235 : : 236 : 0 : switch (of_reconfig_get_state_change(action, rd)) { 237 : : case OF_RECONFIG_CHANGE_ADD: 238 : 0 : adap = of_find_i2c_adapter_by_node(rd->dn->parent); 239 : 0 : if (adap == NULL) 240 : : return NOTIFY_OK; /* not for us */ 241 : : 242 : 0 : if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) { 243 : 0 : put_device(&adap->dev); 244 : 0 : return NOTIFY_OK; 245 : : } 246 : : 247 : 0 : client = of_i2c_register_device(adap, rd->dn); 248 : 0 : if (IS_ERR(client)) { 249 : 0 : dev_err(&adap->dev, "failed to create client for '%pOF'\n", 250 : : rd->dn); 251 : 0 : put_device(&adap->dev); 252 : 0 : of_node_clear_flag(rd->dn, OF_POPULATED); 253 : 0 : return notifier_from_errno(PTR_ERR(client)); 254 : : } 255 : 0 : put_device(&adap->dev); 256 : 0 : break; 257 : : case OF_RECONFIG_CHANGE_REMOVE: 258 : : /* already depopulated? */ 259 : 0 : if (!of_node_check_flag(rd->dn, OF_POPULATED)) 260 : : return NOTIFY_OK; 261 : : 262 : : /* find our device by node */ 263 : 0 : client = of_find_i2c_device_by_node(rd->dn); 264 : 0 : if (client == NULL) 265 : : return NOTIFY_OK; /* no? not meant for us */ 266 : : 267 : : /* unregister takes one ref away */ 268 : 0 : i2c_unregister_device(client); 269 : : 270 : : /* and put the reference of the find */ 271 : 0 : put_device(&client->dev); 272 : 0 : break; 273 : : } 274 : : 275 : : return NOTIFY_OK; 276 : : } 277 : : 278 : : struct notifier_block i2c_of_notifier = { 279 : : .notifier_call = of_i2c_notify, 280 : : }; 281 : : #endif /* CONFIG_OF_DYNAMIC */