面試被問到IIC,總結。

 

 

 

Linux3.5內核中,IIC。node

 1 i2c_add_driver
 2     i2c_register_driver
 3         a. at24cxx_driver放入i2c_bus_type的drv鏈表
 4            而且從dev鏈表裏取出能匹配的i2c_client並調用probe
 5         driver_register
 6             
 7         
 8         b. 對於每個適配器,調用__process_new_driver
 9            對於每個適配器,調用它的函數肯定address_list裏的設備是否存在
10            若是存在,再調用detect進一步肯定、設置,而後i2c_new_device
11         /* Walk the adapters that are already present */
12         i2c_for_each_dev(driver, __process_new_driver);
13             __process_new_driver
14                 i2c_do_add_adapter
15                     /* Detect supported devices on that bus, and instantiate them */
16                     i2c_detect(adap, driver);
17                         for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
18                             err = i2c_detect_address(temp_client, driver);
19                                         /* 判斷這個設備是否存在:簡單的發出S信號肯定有ACK */
20                                         if (!i2c_default_probe(adapter, addr))
21                                             return 0;
22                                         
23                                         memset(&info, 0, sizeof(struct i2c_board_info));
24                                         info.addr = addr;    
25                                         
26                                         // 設置info.type
27                                         err = driver->detect(temp_client, &info);
28                     
29                                         i2c_new_device

 

 

 

使用讀寫IIC器件的函數接口:數組

/**
*I2c_Master_發送-在主傳輸模式下發出單個I2c消息
*@客戶端:從設備的句柄
*@buf:將寫入從系統的數據
*@計數:要寫入的字節數,必須小於64K,由於msg.len是u16
*返回負的errno,或者返回寫入的字節數。
*/

/*
* * i2c_master_send - issue a single I2C message in master transmit mode * @client: Handle to slave device * @buf: Data that will be written to the slave * @count: How many bytes to write, must be less than 64k since msg.len is u16 * * Returns negative errno, or else the number of bytes written. */ int i2c_master_send(const struct i2c_client *client, const char *buf, int count) { int ret; struct i2c_adapter *adap = client->adapter; struct i2c_msg msg; msg.addr = client->addr; msg.flags = client->flags & I2C_M_TEN; msg.len = count; msg.buf = (char *)buf; ret = i2c_transfer(adap, &msg, 1); /* * If everything went ok (i.e. 1 msg transmitted), return #bytes * transmitted, else error code. */ return (ret == 1) ? count : ret; }
/**
*I2c_Master_Recv-在主接收模式下發出單個I2c消息
*@客戶端:從設備的句柄
*@buf:從從屬服務器讀取數據的存儲位置
*@計數:要讀取的字節數,必須小於64K,由於msg.len是u16
*返回負的errno,不然返回讀取的字節數。
*/

/*
* * i2c_master_recv - issue a single I2C message in master receive mode * @client: Handle to slave device * @buf: Where to store data read from slave * @count: How many bytes to read, must be less than 64k since msg.len is u16 * * Returns negative errno, or else the number of bytes read. */ int i2c_master_recv(const struct i2c_client *client, char *buf, int count) { struct i2c_adapter *adap = client->adapter; struct i2c_msg msg; int ret; msg.addr = client->addr; msg.flags = client->flags & I2C_M_TEN; msg.flags |= I2C_M_RD; msg.len = count; msg.buf = buf; ret = i2c_transfer(adap, &msg, 1); /* * If everything went ok (i.e. 1 msg received), return #bytes received, * else error code. */ return (ret == 1) ? count : ret; }

 

 

本身寫的時候:服務器

/**
*結構I2c_Board_信息-設備建立模板
*@類型:芯片類型,初始化i2c_client.name
*@標誌:初始化i2c_client.flags
*@地址:存儲在I2c_client.addr中
*@平臺數據:存儲在i2c_client.dev.platform_data
*@archdata:複製到i2c_client.dev.archdata
*@節點:指向OpenFirmware設備節點的指針
*@IRQ:存儲在i2c_client.irq中
*
*I2c實際上不支持硬件探測,儘管控制器和
*設備可能可以使用I2c總線快速判斷是否存在
*位於給定地址的設備。司機一般須要更多的信息
*如芯片類型、配置、相關IRQ等。
*i2c_board_info用於構建列出i2c設備的信息表。
*那是存在的。此信息用於增加驅動程序模型樹。
*對於主板,這是使用i2c_register_board_info()靜態完成的。
*總線號標識還沒有提供的適配器。對於附加板,
*I2c_new_device()使用已知的適配器動態執行此操做。
*/
/*
* * struct i2c_board_info - template for device creation * @type: chip type, to initialize i2c_client.name * @flags: to initialize i2c_client.flags * @addr: stored in i2c_client.addr * @platform_data: stored in i2c_client.dev.platform_data * @archdata: copied into i2c_client.dev.archdata * @of_node: pointer to OpenFirmware device node * @irq: stored in i2c_client.irq * * I2C doesn't actually support hardware probing, although controllers and * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's * a device at a given address. Drivers commonly need more information than * that, such as chip type, configuration, associated IRQ, and so on. * * i2c_board_info is used to build tables of information listing I2C devices * that are present. This information is used to grow the driver model tree. * For mainboards this is done statically using i2c_register_board_info(); * bus numbers identify adapters that aren't yet available. For add-on boards, * i2c_new_device() does this dynamically with the adapter already known. */ struct i2c_board_info { char type[I2C_NAME_SIZE]; unsigned short flags; unsigned short addr; void *platform_data; struct dev_archdata *archdata; struct device_node *of_node; int irq; };

寫好  i2c_register_board_info smdk4x12_i2c_devs = {  };less

 i2c_register_board_info(i2c_register_board_info);    //註冊硬件信息。ide

platform_add_devices(smdk4x12_devices)   //smdk4x12_devices是放的全部platform_device結構體數組。函數

相關文章
相關標籤/搜索