Merge branch 'i2c/for-mergewindow' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:

 - core supports now bus regulators controlling power for SCL/SDA

 - quite some DT binding conversions to YAML

 - added a seperate DT binding for the optional SMBus Alert feature

 - documentation with examples how to deal with I2C sysfs files

 - some bigger rework for the i801 driver

 - and a few usual driver updates

* 'i2c/for-mergewindow' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (42 commits)
  i2c: ali1535: mention that the device should not be disabled
  i2c: mpc: Restore reread of I2C status register
  i2c: core-smbus: Expose PEC calculate function for generic use
  Documentation: i2c: Add doc for I2C sysfs
  i2c: core: Disable client irq on reboot/shutdown
  dt-bindings: i2c: update bindings for MT8195 SoC
  i2c: imx: Fix some checkpatch warnings
  i2c: davinci: Simplify with dev_err_probe()
  i2c: cadence: Simplify with dev_err_probe()
  i2c: xiic: Simplify with dev_err_probe()
  i2c: cadence: Clear HOLD bit before xfer_size register rolls over
  dt-bindings: i2c: ce4100: Replace "ti,pcf8575" by "nxp,pcf8575"
  i2c: i801: Improve i801_setup_hstcfg
  i2c: i801: Use driver name constant instead of function dev_driver_string
  i2c: i801: Simplify initialization of i2c_board_info in i801_probe_optional_slaves
  i2c: i801: Improve status polling
  i2c: cht-wc: Replace of_node by NULL
  i2c: riic: Add RZ/G2L support
  dt-bindings: i2c: renesas,riic: Document RZ/G2L I2C controller
  dt-bindings: i2c: renesas,iic: Convert to json-schema
  ...
This commit is contained in:
Linus Torvalds 2021-07-04 11:47:18 -07:00
commit 855ff900b8
35 changed files with 1316 additions and 376 deletions

View File

@ -15,6 +15,7 @@ Required properties:
"mediatek,mt8173-i2c": for MediaTek MT8173
"mediatek,mt8183-i2c": for MediaTek MT8183
"mediatek,mt8192-i2c": for MediaTek MT8192
"mediatek,mt8195-i2c", "mediatek,mt8192-i2c": for MediaTek MT8195
"mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek MT8516
- reg: physical base address of the controller and dma base, length of memory
mapped region.
@ -32,6 +33,7 @@ Optional properties:
- mediatek,have-pmic: platform can control i2c form special pmic side.
Only mt6589 and mt8135 support this feature.
- mediatek,use-push-pull: IO config use push-pull mode.
- vbus-supply: phandle to the regulator that provides power to SCL/SDA.
Example:

View File

@ -62,7 +62,6 @@ Example:
reg = <0x3c>;
pwms = <&pwm 4 3000>;
reset-gpios = <&gpio2 7 1>;
reset-active-low;
};
};

View File

@ -1,37 +0,0 @@
I2C for OMAP platforms
Required properties :
- compatible : Must be
"ti,omap2420-i2c" for OMAP2420 SoCs
"ti,omap2430-i2c" for OMAP2430 SoCs
"ti,omap3-i2c" for OMAP3 SoCs
"ti,omap4-i2c" for OMAP4+ SoCs
"ti,am654-i2c", "ti,omap4-i2c" for AM654 SoCs
"ti,j721e-i2c", "ti,omap4-i2c" for J721E SoCs
"ti,am64-i2c", "ti,omap4-i2c" for AM64 SoCs
- ti,hwmods : Must be "i2c<n>", n being the instance number (1-based)
- #address-cells = <1>;
- #size-cells = <0>;
Recommended properties :
- clock-frequency : Desired I2C bus clock frequency in Hz. Otherwise
the default 100 kHz frequency will be used.
Optional properties:
- Child nodes conforming to i2c bus binding
Note: Current implementation will fetch base address, irq and dma
from omap hwmod data base during device registration.
Future plan is to migrate hwmod data base contents into device tree
blob so that, all the required data will be used from device tree dts
file.
Examples :
i2c1: i2c@0 {
compatible = "ti,omap3-i2c";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "i2c1";
clock-frequency = <400000>;
};

View File

@ -71,7 +71,7 @@ This is an example which is used on FalconFalls:
/* This I2C controller has one gpio controller */
gpio@26 {
#gpio-cells = <2>;
compatible = "ti,pcf8575";
compatible = "nxp,pcf8575";
reg = <0x26>;
gpio-controller;
};
@ -85,7 +85,7 @@ This is an example which is used on FalconFalls:
gpio@26 {
#gpio-cells = <2>;
compatible = "ti,pcf8575";
compatible = "nxp,pcf8575";
reg = <0x26>;
gpio-controller;
};

View File

@ -9,6 +9,7 @@ PROPERTIES:
"qcom,msm8916-cci"
"qcom,msm8996-cci"
"qcom,sdm845-cci"
"qcom,sm8250-cci"
- reg
Usage: required
@ -41,8 +42,8 @@ PROPERTIES:
SUBNODES:
The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996 and
sdm845), described as subdevices named "i2c-bus@0" and "i2c-bus@1".
The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996,
sdm845 and sm8250), described as subdevices named "i2c-bus@0" and "i2c-bus@1".
PROPERTIES:

View File

@ -36,6 +36,7 @@ properties:
- rockchip,px30-i2c
- rockchip,rk3308-i2c
- rockchip,rk3328-i2c
- rockchip,rk3568-i2c
- const: rockchip,rk3399-i2c
reg:

View File

@ -89,8 +89,11 @@ wants to support one of the below features, it should adapt these bindings.
- smbus
states that additional SMBus restrictions and features apply to this bus.
Examples of features are SMBusHostNotify and SMBusAlert. Examples of
restrictions are more reserved addresses and timeout definitions.
An example of feature is SMBusHostNotify. Examples of restrictions are
more reserved addresses and timeout definitions.
- smbus-alert
states that the optional SMBus-Alert feature apply to this bus.
Required properties (per child device)
--------------------------------------

View File

@ -1,67 +0,0 @@
I2C for R-Car platforms
Required properties:
- compatible:
"renesas,i2c-r8a7742" if the device is a part of a R8A7742 SoC.
"renesas,i2c-r8a7743" if the device is a part of a R8A7743 SoC.
"renesas,i2c-r8a7744" if the device is a part of a R8A7744 SoC.
"renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC.
"renesas,i2c-r8a77470" if the device is a part of a R8A77470 SoC.
"renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC.
"renesas,i2c-r8a774b1" if the device is a part of a R8A774B1 SoC.
"renesas,i2c-r8a774c0" if the device is a part of a R8A774C0 SoC.
"renesas,i2c-r8a774e1" if the device is a part of a R8A774E1 SoC.
"renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC.
"renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC.
"renesas,i2c-r8a7790" if the device is a part of a R8A7790 SoC.
"renesas,i2c-r8a7791" if the device is a part of a R8A7791 SoC.
"renesas,i2c-r8a7792" if the device is a part of a R8A7792 SoC.
"renesas,i2c-r8a7793" if the device is a part of a R8A7793 SoC.
"renesas,i2c-r8a7794" if the device is a part of a R8A7794 SoC.
"renesas,i2c-r8a7795" if the device is a part of a R8A7795 SoC.
"renesas,i2c-r8a7796" if the device is a part of a R8A77960 SoC.
"renesas,i2c-r8a77961" if the device is a part of a R8A77961 SoC.
"renesas,i2c-r8a77965" if the device is a part of a R8A77965 SoC.
"renesas,i2c-r8a77970" if the device is a part of a R8A77970 SoC.
"renesas,i2c-r8a77980" if the device is a part of a R8A77980 SoC.
"renesas,i2c-r8a77990" if the device is a part of a R8A77990 SoC.
"renesas,i2c-r8a77995" if the device is a part of a R8A77995 SoC.
"renesas,i2c-r8a779a0" if the device is a part of a R8A779A0 SoC.
"renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device.
"renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible
device.
"renesas,rcar-gen3-i2c" for a generic R-Car Gen3 or RZ/G2 compatible
device.
"renesas,i2c-rcar" (deprecated)
When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first followed
by the generic version.
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt specifier.
Optional properties:
- clock-frequency: desired I2C bus clock frequency in Hz. The absence of this
property indicates the default frequency 100 kHz.
- clocks: clock specifier.
- dmas: Must contain a list of two references to DMA specifiers, one for
transmission, and one for reception.
- dma-names: Must contain a list of two DMA names, "tx" and "rx".
- i2c-scl-falling-time-ns: see i2c.txt
- i2c-scl-internal-delay-ns: see i2c.txt
- i2c-scl-rising-time-ns: see i2c.txt
Examples :
i2c0: i2c@e6508000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
reg = <0 0xe6508000 0 0x40>;
interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
clock-frequency = <400000>;
};

View File

@ -1,22 +0,0 @@
Device tree configuration for Renesas EMEV2 IIC controller
Required properties:
- compatible : "renesas,iic-emev2"
- reg : address start and address range size of device
- interrupts : specifier for the IIC controller interrupt
- clocks : phandle to the IP core SCLK
- clock-names : must be "sclk"
- #address-cells : should be <1>
- #size-cells : should be <0>
Example:
iic0: i2c@e0070000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "renesas,iic-emev2";
reg = <0xe0070000 0x28>;
interrupts = <0 32 IRQ_TYPE_EDGE_RISING>;
clocks = <&iic0_sclk>;
clock-names = "sclk";
};

