* [PATCH] i2c: emev2: add slave support @ 2015-11-30 0:15 ` Niklas Söderlund 0 siblings, 0 replies; 8+ messages in thread From: Niklas Söderlund @ 2015-11-30 0:15 UTC (permalink / raw) To: wsa, linux-i2c Cc: ian.molton, laurent.pinchart, magnus.damm, linux-sh, Niklas Söderlund Add i2c slave support to EMEV2. Tested using a EMEV2, BeagleBone Black and a 24c02 eeprom. While the EMEV2 provided a emulated eeprom on iic0 using slave-24c02 iic0 the Bone could talk to both the physical and the emulated eeprom. The EMEV2 could talk to the physical eeprom while still provide the emulated eeprom. Niklas Söderlund (1): i2c: emev2: add slave support drivers/i2c/busses/i2c-emev2.c | 110 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) -- 2.6.2 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] i2c: emev2: add slave support @ 2015-11-30 0:15 ` Niklas Söderlund 0 siblings, 0 replies; 8+ messages in thread From: Niklas Söderlund @ 2015-11-30 0:15 UTC (permalink / raw) To: wsa, linux-i2c Cc: ian.molton, laurent.pinchart, magnus.damm, linux-sh, Niklas Söderlund Add i2c slave support to EMEV2. Tested using a EMEV2, BeagleBone Black and a 24c02 eeprom. While the EMEV2 provided a emulated eeprom on iic0 using slave-24c02 iic0 the Bone could talk to both the physical and the emulated eeprom. The EMEV2 could talk to the physical eeprom while still provide the emulated eeprom. Niklas Söderlund (1): i2c: emev2: add slave support drivers/i2c/busses/i2c-emev2.c | 110 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) -- 2.6.2 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] i2c: emev2: add slave support 2015-11-30 0:15 ` Niklas Söderlund @ 2015-11-30 0:15 ` Niklas Söderlund -1 siblings, 0 replies; 8+ messages in thread From: Niklas Söderlund @ 2015-11-30 0:15 UTC (permalink / raw) To: wsa, linux-i2c Cc: ian.molton, laurent.pinchart, magnus.damm, linux-sh, Niklas Söderlund Add I2C slave provider using the generic slave interface. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> --- drivers/i2c/busses/i2c-emev2.c | 110 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c index 192ef6b..ad87b5a 100644 --- a/drivers/i2c/busses/i2c-emev2.c +++ b/drivers/i2c/busses/i2c-emev2.c @@ -71,6 +71,7 @@ struct em_i2c_device { struct i2c_adapter adap; struct completion msg_done; struct clk *sclk; + struct i2c_client *slave; }; static inline void em_clear_set_bit(struct em_i2c_device *priv, u8 clear, u8 set, u8 reg) @@ -226,22 +227,129 @@ static int em_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, return num; } +static bool em_i2c_slave_irq(struct em_i2c_device *priv) +{ + u8 status, value; + + if (!priv->slave) + return false; + + status = readb(priv->base + I2C_OFS_IICSE0); + + /* Extension code, do not participate */ + if (status & I2C_BIT_EXC0) { + em_clear_set_bit(priv, 0, I2C_BIT_LREL0, I2C_OFS_IICC0); + return true; + } + + /* Stop detected, we don't know if it's for slave or master */ + if (status & I2C_BIT_SPD0) { + /* Notify slave device */ + i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value); + /* Pretend we did not handle the interrupt */ + return false; + } + + /* Only handle interrupts addressed to us */ + if (!(status & I2C_BIT_COI0)) + return false; + + /* Enable stop interrupts */ + em_clear_set_bit(priv, 0, I2C_BIT_SPIE0, I2C_OFS_IICC0); + + /* Transmission or Reception */ + if (status & I2C_BIT_TRC0) { + if (status & I2C_BIT_ACKD0) { + /* 9 bit interrupt mode */ + em_clear_set_bit(priv, 0, I2C_BIT_WTIM0, I2C_OFS_IICC0); + + /* Send data */ + enum i2c_slave_event event = status & I2C_BIT_STD0 ? + I2C_SLAVE_READ_REQUESTED : + I2C_SLAVE_READ_PROCESSED; + i2c_slave_event(priv->slave, event, &value); + writeb(value, priv->base + I2C_OFS_IIC0); + } else { + /* NACK, stop transmitting */ + em_clear_set_bit(priv, 0, I2C_BIT_LREL0, I2C_OFS_IICC0); + } + } else { + /* 8 bit interrupt mode */ + em_clear_set_bit(priv, I2C_BIT_WTIM0, I2C_BIT_ACKE0, + I2C_OFS_IICC0); + em_clear_set_bit(priv, I2C_BIT_WTIM0, I2C_BIT_WREL0, + I2C_OFS_IICC0); + + if (status & I2C_BIT_STD0) { + i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, + &value); + } else { + /* Recv data */ + value = readb(priv->base + I2C_OFS_IIC0); + int ret = i2c_slave_event(priv->slave, + I2C_SLAVE_WRITE_RECEIVED, &value); + if (ret < 0) + em_clear_set_bit(priv, I2C_BIT_ACKE0, 0, + I2C_OFS_IICC0); + } + } + + return true; +} + static irqreturn_t em_i2c_irq_handler(int this_irq, void *dev_id) { struct em_i2c_device *priv = dev_id; + if (em_i2c_slave_irq(priv)) + return IRQ_HANDLED; + complete(&priv->msg_done); + return IRQ_HANDLED; } static u32 em_i2c_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SLAVE; +} + +static int em_i2c_reg_slave(struct i2c_client *slave) +{ + struct em_i2c_device *priv = i2c_get_adapdata(slave->adapter); + + if (priv->slave) + return -EBUSY; + + if (slave->flags & I2C_CLIENT_TEN) + return -EAFNOSUPPORT; + + priv->slave = slave; + + /* Set slave address */ + writeb(slave->addr << 1, priv->base + I2C_OFS_SVA0); + + return 0; +} + +static int em_i2c_unreg_slave(struct i2c_client *slave) +{ + struct em_i2c_device *priv = i2c_get_adapdata(slave->adapter); + + WARN_ON(!priv->slave); + + writeb(0, priv->base + I2C_OFS_SVA0); + + priv->slave = NULL; + + return 0; } static struct i2c_algorithm em_i2c_algo = { .master_xfer = em_i2c_xfer, .functionality = em_i2c_func, + .reg_slave = em_i2c_reg_slave, + .unreg_slave = em_i2c_unreg_slave, }; static int em_i2c_probe(struct platform_device *pdev) -- 2.6.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH] i2c: emev2: add slave support @ 2015-11-30 0:15 ` Niklas Söderlund 0 siblings, 0 replies; 8+ messages in thread From: Niklas Söderlund @ 2015-11-30 0:15 UTC (permalink / raw) To: wsa, linux-i2c Cc: ian.molton, laurent.pinchart, magnus.damm, linux-sh, Niklas Söderlund Add I2C slave provider using the generic slave interface. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> --- drivers/i2c/busses/i2c-emev2.c | 110 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c index 192ef6b..ad87b5a 100644 --- a/drivers/i2c/busses/i2c-emev2.c +++ b/drivers/i2c/busses/i2c-emev2.c @@ -71,6 +71,7 @@ struct em_i2c_device { struct i2c_adapter adap; struct completion msg_done; struct clk *sclk; + struct i2c_client *slave; }; static inline void em_clear_set_bit(struct em_i2c_device *priv, u8 clear, u8 set, u8 reg) @@ -226,22 +227,129 @@ static int em_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, return num; } +static bool em_i2c_slave_irq(struct em_i2c_device *priv) +{ + u8 status, value; + + if (!priv->slave) + return false; + + status = readb(priv->base + I2C_OFS_IICSE0); + + /* Extension code, do not participate */ + if (status & I2C_BIT_EXC0) { + em_clear_set_bit(priv, 0, I2C_BIT_LREL0, I2C_OFS_IICC0); + return true; + } + + /* Stop detected, we don't know if it's for slave or master */ + if (status & I2C_BIT_SPD0) { + /* Notify slave device */ + i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value); + /* Pretend we did not handle the interrupt */ + return false; + } + + /* Only handle interrupts addressed to us */ + if (!(status & I2C_BIT_COI0)) + return false; + + /* Enable stop interrupts */ + em_clear_set_bit(priv, 0, I2C_BIT_SPIE0, I2C_OFS_IICC0); + + /* Transmission or Reception */ + if (status & I2C_BIT_TRC0) { + if (status & I2C_BIT_ACKD0) { + /* 9 bit interrupt mode */ + em_clear_set_bit(priv, 0, I2C_BIT_WTIM0, I2C_OFS_IICC0); + + /* Send data */ + enum i2c_slave_event event = status & I2C_BIT_STD0 ? + I2C_SLAVE_READ_REQUESTED : + I2C_SLAVE_READ_PROCESSED; + i2c_slave_event(priv->slave, event, &value); + writeb(value, priv->base + I2C_OFS_IIC0); + } else { + /* NACK, stop transmitting */ + em_clear_set_bit(priv, 0, I2C_BIT_LREL0, I2C_OFS_IICC0); + } + } else { + /* 8 bit interrupt mode */ + em_clear_set_bit(priv, I2C_BIT_WTIM0, I2C_BIT_ACKE0, + I2C_OFS_IICC0); + em_clear_set_bit(priv, I2C_BIT_WTIM0, I2C_BIT_WREL0, + I2C_OFS_IICC0); + + if (status & I2C_BIT_STD0) { + i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, + &value); + } else { + /* Recv data */ + value = readb(priv->base + I2C_OFS_IIC0); + int ret = i2c_slave_event(priv->slave, + I2C_SLAVE_WRITE_RECEIVED, &value); + if (ret < 0) + em_clear_set_bit(priv, I2C_BIT_ACKE0, 0, + I2C_OFS_IICC0); + } + } + + return true; +} + static irqreturn_t em_i2c_irq_handler(int this_irq, void *dev_id) { struct em_i2c_device *priv = dev_id; + if (em_i2c_slave_irq(priv)) + return IRQ_HANDLED; + complete(&priv->msg_done); + return IRQ_HANDLED; } static u32 em_i2c_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SLAVE; +} + +static int em_i2c_reg_slave(struct i2c_client *slave) +{ + struct em_i2c_device *priv = i2c_get_adapdata(slave->adapter); + + if (priv->slave) + return -EBUSY; + + if (slave->flags & I2C_CLIENT_TEN) + return -EAFNOSUPPORT; + + priv->slave = slave; + + /* Set slave address */ + writeb(slave->addr << 1, priv->base + I2C_OFS_SVA0); + + return 0; +} + +static int em_i2c_unreg_slave(struct i2c_client *slave) +{ + struct em_i2c_device *priv = i2c_get_adapdata(slave->adapter); + + WARN_ON(!priv->slave); + + writeb(0, priv->base + I2C_OFS_SVA0); + + priv->slave = NULL; + + return 0; } static struct i2c_algorithm em_i2c_algo = { .master_xfer = em_i2c_xfer, .functionality = em_i2c_func, + .reg_slave = em_i2c_reg_slave, + .unreg_slave = em_i2c_unreg_slave, }; static int em_i2c_probe(struct platform_device *pdev) -- 2.6.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] i2c: emev2: add slave support 2015-11-30 0:15 ` Niklas Söderlund @ 2015-12-03 21:03 ` Wolfram Sang -1 siblings, 0 replies; 8+ messages in thread From: Wolfram Sang @ 2015-12-03 21:03 UTC (permalink / raw) To: Niklas Söderlund Cc: linux-i2c, ian.molton, laurent.pinchart, magnus.damm, linux-sh [-- Attachment #1: Type: text/plain, Size: 423 bytes --] On Mon, Nov 30, 2015 at 01:15:58AM +0100, Niklas Söderlund wrote: > Add I2C slave provider using the generic slave interface. > > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Looks mostly fine. Sparse says: SPARSE drivers/i2c/busses/i2c-emev2.c:267:25: warning: mixing declarations and code drivers/i2c/busses/i2c-emev2.c:289:25: warning: mixing declarations and code Please fix. [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] i2c: emev2: add slave support @ 2015-12-03 21:03 ` Wolfram Sang 0 siblings, 0 replies; 8+ messages in thread From: Wolfram Sang @ 2015-12-03 21:03 UTC (permalink / raw) To: Niklas Söderlund Cc: linux-i2c, ian.molton, laurent.pinchart, magnus.damm, linux-sh [-- Attachment #1: Type: text/plain, Size: 423 bytes --] On Mon, Nov 30, 2015 at 01:15:58AM +0100, Niklas Söderlund wrote: > Add I2C slave provider using the generic slave interface. > > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Looks mostly fine. Sparse says: SPARSE drivers/i2c/busses/i2c-emev2.c:267:25: warning: mixing declarations and code drivers/i2c/busses/i2c-emev2.c:289:25: warning: mixing declarations and code Please fix. [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] i2c: emev2: add slave support 2015-11-30 0:15 ` Niklas Söderlund @ 2015-12-02 10:02 ` Wolfram Sang -1 siblings, 0 replies; 8+ messages in thread From: Wolfram Sang @ 2015-12-02 10:02 UTC (permalink / raw) To: Niklas Söderlund Cc: linux-i2c, ian.molton, laurent.pinchart, magnus.damm, linux-sh [-- Attachment #1: Type: text/plain, Size: 593 bytes --] On Mon, Nov 30, 2015 at 01:15:57AM +0100, Niklas Söderlund wrote: > Add i2c slave support to EMEV2. > > Tested using a EMEV2, BeagleBone Black and a 24c02 eeprom. While the > EMEV2 provided a emulated eeprom on iic0 using slave-24c02 iic0 the Bone > could talk to both the physical and the emulated eeprom. The EMEV2 could > talk to the physical eeprom while still provide the emulated eeprom. Yay, good testing here. Which board did you use? KZM9D? Do you have pin descriptions for the connectors, if so? I am looking for these for quite some time. Thanks, Wolfram [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] i2c: emev2: add slave support @ 2015-12-02 10:02 ` Wolfram Sang 0 siblings, 0 replies; 8+ messages in thread From: Wolfram Sang @ 2015-12-02 10:02 UTC (permalink / raw) To: Niklas Söderlund Cc: linux-i2c, ian.molton, laurent.pinchart, magnus.damm, linux-sh [-- Attachment #1: Type: text/plain, Size: 593 bytes --] On Mon, Nov 30, 2015 at 01:15:57AM +0100, Niklas Söderlund wrote: > Add i2c slave support to EMEV2. > > Tested using a EMEV2, BeagleBone Black and a 24c02 eeprom. While the > EMEV2 provided a emulated eeprom on iic0 using slave-24c02 iic0 the Bone > could talk to both the physical and the emulated eeprom. The EMEV2 could > talk to the physical eeprom while still provide the emulated eeprom. Yay, good testing here. Which board did you use? KZM9D? Do you have pin descriptions for the connectors, if so? I am looking for these for quite some time. Thanks, Wolfram [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-12-03 21:03 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-11-30 0:15 [PATCH] i2c: emev2: add slave support Niklas Söderlund 2015-11-30 0:15 ` Niklas Söderlund 2015-11-30 0:15 ` Niklas Söderlund 2015-11-30 0:15 ` Niklas Söderlund 2015-12-03 21:03 ` Wolfram Sang 2015-12-03 21:03 ` Wolfram Sang 2015-12-02 10:02 ` Wolfram Sang 2015-12-02 10:02 ` Wolfram Sang
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.