Linux I2C driver notes

Source: Internet
Author: User

1. i2c-dev Interface

 

I2C Dev-Interface

Generally, I2C devices are controlled by a kernel driver. However, in the user space, you can also access an I2C device: you need

Load the i2c-dev module.

Each registered I2C adapter (Controller) obtains a font size starting from 0. You can check

/Sys/class/i2c-dev to see which number the adapter corresponds. You can also run the "i2cdetect-L" command to obtain

Lists All I2C adapters of your current system. I2cdetct is a tool in the i2c-tool package.

The I2C device file is a character device, the master device number is 89, and the sub-device number is allocated as described above. The device file name is usually

Specified as "I2C-% d" (i2c-0, i2c-1,..., i2c-10,...) I2C device file is character device, master device number is

89. The sub-device number is allocated as described above. The device file name is typically set to "I2C-% d" (i2c-0, i2c-1,

..., I2c-10,...). All 256 device numbers are reserved for I2C.

C example

==========

Suppose you want to access the I2C adapter in your C application. The first thing is to include the header file "# include

<Linux/i2c-dev.h> ". Note that there are two "i2c-dev.h" files: one belongs to the Linux kernel

In the kernel driver; one is published by the i2c-tools for use in user programs. Obviously, we need to use the second

A i2c-dev.h file.

Now, you need to determine which adapter to access. You Need To view/sys/class/i2c-dev/or run

"I2cdetect-L" OK. The adapter number is often dynamically allocated. You cannot preassume a value. Because they are

It will change to a different value after the system is restarted.

Next, open the device file as follows:

Int file;

Int adapter_nr = 2;/* probably dynamically determined */

Char filename [20];

Snprintf (filename, 19, "/dev/I2C-% d", adapter_nr );

File = open (filename, o_rdwr );

If (File <0 ){

/* Error handling; you can check errno to see what went wrong */

Exit (1 );

}

After you open the device, you must specify the device address to which you want to communicate:

Int ADDR = 0x40;

If (IOCTL (file, i2c_slave, ADDR) <0 ){

/* Error handling; you can check errno to see what went wrong */

Exit (1 );

}

Well, you are now ready to communicate with I2C devices. You can now use the SMBus command set or the I2C format is not available

(Plain I2C) communicates with your device. If the device supports the SMB protocol, select the SMBus command set first.

The Code is as follows:

_ U8 register = 0x10;/* Device register to access */

_ S32 res;

Char Buf [10];

/* Using SMBus commands */

Res = i2c_smbus_read_word_data (file, register );

If (RES <0 ){

/* Error handling; you can check errno to see what went wrong */

} Else {

/* Res contains the read word */

}

/* Using I2C write, equivalent

I2c_smbus_write_word_data (file, register, 0x6543 )*/

Buf [0] = reister;

Buf [1] = 0x43;

Buf [2] = 0x65;

If (write (file, Buf, 3 )! = 3 ){

/* Error handling: I2C Transaction Failed */

}

/* Using I2C read, equivalent of i2c_smbus_read_byte (File )*/

If (read (file, Buf, 1 )! = 1 ){

/* Error handling: I2C Transaction Failed */

} Else {

/* Buf [0] contains the read byte */

}

Note that only a subset of I2C and SMBus protocols can be called through read () and write. You

The mixing read and write messages in the same transaction

Supported by read ()/write. For this reason, the read () and write () interfaces are almost invisible to the user space.

Program usage.

Important: because of the use of inline functions, you * have * to use '-o "or

Some variation when you compile your program!

Full Interface Description

======================================

IOCTLs is defined as follows:

IOCTL (file, i2c_slave, long ADDR)

Change slave address. The address is passed in the 7 lower bits of

Argument (Response t for 10 bit addresses, passed in the 10 lower bits in this

Case)

IOCTL (file, i2c_tenbit, long SELECT)

Selects ten BIT addressed if select not equals 0, selects normal 7 bit

Addresses if select equals 0. Default 0. This request is only valid if

Adapter has i2c_func_10bit_addr.

IOCTL (file, i2c_pec, long SELECT)

Selects SMBus PEC (packet error checking) Generation and verification if

Select not equals 0, disables if select equals 0. Default 0.

Used only for SMBus transactions. This request only has an effect if

Adapter has i2c_func_smbus_pec; it is still safe if not, it just doesn't have

Any effect.

IOCTL (file, i2c_funcs, unsigned long * funcs)

Gets the adapter functionality and puts it in * funcs.

IOCTL (file, i2c_rdwr, struct i2c_rdwr_ioctl_data * msgset)

Do combined read/write transaction without stop in between. Only valid if

