2019-12-03 11:49:50

by Biwen Li

[permalink] [raw]
Subject: [v6] i2c: imx: support slave mode for imx I2C driver

The patch supports slave mode for imx I2C driver

Signed-off-by: Biwen Li <[email protected]>
---
Change in v6:
- delete robust logs and comments
- not read status register again in master isr.

Change in v5:
- fix a bug that cannot determine in what mode(master mode or
slave mode)

Change in v4:
- add MACRO CONFIG_I2C_SLAVE to fix compilation issue

Change in v3:
- support layerscape and i.mx platform

Change in v2:
- remove MACRO CONFIG_I2C_SLAVE

drivers/i2c/busses/i2c-imx.c | 199 +++++++++++++++++++++++++++++++----
1 file changed, 181 insertions(+), 18 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index a3b61336fe55..40ccfca600bf 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -203,6 +203,9 @@ struct imx_i2c_struct {
struct pinctrl_state *pinctrl_pins_gpio;

struct imx_i2c_dma *dma;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ struct i2c_client *slave;
+#endif
};

static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
@@ -279,6 +282,14 @@ static inline unsigned char imx_i2c_read_reg(struct imx_i2c_struct *i2c_imx,
return readb(i2c_imx->base + (reg << i2c_imx->hwdata->regshift));
}

+/* Set up i2c controller register and i2c status register to default value. */
+static void i2c_imx_reset_regs(struct imx_i2c_struct *i2c_imx)
+{
+ imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
+ i2c_imx, IMX_I2C_I2CR);
+ imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
+}
+
/* Functions for DMA support */
static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
dma_addr_t phy_addr)
@@ -588,23 +599,25 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
}

-static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
+static void i2c_imx_clr_if_bit(unsigned int status, struct imx_i2c_struct *i2c_imx)
{
- struct imx_i2c_struct *i2c_imx = dev_id;
- unsigned int temp;
+ status &= ~I2SR_IIF;
+ status |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
+ imx_i2c_write_reg(status, i2c_imx, IMX_I2C_I2SR);
+}

- temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
- if (temp & I2SR_IIF) {
- /* save status register */
- i2c_imx->i2csr = temp;
- temp &= ~I2SR_IIF;
- temp |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
- imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
- wake_up(&i2c_imx->queue);
- return IRQ_HANDLED;
- }
+static void i2c_imx_clr_al_bit(unsigned int status, struct imx_i2c_struct *i2c_imx)
+{
+ status &= ~I2SR_IAL;
+ status |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IAL);
+ imx_i2c_write_reg(status, i2c_imx, IMX_I2C_I2SR);
+}

- return IRQ_NONE;
+static irqreturn_t i2c_imx_master_isr(struct imx_i2c_struct *i2c_imx)
+{
+ wake_up(&i2c_imx->queue);
+
+ return IRQ_HANDLED;
}

static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx,
@@ -900,6 +913,13 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,

dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);

+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ if (i2c_imx->slave) {
+ dev_err(&i2c_imx->adapter.dev, "Please not do operations of master mode in slave mode");
+ return -EBUSY;
+ }
+#endif
+
result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
if (result < 0)
goto out;
@@ -1048,11 +1068,157 @@ static u32 i2c_imx_func(struct i2c_adapter *adapter)
| I2C_FUNC_SMBUS_READ_BLOCK_DATA;
}

