1. 程式人生 > >Linux裝置驅動程式架構分析之一個I2C驅動例項

Linux裝置驅動程式架構分析之一個I2C驅動例項

作者:劉昊昱 

核心版本:3.10.1

編寫一個I2C裝置驅動程式的工作可分為兩部分,一是定義和註冊I2C裝置,即i2c_client;二是定義和註冊I2C裝置驅動,即i2c_driver。下面我們就以mini2440的I2C裝置at24c08 EEPROM為例,介紹如何完成這兩個工作。

一、定義和註冊I2C裝置

步驟1:用i2c_board_info儲存I2C裝置相關資訊

在Linux中,struct i2c_client代表一個I2C裝置,該結構體定義在include/linux/i2c.h檔案中:

200/**
201 * struct i2c_client - represent an I2Cslave device
202 * @flags: I2C_CLIENT_TEN indicates thedevice uses a ten bit chip address;
203 * I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking
204 * @addr: Address used on the I2C busconnected to the parent adapter.
205 * @name: Indicates the type of thedevice, usually a chip name that's
206 * generic enough to hide second-sourcing and compatible revisions.
207 * @adapter: manages the bus segmenthosting this I2C device
208 * @driver: device's driver, hencepointer to access routines
209 * @dev: Driver model device node forthe slave.
210 * @irq: indicates the IRQ generated bythis device (if any)
211 * @detected: member of ani2c_driver.clients list or i2c-core's
212 * userspace_devices list
213 *
214 * An i2c_client identifies a singledevice (i.e. chip) connected to an
215 * i2c bus. The behaviour exposed to Linuxis defined by the driver
216 * managing the device.
217 */
218struct i2c_client {
219   unsigned short flags;       /*div., see below      */
220   unsigned short addr;        /*chip address - NOTE: 7bit    */
221                    /* addresses are stored inthe  */
222                    /* _LOWER_ 7 bits       */
223   char name[I2C_NAME_SIZE];
224   struct i2c_adapter *adapter;    /*the adapter we sit on    */
225   struct i2c_driver *driver;  /* andour access routines  */
226   struct device dev;      /* thedevice structure     */
227   int irq;            /* irq issuedby device     */
228   struct list_head detected;
229};


我們不用直接定義一個i2c_client結構,Linux會根據I2C裝置的相關資訊自動建立i2c_client。所以,我們需要提供I2C裝置的相關資訊。對於Mini2440的I2C裝置at24c08 EEPROM,其相關資訊儲存在arch/arm/mach-s3c24xx/mach-mini2440.c檔案中:

485/*
486 * I2C devices
487 */
488static struct at24_platform_data at24c08= {
489   .byte_len   = SZ_8K / 8,
490   .page_size  = 16,
491};
492
493static struct i2c_board_infomini2440_i2c_devs[] __initdata = {
494   {
495       I2C_BOARD_INFO("24c08", 0x50),
496       .platform_data = &at24c08,
497   },
498};


struct i2c_board_info是建立i2c裝置的模板,該結構體定義在include/linux/i2c.h檔案中:

251/**
252 * struct i2c_board_info - template fordevice creation
253 * @type: chip type, to initializei2c_client.name
254 * @flags: to initializei2c_client.flags
255 * @addr: stored in i2c_client.addr
256 * @platform_data: stored ini2c_client.dev.platform_data
257 * @archdata: copied intoi2c_client.dev.archdata
258 * @of_node: pointer to OpenFirmwaredevice node
259 * @acpi_node: ACPI device node
260 * @irq: stored in i2c_client.irq
261 *
262 * I2C doesn't actually support hardwareprobing, although controllers and
263 * devices may be able to useI2C_SMBUS_QUICK to tell whether or not there's
264 * a device at a given address.  Drivers commonly need more information than
265 * that, such as chip type,configuration, associated IRQ, and so on.
266 *
267 * i2c_board_info is used to buildtables of information listing I2C devices
268 * that are present.  This information is used to grow the drivermodel tree.
269 * For mainboards this is donestatically using i2c_register_board_info();
270 * bus numbers identify adapters thataren't yet available.  For add-on boards,
271 * i2c_new_device() does thisdynamically with the adapter already known.
272 */
273struct i2c_board_info {
274   char        type[I2C_NAME_SIZE];
275   unsigned short  flags;
276   unsigned short  addr;
277   void        *platform_data;
278   struct dev_archdata *archdata;
279   struct device_node *of_node;
280   struct acpi_dev_node acpi_node;
281   int     irq;
282};


從註釋可以看到,i2c_board_info結構體用來儲存I2C裝置的相關資訊,Linux根據這些資訊建立I2C裝置相關的裝置模型樹。對於mainboards,通過呼叫i2c_register_board_info()靜態完成。對於add-on boards,通過呼叫i2c_new_device()動態完成。

i2c_board_info結構體有兩個成員必須初始化,一個是type,用來初始化i2c_client.name;另一個是addr,用來初始化i2c_client.addr。其它i2c_board_info結構體成員根據需要賦值或保持為空。

巨集I2C_BOARD_INFO定義在include/linux/i2c.h檔案中,其內容如下:

284/**
285 * I2C_BOARD_INFO - macro used to listan i2c device and its address
286 * @dev_type: identifies the device type
287 * @dev_addr: the device's address onthe bus.
288 *
289 * This macro initializes essentialfields of a struct i2c_board_info,
290 * declaring what has been provided on aparticular board.  Optional
291 * fields (such as associated irq, ordevice-specific platform_data)
292 * are provided using conventionalsyntax.
293 */
294#define I2C_BOARD_INFO(dev_type,dev_addr) \
295   .type = dev_type, .addr = (dev_addr)


從註釋可以看到,I2C_BOARD_INFO巨集用來初始化i2c_board_info結構體的兩個必須初始化的成員變數type和addr。i2c_board_info結構體的其它成員變數使用常規的初始化語法。

struct at24_platform_data定義在include/linux/i2c/at24.h檔案中:

1

