Linux I²C Subsystem Architecture

Source: Internet
Author: User

 

Bus driver

4.1 Overview

The I²C bus driver is the software implementation of the I²C adapter, which provides the ability of the I²C adapter to complete data communication from the device, such as start, stop, response signal and master_xfer implementation function.

The I²C bus driver is described by I2c_adapter and I2c_algorithm.

Hardware description of the 4.2 S3C2440I2C controller

The s3c2440 processor incorporates an I²C controller with four registers for control:

Iiccon i²c Control Register

Iicstat i²c Status Register

Iicds I²C Transceiver Data Shift Register

Iicadd i²c Address Register

With the Iiccon,iicds,iicadd register operation, the start bit, stop bit, data and address are generated on the I²c bus, while the transmitted state is obtained through the Iicstat register.

4.3 i2c-s3c2410 bus driver analysis (platform_driver)

I²c bus driver code in DRIVERS/I2C/BUSSES/I2C-S3C2410.C, this code also supports the S3C2410,S3C6410,S5PC110 and other Samsung series of chips.

Initializing modules and unloading modules

[CPP]View Plaincopy
    1. static int __init i2c_adap_s3c_init (void)
    2. {
    3. Returnplatform_driver_register (&s3c24xx_i2c_driver);
    4. }
    5. static void __exit i2c_adap_s3c_exit (void)
    6. {
    7. Platform_driver_unregister (&s3c24xx_i2c_driver);
    8. }

Bus driver is based on platform, which conforms to the idea of device-driven model.

[CPP]View Plaincopy
  1. static struct Platform_drivers3c24xx_i2c_driver = {
  2. . Probe = S3c24xx_i2c_probe,
  3. . remove = S3c24xx_i2c_remove,
  4. . id_table = S3c24xx_driver_ids,
  5. . Driver = {
  6. . Owner = This_module,
  7. . Name = "S3C-I2C",
  8. . PM = S3c24xx_dev_pm_ops,
  9. . of_match_table= S3c24xx_i2c_match,
  10. },
  11. };

S3c24xx_i2c_probe function

When the Platform_driver_register function is called to register the platform_driver struct, if Platformdevice and platform driver match successfully, the probe function is called to initialize the adapter hardware.

[CPP]View Plaincopy
  1. static int S3c24xx_i2c_probe (structplatform_device *pdev)
  2. {
  3. ......
  4. / * Initialize Adapter information * /
  5. strlcpy (I2c->adap.name,"S3C2410-I2C", sizeof (i2c->adap.name));
  6. I2c->adap.owner = This_module;
  7. I2c->adap.algo = &s3c24xx_i2c_algorithm;
  8. I2c->adap.retries= 2;
  9. I2c->adap. class = I2c_class_hwmon |  I2C_CLASS_SPD;
  10. I2c->tx_setup = 50;
  11. /* Initialize spin lock and wait queue header */
  12. Spin_lock_init (&i2c->lock);
  13. Init_waitqueue_head (&i2c->wait);
  14. / * Map Register * /
  15. Res= Platform_get_resource (Pdev, Ioresource_mem, 0);
  16. I2c->ioarea= request_mem_region (Res->start, Resource_size (res),
  17. Pdev->name);
  18. I2c->regs= Ioremap (Res->start, Resource_size (res));
  19. / * Set the information required for the I²C core * /
  20. I2c->adap.algo_data= I²c;
  21. I2c->adap.dev.parent= &pdev->dev;
  22. / * Initialize the I²C controller * /
  23. ret= S3c24xx_i2c_init (I²C);
  24. / * Request interrupted * /
  25. i2c->irq= ret = PLATFORM_GET_IRQ (pdev, 0);
  26. Ret= Request_irq (I2C->IRQ, S3C24XX_I2C_IRQ, 0,
  27. Dev_name (&pdev->dev), i²c);
  28. / * Register the I²C adapter * /
  29. ret= I2c_add_numbered_adapter (&I2C->ADAP);
  30. ......
  31. }

