| 
		    
                    
 当系统开机、I2C总线驱动装入完成后,就可以装入设备驱动了。首先装入如下结构: 
  
 
    
        
            | 
             static struct i2c_driver driver =  
            { 
               .name           = "i2c TV tuner driver", 
               .id             = I2C_DRIVERID_TUNER, 
               .flags          = I2C_DF_NOTIFY, 
               .attach_adapter = tuner_probe, 
               .detach_client  = tuner_detach, 
               .command        = tuner_command, 
            }; 
              
            i2c_add_driver(&driver); 
             | 
         
    
 
  
这个i2c_driver一旦装入完成,其中的attach_adapter函数就会被调用。在其中可以遍历系统中的每个i2c总线驱动,探测想要访问的设备: 
  
 
    
        
            | 
             static int tuner_probe(struct i2c_adapter *adap)  
            { 
             return i2c_probe(adap, &addr_data, tuner_attach);  
            } 
              
             | 
         
    
 
  
注意探测可能会找到多个设备,因而不仅一个I2C总线可以挂多个不同类型的设备,一个设备驱动也可以同时为挂在多个不同I2C总线上的设备服务。 
  
每当设备驱动探测到了一个它能支持的设备,它就创建一个struct i2c_client来标识这个设备: 
  
 
    
        
            | 
             new_client->addr = address; 
            new_client->adapter = adapter; 
            new_client->driver = &driver; 
              
            /* Tell the I2C layer a new client has arrived */ 
            err = i2c_attach_client(new_client); 
            if (err) 
                goto error; 
             | 
         
    
 
  
可见,一个i2c_client代表着位于adapter总线上,地址为address,使用driver来驱动的一个设备。它将总线驱动与设备驱动,以及设备地址绑定在了一起。一个i2c_client就代表着一个I2C设备。 
  
当得到I2C设备后,就可以直接对此设备进行读写: 
  
 
    
        
            | 
             /* 
             * The master routines are the ones normally used to transmit data to devices 
             * on a bus (or read from them). Apart from two basic transfer functions to  
             * transmit one message at a time, a more complex version can be used to  
             * transmit an arbitrary number of messages without interruption. 
             */ 
              
            extern int i2c_master_send(struct i2c_client *,const char* ,int); 
            extern int i2c_master_recv(struct i2c_client *,char* ,int); 
              
             | 
         
    
 
  
与通常意义上的读写函数一样,这两个函数对i2c_client指针指定的设备,读写int个char。返回值为读写的字节数。对于我们现有的SLIC的驱动,只要将最后要往总线上进行读写的数据引出传输到这两个函数中,移植工作就算完成了,我们将得到一个Linux版的I2C设备驱动。 
  
-- 
原文链接: http://www.gnome-cn.org/resources/blog/lonestar/linuxdei2cqudongjiagou 
		    
                      
		      
		      
		   |