Adatpter has i2c_func_i2c. The argument is a pointer to

Struct i2c_rdwr_ioctl_data {

Struct i2c_msg * msgs;/* PTR to array of simple messages */

Int nmsgs;/* Number of messages to exchanges */

}

Msgs [] contains a pointer to data buffer. This function is called Based on the i2c_m_rd flag in each message

Write or read data to the buffer. In each message, slave address and whether to use

Ten-bit-address must be set.

IOCTL (file, i2c_smbus, struct i2c_smbus_ioctl_data * ARGs)

Not meant to be called directly; instead, use the access functions below.

You can use the read (2) and write (2) calls to perform format-free I2C transmission. Use IOCTL before accessing the device

I2c_slave to set the address.

You can use SMBus-level transmission (see documentation file SMBus-protocol for details)

Function call:

_ S32 i2c_smbus_write_quick (INT file, _ u8 value );

_ S32 i2c_smbus_read_byte (INT file );

_ S32 i2c_smbus_write_byte (INT file, _ u8 value );

_ S32 i2c_smbus_read_byte_data (INT file, _ u8 command );

_ S32 i2c_smbus_write_byte_data (INT file, _ u8 command, _ u8 value );

_ S32 i2c_smbus_read_word_data (INT file, _ u8 command );

_ S32 i2c_smbus_write_word_data (INT file, _ u8 command, _ b2value );

_ S32 i2c_smbus_process_call (INT file, _ u8 Comand, _ b2value );

_ S32 i2c_smbus_read_block_data (INT file, _ u8 command, _ u8 * values );

_ S32 i2c_smbus_write_block_data (INT file, _ u8 command, _ u8 length,

_ U8 * values );

-1 is returned when all the above transfer fails; you can read errno to check the specific error information. 'Write' after transmission is successful

0; 'read' is returned after transmission is successful. Except read_block, the number of bytes read is returned,

The block buffer length cannot exceed 32 bytes.

The above functions are all inline functions, that resolve to callto

I2c_smbus_access function, that on its turn calla specific IOCTL with

Data in a specific format. Read the source code if you want to know what

Happenss behind the screens.

Implementation Details

======================================

The following is the internal processing of the kernel when you use the I2C/dev interface:

1 * your program opens/dev/i2c-N and calls IOCTL ()

2 * open () and IOCTL () calls will be handled by the i2c-dev kernel driver: refer to the related functions of the i2c-dev.c

(I2cdev_ioctl (), i2cdev_open ()...). You can think of i2c-dev as a universal access by user programs

I2C chip driver.

3 * Some IOCTL commands are for management tasks and can be directly processed by the i2c-dev. For example, i2c_slave (set you

Device address to be accessed) and i2c_pec (enable or disable SMBus error check ).

4 * Other IOCTL commands are converted into function calls in the kernel driver by the i2c-dev. For example, i2c_funcs

Use I2C. h: 2c_get_functionality () to request functions supported by the I2C adapter (functionality );

I2c_smbus, which performs SMBus transmission by calling i2c-core.c: i2c_smbus_xfer.

I2c-dev driver is responsible for checking the validity of parameters from the user space. In addition, the user program accesses

There is no difference between I2C and function calls for Kernel access to I2C. This means that no support is required in the I2C bus driver.

Code accessed by the user.

The functions in i2c-core.c/I2C-. h are the encapsulation call routines that your actual I2C bus driver needs to implement. Each

The adapter must declare some callback functions to implement these standard calls.

I2C. h: i2c_get_functionality () call i2c_adapter.algo-> functionality (),

I2c-core.c: i2c_smbus_xfer () call i2c_adapter.algo-> smbus_xfer () (if

Smbus_xfer () callback function), otherwise

I2c-core.c: i2c_smbus_xfer_emulated () will call i2c_adapter.algo-> master_xfer ().

(Note: The smbus_xfer () and master_xfer () callback functions must at least implement one)

After your I2C bus driver has processed these request, execution runs up

Call chain, with almost no processing done, using t by i2c-dev to package

Returned data, if any, in suitable format for the ioctl.

 

 

 



2. I2C functionality

 

Introduction
------------

Not all I2C or SMBus adapters implement all functions in the I2C specification, so when accessing the I2C adapter,
It is not entirely assumed that the adapter provides the functions you need. The client needs to check whether the adapter provides
Required functions.

Functionalilty Constants
-----------------------

For a list of constantly updated I2C adapter function constants, see <Linux/I2C. h>