View File

@ -0,0 +1,54 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/renesas,iic-emev2.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas EMMA Mobile EV2 IIC Interface
maintainers:
- Wolfram Sang <wsa+renesas@sang-engineering.com>
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
properties:
compatible:
const: renesas,iic-emev2
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
clock-names:
const: sclk
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- '#address-cells'
- '#size-cells'
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
iic0: i2c@e0070000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "renesas,iic-emev2";
reg = <0xe0070000 0x28>;
interrupts = <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
clocks = <&iic0_sclk>;
clock-names = "sclk";
};

View File

@ -1,72 +0,0 @@
Device tree configuration for Renesas IIC (sh_mobile) driver
Required properties:
- compatible :
- "renesas,iic-r8a73a4" (R-Mobile APE6)
- "renesas,iic-r8a7740" (R-Mobile A1)
- "renesas,iic-r8a7742" (RZ/G1H)
- "renesas,iic-r8a7743" (RZ/G1M)
- "renesas,iic-r8a7744" (RZ/G1N)
- "renesas,iic-r8a7745" (RZ/G1E)
- "renesas,iic-r8a774a1" (RZ/G2M)
- "renesas,iic-r8a774b1" (RZ/G2N)
- "renesas,iic-r8a774c0" (RZ/G2E)
- "renesas,iic-r8a774e1" (RZ/G2H)
- "renesas,iic-r8a7790" (R-Car H2)
- "renesas,iic-r8a7791" (R-Car M2-W)
- "renesas,iic-r8a7792" (R-Car V2H)
- "renesas,iic-r8a7793" (R-Car M2-N)
- "renesas,iic-r8a7794" (R-Car E2)
- "renesas,iic-r8a7795" (R-Car H3)
- "renesas,iic-r8a7796" (R-Car M3-W)
- "renesas,iic-r8a77961" (R-Car M3-W+)
- "renesas,iic-r8a77965" (R-Car M3-N)
- "renesas,iic-r8a77990" (R-Car E3)
- "renesas,iic-sh73a0" (SH-Mobile AG5)
- "renesas,rcar-gen2-iic" (generic R-Car Gen2 or RZ/G1
compatible device)
- "renesas,rcar-gen3-iic" (generic R-Car Gen3 or RZ/G2
compatible device)
- "renesas,rmobile-iic" (generic device)
When compatible with a generic R-Car version, nodes
must list the SoC-specific version corresponding to
the platform first followed by the generic R-Car
version.
When compatible with "renesas,rmobile-iic" it should
be the last compatibility string listed.
The r8a77990 (R-Car E3) and r8a774c0 (RZ/G2E)
controllers are not considered compatible with
"renesas,rcar-gen3-iic" or "renesas,rmobile-iic"
due to the absence of automatic transmission registers.
- reg : address start and address range size of device
- interrupts : interrupt of device
- clocks : clock for device
- #address-cells : should be <1>
- #size-cells : should be <0>
Optional properties:
- clock-frequency : frequency of bus clock in Hz. Default 100kHz if unset.
- dmas : Must contain a list of two references to DMA
specifiers, one for transmission, and one for
reception.
- dma-names : Must contain a list of two DMA names, "tx" and "rx".
Pinctrl properties might be needed, too. See there.
Example:
iic0: i2c@e6500000 {
compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic",
"renesas,rmobile-iic";
reg = <0 0xe6500000 0 0x425>;
interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7790_CLK_IIC0>;
clock-frequency = <400000>;
#address-cells = <1>;
#size-cells = <0>;
};

View File

@ -0,0 +1,158 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/renesas,rcar-i2c.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas R-Car I2C Controller
maintainers:
- Wolfram Sang <wsa+renesas@sang-engineering.com>
properties:
compatible:
oneOf:
- items:
- enum:
- renesas,i2c-r8a7778 # R-Car M1A
- renesas,i2c-r8a7779 # R-Car H1
- const: renesas,rcar-gen1-i2c # R-Car Gen1
- items:
- enum:
- renesas,i2c-r8a7742 # RZ/G1H
- renesas,i2c-r8a7743 # RZ/G1M
- renesas,i2c-r8a7744 # RZ/G1N
- renesas,i2c-r8a7745 # RZ/G1E
- renesas,i2c-r8a77470 # RZ/G1C
- renesas,i2c-r8a7790 # R-Car H2
- renesas,i2c-r8a7791 # R-Car M2-W
- renesas,i2c-r8a7792 # R-Car V2H
- renesas,i2c-r8a7793 # R-Car M2-N
- renesas,i2c-r8a7794 # R-Car E2
- const: renesas,rcar-gen2-i2c # R-Car Gen2 and RZ/G1
- items:
- enum:
- renesas,i2c-r8a774a1 # RZ/G2M
- renesas,i2c-r8a774b1 # RZ/G2N
- renesas,i2c-r8a774c0 # RZ/G2E
- renesas,i2c-r8a774e1 # RZ/G2H
- renesas,i2c-r8a7795 # R-Car H3
- renesas,i2c-r8a7796 # R-Car M3-W
- renesas,i2c-r8a77961 # R-Car M3-W+
- renesas,i2c-r8a77965 # R-Car M3-N
- renesas,i2c-r8a77970 # R-Car V3M
- renesas,i2c-r8a77980 # R-Car V3H
- renesas,i2c-r8a77990 # R-Car E3
- renesas,i2c-r8a77995 # R-Car D3
- renesas,i2c-r8a779a0 # R-Car V3U
- const: renesas,rcar-gen3-i2c # R-Car Gen3 and RZ/G2
reg:
maxItems: 1
interrupts:
maxItems: 1
clock-frequency:
description:
Desired I2C bus clock frequency in Hz. The absence of this property
indicates the default frequency 100 kHz.
clocks:
maxItems: 1
power-domains:
maxItems: 1
resets:
maxItems: 1
dmas:
minItems: 2
maxItems: 4
description:
Must contain a list of pairs of references to DMA specifiers, one for
transmission, and one for reception.
dma-names:
minItems: 2
maxItems: 4
items:
enum:
- tx
- rx
i2c-scl-falling-time-ns:
default: 35
description:
Number of nanoseconds the SCL signal takes to fall; t(f) in the I2C
specification.
i2c-scl-internal-delay-ns:
default: 50
description:
Number of nanoseconds the IP core additionally needs to setup SCL.
i2c-scl-rising-time-ns:
default: 200
description:
Number of nanoseconds the SCL signal takes to rise; t(r) in the I2C
specification.
required:
- compatible
- reg
- interrupts
- clocks
- power-domains
- '#address-cells'
- '#size-cells'
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
- if:
properties:
compatible:
contains:
enum:
- renesas,rcar-gen1-i2c
- renesas,rcar-gen2-i2c
then:
properties:
dmas: false
dma-names: false
- if:
properties:
compatible:
contains:
enum:
- renesas,rcar-gen2-i2c
- renesas,rcar-gen3-i2c
then:
required:
- resets
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/r8a7791-cpg-mssr.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/r8a7791-sysc.h>
i2c0: i2c@e6508000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c";
reg = <0xe6508000 0x40>;
interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <400000>;
clocks = <&cpg CPG_MOD 931>;
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
resets = <&cpg 931>;
i2c-scl-internal-delay-ns = <6>;
};

View File

@ -1,32 +0,0 @@
Device tree configuration for Renesas RIIC driver
Required properties:
- compatible :
"renesas,riic-r7s72100" if the device is a part of a R7S72100 SoC.
"renesas,riic-r7s9210" if the device is a part of a R7S9210 SoC.
"renesas,riic-rz" for a generic RZ/A compatible device.
- reg : address start and address range size of device
- interrupts : 8 interrupts (TEI, RI, TI, SPI, STI, NAKI, ALI, TMOI)
- clock-frequency : frequency of bus clock in Hz
- #address-cells : should be <1>
- #size-cells : should be <0>
Pinctrl properties might be needed, too. See there.
Example:
i2c0: i2c@fcfee000 {
compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
reg = <0xfcfee000 0x44>;
interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>,
<0 158 IRQ_TYPE_EDGE_RISING>,
<0 159 IRQ_TYPE_EDGE_RISING>,
<0 160 IRQ_TYPE_LEVEL_HIGH>,
<0 161 IRQ_TYPE_LEVEL_HIGH>,
<0 162 IRQ_TYPE_LEVEL_HIGH>,
<0 163 IRQ_TYPE_LEVEL_HIGH>,
<0 164 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <100000>;
#address-cells = <1>;
#size-cells = <0>;
};

View File

