What to do in the I2C device driver

Source: Internet
Author: User

Reproduced in front of a lot of articles on I2C, to finish a project, but also to write their own points I2C experience, I this is a pure application angle, want to see the principle, to see reprinted articles, people write a lot better.

For a I2C device, the device file is the simplest and most complex, saying it's simple because it's very easy to provide code under Linux, but there are a lot of vendors that don't provide or do not provide Linux code, which is complicated. Then this I now do not say, the following said a few I2C equipment (take ISA1200 as an example) after discovering that no matter how the device files are always to do some things themselves, this is probably the so-called transplant bar.

Of course, this work is done in the board file. Take mach-s5pv210.c for example:

First of all, with the board of their own I2C implementation drive loading:

First, create ISA1200 information in the board file:

static int isa1200_power (int on)

{

if (ON) {

Gpio_direction_output (S5PV210_GPJ3 (1), 1);

Gpio_direction_output (s5pv210_gpj3 (0), 1);

}else{

Gpio_direction_output (S5PV210_GPJ3 (1), 0);

Gpio_direction_output (s5pv210_gpj3 (0), 0);

}

return 0;

}

static struct Isa1200_platform_data Isa1200_1_pdata = {

. Name = "Isa1200",

. power_on = Isa1200_power,

. pwm_ch_id = 1,

. Hap_en_gpio = S5pv210_gph3 (1),

. Max_timeout = 60000,

};

static void Isa1200_init (void)

