欧美亚洲一区二区三区,午夜欧美艳情视频免费看,欧美XXXXX又粗又大,国精品产露脸偷拍视频

技術(shù)文摘

Linux I2C驅(qū)動(dòng)分析(二)——I2C板級設(shè)備掃描和數(shù)據(jù)傳輸












一、板級設(shè)備掃描

針對上一篇文章最后的i2c_scan_static_board_info(adap)函數(shù)處,首先先看下在系統(tǒng)啟動(dòng)的時(shí)候板級設(shè)備的注冊。

針對我現(xiàn)在使用的開發(fā)板,對于I2C設(shè)備注冊程序如下:

1.     static struct i2c_board_info i2c_devices_info[] = {

2.     #ifdef CONFIG_SND_SOC_ALC5623

3.             {

4.                     I2C_BOARD_INFO("alc5623", 0x1a),

5.                     .platform_data = &alc5623_data,

6.             },

7.     #endif

8.     #ifdef CONFIG_RTC_DRV_DS3231M

9.             {

10.                    I2C_BOARD_INFO("ds3231m", 0x68),

11.                    .platform_data = NULL,

12.            },

13.    #endif

14.    #ifdef CONFIG_RTC_DRV_PCF8563

15.            {

16.                    I2C_BOARD_INFO("pcf8563", 0x51),

17.                    .platform_data = NULL,

18.            },

19.    #endif

20.    };

21.    static int __init gsc3280_i2c_devices_init(void)

22.    {

23.        i2c_register_board_info(0, i2c_devices_info, ARRAY_SIZE(i2c_devices_info));

24.        return 0;

25.    }

26.    device_initcall(gsc3280_i2c_devices_init);


在這里總共有三個(gè)I2C設(shè)備,名稱分別為alc5623、ds3231m和pcf8563。宏I2C_BOARD_INFO的功能就是設(shè)置I2C設(shè)備的名稱和地址,由device_initcall可以看出,gsc3280_i2c_devices_init()函數(shù)在系統(tǒng)啟動(dòng)的時(shí)候就會(huì)被調(diào)用,i2c_register_board_info()函數(shù)完成板級設(shè)備的注冊,程序如下:

1.     DECLARE_RWSEM(__i2c_board_lock);

2.     EXPORT_SYMBOL_GPL(__i2c_board_lock);

3.      

4.     LIST_HEAD(__i2c_board_list);

5.     EXPORT_SYMBOL_GPL(__i2c_board_list);

6.      

7.     int __i2c_first_dynamic_bus_num;

8.     EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num);

9.      

10.    int __init

11.    i2c_register_board_info(int busnum,

12.        struct i2c_board_info const *info, unsigned len)

13.    {

14.        int status;

15.        down_write(&__i2c_board_lock);

16.        /* dynamic bus numbers will be assigned after the last static one */

17.        if (busnum >= __i2c_first_dynamic_bus_num)

18.            __i2c_first_dynamic_bus_num = busnum + 1;

19.        for (status = 0; len; len--, info++) {

20.            struct i2c_devinfo    *devinfo;

21.            devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);

22.            if (!devinfo) {

23.                pr_debug("i2c-core: can't register boardinfo!\n");

24.                status = -ENOMEM;

25.                break;

26.            }

27.            devinfo->busnum = busnum;

28.            devinfo->board_info = *info;

29.            list_add_tail(&devinfo->list, &__i2c_board_list);

30.        }

31.        up_write(&__i2c_board_lock);

32.        return status;

33.    }


