diff options
| author | Wolfram Sang <wsa+renesas@sang-engineering.com> | 2026-04-20 01:03:38 +0300 |
|---|---|---|
| committer | Wolfram Sang <wsa+renesas@sang-engineering.com> | 2026-04-20 01:03:38 +0300 |
| commit | d891635322fbb49559ce9da4cad8643331600519 (patch) | |
| tree | a94f7ca5d7db260c95594999dbc34f2a45f4bb10 | |
| parent | c1f49dea2b8f335813d3b348fd39117fb8efb428 (diff) | |
| parent | faed986de5250e1cd1296e82d1fcb4c03997e02a (diff) | |
| download | linux-d891635322fbb49559ce9da4cad8643331600519.tar.xz | |
Merge tag 'i2c-host-7.1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux into i2c/for-mergewindow
i2c-host for v7.1, part 2
- cx92755: convert I2C bindings to DT schema
- mediatek: add optional bus power management during transfers
- pxa: handle early bus busy condition
| -rw-r--r-- | Documentation/devicetree/bindings/i2c/cnxt,cx92755-i2c.yaml | 49 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/i2c/i2c-digicolor.txt | 25 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-mt65xx.c | 13 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 18 |
4 files changed, 73 insertions, 32 deletions
diff --git a/Documentation/devicetree/bindings/i2c/cnxt,cx92755-i2c.yaml b/Documentation/devicetree/bindings/i2c/cnxt,cx92755-i2c.yaml new file mode 100644 index 000000000000..c11bbf8aa9c5 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/cnxt,cx92755-i2c.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/cnxt,cx92755-i2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Conexant Digicolor I2C controller + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + +maintainers: + - Baruch Siach <baruch@tkos.co.il> + +properties: + compatible: + const: cnxt,cx92755-i2c + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-frequency: + default: 100000 + +required: + - compatible + - reg + - interrupts + - clocks + +unevaluatedProperties: false + +examples: + - | + i2c@f0000120 { + compatible = "cnxt,cx92755-i2c"; + reg = <0xf0000120 0x10>; + interrupts = <28>; + clocks = <&main_clk>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-digicolor.txt b/Documentation/devicetree/bindings/i2c/i2c-digicolor.txt deleted file mode 100644 index 457a098d4f7e..000000000000 --- a/Documentation/devicetree/bindings/i2c/i2c-digicolor.txt +++ /dev/null @@ -1,25 +0,0 @@ -Conexant Digicolor I2C controller - -Required properties: - - compatible: must be "cnxt,cx92755-i2c" - - reg: physical address and length of the device registers - - interrupts: a single interrupt specifier - - clocks: clock for the device - - #address-cells: should be <1> - - #size-cells: should be <0> - -Optional properties: -- clock-frequency: the desired I2C bus clock frequency in Hz; in - absence of this property the default value is used (100 kHz). - -Example: - - i2c: i2c@f0000120 { - compatible = "cnxt,cx92755-i2c"; - reg = <0xf0000120 0x10>; - interrupts = <28>; - clocks = <&main_clk>; - clock-frequency = <100000>; - #address-cells = <1>; - #size-cells = <0>; - }; diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index cb4d3aa709d0..126040ca05f1 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -21,6 +21,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/regulator/consumer.h> #include <linux/scatterlist.h> #include <linux/sched.h> #include <linux/slab.h> @@ -1244,9 +1245,15 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, bool write_then_read_en = false; struct mtk_i2c *i2c = i2c_get_adapdata(adap); + if (i2c->adap.bus_regulator) { + ret = regulator_enable(i2c->adap.bus_regulator); + if (ret) + return ret; + } + ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks); if (ret) - return ret; + goto err_regulator; i2c->auto_restart = i2c->dev_comp->auto_restart; @@ -1301,6 +1308,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, err_exit: clk_bulk_disable(I2C_MT65XX_CLK_MAX, i2c->clocks); +err_regulator: + if (i2c->adap.bus_regulator) + regulator_disable(i2c->adap.bus_regulator); + return ret; } diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index f55840b2eb9a..9a8b154ab69e 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -71,6 +71,7 @@ #define ISR_GCAD (1 << 8) /* general call address detected */ #define ISR_SAD (1 << 9) /* slave address detected */ #define ISR_BED (1 << 10) /* bus error no ACK/NAK */ +#define ISR_A3700_EBB (1 << 11) /* early bus busy for armada 3700 */ #define ILCR_SLV_SHIFT 0 #define ILCR_SLV_MASK (0x1FF << ILCR_SLV_SHIFT) @@ -263,6 +264,7 @@ struct pxa_i2c { bool highmode_enter; u32 fm_mask; u32 hs_mask; + u32 busy_mask; struct i2c_bus_recovery_info recovery; struct pinctrl *pinctrl; @@ -430,7 +432,7 @@ static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c) while (1) { isr = readl(_ISR(i2c)); - if (!(isr & (ISR_IBB | ISR_UB))) + if (!(isr & i2c->busy_mask)) return 0; if (isr & ISR_SAD) @@ -467,7 +469,7 @@ static int i2c_pxa_wait_master(struct pxa_i2c *i2c) * quick check of the i2c lines themselves to ensure they've * gone high... */ - if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) == 0 && + if ((readl(_ISR(i2c)) & i2c->busy_mask) == 0 && readl(_IBMR(i2c)) == (IBMR_SCLS | IBMR_SDAS)) { if (i2c_debug > 0) dev_dbg(&i2c->adap.dev, "%s: done\n", __func__); @@ -488,7 +490,7 @@ static int i2c_pxa_set_master(struct pxa_i2c *i2c) if (i2c_debug) dev_dbg(&i2c->adap.dev, "setting to bus master\n"); - if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) != 0) { + if ((readl(_ISR(i2c)) & i2c->busy_mask) != 0) { dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__); if (!i2c_pxa_wait_master(i2c)) { dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__); @@ -514,7 +516,7 @@ static int i2c_pxa_wait_slave(struct pxa_i2c *i2c) dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n", __func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c))); - if ((readl(_ISR(i2c)) & (ISR_UB|ISR_IBB)) == 0 || + if ((readl(_ISR(i2c)) & i2c->busy_mask) == 0 || (readl(_ISR(i2c)) & ISR_SAD) != 0 || (readl(_ICR(i2c)) & ICR_SCLE) == 0) { if (i2c_debug > 1) @@ -1177,7 +1179,7 @@ static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c) /* * Wait for the bus to become free. */ - while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) + while (timeout-- && readl(_ISR(i2c)) & i2c->busy_mask) udelay(1000); if (timeout < 0) { @@ -1322,7 +1324,7 @@ static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap) * handing control of the bus back to avoid the bus changing state. */ isr = readl(_ISR(i2c)); - if (isr & (ISR_UB | ISR_IBB)) { + if (isr & i2c->busy_mask) { dev_dbg(&i2c->adap.dev, "recovery: resetting controller, ISR=0x%08x\n", isr); i2c_pxa_do_reset(i2c); @@ -1479,6 +1481,10 @@ static int i2c_pxa_probe(struct platform_device *dev) i2c->fm_mask = pxa_reg_layout[i2c_type].fm; i2c->hs_mask = pxa_reg_layout[i2c_type].hs; + i2c->busy_mask = ISR_UB | ISR_IBB; + if (i2c_type == REGS_A3700) + i2c->busy_mask |= ISR_A3700_EBB; + if (i2c_type != REGS_CE4100) i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar; |
