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.2 2004/03/03 17:56:56 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 *
00060 i2c_adapter_compute_udi (HalDevice * d, int append_num)
00061 {
00062     const char *format;
00063     static char buf[256];
00064 
00065     if (append_num == -1)
00066         format = "/org/freedesktop/Hal/devices/i2c_adapter_%d";
00067     else
00068         format = "/org/freedesktop/Hal/devices/i2c_adapter_%d-%d";
00069 
00070     snprintf (buf, 256, format,
00071           ds_property_get_int (d, "i2c_adapter.adapter"),
00072           append_num);
00073 
00074     return buf;
00075 }
00076 
00077 
00078 /* fwd decl */
00079 static void visit_class_device_i2c_adapter_got_parent (HalDevice * parent,
00080                                void *data1,
00081                                void *data2);
00082 
00091 void
00092 visit_class_device_i2c_adapter (const char *path,
00093                 struct sysfs_class_device *class_device)
00094 {
00095     HalDevice *d;
00096     struct sysfs_attribute *cur;
00097     char *parent_sysfs_path;
00098     char *product_name;
00099     char attr_name[SYSFS_NAME_LEN];
00100     const char *last_elem;
00101     int adapter_num;
00102     int len;
00103     int i;
00104 
00105     if (class_device->sysdevice == NULL) {
00106         HAL_INFO (("Skipping virtual class device at path %s\n",
00107                path));
00108         return;
00109     }
00110 
00111     HAL_INFO (("i2c_adapter: sysdevice_path=%s, path=%s\n",
00112            class_device->sysdevice->path, path));
00113 
00116     d = ds_device_new ();
00117     ds_property_set_string (d, "info.bus", "i2c_adapter");
00118     ds_property_set_string (d, "linux.sysfs_path", path);
00119     ds_property_set_string (d, "linux.sysfs_path_device",
00120                 class_device->sysdevice->path);
00121 
00122     /* Sets last_elem to i2c-2 in path=/sys/class/i2c-adapter/i2c-2 */
00123     last_elem = get_last_element (path);
00124     sscanf (last_elem, "i2c-%d", &adapter_num);
00125     ds_property_set_int (d, "i2c_adapter.adapter", adapter_num);
00126 
00127     /* guestimate product name */
00128     dlist_for_each_data (sysfs_get_device_attributes
00129                  (class_device->sysdevice), cur,
00130                  struct sysfs_attribute) {
00131         
00132         if (sysfs_get_name_from_path (cur->path,
00133                           attr_name,
00134                           SYSFS_NAME_LEN) != 0)
00135             continue;
00136 
00137         /* strip whitespace */
00138         len = strlen (cur->value);
00139         for (i = len - 1; isspace (cur->value[i]); --i)
00140             cur->value[i] = '\0';
00141 
00142         /*printf("attr_name=%s -> '%s'\n", attr_name, cur->value); */
00143 
00144         if (strcmp (attr_name, "name") == 0)
00145             product_name = cur->value;
00146     }
00147 
00148     ds_property_set_string (d, "info.product",
00149                 "I2C Adapter Interface");
00150     if (product_name == NULL)
00151         ds_property_set_string (d, "i2c_adapter.name",
00152                     "I2C Adapter Interface");
00153     else
00154         ds_property_set_string (d, "i2c_adapter.name",
00155                     product_name);
00156 
00157     parent_sysfs_path =
00158         get_parent_sysfs_path (class_device->sysdevice->path);
00159 
00160     /* Find parent; this happens asynchronously as our parent might
00161      * be added later. If we are probing this can't happen so the
00162      * timeout is set to zero in that event..
00163      */
00164     ds_device_async_find_by_key_value_string
00165         ("linux.sysfs_path_device", parent_sysfs_path, TRUE,
00166          visit_class_device_i2c_adapter_got_parent, (void *) d, NULL,
00167          is_probing ? 0 : HAL_LINUX_HOTPLUG_TIMEOUT);
00168 
00169     free (parent_sysfs_path);
00170 }
00171 
00179 static void
00180 visit_class_device_i2c_adapter_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     /*printf("parent=0x%08x\n", parent); */
00188 
00189     if (parent != NULL) {
00190         ds_property_set_string (d, "info.parent", parent->udi);
00191         find_and_set_physical_device (d);
00192         ds_property_set_bool (d, "info.virtual", TRUE);
00193     } else {
00194         HAL_ERROR (("No parent for I2C adapter device!"));
00195         ds_device_destroy (d);
00196         return;
00197     }
00198 
00199     /* Add the i2c_adapter capability to our parent device */
00200     ds_add_capability (parent, "i2c_adapter");
00201 
00202     /* Compute a proper UDI (unique device id) and try to locate a persistent
00203      * unplugged device or simple add this new device...
00204      */
00205     new_udi =
00206         rename_and_merge (d, i2c_adapter_compute_udi, "i2c_adapter");
00207     if (new_udi != NULL) {
00208         new_d = ds_device_find (new_udi);
00209         if (new_d != NULL) {
00210             ds_gdl_add (new_d);
00211         }
00212     }
00213 }
00214 
00215 
00219 void
00220 linux_class_i2c_adapter_init ()
00221 {
00222 }
00223 
00228 void
00229 linux_class_i2c_adapter_detection_done ()
00230 {
00231 }
00232 
00236 void
00237 linux_class_i2c_adapter_shutdown ()
00238 {
00239 }
00240 

Generated on Thu Mar 11 21:32:22 2004 for HAL by doxygen 1.3.6-20040222