4/**
15 * struct at24_platform_data - data toset up at24 (generic eeprom) driver
16 * @byte_len: size of eeprom in byte
17 * @page_size: number of byte which canbe written in one go
18 * @flags: tunable options, checkAT24_FLAG_* defines
19 * @setup: an optional callback invokedafter eeprom is probed; enables kernel
20   code to access eeprom via memory_accessor, see example
21 * @context: optional parameter passed tosetup()
22 *
23 * If you set up a custom eeprom type,please double-check the parameters.
24 * Especially page_size needs extra care,as you risk data loss if your value
25 * is bigger than what the chip actuallysupports!
26 *
27 * An example in pseudo code for asetup() callback:
28 *
29 * void get_mac_addr(structmemory_accessor *mem_acc, void *context)
30 * {
31 * u8 *mac_addr = ethernet_pdata->mac_addr;
32 * off_t offset = context;
33 *
34 * // Read MAC addr from EEPROM
35 * if (mem_acc->read(mem_acc, mac_addr, offset, ETH_ALEN) == ETH_ALEN)
36 *     pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr);
37 * }
38 *
39 * This function pointer and context cannow be set up in at24_platform_data.
40 */
41
42struct at24_platform_data {
43   u32     byte_len;       /* size (sum of all addr) */
44   u16     page_size;      /* for writes */
45   u8      flags;
46#define AT24_FLAG_ADDR16    0x80   /* address pointer is 16 bit */
47#define AT24_FLAG_READONLY  0x40   /* sysfs-entry will be read-only */
48#define AT24_FLAG_IRUGO     0x20   /* sysfs-entry will be world-readable */
49#define AT24_FLAG_TAKE8ADDR 0x10    /* take always 8 addresses (24c00) */
50
51   void        (*setup)(structmemory_accessor *, void *context);
52   void        *context;
53};

該結構體用來儲存at24系列EEPROM的platform data。byte_len成員變數儲存EEPROM的大小,以byte為單位。page_size成員變數用來指定一次最多能寫多少個byte。對於Mini2440,定義at24_platform_data結構體變數at24c08:

488static struct at24_platform_data at24c08= {
489   .byte_len   = SZ_8K / 8,
490   .page_size  = 16,
491};


SZ_8K巨集即8K,定義在include/linux/sizes.h檔案中:

25#define SZ_8K               0x00002000


步驟2:呼叫i2c_register_board_info註冊i2c裝置相關資訊

對於Mini2440的I2C裝置at24c08 EEPROM,由arch/arm/mach-s3c24xx/mach-mini2440.c檔案中的mini2440_init函式呼叫i2c_register_board_info註冊i2c裝置相關資訊,mini2440_init函式內容如下:

622static void __init mini2440_init(void)
623{
624   struct mini2440_features_t features = { 0 };
625   int i;
626
627   printk(KERN_INFO "MINI2440: Option string mini2440=%s\n",
628            mini2440_features_str);
629
630   /* Parse the feature string */
631   mini2440_parse_features(&features, mini2440_features_str);
632
633   /* turn LCD on */
634   s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
635
636   /* Turn the backlight early on */
637   WARN_ON(gpio_request_one(S3C2410_GPG(4), GPIOF_OUT_INIT_HIGH, NULL));
638   gpio_free(S3C2410_GPG(4));
639
640   /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s*/
641   gpio_request_one(S3C2410_GPB(1), GPIOF_IN, NULL);
642   s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
643   gpio_free(S3C2410_GPB(1));
644
645   /* mark the key as input, without pullups (there is one on the board) */
646   for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
647       s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
648       s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
649   }
650   if (features.lcd_index != -1) {
651       int li;
652
653       mini2440_fb_info.displays =
654           &mini2440_lcd_cfg[features.lcd_index];
655
656       printk(KERN_INFO "MINI2440: LCD");
657       for (li = 0; li < ARRAY_SIZE(mini2440_lcd_cfg); li++)
658            if (li == features.lcd_index)
659                printk(" [%d:%dx%d]",li,
660                   mini2440_lcd_cfg[li].width,
661                   mini2440_lcd_cfg[li].height);
662            else
663                printk(" %d:%dx%d",li,
664                    mini2440_lcd_cfg[li].width,
665                    mini2440_lcd_cfg[li].height);
666       printk("\n");
667       s3c24xx_fb_set_platdata(&mini2440_fb_info);
668   }
669
670   s3c24xx_udc_set_platdata(&mini2440_udc_cfg);
671   s3c24xx_mci_set_platdata(&mini2440_mmc_cfg);
672   s3c_nand_set_platdata(&mini2440_nand_info);
673   s3c_i2c0_set_platdata(NULL);
674
675   i2c_register_board_info(0, mini2440_i2c_devs,
676                ARRAY_SIZE(mini2440_i2c_devs));
677
678   platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
679
680   if (features.count) /* the optional features */
681       platform_add_devices(features.optional, features.count);
682
683}


這個函式我們這裡只需要關注675行,呼叫i2c_register_board_info註冊mini2440_i2c_devs。mini2440_i2c_devs就是上面定義的i2c_board_info結構體陣列,其中定義了at24c08相關資訊。

i2c_register_board_info函式定義在drivers/i2c/i2c-boardinfo.c檔案中,其內容如下:

42/**
43 * i2c_register_board_info - staticallydeclare I2C devices
44 * @busnum: identifies the bus to whichthese devices belong
45 * @info: vector of i2c devicedescriptors
46 * @len: how many descriptors in the vector;may be zero to reserve
47 * the specified bus number.
48 *
49 * Systems using the Linux I2C driverstack can declare tables of board info
50 * while they initialize.  This should be done in board-specific initcode
51 * near arch_initcall() time, orequivalent, before any I2C adapter driver is
52 * registered.  For example, mainboard init code could defineseveral devices,
53 * as could the init code for eachdaughtercard in a board stack.
54 *
55 * The I2C devices will be created later,after the adapter for the relevant
56 * bus has been registered.  After that moment, standard driver modeltools
57 * are used to bind "new style"I2C drivers to the devices.  The busnumber
58 * for any device declared using thisroutine is not available for dynamic
59 * allocation.
60 *
61 * The board info passed can safely be__initdata, but be careful of embedded
62 * pointers (for platform_data,functions, etc) since that won't be copied.
63 */
64int __init
65i2c_register_board_info(int busnum,
66   struct i2c_board_info const *info, unsigned len)
67{
68   int status;
69
70   down_write(&__i2c_board_lock);
71
72   /* dynamic bus numbers will be assigned after the last static one */
73   if (busnum >= __i2c_first_dynamic_bus_num)
74       __i2c_first_dynamic_bus_num = busnum + 1;
75
76   for (status = 0; len; len--, info++) {
77       struct i2c_devinfo  *devinfo;
78
79       devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
80       if (!devinfo) {
81            pr_debug("i2c-core: can'tregister boardinfo!\n");
82            status = -ENOMEM;
83            break;
84       }
85
86       devinfo->busnum = busnum;
87       devinfo->board_info = *info;
88       list_add_tail(&devinfo->list, &__i2c_board_list);
89   }
90
91   up_write(&__i2c_board_lock);
92
93   return status;
94}


