All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Andreas Färber" <afaerber@suse.de>
To: Jean-Christophe DUBOIS <jcd@tribudubois.net>
Cc: peter.maydell@linaro.org, peter.crosthwaite@xilinx.com,
	peter.chubb@nicta.com.au, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 4/4] Add qtest support for i.MX I2C device emulation.
Date: Sat, 04 May 2013 18:53:41 +0200	[thread overview]
Message-ID: <51853D15.7040409@suse.de> (raw)
In-Reply-To: <e4904950b6cfb64d42a2af694caef301024fb07d.1367676178.git.jcd@tribudubois.net>

Am 04.05.2013 16:09, schrieb Jean-Christophe DUBOIS:
> This is using a ds1338 RTC chip on the i2c bus. This RTC
> chip is nop present on the real board
> 
> Signed-off-by: Jean-Christophe DUBOIS <jcd@tribudubois.net>
> ---
>  tests/Makefile         |   3 +
>  tests/ds1338-test.c    |  64 ++++++++++++++
>  tests/libqos/i2c-imx.c | 224 +++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/libqos/i2c.h     |   3 +
>  4 files changed, 294 insertions(+)
>  create mode 100644 tests/ds1338-test.c
>  create mode 100644 tests/libqos/i2c-imx.c
[...]

The qtest itself looks fine, thanks.

