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                request_module("%s%s", I2C_MODULE_PREFIX, info.type);
  65
  66                result = i2c_new_device(adap, &info);
  67                if (result == NULL) {
  68                        dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
  69                                node->full_name);
  70                        of_node_put(node);
  71                        irq_dispose_mapping(info.irq);
  72                        continue;
  73                }
  74        }
  75}
  76EXPORT_SYMBOL(of_i2c_register_devices);
  77
  78static int of_dev_node_match(struct device *dev, void *data)
  79{
  80        return dev->of_node == data;
  81}
  82
  83/* must call put_device() when done with returned i2c_client device */
  84struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
  85{
  86        struct device *dev;
  87
  88        dev = bus_find_device(&i2c_bus_type, NULL, node,
  89                                         of_dev_node_match);
  90        if (!dev)
  91                return NULL;
  92
  93        return i2c_verify_client(dev);
  94}
  95EXPORT_SYMBOL(of_find_i2c_device_by_node);
  96
  97/* must call put_device() when done with returned i2c_adapter device */
  98struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
  99{
 100        struct device *dev;
 101
 102        dev = bus_find_device(&i2c_bus_type, NULL, node,
 103                                         of_dev_node_match);
 104        if (!dev)
 105                return NULL;
 106
 107        return i2c_verify_adapter(dev);
 108}
 109EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
 110
 111MODULE_LICENSE("GPL");
 112
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.