上面的程序位于i2c-boardinfo.c中,i2c_register_board_info()函數(shù)的for循環(huán)中,首先會(huì)申請I2C設(shè)備信息結(jié)構(gòu)體,如果申請成功,將I2C總線號和設(shè)備信息賦值給設(shè)備信息結(jié)構(gòu)體,并且將設(shè)備信息結(jié)構(gòu)體的鏈表插入到__i2c_board_list中,此處尤為重要,在本文的開頭中所提的函數(shù)i2c_scan_static_board_info(adap);,此函數(shù)就是通過__i2c_board_list鏈表找到上面注冊的設(shè)備信息,結(jié)合gsc3280_i2c_devices_init()函數(shù)和i2c_devices_info結(jié)構(gòu)體,此處for循環(huán)的len為3,即正常情況下需要?jiǎng)?chuàng)建三個(gè)devinfo結(jié)構(gòu)體,for循環(huán)結(jié)束后,__i2c_board_list鏈表中也就有了三個(gè)I2C設(shè)備的鏈表項(xiàng),在程序的其他地方如果需要使用這里注冊的設(shè)備結(jié)構(gòu)信息,只需要遍歷鏈表__i2c_board_list,通過總線號即可找到相應(yīng)的設(shè)備信息。

接下來就可以看下函數(shù)i2c_scan_static_board_info(adap):

1.   static void i2c_scan_static_board_info(struct i2c_adapter *adapter)

2.   {

3.       struct i2c_devinfo    *devinfo;

4.       down_read(&__i2c_board_lock);

5.       list_for_each_entry(devinfo, &__i2c_board_list, list) {

6.           if (devinfo->busnum == adapter->nr

7.                   && !i2c_new_device(adapter,

8.                           &devinfo->board_info))

9.               dev_err(&adapter->dev,

10.                  "Can't create device at 0x%02x\n",

11.                  devinfo->board_info.addr);

12.      }

13.      up_read(&__i2c_board_lock);

14.  }


從上面程序可以看到,語句list_for_each_entry(devinfo, &__i2c_board_list, list) 實(shí)現(xiàn)對__i2c_board_list的遍歷,if語句的前半部分“devinfo->busnum ==adapter->nr”判斷是否是需要尋找的結(jié)構(gòu)體,如果是,就調(diào)用函數(shù)i2c_new_device()創(chuàng)建新的I2C設(shè)備,i2c_new_device函數(shù)如下:

1.   struct i2c_client *

2.   i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)

3.   {

4.       struct i2c_client    *client;

5.       int            status;

6.       client = kzalloc(sizeof *client, GFP_KERNEL);

7.       if (!client)

8.           return NULL;

9.       client->adapter = adap;

10.      client->dev.platform_data = info->platform_data;

11.      if (info->archdata)

12.          client->dev.archdata = *info->archdata;

13.      client->flags = info->flags;

14.      client->addr = info->addr;

15.      client->irq = info->irq;

16.      strlcpy(client->name, info->type, sizeof(client->name));

17.      /* Check for address validity */

18.      status = i2c_check_client_addr_validity(client);

19.      if (status) {

20.          dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n",

21.              client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);

22.          goto out_err_silent;

23.      }

24.      /* Check for address business */

25.      status = i2c_check_addr_busy(adap, client->addr);

26.      if (status)

27.          goto out_err;

28.      client->dev.parent = &client->adapter->dev;

29.      client->dev.bus = &i2c_bus_type;

30.      client->dev.type = &i2c_client_type;

31.      client->dev.of_node = info->of_node;

32.      dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),

33.           client->addr);

34.      status = device_register(&client->dev);

35.      if (status)

36.          goto out_err;

37.      dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",

38.          client->name, dev_name(&client->dev));

39.      return client;

40.  out_err:

41.      dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "

42.          "(%d)\n", client->name, client->addr, status);

43.  out_err_silent:

44.      kfree(client);

45.      return NULL;

46.  }

47.  EXPORT_SYMBOL_GPL(i2c_new_device);


從函數(shù)i2c_new_device()中可以看到,此函數(shù)創(chuàng)建了i2c_client結(jié)構(gòu)體,對結(jié)構(gòu)體的內(nèi)容進(jìn)行了注冊,設(shè)備信息進(jìn)行了填充,對于本文所使用的開發(fā)板,如果程序執(zhí)行正常,系統(tǒng)啟動(dòng)成功后,在內(nèi)存中就有了三個(gè)

i2c_client結(jié)構(gòu)體了,分別對應(yīng)alc5623、ds3231m和pcf8563。