I2c_func_i2c unformatted i2c-level commands (pure SMBus adapter cannot use these
Command)
I2c_func_10bit_addr handles 10-bit address extensions
I2c_func_protocol_mangling is familiar with i2c_m_ignore_nak, i2c_m_rev_dir_addr,
I2c_m_nostart, i2c_mno_rd_ack and other flags (which modify the I2C Protocol)
I2c_func_smbus_quick process the SMBus write_quick command
I2c_func_smbus_read_byte
I2c_func_smbus_write_byte command for processing SMBus write_byte
I2c_func_smbus_read_byte_data command for processing SMBus read_byte_data
I2c_func_smbus_write_byte_data command for processing SMBus write_byte_data
I2c_func_smbus_read_word_data command for processing SMBus read_word_data
I2c_func_smbus_write_word_data command for processing SMBus write_word_data
I2c_func_smbus_proc_call process the SMBus process_call command
I2c_func_smbus_read_block_data command for processing SMBus read_block_data
I2c_func_smbus_wirte_block_data command for processing SMBus wrtie_block_data
I2c_func_smbus_read_i2c_block process the SMBus read_i2c_block_data command
I2c_func_smbus_write_i2c_block: SMBus write_i2c_block_data command

Some flags combinations are defined as follows (for your convenience ):

I2c_func_smbus_byte command for processing SMBus read_byte & write_byte
I2c_func_smbus_byte_data processing SMBus read_byte_data & write_byte_data command
I2c_func_smbus_word_data processing SMBus read_word_data & write_word_data command
I2c_func_smbus_block_data processing SMBus read_block_data & write_block_data command
I2c_fu7nc_smbus_i2c_block process SMBus read_i2c_block_data &
Write_i2c_block_data command
I2c_func_smbus_emul processes all SMBus commands that can be simulated by I2C Adapter
(Using transparent emulation layer)

Adapter implementation
----------------------

When you write a new Adapter Driver, you must implement the callback function 'functional '. Typical implementation
As shown below.

A typical SMBus-only adapter needs to list all SMBus transactions it supports. The following
Example from i2c-piix4 DRIVER:

Static u32 piix4_func (struct i2c_adapter * adapter)
{
Return i2c_func_smbus_quick | i2c_func_smbus_byte |
I2c_func_smbus_byte_data | i2c_func_smbus_word_data |
I2c_func_smbus_block_data;
}

A typical full-I2C adapter needs to use the following functionality function (from the i2c-pxa driver ):

Srtatic u32 i2c_pxa_functionality (struct i2c_adapter * ADAP)
{
Return i2c_func_i2c | i2c_func_smbus_emul;
}

I2c_func_smbus_emul contains all SMBus transactions (including I2C Block
Transactions), The i2c-core can use i2c_func_i2c to simulate all SMBus commands. This idea is a hope
Client drivers only checks whether the I2C subsystem supports the SMBus command set, regardless of hardware or software.
Simulation.

Client checking
---------------

Before a client attempts to access the I2C adapter, or before testing whether the adapter supports a device
First, check whether the required functionality is supported. The typical practice is as follows (from im75 driver ):

Static int im75_detect (...)
{
(...)
If (! I2c_check_functionality (adapter, i2c_func_smbus_byte_data |
I2c_func_smbus_word_data ))
Goto exit;
(...)
}

The im75 driver checks whether the adapter supports SMBus byte data & SMBus word data.
Transactions. If not, the driver will no longer work on this adapter and will not continue execution. If
If the detection succeeds, the driver knows that it can call the following function:
I2c_smbus_read_byte_data (), i2c_smbus_write_byte_data (),
I2c_smbus_read_word_data (), i2c_smbus_write_word_data ().
Therefore, the functionality constant that you use i2c_check_functionality () to detect should be consistent with your
The function interfaces that the driver wants to call match.

Note that the above detection does not care whether functionalities is implemented by hardware or software simulation. Client
Drivers does not need to care about this, the i2c-core will transparently implement SMBus on the I2C Adapter Driver
Transactions.

Checking through/dev
---------------------

If you need to access the I2C adapter in the user space, you need to use/dev interface. You still need to check
Test whether the required functionality is supported. This is done through i2c_funcs IOCTL. Example:

Int file;
If (file = open ("/dev/i2c-0", o_rdwr) <0 ){
/* Some kind of error handling */
Exit (1 );
}
If (IOCTL (file, i2c_funcs, & funcs) <0 ){
/* Some kind of error handling */
Exit (1 );
}
If (! (Funcs & i2c_func_smbus_quick )){
/* Oops, the needed functionality (SMBus write_quick function) is not
Available! */
Exit (1 );
}
/* Now it is safe to use the SMBus write_quick command */

 

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.