+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+static int i2c_imx_slave_init(struct imx_i2c_struct *i2c_imx)
+{
+ int temp;
+
+ /* Resume */
+ temp = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
+ if (temp < 0) {
+ dev_err(&i2c_imx->adapter.dev, "failed to resume i2c controller");
+ return temp;
+ }
+
+ /* Set slave addr. */
+ imx_i2c_write_reg((i2c_imx->slave->addr << 1), i2c_imx, IMX_I2C_IADR);
+
+ i2c_imx_reset_regs(i2c_imx);
+
+ /* Enable module */
+ temp = i2c_imx->hwdata->i2cr_ien_opcode;
+ imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+
+ /* Enable interrupt from i2c module */
+ temp |= I2CR_IIEN;
+ imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+
+ /* Wait controller to be stable */
+ usleep_range(50, 150);
+ return 0;
+}
+
+static irqreturn_t i2c_imx_slave_isr(struct imx_i2c_struct *i2c_imx)
+{
+ unsigned int status, ctl;
+ u8 value;
+
+ status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
+ ctl = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+ if (status & I2SR_IAL) { /* Arbitration lost */
+ i2c_imx_clr_al_bit(status, i2c_imx);
+ } else if (status & I2SR_IAAS) { /* Addressed as a slave */
+ if (status & I2SR_SRW) { /* Master wants to read from us*/
+ dev_dbg(&i2c_imx->adapter.dev, "read requested");
+ i2c_slave_event(i2c_imx->slave, I2C_SLAVE_READ_REQUESTED, &value);
+
+ /* Slave transmit */
+ ctl |= I2CR_MTX;
+ imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
+
+ /* Send data */
+ imx_i2c_write_reg(value, i2c_imx, IMX_I2C_I2DR);
+ } else { /* Master wants to write to us */
+ dev_dbg(&i2c_imx->adapter.dev, "write requested");
+ i2c_slave_event(i2c_imx->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
+
+ /* Slave receive */
+ ctl &= ~I2CR_MTX;
+ imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
+ /* Dummy read */
+ imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
+ }
+ } else if (!(ctl & I2CR_MTX)) { /* Receive mode */
+ if (status & I2SR_IBB) { /* No STOP signal detected */
+ ctl &= ~I2CR_MTX;
+ imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
+
+ value = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
+ i2c_slave_event(i2c_imx->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
+ } else { /* STOP signal is detected */
+ dev_dbg(&i2c_imx->adapter.dev,
+ "STOP signal detected");
+ i2c_slave_event(i2c_imx->slave, I2C_SLAVE_STOP, &value);
+ }
+ } else if (!(status & I2SR_RXAK)) { /* Transmit mode received ACK */
+ ctl |= I2CR_MTX;
+ imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
+
+ i2c_slave_event(i2c_imx->slave, I2C_SLAVE_READ_PROCESSED, &value);
+
+ imx_i2c_write_reg(value, i2c_imx, IMX_I2C_I2DR);
+ } else { /* Transmit mode received NAK */
+ ctl &= ~I2CR_MTX;
+ imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
+ imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
+ }
+ return IRQ_HANDLED;
+}
+
+static int i2c_imx_reg_slave(struct i2c_client *client)
+{
+ struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
+ int ret;
+ if (i2c_imx->slave)
+ return -EBUSY;
+
+ i2c_imx->slave = client;
+
+ ret = i2c_imx_slave_init(i2c_imx);
+
+ return ret;
+}
+
+static int i2c_imx_unreg_slave(struct i2c_client *client)
+{
+ struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
+
+ if (!i2c_imx->slave)
+ return -EINVAL;
+
+ /* Reset slave address. */
+ imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IADR);
+
+ i2c_imx_reset_regs(i2c_imx);
+
+ i2c_imx->slave = NULL;
+
+ /* Suspend */
+ pm_runtime_put_sync(i2c_imx->adapter.dev.parent);
+
+ return 0;
+}
+#endif
+
static const struct i2c_algorithm i2c_imx_algo = {
.master_xfer = i2c_imx_xfer,
.functionality = i2c_imx_func,
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ .reg_slave = i2c_imx_reg_slave,
+ .unreg_slave = i2c_imx_unreg_slave,
+#endif
};

+static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
+{
+ struct imx_i2c_struct *i2c_imx = dev_id;
+ unsigned int status;
+
+ status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
+
+ if (status & I2SR_IIF) {
+ i2c_imx_clr_if_bit(status, i2c_imx);
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+ if (i2c_imx->slave)
+ return i2c_imx_slave_isr(i2c_imx);
+#endif
+ i2c_imx->i2csr = status;
+ return i2c_imx_master_isr(i2c_imx);
+ }
+
+ return IRQ_NONE;
+}
+
static int i2c_imx_probe(struct platform_device *pdev)
{
struct imx_i2c_struct *i2c_imx;
@@ -1148,10 +1314,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
clk_notifier_register(i2c_imx->clk, &i2c_imx->clk_change_nb);
i2c_imx_set_clk(i2c_imx, clk_get_rate(i2c_imx->clk));

- /* Set up chip registers to defaults */
- imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
- i2c_imx, IMX_I2C_I2CR);
- imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
+ i2c_imx_reset_regs(i2c_imx);

/* Init optional bus recovery function */
ret = i2c_imx_init_recovery_info(i2c_imx, pdev);
--
2.17.1


2019-12-04 10:00:59

by Sascha Hauer

[permalink] [raw]
Subject: Re: [v6] i2c: imx: support slave mode for imx I2C driver

Hi,

The patch looks ok to me now, but I still do not like the #ifdeffery
around CONFIG_I2C_SLAVE. With the patch I just sent (You are on Cc:)
we could apply the following on your patch which makes it more readable
and increases compile coverage.

Wolfram, Biwen, what do you think?

Sascha

---------------------------8<------------------------------

From 52f7c2bf59db61d4b27b59ca6404136e3ed77310 Mon Sep 17 00:00:00 2001
From: Sascha Hauer <[email protected]>
Date: Wed, 4 Dec 2019 10:56:34 +0100
Subject: [PATCH] fixup! i2c: imx: support slave mode for imx I2C driver

---
drivers/i2c/busses/i2c-imx.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 40ccfca600bf..c5d9ae8226cd 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -203,9 +203,7 @@ struct imx_i2c_struct {
struct pinctrl_state *pinctrl_pins_gpio;

struct imx_i2c_dma *dma;
-#if IS_ENABLED(CONFIG_I2C_SLAVE)
struct i2c_client *slave;
-#endif
};

static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
@@ -913,12 +911,10 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,

dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);

