Difference between revisions of "I2C device tree configuration"

[quality revision] [quality revision]
imported>Frq08467
m (Update compatible name & remove release 1.2 tags)
 
Template:ArticleMainWriter Template:ReviewersList Template:ArticleApprovedVersion

1 Article purpose[edit]

This article explains how to configure the I2C internal peripheral[1] when the peripheral is assigned to Linux® OS, and in particular:

  • how to configure the STM32 I2C peripheral
  • how to configure the STM32 external I2C devices present either on the board or on a hardware extension.

The configuration is performed using the device tree mechanism[2].

It is used by the STM32 I2C Linux® driver that registers relevant information in the I2C framework.

If the peripheral is assigned to another execution context, refer to How to assign an internal peripheral to a runtime context article for guidelines on peripheral assignment and configuration.

2 DT bindings documentation[edit]

The I2C is represented by:

  • The Generic device tree bindings for I2C busses[3]
  • The STM32 I2C controller device tree bindings[4]

3 DT configuration[edit]

This hardware description is a combination of the STM32 microprocessor device tree files (.dtsi extension) and board device tree files (.dts extension). See the Device tree for an explanation of the device tree file split.

STM32CubeMX can be used to generate the board device tree. Refer to How to configure the DT using STM32CubeMX for more details.

3.1 DT configuration (STM32 level)[edit]

At device level, the I2C controller is declared as follows:


i2c2: i2c@40013000 {
	compatible = "st,
stm32f7
stm32mp15-i2c";
	reg = <0x5c002000 0x400>;
	interrupt-names = "event", "error"
, "wakeup"
;

        interrupts-extended = <&
intc
exti 
GIC_SPI
22 
33
IRQ_TYPE_LEVEL_HIGH>,

                                           <&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>
, <&exti 22 1>
;
	clocks = <&rcc I2C2_K>;
	resets = <&rcc I2C2_R>;
	#address-cells = <1>;
	#size-cells = <0>;

        dmas = <&dmamux1 35 0x400 
0x05>
0x80000001>,

                     <&dmamux1 36 0x400 
0x05>
0x80000001>;
        dma-names = "rx", "tx";
	power-domains = <&pd_core>;

        st,syscfg-fmp = <&syscfg 0x4 0x2>;

st,syscfg-fmp-clr
 
=
 
<&syscfg
 
0x44 0x2>
     wakeup-source;
	status = "disabled";
};

Warning.png This device tree part is related to STM32 microprocessors. It must be kept as is, without being modified by the end-user.

Refer to the DTS file: stm32mp157cstm32mp151.dtsi[5]

3.2 DT configuration (board level)[edit]


&
i2c3
i2c2 {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&i2c2_pins_a>;
	pinctrl-1 = <&i2c2_pins_sleep_a>;
	i2c-scl-rising-time-ns = <185>;
	i2c-scl-falling-time-ns = <20>;
        st,smbus-alert;
        st,smbus-host-notify;
	status = "okay";
	/delete-property/dmas;
	/delete-property/dma-names;

	ov5640: camera@3c {
         [...]
	};
};

There are two levels of device tree configuration:

3.2.1 I²C internal peripheral related properties[edit]

The device tree properties related to the I²C internal peripheral and to the I²C bus which belong to i2cx node

  • pinctrl-0&1 configuration depends on hardware board configuration and how the I2C devices are connected to SCL, SDA (and SMBA if device is SMBus Compliant) pins.
    More details about pin configuration are available here: Pinctrl device tree configuration
  • clock-frequency represents the I2C bus speed : normal (100KHz), Fast (400KHz) and Fast+(up to 1MHz). This value is given in Hz.
  • dmas By default, DMAs are enabled for all I2C instances. This is up to the user to remove them if not needed. /delete-property/ is used to remove DMA usage for I2C. Both /delete-property/dma-names and /delete-property/dmas have to be inserted to get rid of DMAs.
  • i2c-scl-rising/falling-time-ns are both optional values depending on the board hardware characteristics: wires length, resistor and capacitor of the hardware design.
    These values must be provided in nanoseconds and can be measured by observing the SCL rising and falling slope on an oscilloscope. See how to measure I2C timings.
    The I2C driver uses this information to compute accurate I2C timings according to the requested clock-frequency.
    The STM32CubeMX implements an algorithm that follows the I2C standard and takes into account the user inputs.
    When those values are not provided, the driver uses its default values.
    Providing wrong parameters will produce inaccurate clock-frequency.
    In case the driver fails to compute timing parameters in line with the user input (SCL raising/falling and clock frequency), the clock frequency will be downgraded to a lower frequency.
    Example: if user specifies 400 kHz as clock frequency but the algorithm fails to generate timings for the specified SCL rising and falling time, the clock frequency will be dropped to 100 kHz.
  • dmas By default, DMAs are enabled for all I2C instances. This is up to the user to remove them if not needed. /delete-property/ is used to remove DMA usage for I2C. Both /delete-property/dma-names and /delete-property/dma have to be inserted to get rid of DMAs.