到此位置,I2C總線驅(qū)動(dòng),I2C設(shè)備的注冊和相應(yīng)結(jié)構(gòu)體的申請就已經(jīng)完成了,接下來看下常用的I2C數(shù)據(jù)傳輸函數(shù),I2C設(shè)備驅(qū)動(dòng)主要調(diào)用這些數(shù)據(jù)傳輸接口完成數(shù)據(jù)的傳輸。







二、I2C數(shù)據(jù)傳輸

I2C數(shù)據(jù)傳輸分為兩種,一種為符合I2C協(xié)議的普通數(shù)據(jù)傳輸,另外一種為符合SMBUS協(xié)議的數(shù)據(jù)傳輸,接下來我們首先看下符合I2C協(xié)議的普通數(shù)據(jù)傳輸。

1、I2C協(xié)議的普通數(shù)據(jù)傳輸

I2C協(xié)議普通數(shù)據(jù)傳輸?shù)慕涌诤瘮?shù)基本為i2c_master_send和i2c_master_recv,查看其函數(shù)發(fā)現(xiàn),最后都是調(diào)用i2c_transfer函數(shù)實(shí)現(xiàn)傳輸?shù)模琲2c_transfer函數(shù)如下:

1.     int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)

2.     {

3.         int ret;

4.         if (adap->algo->master_xfer) {

5.     #ifdef DEBUG

6.             for (ret = 0; ret < num; ret++) {

7.                 dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "

8.                     "len=%d%s/n", ret, (msgs[ret].flags & I2C_M_RD)

9.                     ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,

10.                    (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");

11.            }

12.    #endif

13.            if (in_atomic() || irqs_disabled()) {

14.                ret = mutex_trylock(&adap->bus_lock);

15.                if (!ret)

16.                    /* I2C activity is ongoing. */

17.                    return -EAGAIN;

18.            } else {

19.                mutex_lock_nested(&adap->bus_lock, adap->level);

20.            }

21.            ret = adap->algo->master_xfer(adap,msgs,num);

22.            mutex_unlock(&adap->bus_lock);

23.            return ret;

24.        } else {

25.            dev_dbg(&adap->dev, "I2C level transfers not supported/n");

26.            return -ENOSYS;

27.        }

28.    }


因?yàn)樵谶@里的同步用的是mutex。首先判斷是否允許睡眠,如果不允許,嘗試獲鎖,如果獲鎖失敗,則返回。這樣的操作是避免進(jìn)入睡眠,我們在后面也可以看到,實(shí)際的傳輸工作交給了adap->algo->master_xfer()完成,也就是我們在(一)中注冊的algorithm中的i2c_gsc_func函數(shù)。


2SMBUS協(xié)議I2C數(shù)據(jù)傳輸

SMBUS協(xié)議的具體內(nèi)容可以參考網(wǎng)絡(luò),在I2C驅(qū)動(dòng)中,符合SMBUS協(xié)議傳輸?shù)暮瘮?shù)很多,包括i2c_smbus_read_byte、i2c_smbus_write_byte、i2c_smbus_read_byte_data、i2c_smbus_write_byte_data、i2c_smbus_read_word_data和i2c_smbus_write_word_data等,閱讀這些函數(shù)發(fā)現(xiàn),程序里面都是根據(jù)SMBUS協(xié)議和函數(shù)功能,完成對函數(shù)i2c_smbus_xfer形參的賦值,最后調(diào)用此函數(shù)來實(shí)現(xiàn)傳輸。接下來看下i2c_smbus_xfer函數(shù):

1.   s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,

2.            char read_write, u8 command, int protocol,

3.            union i2c_smbus_data *data)

4.   {

5.       unsigned long orig_jiffies;

6.       int try;

7.       s32 res;

8.       flags &= I2C_M_TEN | I2C_CLIENT_PEC;

9.       if (adapter->algo->smbus_xfer) {

10.          i2c_lock_adapter(adapter);

11.          /* Retry automatically on arbitration loss */

12.          orig_jiffies = jiffies;

13.          for (res = 0, try = 0; try <= adapter->retries; try++) {

14.              res = adapter->algo->smbus_xfer(adapter, addr, flags,

15.                              read_write, command,

16.                              protocol, data);

17.              if (res != -EAGAIN)

18.                  break;

19.              if (time_after(jiffies,

20.                   orig_jiffies + adapter->timeout))

21.                  break;

22.          }

23.          i2c_unlock_adapter(adapter);

24.      } else

25.          res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,

26.                       command, protocol, data);