Probe main work is when the hardware and request the I²C adapter to use the IO address, interrupt number, etc., and then add this adapter to the I²c core. I2c_adapter Registration Process I2c_add_numbered_adapter->i2c_register_adapter

I²c Bus Communication method

[CPP]View Plaincopy
    1. static const struct i2c_algorithms3c24xx_i2c_algorithm = {
    2. . Master_xfer = S3c24xx_i2c_xfer,
    3. . functionality = S3c24xx_i2c_func,
    4. };

S3c24xx_i2c_xfer function is the realization of bus communication mode, which relies on two functions of S3c24xx_i2c_doxfer and S3c24xx_i2c_message_start;

[CPP]View Plaincopy
  1. static int S3c24xx_i2c_doxfer (STRUCTS3C24XX_I2C *i2c,
  2. struct i2c_msg *msgs, int num)
  3. {
  4. RET =s3c24xx_i2c_set_master (I²C);
  5. I2c->msg = msgs;
  6. i2c->msg_num= num;
  7. I2c->msg_ptr= 0;
  8. i2c->msg_idx= 0;
  9. I2c->state = State_start;
  10. S3c24xx_i2c_message_start (I2C,MSGS);
  11. }

First set the S3C i²c device as the primary device, and then call the S3c24xx_i2c_message_start function to start the I²C message transfer.

The S3c24xx_i2c_func function returns the communication capabilities supported by the adapter.

4.4 Device Resources for adapters (Platform_device)

S3C2440 's I²c bus driver is based on the platform to achieve, we analyzed the Platformdriver section, and then look at the platform device part.

The resource information for the Platform_device struct and the I²C controller is defined in the arch/arm/plat-samsung/dev-i2c0.c file:

[CPP]View Plaincopy
  1. Static struct resource s3c_i2c_resource[] ={
  2. [0]= {
  3. . start= S3C_PA_IIC,
  4. . end = S3c_pa_iic + Sz_4k-1,
  5. . flags= Ioresource_mem,
  6. },
  7. [1]= {
  8. . start= IRQ_IIC,
  9. . end = IRQ_IIC,
  10. . flags= Ioresource_irq,
  11. },
  12. };
  13. struct Platform_device s3c_device_i2c0 = {
  14. . Name = "S3C2410-I2C",/ * Device name * /
  15. #ifdef CONFIG_S3C_DEV_I2C1
  16. . id = 0,
  17. #else
  18. . id =-1,
  19. #endif
  20. . Num_resources =array_size (S3c_i2c_resource),
  21. . Resource =s3c_i2c_resource,
  22. };
  23. struct S3c2410_platform_i2cdefault_i2c_data __initdata = {
  24. . Flags = 0,
  25. . slave_addr = 0x10,/ */i²c Adapter Address * /
  26. . frequency = 100*1000,/ * Bus frequency * /
  27. . Sda_delay = +,/ * SDA Edge delay Time NS * /
  28. };
  29. void __init S3c_i2c0_set_platdata (structs3c2410_platform_i2c *pd)
  30. {
  31. STRUCTS3C2410_PLATFORM_I2C *NPD;
  32. if (!PD)
  33. Pd= &default_i2c_data;
  34. Npd= S3c_set_platdata (PD, sizeof (struct S3C2410_PLATFORM_I2C),
  35. &S3C_DEVICE_I2C0);
  36. if (!npd->cfg_gpio)
  37. Npd->cfg_gpio= S3c_i2c0_cfg_gpio;
  38. }

Register the Platform_device into the kernel in the board file:

[CPP]View Plaincopy
    1. Static struct platform_device*mini2440_devices[] __initdata = {
    2. ......
    3. &S3C_DEVICE_I2C0,
    4. ......
    5. };

Call the S3c_i2c0_set_platdata function to assign the adapter specific data to Dev.platform_data:

[CPP]View Plaincopy
    1. static void __init mini2440_init (void)
    2. {
    3. ......
    4. S3c_i2c0_set_platdata (NULL);
    5. }

The I²c bus driver is analyzed here.

Linux I²C Subsystem Architecture

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.