Skip to content

Commit

Permalink
libqos: i2c: move address into QI2CDevice
Browse files Browse the repository at this point in the history
This removes the hardcoded I2C address from the tests.  The address
is passed via QOSGraphEdgeOptions to i2c_device_create and stored
in the QI2CDevice.

The i2c_send and i2c_recv functions, along with their wrappers,
therefore, can be changed to take a QI2CDevice rather than an
adapter/address pair.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
bonzini committed Jun 3, 2019
1 parent 8130dbc commit 0659947
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 75 deletions.
4 changes: 2 additions & 2 deletions tests/ds1338-test.c
Expand Up @@ -31,13 +31,12 @@ static inline uint8_t bcd2bin(uint8_t x)
static void send_and_receive(void *obj, void *data, QGuestAllocator *alloc)
{
QI2CDevice *i2cdev = (QI2CDevice *)obj;
I2CAdapter *i2c = i2cdev->bus;

uint8_t resp[7];
time_t now = time(NULL);
struct tm *tm_ptr = gmtime(&now);

i2c_read_block(i2c, DS1338_ADDR, 0, resp, sizeof(resp));
i2c_read_block(i2cdev, 0, resp, sizeof(resp));

/* check retrieved time againt local time */
g_assert_cmpuint(bcd2bin(resp[4]), == , tm_ptr->tm_mday);
Expand All @@ -50,6 +49,7 @@ static void ds1338_register_nodes(void)
QOSGraphEdgeOptions opts = {
.extra_device_opts = "address=0x68"
};
add_qi2c_address(&opts, &(QI2CAddress) { DS1338_ADDR });

qos_node_create_driver("ds1338", i2c_device_create);
qos_node_consumes("ds1338", "i2c-bus", &opts);
Expand Down
51 changes: 29 additions & 22 deletions tests/libqos/i2c.c
Expand Up @@ -10,69 +10,76 @@
#include "libqos/i2c.h"
#include "libqtest.h"

void i2c_send(I2CAdapter *i2c, uint8_t addr,
const uint8_t *buf, uint16_t len)
void i2c_send(QI2CDevice *i2cdev, const uint8_t *buf, uint16_t len)
{
i2c->send(i2c, addr, buf, len);
i2cdev->bus->send(i2cdev->bus, i2cdev->addr, buf, len);
}

void i2c_recv(I2CAdapter *i2c, uint8_t addr,
uint8_t *buf, uint16_t len)
void i2c_recv(QI2CDevice *i2cdev, uint8_t *buf, uint16_t len)
{
i2c->recv(i2c, addr, buf, len);
i2cdev->bus->recv(i2cdev->bus, i2cdev->addr, buf, len);
}

void i2c_read_block(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
uint8_t *buf, uint16_t len)
void i2c_read_block(QI2CDevice *i2cdev, uint8_t reg,
uint8_t *buf, uint16_t len)
{
i2c_send(i2c, addr, &reg, 1);
i2c_recv(i2c, addr, buf, len);
i2c_send(i2cdev, &reg, 1);
i2c_recv(i2cdev, buf, len);
}

void i2c_write_block(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
void i2c_write_block(QI2CDevice *i2cdev, uint8_t reg,
const uint8_t *buf, uint16_t len)
{
uint8_t *cmd = g_malloc(len + 1);
cmd[0] = reg;
memcpy(&cmd[1], buf, len);
i2c_send(i2c, addr, cmd, len + 1);
i2c_send(i2cdev, cmd, len + 1);
g_free(cmd);
}

uint8_t i2c_get8(I2CAdapter *i2c, uint8_t addr, uint8_t reg)
uint8_t i2c_get8(QI2CDevice *i2cdev, uint8_t reg)
{
uint8_t resp[1];
i2c_read_block(i2c, addr, reg, resp, sizeof(resp));
i2c_read_block(i2cdev, reg, resp, sizeof(resp));
return resp[0];
}

uint16_t i2c_get16(I2CAdapter *i2c, uint8_t addr, uint8_t reg)
uint16_t i2c_get16(QI2CDevice *i2cdev, uint8_t reg)
{
uint8_t resp[2];
i2c_read_block(i2c, addr, reg, resp, sizeof(resp));
i2c_read_block(i2cdev, reg, resp, sizeof(resp));
return (resp[0] << 8) | resp[1];
}

void i2c_set8(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
uint8_t value)
void i2c_set8(QI2CDevice *i2cdev, uint8_t reg, uint8_t value)
{
i2c_write_block(i2c, addr, reg, &value, 1);
i2c_write_block(i2cdev, reg, &value, 1);
}

void i2c_set16(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
uint16_t value)
void i2c_set16(QI2CDevice *i2cdev, uint8_t reg, uint16_t value)
{
uint8_t data[2];

data[0] = value >> 8;
data[1] = value & 255;
i2c_write_block(i2c, addr, reg, data, sizeof(data));
i2c_write_block(i2cdev, reg, data, sizeof(data));
}

void *i2c_device_create(void *i2c_bus, QGuestAllocator *alloc, void *addr)
{
QI2CDevice *i2cdev = g_new0(QI2CDevice, 1);

i2cdev->bus = i2c_bus;
if (addr) {
i2cdev->addr = ((QI2CAddress *)addr)->addr;
}
return &i2cdev->obj;
}

void add_qi2c_address(QOSGraphEdgeOptions *opts, QI2CAddress *addr)
{
g_assert(addr);

opts->arg = addr;
opts->size_arg = sizeof(QI2CAddress);
}
27 changes: 15 additions & 12 deletions tests/libqos/i2c.h
Expand Up @@ -22,6 +22,11 @@ struct I2CAdapter {
QTestState *qts;
};

typedef struct QI2CAddress QI2CAddress;
struct QI2CAddress {
uint8_t addr;
};

typedef struct QI2CDevice QI2CDevice;
struct QI2CDevice {
/*
Expand All @@ -36,25 +41,23 @@ struct QI2CDevice {
*/
QOSGraphObject obj;
I2CAdapter *bus;
uint8_t addr;
};

void *i2c_device_create(void *i2c_bus, QGuestAllocator *alloc, void *addr);
void add_qi2c_address(QOSGraphEdgeOptions *opts, QI2CAddress *addr);

void i2c_send(I2CAdapter *i2c, uint8_t addr,
const uint8_t *buf, uint16_t len);
void i2c_recv(I2CAdapter *i2c, uint8_t addr,
uint8_t *buf, uint16_t len);
void i2c_send(QI2CDevice *dev, const uint8_t *buf, uint16_t len);
void i2c_recv(QI2CDevice *dev, uint8_t *buf, uint16_t len);

void i2c_read_block(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
void i2c_read_block(QI2CDevice *dev, uint8_t reg,
uint8_t *buf, uint16_t len);
void i2c_write_block(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
void i2c_write_block(QI2CDevice *dev, uint8_t reg,
const uint8_t *buf, uint16_t len);
uint8_t i2c_get8(I2CAdapter *i2c, uint8_t addr, uint8_t reg);
uint16_t i2c_get16(I2CAdapter *i2c, uint8_t addr, uint8_t reg);
void i2c_set8(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
uint8_t value);
void i2c_set16(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
uint16_t value);
uint8_t i2c_get8(QI2CDevice *dev, uint8_t reg);
uint16_t i2c_get16(QI2CDevice *dev, uint8_t reg);
void i2c_set8(QI2CDevice *dev, uint8_t reg, uint8_t value);
void i2c_set16(QI2CDevice *dev, uint8_t reg, uint16_t value);

/* i2c-omap.c */
typedef struct OMAPI2C {
Expand Down
31 changes: 14 additions & 17 deletions tests/pca9552-test.c
Expand Up @@ -19,65 +19,61 @@

static void pca9552_init(QI2CDevice *i2cdev)
{
I2CAdapter *i2c = i2cdev->bus;

/* Switch on LEDs 0 and 12 */
i2c_set8(i2c, PCA9552_TEST_ADDR, PCA9552_LS0, 0x54);
i2c_set8(i2c, PCA9552_TEST_ADDR, PCA9552_LS3, 0x54);
i2c_set8(i2cdev, PCA9552_LS0, 0x54);
i2c_set8(i2cdev, PCA9552_LS3, 0x54);
}

static void receive_autoinc(void *obj, void *data, QGuestAllocator *alloc)
{
QI2CDevice *i2cdev = (QI2CDevice *)obj;
I2CAdapter *i2c = i2cdev->bus;
uint8_t resp;
uint8_t reg = PCA9552_LS0 | PCA9552_AUTOINC;

pca9552_init(i2cdev);

i2c_send(i2c, PCA9552_TEST_ADDR, &reg, 1);
i2c_send(i2cdev, &reg, 1);

/* PCA9552_LS0 */
i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1);
i2c_recv(i2cdev, &resp, 1);
g_assert_cmphex(resp, ==, 0x54);

/* PCA9552_LS1 */
i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1);
i2c_recv(i2cdev, &resp, 1);
g_assert_cmphex(resp, ==, 0x55);

/* PCA9552_LS2 */
i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1);
i2c_recv(i2cdev, &resp, 1);
g_assert_cmphex(resp, ==, 0x55);

/* PCA9552_LS3 */
i2c_recv(i2c, PCA9552_TEST_ADDR, &resp, 1);
i2c_recv(i2cdev, &resp, 1);
g_assert_cmphex(resp, ==, 0x54);
}

static void send_and_receive(void *obj, void *data, QGuestAllocator *alloc)
{
QI2CDevice *i2cdev = (QI2CDevice *)obj;
I2CAdapter *i2c = i2cdev->bus;
uint8_t value;

value = i2c_get8(i2c, PCA9552_TEST_ADDR, PCA9552_LS0);
value = i2c_get8(i2cdev, PCA9552_LS0);
g_assert_cmphex(value, ==, 0x55);

value = i2c_get8(i2c, PCA9552_TEST_ADDR, PCA9552_INPUT0);
value = i2c_get8(i2cdev, PCA9552_INPUT0);
g_assert_cmphex(value, ==, 0x0);

pca9552_init(i2cdev);

value = i2c_get8(i2c, PCA9552_TEST_ADDR, PCA9552_LS0);
value = i2c_get8(i2cdev, PCA9552_LS0);
g_assert_cmphex(value, ==, 0x54);

value = i2c_get8(i2c, PCA9552_TEST_ADDR, PCA9552_INPUT0);
value = i2c_get8(i2cdev, PCA9552_INPUT0);
g_assert_cmphex(value, ==, 0x01);

value = i2c_get8(i2c, PCA9552_TEST_ADDR, PCA9552_LS3);
value = i2c_get8(i2cdev, PCA9552_LS3);
g_assert_cmphex(value, ==, 0x54);

value = i2c_get8(i2c, PCA9552_TEST_ADDR, PCA9552_INPUT1);
value = i2c_get8(i2cdev, PCA9552_INPUT1);
g_assert_cmphex(value, ==, 0x10);
}

Expand All @@ -86,6 +82,7 @@ static void pca9552_register_nodes(void)
QOSGraphEdgeOptions opts = {
.extra_device_opts = "address=0x60"
};
add_qi2c_address(&opts, &(QI2CAddress) { 0x60 });

qos_node_create_driver("pca9552", i2c_device_create);
qos_node_consumes("pca9552", "i2c-bus", &opts);
Expand Down
44 changes: 22 additions & 22 deletions tests/tmp105-test.c
Expand Up @@ -46,19 +46,18 @@ static void send_and_receive(void *obj, void *data, QGuestAllocator *alloc)
{
uint16_t value;
QI2CDevice *i2cdev = (QI2CDevice *)obj;
I2CAdapter *i2c = i2cdev->bus;

value = qmp_tmp105_get_temperature(TMP105_TEST_ID);
g_assert_cmpuint(value, ==, 0);

value = i2c_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
value = i2c_get16(i2cdev, TMP105_REG_TEMPERATURE);
g_assert_cmphex(value, ==, 0);

qmp_tmp105_set_temperature(TMP105_TEST_ID, 20000);
value = qmp_tmp105_get_temperature(TMP105_TEST_ID);
g_assert_cmpuint(value, ==, 20000);

value = i2c_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
value = i2c_get16(i2cdev, TMP105_REG_TEMPERATURE);
g_assert_cmphex(value, ==, 0x1400);

qmp_tmp105_set_temperature(TMP105_TEST_ID, 20938); /* 20 + 15/16 */
Expand All @@ -67,50 +66,51 @@ static void send_and_receive(void *obj, void *data, QGuestAllocator *alloc)
g_assert_cmpuint(value, <, 20938 + TMP105_PRECISION/2);

/* Set config */
i2c_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x60);
value = i2c_get8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG);
i2c_set8(i2cdev, TMP105_REG_CONFIG, 0x60);
value = i2c_get8(i2cdev, TMP105_REG_CONFIG);
g_assert_cmphex(value, ==, 0x60);

value = i2c_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
value = i2c_get16(i2cdev, TMP105_REG_TEMPERATURE);
g_assert_cmphex(value, ==, 0x14f0);

/* Set precision to 9, 10, 11 bits. */
i2c_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x00);
g_assert_cmphex(i2c_get8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG), ==, 0x00);
value = i2c_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
i2c_set8(i2cdev, TMP105_REG_CONFIG, 0x00);
g_assert_cmphex(i2c_get8(i2cdev, TMP105_REG_CONFIG), ==, 0x00);
value = i2c_get16(i2cdev, TMP105_REG_TEMPERATURE);
g_assert_cmphex(value, ==, 0x1480);