27.      return res;

28.  }


如果adapter有smbus_xfer()函數(shù),則直接調(diào)用它發(fā)送數(shù)據(jù)。否則也就是在adapter不支持smbus協(xié)議的情況下,調(diào)用i2c_smbus_xfer_emulated()繼續(xù)處理。根據(jù)(一)中的總線驅(qū)動(dòng)是不支持smbus協(xié)議的。繼續(xù)看函數(shù)i2c_smbus_xfer_emulated。

1.    static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,

2.                                      unsigned short flags,

3.                                      char read_write, u8 command, int size,

4.                                      union i2c_smbus_data * data)

5.    {

6.        /* So we need to generate a series of msgs. In the case of writing, we

7.          need to use only one message; when reading, we need two. We initialize

8.          most things with sane defaults, to keep the code below somewhat

9.          simpler. */

10.      //寫操作只會(huì)進(jìn)行一次交互,而讀操作,有時(shí)會(huì)有兩次操作.

11.      //因?yàn)橛袝r(shí)候讀操作要先寫command,再從總線上讀數(shù)據(jù)

12.      //在這里為了代碼的簡潔,使用了兩個(gè)緩存區(qū),將兩種情況統(tǒng)一起來.

13.      unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];

14.      unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];

15.      //一般來說,讀操作要交互兩次,例外的情況我們在下面會(huì)接著分析

16.      int num = read_write == I2C_SMBUS_READ?2:1;

17.      //與設(shè)備交互的數(shù)據(jù),一般在msg[0]存放寫入設(shè)備的信息,在msb[1]里存放接收到的

18.      //信息,不過也有例外的

19.      //msg[2]的初始化,默認(rèn)發(fā)送緩存區(qū)占一個(gè)字節(jié),無接收緩存

20.      struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },

21.                                { addr, flags | I2C_M_RD, 0, msgbuf1 }

22.                              };

23.      int i;

24.      u8 partial_pec = 0;

25.      //將要發(fā)送的信息copy到發(fā)送緩存區(qū)的第一字節(jié)

26.      msgbuf0[0] = command;

