Oneness ~linux device-driven i²c core, bus, and device driver

Source: Internet
Author: User
Tags ack

    • The city I miss is dusk
    • Why do I always passionately devoted to you
    • Once gave me happiness also gave me trauma
    • Once gave me hope and gave me despair
    • I'm in a strange crowd in a faraway city
    • Feel your Distant sorrow
    • My fantasies.

Your sorrow, like my despair, so long,,,, this is today's melody, straight into the bottom of my heart ~~~~~~~~~~~~~~~~

In the Linux system, the I²c drive consists of 3 parts, namely, the I²c core, the I²c bus drive and the I²C device driver, the I²C bus uses only SCL, SDA these two signal lines to realize the data interaction between the devices, greatly simplifies the use of hardware resources and PCB board cabling space

1 Linux's I²c architecture

1.1 Components

1) I²c Core

I²c Core provides i²c bus driver and device driver registration, logoff method, I²c communication method, etc.

2) I²c bus driver

The I²C bus driver mainly contains the I²C adapter data structure I2c_adapter, the algorithm data structure of the I²C adapter I2c_algorithm and the function of controlling the I²C adapter to generate the communication signal. is the implementation of the adapter side of the I²C hardware architecture The adapter can be controlled by the CPU and can even be integrated directly inside the CPU.

3) i²c device driver

I²c device driver mainly includes the data structure I2c_driver and i2c_client, we need to implement the member function according to the specific device. is the implementation of the device-side in the hardware architecture of I²C, the device is generally hooked up to the CPU-controlled i²c adapter, and the data is exchanged with the CPU via the I²C adapter.

1.2 I²c Equipment

All the I C devices are displayed in the Sysfs file system, stored in the/sys/bus/i2c/directory, listed as adapter address and chip address, I entered the command on Linux to obtain:

1.3 I2C.h Header File

The i2c.h header in the kernel defines the 4 data structures for I2c_driver, i2c_client, I2c_adapter, and I2c_algorithm. Understanding the role of these 4 structures is critical. The following analysis of the relationship between these 4 data structures and the role. As for the individual structure of the specific code to find in this file is OK.

1) I2c_adapter and I2c_algorithm.

The i2c_adapter corresponds to a physical adapter, while the i2c_algorithm corresponds to a set of communication methods. An I-C adapter requires a communication function provided in I2c_algorithm to control the adapter to generate a specific access cycle. A i2c_adapter that lacks i2c_algorithm can do nothing, so i2c_adapter contains a pointer to the I2c_algorithm it uses. the key function in I2c_algorithm Master_xfer () is used to generate the signals required for the I²c access cycle, in i2c_msg (that is, the I²C message) unit

2) I2c_driver and i2c_client.

The i2c_driver corresponds to a set of drive methods, which are purely auxiliary data structures that do not correspond to any physical entities. I2c_client corresponds to a real physical device, each I-C device needs a i2c_client to describe. I2c_client is generally included in the private information structure of the I-C character device. I2c_driver is associated with i2c_client at the moment when the I2c_driver Attach_adapter () function is run. Attach_adapter () detects the physical device and, when determining the presence of a client, points the adapter pointer of the I2c_client data structure used by the client to the corresponding I2c_adapter,driver pointer to the I2C_ Driver, and calls the I2c_adapter's Client_register () function. The opposite process occurs when the I2c_driver detach_client () function is called.

3) I2c_adpater and I2c_client

The relationship between I2c_adpater and I2c_client is consistent with the adapter and device in the I-C hardware system, that is, i2c_client is attached to I2c_adpater. Because a single adapter can connect multiple i²c devices, a i2c_adpater can also be Multiple i2c_client are attached, and the i2c_adpater includes a linked list of i2c_client attached to it.

2 Linux I²c Core

2.1 Add/Remove I2c_adapter.

int I²c Add Adapter (struct I²C adapter *adap); int i²c del adapter (struct-I²c adapter *adap);

2.2 Add/Remove I2c_driver.

int i²c Register driver (struct module *owner, struct-i²c driver *driver); int i²c del driver (struct-i²c driver *driver); inline int i²c Add driver (struct-i²c driver *driver);

2.3 I2c_client Attachment/Detachment

int i²c Attach Client (struct I²C client *client); int i²c detach Client (struct I²C client *client)

2.4 I²c transmit, send and receive

2.5 i²c Control Command Assignment

The following function is useful for assigning commands to the I-C adapter device file ioctl to the Algo_control () function of the algorithm of the Ching adapter or to the command () function of I2c_driver, as follows:

