I2C driver write guide 1: Update I2C drivers to 2.6 New Driver Model

Source: Internet
Author: User

Original article: Documentation/I2C/upgrading-clients
Translator: Guo shaobei
2010/05/10

Update I2C drivers to the new 2.6 Driver Model
========================================================== ==========

Note: the I2C driver here refers to the I2C client driver, for example, RTC, USB
Transceiver driver and so on.

Ben dooks <ben-linux@fluff.org>

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

This document describes how to upgrade the I2C client driver that already exists in Linux 2.6 From the old model to the new
.

Example of the old model driver
------------------------

Struct example_state {
Struct i2c_client client;
....
};

Static struct i2c_driver example_driver;

Static unsigned short ignore [] = {i2c_client_end };
Static unsigned short normal_addr [] = {our_addr, i2c_client_end };

I2c_client_insmod;

Static int example_attach (struct i2c_adapter * ADAP, int ADDR, int kind)
{
Struct example_state * State;
Struct device * Dev = & ADAP-> dev;/* to use for Dev _ reports */
Int ret;

State = kzarloc (sizeof (struct example_state), gfp_kernel );
If (State = NULL ){
Dev_err (Dev, "failed to create our State/N ");
Return-enomem;
}

Example-> client. ADDR = ADDR;
Example-> client. Flags = 0;
Example-> client. Adapter = ADAP;

I2c_set_clientdata (& State-> i2c_client, State );
Strlcpy (client-> i2c_client.name, "example", i2c_name_size );

Ret = i2c_attach_client (& State-> i2c_client );
If (Ret <0 ){
Dev_err (Dev, "failed to attach client/N ");
Kfree (State );
Return ret;
}

Dev = & State-> i2c_client.dev;

/* Rest of the initialisation goes here .*/

Dev_info (Dev, "example client created/N ");

Return 0;
}

Static int _ devexit example_detach (struct i2c_client * client)
{
Struct example_state * State = i2c_get_clientdata (client );

I2c_detach_client (client );
Kfree (State );
Return 0;
}

Static int example_attach_adapter (struct i2c_adapter * ADAP)
{
Return i2c_probe (ADAP, & addr_data, example_attach );
}

Static struct i2c_driver example_driver = {
. Driver = {
. Owner = this_module,
. Name = "example ",
},
. Attach_adapter = example_attach_adapter,
. Detach_client = _ devexit_p (example_detach ),
. Suspend = example_suspend,
. Resume = example_resume,
};

Update Client
-------------------

The new binding model checks the devices supported by its maintained linked list and the addresses of matched devices registered through code.
. This means that the. attach_adapter and. detach_adapter methods and addr_data methods in the driver are not deleted.
Use again, as shown below:

-Static struct i2c_driver example_driver;

-Static unsigned short ignore [] = {i2c_client_end };
-Static unsigned short normal_addr [] = {our_addr, i2c_client_end };

-I2c_client_insmod;

-Static int example_attach_adapter (struct i2c_adapter * ADAP)
-{
-Return i2c_probe (ADAP, & addr_data, example_attach );
-}

Static struct i2c_driver example_driver = {
-. Attach_adapter = example_attach_adapter,
-. Detach_client = _ devexit_p (example_detach ),
}

Add the probe and remove methods in i2c_driver as follows:

Static struct i2c_driver example_driver = {
+. Probe = example_probe,
+. Remove = _ devexit_p (example_remove ),
}

Modify the example_attach method: method name, and accept the new parameter (i2c_client) as follows:

-Static int example_attach (struct i2c_adapter * ADAP, int ADDR, int kind)
+ Static int example_probe (struct i2c_client * client,
+ Const struct i2c_device_id * ID)

Modify example_attach to example_probe. The probe function must be modified because the i2c_client has been
Create and use.

The following client fields has been created before the probe function is called, so the following client creates the code
Can be deleted:

-Example-> client. ADDR = ADDR;
-Example-> client. Flags = 0;
-Example-> client. Adapter = ADAP;
-
-Strlcpy (client-> i2c_client.name, "example", i2c_name_size );

I2c_set_clientdata is now:

-I2c_set_clientdata (& State-> client, State );
+ I2c_set_clientdata (client, State );

The call to i2c_attach_client () is no longer needed. If the probe function returns successfully, the driver will be automatically matched by the i2c-core
Configuration. The probe function is modified as follows:

-Ret = i2c_attach_client (& State-> i2c_client );
-If (Ret <0 ){
-Dev_err (Dev, "failed to attach client/N ");
-Kfree (State );
-Return ret;
-}

Delete the storage of the struct i2c_client domain from struct example_state.
I2c_client access parameters. When needed, we only need to store a pointer to i2c_client.

Struct example_state {
-Struct i2c_client client;
+ Struct i2c_client * client;

The new I2C client is as follows:

-Struct device * Dev = & ADAP-> dev;/* to use for Dev _ reports */
+ Struct device * Dev = & i2c_client-> dev;/* to use for Dev _ reports */

After the client is changed to attach, the driver no longer needs to register a new client data structure to the core
. As follows:

-Dev = & State-> i2c_client.dev;

In the probe function, make sure that the pointer to the client is saved in the new State:

Static int example_probe (struct i2c_client * i2c_client,
Const struct i2c_device_id * ID)
{
Struct example_state * State;
Struct device * Dev = & i2c_client-> dev;
Int ret;

State = kzarloc (sizeof (struct example_state), gfp_kernel );
If (State = NULL ){
Dev_err (Dev, "failed to create our State/N ");
Return-enomem;
}

+ State-> client = i2c_client;

Update the detach method, change example_detach to example_remove, and delete the i2c_detach_client ()
. You can also delete the returned variable because it is no longer required by the i2c-core function.

-Static int _ devexit example_detach (struct i2c_client * client)
+ Static int _ devexit example_remove (struct i2c_client * client)
{
Struct example_state * State = i2c_get_clientdata (client );

-I2c_detach_client (client );

Finally make sure we have a correct ID table for i2c-core and other utilities:

+ Struct i2c_device_id example_idtable [] = {
+ {"Example", 0 },
+ {}
+ };
+
+ Module_device_table (I2C, example_idtable );

Static struct i2c_driver example_driver = {
. Driver = {
. Owner = this_module,
. Name = "example ",
},
+. Id_table = example_ids,

Our driver now looks like this:

Struct example_state {
Struct i2c_client * client;
....
};

Static int example_probe (struct i2c_client * client,
Const struct i2c_device_id * ID)
{
Struct example_state * State;
Struct device * Dev = & client-> dev;

State = kzarloc (sizeof (struct example_state), gfp_kernel );
If (State = NULL ){
Dev_err (Dev, "failed to create our State/N ");
Return-enomem;
}

State-> client = client;
I2c_set_clientdata (client, State );

/* Rest of the initialisation goes here .*/

Dev_info (Dev, "example client created/N ");

Return 0;
}

Static int _ devexit example_remove (struct i2c_client * client)
{
Struct example_state * State = i2c_get_clientdata (client );

Kfree (State );
Return 0;
}

Static struct i2c_device_id example_idtable [] = {
{"Example", 0 },
{}
};

Module_device_table (I2C, example_idtable );

Static struct i2c_driver example_driver = {
. Driver = {
. Owner = this_module,
. Name = "example ",
},
. Id_table = example_idtable,
. Probe = example_probe,
. Remove = _ devexit_p (example_remove ),
. Suspend = example_suspend,
. Resume = example_resume,
};

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.