-#if IS_ENABLED(CONFIG_I2C_SLAVE)
if (i2c_imx->slave) {
dev_err(&i2c_imx->adapter.dev, "Please not do operations of master mode in slave mode");
return -EBUSY;
}
-#endif

result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
if (result < 0)
@@ -1068,7 +1064,6 @@ static u32 i2c_imx_func(struct i2c_adapter *adapter)
| I2C_FUNC_SMBUS_READ_BLOCK_DATA;
}

-#if IS_ENABLED(CONFIG_I2C_SLAVE)
static int i2c_imx_slave_init(struct imx_i2c_struct *i2c_imx)
{
int temp;
@@ -1159,6 +1154,10 @@ static int i2c_imx_reg_slave(struct i2c_client *client)
{
struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
int ret;
+
+ if (!IS_ENABLED(CONFIG_I2C_SLAVE))
+ return -EINVAL;
+
if (i2c_imx->slave)
return -EBUSY;

@@ -1173,6 +1172,9 @@ static int i2c_imx_unreg_slave(struct i2c_client *client)
{
struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);

+ if (!IS_ENABLED(CONFIG_I2C_SLAVE))
+ return -EINVAL;
+
if (!i2c_imx->slave)
return -EINVAL;

@@ -1188,15 +1190,12 @@ static int i2c_imx_unreg_slave(struct i2c_client *client)

return 0;
}
-#endif

static const struct i2c_algorithm i2c_imx_algo = {
.master_xfer = i2c_imx_xfer,
.functionality = i2c_imx_func,
-#if IS_ENABLED(CONFIG_I2C_SLAVE)
.reg_slave = i2c_imx_reg_slave,
.unreg_slave = i2c_imx_unreg_slave,
-#endif
};

static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
@@ -1208,10 +1207,10 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)

if (status & I2SR_IIF) {
i2c_imx_clr_if_bit(status, i2c_imx);
-#if IS_ENABLED(CONFIG_I2C_SLAVE)
- if (i2c_imx->slave)
+
+ if (IS_ENABLED(CONFIG_I2C_SLAVE) && i2c_imx->slave)
return i2c_imx_slave_isr(i2c_imx);
-#endif
+
i2c_imx->i2csr = status;
return i2c_imx_master_isr(i2c_imx);
}
--
2.24.0


--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2019-12-05 11:45:02

by Oleksij Rempel

[permalink] [raw]
Subject: Re: [v6] i2c: imx: support slave mode for imx I2C driver

Hi,

On 04.12.19 11:00, Sascha Hauer wrote:
> Hi,
>
> The patch looks ok to me now, but I still do not like the #ifdeffery
> around CONFIG_I2C_SLAVE. With the patch I just sent (You are on Cc:)
> we could apply the following on your patch which makes it more readable
> and increases compile coverage.
>
> Wolfram, Biwen, what do you think?


RCAR depends on slave:
config I2C_RCAR

tristate "Renesas R-Car I2C Controller"

depends on ARCH_RENESAS || COMPILE_TEST

select I2C_SLAVE
see:
drivers/i2c/busses/i2c-rcar.c

So, I would suggest to do the same in imx.

So far, I tested this patch on iMX6S. It works in one board (i2c-gpio + i2c-imx) and
two board (i2c-imx + i2c-imx) configuration.
Tested-by: Oleksij Rempel <[email protected]>