Info.png I2C timings are highly recommended for I2C bus frequency higher than 100KHz.
  • st,smbus-alert optional property allow to enable the driver handling of the SMBus Alert mechanism. When enabled, the slave driver's alert function will be called whenever the slave device generates an SMBus Alert message.
  • st,smbus-host-notify optional property allow to enable the driver handling of the SMBus Host Notify mechanism. When enabled, an IRQ handler will get called whenever a slave device sends a Host Notify message.
Info.png See Linux smbus-protocol documentation [6] for more details about SMBus Alert & Host Notify handling.

3.2.2 I²C devices related properties[edit]

The device tree properties related to I²C devices connected to the specified I²C bus. Each I²C device is represented by a sub-node.

  • reg represents the I2C peripheral slave address on the bus.
    Be aware that some slave address bits can have a special meaning for the framework. For instance, the 31Template:Sup st bit indicates 10-bit device capability.
    Refer to i2c.txt[3] for further details

3.

3 DT configuration examples[edit]

32.3.1 How to measure I2C timings[edit]

i2c-scl-rising-time-ns is measured on the SCL rising edge and i2c-scl-falling-time-ns on the SCL falling edge. On the oscilloscope, measure the time between the 20% to 80% range of amplitude for rising time and falling time in nanoseconds.

Alternate text
I2C timings

3.3

.2

DT configuration examples[edit]

3.3.1 Example of an external EEPROM slave device[edit]


i2c4: {
    status = "okay";
    i2c-scl-rising-time-ns = <185>;
    i2c-scl-falling-time-ns = <20>;
   
    eeprom@50 {
        compatible = "at,24c256";
        pagesize = <64>;
        reg = <0x50>;
    };
};

The above example registers an EEPROM device on i2c-X bus (X depends on how many adapters are probed at runtime) at address 0x50 and this instance is compatible with the driver registered with the same compatible property.
Please note that the driver is going to use MDMA for data transfer and that SCL rising/falling times have been provided as inputs.

3.3.32 Example of an EEPROM slave device emulator registering on STM32 side[edit]


i2c4: {
    eeprom@64 {
        status = "okay";
        compatible = "linux,slave-24c02";
        reg = <0x40000064>;
    };
};

The above example registers an EEPROM emulator on STM32 side at slave address 0x64.
STM32 acts as an I2C EEPROM that can be accessed from an external master device connected on I2C bus.

3.3.3 Example of a stts751 thermal sensor with SMBus Alert feature enabled[edit]

The stts751 thermal sensor [7] is able to send an SMBus Alert when configured threshold are reached. The device driver can be enabled in the kernel:

[x] Device Drivers
    [x] Hardware Monitoring support
        [x] ST Microelectronics STTS751

This can be done manually in your kernel:

CONFIG_SENSORS_STTS751=y

Since the SMBus Alert is relying on a dedicated pin to work, the pinctrl of the I2C controller (here i2c2) must be updated to add the corresponding SMBA pin.

For the i2c2 controller:


i2c2_pins_a: i2c2-0 {
    pins {
        pinmux = <STM32_PINMUX('H', 4, AF4)>, /* I2C2_SCL */
                        <STM32_PINMUX('H', 5, AF4)>, /* I2C2_SDA */
                        <STM32_PINMUX('H', 6, AF4)>; /* I2C2_SMBA */
        bias-disable;
        drive-open-drain;
        slew-rate = <0>;
    };
};

i2c2_pins_sleep_a: i2c2-1 {
    pins {
        pinmux = <STM32_PINMUX('H', 4, ANALOG)>, /* I2C2_SCL */
                        <STM32_PINMUX('H', 5, ANALOG)>, /* I2C2_SDA */
                        <STM32_PINMUX('H', 6, ANALOG)>; /* I2C2_SMBA */
    };
};

Within the device-tree, the st,smbus-alert property must be added, as well as the node to enable the stts751.


i2c2: {
    st,smbus-alert;
    stts751@3b {
        status = "okay";
        compatible = "stts751";
        reg = <0x3b>;
    };
};

4 How to configure the DT using STM32CubeMX[edit]

The STM32CubeMX tool can be used to configure the STM32MPU device and get the corresponding platform configuration device tree files.
The STM32CubeMX may not support all the properties described in the above DT bindings documentation paragraph. If so, the tool inserts user sections in the generated device tree. These sections can then be edited to add some properties and they are preserved from one generation to another. Refer to STM32CubeMX user manual for further information.