27.      switch(size) {

28.          //quick類型,它并不傳輸有效數(shù)據(jù),只是將地址寫到總線上,等待應(yīng)答即可

29.          //所以將發(fā)送緩存區(qū)長度置為0。再根據(jù)讀/寫操作,調(diào)整msg[0]的標(biāo)志位

30.          //這類傳輸只需要一次總線交互

31.      case I2C_SMBUS_QUICK:

32.          msg[0].len = 0;

33.          /* Special case: The read/write field is used as data */

34.          msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0;

35.          num = 1;

36.          break;

37.      case I2C_SMBUS_BYTE:

38.          //BYTE類型指一次寫和讀只有一個(gè)字節(jié).這種情況下,讀和寫都只會(huì)交互一次

39.          //這種類型的讀有例外,它讀取出來的數(shù)據(jù)不是放在msg[1]中的,而是存放在msg[0]

40.          if (read_write == I2C_SMBUS_READ) {

41.              /* Special case: only a */

42.              msg[0].flags = I2C_M_RD | flags;

43.              num = 1;

44.          }

45.          break;

46.      case I2C_SMBUS_BYTE_DATA:

47.          //Byte_Data是指命令+數(shù)據(jù)的傳輸形式,在這種情況下,寫只需要一次交互,讀卻要兩次

48.          //第一次將command寫到總線上,第二次要轉(zhuǎn)換方向,要將設(shè)備地址和read標(biāo)志寫入總線.

49.          //應(yīng)回答之后再進(jìn)行read操作

50.          //寫操作占兩字節(jié),分別是command+data,讀操作的有效數(shù)據(jù)只有一個(gè)字節(jié)

51.          //交互次數(shù)用初始化值就可以了

52.          if (read_write == I2C_SMBUS_READ)

53.              msg[1].len = 1;

54.          else {

55.              msg[0].len = 2;

56.              msgbuf0[1] = data->byte;

57.          }

58.          break;

59.      case I2C_SMBUS_WORD_DATA:

60.          //Word_Data是指命令+雙字節(jié)的形式.這種情況跟Byte_Data的情況類似

61.          //兩者相比只是交互的數(shù)據(jù)大小不同

62.          if (read_write == I2C_SMBUS_READ)

63.              msg[1].len = 2;

64.          else {

65.              msg[0].len=3;

66.              msgbuf0[1] = data->word & 0xff;

67.              msgbuf0[2] = data->word >> 8;

68.          }

69.          break;

70.      case I2C_SMBUS_PROC_CALL:

71.          //Proc_Call的方式與write 的Word_Data相似,只不過寫完Word_Data之后,要等待它的應(yīng)答

72.          //應(yīng)該它需要交互兩次,一次寫一次讀

73.          num = 2; /* Special case */

74.          read_write = I2C_SMBUS_READ;

75.          msg[0].len = 3;

76.          msg[1].len = 2;

77.          msgbuf0[1] = data->word & 0xff;

78.          msgbuf0[2] = data->word >> 8;

79.          break;

80.      case I2C_SMBUS_BLOCK_DATA:

81.          //Block_Data:指command+N段數(shù)據(jù)的情況.

82.          //如果是讀操作,它首先要寫command到總線,然后再讀N段數(shù)據(jù),要寫的command已經(jīng)

83.          //放在msg[0]了,現(xiàn)在只需要將msg[1]的標(biāo)志置I2C_M_RECV_LEN位,msg[1]有效長度為1字節(jié),因?yàn)?/span>

84.          //adapter驅(qū)動(dòng)會(huì)處理好的,現(xiàn)在還不知道要傳多少段數(shù)據(jù).

85.          //對于寫的情況:msg[1]照例不需要.將要寫的數(shù)據(jù)全部都放到msb[0]中.相應(yīng)的也要更新

86.          //msg[0]中的緩存區(qū)長度

87.          if (read_write == I2C_SMBUS_READ) {

88.              msg[1].flags |= I2C_M_RECV_LEN;

89.              msg[1].len = 1; /* block length will be added by

90.                        the underlying bus driver */

91.          } else {

92.              //data->block[0]表示后面有多少段數(shù)據(jù).總長度要加2是因?yàn)閏ommand+count+N段數(shù)據(jù)

93.              msg[0].len = data->block[0] + 2;

94.              if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {

95.                  dev_err(&adapter->dev, "smbus_access called with "

96.                        "invalid block write size (%d)/n",

97.                        data->block[0]);

98.                  return -1;

99.              }

100.            for (i = 1; i < msg[0].len; i++)

101.                msgbuf0 = data->block[i-1];

102.        }

103.        break;

104.    case I2C_SMBUS_BLOCK_PROC_CALL:

105.        //Proc_Call:表示寫完Block_Data之后,要等它的應(yīng)答消息它和Block_Data相比,只是多了一部份應(yīng)答而已

106.        num = 2; /* Another special case */

107.        read_write = I2C_SMBUS_READ;

108.        if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {

109.            dev_err(&adapter->dev, "%s called with invalid "

110.                "block proc call size (%d)/n", __func__,

111.                data->block[0]);

112.            return -1;

113.        }

114.        msg[0].len = data->block[0] + 2;

115.        for (i = 1; i < msg[0].len; i++)

116.            msgbuf0 = data->block[i-1];

117.        msg[1].flags |= I2C_M_RECV_LEN;

118.        msg[1].len = 1; /* block length will be added by

119.                  the underlying bus driver */

120.        break;

121.    case I2C_SMBUS_I2C_BLOCK_DATA:

122.        //I2c Block_Data與Block_Data相似,只不過read的時(shí)候,數(shù)據(jù)長度是預(yù)先定義好了的.另外

123.        //與Block_Data相比,中間不需要傳輸Count字段.(Count表示數(shù)據(jù)段數(shù)目)

124.        if (read_write == I2C_SMBUS_READ) {

125.            msg[1].len = data->block[0];

126.        } else {

127.            msg[0].len = data->block[0] + 1;

128.            if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {

129.                dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with "

130.                      "invalid block write size (%d)/n",

131.                      data->block[0]);

132.                return -1;

133.            }

134.            for (i = 1; i <= data->block[0]; i++)

135.                msgbuf0 = data->block;

136.        }

