Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

linux_i2c.c

00001 /***************************************************************************
00002  * CVSID: $Id: linux_i2c.c,v 1.1 2004/01/09 23:22:58 david Exp $
00003  *
00004  * linux_i2c.c : I2C handling on Linux 2.6; based on linux_pci.c
00005  *
00006  * Copyright (C) 2004 Matthew Mastracci <matt@aclaro.com>
00007  * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
00008  *
00009  * Licensed under the Academic Free License version 2.0
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  *
00025  **************************************************************************/
00026 
00027 #ifdef HAVE_CONFIG_H
00028 #  include <config.h>
00029 #endif
00030 
00031 #include <ctype.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <getopt.h>
00036 #include <assert.h>
00037 #include <unistd.h>
00038 #include <stdarg.h>
00039 
00040 #include "../logger.h"
00041 #include "../device_store.h"
00042 #include "linux_i2c.h"
00043 
00069 static char* i2c_compute_udi(HalDevice* d, int append_num)
00070 {
00071     static char buf[256];
00072 
00073     if( append_num==-1 )
00074         sprintf(buf, "/org/freedesktop/Hal/devices/i2c_%s",
00075                 ds_property_get_string(d, "i2c.product"));
00076     else
00077         sprintf(buf, "/org/freedesktop/Hal/devices/i2c_%s/%d", 
00078                 ds_property_get_string(d, "i2c.product"),
00079                 append_num);
00080     
00081     return buf;
00082 }
00083 
00084 
00085 /* fwd decl */
00086 static void visit_device_i2c_got_parent(HalDevice* parent, 
00087                                         void* data1, void* data2);
00088 
00097 void visit_device_i2c(const char* path, struct sysfs_device *device)
00098 {
00099     int i;
00100     int len;
00101     HalDevice* d;
00102     char attr_name[SYSFS_NAME_LEN];
00103     struct sysfs_attribute* cur;
00104     char* product_name = NULL;
00105     const char* driver;
00106     char* parent_sysfs_path;
00107 
00108     /* Must be a new I2C device */
00109     d = ds_device_new();
00110     ds_property_set_string(d, "info.bus", "i2c");
00111     ds_property_set_string(d, "info.category", "i2c");
00112     ds_property_set_string(d, "info.capabilities", "i2c");
00113     ds_property_set_string(d, "linux.sysfs_path", path);
00114     ds_property_set_string(d, "linux.sysfs_path_device", path);
00119     ds_property_set_string(d, "i2c.linux.sysfs_path", path);
00120     /*printf("*** created udi=%s for path=%s\n", d, path);*/
00121 
00122     /* set driver */
00123     driver = drivers_lookup(path);
00124     if( driver!=NULL )
00125         ds_property_set_string(d, "linux.driver", driver);
00126 
00127     dlist_for_each_data(sysfs_get_device_attributes(device), cur,
00128                         struct sysfs_attribute)
00129     {
00130         
00131         if( sysfs_get_name_from_path(cur->path, 
00132                                      attr_name, SYSFS_NAME_LEN) != 0 )
00133             continue;
00134         
00135         /* strip whitespace */
00136         len = strlen(cur->value);
00137         for(i=len-1; isspace(cur->value[i]); --i)
00138             cur->value[i] = '\0';
00139         
00140         /*printf("attr_name=%s -> '%s'\n", attr_name, cur->value);*/
00141         
00142         if( strcmp(attr_name, "name")==0 )
00143            product_name = cur->value;
00144     }
00145 
00146     if( product_name==NULL )
00147         product_name = "Unknown";
00148 
00149     ds_property_set_string(d, "i2c.product", product_name);
00150 
00151     /* Provide best-guess of name, goes in Product property; 
00152      * .fdi files can override this */
00153     ds_property_set_string(d, "info.product", product_name);
00154 
00155     parent_sysfs_path = get_parent_sysfs_path(path);
00156 
00157     /* Find parent; this happens asynchronously as our parent might
00158      * be added later. If we are probing this can't happen so the
00159      * timeout is set to zero in that event..
00160      */
00161     HAL_INFO(("For device = %s, parent = %s", ds_property_get_string(d, "linux.sysfs_path"), parent_sysfs_path));
00162     ds_device_async_find_by_key_value_string("linux.sysfs_path_device",
00163                                              parent_sysfs_path, 
00164                                              TRUE,
00165                                              visit_device_i2c_got_parent,
00166                                              (void*) d, NULL, 
00167                                              is_probing ? 0 :
00168                                              HAL_LINUX_HOTPLUG_TIMEOUT);
00169 
00170     free(parent_sysfs_path);
00171 }
00172 
00180 static void visit_device_i2c_got_parent(HalDevice* parent, 
00181                                         void* data1, void* data2)
00182 {
00183     char* new_udi = NULL;
00184     HalDevice* new_d = NULL;
00185     HalDevice* d = (HalDevice*) data1;
00186 
00187     if( parent!=NULL )
00188     {
00189         ds_property_set_string(d, "info.parent", parent->udi);
00190     }
00191     else
00192     {
00193         /* An I2C device should always have a parent! */
00194         HAL_WARNING(("No parent for I2C device!"));
00195     }
00196 
00197     /* Compute a proper UDI (unique device id) and try to locate a persistent
00198      * unplugged device or simple add this new device...
00199      */
00200     new_udi = rename_and_merge(d, i2c_compute_udi, "i2c");
00201     if( new_udi!=NULL )
00202     {
00203         new_d = ds_device_find(new_udi);
00204         if( new_d!=NULL )
00205         {
00206             ds_gdl_add(new_d);
00207         }
00208     }
00209 }
00210 
00214 void linux_i2c_init()
00215 {
00216     /* get all drivers under /sys/bus/i2c/drivers */
00217     drivers_collect("i2c");
00218 }
00219 
00224 void linux_i2c_detection_done()
00225 {
00226 }
00227 
00231 void linux_i2c_shutdown()
00232 {
00233 }
00234 

Generated on Sat Feb 7 22:11:47 2004 for HAL by doxygen 1.3.5