int i²c control (struct I²C client *client, unsigned int cmd, unsigned long arg), void i²c clients command (struct-i²c adapt ER *adap, unsigned int cmd,void *arg);

3 Linux i²c Bus driver

3.1 I²c Adapter driver loading and unloading

The module load and unload function template for the I²C bus driver is as follows code        static int      init i²c adapter XXX init (void)        {          xxx adpater HW init ();          I²c Add Adapter (&xxx adapter);        }        static void      exit I²c adapter XXX exit (void)        {           xxx adpater hw free ();         I²c del adapter (&xxx adapter);       
Implementations of the Xxx_adpater_hw_init () and Xxx_adpater_hw_free () functions are directly related to the specific CPU and I²C device hardware

3.2 I²c Bus Communication method

The

method of communication mainly implements the Master_xfer () function and the functionality () function of the i2c_algorithm. The functionality () function is very simple to return the communication protocol supported by algorithm, and the Master_xfer () function completes each i²c message in the number of i2c_msg passed to it on the I²c adapter, as shown in the following code, XXX The Master_xfer () function template for the device.

static int i²c adapter XXX xfer (struct i²c adapter *adap, struct i²c msg *msgs, int num) {... f                                    or (i = 0; i < num; i++) {i²c adapter xxx start ();/* Generate start bit *///Read message */ if (msgs[i]->flags &i2c M RD) {i²c adapter xxx setaddr ((msg->addr << 1) | 1); /* Send from Device read address */i²c adapter XXX wait ack (); /* Get ack*/i²c adapter xxx readbytes (msgs[i]->buf, Msgs[i]->len) from the device;                      /* Read Msgs[i]->len Long data to msgs[i]->buf*/} else/* is write message */{ I²c Adapter xxx setaddr (msg->addr << 1); /* Send from Device write address */i²c adapter XXX wait ack (); /* Get ack*/i²c adapter xxx writebytes (msgs[i]->buf, Msgs[i]->len) from the device; /* Read Msgs[i]->len Long data to msgs[i]->buf*/}} i²c adapter xxx Stop ();  /* Generate Stop bit */}

3.3 XXX_I2C Structural Body

Most i²c bus drivers define a XXX_I2C structure as the algo_data of the I2c_adapter (like "private Data"), which contains the I-C message pointer, the number index, and the I-C adapter algorithm access control spin lock, wait queue, etc., and mast The processing of messages in the Er_xfer () function completion message can also be controlled by access to the members of the XXX_I2C struct, defined by the XXX_I2C structure as follows:

struct XXX i²c        {                        spinlock t        lock;                      Wait Queue head T     wait;                      struct-i²c msg  *msg;                                      unsigned int          msg num;                                        unsigned int          msg idx;                                           unsigned int          msg ptr;         ...                   struct-I²c adapter ADAP;       

4 Linux i²c Device driver

I²c device driver to use i2c_driver and i2c_client data structures and populate them with member functions

4.1 Module loading and unloading

The load and unload function template code for the I²C device driver is as follows:

static int      init YYY init (void)        {          int res;          /* Register character device */                          res = Register Chrdev (YYY MAJOR, "YYY", &yyy fops),//////Old Kernel interface//description register "YYY" This character device when using the file_operations structure The Yyy_fops description registers "yyy" for this character device, the file_operations structure used is yyy_fops         if (res) goto out            ;                      /* Add I²c driver*/                     res = i²c Add driver (&yyy driver);         if (res)                       goto out Unreg class;         return 0;         Out Unreg chrdev:unregister Chrdev (i²c MAJOR, "i²c");                               OUT:PRINTK (KERN ERR "%s:driver initialisation failed\n",          FILE);         return res;       }       static void      exit YYY exit (void)       {                    i²c del driver (&i2cdev driver);                        Unregister Chrdev (YYY MAJOR, "YYY");       }

4.2 I2c_driver member functions

The execution of the i2c_add_driver will cause the execution of the Yyy_attach_adapter () function in the i2c_driver struct, and we can probe the physical device in the Yyy_attach_adapter () function. In order to implement the probe, the Yyy_attach_adapter () function simply calls the I2c_probe () function of the i²c core, and the I2c_attach_adapter function code of the I²C device driver is as follows:

static int yyy Attach adapter (struct I²C adapter *adapter) {    
The 1th parameter is the I2c_adapter pointer, the 2nd parameter is the address data to be probed, and the 3rd parameter is the specific probe function

The I2c_probe () function throws a call to the Yyy_detect () function, and you can initialize the I2C_CLIENT,I2C device-driven detect function code in the Yyy_detect () function as follows:

static int yyy Detect (struct-I²c adapter *adapter, int address, int kind) {struct-i²c clien                       T *new client;         struct YYY data *data;         int err = 0;       if (!I2C check functionality (adapter, i²c FUNC XXX) goto exit; if (! (            data = kzalloc (sizeof (struct yyy data), GFP KERNEL))//Allocates the memory of the private information structure, I2c_client is also created {err =-enomem;        Goto exit;                    } New client = &data->client;                 New client->addr = address;                  New Client->adapter = adapter;                   New client->driver = &yyy driver;              New client->flags = 0; /* The new client will be attached to adapter */if ((Err = i²c Attach client))//Call the kernel's i2c_attach_client () I C core system contains a                     A new I-C device goto exit Kfree; YYY Init client (new client);                     Initialize the i2c_client corresponding to the I²C device return 0; EXIT kfree:kfree (data);      Exit:return err;  }

When an I²C device-driven unload function makes a i2c_del_driver call, each i2c_client associated with Yyy_driver is thrown, and the code for the function Yyy_detach_client () is designed as follows:

static int yyy Detach client (struct I²C client *client)       {         int err;                  struct YYY Data *data = I²c get Clientdata (client); The I2c_get_clientdata () function is used to obtain the Yyy_data pointer from the i2c_client pointer in the Yyy_data private information structure (        err = i²c Detach Client ( Client))//Call the I-C core function i2c_detach_client (), this function will raise the I2c_adapter Client_unregister () function to be called         return err;               Kfree (data);    Frees the Yyy_data memory.        return 0;       

implementation of 4.3 Yyy_command ()

It implements the control commands for the device. The specific control commands are device-dependent, assuming that the YYY device accepts two classes of command yyy_cmd1 and YYY_CMD2, while the functions that handle the two commands yyy_cmd1 () and YYY_CMD2 (), the I²C device-driven command function code is as follows:

static int yyy command (struct i²c client *client, unsigned int cmd, void  *arg)       {         switch (cmd)          {            case YYY CMD1:            return YYY cmd1 (client, arg);           Case YYY CMD2:              return YYY cmd2 (client, arg);           Default:             return  -EINVAL;         }      

The implementation of the specific command is through the number of pieces of I2C_MSG messages, and call the core of the transmission, sending and receiving functions, I c core transmission, sending and receiving functions called I C adapter corresponding to the algorithm correlation function to complete.

4.4 File Operation interface

As a character class device, the Linux I C device-driven file operation interface is fully consistent with the normal device driver, but in which the i2c_client, I2c_driver, I2c_adapter, and i2c_algorithm structures and the i²c core are used, and the device read and write and control needs to take advantage of the architecture of the various components of the collaboration, the following is an I²C device file interface Write function Example:

Static Ssize t yyy write (struct file *file, char *buf, size t count, Loff t off)        {        struct       i²c client       *cli ent       =      (struct i²c client*) file->private data;             I²c msg msg[1];          char *tmp;          int ret;          TMP = Kmalloc (count, GFP KERNEL);          if (tmp = = NULL)           return  -Enomem;         if (Copy from user (TMP, BUF, count))         {           kfree (TMP);           return  -efault;         }               MSG[0].ADDR = client->addr;//address         msg[0].flags = 0;               0 for write         Msg[0].len = count;             Number of bytes to write         msg[0].buf = tmp;               Data to be written         ret = i²c transfer (Client->adapter, MSG, 1);  Transfer i C message         return (ret = = 1)? Count:ret;       

The write operation of the I²C device has undergone several steps as follows:

    1. From user space to character device driver write function interface, write function constructs the number of I²C messages.
    2. The Write function passes the number of constructed I-C messages to the transfer function I2c_transfer () of the i²c core.
    3. I2 C Core transfer function I2c_tr Ansfer () find the corresponding adapter algorithm communication method function Master_xfer () to finalize the processing of the I²C message.

4.5 i2c-dev.c File Analysis

The I2cdev_read (), I2cdev_write () functions are provided in i2c-dev.c to correspond to the read () and write () file operation interfaces to be used by the user space, which invoke the I2c_master_recv () and i2c_ of the I C core, respectively The Master_send () function constructs an I²C message and raises the call of the adapter algorithm communication function to complete the transmission of the message. But i2c-dev.c the I2cdev_read () and I2cdev_write () functions are not too versatile, There is not much practical value, only applicable to non-repstart mode situations. For reads and writes of more than two messages, the I2C_MSG message array needs to be woven into the user space and the I2c_rdwr IOCTL command is called.

All rights reserved, reprint please specify reprint address: http://www.cnblogs.com/lihuidashen/p/4511469.html

Oneness ~linux device-driven i²c core, bus, and device driver

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.