1*1cf4323eSThomas Huth /* 2*1cf4323eSThomas Huth * QTest I2C driver 3*1cf4323eSThomas Huth * 4*1cf4323eSThomas Huth * Copyright (c) 2012 Andreas Färber 5*1cf4323eSThomas Huth * 6*1cf4323eSThomas Huth * This work is licensed under the terms of the GNU GPL, version 2 or later. 7*1cf4323eSThomas Huth * See the COPYING file in the top-level directory. 8*1cf4323eSThomas Huth */ 9*1cf4323eSThomas Huth #include "qemu/osdep.h" 10*1cf4323eSThomas Huth #include "libqos/i2c.h" 11*1cf4323eSThomas Huth #include "libqtest.h" 12*1cf4323eSThomas Huth 13*1cf4323eSThomas Huth void i2c_send(QI2CDevice *i2cdev, const uint8_t *buf, uint16_t len) 14*1cf4323eSThomas Huth { 15*1cf4323eSThomas Huth i2cdev->bus->send(i2cdev->bus, i2cdev->addr, buf, len); 16*1cf4323eSThomas Huth } 17*1cf4323eSThomas Huth 18*1cf4323eSThomas Huth void i2c_recv(QI2CDevice *i2cdev, uint8_t *buf, uint16_t len) 19*1cf4323eSThomas Huth { 20*1cf4323eSThomas Huth i2cdev->bus->recv(i2cdev->bus, i2cdev->addr, buf, len); 21*1cf4323eSThomas Huth } 22*1cf4323eSThomas Huth 23*1cf4323eSThomas Huth void i2c_read_block(QI2CDevice *i2cdev, uint8_t reg, 24*1cf4323eSThomas Huth uint8_t *buf, uint16_t len) 25*1cf4323eSThomas Huth { 26*1cf4323eSThomas Huth i2c_send(i2cdev, ®, 1); 27*1cf4323eSThomas Huth i2c_recv(i2cdev, buf, len); 28*1cf4323eSThomas Huth } 29*1cf4323eSThomas Huth 30*1cf4323eSThomas Huth void i2c_write_block(QI2CDevice *i2cdev, uint8_t reg, 31*1cf4323eSThomas Huth const uint8_t *buf, uint16_t len) 32*1cf4323eSThomas Huth { 33*1cf4323eSThomas Huth uint8_t *cmd = g_malloc(len + 1); 34*1cf4323eSThomas Huth cmd[0] = reg; 35*1cf4323eSThomas Huth memcpy(&cmd[1], buf, len); 36*1cf4323eSThomas Huth i2c_send(i2cdev, cmd, len + 1); 37*1cf4323eSThomas Huth g_free(cmd); 38*1cf4323eSThomas Huth } 39*1cf4323eSThomas Huth 40*1cf4323eSThomas Huth uint8_t i2c_get8(QI2CDevice *i2cdev, uint8_t reg) 41*1cf4323eSThomas Huth { 42*1cf4323eSThomas Huth uint8_t resp[1]; 43*1cf4323eSThomas Huth i2c_read_block(i2cdev, reg, resp, sizeof(resp)); 44*1cf4323eSThomas Huth return resp[0]; 45*1cf4323eSThomas Huth } 46*1cf4323eSThomas Huth 47*1cf4323eSThomas Huth uint16_t i2c_get16(QI2CDevice *i2cdev, uint8_t reg) 48*1cf4323eSThomas Huth { 49*1cf4323eSThomas Huth uint8_t resp[2]; 50*1cf4323eSThomas Huth i2c_read_block(i2cdev, reg, resp, sizeof(resp)); 51*1cf4323eSThomas Huth return (resp[0] << 8) | resp[1]; 52*1cf4323eSThomas Huth } 53*1cf4323eSThomas Huth 54*1cf4323eSThomas Huth void i2c_set8(QI2CDevice *i2cdev, uint8_t reg, uint8_t value) 55*1cf4323eSThomas Huth { 56*1cf4323eSThomas Huth i2c_write_block(i2cdev, reg, &value, 1); 57*1cf4323eSThomas Huth } 58*1cf4323eSThomas Huth 59*1cf4323eSThomas Huth void i2c_set16(QI2CDevice *i2cdev, uint8_t reg, uint16_t value) 60*1cf4323eSThomas Huth { 61*1cf4323eSThomas Huth uint8_t data[2]; 62*1cf4323eSThomas Huth 63*1cf4323eSThomas Huth data[0] = value >> 8; 64*1cf4323eSThomas Huth data[1] = value & 255; 65*1cf4323eSThomas Huth i2c_write_block(i2cdev, reg, data, sizeof(data)); 66*1cf4323eSThomas Huth } 67*1cf4323eSThomas Huth 68*1cf4323eSThomas Huth void *i2c_device_create(void *i2c_bus, QGuestAllocator *alloc, void *addr) 69*1cf4323eSThomas Huth { 70*1cf4323eSThomas Huth QI2CDevice *i2cdev = g_new0(QI2CDevice, 1); 71*1cf4323eSThomas Huth 72*1cf4323eSThomas Huth i2cdev->bus = i2c_bus; 73*1cf4323eSThomas Huth if (addr) { 74*1cf4323eSThomas Huth i2cdev->addr = ((QI2CAddress *)addr)->addr; 75*1cf4323eSThomas Huth } 76*1cf4323eSThomas Huth return &i2cdev->obj; 77*1cf4323eSThomas Huth } 78*1cf4323eSThomas Huth 79*1cf4323eSThomas Huth void add_qi2c_address(QOSGraphEdgeOptions *opts, QI2CAddress *addr) 80*1cf4323eSThomas Huth { 81*1cf4323eSThomas Huth g_assert(addr); 82*1cf4323eSThomas Huth 83*1cf4323eSThomas Huth opts->arg = addr; 84*1cf4323eSThomas Huth opts->size_arg = sizeof(QI2CAddress); 85*1cf4323eSThomas Huth } 86