@ -0,0 +1,93 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/renesas,riic.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas RZ/A and RZ/G2L I2C Bus Interface (RIIC)
maintainers:
- Chris Brandt <chris.brandt@renesas.com>
- Wolfram Sang <wsa+renesas@sang-engineering.com>
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
properties:
compatible:
items:
- enum:
- renesas,riic-r7s72100 # RZ/A1H
- renesas,riic-r7s9210 # RZ/A2M
- renesas,riic-r9a07g044 # RZ/G2{L,LC}
- const: renesas,riic-rz # RZ/A or RZ/G2L
reg:
maxItems: 1
interrupts:
items:
- description: Transmit End Interrupt (TEI)
- description: Receive Data Full Interrupt (RI)
- description: Transmit Data Empty Interrupt (TI)
- description: Stop Condition Detection Interrupt (SPI)
- description: Start Condition Detection Interrupt (STI)
- description: NACK Reception Interrupt (NAKI)
- description: Arbitration-Lost Interrupt (ALI)
- description: Timeout Interrupt (TMOI)
clock-frequency:
description:
Desired I2C bus clock frequency in Hz. The absence of this property
indicates the default frequency 100 kHz.
clocks:
maxItems: 1
power-domains:
maxItems: 1
required:
- compatible
- reg
- interrupts
- clocks
- clock-frequency
- power-domains
- '#address-cells'
- '#size-cells'
if:
properties:
compatible:
contains:
enum:
- renesas,riic-r9a07g044
then:
required:
- resets
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/r7s72100-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
i2c0: i2c@fcfee000 {
compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
reg = <0xfcfee000 0x44>;
interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 158 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 159 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp9_clks R7S72100_CLK_I2C0>;
clock-frequency = <100000>;
power-domains = <&cpg_clocks>;
#address-cells = <1>;
#size-cells = <0>;
};

View File

@ -0,0 +1,149 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/renesas,rmobile-iic.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas R-Mobile I2C Bus Interface (IIC)
maintainers:
- Wolfram Sang <wsa+renesas@sang-engineering.com>
properties:
compatible:
oneOf:
- items:
- enum:
- renesas,iic-r8a73a4 # R-Mobile APE6
- renesas,iic-r8a7740 # R-Mobile A1
- renesas,iic-sh73a0 # SH-Mobile AG5
- const: renesas,rmobile-iic # Generic
- items:
- enum:
- renesas,iic-r8a7742 # RZ/G1H
- renesas,iic-r8a7743 # RZ/G1M
- renesas,iic-r8a7744 # RZ/G1N
- renesas,iic-r8a7745 # RZ/G1E
- renesas,iic-r8a7790 # R-Car H2
- renesas,iic-r8a7791 # R-Car M2-W
- renesas,iic-r8a7792 # R-Car V2H
- renesas,iic-r8a7793 # R-Car M2-N
- renesas,iic-r8a7794 # R-Car E2
- const: renesas,rcar-gen2-iic # R-Car Gen2 and RZ/G1
- const: renesas,rmobile-iic # Generic
- items:
- enum:
- renesas,iic-r8a774a1 # RZ/G2M
- renesas,iic-r8a774b1 # RZ/G2N
- renesas,iic-r8a774c0 # RZ/G2E
- renesas,iic-r8a774e1 # RZ/G2H
- renesas,iic-r8a7795 # R-Car H3
- renesas,iic-r8a7796 # R-Car M3-W
- renesas,iic-r8a77961 # R-Car M3-W+
- renesas,iic-r8a77965 # R-Car M3-N
- renesas,iic-r8a77990 # R-Car E3
- const: renesas,rcar-gen3-iic # R-Car Gen3 and RZ/G2
- const: renesas,rmobile-iic # Generic
reg:
maxItems: 1
interrupts: true
clock-frequency:
description:
Desired I2C bus clock frequency in Hz. The absence of this property
indicates the default frequency 100 kHz.
clocks:
maxItems: 1
power-domains:
maxItems: 1
resets:
maxItems: 1
dmas:
minItems: 2
maxItems: 4
description:
Must contain a list of pairs of references to DMA specifiers, one for
transmission, and one for reception.
dma-names:
minItems: 2
maxItems: 4
items:
enum:
- tx
- rx
required:
- compatible
- reg
- interrupts
- clocks
- power-domains
- '#address-cells'
- '#size-cells'
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
- if:
properties:
compatible:
contains:
enum:
- renesas,iic-r8a7740
- renesas,iic-sh73a0
then:
properties:
interrupts:
items:
- description: Arbitration Lost Interrupt (ALI)
- description: Non-acknowledge Detection Interrupt (TACKI)
- description: Wait Interrupt (WAITI)
- description: Data Transmit Enable interrupt (DTEI)
else:
properties:
interrupts:
items:
- description: Single combined interrupt
- if:
properties:
compatible:
contains:
enum:
- renesas,rcar-gen2-iic
- renesas,rcar-gen3-iic
then:
required:
- resets
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/r8a7790-cpg-mssr.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/r8a7790-sysc.h>
iic0: i2c@e6500000 {
compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic",
"renesas,rmobile-iic";
reg = <0xe6500000 0x425>;
interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 318>;
clock-frequency = <400000>;
dmas = <&dmac0 0x61>, <&dmac0 0x62>, <&dmac1 0x61>, <&dmac1 0x62>;
dma-names = "tx", "rx", "tx", "rx";
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
resets = <&cpg 318>;
#address-cells = <1>;
#size-cells = <0>;
};

View File

@ -0,0 +1,102 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/ti,omap4-i2c.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Bindings for I2C controllers on TI's OMAP and K3 SoCs
maintainers:
- Vignesh Raghavendra <vigneshr@ti.com>
properties:
compatible:
oneOf:
- enum:
- ti,omap2420-i2c
- ti,omap2430-i2c
- ti,omap3-i2c
- ti,omap4-i2c
- items:
- enum:
- ti,am4372-i2c
- ti,am64-i2c
- ti,am654-i2c
- ti,j721e-i2c
- const: ti,omap4-i2c
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
clock-names:
const: fck
clock-frequency: true
power-domains: true
"#address-cells":
const: 1
"#size-cells":
const: 0
ti,hwmods:
description:
Must be "i2c<n>", n being the instance number (1-based).
This property is applicable only on legacy platforms mainly omap2/3
and ti81xx and should not be used on other platforms.
$ref: /schemas/types.yaml#/definitions/string
deprecated: true
# subnode's properties
patternProperties:
"@[0-9a-f]+$":
type: object
description:
Flash device uses the below defined properties in the subnode.
required:
- compatible
- reg
- interrupts
additionalProperties: false
if:
properties:
compatible:
oneOf:
- const: ti,omap2420-i2c
- const: ti,omap2430-i2c
- const: ti,omap3-i2c
- const: ti,omap4-i2c
then:
properties:
ti,hwmods:
items:
- pattern: "^i2c([1-9])$"
else:
properties:
ti,hwmods: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
main_i2c0: i2c@2000000 {
compatible = "ti,j721e-i2c", "ti,omap4-i2c";
reg = <0x2000000 0x100>;
interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
};

View File

