Analysis of S3C2440 driver-I2C Driver (2)

Source: Internet
Author: User

Next to the introduction of the main I2C data structure in the previous blog post, let's go into the I2C driver code to get a glimpse of this slightly complicated driver. Since the Code already has a certain length, you can no longer copy the entire segment as before, and then analyze it directly. In order for the monks to better read their notes in the future, and for the cainiao who are more comfortable with me (it should be none, huh, huh), this time I will adopt the logic order of the Code, where to talk about it, where can I paste the code ~ Go ~~~

 

See more than 600 lines of i2c-dev.c driver code, for general beginners is still awkward, but it does not matter, we remember to see the driver, the first thing to find the entrance and exit! The code for _ init and _ exit is as follows:

 

Static int _ init i2c_dev_init (void) <br/>{< br/> int res; </P> <p> printk (kern_info "I2C/dev entries driver/N"); </P> <p> res = register_chrdev (i2c_major, "I2C ", & i2cdev_fops); <br/> If (RES) <br/> goto out; </P> <p> i2c_dev_class = class_create (this_module, "i2c-dev "); <br/> If (is_err (i2c_dev_class) {<br/> res = ptr_err (i2c_dev_class); <br/> goto out_unreg_chrdev; <br/>}</P> <p> res = i2c_add_driver (& i2cdev_driver); <br/> If (RES) <br/> goto out_unreg_class; </P> <p> return 0; </P> <p> out_unreg_class: <br/> class_destroy (i2c_dev_class); <br/> out_unreg_chrdev: <br/> unregister_chrdev (i2c_major, "I2C"); <br/> out: <br/> printk (kern_err "% s: Driver initialisation failed/N ", _ file _); <br/> return res; <br/>}</P> <p> static void _ exit i2c_dev_exit (void) <br/>{< br/> i2c_del_driver (& i2cdev_driver); <br/> class_destroy (i2c_dev_class); <br/> unregister_chrdev (i2c_major, "I2C "); <br/>}

 

I2c_dev_init:

This initial function mainly does three things.

1. Res = register_chrdev (i2c_major, "I2C", & i2cdev_fops );

Obviously, register a character device and link it to the i2cdev_fops struct of the user space's operation function.

 

2. i2c_dev_class = class_create (this_module, "i2c-dev ");

The class_create function is a new thing for us. We need to study it. The struct class struct is defined in the Linux kernel. As the name suggests, a struct class struct type variable corresponds to a class, and the kernel also provides class_create (...) Function, you can use it to create a class, which is stored under sysfs. Once this class is created, call device_create (...) Function to create a device node in the/dev directory. In this way, when the module is loaded, udev in the user space will automatically respond to device_create (...) Function to find the corresponding class under/sysfs to create a device node.

 

3. Res = i2c_add_driver (& i2cdev_driver );

Register a device. The i2cdev_driver structure is defined as follows elsewhere in the Code:

 

Static struct i2c_driver i2cdev_driver ={< br/>. driver ={< br/>. name = "dev_driver", <br/>}, <br/>. attach_adapter = i2cdev_attach_adapter, <br/>. detach_adapter = i2cdev_detach_adapter, <br/> };

 

This struct mainly includes two functions: i2cdev_attach_adapter and i2cdev_detach_adapter. The i2cdev_attach_adapter is responsible for linking to the I2C adapter, while the latter is vice versa.

 

First, we will discuss i2cdev_attach_adapter. The Code is as follows:

Static int i2cdev_attach_adapter (struct i2c_adapter * ADAP) <br/>{< br/> struct i2c_dev * i2c_dev; <br/> int res; </P> <p> i2c_dev = get_free_i2c_dev (ADAP); <br/> If (is_err (i2c_dev) <br/> return ptr_err (i2c_dev ); </P> <p>/* Register this I2C device with the driver core */<br/> i2c_dev-> Dev = device_create (i2c_dev_class, & ADAP-> Dev, <br/> mkdev (i2c_major, ADAP-> nr), null, <br/> "I2C-% d", ADAP-> nr ); <br/> If (is_err (i2c_dev-> Dev) {<br/> res = ptr_err (i2c_dev-> Dev); <br/> goto error; <br/>}< br/> res = device_create_file (i2c_dev-> Dev, & dev_attr_name); <br/> If (RES) <br/> goto error_destroy; </P> <p> pr_debug ("i2c-dev: adapter [% s] registered as minor % d/N", <br/> ADAP-> name, ADAP-> nr); <br/> return 0; <br/> error_destroy: <br/> device_destroy (i2c_dev_class, mkdev (i2c_major, ADAP-> nr )); <br/> error: <br/> return_i2c_dev (i2c_dev); <br/> return res; <br/>}

 

The function first passes in an i2c_adapter struct pointer, which exactly represents an I2C Adapter. The function mainly does three things.

1. i2c_dev = get_free_i2c_dev (ADAP );

The input ADAP adapter pointer refers to the incoming adapter pointer in the returned i2c_dev structure.

 

2. i2c_dev-> Dev = device_create (i2c_dev_class, & ADAP-> Dev,
Mkdev (i2c_major, ADAP-> nr), null, "I2C-% d", ADAP-> nr );

The first parameter specifies the class of the device to be created. The second parameter is the parent device of the device. If not, it is null. The third parameter is the device number, the fourth parameter is the device name, and the fifth parameter is the slave device number. Create a module and link it to sysfs.

 

3. Res = device_create_file (i2c_dev-> Dev, & dev_attr_name );

Create a property file for the device.

 

 

Now let's take a look at the i2cdev_detach_adapter function.

Static int i2cdev_detach_adapter (struct i2c_adapter * ADAP) <br/>{< br/> struct i2c_dev * i2c_dev; </P> <p> i2c_dev = ignore (ADAP-> nr ); <br/> If (! I2c_dev)/* attach_adapter must have failed */<br/> return 0; </P> <p> device_remove_file (i2c_dev-> Dev, & dev_attr_name ); <br/> return_i2c_dev (i2c_dev); <br/> device_destroy (i2c_dev_class, mkdev (i2c_major, ADAP-> nr); </P> <p> pr_debug ("i2c-dev: adapter [% s] unregistered/N ", ADAP-> name); <br/> return 0; <br/>}

 

This function does a total of four tasks to "get rid of" the adapter.

1. i2c_dev = i2c_dev_get_by_minor (ADAP-> nr );

Find the device by the device number and bring it back by the i2c_dev struct pointer for the following functions.

 

2. device_remove_file (i2c_dev-> Dev, & dev_attr_name );

Delete the corresponding device_create_file.

 

3. return_i2c_dev (i2c_dev );

Delete the input device from the device list and release i2c_dev.

 

4. device_destroy (i2c_dev_class, mkdev (i2c_major, ADAP-> nr ));

Delete the device together with the class corresponding to the device (actually a high-level view that ignores underlying operations.


 

So far, the initialization of the driver is complete. Let's look back and exit function _ exit.

Static void _ exit i2c_dev_exit (void) <br/>{< br/> i2c_del_driver (& i2cdev_driver); <br/> class_destroy (i2c_dev_class ); <br/> unregister_chrdev (i2c_major, "I2C"); <br/>}

 

There are only three statements. The execution sequence is exactly the same as the registration sequence of the initialization function _ init. Here we will not go into details about how the functions are executed.

 

 

The space functions provided in i2cdev_fops are to be further explored in the next blog. Here, only the code of its struct is pasted as follows:

Static const struct file_operations i2cdev_fops ={< br/>. owner = this_module, <br/>. llseek = no_llseek, <br/>. read = i2cdev_read, <br/>. write = i2cdev_write, <br/>. unlocked_ioctl = i2cdev_ioctl, <br/>. open = i2cdev_open, <br/>. release = i2cdev_release, <br/> };

 

Hey hey, very familiar structure, very familiar face. Please refer to the next section for details ~

 

Links to this series of blog posts:

I2C drive (1) http://blog.csdn.net/jarvis_xian/archive/2011/05/27/6449939.aspx
I2C drive (2) http://blog.csdn.net/jarvis_xian/archive/2011/05/27/6451168.aspx
I2C drive (3) http://blog.csdn.net/jarvis_xian/archive/2011/05/28/6452431.aspx
I2C drive (4) http://blog.csdn.net/jarvis_xian/archive/2011/05/30/6455697.aspx

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.