>
> Sascha
>
> ---------------------------8<------------------------------
>
> From 52f7c2bf59db61d4b27b59ca6404136e3ed77310 Mon Sep 17 00:00:00 2001
> From: Sascha Hauer <[email protected]>
> Date: Wed, 4 Dec 2019 10:56:34 +0100
> Subject: [PATCH] fixup! i2c: imx: support slave mode for imx I2C driver
>
> ---
> drivers/i2c/busses/i2c-imx.c | 21 ++++++++++-----------
> 1 file changed, 10 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index 40ccfca600bf..c5d9ae8226cd 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -203,9 +203,7 @@ struct imx_i2c_struct {
> struct pinctrl_state *pinctrl_pins_gpio;
>
> struct imx_i2c_dma *dma;
> -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> struct i2c_client *slave;
> -#endif
> };
>
> static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
> @@ -913,12 +911,10 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
>
> dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
>
> -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> if (i2c_imx->slave) {
> dev_err(&i2c_imx->adapter.dev, "Please not do operations of master mode in slave mode");
> return -EBUSY;
> }
> -#endif
>
> result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
> if (result < 0)
> @@ -1068,7 +1064,6 @@ static u32 i2c_imx_func(struct i2c_adapter *adapter)
> | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
> }
>
> -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> static int i2c_imx_slave_init(struct imx_i2c_struct *i2c_imx)
> {
> int temp;
> @@ -1159,6 +1154,10 @@ static int i2c_imx_reg_slave(struct i2c_client *client)
> {
> struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
> int ret;
> +
> + if (!IS_ENABLED(CONFIG_I2C_SLAVE))
> + return -EINVAL;
> +
> if (i2c_imx->slave)
> return -EBUSY;
>
> @@ -1173,6 +1172,9 @@ static int i2c_imx_unreg_slave(struct i2c_client *client)
> {
> struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
>
> + if (!IS_ENABLED(CONFIG_I2C_SLAVE))
> + return -EINVAL;
> +
> if (!i2c_imx->slave)
> return -EINVAL;
>
> @@ -1188,15 +1190,12 @@ static int i2c_imx_unreg_slave(struct i2c_client *client)
>
> return 0;
> }
> -#endif
>
> static const struct i2c_algorithm i2c_imx_algo = {
> .master_xfer = i2c_imx_xfer,
> .functionality = i2c_imx_func,
> -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> .reg_slave = i2c_imx_reg_slave,
> .unreg_slave = i2c_imx_unreg_slave,
> -#endif
> };
>
> static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
> @@ -1208,10 +1207,10 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
>
> if (status & I2SR_IIF) {
> i2c_imx_clr_if_bit(status, i2c_imx);
> -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> - if (i2c_imx->slave)
> +
> + if (IS_ENABLED(CONFIG_I2C_SLAVE) && i2c_imx->slave)
> return i2c_imx_slave_isr(i2c_imx);
> -#endif
> +
> i2c_imx->i2csr = status;
> return i2c_imx_master_isr(i2c_imx);
> }
>

Kind regards,
Oleksij Rempel

--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2019-12-06 07:39:35

by Sascha Hauer

[permalink] [raw]
Subject: Re: [v6] i2c: imx: support slave mode for imx I2C driver

On Thu, Dec 05, 2019 at 12:43:46PM +0100, Oleksij Rempel wrote:
> Hi,
>
> On 04.12.19 11:00, Sascha Hauer wrote:
> > Hi,
> >
> > The patch looks ok to me now, but I still do not like the #ifdeffery
> > around CONFIG_I2C_SLAVE. With the patch I just sent (You are on Cc:)
> > we could apply the following on your patch which makes it more readable
> > and increases compile coverage.
> >
> > Wolfram, Biwen, what do you think?
>
>
> RCAR depends on slave:
> config I2C_RCAR
>
> tristate "Renesas R-Car I2C Controller"
>
> depends on ARCH_RENESAS || COMPILE_TEST
>
> select I2C_SLAVE
> see:
> drivers/i2c/busses/i2c-rcar.c
>
> So, I would suggest to do the same in imx.

I suggested that to v1 of this patch. If we agree though that I2C slave
support deserves an extra Kconfig option we should also make the drivers
cope with that situation. Otherwise we would better make I2C slave
support non optional.

Sascha

--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2020-03-04 04:14:12

by Biwen Li

[permalink] [raw]
Subject: RE: [EXT] Re: [v6] i2c: imx: support slave mode for imx I2C driver

Hi Wolfram,

Any comments?

Best Regards,
Biwen Li

>
> Hi,
>
> On 04.12.19 11:00, Sascha Hauer wrote:
> > Hi,
> >
> > The patch looks ok to me now, but I still do not like the #ifdeffery
> > around CONFIG_I2C_SLAVE. With the patch I just sent (You are on Cc:)
> > we could apply the following on your patch which makes it more
> > readable and increases compile coverage.
> >
> > Wolfram, Biwen, what do you think?
>
>
> RCAR depends on slave:
> config I2C_RCAR
>
> tristate "Renesas R-Car I2C Controller"
>
> depends on ARCH_RENESAS || COMPILE_TEST
>
> select I2C_SLAVE
> see:
> drivers/i2c/busses/i2c-rcar.c
>
> So, I would suggest to do the same in imx.
>
> So far, I tested this patch on iMX6S. It works in one board (i2c-gpio + i2c-imx)
> and two board (i2c-imx + i2c-imx) configuration.
> Tested-by: Oleksij Rempel <[email protected]>
>
>
> >
> > Sascha
> >
> > ---------------------------8<------------------------------
> >
> > From 52f7c2bf59db61d4b27b59ca6404136e3ed77310 Mon Sep 17
> 00:00:00
> > 2001
> > From: Sascha Hauer <[email protected]>
> > Date: Wed, 4 Dec 2019 10:56:34 +0100
> > Subject: [PATCH] fixup! i2c: imx: support slave mode for imx I2C
> > driver
> >
> > ---
> > drivers/i2c/busses/i2c-imx.c | 21 ++++++++++-----------
> > 1 file changed, 10 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-imx.c
> > b/drivers/i2c/busses/i2c-imx.c index 40ccfca600bf..c5d9ae8226cd 100644
> > --- a/drivers/i2c/busses/i2c-imx.c
> > +++ b/drivers/i2c/busses/i2c-imx.c
> > @@ -203,9 +203,7 @@ struct imx_i2c_struct {
> > struct pinctrl_state *pinctrl_pins_gpio;
> >
> > struct imx_i2c_dma *dma;
> > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > struct i2c_client *slave;
> > -#endif
> > };
> >
> > static const struct imx_i2c_hwdata imx1_i2c_hwdata = { @@ -913,12
> > +911,10 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
> >
> > dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
> >
> > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > if (i2c_imx->slave) {
> > dev_err(&i2c_imx->adapter.dev, "Please not do operations
> of master mode in slave mode");
> > return -EBUSY;
> > }
> > -#endif
> >
> > result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
> > if (result < 0)
> > @@ -1068,7 +1064,6 @@ static u32 i2c_imx_func(struct i2c_adapter
> *adapter)
> > | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
> > }
> >
> > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > static int i2c_imx_slave_init(struct imx_i2c_struct *i2c_imx)
> > {
> > int temp;
> > @@ -1159,6 +1154,10 @@ static int i2c_imx_reg_slave(struct i2c_client
> *client)
> > {
> > struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
> > int ret;
> > +
> > + if (!IS_ENABLED(CONFIG_I2C_SLAVE))
> > + return -EINVAL;
> > +
> > if (i2c_imx->slave)
> > return -EBUSY;
> >
> > @@ -1173,6 +1172,9 @@ static int i2c_imx_unreg_slave(struct i2c_client
> *client)
> > {
> > struct imx_i2c_struct *i2c_imx =
> > i2c_get_adapdata(client->adapter);
> >
> > + if (!IS_ENABLED(CONFIG_I2C_SLAVE))
> > + return -EINVAL;
> > +
> > if (!i2c_imx->slave)
> > return -EINVAL;
> >
> > @@ -1188,15 +1190,12 @@ static int i2c_imx_unreg_slave(struct
> > i2c_client *client)
> >
> > return 0;
> > }
> > -#endif
> >
> > static const struct i2c_algorithm i2c_imx_algo = {
> > .master_xfer = i2c_imx_xfer,
> > .functionality = i2c_imx_func,
> > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > .reg_slave = i2c_imx_reg_slave,
> > .unreg_slave = i2c_imx_unreg_slave,
> > -#endif
> > };
> >
> > static irqreturn_t i2c_imx_isr(int irq, void *dev_id) @@ -1208,10
> > +1207,10 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
> >
> > if (status & I2SR_IIF) {
> > i2c_imx_clr_if_bit(status, i2c_imx); -#if
> > IS_ENABLED(CONFIG_I2C_SLAVE)
> > - if (i2c_imx->slave)
> > +
> > + if (IS_ENABLED(CONFIG_I2C_SLAVE) && i2c_imx->slave)
> > return i2c_imx_slave_isr(i2c_imx); -#endif
> > +
> > i2c_imx->i2csr = status;
> > return i2c_imx_master_isr(i2c_imx);
> > }
> >
>
> Kind regards,
> Oleksij Rempel
>
> --
> Pengutronix e.K. |
> |
> Industrial Linux Solutions |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.
> pengutronix.de%2F&amp;data=02%7C01%7Cbiwen.li%40nxp.com%7C2374a
> 486922f4625717e08d779786b2f%7C686ea1d3bc2b4c6fa92cd99c5c30163
> 5%7C0%7C0%7C637111430406497837&amp;sdata=fiW0xphV%2FFRLNU3x
> xYaU6qzAyiydVfJwiHc5Xu%2BcvCQ%3D&amp;reserved=0 |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686 | Fax:
> +49-5121-206917-5555 |

2020-03-04 05:23:39

by Oleksij Rempel

[permalink] [raw]
Subject: Re: [EXT] Re: [v6] i2c: imx: support slave mode for imx I2C driver

Hi Biwen,

On Wed, Mar 04, 2020 at 04:13:03AM +0000, Biwen Li wrote:
> Hi Wolfram,
>
> Any comments?

Wolfram is waiting until you react to our comments. Until this is not
happened, I will not ACK this patch and Wolfram will not take it.

regards,
Oleksij

> Best Regards,
> Biwen Li
>
> >
> > Hi,
> >
> > On 04.12.19 11:00, Sascha Hauer wrote:
> > > Hi,
> > >
> > > The patch looks ok to me now, but I still do not like the #ifdeffery
> > > around CONFIG_I2C_SLAVE. With the patch I just sent (You are on Cc:)
> > > we could apply the following on your patch which makes it more
> > > readable and increases compile coverage.
> > >
> > > Wolfram, Biwen, what do you think?
> >
> >
> > RCAR depends on slave:
> > config I2C_RCAR
> >
> > tristate "Renesas R-Car I2C Controller"
> >
> > depends on ARCH_RENESAS || COMPILE_TEST
> >
> > select I2C_SLAVE
> > see:
> > drivers/i2c/busses/i2c-rcar.c
> >
> > So, I would suggest to do the same in imx.
> >
> > So far, I tested this patch on iMX6S. It works in one board (i2c-gpio + i2c-imx)
> > and two board (i2c-imx + i2c-imx) configuration.
> > Tested-by: Oleksij Rempel <[email protected]>
> >
> >
> > >
> > > Sascha
> > >
> > > ---------------------------8<------------------------------
> > >
> > > From 52f7c2bf59db61d4b27b59ca6404136e3ed77310 Mon Sep 17
> > 00:00:00
> > > 2001
> > > From: Sascha Hauer <[email protected]>
> > > Date: Wed, 4 Dec 2019 10:56:34 +0100
> > > Subject: [PATCH] fixup! i2c: imx: support slave mode for imx I2C
> > > driver
> > >
> > > ---
> > > drivers/i2c/busses/i2c-imx.c | 21 ++++++++++-----------
> > > 1 file changed, 10 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/i2c/busses/i2c-imx.c
> > > b/drivers/i2c/busses/i2c-imx.c index 40ccfca600bf..c5d9ae8226cd 100644
> > > --- a/drivers/i2c/busses/i2c-imx.c
> > > +++ b/drivers/i2c/busses/i2c-imx.c
> > > @@ -203,9 +203,7 @@ struct imx_i2c_struct {
> > > struct pinctrl_state *pinctrl_pins_gpio;
> > >
> > > struct imx_i2c_dma *dma;
> > > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > > struct i2c_client *slave;
> > > -#endif
> > > };
> > >
> > > static const struct imx_i2c_hwdata imx1_i2c_hwdata = { @@ -913,12
> > > +911,10 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
> > >
> > > dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
> > >
> > > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > > if (i2c_imx->slave) {
> > > dev_err(&i2c_imx->adapter.dev, "Please not do operations
> > of master mode in slave mode");
> > > return -EBUSY;
> > > }
> > > -#endif
> > >
> > > result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
> > > if (result < 0)
> > > @@ -1068,7 +1064,6 @@ static u32 i2c_imx_func(struct i2c_adapter
> > *adapter)
> > > | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
> > > }
> > >
> > > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > > static int i2c_imx_slave_init(struct imx_i2c_struct *i2c_imx)
> > > {
> > > int temp;
> > > @@ -1159,6 +1154,10 @@ static int i2c_imx_reg_slave(struct i2c_client
> > *client)
> > > {
> > > struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
> > > int ret;
> > > +
> > > + if (!IS_ENABLED(CONFIG_I2C_SLAVE))
> > > + return -EINVAL;
> > > +
> > > if (i2c_imx->slave)
> > > return -EBUSY;
> > >
> > > @@ -1173,6 +1172,9 @@ static int i2c_imx_unreg_slave(struct i2c_client
> > *client)
> > > {
> > > struct imx_i2c_struct *i2c_imx =
> > > i2c_get_adapdata(client->adapter);
> > >
> > > + if (!IS_ENABLED(CONFIG_I2C_SLAVE))
> > > + return -EINVAL;
> > > +
> > > if (!i2c_imx->slave)
> > > return -EINVAL;
> > >
> > > @@ -1188,15 +1190,12 @@ static int i2c_imx_unreg_slave(struct
> > > i2c_client *client)
> > >
> > > return 0;
> > > }
> > > -#endif
> > >
> > > static const struct i2c_algorithm i2c_imx_algo = {
> > > .master_xfer = i2c_imx_xfer,
> > > .functionality = i2c_imx_func,
> > > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > > .reg_slave = i2c_imx_reg_slave,
> > > .unreg_slave = i2c_imx_unreg_slave,
> > > -#endif
> > > };
> > >
> > > static irqreturn_t i2c_imx_isr(int irq, void *dev_id) @@ -1208,10
> > > +1207,10 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
> > >
> > > if (status & I2SR_IIF) {
> > > i2c_imx_clr_if_bit(status, i2c_imx); -#if
> > > IS_ENABLED(CONFIG_I2C_SLAVE)
> > > - if (i2c_imx->slave)
> > > +
> > > + if (IS_ENABLED(CONFIG_I2C_SLAVE) && i2c_imx->slave)
> > > return i2c_imx_slave_isr(i2c_imx); -#endif
> > > +
> > > i2c_imx->i2csr = status;
> > > return i2c_imx_master_isr(i2c_imx);
> > > }
> > >
> >
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2020-03-04 06:55:33

by Biwen Li

[permalink] [raw]
Subject: RE: [EXT] Re: [v6] i2c: imx: support slave mode for imx I2C driver

>
> Caution: EXT Email
>
> Hi Biwen,
>
> On Wed, Mar 04, 2020 at 04:13:03AM +0000, Biwen Li wrote:
> > Hi Wolfram,
> >
> > Any comments?
>
> Wolfram is waiting until you react to our comments. Until this is not happened,
> I will not ACK this patch and Wolfram will not take it.
Hi Oleksij,

Okay, got it. Thank you for your reply.
Please look into my reply for you and Sascha.

Best Regards,
Biwen Li
>
> regards,
> Oleksij
>
> > Best Regards,
> > Biwen Li
> >
> > >
> > > Hi,
> > >
> > > On 04.12.19 11:00, Sascha Hauer wrote:
> > > > Hi,
> > > >
> > > > The patch looks ok to me now, but I still do not like the
> > > > #ifdeffery around CONFIG_I2C_SLAVE. With the patch I just sent
> > > > (You are on Cc:) we could apply the following on your patch which
> > > > makes it more readable and increases compile coverage.
> > > >
> > > > Wolfram, Biwen, what do you think?
Hi Sascha,

Your patch is ok. But I agree with RCAR.(Keep I2C_SLAVE).
In first version I get a build error, so I add the option in second version patch.
If you want to remove the option I2C_SLAVE, firstly you should
delete it in <linux kernel source code>/include/linux/i2c.h. Then
build error will be gone and it's safe to remove option I2C_SLAVE.

Best Regards,
Biwen Li
> > >
> > >
> > > RCAR depends on slave:
> > > config I2C_RCAR
> > >
> > > tristate "Renesas R-Car I2C Controller"
> > >
> > > depends on ARCH_RENESAS || COMPILE_TEST
> > >
> > > select I2C_SLAVE
> > > see:
> > > drivers/i2c/busses/i2c-rcar.c
> > >
> > > So, I would suggest to do the same in imx.
> > >
> > > So far, I tested this patch on iMX6S. It works in one board
> > > (i2c-gpio + i2c-imx) and two board (i2c-imx + i2c-imx) configuration.
> > > Tested-by: Oleksij Rempel <[email protected]>
Hi Oleksij,

Okay, thank you so much.
I agree with your suggestions.

Best Regards,
Biwen Li
> > >
> > >
> > > >
> > > > Sascha
> > > >
> > > > ---------------------------8<------------------------------
> > > >
> > > > From 52f7c2bf59db61d4b27b59ca6404136e3ed77310 Mon Sep 17
> > > 00:00:00
> > > > 2001
> > > > From: Sascha Hauer <[email protected]>
> > > > Date: Wed, 4 Dec 2019 10:56:34 +0100
> > > > Subject: [PATCH] fixup! i2c: imx: support slave mode for imx I2C
> > > > driver
> > > >
> > > > ---
> > > > drivers/i2c/busses/i2c-imx.c | 21 ++++++++++-----------
> > > > 1 file changed, 10 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/drivers/i2c/busses/i2c-imx.c
> > > > b/drivers/i2c/busses/i2c-imx.c index 40ccfca600bf..c5d9ae8226cd
> > > > 100644
> > > > --- a/drivers/i2c/busses/i2c-imx.c
> > > > +++ b/drivers/i2c/busses/i2c-imx.c
> > > > @@ -203,9 +203,7 @@ struct imx_i2c_struct {
> > > > struct pinctrl_state *pinctrl_pins_gpio;
> > > >
> > > > struct imx_i2c_dma *dma;
> > > > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > > > struct i2c_client *slave;
> > > > -#endif
> > > > };
> > > >
> > > > static const struct imx_i2c_hwdata imx1_i2c_hwdata = { @@
> > > > -913,12
> > > > +911,10 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
> > > >
> > > > dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
> > > >
> > > > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > > > if (i2c_imx->slave) {
> > > > dev_err(&i2c_imx->adapter.dev, "Please not do
> > > > operations
> > > of master mode in slave mode");
> > > > return -EBUSY;
> > > > }
> > > > -#endif
> > > >
> > > > result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
> > > > if (result < 0)
> > > > @@ -1068,7 +1064,6 @@ static u32 i2c_imx_func(struct i2c_adapter
> > > *adapter)
> > > > | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
> > > > }
> > > >
> > > > -#if IS_ENABLED(CONFIG_I2C_SLAVE)
> > > > static int i2c_imx_slave_init(struct imx_i2c_struct *i2c_imx)
> > > > {
> > > > int temp;
> > > > @@ -1159,6 +1154,10 @@ static int i2c_imx_reg_slave(struct
> > > > i2c_client
> > > *client)
> > > > {
> > > > struct imx_i2c_struct *i2c_imx =
> i2c_get_adapdata(client->adapter);
> > > > int ret;
> > > > +
> > > > + if (!IS_ENABLED(CONFIG_I2C_SLAVE))
> > > > + return -EINVAL;
> > > > +
> > > > if (i2c_imx->slave)
> > > > return -EBUSY;
> > > >
> > > > @@ -1173,6 +1172,9 @@ static int i2c_imx_unreg_slave(struct
> > > > i2c_client
> > > *client)
> > > > {
> > > > struct imx_i2c_struct *i2c_imx =
> > > > i2c_get_adapdata(client->adapter);
> > > >
> > > > + if (!IS_ENABLED(CONFIG_I2C_SLAVE))
> > > > + return -EINVAL;
> > > > +
> > > > if (!i2c_imx->slave)
> > > > return -EINVAL;
> > > >
> > > > @@ -1188,15 +1190,12 @@ static int i2c_imx_unreg_slave(struct
> > > > i2c_client *client)
> > > >
> > > > return 0;
> > > > }
> > > > -#endif
> > > >
> > > > static const struct i2c_algorithm i2c_imx_algo = {
> > > > .master_xfer = i2c_imx_xfer,
> > > > .functionality = i2c_imx_func, -#if
> > > > IS_ENABLED(CONFIG_I2C_SLAVE)
> > > > .reg_slave = i2c_imx_reg_slave,
> > > > .unreg_slave = i2c_imx_unreg_slave,
> > > > -#endif
> > > > };
> > > >
> > > > static irqreturn_t i2c_imx_isr(int irq, void *dev_id) @@
> > > > -1208,10
> > > > +1207,10 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
> > > >
> > > > if (status & I2SR_IIF) {
> > > > i2c_imx_clr_if_bit(status, i2c_imx); -#if
> > > > IS_ENABLED(CONFIG_I2C_SLAVE)
> > > > - if (i2c_imx->slave)
> > > > +
> > > > + if (IS_ENABLED(CONFIG_I2C_SLAVE) && i2c_imx->slave)
> > > > return i2c_imx_slave_isr(i2c_imx); -#endif
> > > > +
> > > > i2c_imx->i2csr = status;
> > > > return i2c_imx_master_isr(i2c_imx);
> > > > }
> > > >
> > >
> --
> Pengutronix e.K. |
> |
> Steuerwalder Str. 21 |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.
> pengutronix.de%2F&amp;data=02%7C01%7Cbiwen.li%40nxp.com%7Ce5b72
> 9bd982449714e7708d7bffc0f7f%7C686ea1d3bc2b4c6fa92cd99c5c301635
> %7C0%7C0%7C637188961657171765&amp;sdata=6NGHA8U89taUe48JY7
> GT23wYNrvvTVXQ%2BOfrT3sZmDk%3D&amp;reserved=0 |
> 31137 Hildesheim, Germany | Phone:
> +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax:
> +49-5121-206917-5555 |