際際滷

際際滷Share a Scribd company logo
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Inter Integrated Circuit (I2C) Drivers
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
What to Expect
¢ I2C Overview
¢ I2C Conditions & Transactions
¢ I2C Subsystem in Linux C I2C Adapter & I2C
Client
¢ I2C Client Driver
¢ I2C Device Registration (Non DT and DT)
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Overview
¢ Originally developed by Phillips
¢ Suitable for small slow devices
¢ I2C is a 2-wire protocol
C One Serial Clock Line
C One Data Line
¢ Popular in Desktops & Embedded Systems
¢ Used for accessing
C EEPROMs
C RTCs
C ADCs
C ....
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Conditions
¢ Start Condition
C Master signals this condition to initiate the transfer
on the bus
¢ Stop Condition
C Master signals this condition to stop the transfer
¢ ACK Condition
C Master or Slave signals this to acknowledge the
succesful receipt of byte
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Transactions
¢ Master begins the communication by issuing
the start condition.
¢ Sends a 7/10 bit slave address followed by
read/write bit
¢ The addressed slave ACKs the transfer
¢ Transmitter transmits a byte of data and
receiver issues ACK on successful receipt
¢ Master issues a STOP condition to conclude
the transaction
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Transactions...
Start Data 1
SLA + W
Slave
ACK
Data 2 Data N
Slave
ACK
Slave
ACK
Stop
Master Write
Slave
ACK
Start Addr. 1
SLA +
W
Slave
ACK
Repeat
Start
Data
1
Slave
ACK
SLA +
R
Stop
Master
ACK
Data
N
Master
NACK
Master Read
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Character Driver Framework
User Space
i2c_app.c,
i2c_intr.c
Char Driver (i2c_char.c)
Low Level I2
C Driver
(low_level_driver.c)
App
open(), read(),
write()
/dev/i2c_drv0
my_open() my_read() my_write()
i2c_receive() i2c_transmit()
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
AM335X I2C Initialization
¢ Get the virtual address for the I2C-0 registers base address
¢ Set up the I2C speed
C Set the pre-scalar register to generate the I2C module
internal clock from the functional clock
C Set the scl low time & scl high time registers
¢ Enable the events
C Update the `Interrupt Enable Set¨ register to enable various
events such as XRDY, RRDY and so on
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
AM335x I2C Registers
¢ I2C_SA_REGISTER (Slave Address Register)
¢ I2C_CON_REGISTER (Configuration Register)
C Bits for enabling / disabling the I2C module
C Selecting the Fast / Standard mode of operation
C Selecting the Master / Slave config
C Sending the Start / Stop conditions on the bus
¢ I2C_DATA (RX/TX Data Register)
¢ I2C_BUF (FIFO Thresholds, DMA configuration)
¢ I2C_CNT (Bytes in I2C data payload)
¢ I2C_IRQ_STATUS_REG
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
AM335X I2C APIs
¢ #include ^i2c_char.h ̄
¢ u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int
reg)
¢ void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
int reg, u16 val)
¢ u16 wait_for_event(struct omap_i2c_dev *dev)
¢ void omap_i2c_ack_stat(struct omap_i2c_dev, u16 stat)
¢ val = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG)
¢ val |= OMAP_I2C_BUF_TXFIF
¢ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, val)
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Accessing EEPROM
0XAA
0x0060
EEPROM
I2C Slave Address 0X50
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Writing to EEPROM
¢ For writing at EEPROM offset 0x0060
¢ Send the start condition
¢ Send the slave address of EEPROM (0X50), followed
by direction (Read/Write)
¢ Send the EEPROM offset higher byte, followed by
lower byte
¢ Send the actual data to be written
¢ Send the Stop condition
¢ START->0x50->0x00(offset high)->0x60 (offset low)-
>0X99(Data)->STOP
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Reading From EEPROM
¢ Write the EEPROM offset say 0x0060 (read offset)
C START->0x50->0x00(offset high)->0x60 (offset
low)->STOP
¢ Read the EEPROM data
C Send the start condition
C Send the slave address of EEPROM (0X50),
followed by direction (Read)
C Read the data
C Send the stop condition
C START->0x50->Data (RX)->Data (RX)->STOP
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Need for Linux Device Model
¢ Maximize the code re-usability across the platforms
C Same device drivers on different platforms
¢ To achieve this
C Decouple device drivers from controller drivers
C Decouple hardware description from the drivers
¢ In addition to above
C Information about how the system is put together
¢ Effective power management
C Communication with user space
C Hotpluggable devices
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Device Drivers in Linux
Application
System Call
Interface
Framework
Driver
Bus
Infrastructure
Hardware
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Device model data structures
¢ struct bus_type
C Represents the bus such as USB, PCI, I2C etc
¢ struct device_driver
C Represents the driver capable of handling certain
devices
¢ struct device
C Represents the device connected to the bus
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Linux I2C Subsystem
¢ I2C subsystem provides
C API to implement I2C controller driver
C API to implement I2C device driver in kernel space
C An abstraction to implement the client drivers
independent of adapter drivers
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Linux I2C Subsystem ...
User Space
Kernel Space
I2C Device
(i2c_client)
I2C Host
Controller
(i2c_adapter)
Hardware Space
/sys, /dev
User Applications
User Mode I2C
Device Driver
I2C Core
i2c-dev
Vertical: Character
I2C Client Driver
I2C Bus
I2C Adapter (platform_driver) / Algo Driver (i2c_algorithm)
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Subsystem Details
¢ i2c-adapter / i2c-algo
C Controller-specific I2C host controller / adapter
C Also called as the I2C bus drivers
¢ i2c-core
C Hides the adapter details from the layers above
C By providing the generic I2C APIs
¢ i2c-dev
C Provides device access in user space through /sys
C Enables implementation of User Mode Drivers
¢ i2c-client
C Driver specific to an I2C device
C Implemented using i2c-core APIs
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Client Driver
¢ Typically a character driver vertical - /dev or
/sys exposed
¢ But actually depends on the device category
¢ Registers with I2C Core (in the init function)
¢ Unregisters from I2C Core (in the cleanup
function)
¢ And uses the generic function from I2C Core for
data transfers
C int i2c_transfer(struct i2c_adapter *adap, struct
i2c_msg *msgs, int num)
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Client Driver init & cleanup
¢ Registering to the I2C Core using
C int i2c_add_driver(struct i2c_driver *)
C struct i2c_driver contains
¢ probe function C called on device detection
¢ remove function C called on device shutdown
¢ id_table C Table of device identifiers
¢ Unregistering from the I2C Core using
C void i2c_del_driver(struct i2c_driver *)
¢ Common bare-bone of init & cleanup
C Just use module_i2c_driver(struct i2c_driver)
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Client Driver Registration
¢ struct i2c_driver dummy_driver = {
driver = {
name = ^dummy_client ̄,
owner = THIS_MODULE,
},
.probe = dummy_probe,
.remove = dummy_remove,
.id_table = dummy_ids,
}
¢ static const struct i2c_device_id dummy_ids = {
{ ^dummy_device ̄, 0},
{}
}
¢
i2c_add_driver(dummy_driver)
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Adapter Driver (Un)Registeration
¢ Registering to the I2C Core using
C int i2c_add_numbered_adapter(struct i2c_adapter
*);
C Registered in the platform driver probe
¢ Unregistering from the I2C Core using
C void i2c_del_adapter(struct i2c_driver *);
C In platform driver remove functions
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
I2C Client Driver Examples
¢ Path: <kernel_source>/drivers/
C I2C EEPROM: AT24
¢ misc/eeprom/at24.c
C I2C RTC: DS1307
¢ rtc/rtc-ds1307.c
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Registering the I2C Client (Non DT)
¢ On non-DT platforms, the struct i2c_board_info
describes how device is connected to a board
¢ Defined with I2C_BOARD_INFO helper macro
C Takes as the arguments, the device name and the
slave address of the device on the bus
¢ An array of such structures is registered on per
bus basis using the i2c_register_board_info
during the platform initialization
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Registering the I2C Client (Non DT)..
¢ static struct i2c_board_info my_i2c_devices [] = {
{
I2C_BOARD_INFO (^my_device ̄, 0 x1D ),
. irq = 70,
.platform_data = &my_data
},
}
¢ i2c_register_board_info(0, my_i2c_devices,
ARRAY_SIZE (my_i2c_devices))
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Registering an I2C Client (DT)
¢ In the device tree, the I2C devices on the bus
are described as children of the I2C controller
node
¢ reg property gives the I2C slave address on the
bus
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
Registering an I2C Client (DT) ...
¢ i2c@49607899 {
compatible = "dummy_adap";
clock-frequency = <0x186a0>;
#address-cells = <0x1>;
#size-cells = <0x0>;
my_dummy@0 {
compatible = "dummy_device";
reg = <0x40>;
};
};
¢ Registered internally by i2c_core based on info from DTB
¢ i2c_new_device(struct i2c_adapter *, struct i2c_board_info *)
@ 2021-22 Embitude Trainings <info@embitude.in>
All Rights Reserved
What all did we learn?
¢ I2C Overview
¢ I2C Conditions & Transactions
¢ I2C Subsystem in Linux C I2C Adapter & I2C
Client
¢ I2C Client Driver
¢ I2C Device Registration (Non DT and DT)

More Related Content

I2c drivers

  • 1. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Inter Integrated Circuit (I2C) Drivers
  • 2. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved What to Expect ¢ I2C Overview ¢ I2C Conditions & Transactions ¢ I2C Subsystem in Linux C I2C Adapter & I2C Client ¢ I2C Client Driver ¢ I2C Device Registration (Non DT and DT)
  • 3. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Overview ¢ Originally developed by Phillips ¢ Suitable for small slow devices ¢ I2C is a 2-wire protocol C One Serial Clock Line C One Data Line ¢ Popular in Desktops & Embedded Systems ¢ Used for accessing C EEPROMs C RTCs C ADCs C ....
  • 4. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Conditions ¢ Start Condition C Master signals this condition to initiate the transfer on the bus ¢ Stop Condition C Master signals this condition to stop the transfer ¢ ACK Condition C Master or Slave signals this to acknowledge the succesful receipt of byte
  • 5. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Transactions ¢ Master begins the communication by issuing the start condition. ¢ Sends a 7/10 bit slave address followed by read/write bit ¢ The addressed slave ACKs the transfer ¢ Transmitter transmits a byte of data and receiver issues ACK on successful receipt ¢ Master issues a STOP condition to conclude the transaction
  • 6. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Transactions... Start Data 1 SLA + W Slave ACK Data 2 Data N Slave ACK Slave ACK Stop Master Write Slave ACK Start Addr. 1 SLA + W Slave ACK Repeat Start Data 1 Slave ACK SLA + R Stop Master ACK Data N Master NACK Master Read
  • 7. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Character Driver Framework User Space i2c_app.c, i2c_intr.c Char Driver (i2c_char.c) Low Level I2 C Driver (low_level_driver.c) App open(), read(), write() /dev/i2c_drv0 my_open() my_read() my_write() i2c_receive() i2c_transmit()
  • 8. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved AM335X I2C Initialization ¢ Get the virtual address for the I2C-0 registers base address ¢ Set up the I2C speed C Set the pre-scalar register to generate the I2C module internal clock from the functional clock C Set the scl low time & scl high time registers ¢ Enable the events C Update the `Interrupt Enable Set¨ register to enable various events such as XRDY, RRDY and so on
  • 9. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved AM335x I2C Registers ¢ I2C_SA_REGISTER (Slave Address Register) ¢ I2C_CON_REGISTER (Configuration Register) C Bits for enabling / disabling the I2C module C Selecting the Fast / Standard mode of operation C Selecting the Master / Slave config C Sending the Start / Stop conditions on the bus ¢ I2C_DATA (RX/TX Data Register) ¢ I2C_BUF (FIFO Thresholds, DMA configuration) ¢ I2C_CNT (Bytes in I2C data payload) ¢ I2C_IRQ_STATUS_REG
  • 10. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved AM335X I2C APIs ¢ #include ^i2c_char.h ̄ ¢ u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) ¢ void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev, int reg, u16 val) ¢ u16 wait_for_event(struct omap_i2c_dev *dev) ¢ void omap_i2c_ack_stat(struct omap_i2c_dev, u16 stat) ¢ val = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG) ¢ val |= OMAP_I2C_BUF_TXFIF ¢ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, val)
  • 11. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Accessing EEPROM 0XAA 0x0060 EEPROM I2C Slave Address 0X50
  • 12. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Writing to EEPROM ¢ For writing at EEPROM offset 0x0060 ¢ Send the start condition ¢ Send the slave address of EEPROM (0X50), followed by direction (Read/Write) ¢ Send the EEPROM offset higher byte, followed by lower byte ¢ Send the actual data to be written ¢ Send the Stop condition ¢ START->0x50->0x00(offset high)->0x60 (offset low)- >0X99(Data)->STOP
  • 13. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Reading From EEPROM ¢ Write the EEPROM offset say 0x0060 (read offset) C START->0x50->0x00(offset high)->0x60 (offset low)->STOP ¢ Read the EEPROM data C Send the start condition C Send the slave address of EEPROM (0X50), followed by direction (Read) C Read the data C Send the stop condition C START->0x50->Data (RX)->Data (RX)->STOP
  • 14. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Need for Linux Device Model ¢ Maximize the code re-usability across the platforms C Same device drivers on different platforms ¢ To achieve this C Decouple device drivers from controller drivers C Decouple hardware description from the drivers ¢ In addition to above C Information about how the system is put together ¢ Effective power management C Communication with user space C Hotpluggable devices
  • 15. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Device Drivers in Linux Application System Call Interface Framework Driver Bus Infrastructure Hardware
  • 16. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Device model data structures ¢ struct bus_type C Represents the bus such as USB, PCI, I2C etc ¢ struct device_driver C Represents the driver capable of handling certain devices ¢ struct device C Represents the device connected to the bus
  • 17. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Linux I2C Subsystem ¢ I2C subsystem provides C API to implement I2C controller driver C API to implement I2C device driver in kernel space C An abstraction to implement the client drivers independent of adapter drivers
  • 18. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Linux I2C Subsystem ... User Space Kernel Space I2C Device (i2c_client) I2C Host Controller (i2c_adapter) Hardware Space /sys, /dev User Applications User Mode I2C Device Driver I2C Core i2c-dev Vertical: Character I2C Client Driver I2C Bus I2C Adapter (platform_driver) / Algo Driver (i2c_algorithm)
  • 19. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Subsystem Details ¢ i2c-adapter / i2c-algo C Controller-specific I2C host controller / adapter C Also called as the I2C bus drivers ¢ i2c-core C Hides the adapter details from the layers above C By providing the generic I2C APIs ¢ i2c-dev C Provides device access in user space through /sys C Enables implementation of User Mode Drivers ¢ i2c-client C Driver specific to an I2C device C Implemented using i2c-core APIs
  • 20. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Client Driver ¢ Typically a character driver vertical - /dev or /sys exposed ¢ But actually depends on the device category ¢ Registers with I2C Core (in the init function) ¢ Unregisters from I2C Core (in the cleanup function) ¢ And uses the generic function from I2C Core for data transfers C int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
  • 21. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Client Driver init & cleanup ¢ Registering to the I2C Core using C int i2c_add_driver(struct i2c_driver *) C struct i2c_driver contains ¢ probe function C called on device detection ¢ remove function C called on device shutdown ¢ id_table C Table of device identifiers ¢ Unregistering from the I2C Core using C void i2c_del_driver(struct i2c_driver *) ¢ Common bare-bone of init & cleanup C Just use module_i2c_driver(struct i2c_driver)
  • 22. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Client Driver Registration ¢ struct i2c_driver dummy_driver = { driver = { name = ^dummy_client ̄, owner = THIS_MODULE, }, .probe = dummy_probe, .remove = dummy_remove, .id_table = dummy_ids, } ¢ static const struct i2c_device_id dummy_ids = { { ^dummy_device ̄, 0}, {} } ¢ i2c_add_driver(dummy_driver)
  • 23. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Adapter Driver (Un)Registeration ¢ Registering to the I2C Core using C int i2c_add_numbered_adapter(struct i2c_adapter *); C Registered in the platform driver probe ¢ Unregistering from the I2C Core using C void i2c_del_adapter(struct i2c_driver *); C In platform driver remove functions
  • 24. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved I2C Client Driver Examples ¢ Path: <kernel_source>/drivers/ C I2C EEPROM: AT24 ¢ misc/eeprom/at24.c C I2C RTC: DS1307 ¢ rtc/rtc-ds1307.c
  • 25. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Registering the I2C Client (Non DT) ¢ On non-DT platforms, the struct i2c_board_info describes how device is connected to a board ¢ Defined with I2C_BOARD_INFO helper macro C Takes as the arguments, the device name and the slave address of the device on the bus ¢ An array of such structures is registered on per bus basis using the i2c_register_board_info during the platform initialization
  • 26. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Registering the I2C Client (Non DT).. ¢ static struct i2c_board_info my_i2c_devices [] = { { I2C_BOARD_INFO (^my_device ̄, 0 x1D ), . irq = 70, .platform_data = &my_data }, } ¢ i2c_register_board_info(0, my_i2c_devices, ARRAY_SIZE (my_i2c_devices))
  • 27. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Registering an I2C Client (DT) ¢ In the device tree, the I2C devices on the bus are described as children of the I2C controller node ¢ reg property gives the I2C slave address on the bus
  • 28. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved Registering an I2C Client (DT) ... ¢ i2c@49607899 { compatible = "dummy_adap"; clock-frequency = <0x186a0>; #address-cells = <0x1>; #size-cells = <0x0>; my_dummy@0 { compatible = "dummy_device"; reg = <0x40>; }; }; ¢ Registered internally by i2c_core based on info from DTB ¢ i2c_new_device(struct i2c_adapter *, struct i2c_board_info *)
  • 29. @ 2021-22 Embitude Trainings <info@embitude.in> All Rights Reserved What all did we learn? ¢ I2C Overview ¢ I2C Conditions & Transactions ¢ I2C Subsystem in Linux C I2C Adapter & I2C Client ¢ I2C Client Driver ¢ I2C Device Registration (Non DT and DT)