第一個引數busnum表明I2C裝置所依附的I2C匯流排的匯流排號。

72-74行,如果引數傳遞進來的busnum 大於等於__i2c_first_dynamic_bus_num,則將__i2c_first_dynamic_bus_num設定為busnum+1。__i2c_first_dynamic_bus_num代表第一個動態分配的I2C匯流排號,所以,動態分配的I2C匯流排號總是大於靜態分配的I2C匯流排號。

__i2c_first_dynamic_bus_num定義在drivers/i2c/i2c-boardinfo.c檔案中:

38int __i2c_first_dynamic_bus_num;


因為__i2c_first_dynamic_bus_num是一個全域性變數,所以其值被自動初始化為0。所以73行的if判斷是成立的。

76-89行,迴圈遍歷info陣列,用i2c_board_info變數初始化structi2c_devinfo指標變數devinfo,然後將devinfo放入__i2c_board_list連結串列中。

i2c_devinfo變數定義在drivers/i2c/i2c-core.h檔案中:

22struct i2c_devinfo {
23   struct list_head    list;
24   int         busnum;
25   struct i2c_board_info  board_info;
26};


可以看到i2c_devinfo結構體只有三個成員變數,busnum用來儲存I2C裝置所依附的I2C匯流排號。board_info用來儲存I2C裝置相關資訊。list用於連結到全域性連結串列__i2c_board_list中。

__i2c_board_list 連結串列定義在drivers/i2c/i2c-boardinfo.c檔案中:

35LIST_HEAD(__i2c_board_list);
36EXPORT_SYMBOL_GPL(__i2c_board_list);


全域性變數__i2c_board_list上掛載著所有的I2C裝置的資訊,包括I2C裝置所在的I2C匯流排的匯流排號。

所以,i2c_register_board_info函式並沒有建立i2c_client,只是將i2c_devinfo變數放入__i2c_board_list連結串列中。那麼,什麼時候才會建立i2c_client呢?這個就與建立I2C裝置驅動程式無關了,而是跟I2C adapter驅動程式有關:

註冊一個I2C adapter有兩種方法,一是呼叫i2c_add_adapter函式,二是呼叫i2c_add_numbered_adapter函式。

先來看i2c_add_adapter函式,它定義在drivers/i2c/i2c-core.c檔案中:

1099/**
1100 * i2c_add_adapter - declare i2cadapter, use dynamic bus number
1101 * @adapter: the adapter to add
1102 * Context: can sleep
1103 *
1104 * This routine is used to declare anI2C adapter when its bus number
1105 * doesn't matter or when its busnumber is specified by an dt alias.
1106 * Examples of bases when the busnumber doesn't matter: I2C adapters
1107 * dynamically added by USB links orPCI plugin cards.
1108 *
1109 * When this returns zero, a new busnumber was allocated and stored
1110 * in adap->nr, and the specifiedadapter became available for clients.
1111 * Otherwise, a negative errno value isreturned.
1112 */
1113int i2c_add_adapter(struct i2c_adapter*adapter)
1114{
1115   struct device *dev = &adapter->dev;
1116   int id;
1117
1118   if (dev->of_node) {
1119       id = of_alias_get_id(dev->of_node, "i2c");
1120       if (id >= 0) {
1121            adapter->nr = id;
1122            return__i2c_add_numbered_adapter(adapter);
1123       }
1124   }
1125
1126   mutex_lock(&core_lock);
1127   id = idr_alloc(&i2c_adapter_idr, adapter,
1128               __i2c_first_dynamic_bus_num, 0,GFP_KERNEL);
1129   mutex_unlock(&core_lock);
1130   if (id < 0)
1131       return id;
1132
1133   adapter->nr = id;
1134
1135   return i2c_register_adapter(adapter);
1136}


該函式為引數指定的i2c_adapter動態分配的個I2C匯流排號,並註冊該i2c_adapter。

1118-1124行,忽略。

1127-1133行,呼叫idr_alloc,動態分配一個id號,並將該id號做為i2c_adapter的I2C匯流排號。

關於idr機制,我們不詳細分析,只需要知道它是一種快速索引機制,它將一個整數ID與一個需要被索引的指標建立聯絡,方便進行查詢。例如,這裡idr_alloc返回的id與i2c_adapter建立了索引。idr_alloc的第三個引數指定返回ID的最小值(閉區間),第四個引數指定返回ID的最大值(開區間),即idr_alloc返回的ID大於等於第三個引數,而且必須小於第四個引數。在這個函式中,第三個引數為__i2c_first_dynamic_bus_num,所以返回的id必然是大於等於__i2c_first_dynamic_bus_num的,即動態分配的I2C匯流排號必然大於__i2c_first_dynamic_bus_num。

1135行,呼叫i2c_register_adapter註冊i2c_adapter。

下面我們來看i2c_add_numbered_adapter,該函式定義在drivers/i2c/i2c-core.c檔案中:

