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
next prev parent 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).