> diff --git a/tests/libqos/i2c-imx.c b/tests/libqos/i2c-imx.c
> new file mode 100644
> index 0000000..da7316f
> --- /dev/null
> +++ b/tests/libqos/i2c-imx.c
> @@ -0,0 +1,224 @@
> +/*
> + * QTest i.MX I2C driver
> + *
> + * Copyright (c) 2013 Jean-Christophe Dubois
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +#include "libqos/i2c.h"
> +
> +#include <glib.h>
> +#include <string.h>
> +
> +#include "qemu/osdep.h"

> +#include "qemu/bswap.h"

Is this one needed?

> +#include "libqtest.h"
> +

> +enum IMXI2CRegisters {
> +    IMX_I2C_IADR = 0x00,
> +    IMX_I2C_IFDR = 0x04,
> +    IMX_I2C_I2CR = 0x08,
> +    IMX_I2C_I2SR = 0x0c,
> +    IMX_I2C_I2DR = 0x10,
> +};
> +
> +enum IMXI2CCRBits {
> +    IMX_I2C_I2CR_IEN  = 1 << 7,
> +    IMX_I2C_I2CR_IIEN = 1 << 6,
> +    IMX_I2C_I2CR_MSTA = 1 << 5,
> +    IMX_I2C_I2CR_MTX  = 1 << 4,
> +    IMX_I2C_I2CR_TXAK = 1 << 3,
> +    IMX_I2C_I2CR_RSTA = 1 << 2,
> +};
> +
> +enum IMXI2CSRBits {
> +    IMX_I2C_I2SR_ICF  = 1 << 7,
> +    IMX_I2C_I2SR_IAAF = 1 << 6,
> +    IMX_I2C_I2SR_IBB  = 1 << 5,
> +    IMX_I2C_I2SR_IAL  = 1 << 4,
> +    IMX_I2C_I2SR_SRW  = 1 << 2,
> +    IMX_I2C_I2SR_IIF  = 1 << 1,
> +    IMX_I2C_I2SR_RXAK = 1 << 0,
> +};
> +
> +enum IMXI2CDirection {
> +    IMX_I2C_READ,
> +    IMX_I2C_WRITE,
> +};

libqos/i2c-omap.c was a driver for an unmaintained legacy device.
i.MX I2C however is being added by you in 2/4, so it would be better to
put these constants in a header in 2/4 for reuse here (i2c/imx_regs.h?).

Otherwise looking fine!

Regards,
Andreas

> +
> +typedef struct IMXI2C {
> +    I2CAdapter parent;
> +
> +    uint64_t addr;
> +} IMXI2C;
> +
> +
> +static void imx_i2c_set_slave_addr(IMXI2C *s, uint8_t addr,
> +                                   enum IMXI2CDirection direction)
> +{
> +    writeb(s->addr + IMX_I2C_I2DR, (addr << 1) |
> +           (direction == IMX_I2C_READ ? 1 : 0));
> +}
> +
> +static void imx_i2c_send(I2CAdapter *i2c, uint8_t addr,
> +                         const uint8_t *buf, uint16_t len)
> +{
> +    IMXI2C *s = (IMXI2C *)i2c;
> +    uint8_t data;
> +    uint8_t status;
> +    uint16_t size = 0;
> +
> +    if (!len) {
> +        return;
> +    }
> +
> +    /* set the bus for write */
> +    data = IMX_I2C_I2CR_IEN |
> +           IMX_I2C_I2CR_IIEN |
> +           IMX_I2C_I2CR_MSTA |
> +           IMX_I2C_I2CR_MTX |
> +           IMX_I2C_I2CR_TXAK;
> +
> +    writeb(s->addr + IMX_I2C_I2CR, data);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IBB) != 0);
> +
> +    /* set the slave address */
> +    imx_i2c_set_slave_addr(s, addr, IMX_I2C_WRITE);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IIF) != 0);
> +    g_assert((status & IMX_I2C_I2SR_RXAK) == 0);
> +
> +    /* ack the interrupt */
> +    writeb(s->addr + IMX_I2C_I2SR, 0);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IIF) == 0);
> +
> +    while (size < len) {
> +        /* check we are still busy */
> +        status = readb(s->addr + IMX_I2C_I2SR);
> +        g_assert((status & IMX_I2C_I2SR_IBB) != 0);
> +
> +        /* write the data */
> +        writeb(s->addr + IMX_I2C_I2DR, buf[size]);
> +        status = readb(s->addr + IMX_I2C_I2SR);
> +        g_assert((status & IMX_I2C_I2SR_IIF) != 0);
> +        g_assert((status & IMX_I2C_I2SR_RXAK) == 0);
> +
> +        /* ack the interrupt */
> +        writeb(s->addr + IMX_I2C_I2SR, 0);
> +        status = readb(s->addr + IMX_I2C_I2SR);
> +        g_assert((status & IMX_I2C_I2SR_IIF) == 0);
> +
> +        size++;
> +    }
> +
> +    /* release the bus */
> +    data &= ~(IMX_I2C_I2CR_MSTA | IMX_I2C_I2CR_MTX);
> +    writeb(s->addr + IMX_I2C_I2CR, data);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IBB) == 0);
> +}
> +
> +static void imx_i2c_recv(I2CAdapter *i2c, uint8_t addr,
> +                         uint8_t *buf, uint16_t len)
> +{
> +    IMXI2C *s = (IMXI2C *)i2c;
> +    uint8_t data;
> +    uint8_t status;
> +    uint16_t size = 0;
> +
> +    if (!len) {
> +        return;
> +    }
> +
> +    /* set the bus for write */
> +    data = IMX_I2C_I2CR_IEN |
> +           IMX_I2C_I2CR_IIEN |
> +           IMX_I2C_I2CR_MSTA |
> +           IMX_I2C_I2CR_MTX |
> +           IMX_I2C_I2CR_TXAK;
> +
> +    writeb(s->addr + IMX_I2C_I2CR, data);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IBB) != 0);
> +
> +    /* set the slave address */
> +    imx_i2c_set_slave_addr(s, addr, IMX_I2C_READ);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IIF) != 0);
> +    g_assert((status & IMX_I2C_I2SR_RXAK) == 0);
> +
> +    /* ack the interrupt */
> +    writeb(s->addr + IMX_I2C_I2SR, 0);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IIF) == 0);
> +
> +    /* set the bus for read */
> +    data &= ~IMX_I2C_I2CR_MTX;
> +    /* if only one byte don't ack */
> +    if (len != 1) {
> +        data &= ~IMX_I2C_I2CR_TXAK;
> +    }
> +    writeb(s->addr + IMX_I2C_I2CR, data);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IBB) != 0);
> +
> +    /* dummy read */
> +    readb(s->addr + IMX_I2C_I2DR);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IIF) != 0);
> +
> +    /* ack the interrupt */
> +    writeb(s->addr + IMX_I2C_I2SR, 0);
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IIF) == 0);
> +
> +    while (size < len) {
> +        /* check we are still busy */
> +        status = readb(s->addr + IMX_I2C_I2SR);
> +        g_assert((status & IMX_I2C_I2SR_IBB) != 0);
> +
> +        if (size == (len - 1)) {
> +            /* stop the read transaction */
> +            data &= ~(IMX_I2C_I2CR_MSTA | IMX_I2C_I2CR_MTX);
> +        } else {
> +            /* ack the data read */
> +            data |= IMX_I2C_I2CR_TXAK;
> +        }
> +        writeb(s->addr + IMX_I2C_I2CR, data);
> +
> +        /* read the data */
> +        buf[size] = readb(s->addr + IMX_I2C_I2DR);
> +
> +        if (size != (len - 1)) {
> +            status = readb(s->addr + IMX_I2C_I2SR);
> +            g_assert((status & IMX_I2C_I2SR_IIF) != 0);
> +
> +            /* ack the interrupt */
> +            writeb(s->addr + IMX_I2C_I2SR, 0);
> +        }
> +
> +        status = readb(s->addr + IMX_I2C_I2SR);
> +        g_assert((status & IMX_I2C_I2SR_IIF) == 0);
> +
> +        size++;
> +    }
> +
> +    status = readb(s->addr + IMX_I2C_I2SR);
> +    g_assert((status & IMX_I2C_I2SR_IBB) == 0);
> +}
> +
> +I2CAdapter *imx_i2c_create(uint64_t addr)
> +{
> +    IMXI2C *s = g_malloc0(sizeof(*s));
> +    I2CAdapter *i2c = (I2CAdapter *)s;
> +
> +    s->addr = addr;
> +
> +    i2c->send = imx_i2c_send;
> +    i2c->recv = imx_i2c_recv;
> +
> +    return i2c;
> +}
> diff --git a/tests/libqos/i2c.h b/tests/libqos/i2c.h
> index 1ce9af4..c21f1dc 100644
> --- a/tests/libqos/i2c.h
> +++ b/tests/libqos/i2c.h
> @@ -27,4 +27,7 @@ void i2c_recv(I2CAdapter *i2c, uint8_t addr,
>  /* libi2c-omap.c */
>  I2CAdapter *omap_i2c_create(uint64_t addr);
>  
> +/* libi2c-imx.c */
> +I2CAdapter *imx_i2c_create(uint64_t addr);
> +
>  #endif
> 


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

  reply	other threads:[~2013-05-04 16:53 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-04 14:09 [Qemu-devel] [PATCH v2 0/4] Add i.MX25 support through the 3DS evaluation board Jean-Christophe DUBOIS
2013-05-04 14:09 ` [Qemu-devel] [PATCH v2 1/4] Add i.MX FEC Ethernet driver Jean-Christophe DUBOIS
2013-05-05  3:11   ` Peter Crosthwaite
2013-05-05 11:46     ` Andreas Färber
2013-05-05 11:59       ` Peter Crosthwaite
2013-05-05 12:41         ` Peter Maydell
2013-05-05 13:14     ` Jean-Christophe DUBOIS
2013-05-05 13:31       ` Andreas Färber
2013-05-05 14:05         ` Jean-Christophe DUBOIS
2013-05-05 17:49   ` Michael S. Tsirkin
2013-05-05 18:01     ` Peter Maydell
2013-05-05 21:15       ` Michael S. Tsirkin
2013-05-05 22:00         ` Peter Maydell
2013-05-06  8:51           ` Michael S. Tsirkin
2013-05-06  9:08             ` Peter Maydell
2013-05-06  9:24               ` Michael S. Tsirkin
2013-05-06 12:01                 ` Peter Maydell
2013-05-07  0:39                   ` Peter Crosthwaite
2013-05-07  9:03                     ` Peter Maydell
2013-05-04 14:09 ` [Qemu-devel] [PATCH v2 2/4] Add i.MX I2C controller driver Jean-Christophe DUBOIS
2013-05-05  3:14   ` Peter Crosthwaite
2013-05-05  3:58     ` Jean-Christophe DUBOIS
2013-05-05 10:47       ` Peter Maydell
2013-05-05 10:53         ` Peter Crosthwaite
2013-05-05 11:41           ` Peter Maydell
2013-05-05 11:53             ` Peter Crosthwaite
2013-05-05 12:28               ` Jean-Christophe DUBOIS
2013-05-05 11:34     ` Andreas Färber
2013-05-05 12:34       ` Jean-Christophe DUBOIS
2013-05-04 14:09 ` [Qemu-devel] [PATCH v2 3/4] Add i.MX25 3DS evaluation board support Jean-Christophe DUBOIS
2013-05-04 14:09 ` [Qemu-devel] [PATCH v2 4/4] Add qtest support for i.MX I2C device emulation Jean-Christophe DUBOIS
2013-05-04 16:53   ` Andreas Färber [this message]
2013-05-04 19:02     ` Jean-Christophe DUBOIS
2013-05-04 19:48       ` [Qemu-devel] compile the latest source in mac error Peter Cheung
2013-05-04 20:51         ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51853D15.7040409@suse.de \
    --to=afaerber@suse.de \
    --cc=jcd@tribudubois.net \
    --cc=peter.chubb@nicta.com.au \
    --cc=peter.crosthwaite@xilinx.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.