1139/**
1140 * i2c_add_numbered_adapter - declarei2c adapter, use static bus number
1141 * @adap: the adapter to register (withadap->nr initialized)
1142 * Context: can sleep
1143 *
1144 * This routine is used to declare anI2C adapter when its bus number
1145 * matters.  For example, use it for I2C adapters fromsystem-on-chip CPUs,
1146 * or otherwise built in to thesystem's mainboard, and where i2c_board_info
1147 * is used to properly configure I2Cdevices.
1148 *
1149 * If the requested bus number is setto -1, then this function will behave
1150 * identically to i2c_add_adapter, andwill dynamically assign a bus number.
1151 *
1152 * If no devices have pre-been declaredfor this bus, then be sure to
1153 * register the adapter before anydynamically allocated ones.  Otherwise
1154 * the required bus ID may not beavailable.
1155 *
1156 * When this returns zero, thespecified adapter became available for
1157 * clients using the bus numberprovided in adap->nr.  Also, the table
1158 * of I2C devices pre-declared usingi2c_register_board_info() is scanned,
1159 * and the appropriate driver modeldevice nodes are created.  Otherwise, a
1160 * negative errno value is returned.
1161 */
1162int i2c_add_numbered_adapter(structi2c_adapter *adap)
1163{
1164   if (adap->nr == -1) /* -1 means dynamically assign bus id */
1165       return i2c_add_adapter(adap);
1166
1167   return __i2c_add_numbered_adapter(adap);
1168}


該函式用於註冊引數指定的i2c_adapter,該i2c_adapter的I2C匯流排號即i2c_adapter.nr必須已經靜態設定好了。如果adap->nr為-1,則呼叫i2c_add_adapter動態分配I2C匯流排號,再註冊。否則,呼叫__i2c_add_numbered_adapter函式。

__i2c_add_numbered_adapter函式定義在drivers/i2c/i2c-core.c檔案中:

1078/**
1079 * __i2c_add_numbered_adapter -i2c_add_numbered_adapter where nr is never -1
1080 * @adap: the adapter to register (withadap->nr initialized)
1081 * Context: can sleep
1082 *
1083 * See i2c_add_numbered_adapter() fordetails.
1084 */
1085static int__i2c_add_numbered_adapter(struct i2c_adapter *adap)
1086{
1087   int id;
1088
1089   mutex_lock(&core_lock);
1090   id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,
1091               GFP_KERNEL);
1092   mutex_unlock(&core_lock);
1093   if (id < 0)
1094       return id == -ENOSPC ? -EBUSY : id;
1095
1096   return i2c_register_adapter(adap);
1097}


1090-1091行,呼叫idr_alloc函式,建立idr索引關係。返回的id必須大於等於第三個引數adap->nr,同時必須小於第四個引數adap->nr+1,所以返回的id必然等於adap->nr,即靜態指定的I2C匯流排號。

1096行,呼叫i2c_register_adapter註冊i2c_adapter。

到這裡,我們就知道了註冊一個i2c_adapter可以呼叫i2c_add_numbered_adapter函式靜態指定一個I2C匯流排號,也可以呼叫i2c_add_adapter函式動態分配一個I2C匯流排號。但是不論哪種方法,最後的註冊工作都必須通過呼叫i2c_register_adapter函式完成。

i2c_register_adapter函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:

 980staticint i2c_register_adapter(struct i2c_adapter *adap)
 981{
 982   int res = 0;
 983
 984   /* Can't register until after driver model init */
 985   if (unlikely(WARN_ON(!i2c_bus_type.p))) {
 986       res = -EAGAIN;
 987       goto out_list;
 988    }
 989
 990   /* Sanity checks */
 991   if (unlikely(adap->name[0] == '\0')) {
 992       pr_err("i2c-core: Attempt to register an adapter with "
 993               "no name!\n");
 994       return -EINVAL;
 995    }
 996   if (unlikely(!adap->algo)) {
 997       pr_err("i2c-core: Attempt to register adapter '%s' with "
 998               "no algo!\n",adap->name);
 999       return -EINVAL;
1000   }
1001
1002   rt_mutex_init(&adap->bus_lock);
1003   mutex_init(&adap->userspace_clients_lock);
1004   INIT_LIST_HEAD(&adap->userspace_clients);
1005
1006   /* Set default timeout to 1 second if not already set */
1007   if (adap->timeout == 0)
1008       adap->timeout = HZ;
1009
1010   dev_set_name(&adap->dev, "i2c-%d", adap->nr);
1011   adap->dev.bus = &i2c_bus_type;
1012   adap->dev.type = &i2c_adapter_type;
1013   res = device_register(&adap->dev);
1014   if (res)
1015       goto out_list;
1016
1017   dev_dbg(&adap->dev, "adapter [%s] registered\n",adap->name);
1018
1019#ifdef CONFIG_I2C_COMPAT
1020   res = class_compat_create_link(i2c_adapter_compat_class,&adap->dev,
1021                       adap->dev.parent);
1022   if (res)
1023       dev_warn(&adap->dev,
1024             "Failed to createcompatibility class link\n");
1025#endif
1026
1027   /* bus recovery specific initialization */
1028   if (adap->bus_recovery_info) {
1029       struct i2c_bus_recovery_info*bri = adap->bus_recovery_info;
1030
1031       if (!bri->recover_bus) {
1032            dev_err(&adap->dev, "Norecover_bus() found, not using recovery\n");
1033            adap->bus_recovery_info = NULL;
1034            goto exit_recovery;
1035       }
1036
1037       /* Generic GPIO recovery */
1038       if (bri->recover_bus == i2c_generic_gpio_recovery) {
1039            if(!gpio_is_valid(bri->scl_gpio)) {
1040                dev_err(&adap->dev,"Invalid SCL gpio, not using recovery\n");
1041                adap->bus_recovery_info =NULL;
1042                goto exit_recovery;
1043            }
1044
1045            if(gpio_is_valid(bri->sda_gpio))
1046                bri->get_sda =get_sda_gpio_value;
1047           else
1048                bri->get_sda = NULL;
1049
1050            bri->get_scl =get_scl_gpio_value;
1051            bri->set_scl =set_scl_gpio_value;
1052       } else if (!bri->set_scl || !bri->get_scl) {
1053            /* Generic SCL recovery */
1054            dev_err(&adap->dev, "No{get|set}_gpio() found, not using recovery\n");
1055            adap->bus_recovery_info = NULL;
1056       }
1057   }
1058
1059exit_recovery:
1060   /* create pre-declared device nodes */
1061   if (adap->nr < __i2c_first_dynamic_bus_num)
1062       i2c_scan_static_board_info(adap);
1063
1064   /* Notify drivers */
1065   mutex_lock(&core_lock);
1066   bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
1067   mutex_unlock(&core_lock);
1068
1069   return 0;
1070
1071out_list:
1072   mutex_lock(&core_lock);
1073   idr_remove(&i2c_adapter_idr, adap->nr);
1074   mutex_unlock(&core_lock);
1075   return res;
1076}