@ -0,0 +1,395 @@
.. SPDX-License-Identifier: GPL-2.0
===============
Linux I2C Sysfs
===============
Overview
========
I2C topology can be complex because of the existence of I2C MUX
(I2C Multiplexer). The Linux
kernel abstracts the MUX channels into logical I2C bus numbers. However, there
is a gap of knowledge to map from the I2C bus physical number and MUX topology
to logical I2C bus number. This doc is aimed to fill in this gap, so the
audience (hardware engineers and new software developers for example) can learn
the concept of logical I2C buses in the kernel, by knowing the physical I2C
topology and navigating through the I2C sysfs in Linux shell. This knowledge is
useful and essential to use ``i2c-tools`` for the purpose of development and
debugging.
Target audience
---------------
People who need to use Linux shell to interact with I2C subsystem on a system
which the Linux is running on.
Prerequisites
-------------
1. Knowledge of general Linux shell file system commands and operations.
2. General knowledge of I2C, I2C MUX and I2C topology.
Location of I2C Sysfs
=====================
Typically, the Linux Sysfs filesystem is mounted at the ``/sys`` directory,
so you can find the I2C Sysfs under ``/sys/bus/i2c/devices``
where you can directly ``cd`` to it.
There is a list of symbolic links under that directory. The links that
start with ``i2c-`` are I2C buses, which may be either physical or logical. The
other links that begin with numbers and end with numbers are I2C devices, where
the first number is I2C bus number, and the second number is I2C address.
Google Pixel 3 phone for example::
blueline:/sys/bus/i2c/devices $ ls
0-0008 0-0061 1-0028 3-0043 4-0036 4-0041 i2c-1 i2c-3
0-000c 0-0066 2-0049 4-000b 4-0040 i2c-0 i2c-2 i2c-4
``i2c-2`` is an I2C bus whose number is 2, and ``2-0049`` is an I2C device
on bus 2 address 0x49 bound with a kernel driver.
Terminologies
=============
First, let us define a couple of terminologies to avoid confusions in the later
sections.
(Physical) I2C Bus Controller
-----------------------------
The hardware system that the Linux kernel is running on may have multiple
physical I2C bus controllers. The controllers are hardware and physical, and the
system may define multiple registers in the memory space to manipulate the
controllers. Linux kernel has I2C bus drivers under source directory
``drivers/i2c/busses`` to translate kernel I2C API into register
operations for different systems. This terminology is not limited to Linux
kernel only.
I2C Bus Physical Number
-----------------------
For each physical I2C bus controller, the system vendor may assign a physical
number to each controller. For example, the first I2C bus controller which has
the lowest register addresses may be called ``I2C-0``.
Logical I2C Bus
---------------
Every I2C bus number you see in Linux I2C Sysfs is a logical I2C bus with a
number assigned. This is similar to the fact that software code is usually
written upon virtual memory space, instead of physical memory space.
Each logical I2C bus may be an abstraction of a physical I2C bus controller, or
an abstraction of a channel behind an I2C MUX. In case it is an abstraction of a
MUX channel, whenever we access an I2C device via a such logical bus, the kernel
will switch the I2C MUX for you to the proper channel as part of the
abstraction.
Physical I2C Bus
----------------
If the logical I2C bus is a direct abstraction of a physical I2C bus controller,
let us call it a physical I2C bus.
Caveat
------
This may be a confusing part for people who only know about the physical I2C
design of a board. It is actually possible to rename the I2C bus physical number
to a different number in logical I2C bus level in Device Tree Source (DTS) under
section ``aliases``. See
`arch/arm/boot/dts/nuvoton-npcm730-gsj.dts
<../../arch/arm/boot/dts/nuvoton-npcm730-gsj.dts>`_
for an example of DTS file.
Best Practice: **(To kernel software developers)** It is better to keep the I2C
bus physical number the same as their corresponding logical I2C bus number,
instead of renaming or mapping them, so that it may be less confusing to other
users. These physical I2C buses can be served as good starting points for I2C
MUX fanouts. For the following examples, we will assume that the physical I2C
bus has a number same as their I2C bus physical number.
Walk through Logical I2C Bus
============================
For the following content, we will use a more complex I2C topology as an
example. Here is a brief graph for the I2C topology. If you do not understand
this graph at the first glance, do not be afraid to continue reading this doc
and review it when you finish reading.
::
i2c-7 (physical I2C bus controller 7)
`-- 7-0071 (4-channel I2C MUX at 0x71)
|-- i2c-60 (channel-0)
|-- i2c-73 (channel-1)
| |-- 73-0040 (I2C sensor device with hwmon directory)
| |-- 73-0070 (I2C MUX at 0x70, exists in DTS, but failed to probe)
| `-- 73-0072 (8-channel I2C MUX at 0x72)
| |-- i2c-78 (channel-0)
| |-- ... (channel-1...6, i2c-79...i2c-84)
| `-- i2c-85 (channel-7)
|-- i2c-86 (channel-2)
`-- i2c-203 (channel-3)
Distinguish Physical and Logical I2C Bus
----------------------------------------
One simple way to distinguish between a physical I2C bus and a logical I2C bus,
is to read the symbolic link ``device`` under the I2C bus directory by using
command ``ls -l`` or ``readlink``.
An alternative symbolic link to check is ``mux_device``. This link only exists
in logical I2C bus directory which is fanned out from another I2C bus.
Reading this link will also tell you which I2C MUX device created
this logical I2C bus.
If the symbolic link points to a directory ending with ``.i2c``, it should be a
physical I2C bus, directly abstracting a physical I2C bus controller. For
example::
$ readlink /sys/bus/i2c/devices/i2c-7/device
../../f0087000.i2c
$ ls /sys/bus/i2c/devices/i2c-7/mux_device
ls: /sys/bus/i2c/devices/i2c-7/mux_device: No such file or directory
In this case, ``i2c-7`` is a physical I2C bus, so it does not have the symbolic
link ``mux_device`` under its directory. And if the kernel software developer
follows the common practice by not renaming physical I2C buses, this should also
mean the physical I2C bus controller 7 of the system.
On the other hand, if the symbolic link points to another I2C bus, the I2C bus
presented by the current directory has to be a logical bus. The I2C bus pointed
by the link is the parent bus which may be either a physical I2C bus or a
logical one. In this case, the I2C bus presented by the current directory
abstracts an I2C MUX channel under the parent bus.
For example::
$ readlink /sys/bus/i2c/devices/i2c-73/device
../../i2c-7
$ readlink /sys/bus/i2c/devices/i2c-73/mux_device
../7-0071
``i2c-73`` is a logical bus fanout by an I2C MUX under ``i2c-7``
whose I2C address is 0x71.
Whenever we access an I2C device with bus 73, the kernel will always
switch the I2C MUX addressed 0x71 to the proper channel for you as part of the
abstraction.
Finding out Logical I2C Bus Number
----------------------------------
In this section, we will describe how to find out the logical I2C bus number
representing certain I2C MUX channels based on the knowledge of physical
hardware I2C topology.
In this example, we have a system which has a physical I2C bus 7 and not renamed
in DTS. There is a 4-channel MUX at address 0x71 on that bus. There is another
8-channel MUX at address 0x72 behind the channel 1 of the 0x71 MUX. Let us
navigate through Sysfs and find out the logical I2C bus number of the channel 3
of the 0x72 MUX.
First of all, let us go to the directory of ``i2c-7``::
~$ cd /sys/bus/i2c/devices/i2c-7
/sys/bus/i2c/devices/i2c-7$ ls
7-0071 i2c-60 name subsystem
delete_device i2c-73 new_device uevent
device i2c-86 of_node
i2c-203 i2c-dev power
There, we see the 0x71 MUX as ``7-0071``. Go inside it::
/sys/bus/i2c/devices/i2c-7$ cd 7-0071/
/sys/bus/i2c/devices/i2c-7/7-0071$ ls -l
channel-0 channel-3 modalias power
channel-1 driver name subsystem
channel-2 idle_state of_node uevent
Read the link ``channel-1`` using ``readlink`` or ``ls -l``::
/sys/bus/i2c/devices/i2c-7/7-0071$ readlink channel-1
../i2c-73
We find out that the channel 1 of 0x71 MUX on ``i2c-7`` is assigned
with a logical I2C bus number of 73.
Let us continue the journey to directory ``i2c-73`` in either ways::
# cd to i2c-73 under I2C Sysfs root
/sys/bus/i2c/devices/i2c-7/7-0071$ cd /sys/bus/i2c/devices/i2c-73
/sys/bus/i2c/devices/i2c-73$
# cd the channel symbolic link
/sys/bus/i2c/devices/i2c-7/7-0071$ cd channel-1
/sys/bus/i2c/devices/i2c-7/7-0071/channel-1$
# cd the link content
/sys/bus/i2c/devices/i2c-7/7-0071$ cd ../i2c-73
/sys/bus/i2c/devices/i2c-7/i2c-73$
Either ways, you will end up in the directory of ``i2c-73``. Similar to above,
we can now find the 0x72 MUX and what logical I2C bus numbers
that its channels are assigned::
/sys/bus/i2c/devices/i2c-73$ ls
73-0040 device i2c-83 new_device
73-004e i2c-78 i2c-84 of_node
73-0050 i2c-79 i2c-85 power
73-0070 i2c-80 i2c-dev subsystem
73-0072 i2c-81 mux_device uevent
delete_device i2c-82 name
/sys/bus/i2c/devices/i2c-73$ cd 73-0072
/sys/bus/i2c/devices/i2c-73/73-0072$ ls
channel-0 channel-4 driver of_node
channel-1 channel-5 idle_state power
channel-2 channel-6 modalias subsystem
channel-3 channel-7 name uevent
/sys/bus/i2c/devices/i2c-73/73-0072$ readlink channel-3
../i2c-81
There, we find out the logical I2C bus number of the channel 3 of the 0x72 MUX
is 81. We can later use this number to switch to its own I2C Sysfs directory or
issue ``i2c-tools`` commands.
Tip: Once you understand the I2C topology with MUX, command
`i2cdetect -l
<https://manpages.debian.org/unstable/i2c-tools/i2cdetect.8.en.html>`_
in
`I2C Tools
<https://i2c.wiki.kernel.org/index.php/I2C_Tools>`_
can give you
an overview of the I2C topology easily, if it is available on your system. For
example::
$ i2cdetect -l | grep -e '\-73' -e _7 | sort -V
i2c-7 i2c npcm_i2c_7 I2C adapter
i2c-73 i2c i2c-7-mux (chan_id 1) I2C adapter
i2c-78 i2c i2c-73-mux (chan_id 0) I2C adapter
i2c-79 i2c i2c-73-mux (chan_id 1) I2C adapter
i2c-80 i2c i2c-73-mux (chan_id 2) I2C adapter
i2c-81 i2c i2c-73-mux (chan_id 3) I2C adapter
i2c-82 i2c i2c-73-mux (chan_id 4) I2C adapter
i2c-83 i2c i2c-73-mux (chan_id 5) I2C adapter
i2c-84 i2c i2c-73-mux (chan_id 6) I2C adapter
i2c-85 i2c i2c-73-mux (chan_id 7) I2C adapter
Pinned Logical I2C Bus Number
-----------------------------
If not specified in DTS, when an I2C MUX driver is applied and the MUX device is
successfully probed, the kernel will assign the MUX channels with a logical bus
number based on the current biggest logical bus number incrementally. For
example, if the system has ``i2c-15`` as the highest logical bus number, and a
4-channel MUX is applied successfully, we will have ``i2c-16`` for the
MUX channel 0, and all the way to ``i2c-19`` for the MUX channel 3.
The kernel software developer is able to pin the fanout MUX channels to a static
logical I2C bus number in the DTS. This doc will not go through the details on
how to implement this in DTS, but we can see an example in:
`arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts
<../../arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts>`_
In the above example, there is an 8-channel I2C MUX at address 0x70 on physical
I2C bus 2. The channel 2 of the MUX is defined as ``imux18`` in DTS,
and pinned to logical I2C bus number 18 with the line of ``i2c18 = &imux18;``
in section ``aliases``.
Take it further, it is possible to design a logical I2C bus number schema that
can be easily remembered by humans or calculated arithmetically. For example, we
can pin the fanout channels of a MUX on bus 3 to start at 30. So 30 will be the
logical bus number of the channel 0 of the MUX on bus 3, and 37 will be the
logical bus number of the channel 7 of the MUX on bus 3.
I2C Devices
===========
In previous sections, we mostly covered the I2C bus. In this section, let us see
what we can learn from the I2C device directory whose link name is in the format
of ``${bus}-${addr}``. The ``${bus}`` part in the name is a logical I2C bus
decimal number, while the ``${addr}`` part is a hex number of the I2C address
of each device.
I2C Device Directory Content
----------------------------
Inside each I2C device directory, there is a file named ``name``.
This file tells what device name it was used for the kernel driver to
probe this device. Use command ``cat`` to read its content. For example::
/sys/bus/i2c/devices/i2c-73$ cat 73-0040/name
ina230
/sys/bus/i2c/devices/i2c-73$ cat 73-0070/name
pca9546
/sys/bus/i2c/devices/i2c-73$ cat 73-0072/name
pca9547
There is a symbolic link named ``driver`` to tell what Linux kernel driver was
used to probe this device::
/sys/bus/i2c/devices/i2c-73$ readlink -f 73-0040/driver
/sys/bus/i2c/drivers/ina2xx
/sys/bus/i2c/devices/i2c-73$ readlink -f 73-0072/driver
/sys/bus/i2c/drivers/pca954x
But if the link ``driver`` does not exist at the first place,
it may mean that the kernel driver failed to probe this device due to
some errors. The error may be found in ``dmesg``::
/sys/bus/i2c/devices/i2c-73$ ls 73-0070/driver
ls: 73-0070/driver: No such file or directory
/sys/bus/i2c/devices/i2c-73$ dmesg | grep 73-0070
pca954x 73-0070: probe failed
pca954x 73-0070: probe failed
Depending on what the I2C device is and what kernel driver was used to probe the
device, we may have different content in the device directory.
I2C MUX Device
--------------
While you may be already aware of this in previous sections, an I2C MUX device
will have symbolic link ``channel-*`` inside its device directory.
These symbolic links point to their logical I2C bus directories::
/sys/bus/i2c/devices/i2c-73$ ls -l 73-0072/channel-*
lrwxrwxrwx ... 73-0072/channel-0 -> ../i2c-78
lrwxrwxrwx ... 73-0072/channel-1 -> ../i2c-79
lrwxrwxrwx ... 73-0072/channel-2 -> ../i2c-80
lrwxrwxrwx ... 73-0072/channel-3 -> ../i2c-81
lrwxrwxrwx ... 73-0072/channel-4 -> ../i2c-82
lrwxrwxrwx ... 73-0072/channel-5 -> ../i2c-83
lrwxrwxrwx ... 73-0072/channel-6 -> ../i2c-84
lrwxrwxrwx ... 73-0072/channel-7 -> ../i2c-85
I2C Sensor Device / Hwmon
-------------------------
I2C sensor device is also common to see. If they are bound by a kernel hwmon
(Hardware Monitoring) driver successfully, you will see a ``hwmon`` directory
inside the I2C device directory. Keep digging into it, you will find the Hwmon
Sysfs for the I2C sensor device::
/sys/bus/i2c/devices/i2c-73/73-0040/hwmon/hwmon17$ ls
curr1_input in0_lcrit_alarm name subsystem
device in1_crit power uevent
in0_crit in1_crit_alarm power1_crit update_interval
in0_crit_alarm in1_input power1_crit_alarm
in0_input in1_lcrit power1_input
in0_lcrit in1_lcrit_alarm shunt_resistor
For more info on the Hwmon Sysfs, refer to the doc:
`Naming and data format standards for sysfs files
<../hwmon/sysfs-interface.rst>`_
Instantiate I2C Devices in I2C Sysfs
------------------------------------
Refer to the doc:
`How to instantiate I2C devices, Method 4: Instantiate from user-space
<instantiating-devices.rst#method-4-instantiate-from-user-space>`_

