qemu

Форк
0
/
smbus_master.c 
164 строки · 3.4 Кб
1
/*
2
 * QEMU SMBus host (master) emulation.
3
 *
4
 * This code emulates SMBus transactions from the master point of view,
5
 * it runs the individual I2C transaction to do the SMBus protocol
6
 * over I2C.
7
 *
8
 * Copyright (c) 2007 CodeSourcery.
9
 * Written by Paul Brook
10
 *
11
 * This code is licensed under the LGPL.
12
 */
13

14
#include "qemu/osdep.h"
15
#include "hw/i2c/i2c.h"
16
#include "hw/i2c/smbus_master.h"
17

18
/* Master device commands.  */
19
int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
20
{
21
    if (i2c_start_transfer(bus, addr, read)) {
22
        return -1;
23
    }
24
    i2c_end_transfer(bus);
25
    return 0;
26
}
27

28
int smbus_receive_byte(I2CBus *bus, uint8_t addr)
29
{
30
    uint8_t data;
31

32
    if (i2c_start_recv(bus, addr)) {
33
        return -1;
34
    }
35
    data = i2c_recv(bus);
36
    i2c_nack(bus);
37
    i2c_end_transfer(bus);
38
    return data;
39
}
40

41
int smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
42
{
43
    if (i2c_start_send(bus, addr)) {
44
        return -1;
45
    }
46
    i2c_send(bus, data);
47
    i2c_end_transfer(bus);
48
    return 0;
49
}
50

51
int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
52
{
53
    uint8_t data;
54
    if (i2c_start_send(bus, addr)) {
55
        return -1;
56
    }
57
    i2c_send(bus, command);
58
    if (i2c_start_recv(bus, addr)) {
59
        i2c_end_transfer(bus);
60
        return -1;
61
    }
62
    data = i2c_recv(bus);
63
    i2c_nack(bus);
64
    i2c_end_transfer(bus);
65
    return data;
66
}
67

68
int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
69
{
70
    if (i2c_start_send(bus, addr)) {
71
        return -1;
72
    }
73
    i2c_send(bus, command);
74
    i2c_send(bus, data);
75
    i2c_end_transfer(bus);
76
    return 0;
77
}
78

79
int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
80
{
81
    uint16_t data;
82
    if (i2c_start_send(bus, addr)) {
83
        return -1;
84
    }
85
    i2c_send(bus, command);
86
    if (i2c_start_recv(bus, addr)) {
87
        i2c_end_transfer(bus);
88
        return -1;
89
    }
90
    data = i2c_recv(bus);
91
    data |= i2c_recv(bus) << 8;
92
    i2c_nack(bus);
93
    i2c_end_transfer(bus);
94
    return data;
95
}
96

97
int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
98
{
99
    if (i2c_start_send(bus, addr)) {
100
        return -1;
101
    }
102
    i2c_send(bus, command);
103
    i2c_send(bus, data & 0xff);
104
    i2c_send(bus, data >> 8);
105
    i2c_end_transfer(bus);
106
    return 0;
107
}
108

109
int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
110
                     int len, bool recv_len, bool send_cmd)
111
{
112
    int rlen;
113
    int i;
114

115
    if (send_cmd) {
116
        if (i2c_start_send(bus, addr)) {
117
            return -1;
118
        }
119
        i2c_send(bus, command);
120
    }
121
    if (i2c_start_recv(bus, addr)) {
122
        if (send_cmd) {
123
            i2c_end_transfer(bus);
124
        }
125
        return -1;
126
    }
127
    if (recv_len) {
128
        rlen = i2c_recv(bus);
129
    } else {
130
        rlen = len;
131
    }
132
    if (rlen > len) {
133
        rlen = 0;
134
    }
135
    for (i = 0; i < rlen; i++) {
136
        data[i] = i2c_recv(bus);
137
    }
138
    i2c_nack(bus);
139
    i2c_end_transfer(bus);
140
    return rlen;
141
}
142

143
int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
144
                      int len, bool send_len)
145
{
146
    int i;
147

148
    if (len > 32) {
149
        len = 32;
150
    }
151

152
    if (i2c_start_send(bus, addr)) {
153
        return -1;
154
    }
155
    i2c_send(bus, command);
156
    if (send_len) {
157
        i2c_send(bus, len);
158
    }
159
    for (i = 0; i < len; i++) {
160
        i2c_send(bus, data[i]);
161
    }
162
    i2c_end_transfer(bus);
163
    return 0;
164
}
165

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.