984-1000行,做一些必要的檢查工作。

1002-1008行,做一些簡單的i2c_adapter成員變數初始化工作。

1010-1013行,初始化i2c_adapter.dev,並呼叫device_register註冊i2c_adapter.dev。

1028-1057行,I2C匯流排恢復時相關的初始化工作。

1060-1062行,因為動態分析的I2C匯流排號必須大於或等於__i2c_first_dynamic_bus_num,所以,如果adap->nr< __i2c_first_dynamic_bus_num,說明是靜態指定的I2C匯流排號,此時,要呼叫i2c_scan_static_board_info函式探測I2C總線上靜態註冊的I2C裝置。

i2c_scan_static_board_info函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:

 941staticvoid i2c_scan_static_board_info(struct i2c_adapter *adapter)
 942{
 943   struct i2c_devinfo  *devinfo;
 944
 945   down_read(&__i2c_board_lock);
 946   list_for_each_entry(devinfo, &__i2c_board_list, list) {
 947       if (devinfo->busnum == adapter->nr
 948                &&!i2c_new_device(adapter,
 949                       &devinfo->board_info))
 950           dev_err(&adapter->dev,
 951                "Can't create device at0x%02x\n",
 952                devinfo->board_info.addr);
 953    }
 954   up_read(&__i2c_board_lock);
 955}


946-953行,遍歷__i2c_board_list連結串列,如果devinfo->busnum等於adapter->nr,即連結串列節點所代表的I2C裝置的I2C匯流排號等於i2c_adapter的I2C匯流排號,則呼叫i2c_new_device建立並註冊I2C裝置對應的i2c_client結構體。

到這裡,就和我們在本文開始部分介紹的靜態註冊的i2c_board_info資訊聯絡起來了。回憶一下我們通過呼叫i2c_register_board_info函式將將包含所有I2C裝置的i2c_board_info資訊的i2c_devinfo變數加入到__i2c_board_list連結串列中。現在在註冊i2c_adater時,又通過呼叫i2c_scan_static_board_info函式遍歷__i2c_board_list連結串列,查詢屬於對應i2c_adapter的I2C裝置,如果找到,呼叫i2c_new_device建立對應的i2c_client結構體。

i2c_new_device函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:

 612/**
 613* i2c_new_device - instantiate an i2c device
 614* @adap: the adapter managing the device
 615* @info: describes one I2C device; bus_num is ignored
 616* Context: can sleep
 617*
 618* Create an i2c device. Binding is handled through driver model
 619* probe()/remove() methods.  A driver maybe bound to this device when we
 620* return from this function, or any later moment (e.g. maybe hotplugging will
 621* load the driver module).  This call isnot appropriate for use by mainboard
 622* initialization logic, which usually runs during an arch_initcall() long
 623* before any i2c_adapter could exist.
 624*
 625* This returns the new i2c client, which may be saved for later use with
 626* i2c_unregister_device(); or NULL to indicate an error.
 627*/
 628struct i2c_client *
 629i2c_new_device(struct i2c_adapter *adap,struct i2c_board_info const *info)
 630{
 631   struct i2c_client   *client;
 632   int         status;
 633
 634   client = kzalloc(sizeof *client, GFP_KERNEL);
 635   if (!client)
 636       return NULL;
 637
 638   client->adapter = adap;
 639
 640   client->dev.platform_data = info->platform_data;
 641
 642   if (info->archdata)
 643       client->dev.archdata = *info->archdata;
 644
 645   client->flags = info->flags;
 646   client->addr = info->addr;
 647   client->irq = info->irq;
 648
 649   strlcpy(client->name, info->type, sizeof(client->name));
 650
 651   /* Check for address validity */
 652   status = i2c_check_client_addr_validity(client);
 653   if (status) {
 654        dev_err(&adap->dev,"Invalid %d-bit I2C address 0x%02hx\n",
 655            client->flags & I2C_CLIENT_TEN ?10 : 7, client->addr);
 656       goto out_err_silent;
 657    }
 658
 659   /* Check for address business */
 660   status = i2c_check_addr_busy(adap, client->addr);
 661   if (status)
 662       goto out_err;
 663
 664   client->dev.parent = &client->adapter->dev;
 665   client->dev.bus = &i2c_bus_type;
 666   client->dev.type = &i2c_client_type;
 667   client->dev.of_node = info->of_node;
 668   ACPI_HANDLE_SET(&client->dev, info->acpi_node.handle);
 669
 670   /* For 10-bit clients, add an arbitrary offset to avoid collisions */
 671   dev_set_name(&client->dev, "%d-%04x",i2c_adapter_id(adap),
 672            client->addr | ((client->flags & I2C_CLIENT_TEN)
 673                     ? 0xa000 : 0));
 674    status =device_register(&client->dev);
 675   if (status)
 676       goto out_err;
 677
 678   dev_dbg(&adap->dev, "client [%s] registered with bus id%s\n",
 679       client->name, dev_name(&client->dev));
 680
 681   return client;
 682
 683out_err:
 684   dev_err(&adap->dev, "Failed to register i2c client %s at0x%02x "
 685       "(%d)\n", client->name, client->addr, status);
 686out_err_silent:
 687   kfree(client);
 688   return NULL;
 689}


這個函式根據引數傳遞進來的資訊,建立並註冊i2c_client。

634行,為i2c_client變數分配記憶體空間。

638行,將i2c_client.adapter設定為引數傳遞進來的i2c_adapter。

640 行,將i2c_client.dev.platform_data設定為 info->platform_data;

645行,將i2c_client.flags設定為info->flags;

646行,將i2c_client.addr設定為info->addr;

647行,將i2c_client.irq設定為info->irq;

649行,將i2c_client.name設定為info->type;

651-657行,檢查指定的I2C裝置地址是否有效。

660-662行,檢查指定的I2C裝置地址是否忙。

664-674行,初始化i2c_client.dev,並呼叫device_register註冊i2c_client.dev。