i2c_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x20);
g_assert_cmphex(i2c_get8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG), ==, 0x20);
value = i2c_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
i2c_set8(i2cdev, TMP105_REG_CONFIG, 0x20);
g_assert_cmphex(i2c_get8(i2cdev, TMP105_REG_CONFIG), ==, 0x20);
value = i2c_get16(i2cdev, TMP105_REG_TEMPERATURE);
g_assert_cmphex(value, ==, 0x14c0);

i2c_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x40);
g_assert_cmphex(i2c_get8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG), ==, 0x40);
value = i2c_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
i2c_set8(i2cdev, TMP105_REG_CONFIG, 0x40);
g_assert_cmphex(i2c_get8(i2cdev, TMP105_REG_CONFIG), ==, 0x40);
value = i2c_get16(i2cdev, TMP105_REG_TEMPERATURE);
g_assert_cmphex(value, ==, 0x14e0);

/* stored precision remains the same */
value = qmp_tmp105_get_temperature(TMP105_TEST_ID);
g_assert_cmpuint(value, >=, 20938 - TMP105_PRECISION/2);
g_assert_cmpuint(value, <, 20938 + TMP105_PRECISION/2);

i2c_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x60);
g_assert_cmphex(i2c_get8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG), ==, 0x60);
value = i2c_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
i2c_set8(i2cdev, TMP105_REG_CONFIG, 0x60);
g_assert_cmphex(i2c_get8(i2cdev, TMP105_REG_CONFIG), ==, 0x60);
value = i2c_get16(i2cdev, TMP105_REG_TEMPERATURE);
g_assert_cmphex(value, ==, 0x14f0);

i2c_set16(i2c, TMP105_TEST_ADDR, TMP105_REG_T_LOW, 0x1234);
g_assert_cmphex(i2c_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_T_LOW), ==, 0x1234);
i2c_set16(i2c, TMP105_TEST_ADDR, TMP105_REG_T_HIGH, 0x4231);
g_assert_cmphex(i2c_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_T_HIGH), ==, 0x4231);
i2c_set16(i2cdev, TMP105_REG_T_LOW, 0x1234);
g_assert_cmphex(i2c_get16(i2cdev, TMP105_REG_T_LOW), ==, 0x1234);
i2c_set16(i2cdev, TMP105_REG_T_HIGH, 0x4231);
g_assert_cmphex(i2c_get16(i2cdev, TMP105_REG_T_HIGH), ==, 0x4231);
}

static void tmp105_register_nodes(void)
{
QOSGraphEdgeOptions opts = {
.extra_device_opts = "id=" TMP105_TEST_ID ",address=0x49"
};
add_qi2c_address(&opts, &(QI2CAddress) { 0x49 });

qos_node_create_driver("tmp105", i2c_device_create);
qos_node_consumes("tmp105", "i2c-bus", &opts);
Expand Down

0 comments on commit 0659947

Please sign in to comment.