Introduction to the Android Driver (ii) IIC

Source: Internet
Author: User

I. About I2C


The I2C (Inter-Integrated Circuit) bus is a two-line serial bus developed by Philips to connect the microcontroller and its peripheral devices. The main advantage of I2C bus is its simplicity and effectiveness. The simplicity is embodied in the simple wiring. There are only two lines of data cable (SCL) and clock line (SDA), and the control is simple. Therefore, some smaller encapsulated devices mostly use I2C bus. Common devices that use I2C bus include EEPROM, RTC, and some sensors. Here we will introduce the compilation of linux-based I2C device drivers.


  • I2C device drivers can be written in multiple ways.


    One is to directly operate the I2C controller of the CPU and write a character driver to a device. This driver is relatively direct and does not need to be too dependent on Kernel configurations, however, this type of device driver depends on the CPU, which is less portable.

    One is to compile the device driver based on the Linux kernel I2C subsystem. Generally, the kernel inherits the controller driver of the CPU and can be obtained through technical support even if it does not, therefore, we only need to use the interfaces provided by the I2C subsystem in linux to build our device drivers. In this way, our device drivers do not depend on a specific CPU and are more portable.

    IIC drivers are mainly divided into Master and Slave, Master is the host controller, IIC controller like A10 is a Master, Slave is the IIC Slave device, it must be attached to the Master to work
    Almost all sensor devices on smartphones and tablets are IIC devices. The most common IIC devices are capacitive touch screens and cameras. Next, we will analyze drivers such as touch screens, EEPROM, and cameras.

    • How I2C bus works

      The I2C bus is a serial bus consisting of the data cable SDA and clock SCL.

      Parallel Connection on this bus, each device has a unique address identification, can be used as


      The sender device or receiver device (determined by the device's functions ). The interface circuit structure of I2C bus is shown in 1.


      • Several signal statuses of I2C bus

        1. Idle status: SDA and SCL are both high.

        2. Start condition (S): In high-power mode, SDA changes from high level to low level and starts to transmit data.

        3. End condition (P): In high-power mode, SDA changes from low-level to high-level and ends data transmission.

        4. valid data: SDA remains stable and valid during the high-level period of the SCL. SDA changes can only occur during the low-level period of the SCL.

        5. ACK signal: During data transmission, each byte of data received by the receiver generates an ACK signal, which sends a specific low-level pulse to the sending device, indicating that the data has been received.


        • Basic I2C bus operations

          The I2C bus must be controlled by the master device (usually a microcontroller). The master device generates a serial clock (SCL), controls the transmission direction of the bus, and generates Start and Stop conditions.

          In data transmission, the first condition is generated by the master device, followed by the control byte of the device (the first seven digits are the address of the device, and the last one is the read/write bit ). The next step is to read and write the data and the ACK response signal. When data transmission ends, the master device generates a stop condition. The specific process 2 is shown.





          Ii. Linux I2C driver
          • I2C driver hierarchy
            Linux has good support for I2C devices. The I2C driver in Linux can be divided into three parts: 1. i2C core: Manages I2C bus, I2C adapter, and I2C driver. 2. I2C controller driver I2C adapter: for different types of I2C controllers, the specific method to achieve I2C bus access. 3. I2C driver driven by I2C devices: provides specific functions for specific I2C devices, including read, write, and ioctl interfaces for user-layer operations.
            The three layers are shown in figure 3 and figure 4.








            • I2C core)
              I2C core is the core part of Linux kernel for maintaining and managing I2C. It maintains two static lists, respectively recording the I2C driver structure and I2C adapter structure in the system. I2C core provides interface functions that allow an I2C adapter, I2C driver, and I2C client to register in I2C core during initialization, and to log out upon exit. At the same time, it also provides general interfaces for I2C bus read/write access (specifically implemented in I2C adapter related to I2C Controller) and is mainly used in I2C device drivers.
              • I2C controller driver (I2C adapter)
                I2C adapter is a specific method for accessing the I2C bus at the underlying layer for different types of I2C controller hardware. The I2C adapter constructs a data structure for the I2C core layer interface and registers a controller with the I2C core through the interface function. The I2C adapter mainly implements the I2C bus access algorithm. The master_xfer () function is the implementation of the I2C adapter's underlying read/write method on the I2C bus. At the same time, the I2C adapter also implements the handler for I2C controller interruption.

                • I2C driver)
                  I2C driver is a software implementation for I2C slave devices. I2C driver provides a general I2C device driver, which implements the access interface for character devices. The specific access to devices is implemented through I2C adapter. I2C driver constructs a data structure for the I2C core layer interface, and registers an I2C Device driver with I2C Core through the interface function. At the same time, I2C driver constructs a Data Structure for user-layer interfaces, and registers it with the kernel as a character-type device with the main device Number of 89 through interface functions. I2C driver allows users to access I2C devices, including open, read, write, ioctl, and release. You can use the open function to open I2C device files, the ioctl function is used to set the address of the I2C device to be accessed, and then the read and write operations on the I2C device can be completed through the read and write Functions. The general method provided by I2C driver can access any I2C device. However, the implemented read, write, ioctl, and other functions are completely implemented based on general devices, all operation data is based on byte streams and has no clear format or meaning. To facilitate and effectively use I2C devices, you can develop specific I2C device drivers for a specific I2C device, complete the interpretation of specific data formats and implement some special functions in the driver.

                  Iii. I2C Controller Driver Based on SUNXI Platform
                  The file i2c-sunxi.c located in the drivers/i2c/busses directory is an I2C Bus Controller Driver Based on the sunxi platform. It is responsible for implementing the corresponding read/write methods for the three I2C buses in the system, but the controller driver itself does not communicate, but waits for the device driver to call its function. Figure 5 shows the I2C driver hierarchy based on the SUNXI platform. The figure shows three I2C adapters, which correspond to the source code structure of the three I2C controllers on the SUNXI platform.
                  The drivers/i2c/directory contains several important files and directories as follows: 1. file i2c-core.c: implementation of core functions of I2C subsystem; 2. file i2c-dev.c: Universal Slave Device Driver implementation; 3. directory busses: Contains I2C bus controller drivers based on different platforms; 4. directory algos: Implements algorithm for some I2C bus controllers.
                  Iv. Development of I2C Device Drivers
                  • General I2C device driver structure
                    A specific I2C device driver must implement two interfaces. On the one hand, it is an interface for the I2C core layer, which is used to hook the I2C adapter to implement access to the I2C bus and I2C devices, this includes the implementation of probe, remove, detect and other interface functions; on the other hand, it is the interface for the user's application layer to provide the interface for the user program to access the I2C device, including the implementation of open, release, read, write and the most important interface functions for standard file operations such as ioctl. The interface functions of I2C core layer are described as follows:
                    Probe: callback function for device binding by I2C driver. Remove: callback function used by the I2C driver to unbind the device. Detect: callback function for I2C device detection. It identifies the supported devices (return 0 indicates support; otherwise, return-ENODEV). In addition, you need to define a list of addresses for detection (address_list) and a device type (class), so that those i2c bus that only match the device type are detected. For example, if the drive of an auto-monitor hardware core is set to I2C_CLASS_HWMON, only controllers whose class domain is I2C_CLASS_HWMON can be tested by the driver.
                    • Common Data Structure Analysis
                      I2c_adapter
                      Struct i2c_adapter {
                      Struct module * owner;/* module */unsigned int id;/* type of algorithm, defined in i2c-id.h, starting with I2C_ALGO _ */unsigned int class; const struct i2c_algorithm * algo;/* bus communication method struct pointer */void * algo_data;/* algorithm data */struct rt_mutex bus_lock; int timeout;/* timeout time, in jiffies */int retries;/* Number of retries */struct device dev;/* Controller device */int nr; char name [48]; /* controller name */struct completion dev_released;/* used to synchronize */struct mutex userspace_clients_lock; struct list_head userspace_clients;
                      };
                      The i2c_adapter corresponds to a physical controller. An I2C Controller requires the communication functions provided in i2c_algorithm to control the generation of specific access periods on the controller.

                      I2c_algorithm
                      Struct i2c_algorithm {
                      /* I2C transmission function pointer */int (* master_xfer) (struct i2c_adapter * adap, struct i2c_msg * msgs, int num ); /* smbus transmission function pointer */int (* smbus_xfer) (struct i2c_adapter * adap, 2010addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data);/* return the functions supported by the Controller */u32 (* functionality) (struct i2c_adapter *);
                      }; The key function master_xfer () in i2c_algorithm is used to generate signals required for I2C access cycles, in i2c_msg (I2C message.

                      I2c_msg
                      Struct i2c_msg {
                      _ 16addr;/* slave device address */_ 16flags;/* Message Type */_ 16len;/* message length */_ u8 * buf; /* message data */
                      };
                      I2c_msg is the basic unit for I2C transmission. It contains the specific address of the slave device, the message type, and the specific data information to be transmitted. Before each I2C message is transmitted, a start bit is generated, which is sent immediately from the device address, and then the data is sent or received. A stop bit is also required for the last message.
                      I2c_client
                      Struct i2c_client {
                      Unsigned short flags;/* flag */unsigned short addr;/* low 7-bit chip address */char name [I2C_NAME_SIZE];/* device name */struct i2c_adapter * adapter; /* The attached i2c_adapter */struct i2c_driver * driver;/* The attached i2c_driver */struct device dev; int irq;/* the interrupt number used by the device */struct list_head detected;
                      };
                      The i2c_client corresponds to a real physical device. Each I2C device must be described by an i2c_client.
                      I2c_driver
                      Struct i2c_driver {
                      Unsigned int class; int (* attach_adapter) (struct i2c_adapter *);/* attach i2c_adapter function pointer */int (* detach_adapter) (struct i2c_adapter *); /* remove the i2c_adapter function pointer */int (* probe) (struct i2c_client *, const struct i2c_device_id *); int (* remove) (struct i2c_client *); void (* shutdown) (struct i2c_client *); int (* suspend) (struct i2c_client *, pm_message_t mesg); int (* resume) (struct i2c_client *); void (* alert) (struct i2c_client *, unsigned int data); int (* command) (struct i2c_client * client, unsigned int cmd, void * arg); struct device_driver driver; const struct i2c_device_id * id_table; /* List of device IDs supported by the driver */int (* detect) (struct i2c_client *, struct i2c_board_info *);/* Device Detection Function */const unsigned short * address_list; /* The device address supported by the driver */struct list_head clients;/* the device that is mounted to the detected device */
                      };
                      I2c_driver corresponds to a set of driver methods. Its main member functions include probe (), remove (), suspend (), and resume, in addition, id_table is the ID table of the I2C device supported by the driver. The relationship between i2c_driver and i2c_client is one-to-multiple. One i2c_driver can support multiple i2c_clients of the same type.

Related Article

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.