137.        break;

138.    default:

139.        dev_err(&adapter->dev, "smbus_access called with invalid size (%d)/n",

140.              size);

141.        return -1;

142.    }

143.    //如果啟用了PEC.Quick和I2c Block_Data是不支持PEC的

144.    i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK

145.                      && size != I2C_SMBUS_I2C_BLOCK_DATA);

146.    if (i) {

147.        /* Compute PEC if first message is a write */

148.        //如果第一個(gè)操作是寫操作

149.        if (!(msg[0].flags & I2C_M_RD)) {

150.            //如果只是寫操作

151.            if (num == 1) /* Write only */

152.                //如果只有寫操作,寫緩存區(qū)要擴(kuò)充一個(gè)字節(jié),用來存放計(jì)算出來的PEC

153.                i2c_smbus_add_pec(&msg[0]);

154.            else /* Write followed by read */

155.                //如果后面還有讀操作,先計(jì)算前面寫部份的PEC(注意這種情況下不需要

156.                //擴(kuò)充寫緩存區(qū),因?yàn)椴恍枰l(fā)送PEC.只會(huì)接收到PEC)

157.                partial_pec = i2c_smbus_msg_pec(0, &msg[0]);

158.        }

159.        /* Ask for PEC if last message is a read */

160.        //如果最后一次是讀消息.還要接收到來自slave的PEC.所以接收緩存區(qū)要擴(kuò)充一個(gè)字節(jié)

161.        if (msg[num-1].flags & I2C_M_RD)

162.            msg[num-1].len++;

163.    }

164.    if (i2c_transfer(adapter, msg, num) < 0)

165.        return -1;

166.    /* Check PEC if last message is a read */

167.    //操作完了之后,如果最后一個(gè)操作是PEC的讀操作.檢驗(yàn)后面的PEC是否正確

168.    if (i && (msg[num-1].flags & I2C_M_RD)) {

169.        if (i2c_smbus_check_pec(partial_pec, &msg[num-1]) < 0)

170.            return -1;

171.    }

172.    //操作完了,現(xiàn)在可以將數(shù)據(jù)放到data部份返回了.

173.    if (read_write == I2C_SMBUS_READ)

174.        switch(size) {

175.            case I2C_SMBUS_BYTE:

176.                data->byte = msgbuf0[0];

177.                break;

178.            case I2C_SMBUS_BYTE_DATA:

179.                data->byte = msgbuf1[0];

180.                break;

181.            case I2C_SMBUS_WORD_DATA:

182.            case I2C_SMBUS_PROC_CALL:

183.                data->word = msgbuf1[0] | (msgbuf1[1] << 8);

184.                break;

185.            case I2C_SMBUS_I2C_BLOCK_DATA:

186.                for (i = 0; i < data->block[0]; i++)

187.                    data->block[i+1] = msgbuf1;

188.                break;

189.            case I2C_SMBUS_BLOCK_DATA:

190.            case I2C_SMBUS_BLOCK_PROC_CALL:

191.                for (i = 0; i < msgbuf1[0] + 1; i++)

192.                    data->block = msgbuf1;

193.                break;

194.        }

195.    return 0;

196.}


此處也是調(diào)用i2c_transfer函數(shù)實(shí)現(xiàn)數(shù)據(jù)的最終傳輸?shù)?,在上面已?jīng)講述了此函數(shù)。







原文請參見:http://blog.chinaunix.net/uid-25445243-id-3916323.html