linux-I2c驱动

参考文档:

https://blog.csdn.net/wq690968346/article/details/50921039(i2c_client的四中方法)

https://blog.csdn.net/pengliang528/article/details/78262441

1:最新的I2c模型:设备,总线,驱动模型。

分层模型(1):核心层:提供统一的I2C接口操作函数,

(2):适配器:基于板卡的I2c的硬件操作。基于某个芯片的硬件操作。

bus:I2C_bus_type提供了注册接口函数。

设备层(device):i2c_clinet  注册: i2c_new_device  结构体:i2c_adapter(i2c_board_info)

驱动层(driver):i2c_driver   注册:i2c_add_driver() 结构体:i2c_driver   比较(i2c_device_id)

比较如果名称相同,则调用i2c_driver   的probe函数

第一层:i2c adapter的硬件驱动,探测,初始化i2c_adapter(申请i2c的io地址和中断号),驱动soc控制控制adapter产生的硬件信号以及I2c中断。

第二层:提供i2c_adapter的algorithm,用适配器xxx_xferf()填充i2c_algorithm的master_xfer函数指针,并把i2c_algorithm赋给algo指针,覆盖图中的抽象层,i2c核心层。

第三层:i2c_driver接口,用具体的i2c device设备的attach_adapter()、detach_adapter()方法赋值给i2c_driver的成员函数指针。实现设备device与总线(或者叫adapter)的挂接

第四层:具体device的驱动,i2c_driver只是实现设备与总线的挂接,所以要实现具体设备device的write()、read()、ioctl()等方法,赋值给file_operations,然后注册字符设备(多数是字符设备)

与之相关的c文件:i2c-core.c这个文件实现了I2C核心的功能以及/proc/bus/i2c*接口。

i2c-dev.c实现了I2C适配器设备文件的功能,每一个I2C适配器都被分配一个设备。通过适配器访设备时的主设备号都为89,次设备号为0-255。I2c-dev.c并没有针对特定的设备而设计,只是提供了通用的read(),write(),和ioctl()等接口,应用层可以借用这些接口访问挂接在适配器上的I2C设备的存储空间或寄存器,并控制I2C设备的工作方式。
busses文件夹这个文件中包含了一些I2C总线的驱动,如针对S3C2410,S3C2440,S3C6410等处理器的I2C控制器驱动为i2c-s3c2410.c.
algos文件夹实现了一些I2C总线适配器的algorithm.

先看一些结构体:(从下到上)

  • struct i2c_algorithm {  //i2c传输
  •     int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);//I2C传输函数指针  
  •     int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, union   
  •     i2c_smbus_data *data);//smbus传输函数指针  
  •     u32 (*functionality) (struct i2c_adapter *);//返回适配器支持的功能  
  • };
  • struct i2c_adapter {   //i2c物理上的适配器,一个适配器上有多个i2c_client ,所以i2c_adapter中包含依附于它的i2c_clinet
  • 的链表。
  •  struct module *owner;//所属模块  
  •  unsigned int id;//algorithm的类型,定义于i2c-id.h,  
  •  unsigned int class;      
  •  const struct i2c_algorithm *algo; //总线通信方法结构体指针  
  •  void *algo_data;//algorithm数据  
  •  struct rt_mutex bus_lock;//控制并发访问的自旋锁  
  •  int timeout;     
  •  int retries;//重试次数  
  •  struct device dev; //适配器设备   
  •  int nr;  
  •  char name[48];//适配器名称  
  •  struct completion dev_released;//用于同步  
  •  struct list_head userspace_clients;//client链表头  
  • }; 
  • struct i2c_client {   //对应真是的i2c的物理设备,每个i2c设备东欧要有一个i2c-client来描述
  •  unsigned short flags;//标志    
  •  unsigned short addr; //低7位为芯片地址    
  •  char name[I2C_NAME_SIZE];//设备名称  
  •  struct i2c_adapter *adapter;//依附的i2c_adapter  
  •  struct i2c_driver *driver;//依附的i2c_driver   
  •  struct device dev;//设备结构体    
  •  int irq;//设备所使用的结构体    
  •  struct list_head detected;//链表头  
  •  };
  • struct i2c_driver {  //与i2c_client 是一对多,一个i2c_driver 可以支持多个同等类型的i2c_client 
  • unsigned int class;  
  • int (*attach_adapter)(struct i2c_adapter *);//依附i2c_adapter函数指针  
  • int (*detach_adapter)(struct i2c_adapter *);//脱离i2c_adapter函数指针  
  • int (*probe)(struct i2c_client *, const struct i2c_device_id *);  
  • int (*remove)(struct i2c_client *);  
  • void (*shutdown)(struct i2c_client *);  
  • int (*suspend)(struct i2c_client *, pm_message_t mesg);  
  • int (*resume)(struct i2c_client *);  
  • void (*alert)(struct i2c_client *, unsigned int data);  
  • int (*command)(struct i2c_client *client, unsigned int cmd, void*arg);//命令列表  
  • struct device_driver driver;  
  • const struct i2c_device_id *id_table;//该驱动所支持的设备ID表  
  • int (*detect)(struct i2c_client *, struct i2c_board_info *);  
  • const unsigned short *address_list;  
  • struct list_head clients;  
  • };

主要函数

i2c_transfer()只是用来找到i2c_adapter对应的i2c_algorithm,并使用i2c_algorithm的master_xfer()函数真正的驱动硬件流程

s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command)从i2cbus中读取字节。

  • //增加/删除i2c_adapter  
  • int i2c_add_adapter(struct i2c_adapter *adapter)  
  • int i2c_del_adapter(struct i2c_adapter *adap) 
  • //增加/删除i2c_driver  
  • int i2c_register_driver(struct module *owner, struct i2c_driver *driver)  
  • void i2c_del_driver(struct i2c_driver *driver)
  • //i2c_client依附/脱离  
  • int i2c_attach_client(struct i2c_client *client)  
  • //I2C传输,发送和接收  
  • int i2c_master_send(struct i2c_client *client,const char *buf ,int count)  
  • int i2c_master_recv(struct i2c_client *client, char *buf ,int count)  
  • int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 

猜你喜欢

转载自blog.csdn.net/zuodenghuakai/article/details/84030478