《RTC驱动总结》

一、driver

RTC使用内核I2C子系统、RTC子系统、SYSFS接口技术。

1.      i2c子系统

a.本设备采用16寄存器地址,在构造消息时地址为word;

struct i2c_msg {

     __u16 addr;    /* slave address                    */

     __u16 flags;

     __u16 len;             /*msg length                       */

     __u8 *buf;             /*pointer to msg data                  */

};

按照时序图构建消息,从机地址注册设备时已确定,flags需要注意读/写;

static intisl12027_read_regs(struct i2c_client*client, uint16_t reg,

                             uint8_t *data,size_t n)

{

uint8_t buf[2]={reg>>8,reg&0xff};

       struct i2c_msg msgs[] = {

               {

                       .addr   = client->addr,

.flags  = 0,/*write*/

.len   = 2,

                       .buf    = buf

               },              /* setup read ptr */

               {

                       .addr   = client->addr,

                       .flags  = I2C_M_RD,

.len    = n,

.buf    = data

               }

       };


       int ret;

       ret = i2c_transfer(client->adapter, msgs,ARRAY_SIZE(msgs));

       if (ret != ARRAY_SIZE(msgs)) {

               dev_err(&client->dev,"%s: read error, ret=%d\n",

                       __func__, ret);

               return -EIO;

       }

       return 0;

}

static intisl12027_write_reg(struct i2c_client*client,

                             uint16_t reg,uint8_t val)

{

       int ret;

       uint8_tdata[]={reg>>8,reg&0xff,val};

       struct i2c_msg msgs[] = {

               {

                       .addr   = client->addr,

                       .flags  = 0,

                       .len    = 3,

                       .buf    = data

               }

       };

        ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));

       if (ret != ARRAY_SIZE(msgs)) {

               dev_err(&client->dev,

                       "%s: ret=%dregH=%02x, regL=%02x,val=%02x\n",

                       __func__, ret, data[0],data[1],data[2]);

               return -EIO;

       }

       return 0;

}

b.

2.      RTC子系统

Linux系统把各种机制或者子系统抽象出来,达到低耦合,易扩展,这里暂且按组件来理解,下面是RTC常和那些“组件”组合来完成,device成为他们的纽带。

这里以I2C接口RTC为例:

Linux把按分层思想构建RTC子系统(其它子系统也一样),采用面向对象思想实现。

a.      分层思想

Linux系统实现了对用户的接口,设备访问、SYS访问,PROC访问,并提供了抽象接口,已达到上层不变,接口中使用了多态使得可以支持不同的设备,

rtc->ops->read_time(rtc->dev.parent,tm);

在创建对象时动态绑定:


rtc_device_register(isl1208_driver.driver.name,

                           &client->dev, &isl1208_rtc_ops,

                           THIS_MODULE);

这个是构造函数来创建对象,他实现动态绑定;

rtc->id = id;

    rtc->ops = ops;

    rtc->owner = owner;

    rtc->max_user_freq = 64;

    rtc->dev.parent = dev;

    rtc->dev.class = rtc_class;

    rtc->dev.release = rtc_device_release;

b.      面向对象


你可能感兴趣的:(linux,driver)