root/drivers/i2c/i2c-core-of.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. of_i2c_get_board_info
  2. of_i2c_register_device
  3. of_i2c_register_devices
  4. of_dev_or_parent_node_match
  5. of_find_i2c_device_by_node
  6. of_find_i2c_adapter_by_node
  7. of_get_i2c_adapter_by_node
  8. i2c_of_match_device_sysfs
  9. i2c_of_match_device
  10. of_i2c_notify

   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 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         memset(info, 0, sizeof(*info));
  29 
  30         if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) {
  31                 dev_err(dev, "of_i2c: modalias failure on %pOF\n", node);
  32                 return -EINVAL;
  33         }
  34 
  35         ret = of_property_read_u32(node, "reg", &addr);
  36         if (ret) {
  37                 dev_err(dev, "of_i2c: invalid reg on %pOF\n", node);
  38                 return ret;
  39         }
  40 
  41         if (addr & I2C_TEN_BIT_ADDRESS) {
  42                 addr &= ~I2C_TEN_BIT_ADDRESS;
  43                 info->flags |= I2C_CLIENT_TEN;
  44         }
  45 
  46         if (addr & I2C_OWN_SLAVE_ADDRESS) {
  47                 addr &= ~I2C_OWN_SLAVE_ADDRESS;
  48                 info->flags |= I2C_CLIENT_SLAVE;
  49         }
  50 
  51         info->addr = addr;
  52         info->of_node = node;
  53 
  54         if (of_property_read_bool(node, "host-notify"))
  55                 info->flags |= I2C_CLIENT_HOST_NOTIFY;
  56 
  57         if (of_get_property(node, "wakeup-source", NULL))
  58                 info->flags |= I2C_CLIENT_WAKE;
  59 
  60         return 0;
  61 }
  62 EXPORT_SYMBOL_GPL(of_i2c_get_board_info);
  63 
  64 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         ret = of_i2c_get_board_info(&adap->dev, node, &info);
  74         if (ret)
  75                 return ERR_PTR(ret);
  76 
  77         client = i2c_new_device(adap, &info);
  78         if (!client) {
  79                 dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node);
  80                 return ERR_PTR(-EINVAL);
  81         }
  82         return client;
  83 }
  84 
  85 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         if (!adap->dev.of_node)
  92                 return;
  93 
  94         dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
  95 
  96         bus = of_get_child_by_name(adap->dev.of_node, "i2c-bus");
  97         if (!bus)
  98                 bus = of_node_get(adap->dev.of_node);
  99 
 100         for_each_available_child_of_node(bus, node) {
 101                 if (of_node_test_and_set_flag(node, OF_POPULATED))
 102                         continue;
 103 
 104                 client = of_i2c_register_device(adap, node);
 105                 if (IS_ERR(client)) {
 106                         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         of_node_put(bus);
 114 }
 115 
 116 static int of_dev_or_parent_node_match(struct device *dev, const void *data)
 117 {
 118         if (dev->of_node == data)
 119                 return 1;
 120 
 121         if (dev->parent)
 122                 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 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         if (!dev)
 135                 return NULL;
 136 
 137         client = i2c_verify_client(dev);
 138         if (!client)
 139                 put_device(dev);
 140 
 141         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 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         dev = bus_find_device(&i2c_bus_type, NULL, node,
 152                               of_dev_or_parent_node_match);
 153         if (!dev)
 154                 return NULL;
 155 
 156         adapter = i2c_verify_adapter(dev);
 157         if (!adapter)
 158                 put_device(dev);
 159 
 160         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 struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node)
 166 {
 167         struct i2c_adapter *adapter;
 168 
 169         adapter = of_find_i2c_adapter_by_node(node);
 170         if (!adapter)
 171                 return NULL;
 172 
 173         if (!try_module_get(adapter->owner)) {
 174                 put_device(&adapter->dev);
 175                 adapter = NULL;
 176         }
 177 
 178         return adapter;
 179 }
 180 EXPORT_SYMBOL(of_get_i2c_adapter_by_node);
 181 
 182 static const struct of_device_id*
 183 i2c_of_match_device_sysfs(const struct of_device_id *matches,
 184                                   struct i2c_client *client)
 185 {
 186         const char *name;
 187 
 188         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                 if (sysfs_streq(client->name, matches->compatible))
 196                         return matches;
 197 
 198                 name = strchr(matches->compatible, ',');
 199                 if (!name)
 200                         name = matches->compatible;
 201                 else
 202                         name++;
 203 
 204                 if (sysfs_streq(client->name, name))
 205                         return matches;
 206         }
 207 
 208         return NULL;
 209 }
 210 
 211 const struct of_device_id
 212 *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         if (!(client && matches))
 218                 return NULL;
 219 
 220         match = of_match_device(matches, &client->dev);
 221         if (match)
 222                 return match;
 223 
 224         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 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         switch (of_reconfig_get_state_change(action, rd)) {
 237         case OF_RECONFIG_CHANGE_ADD:
 238                 adap = of_find_i2c_adapter_by_node(rd->dn->parent);
 239                 if (adap == NULL)
 240                         return NOTIFY_OK;       /* not for us */
 241 
 242                 if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) {
 243                         put_device(&adap->dev);
 244                         return NOTIFY_OK;
 245                 }
 246 
 247                 client = of_i2c_register_device(adap, rd->dn);
 248                 if (IS_ERR(client)) {
 249                         dev_err(&adap->dev, "failed to create client for '%pOF'\n",
 250                                  rd->dn);
 251                         put_device(&adap->dev);
 252                         of_node_clear_flag(rd->dn, OF_POPULATED);
 253                         return notifier_from_errno(PTR_ERR(client));
 254                 }
 255                 put_device(&adap->dev);
 256                 break;
 257         case OF_RECONFIG_CHANGE_REMOVE:
 258                 /* already depopulated? */
 259                 if (!of_node_check_flag(rd->dn, OF_POPULATED))
 260                         return NOTIFY_OK;
 261 
 262                 /* find our device by node */
 263                 client = of_find_i2c_device_by_node(rd->dn);
 264                 if (client == NULL)
 265                         return NOTIFY_OK;       /* no? not meant for us */
 266 
 267                 /* unregister takes one ref away */
 268                 i2c_unregister_device(client);
 269 
 270                 /* and put the reference of the find */
 271                 put_device(&client->dev);
 272                 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 */

/* [<][>][^][v][top][bottom][index][help] */