i2c_register_adapter函式我們還有一點內容沒有分析完,回到i2c_register_adapter函式,上面我們分析到了1062行的i2c_scan_static_board_info(adap),只有在adap->nr小於__i2c_first_dynamic_bus_num即靜態指定了i2c_adapter的I2C匯流排號的情況下,才會呼叫這個函式。對於動態分配I2C匯流排號的情況,直接跳過。這就說明,只有在靜態指定i2c_adapter的I2C匯流排號的情況下,才會掃描靜態註冊的I2C裝置,如果動態指定i2c_adapter的I2C匯流排號,不會掃描靜態註冊的I2C裝置。對於I2C驅動程式,這種靜態註冊的方式,稱為new-style driver;而動態探測的方式,稱為legacy driver。

下面我們繼續分析i2c_register_adapter函式,前面呼叫i2c_scan_static_board_info例項化了靜態註冊的I2C裝置,下面要完成對I2C裝置的動態探測和例項化:

不論是靜態指定還是動態分配I2C匯流排號,都會呼叫到1066行的bus_for_each_drv函式。

1066行,呼叫bus_for_each_drv函式,該函式定義在drivers/base/bus.c檔案中,其內容如下:
 417/**
 418 * bus_for_each_drv - driver iterator
 419 * @bus: bus we're dealing with.
 420 * @start: driver to start iterating on.
 421 * @data: data to pass to the callback.
 422 * @fn: function to call for each driver.
 423 *
 424 * This is nearly identical to the device iterator above.
 425 * We iterate over each driver that belongs to @bus, and call
 426 * @fn for each. If @fn returns anything but 0, we break out
 427 * and return it. If @start is not NULL, we use it as the head
 428 * of the list.
 429 *
 430 * NOTE: we don't return the driver that returns a non-zero
 431 * value, nor do we leave the reference count incremented for that
 432 * driver. If the caller needs to know that info, it must set it
 433 * in the callback. It must also be sure to increment the refcount
 434 * so it doesn't disappear before returning to the caller.
 435 */
 436int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
 437             void *data, int (*fn)(struct device_driver *, void *))
 438{
 439    struct klist_iter i;
 440    struct device_driver *drv;
 441    int error = 0;
 442
 443    if (!bus)
 444        return -EINVAL;
 445
 446    klist_iter_init_node(&bus->p->klist_drivers, &i,
 447                 start ? &start->p->knode_bus : NULL);
 448    while ((drv = next_driver(&i)) && !error)
 449        error = fn(drv, data);
 450    klist_iter_exit(&i);
 451    return error;
 452}


這個函式我們在《Linux裝置模型分析之device(基於3.10.1核心)》一文中已經分析過了。448-449行,這個while迴圈依次遍歷bus->p->klist_drivers中的所有device_driver,對於每個device_driver,呼叫fn(drv,data)函式。這裡,傳遞過來的fn引數是__process_new_adapter,data引數是adap。這個迴圈是一個關鍵點,註冊一個新的i2c_adapter後,要為該i2c_adapter上的i2c裝置匹配驅動程式,這個匹配過程就是通過這個迴圈呼叫__process_new_adapter函式完成的。
__process_new_adapter函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:
 975static int __process_new_adapter(struct device_driver *d, void *data)
 976{
 977    return i2c_do_add_adapter(to_i2c_driver(d), data);
 978}


注意i2c_do_add_adapter函式的第一個引數,從device_driver轉換為i2c_driver。
i2c_do_add_adapter函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:
 957static int i2c_do_add_adapter(struct i2c_driver *driver,
 958                  struct i2c_adapter *adap)
 959{
 960    /* Detect supported devices on that bus, and instantiate them */
 961    i2c_detect(adap, driver);
 962
 963    /* Let legacy drivers scan this bus for matching devices */
 964    if (driver->attach_adapter) {
 965        dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n",
 966             driver->driver.name);
 967        dev_warn(&adap->dev, "Please use another way to instantiate "
 968             "your i2c_client\n");
 969        /* We ignore the return code; if it fails, too bad */
 970        driver->attach_adapter(adap);
 971    }
 972    return 0;
 973}


961行,呼叫i2c_detect函式,探測並初始化該i2c總線上的i2c裝置。該函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:
1730static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
1731{
1732    const unsigned short *address_list;
1733    struct i2c_client *temp_client;
1734    int i, err = 0;
1735    int adap_id = i2c_adapter_id(adapter);
1736
1737    address_list = driver->address_list;
1738    if (!driver->detect || !address_list)
1739        return 0;
1740
1741    /* Stop here if the classes do not match */
1742    if (!(adapter->class & driver->class))
1743        return 0;
1744
1745    /* Set up a temporary client to help detect callback */
1746    temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
1747    if (!temp_client)
1748        return -ENOMEM;
1749    temp_client->adapter = adapter;
1750
1751    for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
1752        dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
1753            "addr 0x%02x\n", adap_id, address_list[i]);
1754        temp_client->addr = address_list[i];
1755        err = i2c_detect_address(temp_client, driver);
1756        if (unlikely(err))
1757            break;
1758    }
1759
1760    kfree(temp_client);
1761    return err;
1762}


1755行,呼叫i2c_detect_address,探測指定的地址上的I2C裝置是否存在,如果存在,註冊該i2c裝置。i2c_detect_address函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:
1675static int i2c_detect_address(struct i2c_client *temp_client,
1676                  struct i2c_driver *driver)
1677{
1678    struct i2c_board_info info;
1679    struct i2c_adapter *adapter = temp_client->adapter;
1680    int addr = temp_client->addr;
1681    int err;
1682
1683    /* Make sure the address is valid */
1684    err = i2c_check_addr_validity(addr);
1685    if (err) {
1686        dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
1687             addr);
1688        return err;
1689    }
1690
1691    /* Skip if already in use */
1692    if (i2c_check_addr_busy(adapter, addr))
1693        return 0;
1694
1695    /* Make sure there is something at this address */
1696    if (!i2c_default_probe(adapter, addr))
1697        return 0;
1698
1699    /* Finally call the custom detection function */
1700    memset(&info, 0, sizeof(struct i2c_board_info));
1701    info.addr = addr;
1702    err = driver->detect(temp_client, &info);
1703    if (err) {
1704        /* -ENODEV is returned if the detection fails. We catch it
1705           here as this isn't an error. */
1706        return err == -ENODEV ? 0 : err;
1707    }
1708
1709    /* Consistency check */
1710    if (info.type[0] == '\0') {
1711        dev_err(&adapter->dev, "%s detection function provided "
1712            "no name for 0x%x\n", driver->driver.name,
1713            addr);
1714    } else {
1715        struct i2c_client *client;
1716
1717        /* Detection succeeded, instantiate the device */
1718        dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",
1719            info.type, info.addr);
1720        client = i2c_new_device(adapter, &info);
1721        if (client)
1722            list_add_tail(&client->detected, &driver->clients);
1723        else
1724            dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n",
1725                info.type, info.addr);
1726    }
1727    return 0;
1728}


