linux驱动之I2C
include/linux/i2c.h
struct i2c_msg;
struct i2c_algorithm;
struct i2c_adapter;
struct i2c_client;
struct i2c_driver;
union i2c_smbus_data;
I2C驅動主要包含三部分:I2C核心、I2C總線驅動、I2C設備驅動,它們主要的數據結構在目錄:/include/linux/i2c.h
struct i2c_driver
1 /* 2 * A driver is capable of handling one or more physical devices present on 3 * I2C adapters. This information is used to inform the driver of adapter 4 * events. 5 * 6 * The driver.owner field should be set to the module owner of this driver. 7 * The driver.name field should be set to the name of this driver. 8 */ 9 struct i2c_driver { 10 int id; 11 unsigned int class; 12 13 /* Notifies the driver that a new bus has appeared. This routine 14 * can be used by the driver to test if the bus meets its conditions 15 * & seek for the presence of the chip(s) it supports. If found, it 16 * registers the client(s) that are on the bus to the i2c admin. via 17 * i2c_attach_client. (LEGACY I2C DRIVERS ONLY) 18 */ 19 int (*attach_adapter)(struct i2c_adapter *); 20 int (*detach_adapter)(struct i2c_adapter *); 21 22 /* tells the driver that a client is about to be deleted & gives it 23 * the chance to remove its private data. Also, if the client struct 24 * has been dynamically allocated by the driver in the function above, 25 * it must be freed here. (LEGACY I2C DRIVERS ONLY) 26 */ 27 int (*detach_client)(struct i2c_client *); 28 29 /* Standard driver model interfaces, for "new style" i2c drivers. 30 * With the driver model, device enumeration is NEVER done by drivers; 31 * it's done by infrastructure. (NEW STYLE DRIVERS ONLY) 32 */ 33 int (*probe)(struct i2c_client *); 34 int (*remove)(struct i2c_client *); 35 36 /* driver model interfaces that don't relate to enumeration */ 37 void (*shutdown)(struct i2c_client *); 38 int (*suspend)(struct i2c_client *, pm_message_t mesg); 39 int (*resume)(struct i2c_client *); 40 41 /* a ioctl like command that can be used to perform specific functions 42 * with the device. 43 */ 44 int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); 45 46 struct device_driver driver; 47 struct list_head list; 48 };struct i2c_client
1 /** 2 * struct i2c_client - represent an I2C slave device 3 * @addr: Address used on the I2C bus connected to the parent adapter. 4 * @name: Indicates the type of the device, usually a chip name that's 5 * generic enough to hide second-sourcing and compatible revisions. 6 * @dev: Driver model device node for the slave. 7 * @driver_name: Identifies new-style driver used with this device; also 8 * used as the module name for hotplug/coldplug modprobe support. 9 * 10 * An i2c_client identifies a single device (i.e. chip) connected to an 11 * i2c bus. The behaviour is defined by the routines of the driver. 12 */ 13 struct i2c_client { 14 unsigned short flags; /* div., see below */ 15 unsigned short addr; /* chip address - NOTE: 7bit */ 16 /* addresses are stored in the */ 17 /* _LOWER_ 7 bits */ 18 char name[I2C_NAME_SIZE]; 19 struct i2c_adapter *adapter; /* the adapter we sit on */ 20 struct i2c_driver *driver; /* and our access routines */ 21 int usage_count; /* How many accesses currently */ 22 /* to the client */ 23 struct device dev; /* the device structure */ 24 int irq; /* irq issued by device (or -1) */ 25 char driver_name[KOBJ_NAME_LEN]; 26 struct list_head list; 27 struct completion released; 28 };struct i2c_algorithm
1 /* 2 * The following structs are for those who like to implement new bus drivers: 3 * i2c_algorithm is the interface to a class of hardware solutions which can 4 * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584 5 * to name two of the most common. 6 */ 7 struct i2c_algorithm { 8 /* If an adapter algorithm can't do I2C-level access, set master_xfer 9 to NULL. If an adapter algorithm can do SMBus access, set 10 smbus_xfer. If set to NULL, the SMBus protocol is simulated 11 using common I2C messages */ 12 /* master_xfer should return the number of messages successfully 13 processed, or a negative value on error */ 14 int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs, 15 int num); 16 int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, 17 unsigned short flags, char read_write, 18 u8 command, int size, union i2c_smbus_data * data); 19 20 /* --- ioctl like call to set div. parameters. */ 21 int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long); 22 23 /* To determine what the adapter supports */ 24 u32 (*functionality) (struct i2c_adapter *); 25 };struct i2c_adapter
1 /* 2 * i2c_adapter is the structure used to identify a physical i2c bus along 3 * with the access algorithms necessary to access it. 4 */ 5 struct i2c_adapter { 6 struct module *owner; 7 unsigned int id; 8 unsigned int class; 9 const struct i2c_algorithm *algo; /* the algorithm to access the bus */ 10 void *algo_data; 11 12 /* --- administration stuff. */ 13 int (*client_register)(struct i2c_client *); 14 int (*client_unregister)(struct i2c_client *); 15 16 /* data fields that are valid for all devices */ 17 u8 level; /* nesting level for lockdep */ 18 struct mutex bus_lock; 19 struct mutex clist_lock; 20 21 int timeout; 22 int retries; 23 struct device dev; /* the adapter device */ 24 25 int nr; 26 struct list_head clients; 27 struct list_head list; 28 char name[48]; 29 struct completion dev_released; 30 }
?
I2C核心
I2C核心提供了I2C總線驅動和設備驅動的注冊、注銷方法,I2C通信方法(algorithm)上層的與具體適配器無關的代碼以及探測設備、檢測設備地址的上層代碼等。
I2C總線驅動
I2C總線驅動是對I2C硬件體系結構中適配器段端的實現,適配器可由CPU控制,甚至可以直接集成在CPU內部。I2C總線驅動主要包括I2C適配器數據結構i2c_adapter、I2C適配器的Algorithm數據結構i2c_algorithm和控制I2C適配器產生通信信號的函數。經由I2C總線驅動的代碼,我們可以控制I2C適配器以主控方式產生開始位、停止位、讀寫周期,以及從設備方式讀寫、產生ACK等。
I2C設備驅動
? ? ?I2C設備驅動即客戶驅動時對I2C硬件體系結構中設備端的實現,設備一般掛接在受CPU控制的I2C適配器上,通過I2C適配器與CPU交換數據。I2C設備驅動主要包含數據結構i2c_driver和i2c_client,我們需要具體設備實現其中的成員函數。
在linux2.6內核中,所有設備都在sysfs文件系統中顯示,在sysfs虛擬文件系統中存放了驅動掛載的總線以及device、driver,當我們注冊一個driver后,內核會將我們注冊的這個driver添加到這類驅動總線上這類總線的擁有一個共同的類似于一個基類kobject,而kset就是koject的一個集合。我們在寫驅動的時候一般不會去分析kobject、kset,畢竟他們在內核里面是非常頂層的軟件抽象層,但是對于內核整個驅動框架,卻不能不分析這類抽象層,下圖是我在樹莓派所做的截圖:
?
我們可以看到在sys文件目錄下面有bus、class等,進入bus后會看到各種設備驅動,如在I2C中我們可以看到device、drivers,當然這些目錄下面都沒有什么內容應為sysfs是一個虛擬文件系統主要是記錄各個進程和內核方面的信息。我們的驅動設備如何和虛擬文件系統產生關系了呢,就是kobject在這兒起了作用,我們的device、driver最終都會掛載一個總線上,后面我們會看到sysfs申請內存為device或者driver建立節點。
同樣注冊一個device后也會掛載在總線上。其實I2C我們也可以看成設備-總線-驅動模型,
i2c_register_driver(THIS_MODULE, driver)
1 /* 2 * An i2c_driver is used with one or more i2c_client (device) nodes to access 3 * i2c slave chips, on a bus instance associated with some i2c_adapter. There 4 * are two models for binding the driver to its device: "new style" drivers 5 * follow the standard Linux driver model and just respond to probe() calls 6 * issued if the driver core sees they match(); "legacy" drivers create device 7 * nodes themselves. 8 */ 9 10 int i2c_register_driver(struct module *owner, struct i2c_driver *driver) 11 { 12 int res; 13 14 /* new style driver methods can't mix with legacy ones */ 15 if (is_newstyle_driver(driver)) { 16 if (driver->attach_adapter || driver->detach_adapter 17 || driver->detach_client) { 18 printk(KERN_WARNING 19 "i2c-core: driver [%s] is confused\n", 20 driver->driver.name); 21 return -EINVAL; 22 } 23 } 24 25 /* add the driver to the list of i2c drivers in the driver core */ 26 driver->driver.owner = owner; 27 driver->driver.bus = &i2c_bus_type; 28 29 /* for new style drivers, when registration returns the driver core 30 * will have called probe() for all matching-but-unbound devices. 31 */ 32 res = driver_register(&driver->driver); 33 if (res) 34 return res; 35 36 mutex_lock(&core_lists); 37 38 list_add_tail(&driver->list,&drivers); 39 pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); 40 41 /* legacy drivers scan i2c busses directly */ 42 if (driver->attach_adapter) { 43 struct i2c_adapter *adapter; 44 45 list_for_each_entry(adapter, &adapters, list) { 46 driver->attach_adapter(adapter); 47 } 48 } 49 50 mutex_unlock(&core_lists); 51 return 0; 52 }driver_register(&driver->driver);
1 /** 2 * driver_register - register driver with bus 3 * @drv: driver to register 4 * 5 * We pass off most of the work to the bus_add_driver() call, 6 * since most of the things we have to do deal with the bus 7 * structures. 8 */ 9 int driver_register(struct device_driver * drv) 10 { 11 if ((drv->bus->probe && drv->probe) || 12 (drv->bus->remove && drv->remove) || 13 (drv->bus->shutdown && drv->shutdown)) { 14 printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); 15 } 16 klist_init(&drv->klist_devices, NULL, NULL); 17 return bus_add_driver(drv); 18 }
klist_init(&drv->klist_devices, NULL, NULL);
1 /** 2 * driver_register - register driver with bus 3 * @drv: driver to register 4 * 5 * We pass off most of the work to the bus_add_driver() call, 6 * since most of the things we have to do deal with the bus 7 * structures. 8 */ 9 int driver_register(struct device_driver * drv) 10 { 11 if ((drv->bus->probe && drv->probe) || 12 (drv->bus->remove && drv->remove) || 13 (drv->bus->shutdown && drv->shutdown)) { 14 printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); 15 } 16 klist_init(&drv->klist_devices, NULL, NULL); 17 return bus_add_driver(drv); 18 } bus_add_driver(drv); 1 /** 2 * bus_add_driver - Add a driver to the bus. 3 * @drv: driver. 4 * 5 */ 6 int bus_add_driver(struct device_driver *drv) 7 { 8 struct bus_type * bus = get_bus(drv->bus); 9 int error = 0; 10 11 if (!bus) 12 return -EINVAL; 13 14 pr_debug("bus %s: add driver %s\n", bus->name, drv->name); 15 error = kobject_set_name(&drv->kobj, "%s", drv->name); 16 if (error) 17 goto out_put_bus; 18 drv->kobj.kset = &bus->drivers; 19 if ((error = kobject_register(&drv->kobj))) 20 goto out_put_bus; 21 22 if (drv->bus->drivers_autoprobe) { 23 error = driver_attach(drv); 24 if (error) 25 goto out_unregister; 26 } 27 klist_add_tail(&drv->knode_bus, &bus->klist_drivers); 28 module_add_driver(drv->owner, drv); 29 30 error = driver_add_attrs(bus, drv); 31 if (error) { 32 /* How the hell do we get out of this pickle? Give up */ 33 printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", 34 __FUNCTION__, drv->name); 35 } 36 error = add_bind_files(drv); 37 if (error) { 38 /* Ditto */ 39 printk(KERN_ERR "%s: add_bind_files(%s) failed\n", 40 __FUNCTION__, drv->name); 41 } 42 43 return error; 44 out_unregister: 45 kobject_unregister(&drv->kobj); 46 out_put_bus: 47 put_bus(bus); 48 return error; 49 }
kobject_register(&drv->kobj)
1 /** 2 * kobject_register - initialize and add an object. 3 * @kobj: object in question. 4 */ 5 6 int kobject_register(struct kobject * kobj) 7 { 8 int error = -EINVAL; 9 if (kobj) { 10 kobject_init(kobj); 11 error = kobject_add(kobj); 12 if (!error) 13 kobject_uevent(kobj, KOBJ_ADD); 14 } 15 return error; 16 } kobject_add(kobj); 1 /** 2 * kobject_add - add an object to the hierarchy. 3 * @kobj: object. 4 */ 5 int kobject_add(struct kobject * kobj) 6 { 7 return kobject_shadow_add(kobj, NULL); 8 } kobject_shadow_add(kobj, NULL);1 /** 2 * kobject_shadow_add - add an object to the hierarchy. 3 * @kobj: object. 4 * @shadow_parent: sysfs directory to add to. 5 */ 6 7 int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent) 8 { 9 int error = 0; 10 struct kobject * parent; 11 12 if (!(kobj = kobject_get(kobj))) 13 return -ENOENT; 14 if (!kobj->k_name) 15 kobj->k_name = kobj->name; 16 if (!*kobj->k_name) { 17 pr_debug("kobject attempted to be registered with no name!\n"); 18 WARN_ON(1); 19 kobject_put(kobj); 20 return -EINVAL; 21 } 22 parent = kobject_get(kobj->parent); 23 24 pr_debug("kobject %s: registering. parent: %s, set: %s\n", 25 kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>", 26 kobj->kset ? kobj->kset->kobj.name : "<NULL>" ); 27 28 if (kobj->kset) { 29 spin_lock(&kobj->kset->list_lock); 30 31 if (!parent) 32 parent = kobject_get(&kobj->kset->kobj); 33 34 list_add_tail(&kobj->entry,&kobj->kset->list); 35 spin_unlock(&kobj->kset->list_lock); 36 kobj->parent = parent; 37 } 38 39 error = create_dir(kobj, shadow_parent); 40 if (error) { 41 /* unlink does the kobject_put() for us */ 42 unlink(kobj); 43 kobject_put(parent); 44 45 /* be noisy on error issues */ 46 if (error == -EEXIST) 47 printk(KERN_ERR "kobject_add failed for %s with " 48 "-EEXIST, don't try to register things with " 49 "the same name in the same directory.\n", 50 kobject_name(kobj)); 51 else 52 printk(KERN_ERR "kobject_add failed for %s (%d)\n", 53 kobject_name(kobj), error); 54 dump_stack(); 55 } 56 57 return error; 58 }
create_dir(kobj, shadow_parent);
?
1 static int create_dir(struct kobject * kobj, struct dentry *shadow_parent) 2 { 3 int error = 0; 4 if (kobject_name(kobj)) { 5 error = sysfs_create_dir(kobj, shadow_parent); 6 if (!error) { 7 if ((error = populate_dir(kobj))) 8 sysfs_remove_dir(kobj); 9 } 10 } 11 return error; 12 }sysfs_create_dir(kobj, shadow_parent);
?
1 /** 2 * sysfs_create_dir - create a directory for an object. 3 * @kobj: object we're creating directory for. 4 * @shadow_parent: parent parent object. 5 */ 6 7 int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent) 8 { 9 struct dentry * dentry = NULL; 10 struct dentry * parent; 11 int error = 0; 12 13 BUG_ON(!kobj); 14 15 if (shadow_parent) 16 parent = shadow_parent; 17 else if (kobj->parent) 18 parent = kobj->parent->dentry; 19 else if (sysfs_mount && sysfs_mount->mnt_sb) 20 parent = sysfs_mount->mnt_sb->s_root; 21 else 22 return -EFAULT; 23 24 error = create_dir(kobj,parent,kobject_name(kobj),&dentry); 25 if (!error) 26 kobj->dentry = dentry; 27 return error; 28 }create_dir(kobj,parent,kobject_name(kobj),&dentry);
1 static int create_dir(struct kobject * k, struct dentry * p, 2 const char * n, struct dentry ** d) 3 { 4 int error; 5 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 6 7 mutex_lock(&p->d_inode->i_mutex); 8 *d = lookup_one_len(n, p, strlen(n)); 9 if (!IS_ERR(*d)) { 10 if (sysfs_dirent_exist(p->d_fsdata, n)) 11 error = -EEXIST; 12 else 13 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, 14 SYSFS_DIR); 15 if (!error) { 16 error = sysfs_create(*d, mode, init_dir); 17 if (!error) { 18 inc_nlink(p->d_inode); 19 (*d)->d_op = &sysfs_dentry_ops; 20 d_rehash(*d); 21 } 22 } 23 if (error && (error != -EEXIST)) { 24 struct sysfs_dirent *sd = (*d)->d_fsdata; 25 if (sd) { 26 list_del_init(&sd->s_sibling); 27 sysfs_put(sd); 28 } 29 d_drop(*d); 30 } 31 dput(*d); 32 } else 33 error = PTR_ERR(*d); 34 mutex_unlock(&p->d_inode->i_mutex); 35 return error; 36 }sysfs_create(*d, mode, init_dir);
1 int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *)) 2 { 3 int error = 0; 4 struct inode * inode = NULL; 5 if (dentry) { 6 if (!dentry->d_inode) { 7 struct sysfs_dirent * sd = dentry->d_fsdata; 8 if ((inode = sysfs_new_inode(mode, sd))) { 9 if (dentry->d_parent && dentry->d_parent->d_inode) { 10 struct inode *p_inode = dentry->d_parent->d_inode; 11 p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; 12 } 13 goto Proceed; 14 } 15 else 16 error = -ENOMEM; 17 } else 18 error = -EEXIST; 19 } else 20 error = -ENOENT; 21 goto Done; 22 23 Proceed: 24 if (init) 25 error = init(inode); 26 if (!error) { 27 d_instantiate(dentry, inode); 28 if (S_ISDIR(mode)) 29 dget(dentry); /* pin only directory dentry in core */ 30 } else 31 iput(inode); 32 Done: 33 return error; 34 }
sysfs_create(*d, mode, init_dir);
1 int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *)) 2 { 3 int error = 0; 4 struct inode * inode = NULL; 5 if (dentry) { 6 if (!dentry->d_inode) { 7 struct sysfs_dirent * sd = dentry->d_fsdata; 8 if ((inode = sysfs_new_inode(mode, sd))) { 9 if (dentry->d_parent && dentry->d_parent->d_inode) { 10 struct inode *p_inode = dentry->d_parent->d_inode; 11 p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; 12 } 13 goto Proceed; 14 } 15 else 16 error = -ENOMEM; 17 } else 18 error = -EEXIST; 19 } else 20 error = -ENOENT; 21 goto Done; 22 23 Proceed: 24 if (init) 25 error = init(inode); 26 if (!error) { 27 d_instantiate(dentry, inode); 28 if (S_ISDIR(mode)) 29 dget(dentry); /* pin only directory dentry in core */ 30 } else 31 iput(inode); 32 Done: 33 return error; 34 }
sysfs_new_inode(mode, sd))
1 struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd) 2 { 3 struct inode * inode = new_inode(sysfs_sb); 4 if (inode) { 5 inode->i_blocks = 0; 6 inode->i_mapping->a_ops = &sysfs_aops; 7 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; 8 inode->i_op = &sysfs_inode_operations; 9 inode->i_ino = sd->s_ino; 10 lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key); 11 12 if (sd->s_iattr) { 13 /* sysfs_dirent has non-default attributes 14 * get them for the new inode from persistent copy 15 * in sysfs_dirent 16 */ 17 set_inode_attr(inode, sd->s_iattr); 18 } else 19 set_default_inode_attr(inode, mode); 20 } 21 return inode; 22 }
new_inode(sysfs_sb); 1 /** 2 * new_inode - obtain an inode 3 * @sb: superblock 4 * 5 * Allocates a new inode for given superblock. 6 */ 7 struct inode *new_inode(struct super_block *sb) 8 { 9 /* 10 * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW 11 * error if st_ino won't fit in target struct field. Use 32bit counter 12 * here to attempt to avoid that. 13 */ 14 static unsigned int last_ino; 15 struct inode * inode; 16 17 spin_lock_prefetch(&inode_lock); 18 19 inode = alloc_inode(sb); 20 if (inode) { 21 spin_lock(&inode_lock); 22 inodes_stat.nr_inodes++; 23 list_add(&inode->i_list, &inode_in_use); 24 list_add(&inode->i_sb_list, &sb->s_inodes); 25 inode->i_ino = ++last_ino; 26 inode->i_state = 0; 27 spin_unlock(&inode_lock); 28 } 29 return inode; 30 } alloc_inode(sb); 1 static struct inode *alloc_inode(struct super_block *sb) 2 { 3 static const struct address_space_operations empty_aops; 4 static struct inode_operations empty_iops; 5 static const struct file_operations empty_fops; 6 struct inode *inode; 7 8 if (sb->s_op->alloc_inode) 9 inode = sb->s_op->alloc_inode(sb); 10 else 11 inode = (struct inode *) kmem_cache_alloc(inode_cachep, GFP_KERNEL); 12 13 if (inode) { 14 struct address_space * const mapping = &inode->i_data; 15 16 inode->i_sb = sb; 17 inode->i_blkbits = sb->s_blocksize_bits; 18 inode->i_flags = 0; 19 atomic_set(&inode->i_count, 1); 20 inode->i_op = &empty_iops; 21 inode->i_fop = &empty_fops; 22 inode->i_nlink = 1; 23 atomic_set(&inode->i_writecount, 0); 24 inode->i_size = 0; 25 inode->i_blocks = 0; 26 inode->i_bytes = 0; 27 inode->i_generation = 0; 28 #ifdef CONFIG_QUOTA 29 memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); 30 #endif 31 inode->i_pipe = NULL; 32 inode->i_bdev = NULL; 33 inode->i_cdev = NULL; 34 inode->i_rdev = 0; 35 inode->dirtied_when = 0; 36 if (security_inode_alloc(inode)) { 37 if (inode->i_sb->s_op->destroy_inode) 38 inode->i_sb->s_op->destroy_inode(inode); 39 else 40 kmem_cache_free(inode_cachep, (inode)); 41 return NULL; 42 } 43 44 mapping->a_ops = &empty_aops; 45 mapping->host = inode; 46 mapping->flags = 0; 47 mapping_set_gfp_mask(mapping, GFP_HIGHUSER); 48 mapping->assoc_mapping = NULL; 49 mapping->backing_dev_info = &default_backing_dev_info; 50 51 /* 52 * If the block_device provides a backing_dev_info for client 53 * inodes then use that. Otherwise the inode share the bdev's 54 * backing_dev_info. 55 */ 56 if (sb->s_bdev) { 57 struct backing_dev_info *bdi; 58 59 bdi = sb->s_bdev->bd_inode_backing_dev_info; 60 if (!bdi) 61 bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info; 62 mapping->backing_dev_info = bdi; 63 } 64 inode->i_private = NULL; 65 inode->i_mapping = mapping; 66 } 67 return inode; 68 }
?kmem_cache_alloc(inode_cachep, GFP_KERNEL);這兒就是最底層為sys虛擬文件系統分配內存的函數,就是采用了高速頁緩存方法,在內存中為節點分配了一塊內存。
1 ** 2 * kmem_cache_alloc - Allocate an object 3 * @cachep: The cache to allocate from. 4 * @flags: See kmalloc(). 5 * 6 * Allocate an object from this cache. The flags are only relevant 7 * if the cache has no available objects. 8 */ 9 void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) 10 { 11 return __cache_alloc(cachep, flags, __builtin_return_address(0)); 12 }? ? ? 上面是關于sysfs虛擬文件系統的分析,與i2c驅動沒有太大的關系,但是我們可以看出來i2c的driver和device最后都是掛在總線上的,這些都是可以歸納為:總線---設備-----驅動模型的,我們可以看出來從i2c_add_driver()函數開始內核不光是在建立一個driver同時也在忙著將這個dirver掛在這個總線上,前面貼出的代碼描述了這個過程,下面在看看流程:
i2c_add_driver()----------->i2c_register_driver() ?
|
|
driver->driver.bus = &i2c_bus_type
1 struct bus_type i2c_bus_type = { 2 .name = "i2c", 3 .dev_attrs = i2c_dev_attrs, 4 .match = i2c_device_match, 5 .uevent = i2c_device_uevent, 6 .probe = i2c_device_probe, 7 .remove = i2c_device_remove, 8 .shutdown = i2c_device_shutdown, 9 .suspend = i2c_device_suspend, 10 .resume = i2c_device_resume, 11 };i2c_driver與i2c_client關系:
i2c_driver對應于一套驅動方法,主要成員函數是probe()、remove()、suspend()、resume()。 ? ? ?
i2c_client對應于真實的物理設備,每個I2C設備都需要一個i2c_client來描述,i2c_driver與i2c_client的關系是一對多,一個i2c_drvier可以支持多個同類型的i2c_client。
i2c_adpater與i2c_client關系
i2c_adpater與i2c_client的關系與I2C硬件體系中適配器和設備的關系一致,即i2c_client依附于i2c_adapter。一個適配器可以連接多個I2C設備,所以一個i2c_adapter也可以被多個i2c_client依附,i2c_adapter中包括依附于它的i2c_client的鏈表。
剛開始沒搞懂其實i2c_client、i2c_adpater這兩個數據結構都是內核抽象出來的便于對多平臺的適應,每一個i2c_adpater對應于一條總線,i2c_client每一個對應于一個具體設備。
網上的解釋:簡單點了, 你的開發板上有幾個I2C接口,就有幾個adapter , 也就是有幾條I2C bus ,??I2C CLIENT 對應的就是你的外圍I2C 設備,有幾個就有幾個CLIENT , 把這些設備插入開發板, 對應其中的一條BUS, 那么相應的就對應了其中的一個ADAPTER , 接下來的就是??CLIENT 與 ADAPTER 勾搭成對了, 后面就是做該做的事了在編寫I2C驅動的時候我們需要實現兩個方面的內容:
1、提供I2C適配器的硬件驅動,探測、初始化I2C適配器、驅動CPU控制的I2C適配器從硬件上產生各種信號及處理I2C中斷。
2、提供I2C適配器的算法,用具體適配器的xxx_dfer()函數填充i2c_algorithm的master_xfer指針。
3、對I2C core的接口,必須實現 struct i2c_drvier數據結構中的幾個特定的功能函數。這些函數是I2C驅動與I2C總線物理層(I2C控制器)和I2C設備器件之間通信的基礎。 4、 對用戶應用層的接口,必須實現struct file_operation數據結構中的一些特定功能的函數,如 open ,release , read ,write,lseek等函數。以上兩類接口中,對I2C core的接口是對I2C設備訪問的基礎,實現對I2C總線具體的訪問方法;對用戶應用層的接口則是方便應用程序開發,實現設備特定功能的必不可少的部分。例如,如果是字符設備,就實現文件操作接口,實現具體設備yyy的yyy_read()、yyy_write()和yyy_ioctl()函數等;如果是聲卡,就實現ALSA驅動。
下面的函數流程就是i2c注冊的過程,在注冊的過程中會把i2c添加到總線上去,同時完成match過程(目前沒有弄清楚的流程),難道是在這兒進行了dev和driver的比較?
i2c_add_driver()---------->i2c_register_driver()------------>driver_register()------------------->bus_add_driver()-------->driver_attach()--------->bus_for_each_dev()-------------->__driver_attach()----------------->driver_probe_device()----------------->int (*match)(struct device * dev, struct device_driver * drv)
?
總結一下I2C驅動的流程:
1、首先,在i2c_client_address_data的normal_i2c屬性中定義好我們設備的設備地址。
2、接下來,i2c_driver就出場了,它的功能是定義i2c設備的名字,探測函數,卸載函數三個屬性。
3、當程序在入口函數中注冊i2c-driver驅動之后,系統就會根據我們第一步中定義的設備地址,調用attach_adapter函數進行匹配設備地址是否支持,在attach_adapter函數中主要的功能是在調用i2c_probe函數,當系統檢測到設備地址匹配時,就會進入i2c_probe函數中干一些重要的事,接著就進入i2c-probe傳入的at24cxx_detect函數中實現我們自己的事。
其實總結一下就下面一個流程:at24cxx_attach_adapter -> i2c_probe -> at24cxx_detect
? 當我們卸載設備時,會自動調用i2c_driver中定義的卸載函數at24cxx_detach_adapter進行卸載設備。
? ?最后一步自然就是在出口函數中卸載i2c-driver驅動。
? 因為I2C只是一種通信的方式,所以在完成前面的工作后我們需要完成我們要在I2C這種通信方式山所做的工作,我們一般在at24cxx_detect()中完成設備register_chrdev()的注冊,然后填寫read()、write()等函數。
? 沒有弄得很清楚的就是為什么沒有注冊i2c_add_adapter()---------->i2c_register_adapter(),適配器和device的匹配是在driver中完成的嗎?
? 參考的比較經典的博文:http://www.cnblogs.com/lihaiyan/p/4452875.html
http://blog.csdn.net/chocolate001/article/details/7470873
http://blog.sina.com.cn/s/blog_63f31f340101byb2.html
http://www.embedu.org/Column/Column213.htm
轉載于:https://www.cnblogs.com/qiuheng/p/5761865.html
總結
以上是生活随笔為你收集整理的linux驱动之I2C的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu5831 Rikka with P
- 下一篇: linux学习作业-第七周