mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'i2c-for-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
"Mostly DT bindings additions this time because Andi was super busy and
I also could only partly cover it.
- new ids for qcom-cci, mt65xx, exynos5, apple, tegra20, k1, i801
- drop support for already removed S3C2410
- introduce and use fwnode_for_each_child_node_scoped()
- mmt65xx: improve write-then-read transactions
- k1: various fixes around bus errors and resets
- usual share of cleanups, minor improvements, PM fixes...
at24 updates:
- add the compatible for Giantec GT24C256C to the device-tree
bindings"
* tag 'i2c-for-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (33 commits)
i2c: i801: Add support for Intel Wildcat Lake-U
dt-bindings: i2c: i2c-mt65xx: Add MediaTek MT8196/6991 compatibles
i2c: designware: Add disabling clocks when probe fails
i2c: designware: Fix clock issue when PM is disabled
i2c: busses: Fix some spelling errors
i2c: mux: Simplify boolean assignment in i2c_mux_alloc
i2c: designware: use dev_err_probe() when probing platform device
i2c: designware: convert to dev_err_probe() on request IRQ error
i2c: spacemit: ensure SDA is released after bus reset
i2c: spacemit: check SDA instead of SCL after bus reset
i2c: spacemit: disable SDA glitch fix to avoid restart delay
i2c: spacemit: remove stop function to avoid bus error
i2c: spacemit: ensure bus release check runs when wait_bus_idle() fails
i2c: mediatek: fix potential incorrect use of I2C_MASTER_WRRD
i2c: boardinfo: Annotate code used in init phase only
dt-bindings: i2c: i2c-mt65xx: Document MediaTek MT6878 I2C
dt-bindings: i2c: samsung,s3c2410-i2c: Drop S3C2410
i2c: s3c2410: Drop S3C2410 OF support
dt-bindings: i2c: spacemit,k1-i2c: Minor whitespace cleanup in example
dt-bindings: i2c: exynos5: add samsung,exynos8890-hsi2c compatible
...
This commit is contained in:
@@ -143,6 +143,7 @@ properties:
|
||||
- const: atmel,24c128
|
||||
- items:
|
||||
- enum:
|
||||
- giantec,gt24c256c
|
||||
- puya,p24c256c
|
||||
- const: atmel,24c256
|
||||
- items:
|
||||
|
||||
@@ -20,17 +20,22 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,s5l8960x-i2c
|
||||
- apple,t7000-i2c
|
||||
- apple,s8000-i2c
|
||||
- apple,t8010-i2c
|
||||
- apple,t8015-i2c
|
||||
- apple,t8103-i2c
|
||||
- apple,t8112-i2c
|
||||
- apple,t6000-i2c
|
||||
- const: apple,i2c
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t6020-i2c
|
||||
- const: apple,t8103-i2c
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,s5l8960x-i2c
|
||||
- apple,t7000-i2c
|
||||
- apple,s8000-i2c
|
||||
- apple,t8010-i2c
|
||||
- apple,t8015-i2c
|
||||
- apple,t8103-i2c
|
||||
- apple,t8112-i2c
|
||||
- apple,t6000-i2c
|
||||
- const: apple,i2c
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -33,11 +33,16 @@ properties:
|
||||
- samsung,exynos7870-hsi2c
|
||||
- tesla,fsd-hsi2c
|
||||
- const: samsung,exynos7-hsi2c
|
||||
- items:
|
||||
- enum:
|
||||
- samsung,exynos8890-hsi2c
|
||||
- const: samsung,exynos8895-hsi2c
|
||||
- items:
|
||||
- enum:
|
||||
- google,gs101-hsi2c
|
||||
- samsung,exynos2200-hsi2c
|
||||
- samsung,exynos850-hsi2c
|
||||
- samsung,exynos990-hsi2c
|
||||
- const: samsung,exynosautov9-hsi2c
|
||||
- const: samsung,exynos5-hsi2c # Exynos5250 and Exynos5420
|
||||
deprecated: true
|
||||
|
||||
@@ -50,6 +50,12 @@ properties:
|
||||
- enum:
|
||||
- mediatek,mt6795-i2c
|
||||
- const: mediatek,mt8173-i2c
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6878-i2c
|
||||
- mediatek,mt6991-i2c
|
||||
- mediatek,mt8196-i2c
|
||||
- const: mediatek,mt8188-i2c
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6893-i2c
|
||||
|
||||
@@ -80,6 +80,11 @@ properties:
|
||||
support for 64 KiB transactions whereas earlier chips supported no
|
||||
more than 4 KiB per transactions.
|
||||
const: nvidia,tegra194-i2c
|
||||
- description: |
|
||||
Tegra256 has 8 generic I2C controllers. The controllers are similar to
|
||||
the previous generations, but have a different parent clock and hence
|
||||
the timing parameters are configured differently.
|
||||
const: nvidia,tegra256-i2c
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -186,6 +191,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra194-i2c
|
||||
- nvidia,tegra256-i2c
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
|
||||
@@ -25,6 +25,8 @@ properties:
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,qcm2290-cci
|
||||
- qcom,sa8775p-cci
|
||||
- qcom,sc7280-cci
|
||||
- qcom,sc8280xp-cci
|
||||
- qcom,sdm670-cci
|
||||
@@ -44,11 +46,11 @@ properties:
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
minItems: 2
|
||||
maxItems: 6
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
minItems: 2
|
||||
maxItems: 6
|
||||
|
||||
interrupts:
|
||||
@@ -113,6 +115,7 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
@@ -120,6 +123,22 @@ allOf:
|
||||
- const: cci_ahb
|
||||
- const: cci
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qcm2290-cci
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: cci
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@@ -223,6 +242,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sa8775p-cci
|
||||
- qcom,sm8550-cci
|
||||
- qcom,sm8650-cci
|
||||
- qcom,x1e80100-cci
|
||||
|
||||
@@ -13,7 +13,6 @@ properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- samsung,s3c2410-i2c
|
||||
- samsung,s3c2440-i2c
|
||||
# For s3c2440-like I2C used inside HDMIPHY block found on several SoCs:
|
||||
- samsung,s3c2440-hdmiphy-i2c
|
||||
@@ -93,7 +92,6 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- samsung,s3c2410-i2c
|
||||
- samsung,s3c2440-i2c
|
||||
- samsung,s3c2440-hdmiphy-i2c
|
||||
then:
|
||||
|
||||
@@ -56,7 +56,7 @@ examples:
|
||||
reg = <0xd4010800 0x38>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <36>;
|
||||
clocks =<&ccu 32>, <&ccu 84>;
|
||||
clocks = <&ccu 32>, <&ccu 84>;
|
||||
clock-names = "func", "bus";
|
||||
clock-frequency = <100000>;
|
||||
};
|
||||
|
||||
@@ -50,6 +50,7 @@ Supported adapters:
|
||||
* Intel Birch Stream (SOC)
|
||||
* Intel Arrow Lake (SOC)
|
||||
* Intel Panther Lake (SOC)
|
||||
* Intel Wildcat Lake (SOC)
|
||||
|
||||
Datasheets: Publicly available at the Intel website
|
||||
|
||||
|
||||
@@ -165,6 +165,7 @@ config I2C_I801
|
||||
Birch Stream (SOC)
|
||||
Arrow Lake (SOC)
|
||||
Panther Lake (SOC)
|
||||
Wildcat Lake (SOC)
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called i2c-i801.
|
||||
|
||||
@@ -1068,11 +1068,10 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev)
|
||||
if (!(dev->flags & ACCESS_POLLING)) {
|
||||
ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr,
|
||||
irq_flags, dev_name(dev->dev), dev);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "failure requesting irq %i: %d\n",
|
||||
dev->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev->dev, ret,
|
||||
"failure requesting irq %i: %d\n",
|
||||
dev->irq, ret);
|
||||
}
|
||||
|
||||
ret = i2c_dw_init_recovery_info(dev);
|
||||
|
||||
@@ -238,7 +238,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
|
||||
|
||||
dev->rst = devm_reset_control_get_optional_exclusive(device, NULL);
|
||||
if (IS_ERR(dev->rst))
|
||||
return PTR_ERR(dev->rst);
|
||||
return dev_err_probe(device, PTR_ERR(dev->rst), "failed to acquire reset\n");
|
||||
|
||||
reset_control_deassert(dev->rst);
|
||||
|
||||
@@ -247,21 +247,23 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
|
||||
goto exit_reset;
|
||||
|
||||
ret = i2c_dw_probe_lock_support(dev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ret = dev_err_probe(device, ret, "failed to probe lock support\n");
|
||||
goto exit_reset;
|
||||
}
|
||||
|
||||
i2c_dw_configure(dev);
|
||||
|
||||
/* Optional interface clock */
|
||||
dev->pclk = devm_clk_get_optional(device, "pclk");
|
||||
if (IS_ERR(dev->pclk)) {
|
||||
ret = PTR_ERR(dev->pclk);
|
||||
ret = dev_err_probe(device, PTR_ERR(dev->pclk), "failed to acquire pclk\n");
|
||||
goto exit_reset;
|
||||
}
|
||||
|
||||
dev->clk = devm_clk_get_optional(device, NULL);
|
||||
if (IS_ERR(dev->clk)) {
|
||||
ret = PTR_ERR(dev->clk);
|
||||
ret = dev_err_probe(device, PTR_ERR(dev->clk), "failed to acquire clock\n");
|
||||
goto exit_reset;
|
||||
}
|
||||
|
||||
@@ -314,6 +316,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
|
||||
|
||||
exit_probe:
|
||||
dw_i2c_plat_pm_cleanup(dev);
|
||||
i2c_dw_prepare_clk(dev, false);
|
||||
exit_reset:
|
||||
reset_control_assert(dev->rst);
|
||||
return ret;
|
||||
@@ -331,9 +334,11 @@ static void dw_i2c_plat_remove(struct platform_device *pdev)
|
||||
i2c_dw_disable(dev);
|
||||
|
||||
pm_runtime_dont_use_autosuspend(device);
|
||||
pm_runtime_put_sync(device);
|
||||
pm_runtime_put_noidle(device);
|
||||
dw_i2c_plat_pm_cleanup(dev);
|
||||
|
||||
i2c_dw_prepare_clk(dev, false);
|
||||
|
||||
i2c_dw_remove_lock_support(dev);
|
||||
|
||||
reset_control_assert(dev->rst);
|
||||
|
||||
@@ -266,11 +266,10 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev)
|
||||
|
||||
ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr_slave,
|
||||
IRQF_SHARED, dev_name(dev->dev), dev);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "failure requesting IRQ %i: %d\n",
|
||||
dev->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev->dev, ret,
|
||||
"failure requesting IRQ %i: %d\n",
|
||||
dev->irq, ret);
|
||||
|
||||
ret = i2c_add_numbered_adapter(adap);
|
||||
if (ret)
|
||||
|
||||
@@ -339,7 +339,7 @@ static int hix5hd2_i2c_xfer_msg(struct hix5hd2_i2c_priv *priv,
|
||||
ret = priv->state;
|
||||
|
||||
/*
|
||||
* If this is the last message to be transfered (stop == 1)
|
||||
* If this is the last message to be transferred (stop == 1)
|
||||
* Then check if the bus can be brought back to idle.
|
||||
*/
|
||||
if (priv->state == HIX5I2C_STAT_RW_SUCCESS && stop)
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
* Arrow Lake-H (SOC) 0x7722 32 hard yes yes yes
|
||||
* Panther Lake-H (SOC) 0xe322 32 hard yes yes yes
|
||||
* Panther Lake-P (SOC) 0xe422 32 hard yes yes yes
|
||||
* Wildcat Lake-U (SOC) 0x4d22 32 hard yes yes yes
|
||||
*
|
||||
* Features supported by this driver:
|
||||
* Software PEC no
|
||||
@@ -236,6 +237,7 @@
|
||||
#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
|
||||
#define PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS 0x43a3
|
||||
#define PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS 0x4b23
|
||||
#define PCI_DEVICE_ID_INTEL_WILDCAT_LAKE_U_SMBUS 0x4d22
|
||||
#define PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS 0x4da3
|
||||
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS 0x51a3
|
||||
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3
|
||||
@@ -1056,6 +1058,7 @@ static const struct pci_device_id i801_ids[] = {
|
||||
{ PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
|
||||
{ PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
|
||||
{ PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
|
||||
{ PCI_DEVICE_DATA(INTEL, WILDCAT_LAKE_U_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
|
||||
+45
-26
@@ -3,6 +3,7 @@
|
||||
* Copyright (C) 2024-2025 Troy Mitchell <troymitchell988@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/iopoll.h>
|
||||
@@ -14,6 +15,7 @@
|
||||
#define SPACEMIT_ICR 0x0 /* Control register */
|
||||
#define SPACEMIT_ISR 0x4 /* Status register */
|
||||
#define SPACEMIT_IDBR 0xc /* Data buffer register */
|
||||
#define SPACEMIT_IRCR 0x18 /* Reset cycle counter */
|
||||
#define SPACEMIT_IBMR 0x1c /* Bus monitor register */
|
||||
|
||||
/* SPACEMIT_ICR register fields */
|
||||
@@ -25,7 +27,8 @@
|
||||
#define SPACEMIT_CR_MODE_FAST BIT(8) /* bus mode (master operation) */
|
||||
/* Bit 9 is reserved */
|
||||
#define SPACEMIT_CR_UR BIT(10) /* unit reset */
|
||||
/* Bits 11-12 are reserved */
|
||||
#define SPACEMIT_CR_RSTREQ BIT(11) /* i2c bus reset request */
|
||||
/* Bit 12 is reserved */
|
||||
#define SPACEMIT_CR_SCLE BIT(13) /* master clock enable */
|
||||
#define SPACEMIT_CR_IUE BIT(14) /* unit enable */
|
||||
/* Bits 15-17 are reserved */
|
||||
@@ -76,6 +79,10 @@
|
||||
SPACEMIT_SR_GCAD | SPACEMIT_SR_IRF | SPACEMIT_SR_ITE | \
|
||||
SPACEMIT_SR_ALD)
|
||||
|
||||
#define SPACEMIT_RCR_SDA_GLITCH_NOFIX BIT(7) /* bypass the SDA glitch fix */
|
||||
/* the cycles of SCL during bus reset */
|
||||
#define SPACEMIT_RCR_FIELD_RST_CYC GENMASK(3, 0)
|
||||
|
||||
/* SPACEMIT_IBMR register fields */
|
||||
#define SPACEMIT_BMR_SDA BIT(0) /* SDA line level */
|
||||
#define SPACEMIT_BMR_SCL BIT(1) /* SCL line level */
|
||||
@@ -88,6 +95,8 @@
|
||||
|
||||
#define SPACEMIT_SR_ERR (SPACEMIT_SR_BED | SPACEMIT_SR_RXOV | SPACEMIT_SR_ALD)
|
||||
|
||||
#define SPACEMIT_BUS_RESET_CLK_CNT_MAX 9
|
||||
|
||||
enum spacemit_i2c_state {
|
||||
SPACEMIT_STATE_IDLE,
|
||||
SPACEMIT_STATE_START,
|
||||
@@ -160,6 +169,7 @@ static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c)
|
||||
static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c)
|
||||
{
|
||||
u32 status;
|
||||
u8 clk_cnt;
|
||||
|
||||
/* if bus is locked, reset unit. 0: locked */
|
||||
status = readl(i2c->base + SPACEMIT_IBMR);
|
||||
@@ -169,9 +179,21 @@ static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c)
|
||||
spacemit_i2c_reset(i2c);
|
||||
usleep_range(10, 20);
|
||||
|
||||
/* check scl status again */
|
||||
for (clk_cnt = 0; clk_cnt < SPACEMIT_BUS_RESET_CLK_CNT_MAX; clk_cnt++) {
|
||||
status = readl(i2c->base + SPACEMIT_IBMR);
|
||||
if (status & SPACEMIT_BMR_SDA)
|
||||
return;
|
||||
|
||||
/* There's nothing left to save here, we are about to exit */
|
||||
writel(FIELD_PREP(SPACEMIT_RCR_FIELD_RST_CYC, 1),
|
||||
i2c->base + SPACEMIT_IRCR);
|
||||
writel(SPACEMIT_CR_RSTREQ, i2c->base + SPACEMIT_ICR);
|
||||
usleep_range(20, 30);
|
||||
}
|
||||
|
||||
/* check sda again here */
|
||||
status = readl(i2c->base + SPACEMIT_IBMR);
|
||||
if (!(status & SPACEMIT_BMR_SCL))
|
||||
if (!(status & SPACEMIT_BMR_SDA))
|
||||
dev_warn_ratelimited(i2c->dev, "unit reset failed\n");
|
||||
}
|
||||
|
||||
@@ -237,6 +259,14 @@ static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c)
|
||||
val |= SPACEMIT_CR_MSDE | SPACEMIT_CR_MSDIE;
|
||||
|
||||
writel(val, i2c->base + SPACEMIT_ICR);
|
||||
|
||||
/*
|
||||
* The glitch fix in the K1 I2C controller introduces a delay
|
||||
* on restart signals, so we disable the fix here.
|
||||
*/
|
||||
val = readl(i2c->base + SPACEMIT_IRCR);
|
||||
val |= SPACEMIT_RCR_SDA_GLITCH_NOFIX;
|
||||
writel(val, i2c->base + SPACEMIT_IRCR);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -267,19 +297,6 @@ static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c)
|
||||
writel(val, i2c->base + SPACEMIT_ICR);
|
||||
}
|
||||
|
||||
static void spacemit_i2c_stop(struct spacemit_i2c_dev *i2c)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(i2c->base + SPACEMIT_ICR);
|
||||
val |= SPACEMIT_CR_STOP | SPACEMIT_CR_ALDIE | SPACEMIT_CR_TB;
|
||||
|
||||
if (i2c->read)
|
||||
val |= SPACEMIT_CR_ACKNAK;
|
||||
|
||||
writel(val, i2c->base + SPACEMIT_ICR);
|
||||
}
|
||||
|
||||
static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
|
||||
{
|
||||
unsigned long time_left;
|
||||
@@ -412,7 +429,6 @@ static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
|
||||
|
||||
val = readl(i2c->base + SPACEMIT_ICR);
|
||||
val &= ~(SPACEMIT_CR_TB | SPACEMIT_CR_ACKNAK | SPACEMIT_CR_STOP | SPACEMIT_CR_START);
|
||||
writel(val, i2c->base + SPACEMIT_ICR);
|
||||
|
||||
switch (i2c->state) {
|
||||
case SPACEMIT_STATE_START:
|
||||
@@ -429,14 +445,16 @@ static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
|
||||
}
|
||||
|
||||
if (i2c->state != SPACEMIT_STATE_IDLE) {
|
||||
val |= SPACEMIT_CR_TB | SPACEMIT_CR_ALDIE;
|
||||
|
||||
if (spacemit_i2c_is_last_msg(i2c)) {
|
||||
/* trigger next byte with stop */
|
||||
spacemit_i2c_stop(i2c);
|
||||
} else {
|
||||
/* trigger next byte */
|
||||
val |= SPACEMIT_CR_ALDIE | SPACEMIT_CR_TB;
|
||||
writel(val, i2c->base + SPACEMIT_ICR);
|
||||
val |= SPACEMIT_CR_STOP;
|
||||
|
||||
if (i2c->read)
|
||||
val |= SPACEMIT_CR_ACKNAK;
|
||||
}
|
||||
writel(val, i2c->base + SPACEMIT_ICR);
|
||||
}
|
||||
|
||||
err_out:
|
||||
@@ -476,12 +494,13 @@ static int spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg *msgs, in
|
||||
spacemit_i2c_enable(i2c);
|
||||
|
||||
ret = spacemit_i2c_wait_bus_idle(i2c);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
ret = spacemit_i2c_xfer_msg(i2c);
|
||||
else if (ret < 0)
|
||||
dev_dbg(i2c->dev, "i2c transfer error: %d\n", ret);
|
||||
else
|
||||
if (ret < 0)
|
||||
dev_dbg(i2c->dev, "i2c transfer error: %d\n", ret);
|
||||
} else {
|
||||
spacemit_i2c_check_bus_release(i2c);
|
||||
}
|
||||
|
||||
spacemit_i2c_disable(i2c);
|
||||
|
||||
|
||||
@@ -1243,6 +1243,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
||||
{
|
||||
int ret;
|
||||
int left_num = num;
|
||||
bool write_then_read_en = false;
|
||||
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
|
||||
|
||||
ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
|
||||
@@ -1256,6 +1257,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
||||
if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) &&
|
||||
msgs[0].addr == msgs[1].addr) {
|
||||
i2c->auto_restart = 0;
|
||||
write_then_read_en = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1280,12 +1282,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
||||
else
|
||||
i2c->op = I2C_MASTER_WR;
|
||||
|
||||
if (!i2c->auto_restart) {
|
||||
if (num > 1) {
|
||||
/* combined two messages into one transaction */
|
||||
i2c->op = I2C_MASTER_WRRD;
|
||||
left_num--;
|
||||
}
|
||||
if (write_then_read_en) {
|
||||
/* combined two messages into one transaction */
|
||||
i2c->op = I2C_MASTER_WRRD;
|
||||
left_num--;
|
||||
}
|
||||
|
||||
/* always use DMA mode. */
|
||||
@@ -1293,7 +1293,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
||||
if (ret < 0)
|
||||
goto err_exit;
|
||||
|
||||
msgs++;
|
||||
if (i2c->op == I2C_MASTER_WRRD)
|
||||
msgs += 2;
|
||||
else
|
||||
msgs++;
|
||||
}
|
||||
/* the return value is number of executed messages */
|
||||
ret = num;
|
||||
|
||||
@@ -138,7 +138,6 @@ static void i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id s3c24xx_i2c_match[] = {
|
||||
{ .compatible = "samsung,s3c2410-i2c", .data = (void *)0 },
|
||||
{ .compatible = "samsung,s3c2440-i2c", .data = (void *)QUIRK_S3C2440 },
|
||||
{ .compatible = "samsung,s3c2440-hdmiphy-i2c",
|
||||
.data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) },
|
||||
|
||||
@@ -425,7 +425,7 @@ static irqreturn_t sprd_i2c_isr(int irq, void *dev_id)
|
||||
* If we did not get one ACK from target when writing data, then we
|
||||
* should finish this transmission since we got some errors.
|
||||
*
|
||||
* When writing data, if i2c_tran == 0 which means we have writen
|
||||
* When writing data, if i2c_tran == 0 which means we have written
|
||||
* done all data, then we can finish this transmission.
|
||||
*
|
||||
* When reading data, if conut < rx fifo full threshold, which
|
||||
|
||||
@@ -152,7 +152,7 @@ struct st_i2c_timings {
|
||||
/**
|
||||
* struct st_i2c_client - client specific data
|
||||
* @addr: 8-bit target addr, including r/w bit
|
||||
* @count: number of bytes to be transfered
|
||||
* @count: number of bytes to be transferred
|
||||
* @xfered: number of bytes already transferred
|
||||
* @buf: data buffer
|
||||
* @result: result of the transfer
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user