1702行,呼叫driver->detect。
1720行,如果探測到i2c裝置確實存在,呼叫i2c_new_device函式初始化對應的i2c_client結構體並註冊。i2c_new_device函式我們在前面已經分析過。
至此,i2c_adapter的註冊過程我們就清楚了。同時,我們對I2C裝置的註冊定義和註冊也就完全清楚了。

二、定義和註冊I2C裝置驅動

步驟1:定義i2c_driver結構體變數。

Linux I2C裝置驅動程式對應的結構體是structi2c_driver,定義在include/linux/i2c.h檔案中:

124/**
125 * struct i2c_driver - represent an I2Cdevice driver
126 * @class: What kind of i2c device weinstantiate (for detect)
127 * @attach_adapter: Callback for busaddition (deprecated)
128 * @probe: Callback for device binding
129 * @remove: Callback for deviceunbinding
130 * @shutdown: Callback for deviceshutdown
131 * @suspend: Callback for device suspend
132 * @resume: Callback for device resume
133 * @alert: Alert callback, for examplefor the SMBus alert protocol
134 * @command: Callback for bus-wide signaling(optional)
135 * @driver: Device driver model driver
136 * @id_table: List of I2C devicessupported by this driver
137 * @detect: Callback for devicedetection
138 * @address_list: The I2C addresses toprobe (for detect)
139 * @clients: List of detected clients wecreated (for i2c-core use only)
140 *
141 * The driver.owner field should be setto the module owner of this driver.
142 * The driver.name field should be setto the name of this driver.
143 *
144 * For automatic device detection, both @detectand @address_list must
145 * be defined. @class should also beset, otherwise only devices forced
146 * with module parameters will becreated. The detect function must
147 * fill at least the name field of thei2c_board_info structure it is
148 * handed upon successful detection, andpossibly also the flags field.
149 *
150 * If @detect is missing, the driverwill still work fine for enumerated
151 * devices. Detected devices simplywon't be supported. This is expected
152 * for the many I2C/SMBus devices whichcan't be detected reliably, and
153 * the ones which can always beenumerated in practice.
154 *
155 * The i2c_client structure which ishanded to the @detect callback is
156 * not a real i2c_client. It isinitialized just enough so that you can
157 * call i2c_smbus_read_byte_data andfriends on it. Don't do anything
158 * else with it. In particular, callingdev_dbg and friends on it is
159 * not allowed.
160 */
161struct i2c_driver {
162   unsigned int class;
163
164   /* Notifies the driver that a new bus has appeared. You should avoid
165    * using this, it will be removed in a near future.
166    */
167   int (*attach_adapter)(struct i2c_adapter *) __deprecated;
168
169   /* Standard driver model interfaces */
170   int (*probe)(struct i2c_client *, const struct i2c_device_id *);
171   int (*remove)(struct i2c_client *);
172
173   /* driver model interfaces that don't relate to enumeration  */
174   void (*shutdown)(struct i2c_client *);
175   int (*suspend)(struct i2c_client *, pm_message_t mesg);
176   int (*resume)(struct i2c_client *);
177
178   /* Alert callback, for example for the SMBus alert protocol.
179    * The format and meaning of the data value depends on the protocol.
180    * For the SMBus alert protocol, there is a single bit of data passed
181    * as the alert response's low bit ("event flag").
182    */
183   void (*alert)(struct i2c_client *, unsigned int data);
184
185   /* a ioctl like command that can be used to perform specific functions
186    * with the device.
187    */
188   int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
189
190   struct device_driver driver;
191   const struct i2c_device_id *id_table;
192
193   /* Device detection callback for automatic device creation */
194   int (*detect)(struct i2c_client *, struct i2c_board_info *);
195   const unsigned short *address_list;
196   struct list_head clients;
197};


注意註釋中的說明,driver.name和driver.owner必須初始化。

id_table成員變數是i2c_device_id結構體指標,它用來儲存該i2c_driver支援的I2C裝置列表。

struct i2c_device_id定義在include/linux/mod_devicetable.h檔案中,其內容如下:

419struct i2c_device_id {
420   char name[I2C_NAME_SIZE];
421   kernel_ulong_t driver_data; /* Data private to the driver */
422};


對於Mini2440的I2C裝置at24c08 EEPROM,其對應的i2c_driver結構體變數實現在drivers/misc/eeprom/at24.c檔案中:

677static struct i2c_driver at24_driver = {
678   .driver = {
679       .name = "at24",
680       .owner = THIS_MODULE,
681   },
682   .probe = at24_probe,
683   .remove = at24_remove,
684   .id_table = at24_ids,
685};


678-681行,初始化了要求必須初始化的i2c_driver.driver.name和i2c_driver.driver.owner。

682行,指定i2c_driver.probe函式為at24_probe。

683行,指定i2c_driver.remove函式為at24_remove。

684行,指定i2c_driver.id_table為at24_ids。

at24_ids定義在drivers/misc/eeprom/at24.c檔案中,其內容如下:

99#define AT24_SIZE_BYTELEN 5
100#define AT24_SIZE_FLAGS 8
101
102#define AT24_BITMASK(x) (BIT(x) - 1)
103
104/* create non-zero magic value for giveneeprom parameters */
105#define AT24_DEVICE_MAGIC(_len,_flags)         \
106   ((1 << AT24_SIZE_FLAGS | (_flags))      \
107       << AT24_SIZE_BYTELEN | ilog2(_len))
108
109static const struct i2c_device_idat24_ids[] = {
110   /* needs 8 addresses as A0-A2 are ignored */
111   { "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) },
112   /* old variants can't be handled with this generic entry! */
113   { "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) },
114   { "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) },
115   /* spd is a 24c02 in memory DIMMs */
116   { "spd", AT24_DEVICE_MAGIC(2048 / 8,
117       AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },
118   { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },
119   /* 24rf08 quirk is handled at i2c-core */
120   { "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },
121   { "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },
122   { "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },
123   { "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },
124   { "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) },
125   { "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) },
126   { "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) },
127   { "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16)},
128   { "at24", 0 },
129   { /* END OF LIST */ }
130};


可以看到,at24_driver支援很多裝置,其中包括Mini2440使用的24c08 EEPROM。

步驟2:呼叫i2c_add_driver註冊i2c_driver結構體變數。

對於Mini2440的I2C裝置at24c08 EEPROM,這一步工作是在drivers/misc/eeprom/at24.c檔案中的at24_init函式中完成的:

687static int __init at24_init(void)
688{
689   if (!io_limit) {
690       pr_err("at24: io_limit must not be 0!\n");
691       return -EINVAL;
692   }
693
694   io_limit = rounddown_pow_of_two(io_limit);
695   return i2c_add_driver(&at24_driver);
696}


695行,呼叫i2c_add_driver註冊上面定義的at24_driver。

i2c_add_driver是一個巨集,定義在include/linux/i2c.h檔案中:
497/* use a define to avoid include chaining to get THIS_MODULE */
498#define i2c_add_driver(driver) \
499    i2c_register_driver(THIS_MODULE, driver)


i2c_register_driver函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:
1307/*
1308 * An i2c_driver is used with one or more i2c_client (device) nodes to access
1309 * i2c slave chips, on a bus instance associated with some i2c_adapter.
1310 */
1311
1312int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
1313{
1314    int res;
1315
1316    /* Can't register until after driver model init */
1317    if (unlikely(WARN_ON(!i2c_bus_type.p)))
1318        return -EAGAIN;
1319
1320    /* add the driver to the list of i2c drivers in the driver core */
1321    driver->driver.owner = owner;
1322    driver->driver.bus = &i2c_bus_type;
1323
1324    /* When registration returns, the driver core
1325     * will have called probe() for all matching-but-unbound devices.
1326     */
1327    res = driver_register(&driver->driver);
1328    if (res)
1329        return res;
1330
1331    /* Drivers should switch to dev_pm_ops instead. */
1332    if (driver->suspend)
1333        pr_warn("i2c-core: driver [%s] using legacy suspend method\n",
1334            driver->driver.name);
1335    if (driver->resume)
1336        pr_warn("i2c-core: driver [%s] using legacy resume method\n",
1337            driver->driver.name);
1338
1339    pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
1340
1341    INIT_LIST_HEAD(&driver->clients);
1342    /* Walk the adapters that are already present */
1343    i2c_for_each_dev(driver, __process_new_driver);
1344
1345    return 0;
1346}


1327行,呼叫driver_register註冊i2c_driver.driver。參考《 Linux裝置模型分析之device_driver(基於3.10.1核心)》對Linux裝置模型的分析,在driver_register執行過程中,如果I2C總線上找到了與該驅動匹配的I2C裝置,則i2c_driver.probe函式會被呼叫執行。

1343行,呼叫i2c_for_each_dev遍歷所有已存在的i2c_adapter。該函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:
1288int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *))
1289{
1290    int res;
1291
1292    mutex_lock(&core_lock);
1293    res = bus_for_each_dev(&i2c_bus_type, NULL, data, fn);
1294    mutex_unlock(&core_lock);
1295
1296    return res;
1297}


1293行,呼叫bus_for_each_dev,這個函式定義在drivers/base/bus.c檔案中,其內容如下:

286intbus_for_each_dev(struct bus_type *bus, struct device *start,
 287            void *data, int (*fn)(struct device *, void *))
 288{
 289   struct klist_iter i;
 290   struct device *dev;
 291   int error = 0;
 292
 293   if (!bus || !bus->p)
 294       return -EINVAL;
 295
 296   klist_iter_init_node(&bus->p->klist_devices, &i,
 297                 (start ?&start->p->knode_bus : NULL));
 298   while ((dev = next_device(&i)) && !error)
 299       error = fn(dev, data);
 300   klist_iter_exit(&i);
 301   return error;
 302}

我們在《 Linux裝置模型分析之device_driver(基於3.10.1核心)》一文中已經分析過這個函式。這裡,傳遞過來的data引數是要註冊的i2c_driver,fn引數是__process_new_driver函式,所以我們來看__process_new_driver函式,該函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:

1300static int __process_new_driver(structdevice *dev, void *data)
1301{
1302   if (dev->type != &i2c_adapter_type)
1303       return 0;
1304   return i2c_do_add_adapter(data, to_i2c_adapter(dev));
1305}


i2c_do_add_adapter函式定義在drivers/i2c/i2c-core.c檔案中,其內容如下:

957static int i2c_do_add_adapter(structi2c_driver *driver,
 958                  struct i2c_adapter *adap)
 959{
 960   /* Detect supported devices on that bus, and instantiate them */
 961   i2c_detect(adap, driver);
 962
 963   /* Let legacy drivers scan this bus for matching devices */
 964   if (driver->attach_adapter) {
 965       dev_warn(&adap->dev, "%s: attach_adapter method isdeprecated\n",
 966            driver->driver.name);
 967       dev_warn(&adap->dev, "Please use another way to instantiate"
 968            "your i2c_client\n");
 969       /* We ignore the return code; if it fails, too bad */
 970       driver->attach_adapter(adap);
 971    }
 972   return 0;
 973}


這個函式我們在分析i2c_adapter的註冊過程時已經分析過了,它主要完成i2c_driver與i2c_adapter上的i2c裝置的匹配工作,如果匹配成功,初始化並註冊對應的i2c_client。

至此,i2c_driver的註冊過程我們就清楚了。

步驟3:實現i2c_driver中要示實現的函式

對於Mini2440的I2C裝置at24c08 EEPROM,at24_driver要求實現的是i2c_driver.probe和i2c_driver.remove函式。

末完,待續!!!