View File

@ -13494,7 +13494,7 @@ M: Vignesh R <vigneshr@ti.com>
L: linux-omap@vger.kernel.org
L: linux-i2c@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/i2c/i2c-omap.txt
F: Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml
F: drivers/i2c/busses/i2c-omap.c
OMAP IMAGING SUBSYSTEM (OMAP3 ISP and OMAP4 ISS)
@ -15722,8 +15722,9 @@ F: drivers/clk/renesas/
RENESAS EMEV2 I2C DRIVER
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
L: linux-renesas-soc@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt
F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml
F: drivers/i2c/busses/i2c-emev2.c
RENESAS ETHERNET DRIVERS
@ -15743,9 +15744,10 @@ F: drivers/iio/adc/rcar-gyroadc.c
RENESAS R-CAR I2C DRIVERS
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
L: linux-renesas-soc@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/i2c/renesas,i2c.txt
F: Documentation/devicetree/bindings/i2c/renesas,iic.txt
F: Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml
F: Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml
F: drivers/i2c/busses/i2c-rcar.c
F: drivers/i2c/busses/i2c-sh_mobile.c
@ -15760,8 +15762,9 @@ F: drivers/thermal/rcar_thermal.c
RENESAS RIIC DRIVER
M: Chris Brandt <chris.brandt@renesas.com>
L: linux-renesas-soc@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/i2c/renesas,riic.txt
F: Documentation/devicetree/bindings/i2c/renesas,riic.yaml
F: drivers/i2c/busses/i2c-riic.c
RENESAS USB PHY DRIVER

View File

@ -508,6 +508,11 @@ static void ali1535_remove(struct pci_dev *dev)
{
i2c_del_adapter(&ali1535_adapter);
release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
/*
* do not call pci_disable_device(dev) since it can cause hard hangs on
* some systems during power-off
*/
}
static struct pci_driver ali1535_driver = {

View File

@ -727,10 +727,14 @@ static void __aspeed_i2c_reg_slave(struct aspeed_i2c_bus *bus, u16 slave_addr)
{
u32 addr_reg_val, func_ctrl_reg_val;
/* Set slave addr. */
addr_reg_val = readl(bus->base + ASPEED_I2C_DEV_ADDR_REG);
addr_reg_val &= ~ASPEED_I2CD_DEV_ADDR_MASK;
addr_reg_val |= slave_addr & ASPEED_I2CD_DEV_ADDR_MASK;
/*
* Set slave addr. Reserved bits can all safely be written with zeros
* on all of ast2[456]00, so zero everything else to ensure we only
* enable a single slave address (ast2500 has two, ast2600 has three,
* the enable bits for which are also in this register) so that we don't
* end up with additional phantom devices responding on the bus.
*/
addr_reg_val = slave_addr & ASPEED_I2CD_DEV_ADDR_MASK;
writel(addr_reg_val, bus->base + ASPEED_I2C_DEV_ADDR_REG);
/* Turn on slave mode. */

View File

@ -578,6 +578,11 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
{
unsigned int ctrl_reg;
unsigned int isr_status;
unsigned long flags;
bool hold_clear = false;
bool irq_save = false;
u32 addr;
id->p_recv_buf = id->p_msg->buf;
id->recv_count = id->p_msg->len;
@ -618,14 +623,43 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET);
}
/* Set the slave address in address register - triggers operation */
cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK,
CDNS_I2C_ADDR_OFFSET);
/* Clear the bus hold flag if bytes to receive is less than FIFO size */
/* Determine hold_clear based on number of bytes to receive and hold flag */
if (!id->bus_hold_flag &&
((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) &&
(id->recv_count <= CDNS_I2C_FIFO_DEPTH))
cdns_i2c_clear_bus_hold(id);
((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) &&
(id->recv_count <= CDNS_I2C_FIFO_DEPTH)) {
if (cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & CDNS_I2C_CR_HOLD) {
hold_clear = true;
if (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT)
irq_save = true;
}
}
addr = id->p_msg->addr;
addr &= CDNS_I2C_ADDR_MASK;
if (hold_clear) {
ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & ~CDNS_I2C_CR_HOLD;
/*
* In case of Xilinx Zynq SOC, clear the HOLD bit before transfer size
* register reaches '0'. This is an IP bug which causes transfer size
* register overflow to 0xFF. To satisfy this timing requirement,
* disable the interrupts on current processor core between register
* writes to slave address register and control register.
*/
if (irq_save)
local_irq_save(flags);
cdns_i2c_writereg(addr, CDNS_I2C_ADDR_OFFSET);
cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);
/* Read it back to avoid bufferring and make sure write happens */
cdns_i2c_readreg(CDNS_I2C_CR_OFFSET);
if (irq_save)
local_irq_restore(flags);
} else {
cdns_i2c_writereg(addr, CDNS_I2C_ADDR_OFFSET);
}
cdns_i2c_writereg(CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET);
}
@ -1217,11 +1251,10 @@ static int cdns_i2c_probe(struct platform_device *pdev)
"Cadence I2C at %08lx", (unsigned long)r_mem->start);
id->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(id->clk)) {
if (PTR_ERR(id->clk) != -EPROBE_DEFER)
dev_err(&pdev->dev, "input clock not found.\n");
return PTR_ERR(id->clk);
}
if (IS_ERR(id->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(id->clk),
"input clock not found.\n");
ret = clk_prepare_enable(id->clk);
if (ret)
dev_err(&pdev->dev, "Unable to enable clock.\n");

View File

@ -354,8 +354,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
return ret;
/* Alloc and register client IRQ */
adap->irq_domain = irq_domain_add_linear(pdev->dev.of_node, 1,
&irq_domain_simple_ops, NULL);
adap->irq_domain = irq_domain_add_linear(NULL, 1, &irq_domain_simple_ops, NULL);
if (!adap->irq_domain)
return -ENOMEM;

View File

@ -768,10 +768,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
if (irq <= 0) {
if (!irq)
irq = -ENXIO;
if (irq != -EPROBE_DEFER)
dev_err(&pdev->dev,
"can't get irq resource ret=%d\n", irq);
return irq;
return dev_err_probe(&pdev->dev, irq, "can't get irq resource\n");
}
dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev),