5 References[edit]

Please refer to the following links for additional information:


<noinclude>

{{ArticleBasedOnModel | [[Peripheral or framework device tree configuration model]]}}
{{ArticleMainWriter | Pierre-YvesM}}
{{ReviewersList|Pierre-YvesM, BichH, FabriceG}}
{{ArticleApprovedVersion | BichH | FabriceG, GeraldB, ErwanL | 12Oct'18 | AlainF - 11Oct'18 - 9163 | 05Feb'19}} 
[[Category:Device tree configuration]]
[[Category:I2C]]</noinclude>

== Article purpose ==
This article explains how to configure the ''I2C internal peripheral''<ref name="I2C internal peripheral"> [[I2C internal peripheral]] </ref> ''' when the peripheral is assigned to Linux<sup>&reg;</sup> OS''', and in particular:
* how to configure the STM32 I2C peripheral
* how to configure the STM32 external I2C devices present either on the board or on a hardware extension.

The configuration is performed using the '''device tree mechanism'''<ref> [[Device tree]]</ref>.

It is used by the ''STM32 I2C Linux<sup>&reg;</sup> driver'' that registers relevant information in the [[I2C overview|I2C]] framework.
If the peripheral is assigned to another execution context, refer to [[How to assign an internal peripheral to a runtime context]] article for guidelines on peripheral assignment and configuration.
== DT bindings documentation ==
The I2C is represented by:
* The ''Generic device tree bindings for I2C busses''<ref name="i2c.txt">{{CodeSource | Linux kernel | Documentation/devicetree/bindings/i2c/i2c.txt}}, Generic device tree bindings for I2C busses</ref>

* The ''STM32 I2C controller device tree bindings''<ref name="i2c-stm32.txt ">{{CodeSource |Linux kernel | Documentation/devicetree/bindings/i2c/i2c-stm32.txt}}</ref>


== DT configuration ==
This hardware description is a combination of the '''STM32 microprocessor''' device tree files (''.dtsi'' extension) and '''board''' device tree files (''.dts'' extension). See the [[Device tree]] for an explanation of the device tree file split.

'''STM32CubeMX''' can be used to generate the board device tree. Refer to [[#How_to_configure_the_DT_using_STM32CubeMX|How to configure the DT using STM32CubeMX]] for more details.

===DT configuration (STM32 level) ===

At device level, the I2C controller is declared as follows:<pre class="brush:c; tab-size:8;gutter:true;">

i2c2: i2c@40013000 {
	compatible = "st,stm32f7stm32mp15-i2c";
	reg = <0x5c002000 0x400>;
	interrupt-names = "event", "error", "wakeup";
	interrupts-extended = <&intc GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,<&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,<&exti 22 1>;
        interrupts-extended = <&exti 22 IRQ_TYPE_LEVEL_HIGH>,<&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
	clocks = <&rcc I2C2_K>;
	resets = <&rcc I2C2_R>;
	#address-cells = <1>;
	#size-cells = <0>;	dmas = <&dmamux1 35 0x400 0x05>,<&dmamux1 36 0x400 0x05>;
	power-domains = <&pd_core>;        dmas = <&dmamux1 35 0x400 0x80000001>,<&dmamux1 36 0x400 0x80000001>;
        dma-names = "rx", "tx";
	power-domains = <&pd_core>;st,syscfg-fmp = <&syscfg 0x4 0x2>;	st,syscfg-fmp-clr = <&syscfg 0x44 0x2>        wakeup-source;
	status = "disabled";
};</pre>

{{Warning|This device tree part is related to STM32 microprocessors. It must be kept as is, without being modified by the end-user.}}

Refer to the DTS file: stm32mp157cstm32mp151.dtsi<ref name=DTS>{{CodeSource | Linux kernel | arch/arm/boot/dts/stm32mp157cstm32mp151.dtsi}}</ref>


=== DT configuration (board level) ===<pre class="brush:c; tab-size:8;gutter:true;">

&i2c3i2c2 {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&i2c2_pins_a>;
	pinctrl-1 = <&i2c2_pins_sleep_a>;
	i2c-scl-rising-time-ns = <185>;
	i2c-scl-falling-time-ns = <20>;        st,smbus-alert;
        st,smbus-host-notify;	status = "okay";
	/delete-property/dmas;
	/delete-property/dma-names;

	ov5640: camera@3c {
         [...]
	};
};</pre>


There are two levels of device tree configuration:* 

==== I²C internal peripheral related properties ====
The device tree properties related to the I²C internal peripheral and to the I²C bus which belong to i2cx node
** '''{{highlight|pinctrl-0&1}}''' configuration depends on hardware board configuration and how the I2C devices are connected to SCL, SDA (and SMBA if device is SMBus Compliant) pins.<br/> More details about pin configuration are available here: [[Pinctrl device tree configuration]] 
** '''{{highlight|clock-frequency}}''' represents the I2C bus speed : '''normal (100KHz)''', '''Fast (400KHz)''' and '''Fast+(up to 1MHz)'''. This value is given in Hz.
* '''{{highlight|dmas}}''' By default, DMAs are enabled for all I2C instances. This is up to the user to '''remove''' them if not needed. ''{{highlight|/delete-property/}}'' is used to remove DMA usage for I2C. Both '''{{highlight|/delete-property/dma-names}}''' and '''{{highlight|/delete-property/dmas}}''' have to be inserted to get rid of DMAs.* '''{{highlight|i2c-scl-rising/falling-time-ns}}''' are both optional values depending on the board hardware characteristics: wires length, resistor and capacitor of the hardware design.<br/> These values must be provided in nanoseconds and can be measured by observing the SCL rising and falling slope on an oscilloscope. See [[I2C device tree configuration#How to measure I2C timings | how to measure I2C timings]].<br/>The I2C driver uses this information to compute accurate I2C timings according to the requested ''{{highlight|clock-frequency}}''. <br/>The STM32CubeMX implements an algorithm that follows the I2C standard and takes into account the user inputs. <br/> When those values are not provided, the driver uses its default values. <br/>Providing wrong parameters will produce inaccurate ''{{highlight|clock-frequency}}''.<br/> In case the driver fails to compute timing parameters in line with the user input (SCL raising/falling and clock frequency), the clock frequency will be downgraded to a lower frequency.<br/> '''Example''': if user specifies 400 kHz as clock frequency but the algorithm fails to generate timings for the specified SCL rising and falling time, the clock frequency will be dropped to 100 kHz.** '''{{highlight|dmas}}''' By default, DMAs are enabled for all I2C instances. This is up to the user to '''remove''' them if not needed. ''{{highlight|/delete-property/}}'' is used to remove DMA usage for I2C. Both '''{{highlight|/delete-property/dma-names}}''' and '''{{highlight|/delete-property/dma}}''' have to be inserted to get rid of DMAs.
* {{Info| I2C timings are highly recommended for I2C bus frequency higher than 100KHz.}}
* '''{{highlight|st,smbus-alert}}''' optional property allow to enable the driver handling of the SMBus Alert mechanism. When enabled, the slave driver's alert function will be called whenever the slave device generates an SMBus Alert message.
* '''{{highlight|st,smbus-host-notify}}''' optional property allow to enable the driver handling of the SMBus Host Notify mechanism. When enabled, an IRQ handler will get called whenever a slave device sends a Host Notify message.
{{Info| See Linux smbus-protocol documentation <ref name="smbus-protocol ">{{CodeSource |Linux kernel | Documentation/i2c/smbus-protocol}}</ref> for more details about SMBus Alert & Host Notify handling.}}

==== I²C devices related properties ====
The device tree properties related to I²C devices connected to the specified I²C bus. Each I²C device is represented by a sub-node.
** '''{{highlight|reg}}''' represents the I2C peripheral slave address on the bus.<br/> Be aware that some slave address bits can have a special meaning for the framework. For instance, the 31{{<sup>|st}}</sup> bit indicates 10-bit device capability.<br/> Refer to i2c.txt<ref name="i2c.txt"/> for further details

=== DT configuration examples ===
=====How to measure I2C timings====
{{highlight|i2c-scl-rising-time-ns}} is measured on the SCL rising edge and {{highlight|i2c-scl-falling-time-ns}} on the SCL falling edge. On the oscilloscope, measure the time between the 20% to 80% range of amplitude for rising time and falling time in nanoseconds.<br/>

[[File:I2C timings.png|thumb|link=|center|766px|alt=Alternate text|I2C timings]]====

=== DT configuration examples ===
====Example of an external EEPROM slave device====<pre class="brush:c; tab-size:8;gutter:true;">

i2c4: {
    status = "okay";
    i2c-scl-rising-time-ns = <185>;
    i2c-scl-falling-time-ns = <20>;

    eeprom@50 {
        compatible = "at,24c256";
        pagesize = <64>;
        reg = <0x50>;
    };
};</pre>

The above example registers an EEPROM device on i2c-X bus (X depends on how many adapters are probed at runtime) at address 0x50 and this instance is compatible with the driver registered with the same compatible property.<br/>

Please note that the driver is going to use MDMA for data transfer and that SCL rising/falling times have been provided as inputs.<br/>


====Example of an EEPROM slave device emulator registering on STM32 side====<pre class="brush:c; tab-size:8;gutter:true;">

i2c4: {
    eeprom@64 {
        status = "okay";
        compatible = "linux,slave-24c02";
        reg = <0x40000064>;
    };
};</pre>

The above example registers an EEPROM emulator on STM32 side at slave address 0x64. <br/>

STM32 acts as an I2C EEPROM that can be accessed from an external master device connected on I2C bus.

====Example of a stts751 thermal sensor with SMBus Alert feature enabled====
The stts751 thermal sensor <ref>https://www.st.com/en/mems-and-sensors/stts751.html</ref> is able to send an SMBus Alert when configured threshold are reached.</br>

The device driver can be enabled in the kernel:</br>

 [x] Device Drivers
     [x] Hardware Monitoring support
         [x] ST Microelectronics STTS751

This can be done manually in your kernel:

CONFIG_SENSORS_STTS751=y

Since the SMBus Alert is relying on a dedicated pin to work, the pinctrl of the I2C controller (here i2c2) must be updated to add the corresponding SMBA pin.</br>


For the i2c2 controller:<pre>

i2c2_pins_a: i2c2-0 {
    pins {
        pinmux = <STM32_PINMUX('H', 4, AF4)>, /* I2C2_SCL */<STM32_PINMUX('H', 5, AF4)>, /* I2C2_SDA */<STM32_PINMUX('H', 6, AF4)>; /* I2C2_SMBA */
        bias-disable;
        drive-open-drain;
        slew-rate = <0>;
    };
};

i2c2_pins_sleep_a: i2c2-1 {
    pins {
        pinmux = <STM32_PINMUX('H', 4, ANALOG)>, /* I2C2_SCL */<STM32_PINMUX('H', 5, ANALOG)>, /* I2C2_SDA */<STM32_PINMUX('H', 6, ANALOG)>; /* I2C2_SMBA */
    };
};</pre>


Within the device-tree, the st,smbus-alert property must be added, as well as the node to enable the stts751.</br>

<pre>

i2c2: {
    st,smbus-alert;
    stts751@3b {
        status = "okay";
        compatible = "stts751";
        reg = <0x3b>;
    };
};</pre>


==How to configure the DT using STM32CubeMX==
The [[STM32CubeMX]] tool can be used to configure the STM32MPU device and get the corresponding [[Device_tree#STM32|platform configuration device tree]] files.<br />

The STM32CubeMX may not support all the properties described in the above [[#DT bindings documentation|DT bindings documentation]] paragraph. If so, the tool inserts '''user sections''' in the generated device tree. These sections can then be edited to add some properties and they are preserved from one generation to another. Refer to [[STM32CubeMX]] user manual for further information.

==References==
Please refer to the following links for additional information:
<references />

<noinclude>

[[Category:Device tree configuration]]
[[Category:I2C]]
{{ArticleBasedOnModel | Peripheral or framework device tree configuration model}}
{{PublicationRequestId | 9163 | 2018-10-11 | AlainF}}</noinclude>
(15 intermediate revisions by 6 users not shown)
Line 1: Line 1:
<noinclude>
 
{{ArticleBasedOnModel | [[Peripheral or framework device tree configuration model]]}}
 
{{ArticleMainWriter | Pierre-YvesM}}
 
{{ReviewersList|Pierre-YvesM, BichH, FabriceG}}
 
{{ArticleApprovedVersion | BichH | FabriceG, GeraldB, ErwanL | 12Oct'18 | AlainF - 11Oct'18 - 9163 | 05Feb'19}}
 
[[Category:Device tree configuration]]
 
[[Category:I2C]]
 
</noinclude>
 
 
 
== Article purpose ==
 
== Article purpose ==
 
This article explains how to configure the ''I2C internal peripheral''<ref name="I2C internal peripheral"> [[I2C internal peripheral]] </ref> ''' when the peripheral is assigned to Linux<sup>&reg;</sup> OS''', and in particular:
 
This article explains how to configure the ''I2C internal peripheral''<ref name="I2C internal peripheral"> [[I2C internal peripheral]] </ref> ''' when the peripheral is assigned to Linux<sup>&reg;</sup> OS''', and in particular:
Line 16: Line 7:
   
 
It is used by the ''STM32 I2C Linux<sup>&reg;</sup> driver'' that registers relevant information in the [[I2C overview|I2C]] framework.
 
It is used by the ''STM32 I2C Linux<sup>&reg;</sup> driver'' that registers relevant information in the [[I2C overview|I2C]] framework.
  +
  +
If the peripheral is assigned to another execution context, refer to [[How to assign an internal peripheral to a runtime context]] article for guidelines on peripheral assignment and configuration.
   
 
== DT bindings documentation ==
 
== DT bindings documentation ==
Line 30: Line 23:
   
 
At device level, the I2C controller is declared as follows:
 
At device level, the I2C controller is declared as follows:
<pre class="brush:c; tab-size:8;gutter:true;">
+
<pre>
 
i2c2: i2c@40013000 {
 
i2c2: i2c@40013000 {
compatible = "st,stm32f7-i2c";
+
compatible = "st,stm32mp15-i2c";
 
reg = <0x5c002000 0x400>;
 
reg = <0x5c002000 0x400>;
interrupt-names = "event", "error", "wakeup";
+
interrupt-names = "event", "error";
interrupts-extended = <&intc GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+
        interrupts-extended = <&exti 22 IRQ_TYPE_LEVEL_HIGH>,
      <&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+
                                          <&intc GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
      <&exti 22 1>;
 
 
clocks = <&rcc I2C2_K>;
 
clocks = <&rcc I2C2_K>;
 
resets = <&rcc I2C2_R>;
 
resets = <&rcc I2C2_R>;
 
#address-cells = <1>;
 
#address-cells = <1>;
 
#size-cells = <0>;
 
#size-cells = <0>;
dmas = <&dmamux1 35 0x400 0x05>,
+
        dmas = <&dmamux1 35 0x400 0x80000001>,
      <&dmamux1 36 0x400 0x05>;
+
                    <&dmamux1 36 0x400 0x80000001>;
  +
        dma-names = "rx", "tx";
 
power-domains = <&pd_core>;
 
power-domains = <&pd_core>;
st,syscfg-fmp = <&syscfg 0x4 0x2>;
+
        st,syscfg-fmp = <&syscfg 0x4 0x2>;
st,syscfg-fmp-clr = <&syscfg 0x44 0x2>;
+
        wakeup-source;
 
status = "disabled";
 
status = "disabled";
 
};
 
};
Line 52: Line 45:
 
{{Warning|This device tree part is related to STM32 microprocessors. It must be kept as is, without being modified by the end-user.}}
 
{{Warning|This device tree part is related to STM32 microprocessors. It must be kept as is, without being modified by the end-user.}}
   
Refer to the DTS file: stm32mp157c.dtsi<ref name=DTS>{{CodeSource | Linux kernel | arch/arm/boot/dts/stm32mp157c.dtsi}}</ref>
+
Refer to the DTS file: stm32mp151.dtsi<ref name=DTS>{{CodeSource | Linux kernel | arch/arm/boot/dts/stm32mp151.dtsi}}</ref>
   
 
=== DT configuration (board level) ===
 
=== DT configuration (board level) ===
<pre class="brush:c; tab-size:8;gutter:true;">
+
<pre>
&i2c3 {
+
&i2c2 {
 
pinctrl-names = "default", "sleep";
 
pinctrl-names = "default", "sleep";
 
pinctrl-0 = <&i2c2_pins_a>;
 
pinctrl-0 = <&i2c2_pins_a>;
Line 62: Line 55:
 
i2c-scl-rising-time-ns = <185>;
 
i2c-scl-rising-time-ns = <185>;
 
i2c-scl-falling-time-ns = <20>;
 
i2c-scl-falling-time-ns = <20>;
  +
        st,smbus-alert;
  +
        st,smbus-host-notify;
 
status = "okay";
 
status = "okay";
 
/delete-property/dmas;
 
/delete-property/dmas;
Line 73: Line 68:
   
 
There are two levels of device tree configuration:
 
There are two levels of device tree configuration:
* The device tree properties related to the I²C internal peripheral and to the I²C bus which belong to i2cx node
 
** '''{{highlight|pinctrl-0&1}}''' configuration depends on hardware board configuration and how the I2C devices are connected to SCL, SDA (and SMBA if device is SMBus Compliant) pins.<br/> More details about pin configuration are available here: [[Pinctrl device tree configuration]]
 
** '''{{highlight|clock-frequency}}''' represents the I2C bus speed : '''normal (100KHz)''', '''Fast (400KHz)''' and '''Fast+(up to 1MHz)'''. This value is given in Hz.
 
** '''{{highlight|i2c-scl-rising/falling-time-ns}}''' are both depending on the board hardware characteristics: wires length, resistor and capacitor of the hardware design.<br/> These values must be provided in nanoseconds and can be measured by observing the SCL rising and falling slope on an oscilloscope. See [[I2C device tree configuration#How to measure I2C timings | how to measure I2C timings]].<br/>The I2C driver uses this information to compute accurate I2C timings according to the requested ''{{highlight|clock-frequency}}''. The STM32CubeMX implements an algorithm that follows the I2C standard and takes into account the user inputs.<br/> Providing wrong parameters will produce inaccurate ''{{highlight|clock-frequency}}''.<br/> In case the driver fails to compute timing parameters in line with the user input (SCL raising/falling and clock frequency), the clock frequency will be downgraded to a lower frequency.<br/> '''Example''': if user specifies 400 kHz as clock frequency but the algorithm fails to generate timings for the specified SCL rising and falling time, the clock frequency will be dropped to 100 kHz.
 
** '''{{highlight|dmas}}''' By default, DMAs are enabled for all I2C instances. This is up to the user to '''remove''' them if not needed. ''{{highlight|/delete-property/}}'' is used to remove DMA usage for I2C. Both '''{{highlight|/delete-property/dma-names}}''' and '''{{highlight|/delete-property/dma}}''' have to be inserted to get rid of DMAs.
 
* The device tree properties related to I²C devices connected to the specified I²C bus. Each I²C device is represented by a sub-node.
 
** '''{{highlight|reg}}''' represents the I2C peripheral slave address on the bus.<br/> Be aware that some slave address bits can have a special meaning for the framework. For instance, the 31{{sup|st}} bit indicates 10-bit device capability.<br/> Refer to i2c.txt<ref name="i2c.txt"/> for further details
 
   
=== DT configuration examples ===
+
==== I²C internal peripheral related properties ====
  +
 
  +
The device tree properties related to the I²C internal peripheral and to the I²C bus which belong to i2cx node
  +
* '''{{highlight|pinctrl-0&1}}''' configuration depends on hardware board configuration and how the I2C devices are connected to SCL, SDA (and SMBA if device is SMBus Compliant) pins.<br/> More details about pin configuration are available here: [[Pinctrl device tree configuration]]
  +
* '''{{highlight|clock-frequency}}''' represents the I2C bus speed : '''normal (100KHz)''', '''Fast (400KHz)''' and '''Fast+(up to 1MHz)'''. This value is given in Hz.
  +
* '''{{highlight|dmas}}''' By default, DMAs are enabled for all I2C instances. This is up to the user to '''remove''' them if not needed. ''{{highlight|/delete-property/}}'' is used to remove DMA usage for I2C. Both '''{{highlight|/delete-property/dma-names}}''' and '''{{highlight|/delete-property/dmas}}''' have to be inserted to get rid of DMAs.
  +
* '''{{highlight|i2c-scl-rising/falling-time-ns}}''' are optional values depending on the board hardware characteristics: wires length, resistor and capacitor of the hardware design.<br/> These values must be provided in nanoseconds and can be measured by observing the SCL rising and falling slope on an oscilloscope. See [[I2C device tree configuration#How to measure I2C timings | how to measure I2C timings]].<br/>The I2C driver uses this information to compute accurate I2C timings according to the requested ''{{highlight|clock-frequency}}''. <br/>The STM32CubeMX implements an algorithm that follows the I2C standard and takes into account the user inputs. <br/>When those values are not provided, the driver uses its default values. <br/>Providing wrong parameters will produce inaccurate ''{{highlight|clock-frequency}}''. In case the driver fails to compute timing parameters in line with the user input (SCL raising/falling and clock frequency), the clock frequency will be downgraded to a lower frequency. '''Example''': if user specifies 400 kHz as clock frequency but the algorithm fails to generate timings for the specified SCL rising and falling time, the clock frequency will be dropped to 100 kHz.
  +
{{Info| I2C timings are highly recommended for I2C bus frequency higher than 100KHz.}}
  +
* '''{{highlight|st,smbus-alert}}''' optional property allow to enable the driver handling of the SMBus Alert mechanism. When enabled, the slave driver's alert function will be called whenever the slave device generates an SMBus Alert message.
  +
* '''{{highlight|st,smbus-host-notify}}''' optional property allow to enable the driver handling of the SMBus Host Notify mechanism. When enabled, an IRQ handler will get called whenever a slave device sends a Host Notify message.
  +
{{Info| See Linux smbus-protocol documentation <ref name="smbus-protocol ">{{CodeSource |Linux kernel | Documentation/i2c/smbus-protocol}}</ref> for more details about SMBus Alert & Host Notify handling.}}
  +
 
  +
==== I²C devices related properties ====
  +
 
  +
The device tree properties related to I²C devices connected to the specified I²C bus. Each I²C device is represented by a sub-node.
  +
* '''{{highlight|reg}}''' represents the I2C peripheral slave address on the bus.<br/> Be aware that some slave address bits can have a special meaning for the framework. For instance, the 31<sup>st</sup> bit indicates 10-bit device capability.<br/> Refer to i2c.txt<ref name="i2c.txt"/> for further details
  +
 
 
====How to measure I2C timings====
 
====How to measure I2C timings====
 
{{highlight|i2c-scl-rising-time-ns}} is measured on the SCL rising edge and {{highlight|i2c-scl-falling-time-ns}} on the SCL falling edge. On the oscilloscope, measure the time between the 20% to 80% range of amplitude for rising time and falling time in nanoseconds.<br/>
 
{{highlight|i2c-scl-rising-time-ns}} is measured on the SCL rising edge and {{highlight|i2c-scl-falling-time-ns}} on the SCL falling edge. On the oscilloscope, measure the time between the 20% to 80% range of amplitude for rising time and falling time in nanoseconds.<br/>
 
[[File:I2C timings.png|thumb|link=|center|766px|alt=Alternate text|I2C timings]]
 
[[File:I2C timings.png|thumb|link=|center|766px|alt=Alternate text|I2C timings]]
  +
  +
=== DT configuration examples ===
 
====Example of an external EEPROM slave device====
 
====Example of an external EEPROM slave device====
<pre class="brush:c; tab-size:8;gutter:true;">
+
<pre>
 
i2c4: {
 
i2c4: {
 
     status = "okay";
 
     status = "okay";
Line 103: Line 109:
   
 
====Example of an EEPROM slave device emulator registering on STM32 side====
 
====Example of an EEPROM slave device emulator registering on STM32 side====
<pre class="brush:c; tab-size:8;gutter:true;">
+
<pre>
 
i2c4: {
 
i2c4: {
 
     eeprom@64 {
 
     eeprom@64 {
Line 114: Line 120:
 
The above example registers an EEPROM emulator on STM32 side at slave address 0x64. <br/>
 
The above example registers an EEPROM emulator on STM32 side at slave address 0x64. <br/>
 
STM32 acts as an I2C EEPROM that can be accessed from an external master device connected on I2C bus.
 
STM32 acts as an I2C EEPROM that can be accessed from an external master device connected on I2C bus.
  +
  +
====Example of a stts751 thermal sensor with SMBus Alert feature enabled====
  +
The stts751 thermal sensor <ref>https://www.st.com/en/mems-and-sensors/stts751.html</ref> is able to send an SMBus Alert when configured threshold are reached.</br>
  +
The device driver can be enabled in the kernel:</br>
  +
[x] Device Drivers
  +
    [x] Hardware Monitoring support
  +
        [x] ST Microelectronics STTS751
  +
  +
This can be done manually in your kernel:
  +
  +
CONFIG_SENSORS_STTS751=y
  +
  +
Since the SMBus Alert is relying on a dedicated pin to work, the pinctrl of the I2C controller (here i2c2) must be updated to add the corresponding SMBA pin.</br>
  +
  +
For the i2c2 controller:
  +
<pre>
  +
i2c2_pins_a: i2c2-0 {
  +
    pins {
  +
        pinmux = <STM32_PINMUX('H', 4, AF4)>, /* I2C2_SCL */
  +
                        <STM32_PINMUX('H', 5, AF4)>, /* I2C2_SDA */
  +
                        <STM32_PINMUX('H', 6, AF4)>; /* I2C2_SMBA */
  +
        bias-disable;
  +
        drive-open-drain;
  +
        slew-rate = <0>;
  +
    };
  +
};
  +
  +
i2c2_pins_sleep_a: i2c2-1 {
  +
    pins {
  +
        pinmux = <STM32_PINMUX('H', 4, ANALOG)>, /* I2C2_SCL */
  +
                        <STM32_PINMUX('H', 5, ANALOG)>, /* I2C2_SDA */
  +
                        <STM32_PINMUX('H', 6, ANALOG)>; /* I2C2_SMBA */
  +
    };
  +
};
  +
</pre>
  +
  +
Within the device-tree, the st,smbus-alert property must be added, as well as the node to enable the stts751.</br>
  +
  +
<pre>
  +
i2c2: {
  +
    st,smbus-alert;
  +
    stts751@3b {
  +
        status = "okay";
  +
        compatible = "stts751";
  +
        reg = <0x3b>;
  +
    };
  +
};
  +
</pre>
   
 
==How to configure the DT using STM32CubeMX==
 
==How to configure the DT using STM32CubeMX==
Line 123: Line 177:
   
 
<references />
 
<references />
  +
  +
<noinclude>
  +
[[Category:Device tree configuration]]
  +
[[Category:I2C]]
  +
{{ArticleBasedOnModel | Peripheral or framework device tree configuration model}}
  +
{{PublicationRequestId | 9163 | 2018-10-11 | AlainF}}
  +
</noinclude>