{

Gpio_direction_output (S5PV210_GPJ3 (7), 1);

Gpio_direction_output (S5PV210_GPJ3 (1), 1);

Gpio_direction_output (s5pv210_gpj3 (0), 1);

/*i2c_register_board_info (3, Isa1200_board_info,

Array_size (Isa1200_board_info));

Return

}

and I2c_board_info structure:

{

I2c_board_info ("Isa1200_1", 0x90>>1),/* This is the I2C device's address from the machine * *

. Platform_data = &isa1200_1_pdata,

},

Then find one of the following three I2C buses such as i2c_devs1[]

* I2C0 * *

static struct I2c_board_info i2c_devs0[] __initdata = {

{

I2c_board_info ("act8937", 0x5b),

. Platform_data = &act8937_platform_data,

},

{

I2c_board_info ("wm8580", 0x1b),

},

};

* I2C1 * *

static struct I2c_board_info i2c_devs1[] __initdata = {

#ifdef CONFIG_VIDEO_TV20

{

I2c_board_info ("S5P_DDC", (0x74>>1)),

},

#endif

};

* I2C2 * *

static struct I2c_board_info i2c_devs2[] __initdata = {

#ifdef config_regulator_max8698

{

/* The address is 0xCC used since Srad = 0 * *

I2c_board_info ("max8698", (0xCC >> 1)),

. Platform_data = &max8698_platform_data,

},

#endif

Fill in the I2c_board_info

* I2C1 * *

static struct I2c_board_info i2c_devs1[] __initdata = {

#ifdef CONFIG_VIDEO_TV20

{

I2c_board_info ("S5P_DDC", (0x74>>1)),

},

{

I2c_board_info ("Isa1200_1", 0x90>>1),/* This is the I2C device's address from the machine * *

. Platform_data = &isa1200_1_pdata,

},

#endif

};

This is to put the ISA1200 on the i2c1, the things they do is completed. The next thing is the bus itself:

First it adds itself to the Platform_device, which is registered on the Platform_device bus:

static struct Platform_device *smdkv210_devices[] __initdata = {

......

&S3C_DEVICE_I2C1,

......

}

Adding the I2C1 bus to the device initialization i2c_register_board_info Let it add the i2c_devs1[list to the devices on the bus i2c1 (that is, all devices registered to I2c_board_info i2c1).

static void __init smdkv210_machine_init (void)

{

......

I2c_register_board_info (1, I2C_DEVS1, Array_size (I2C_DEVS1));

......

}

Let's talk about the Gpio analog I2C implementation driver loading:

The most important here is of course the successful registration of a i2c_gpio_w380:

The first is to find the CLK and SDA corresponding to the GPIO port:

CLK:GPA1[3]

SDA:GPA1[2]

Then build the I2C-GPIO platform_device structure:

static struct I2c_gpio_platform_data I2c_gpio_w380_data = {

. Scl_pin = S5PV210_GPA1 (3),

. Sda_pin = S5PV210_GPA1 (2),

};

static struct Platform_device i2c_gpio_w380= {

. Name = "I2c-gpio", * This name should be consistent with the name in I2c-gpio.c Platform_driver, in other words, the I2C to be used for this GPIO driver is defined in I2c-gpio.

. id = 3,/* This number to the system's original 0,1,2 write down, and then one to use 4, according to this recursive * *

. Dev = {

. Platform_data = &i2c_gpio_w380_data,

},

};

This completes the work of registering two gpio ports as a I2C bus.

The next step is to implement the driver loading method with the I2C of the board itself:

The first is to create ISA1200 information in the board file:

static int isa1200_power (int on)

{

if (ON) {

Gpio_direction_output (S5PV210_GPJ3 (1), 1);

Gpio_direction_output (s5pv210_gpj3 (0), 1);

}else{

Gpio_direction_output (S5PV210_GPJ3 (1), 0);

Gpio_direction_output (s5pv210_gpj3 (0), 0);

}

return 0;

}

static struct Isa1200_platform_data Isa1200_1_pdata = {

. Name = "Isa1200",

. power_on = Isa1200_power,

. pwm_ch_id = 1,

. Hap_en_gpio = S5pv210_gph3 (1),

. Max_timeout = 60000,

};

static void Isa1200_init (void)

{

Gpio_direction_output (S5PV210_GPJ3 (1), 1);

Gpio_direction_output (s5pv210_gpj3 (0), 1);

/*i2c_register_board_info (3, Isa1200_board_info,

Array_size (Isa1200_board_info));

Return

}

and I2c_board_info structure:

{

I2c_board_info ("Isa1200_1", 0x90>>1),/* This is the I2C device's address from the machine * *

. Platform_data = &isa1200_1_pdata,

},

Then add a isa1200 i2c_board_info[to the i2c_gpio_w380 bus]

/* i2c-gpio*/

static struct I2c_board_info i2c_devs3[] __initdata= {

{

I2c_board_info ("Isa1200_1", 0x90>>1),

. Platform_data = &isa1200_1_pdata,

},

};

This is to put the ISA1200 on the i2c_gpio_w380, the things they do is completed. The next thing is the bus itself:

First of all, it will add its own i2c_gpio_w380 to the Platform_device, that is, register to the Platform_device bus:

static struct Platform_device *smdkv210_devices[] __initdata = {

......

&i2c_gpio_w380,

......

}

Then add the i2c_gpio_w380 bus to the device initialization i2c_register_board_info Let it put the bus i2c_gpio_w380 on the device (that is, register to I2c_board_info i2c_devs3[] Adds a list of i2c_gpio_w380 to all devices on the

static void __init smdkv210_machine_init (void)

{

......

I2c_register_board_info (3, I2C_DEVS3, Array_size (I2C_DEVS3));

......

}

The above is the end of a device ISA1200 hook on the Gpio analog I2C bus i2c_gpio_w380. Here the device ISA1200 device file isa1200.c can be called I2C i2c_smbus_write_byte_data,i2c_smbus_read_byte_data functions.

If you want to make two gpio mouth again into the I2C bus register into a i2c_gpio_w380_1:

The first is to find the CLK and SDA corresponding to the GPIO port:

CLK:GPC0[1]

SDA:GPC0[2],

You can do this:

static struct I2c_gpio_platform_data I2c_gpio_w380_1_data= {

. Sda_pin = s5pv210_gpc0 (2),

. Scl_pin = s5pv210_gpc0 (1),

};

static struct Platform_device i2c_gpio_w380_1= {

. Name = "I2c-gpio",///I2c-gpio driver/*

. ID = 4,/* above registered 3, postponed to the 4*/

. Dev = {

. Platform_data = &i2c_gpio_w380_1_data,

}

};

static struct I2c_board_info i2c_devs4[] __initdata= {

{

I2c_board_info ("al3000", address),

},

};

static struct Platform_device *smdkv210_devices[] __initdata = {

......

&i2c_gpio_w380_1,

......

}

static void __init smdkv210_machine_init (void)

{

......

I2c_register_board_info (4, I2C_DEVS4, Array_size (I2C_DEVS4));

......

}

another is the use of Gpio to simulate the I2C time series, which is done separately in the device file. such as:

/*****stop previous seccession and generate START seccession *********************/

void I2c_start (void)

{Set_i2c_scl_high ();

Set_i2c_sda_low ();

Set_i2c_sda_output (); SDA = 0;

Set_i2c_sda_high (); SDA = 1, Stop previous I2C r/w action

Set_i2c_sda_low (); I2C Start Condition

}

/***************** generate I2C Repeat Start **************/

void Repeatstart (void)

{Set_i2c_scl_low ();

Set_i2c_sda_high ();

Set_i2c_sda_output ();

Set_i

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.