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

linux_class_i2c_adapter.c

00001 /***************************************************************************
00002  * CVSID: $Id: linux_class_i2c_adapter.c,v 1.1 2004/01/12 23:30:36 david Exp $
00003  *
00004  * linux_class_i2c_adapter.c : I2C functions for sysfs-agent on Linux 2.6
00005  *
00006  * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
00007  *
00008  * Licensed under the Academic Free License version 2.0
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  **************************************************************************/
00025 
00026 #ifdef HAVE_CONFIG_H
00027 #  include <config.h>
00028 #endif
00029 
00030 #include <ctype.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <getopt.h>
00035 #include <assert.h>
00036 #include <unistd.h>
00037 #include <stdarg.h>
00038 
00039 #include "../logger.h"
00040 #include "../device_store.h"
00041 #include "linux_class_i2c_adapter.h"
00042 
00059 static char* i2c_adapter_compute_udi(HalDevice* d, int append_num)
00060 {
00061     const char* format;
00062     static char buf[256];
00063 
00064     if( append_num==-1 )
00065         format = "/org/freedesktop/Hal/devices/i2c_adapter_%d";
00066     else
00067         format = "/org/freedesktop/Hal/devices/i2c_adapter_%d-%d";
00068 
00069     snprintf(buf, 256, format, 
00070              ds_property_get_int(d, "i2c_adapter.adapter"),
00071              append_num);
00072     
00073     return buf;
00074 }
00075 
00076 
00077 /* fwd decl */
00078 static void visit_class_device_i2c_adapter_got_parent(HalDevice* parent, 
00079                                                       void* data1, void* data2);
00080 
00089 void visit_class_device_i2c_adapter(const char* path, 
00090                                     struct sysfs_class_device* class_device)
00091 {
00092     HalDevice* d;
00093     struct sysfs_attribute* cur;
00094     char* parent_sysfs_path;
00095     char* product_name;
00096     char attr_name[SYSFS_NAME_LEN];
00097     const char* last_elem;
00098     int adapter_num;
00099     int len;
00100     int i;
00101 
00102     if( class_device->sysdevice==NULL )
00103     {
00104         HAL_INFO(("Skipping virtual class device at path %s\n", path));
00105         return;
00106     }
00107 
00108     HAL_INFO(("i2c_adapter: sysdevice_path=%s, path=%s\n", class_device->sysdevice->path, path));
00109 
00112     d = ds_device_new();
00113     ds_property_set_string(d, "info.bus", "i2c_adapter");
00114     ds_property_set_string(d, "linux.sysfs_path", path);
00115     ds_property_set_string(d, "linux.sysfs_path_device", 
00116                            class_device->sysdevice->path);
00117 
00118     /* Sets last_elem to i2c-2 in path=/sys/class/i2c-adapter/i2c-2 */
00119     last_elem = get_last_element(path);
00120     sscanf(last_elem, "i2c-%d", &adapter_num);
00121     ds_property_set_int(d, "i2c_adapter.adapter", adapter_num);
00122 
00123     /* guestimate product name */
00124     dlist_for_each_data(sysfs_get_device_attributes(class_device->sysdevice), cur,
00125                         struct sysfs_attribute)
00126     {
00127         
00128         if( sysfs_get_name_from_path(cur->path, 
00129                                      attr_name, SYSFS_NAME_LEN) != 0 )
00130             continue;
00131         
00132         /* strip whitespace */
00133         len = strlen(cur->value);
00134         for(i=len-1; isspace(cur->value[i]); --i)
00135             cur->value[i] = '\0';
00136         
00137         /*printf("attr_name=%s -> '%s'\n", attr_name, cur->value);*/
00138         
00139         if( strcmp(attr_name, "name")==0 )
00140            product_name = cur->value;
00141     }
00142 
00143     ds_property_set_string(d, "info.product", "I2C Adapter Interface");
00144     if ( product_name==NULL )
00145         ds_property_set_string(d, "i2c_adapter.name", "I2C Adapter Interface");
00146     else
00147         ds_property_set_string(d, "i2c_adapter.name", product_name);
00148 
00149     parent_sysfs_path = get_parent_sysfs_path(class_device->sysdevice->path);
00150 
00151     /* Find parent; this happens asynchronously as our parent might
00152      * be added later. If we are probing this can't happen so the
00153      * timeout is set to zero in that event..
00154      */
00155     ds_device_async_find_by_key_value_string(
00156         "linux.sysfs_path_device",
00157         parent_sysfs_path, 
00158         TRUE,
00159         visit_class_device_i2c_adapter_got_parent,
00160         (void*) d, NULL, 
00161         is_probing ? 0 :
00162         HAL_LINUX_HOTPLUG_TIMEOUT);
00163 
00164     free(parent_sysfs_path);
00165 }
00166 
00174 static void visit_class_device_i2c_adapter_got_parent(HalDevice* parent, 
00175                                                       void* data1, void* data2)
00176 {
00177     char* new_udi = NULL;
00178     HalDevice* new_d = NULL;
00179     HalDevice* d = (HalDevice*) data1;
00180 
00181     /*printf("parent=0x%08x\n", parent);*/
00182 
00183     if( parent!=NULL )
00184     {
00185         ds_property_set_string(d, "info.parent", parent->udi);
00186         find_and_set_physical_device(d);
00187         ds_property_set_bool(d, "info.virtual", TRUE);
00188     }
00189     else
00190     {
00191         HAL_ERROR(("No parent for I2C adapter device!"));
00192         ds_device_destroy(d);
00193         return;
00194     }
00195 
00196     /* Add the i2c_adapter capability to our parent device */
00197     ds_add_capability(parent, "i2c_adapter");
00198 
00199     /* Compute a proper UDI (unique device id) and try to locate a persistent
00200      * unplugged device or simple add this new device...
00201      */
00202     new_udi = rename_and_merge(d, i2c_adapter_compute_udi, "i2c_adapter");
00203     if( new_udi!=NULL )
00204     {
00205         new_d = ds_device_find(new_udi);
00206         if( new_d!=NULL )
00207         {
00208             ds_gdl_add(new_d);
00209         }
00210     }
00211 }
00212 
00213 
00217 void linux_class_i2c_adapter_init()
00218 {
00219 }
00220 
00225 void linux_class_i2c_adapter_detection_done()
00226 {
00227 }
00228 
00232 void linux_class_i2c_adapter_shutdown()
00233 {
00234 }
00235 

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