* [PATCH v2] emev2: add slave support
@ 2015-12-05 17:51 ` Niklas Söderlund
0 siblings, 0 replies; 8+ messages in thread
From: Niklas Söderlund @ 2015-12-05 17:51 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 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.
Changes since v1:
- Fixed sparse errors, thanks Wolfram
- Updated email to contain +renesas
Niklas Söderlund (1):
i2c: emev2: add slave support
drivers/i2c/busses/i2c-emev2.c | 112 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 111 insertions(+), 1 deletion(-)
--
2.6.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] emev2: add slave support
@ 2015-12-05 17:51 ` Niklas Söderlund
0 siblings, 0 replies; 8+ messages in thread
From: Niklas Söderlund @ 2015-12-05 17:51 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 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.
Changes since v1:
- Fixed sparse errors, thanks Wolfram
- Updated email to contain +renesas
Niklas Söderlund (1):
i2c: emev2: add slave support
drivers/i2c/busses/i2c-emev2.c | 112 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 111 insertions(+), 1 deletion(-)
--
2.6.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] i2c: emev2: add slave support
2015-12-05 17:51 ` Niklas Söderlund
@ 2015-12-05 17:51 ` Niklas Söderlund
-1 siblings, 0 replies; 8+ messages in thread
From: Niklas Söderlund @ 2015-12-05 17:51 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+renesas@ragnatech.se>
---
drivers/i2c/busses/i2c-emev2.c | 112 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 111 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c
index 192ef6b..96bb4e7 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,131 @@ 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;
+ enum i2c_slave_event event;
+ int ret;
+
+ 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 */
+ 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);
+ 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.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2] i2c: emev2: add slave support
@ 2015-12-05 17:51 ` Niklas Söderlund
0 siblings, 0 replies; 8+ messages in thread
From: Niklas Söderlund @ 2015-12-05 17:51 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+renesas@ragnatech.se>
---
drivers/i2c/busses/i2c-emev2.c | 112 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 111 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-emev2.c b/drivers/i2c/busses/i2c-emev2.c
index 192ef6b..96bb4e7 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,131 @@ 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;
+ enum i2c_slave_event event;
+ int ret;
+
+ 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 */
+ 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);
+ 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.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] i2c: emev2: add slave support
2015-12-05 17:51 ` Niklas Söderlund
@ 2015-12-05 18:56 ` Wolfram Sang
-1 siblings, 0 replies; 8+ messages in thread
From: Wolfram Sang @ 2015-12-05 18:56 UTC (permalink / raw)
To: Niklas Söderlund
Cc: linux-i2c, ian.molton, laurent.pinchart, magnus.damm, linux-sh,
Niklas Söderlund
[-- Attachment #1: Type: text/plain, Size: 243 bytes --]
On Sat, Dec 05, 2015 at 06:51:31PM +0100, Niklas Söderlund wrote:
> Add I2C slave provider using the generic slave interface.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Applied to for-next, thanks!
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] i2c: emev2: add slave support
@ 2015-12-05 18:56 ` Wolfram Sang
0 siblings, 0 replies; 8+ messages in thread
From: Wolfram Sang @ 2015-12-05 18:56 UTC (permalink / raw)
To: Niklas Söderlund
Cc: linux-i2c, ian.molton, laurent.pinchart, magnus.damm, linux-sh,
Niklas Söderlund
[-- Attachment #1: Type: text/plain, Size: 243 bytes --]
On Sat, Dec 05, 2015 at 06:51:31PM +0100, Niklas Söderlund wrote:
> Add I2C slave provider using the generic slave interface.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Applied to for-next, thanks!
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] emev2: add slave support
2015-12-05 17:51 ` Niklas Söderlund
@ 2015-12-05 18:59 ` Wolfram Sang
-1 siblings, 0 replies; 8+ messages in thread
From: Wolfram Sang @ 2015-12-05 18:59 UTC (permalink / raw)
To: Niklas Söderlund
Cc: linux-i2c, ian.molton, laurent.pinchart, magnus.damm, linux-sh,
Niklas Söderlund
[-- Attachment #1: Type: text/plain, Size: 85 bytes --]
> - Updated email to contain +renesas
This mail address did not work a second ago.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] emev2: add slave support
@ 2015-12-05 18:59 ` Wolfram Sang
0 siblings, 0 replies; 8+ messages in thread
From: Wolfram Sang @ 2015-12-05 18:59 UTC (permalink / raw)
To: Niklas Söderlund
Cc: linux-i2c, ian.molton, laurent.pinchart, magnus.damm, linux-sh,
Niklas Söderlund
[-- Attachment #1: Type: text/plain, Size: 85 bytes --]
> - Updated email to contain +renesas
This mail address did not work a second ago.
[-- 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-05 18:59 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-05 17:51 [PATCH v2] emev2: add slave support Niklas Söderlund
2015-12-05 17:51 ` Niklas Söderlund
2015-12-05 17:51 ` [PATCH v2] i2c: " Niklas Söderlund
2015-12-05 17:51 ` Niklas Söderlund
2015-12-05 18:56 ` Wolfram Sang
2015-12-05 18:56 ` Wolfram Sang
2015-12-05 18:59 ` [PATCH v2] " Wolfram Sang
2015-12-05 18:59 ` 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.