2008-04-12 05:22:35 +10:00
/*
* OF helpers for the I2C API
*
* Copyright ( c ) 2008 Jochen Friedrich < jochen @ scram . de >
*
* Based on a previous patch from Jon Smirl < jonsmirl @ gmail . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*/
# include <linux/i2c.h>
2010-10-19 15:50:31 -07:00
# include <linux/irq.h>
2008-04-12 05:22:35 +10:00
# include <linux/of.h>
2008-07-08 06:38:24 -04:00
# include <linux/of_i2c.h>
2010-06-08 07:48:18 -06:00
# include <linux/of_irq.h>
2008-04-23 19:51:34 +10:00
# include <linux/module.h>
2008-04-12 05:22:35 +10:00
2010-06-08 07:48:18 -06:00
void of_i2c_register_devices ( struct i2c_adapter * adap )
2008-04-12 05:22:35 +10:00
{
void * result ;
struct device_node * node ;
2010-06-08 07:48:18 -06:00
/* Only register child devices if the adapter has a node pointer set */
if ( ! adap - > dev . of_node )
return ;
dev_dbg ( & adap - > dev , " of_i2c: walking child nodes \n " ) ;
for_each_child_of_node ( adap - > dev . of_node , node ) {
2008-04-12 05:22:35 +10:00
struct i2c_board_info info = { } ;
2008-11-28 09:13:45 +00:00
struct dev_archdata dev_ad = { } ;
2010-01-30 01:45:26 -07:00
const __be32 * addr ;
2008-04-12 05:22:35 +10:00
int len ;
2010-06-08 07:48:18 -06:00
dev_dbg ( & adap - > dev , " of_i2c: register %s \n " , node - > full_name ) ;
if ( of_modalias_node ( node , info . type , sizeof ( info . type ) ) < 0 ) {
dev_err ( & adap - > dev , " of_i2c: modalias failure on %s \n " ,
node - > full_name ) ;
2008-07-25 22:25:13 -04:00
continue ;
2010-06-08 07:48:18 -06:00
}
2008-07-25 22:25:13 -04:00
2008-04-12 05:22:35 +10:00
addr = of_get_property ( node , " reg " , & len ) ;
2010-06-08 07:48:18 -06:00
if ( ! addr | | ( len < sizeof ( int ) ) ) {
dev_err ( & adap - > dev , " of_i2c: invalid reg on %s \n " ,
node - > full_name ) ;
2008-04-12 05:22:35 +10:00
continue ;
}
2010-01-30 01:45:26 -07:00
info . addr = be32_to_cpup ( addr ) ;
2010-06-08 07:48:18 -06:00
if ( info . addr > ( 1 < < 10 ) - 1 ) {
dev_err ( & adap - > dev , " of_i2c: invalid addr=%x on %s \n " ,
info . addr , node - > full_name ) ;
continue ;
}
2008-04-12 05:22:35 +10:00
2010-06-08 07:48:18 -06:00
info . irq = irq_of_parse_and_map ( node , 0 ) ;
info . of_node = of_node_get ( node ) ;
2008-11-28 09:13:45 +00:00
info . archdata = & dev_ad ;
2010-11-16 14:42:14 -08:00
request_module ( " %s%s " , I2C_MODULE_PREFIX , info . type ) ;
2008-04-12 05:22:35 +10:00
result = i2c_new_device ( adap , & info ) ;
if ( result = = NULL ) {
2010-06-08 07:48:18 -06:00
dev_err ( & adap - > dev , " of_i2c: Failure registering %s \n " ,
node - > full_name ) ;
of_node_put ( node ) ;
2008-04-12 05:22:35 +10:00
irq_dispose_mapping ( info . irq ) ;
continue ;
}
}
}
2010-06-08 07:48:18 -06:00
EXPORT_SYMBOL ( of_i2c_register_devices ) ;
2008-04-23 19:51:34 +10:00
2009-01-09 15:49:06 -07:00
static int of_dev_node_match ( struct device * dev , void * data )
{
2010-04-13 16:12:29 -07:00
return dev - > of_node = = data ;
2009-01-09 15:49:06 -07:00
}
/* must call put_device() when done with returned i2c_client device */
struct i2c_client * of_find_i2c_device_by_node ( struct device_node * node )
{
struct device * dev ;
dev = bus_find_device ( & i2c_bus_type , NULL , node ,
of_dev_node_match ) ;
if ( ! dev )
return NULL ;
return to_i2c_client ( dev ) ;
}
EXPORT_SYMBOL ( of_find_i2c_device_by_node ) ;
2008-04-23 19:51:34 +10:00
MODULE_LICENSE ( " GPL " ) ;