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