1612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich/* 2612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * OF helpers for the I2C API 3612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * 4612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de> 5612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * 6612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * Based on a previous patch from Jon Smirl <jonsmirl@gmail.com> 7612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * 8612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * This program is free software; you can redistribute it and/or modify 9612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * it under the terms of the GNU General Public License as published by 10612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * the Free Software Foundation; either version 2 of the License, or 11612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich * (at your option) any later version. 12612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich */ 13612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich 14612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich#include <linux/i2c.h> 154c60071c1ea3e204b9dc25c7519f7beef355d47fDavid Daney#include <linux/irq.h> 16612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich#include <linux/of.h> 17f40987b64d0f4d40b006ce09e37161b57c1e970bRobert P. J. Day#include <linux/of_i2c.h> 189fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely#include <linux/of_irq.h> 19138decf83f6a973951ce7faf39094d964de7853aAdrian Bunk#include <linux/module.h> 20612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich 219fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likelyvoid of_i2c_register_devices(struct i2c_adapter *adap) 22612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich{ 23612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich void *result; 24612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich struct device_node *node; 25612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich 269fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely /* Only register child devices if the adapter has a node pointer set */ 279fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely if (!adap->dev.of_node) 289fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely return; 299fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely 309fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); 319fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely 329fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely for_each_child_of_node(adap->dev.of_node, node) { 33612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich struct i2c_board_info info = {}; 34e6a437eba09f1c3505bedf7a9a9766a878ca09faAnton Vorontsov struct dev_archdata dev_ad = {}; 35337148812f97368a8ec4a69f1691e4c5ce3af494Jeremy Kerr const __be32 *addr; 36612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich int len; 37612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich 389fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name); 399fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely 409fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { 419fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely dev_err(&adap->dev, "of_i2c: modalias failure on %s\n", 429fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely node->full_name); 433f07af494dfa6de43137dae430431c9fbf929c0cGrant Likely continue; 449fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely } 453f07af494dfa6de43137dae430431c9fbf929c0cGrant Likely 46612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich addr = of_get_property(node, "reg", &len); 479fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely if (!addr || (len < sizeof(int))) { 489fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely dev_err(&adap->dev, "of_i2c: invalid reg on %s\n", 499fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely node->full_name); 50612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich continue; 51612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich } 52612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich 53337148812f97368a8ec4a69f1691e4c5ce3af494Jeremy Kerr info.addr = be32_to_cpup(addr); 549fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely if (info.addr > (1 << 10) - 1) { 559fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n", 569fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely info.addr, node->full_name); 579fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely continue; 589fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely } 59612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich 609fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely info.irq = irq_of_parse_and_map(node, 0); 619fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely info.of_node = of_node_get(node); 62e6a437eba09f1c3505bedf7a9a9766a878ca09faAnton Vorontsov info.archdata = &dev_ad; 63e6a437eba09f1c3505bedf7a9a9766a878ca09faAnton Vorontsov 64020862648445d7c1b12ea213c152f27def703f3bDavid Daney request_module("%s%s", I2C_MODULE_PREFIX, info.type); 65612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich 66612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich result = i2c_new_device(adap, &info); 67612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich if (result == NULL) { 689fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely dev_err(&adap->dev, "of_i2c: Failure registering %s\n", 699fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely node->full_name); 709fd049927ccba1c1d0343239b82f28c4e07fb95dGrant Likely of_node_put(node); 71612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich irq_dispose_mapping(info.irq); 72612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich continue; 73612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich } 74612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich } 75612212a3f2f053ea68ce9cd16d3deeca7754e8c9Jochen Friedrich} 769fd049927ccba1c1d0343239b82f28c4e07fb95dGrant LikelyEXPORT_SYMBOL(of_i2c_register_devices); 77138decf83f6a973951ce7faf39094d964de7853aAdrian Bunk 782526c151c31358aec66b63921dd712bbec5ee0cbJon Smirlstatic int of_dev_node_match(struct device *dev, void *data) 792526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl{ 8061c7a080a5a061c976988fd4b844dfb468dda255Grant Likely return dev->of_node == data; 812526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl} 822526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl 832526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl/* must call put_device() when done with returned i2c_client device */ 842526c151c31358aec66b63921dd712bbec5ee0cbJon Smirlstruct i2c_client *of_find_i2c_device_by_node(struct device_node *node) 852526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl{ 862526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl struct device *dev; 872526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl 882526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl dev = bus_find_device(&i2c_bus_type, NULL, node, 892526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl of_dev_node_match); 902526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl if (!dev) 912526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl return NULL; 922526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl 932526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl return to_i2c_client(dev); 942526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl} 952526c151c31358aec66b63921dd712bbec5ee0cbJon SmirlEXPORT_SYMBOL(of_find_i2c_device_by_node); 962526c151c31358aec66b63921dd712bbec5ee0cbJon Smirl 97138decf83f6a973951ce7faf39094d964de7853aAdrian BunkMODULE_LICENSE("GPL"); 98