linux内核I2C子系统学习(二)

下面具体分析如何写第一部分:
主控芯片的i2c驱动分为2个步骤:
写总线驱动:
选了个主控芯片,比如:S3C8900(自己瞎编的芯片)
在driver/i2c/busses/i2c-s3c2410.c中没有找到这个芯片的I2C支持(总线驱动支持)。。。(倒霉了,没有选好芯片,也可能是最新型号的,linux内核没跟上)
在此之前先分析i2c-s3c2410.c中完成的工作(总线驱动):
  • 设计对应于i2c_adapter_xxx_init()模板的s3c8900的模块加载函数和对应于i2c_adapter_xxx_exit()函数模板的模块卸载函数。
  • 设计对应于i2c_adapter_xxx_xfer()模板的 s3c8900适配器的通信方法函数,针对 s3c24xx、64xx、s5pc1XX、s5p64xx处理器functionality()函数s3c24xx_i2c-func()只需简单的返回I2C_FUNC_I2C|I2C_FUNC_SMBUS_EMUL|I2C_FUNC_PROTOCOL_MANGLING表明其支持的功能
 
话说没找到总线驱动支持,(这倒霉孩子)那就得编写个类似的i2c-s3c8900.c的总线驱动支持,嘿嘿,照着上面的功能写吧,反正是总线驱动。
写吧,还等啥啊!!~~~~~
  • I2C适配器驱动加载与卸载 
  1. 初始化i2c适配器所使用的硬件资源,如申请I/O地址、中断号等
  2. 通过i2c_add_adapter添加i2c_adapter数据结构,当然这个数据结构的成员已经被xxx适配器的相应的函数指针所初始化
  3. i2c总线卸载模块与装载相反,是否i2c适配器使用的硬件资源,通过i2c_del_adapter删除i2c_adapter的数据结构
        模板如下:    
            static int __init i2c_adapter_xxx_init(void)
                {
                   xxx_adapter_hw_init();//初始化硬件资源
                    i2c_add_adapter(&xxx_adapter);
                }
                    static void __init i2c_adapter_xxx_exit(void)
                        {
        xxx_adapter_hw_free();//释放硬件资源
                            i2c_del_adapter(&xxx_adapter);
                            }
            具体CPU具体分析,有的用platform做的,可以参考6410的做法
  • I2C总线的通信方法
                我们需要为特定的i2c适配器实现其通信方法,主要实现i2c_algorithm的master_xfer()函数和functionality()函数
                functionality函数很简单,用于返回algorithm所支持的通信协议,如:I2C_FUCN-_I2C ,                            I2C_FUNC_10BIT_ADDR,I2C_FUNC_SMBUS_READ_BYTE,I2C_FUNC_SMBUS_write_byte等
                master_xfer函数在i2c适配器上完成传递给他的i2c_msg数组中的每个i2c消息。
        
            模板如下:
            
            static int i2c_adapter_xxx_xfer(struct i2c_adapter *adap,struct i2c_msg *msgs, int num)
                {
                    ......
                    for(i = 0; i<num ; i++){
                        i2c_adapter_xxx_start(); //产生开始位
                        //如果是读消息
                        if(msg[i]->falgs &I2C_M_RD){
                        i2c_adapter_xxx_setaddr((msg->addr<<1)|1); //发送从设备读地址
                         i2c_adapter_xxx_wait_ack();//获取从设备的ack信息
                         i2c_adapter_xxx_readbytes(msgs[i]->buf,msgs[i]->len);//读取msg[i]->len长的数据到msg[i]->buf里
                            }    else{    //是写消息
                              i2c_adapter_xxx_setaddr((msg->addr<<1)|1); //发送从设备写地址
                             i2c_adapter_xxx_wait_ack();//获取从设备的ack信息
                             i2c_adapter_xxx_readbytes(msgs[i]->buf,msgs[i]->len);//读取msg[i]->len长的数据到msg[i]->buf里
                                }        
                            }
                        i2c_adapter_xxx_stop(); //产生停止位
     }
 
 
好啦,完成了装载和卸载,又完成了通信方法这两个重要的东东,那么总线驱动结构已经完成啦,累死了!
 
第三部分准备具体写个驱动程序看看,呵呵
posted on 2012-12-05 19:06  孟浩依然  阅读(3475)  评论(0编辑  收藏  举报