一. IIC 架构浅析
1. 注册板级包中的i2c设备(例如:eeprom1,eeprom2,eeprom3), 将i2c设备添加到__i2c_board_list链表中。
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
2. SPI控制器驱动(spi-s3c64xx.c)
采用平台总线的形式,通过probe函数,初始化相关数据,
当调用i2c_register_adapter(struct i2c_adapter *adap)后,
接着执行--
if (adap->nr < __i2c_first_dynamic_bus_num)
i2c_scan_static_board_info(adap);
//将板级包中的i2c 设备信息取出来,新建i2c设备-client并和和i2c控制器相关联
static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
{
struct i2c_devinfo *devinfo;
down_read(&__i2c_board_lock);
list_for_each_entry(devinfo, &__i2c_board_list, list) {
if (devinfo->busnum == adapter->nr
&& !i2c_new_device(adapter, /// ---->1
&devinfo->board_info))
dev_err(&adapter->dev,
"Can't create device at 0x%02x\n",
devinfo->board_info.addr);
}
up_read(&__i2c_board_lock);
}
----->1
struct i2c_client *i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
{
dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), 设备名字
client->addr);
status = device_register(&client->dev);
}
接着执行
bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
__process_new_adapter-->i2c_do_add_adapter
--->if (driver->attach_adapter) {
driver->attach_adapter(adap); //attach_adapter = i2cdev_attach_adapter
}
注册相应的设备控制器 i2c-%d
static int i2cdev_attach_adapter(struct i2c_adapter *adap)
{
/* register this i2c device with the driver core *///注册设备控制器
i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
MKDEV(I2C_MAJOR, adap->nr), NULL,
"i2c-%d", adap->nr);
res = device_create_file(i2c_dev->dev, &dev_attr_name);//创建设备文件
}
3. 设备驱动层(i2c-dev.c)
/*注册设备驱动*/
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
有一个通用驱动i2cdev_driver--->提供统一的控制器设备节点/设备接口-->供应用层写相应的控制驱动
也可以自己写相应的设备驱动--->at24.c
*************************************************************************************************
二. SPI架构浅析
1.注册spi设备信息
/*
注册spi设备信息, 将信息挂载在board_list链表上
*/
int spi_register_board_info(struct spi_board_info const *info, unsigned n)
-->list_add_tail(&bi->list, &board_list);
2.SPI控制器驱动(spi-s3c64xx.c)
采用平台总线的形式,通过probe函数,初始化相关数据,建立工作队列--主要用来传输数据,
/*
当在probe中调用spi_register_master()函数后,执行spi_match_master_to_boardinfo()
遍历所开发板上的spi设备,接着执行dev = spi_new_device(master, bi);
建立spi控制器和spi设备之间的关系, 并且绑定在spi总线上.
spi%d.%d --->第一个代表总线上的第几个设备,第二个代表第几个总线。
*/
int spi_register_master(struct spi_master *master)
{
list_for_each_entry(bi, &board_list, list)
spi_match_master_to_boardinfo(master, &bi->board_info);
of_register_spi_devices(master); //注册SPI设备
}
3.设备驱动层(spidev.c)
//注册设备驱动
int spi_register_driver(struct spi_driver *sdrv)
有一个通用驱动spidev_spi_driver--->提供统一的设备节点/设备接口
也可以自己写相应的设备驱动