View File

@ -88,6 +88,8 @@
* See the file Documentation/i2c/busses/i2c-i801.rst for details.
*/
#define DRV_NAME "i801_smbus"
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
@ -103,7 +105,7 @@
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/platform_data/itco_wdt.h>
@ -131,8 +133,6 @@
/* PCI Address Constants */
#define SMBBAR 4
#define SMBPCICTL 0x004
#define SMBPCISTS 0x006
#define SMBHSTCFG 0x040
#define TCOBASE 0x050
#define TCOCTL 0x054
@ -141,12 +141,6 @@
#define SBREG_SMBCTRL 0xc6000c
#define SBREG_SMBCTRL_DNV 0xcf000c
/* Host status bits for SMBPCISTS */
#define SMBPCISTS_INTS BIT(3)
/* Control bits for SMBPCICTL */
#define SMBPCICTL_INTDIS BIT(10)
/* Host configuration bits for SMBHSTCFG */
#define SMBHSTCFG_HST_EN BIT(0)
#define SMBHSTCFG_SMB_SMI_EN BIT(1)
@ -164,9 +158,6 @@
#define SMBAUXCTL_CRC BIT(0)
#define SMBAUXCTL_E32B BIT(1)
/* Other settings */
#define MAX_RETRIES 400
/* I801 command constants */
#define I801_QUICK 0x00
#define I801_BYTE 0x04
@ -270,7 +261,7 @@ struct i801_priv {
unsigned int features;
/* isr processing */
wait_queue_head_t waitq;
struct completion done;
u8 status;
/* Command state used by isr for byte-by-byte block transactions */
@ -453,67 +444,53 @@ static int i801_check_post(struct i801_priv *priv, int status)
/* Wait for BUSY being cleared and either INTR or an error flag being set */
static int i801_wait_intr(struct i801_priv *priv)
{
int timeout = 0;
int status;
unsigned long timeout = jiffies + priv->adapter.timeout;
int status, busy;
/* We will always wait for a fraction of a second! */
do {
usleep_range(250, 500);
status = inb_p(SMBHSTSTS(priv));
} while (((status & SMBHSTSTS_HOST_BUSY) ||
!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) &&
(timeout++ < MAX_RETRIES));
busy = status & SMBHSTSTS_HOST_BUSY;
status &= STATUS_ERROR_FLAGS | SMBHSTSTS_INTR;
if (!busy && status)
return status;
} while (time_is_after_eq_jiffies(timeout));
if (timeout > MAX_RETRIES) {
dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n");
return -ETIMEDOUT;
}
return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR);
return -ETIMEDOUT;
}
/* Wait for either BYTE_DONE or an error flag being set */
static int i801_wait_byte_done(struct i801_priv *priv)
{
int timeout = 0;
unsigned long timeout = jiffies + priv->adapter.timeout;
int status;
/* We will always wait for a fraction of a second! */
do {
usleep_range(250, 500);
status = inb_p(SMBHSTSTS(priv));
} while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) &&
(timeout++ < MAX_RETRIES));
if (status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE))
return status & STATUS_ERROR_FLAGS;
} while (time_is_after_eq_jiffies(timeout));
if (timeout > MAX_RETRIES) {
dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n");
return -ETIMEDOUT;
}
return status & STATUS_ERROR_FLAGS;
return -ETIMEDOUT;
}
static int i801_transaction(struct i801_priv *priv, int xact)
{
int status;
int result;
unsigned long result;
const struct i2c_adapter *adap = &priv->adapter;
result = i801_check_pre(priv);
if (result < 0)
return result;
status = i801_check_pre(priv);
if (status < 0)
return status;
if (priv->features & FEATURE_IRQ) {
reinit_completion(&priv->done);
outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
SMBHSTCNT(priv));
result = wait_event_timeout(priv->waitq,
(status = priv->status),
adap->timeout);
if (!result) {
status = -ETIMEDOUT;
dev_warn(&priv->pci_dev->dev,
"Timeout waiting for interrupt!\n");
}
priv->status = 0;
return i801_check_post(priv, status);
result = wait_for_completion_timeout(&priv->done, adap->timeout);
return i801_check_post(priv, result ? priv->status : -ETIMEDOUT);
}
/* the current contents of SMBHSTCNT can be overwritten, since PEC,
@ -638,7 +615,7 @@ static irqreturn_t i801_host_notify_isr(struct i801_priv *priv)
* DEV_ERR - Invalid command, NAK or communication timeout
* BUS_ERR - SMI# transaction collision
* FAILED - transaction was canceled due to a KILL request
* When any of these occur, update ->status and wake up the waitq.
* When any of these occur, update ->status and signal completion.
* ->status must be cleared before kicking off the next transaction.
*
* 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt
@ -653,8 +630,8 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
u8 status;
/* Confirm this is our interrupt */
pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists);
if (!(pcists & SMBPCISTS_INTS))
pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists);
if (!(pcists & PCI_STATUS_INTERRUPT))
return IRQ_NONE;
if (priv->features & FEATURE_HOST_NOTIFY) {
@ -675,7 +652,7 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
if (status) {
outb_p(status, SMBHSTSTS(priv));
priv->status = status;
wake_up(&priv->waitq);
complete(&priv->done);
}
return IRQ_HANDLED;
@ -694,15 +671,15 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
int i, len;
int smbcmd;
int status;
int result;
unsigned long result;
const struct i2c_adapter *adap = &priv->adapter;
if (command == I2C_SMBUS_BLOCK_PROC_CALL)
return -EOPNOTSUPP;
result = i801_check_pre(priv);
if (result < 0)
return result;
status = i801_check_pre(priv);
if (status < 0)
return status;
len = data->block[0];
@ -726,17 +703,10 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
priv->count = 0;
priv->data = &data->block[1];
reinit_completion(&priv->done);
outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv));
result = wait_event_timeout(priv->waitq,
(status = priv->status),
adap->timeout);
if (!result) {
status = -ETIMEDOUT;
dev_warn(&priv->pci_dev->dev,
"Timeout waiting for interrupt!\n");
}
priv->status = 0;
return i801_check_post(priv, status);
result = wait_for_completion_timeout(&priv->done, adap->timeout);
return i801_check_post(priv, result ? priv->status : -ETIMEDOUT);
}
for (i = 1; i <= len; i++) {
@ -1322,11 +1292,11 @@ static void i801_probe_optional_slaves(struct i801_priv *priv)
return;
if (apanel_addr) {
struct i2c_board_info info;
struct i2c_board_info info = {
.addr = apanel_addr,
.type = "fujitsu_apanel",
};
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = apanel_addr;
strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
i2c_new_client_device(&priv->adapter, &info);
}
@ -1715,19 +1685,17 @@ static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; }
static inline void i801_acpi_remove(struct i801_priv *priv) { }
#endif
static unsigned char i801_setup_hstcfg(struct i801_priv *priv)
static void i801_setup_hstcfg(struct i801_priv *priv)
{
unsigned char hstcfg = priv->original_hstcfg;
hstcfg &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
hstcfg |= SMBHSTCFG_HST_EN;
pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hstcfg);
return hstcfg;
}
static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
unsigned char temp;
int err, i;
struct i801_priv *priv;
@ -1838,8 +1806,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (i801_acpi_probe(priv))
return -ENODEV;
err = pcim_iomap_regions(dev, 1 << SMBBAR,
dev_driver_string(&dev->dev));
err = pcim_iomap_regions(dev, 1 << SMBBAR, DRV_NAME);
if (err) {
dev_err(&dev->dev,
"Failed to request SMBus region 0x%lx-0x%Lx\n",
@ -1850,16 +1817,16 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
}
pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &priv->original_hstcfg);
temp = i801_setup_hstcfg(priv);
i801_setup_hstcfg(priv);
if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN))
dev_info(&dev->dev, "Enabling SMBus device\n");
if (temp & SMBHSTCFG_SMB_SMI_EN) {
if (priv->original_hstcfg & SMBHSTCFG_SMB_SMI_EN) {
dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
/* Disable SMBus interrupt feature if SMBus using SMI# */
priv->features &= ~FEATURE_IRQ;
}
if (temp & SMBHSTCFG_SPD_WD)
if (priv->original_hstcfg & SMBHSTCFG_SPD_WD)
dev_info(&dev->dev, "SPD Write Disable is set\n");
/* Clear special mode bits */
@ -1881,24 +1848,23 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
u16 pcictl, pcists;
/* Complain if an interrupt is already pending */
pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists);
if (pcists & SMBPCISTS_INTS)
pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists);
if (pcists & PCI_STATUS_INTERRUPT)
dev_warn(&dev->dev, "An interrupt is pending!\n");
/* Check if interrupts have been disabled */
pci_read_config_word(priv->pci_dev, SMBPCICTL, &pcictl);
if (pcictl & SMBPCICTL_INTDIS) {
pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pcictl);
if (pcictl & PCI_COMMAND_INTX_DISABLE) {
dev_info(&dev->dev, "Interrupts are disabled\n");
priv->features &= ~FEATURE_IRQ;
}
}
if (priv->features & FEATURE_IRQ) {
init_waitqueue_head(&priv->waitq);
init_completion(&priv->done);
err = devm_request_irq(&dev->dev, dev->irq, i801_isr,
IRQF_SHARED,
dev_driver_string(&dev->dev), priv);
IRQF_SHARED, DRV_NAME, priv);
if (err) {
dev_err(&dev->dev, "Failed to allocate irq %d: %d\n",
dev->irq, err);
@ -1988,7 +1954,7 @@ static int i801_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(i801_pm_ops, i801_suspend, i801_resume);
static struct pci_driver i801_driver = {
.name = "i801_smbus",
.name = DRV_NAME,
.id_table = i801_ids,
.probe = i801_probe,
.remove = i801_remove,

View File

@ -170,11 +170,11 @@ enum imx_i2c_type {
struct imx_i2c_hwdata {
enum imx_i2c_type devtype;
unsigned regshift;
unsigned int regshift;
struct imx_i2c_clk_pair *clk_div;
unsigned ndivs;
unsigned i2sr_clr_opcode;
unsigned i2cr_ien_opcode;
unsigned int ndivs;
unsigned int i2sr_clr_opcode;
unsigned int i2cr_ien_opcode;
};
struct imx_i2c_dma {
@ -452,8 +452,6 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a
unsigned long orig_jiffies = jiffies;
unsigned int temp;
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
while (1) {
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
@ -599,8 +597,6 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx, bool atomic)
unsigned int temp = 0;
int result;
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR);
/* Enable I2C controller */
imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
@ -635,7 +631,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx, bool atomic)
if (!i2c_imx->stopped) {
/* Stop I2C transaction */
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
if (!(temp & I2CR_MSTA))
i2c_imx->stopped = 1;
@ -1167,8 +1162,6 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
bool is_lastmsg = false;
struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
/* Start I2C transfer */
result = i2c_imx_start(i2c_imx, atomic);
if (result) {
@ -1371,8 +1364,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
dma_addr_t phy_addr;
const struct imx_i2c_hwdata *match;
dev_dbg(&pdev->dev, "<%s>\n", __func__);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
@ -1395,7 +1386,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
platform_get_device_id(pdev)->driver_data;
/* Setup i2c_imx driver structure */
strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
strscpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
i2c_imx->adapter.owner = THIS_MODULE;
i2c_imx->adapter.algo = &i2c_imx_algo;
i2c_imx->adapter.dev.parent = &pdev->dev;

View File

@ -635,6 +635,8 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
status = readb(i2c->base + MPC_I2C_SR);
if (status & CSR_MIF) {
/* Read again to allow register to stabilise */
status = readb(i2c->base + MPC_I2C_SR);
writeb(0, i2c->base + MPC_I2C_SR);
mpc_i2c_do_intr(i2c, status);
return IRQ_HANDLED;

View File

@ -1225,6 +1225,13 @@ static int mtk_i2c_probe(struct platform_device *pdev)
i2c->adap.quirks = i2c->dev_comp->quirks;
i2c->adap.timeout = 2 * HZ;
i2c->adap.retries = 1;
i2c->adap.bus_regulator = devm_regulator_get_optional(&pdev->dev, "vbus");
if (IS_ERR(i2c->adap.bus_regulator)) {
if (PTR_ERR(i2c->adap.bus_regulator) == -ENODEV)
i2c->adap.bus_regulator = NULL;
else
return PTR_ERR(i2c->adap.bus_regulator);
}
ret = mtk_i2c_parse_dt(pdev->dev.of_node, i2c);
if (ret)
@ -1286,7 +1293,7 @@ static int mtk_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
I2C_DRV_NAME, i2c);
dev_name(&pdev->dev), i2c);
if (ret < 0) {
dev_err(&pdev->dev,
"Request I2C IRQ %d fail\n", irq);

View File

@ -769,6 +769,7 @@ static const struct of_device_id cci_dt_match[] = {
{ .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
{ .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
{ .compatible = "qcom,sdm845-cci", .data = &cci_v2_data},
{ .compatible = "qcom,sm8250-cci", .data = &cci_v2_data},
{}
};
MODULE_DEVICE_TABLE(of, cci_dt_match);

View File

@ -1013,7 +1013,6 @@ static const struct of_device_id rcar_i2c_dt_ids[] = {
{ .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
{ .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
{ .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
{ .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 }, /* Deprecated */
{ .compatible = "renesas,rcar-gen1-i2c", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 },
{ .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 },

View File

@ -42,8 +42,10 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#define RIIC_ICCR1 0x00
#define RIIC_ICCR2 0x04
@ -86,6 +88,11 @@
#define RIIC_INIT_MSG -1
enum riic_type {
RIIC_RZ_A,
RIIC_RZ_G2L,
};
struct riic_dev {
void __iomem *base;
u8 *buf;
@ -395,7 +402,9 @@ static int riic_i2c_probe(struct platform_device *pdev)
struct i2c_adapter *adap;
struct resource *res;
struct i2c_timings i2c_t;
struct reset_control *rstc;
int i, ret;
enum riic_type type;
riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL);
if (!riic)
@ -412,6 +421,17 @@ static int riic_i2c_probe(struct platform_device *pdev)
return PTR_ERR(riic->clk);
}
type = (enum riic_type)of_device_get_match_data(&pdev->dev);
if (type == RIIC_RZ_G2L) {
rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(rstc)) {
dev_err(&pdev->dev, "Error: missing reset ctrl\n");
return PTR_ERR(rstc);
}
reset_control_deassert(rstc);
}
for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) {
res = platform_get_resource(pdev, IORESOURCE_IRQ, riic_irqs[i].res_num);
if (!res)
@ -472,7 +492,8 @@ static int riic_i2c_remove(struct platform_device *pdev)
}
static const struct of_device_id riic_i2c_dt_ids[] = {
{ .compatible = "renesas,riic-rz" },
{ .compatible = "renesas,riic-r9a07g044", .data = (void *)RIIC_RZ_G2L },
{ .compatible = "renesas,riic-rz", .data = (void *)RIIC_RZ_A },
{ /* Sentinel */ },
};

View File

@ -51,6 +51,7 @@
/* STM32F7 I2C control 1 */
#define STM32F7_I2C_CR1_PECEN BIT(23)
#define STM32F7_I2C_CR1_ALERTEN BIT(22)
#define STM32F7_I2C_CR1_SMBHEN BIT(20)
#define STM32F7_I2C_CR1_WUPEN BIT(18)
#define STM32F7_I2C_CR1_SBC BIT(16)
@ -125,6 +126,7 @@
(((n) & STM32F7_I2C_ISR_ADDCODE_MASK) >> 17)
#define STM32F7_I2C_ISR_DIR BIT(16)
#define STM32F7_I2C_ISR_BUSY BIT(15)
#define STM32F7_I2C_ISR_ALERT BIT(13)
#define STM32F7_I2C_ISR_PECERR BIT(11)
#define STM32F7_I2C_ISR_ARLO BIT(9)
#define STM32F7_I2C_ISR_BERR BIT(8)
@ -138,6 +140,7 @@
#define STM32F7_I2C_ISR_TXE BIT(0)
/* STM32F7 I2C Interrupt Clear */
#define STM32F7_I2C_ICR_ALERTCF BIT(13)
#define STM32F7_I2C_ICR_PECCF BIT(11)
#define STM32F7_I2C_ICR_ARLOCF BIT(9)
#define STM32F7_I2C_ICR_BERRCF BIT(8)
@ -278,6 +281,17 @@ struct stm32f7_i2c_msg {
u8 smbus_buf[I2C_SMBUS_BLOCK_MAX + 3] __aligned(4);
};
/**
* struct stm32f7_i2c_alert - SMBus alert specific data
* @setup: platform data for the smbus_alert i2c client
* @ara: I2C slave device used to respond to the SMBus Alert with Alert
* Response Address
*/
struct stm32f7_i2c_alert {
struct i2c_smbus_alert_setup setup;
struct i2c_client *ara;
};
/**
* struct stm32f7_i2c_dev - private data of the controller
* @adap: I2C adapter for this controller
@ -310,6 +324,7 @@ struct stm32f7_i2c_msg {
* @analog_filter: boolean to indicate enabling of the analog filter
* @dnf_dt: value of digital filter requested via dt
* @dnf: value of digital filter to apply
* @alert: SMBus alert specific data
*/
struct stm32f7_i2c_dev {
struct i2c_adapter adap;
@ -341,6 +356,7 @@ struct stm32f7_i2c_dev {
bool analog_filter;
u32 dnf_dt;
u32 dnf;
struct stm32f7_i2c_alert *alert;
};
/*
@ -1624,6 +1640,13 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
f7_msg->result = -EINVAL;
}
if (status & STM32F7_I2C_ISR_ALERT) {
dev_dbg(dev, "<%s>: SMBus alert received\n", __func__);
writel_relaxed(STM32F7_I2C_ICR_ALERTCF, base + STM32F7_I2C_ICR);
i2c_handle_smbus_alert(i2c_dev->alert->ara);
return IRQ_HANDLED;
}
if (!i2c_dev->slave_running) {
u32 mask;
/* Disable interrupts */
@ -1990,6 +2013,42 @@ static void stm32f7_i2c_disable_smbus_host(struct stm32f7_i2c_dev *i2c_dev)
}
}
static int stm32f7_i2c_enable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev)
{
struct stm32f7_i2c_alert *alert;
struct i2c_adapter *adap = &i2c_dev->adap;
struct device *dev = i2c_dev->dev;
void __iomem *base = i2c_dev->base;
alert = devm_kzalloc(dev, sizeof(*alert), GFP_KERNEL);
if (!alert)
return -ENOMEM;
alert->ara = i2c_new_smbus_alert_device(adap, &alert->setup);
if (IS_ERR(alert->ara))
return PTR_ERR(alert->ara);
i2c_dev->alert = alert;
/* Enable SMBus Alert */
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, STM32F7_I2C_CR1_ALERTEN);
return 0;
}
static void stm32f7_i2c_disable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev)
{
struct stm32f7_i2c_alert *alert = i2c_dev->alert;
void __iomem *base = i2c_dev->base;
if (alert) {
/* Disable SMBus Alert */
stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1,
STM32F7_I2C_CR1_ALERTEN);
i2c_unregister_device(alert->ara);
}
}
static u32 stm32f7_i2c_func(struct i2c_adapter *adap)
{
struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
@ -2173,6 +2232,16 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
}
}
if (of_property_read_bool(pdev->dev.of_node, "smbus-alert")) {
ret = stm32f7_i2c_enable_smbus_alert(i2c_dev);
if (ret) {
dev_err(i2c_dev->dev,
"failed to enable SMBus alert protocol (%d)\n",
ret);
goto i2c_disable_smbus_host;
}
}
dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr);
pm_runtime_mark_last_busy(i2c_dev->dev);
@ -2180,6 +2249,9 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
return 0;
i2c_disable_smbus_host:
stm32f7_i2c_disable_smbus_host(i2c_dev);
i2c_adapter_remove:
i2c_del_adapter(adap);
@ -2214,6 +2286,7 @@ static int stm32f7_i2c_remove(struct platform_device *pdev)
{
struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
stm32f7_i2c_disable_smbus_alert(i2c_dev);
stm32f7_i2c_disable_smbus_host(i2c_dev);
i2c_del_adapter(&i2c_dev->adap);

View File

@ -798,11 +798,10 @@ static int xiic_i2c_probe(struct platform_device *pdev)
init_waitqueue_head(&i2c->wait);
i2c->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(i2c->clk)) {
if (PTR_ERR(i2c->clk) != -EPROBE_DEFER)
dev_err(&pdev->dev, "input clock not found.\n");
return PTR_ERR(i2c->clk);
}
if (IS_ERR(i2c->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk),
"input clock not found.\n");
ret = clk_prepare_enable(i2c->clk);
if (ret) {
dev_err(&pdev->dev, "Unable to enable clock.\n");

View File

@ -24,6 +24,7 @@
#include <linux/i2c-smbus.h>
#include <linux/idr.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irqflags.h>
#include <linux/jump_label.h>
#include <linux/kernel.h>
@ -399,7 +400,8 @@ static int i2c_gpio_init_recovery(struct i2c_adapter *adap)
static int i2c_init_recovery(struct i2c_adapter *adap)
{
struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
char *err_str, *err_level = KERN_ERR;
bool is_error_level = true;
char *err_str;
if (!bri)
return 0;
@ -409,7 +411,7 @@ static int i2c_init_recovery(struct i2c_adapter *adap)
if (!bri->recover_bus) {
err_str = "no suitable method provided";
err_level = KERN_DEBUG;
is_error_level = false;
goto err;
}
@ -436,7 +438,10 @@ static int i2c_init_recovery(struct i2c_adapter *adap)
return 0;
err:
dev_printk(err_level, &adap->dev, "Not using recovery: %s\n", err_str);
if (is_error_level)
dev_err(&adap->dev, "Not using recovery: %s\n", err_str);
else
dev_dbg(&adap->dev, "Not using recovery: %s\n", err_str);
adap->bus_recovery_info = NULL;
return -EINVAL;
@ -461,12 +466,14 @@ static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client)
static int i2c_device_probe(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_adapter *adap;
struct i2c_driver *driver;
int status;
if (!client)
return 0;
adap = client->adapter;
client->irq = client->init_irq;
if (!client->irq) {
@ -532,6 +539,14 @@ static int i2c_device_probe(struct device *dev)
dev_dbg(dev, "probe\n");
if (adap->bus_regulator) {
status = regulator_enable(adap->bus_regulator);
if (status < 0) {
dev_err(&adap->dev, "Failed to enable bus regulator\n");
goto err_clear_wakeup_irq;
}
}
status = of_clk_set_defaults(dev->of_node, false);
if (status < 0)
goto err_clear_wakeup_irq;
@ -589,8 +604,10 @@ put_sync_adapter:
static int i2c_device_remove(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_adapter *adap;
struct i2c_driver *driver;
adap = client->adapter;
driver = to_i2c_driver(dev->driver);
if (driver->remove) {
int status;
@ -605,6 +622,8 @@ static int i2c_device_remove(struct device *dev)
devres_release_group(&client->dev, client->devres_group_id);
dev_pm_domain_detach(&client->dev, true);
if (!pm_runtime_status_suspended(&client->dev) && adap->bus_regulator)
regulator_disable(adap->bus_regulator);
dev_pm_clear_wake_irq(&client->dev);
device_init_wakeup(&client->dev, false);
@ -617,6 +636,86 @@ static int i2c_device_remove(struct device *dev)
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int i2c_resume_early(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
int err;
if (!client)
return 0;
if (pm_runtime_status_suspended(&client->dev) &&
client->adapter->bus_regulator) {
err = regulator_enable(client->adapter->bus_regulator);
if (err)
return err;
}
return pm_generic_resume_early(&client->dev);
}
static int i2c_suspend_late(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
int err;
if (!client)
return 0;
err = pm_generic_suspend_late(&client->dev);
if (err)
return err;
if (!pm_runtime_status_suspended(&client->dev) &&
client->adapter->bus_regulator)
return regulator_disable(client->adapter->bus_regulator);
return 0;
}
#endif
#ifdef CONFIG_PM
static int i2c_runtime_resume(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
int err;
if (!client)
return 0;
if (client->adapter->bus_regulator) {
err = regulator_enable(client->adapter->bus_regulator);
if (err)
return err;
}
return pm_generic_runtime_resume(&client->dev);
}
static int i2c_runtime_suspend(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
int err;
if (!client)
return 0;
err = pm_generic_runtime_suspend(&client->dev);
if (err)
return err;
if (client->adapter->bus_regulator)
return regulator_disable(client->adapter->bus_regulator);
return 0;
}
#endif
static const struct dev_pm_ops i2c_device_pm = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(i2c_suspend_late, i2c_resume_early)
SET_RUNTIME_PM_OPS(i2c_runtime_suspend, i2c_runtime_resume, NULL)
};
static void i2c_device_shutdown(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
@ -627,6 +726,8 @@ static void i2c_device_shutdown(struct device *dev)
driver = to_i2c_driver(dev->driver);
if (driver->shutdown)
driver->shutdown(client);
else if (client->irq > 0)
disable_irq(client->irq);
}
static void i2c_client_dev_release(struct device *dev)
@ -674,6 +775,7 @@ struct bus_type i2c_bus_type = {
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.pm = &i2c_device_pm,
};
EXPORT_SYMBOL_GPL(i2c_bus_type);

View File

@ -37,8 +37,15 @@ static u8 crc8(u16 data)
return (u8)(data >> 8);
}
/* Incremental CRC8 over count bytes in the array pointed to by p */
static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
/**
* i2c_smbus_pec - Incremental CRC8 over the given input data array
* @crc: previous return crc8 value
* @p: pointer to data buffer.
* @count: number of bytes in data buffer.
*
* Incremental CRC8 over count bytes in the array pointed to by p
*/
u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
{
int i;
@ -46,6 +53,7 @@ static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
crc = crc8((crc ^ p[i]) << 8);
return crc;
}
EXPORT_SYMBOL(i2c_smbus_pec);
/* Assume a 7-bit address, which is reasonable for SMBus */
static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg)

View File

@ -15,6 +15,7 @@
#include <linux/device.h> /* for struct device */
#include <linux/sched.h> /* for completion */
#include <linux/mutex.h>
#include <linux/regulator/consumer.h>
#include <linux/rtmutex.h>
#include <linux/irqdomain.h> /* for Host Notify IRQ */
#include <linux/of.h> /* for struct device_node */
@ -147,6 +148,7 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
/* Now follow the 'nice' access routines. These also document the calling
conventions of i2c_smbus_xfer. */
u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count);
s32 i2c_smbus_read_byte(const struct i2c_client *client);
s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value);
s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command);
@ -729,6 +731,7 @@ struct i2c_adapter {
const struct i2c_adapter_quirks *quirks;
struct irq_domain *host_notify_domain;
struct regulator *bus_regulator;
};
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)