qemu-devel.nongnu.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).