linux/drivers/of/of_i2c.c
<<
>>
Prefs
   1/*
   2 * OF helpers for the I2C API
   3 *
   4 * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
   5 *
   6 * Based on a previous patch from Jon Smirl <jonsmirl@gmail.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 */
  13
  14#include <linux/i2c.h>
  15#include <linux/irq.h>
  16#include <linux/of.h>
  17#include <linux/of_i2c.h>
  18#include <linux/of_irq.h>
  19#include <linux/module.h>
  20
  21void of_i2c_register_devices(struct i2c_adapter *adap)
  22{
  23        void *result;
  24        struct device_node *node;
  25
  26        /* Only register child devices if the adapter has a node pointer set */
  27        if (!adap->dev.of_node)
  28                return;
  29
  30        dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
  31
  32        for_each_child_of_node(adap->dev.of_node, node) {
  33                struct i2c_board_info info = {};
  34                struct dev_archdata dev_ad = {};
  35                const __be32 *addr;
  36                int len;
  37
  38                dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
  39
  40                if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
  41                        dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
  42                                node->full_name);
  43                        continue;
  44                }
  45
  46                addr = of_get_property(node, "reg", &len);
  47                if (!addr || (len < sizeof(int))) {
  48                        dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
  49                                node->full_name);
  50                        continue;
  51                }
  52
  53                info.addr = be32_to_cpup(addr);
  54                if (info.addr > (1 << 10) - 1) {
  55                        dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
  56                                info.addr, node->full_name);
  57                        continue;
  58                }
  59
  60                info.irq = irq_of_parse_and_map(node, 0);
  61                info.of_node = of_node_get(node);
  62                info.archdata = &dev_ad;
  63
  64                if (of_get_property(node, "wakeup-source", NULL))
  65                        info.flags |= I2C_CLIENT_WAKE;
  66
  67                request_module("%s%s", I2C_MODULE_PREFIX, info.type);
  68
  69                result = i2c_new_device(adap, &info);
  70                if (result == NULL) {
  71                        dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
  72                                node->full_name);
  73                        of_node_put(node);
  74                        irq_dispose_mapping(info.irq);
  75                        continue;
  76                }
  77        }
  78}
  79EXPORT_SYMBOL(of_i2c_register_devices);
  80
  81static int of_dev_node_match(struct device *dev, void *data)
  82{
  83        return dev->of_node == data;
  84}
  85
  86/* must call put_device() when done with returned i2c_client device */
  87struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
  88{
  89        struct device *dev;
  90
  91        dev = bus_find_device(&i2c_bus_type, NULL, node,
  92                                         of_dev_node_match);
  93        if (!dev)
  94                return NULL;
  95
  96        return i2c_verify_client(dev);
  97}
  98EXPORT_SYMBOL(of_find_i2c_device_by_node);
  99
 100/* must call put_device() when done with returned i2c_adapter device */
 101struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
 102{
 103        struct device *dev;
 104
 105        dev = bus_find_device(&i2c_bus_type, NULL, node,
 106                                         of_dev_node_match);
 107        if (!dev)
 108                return NULL;
 109
 110        return i2c_verify_adapter(dev);
 111}
 112EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
 113
 114MODULE_LICENSE("GPL");
 115
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.