target/arm: Update find_last_active for PREDDESC
[qemu/ar7.git] / hw / i2c / smbus_master.c
blobdc43b8637d11ad7acda48eef28afe20fff1e5522
1 /*
2 * QEMU SMBus host (master) emulation.
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.
8 * Copyright (c) 2007 CodeSourcery.
9 * Written by Paul Brook
11 * This code is licensed under the LGPL.
14 #include "qemu/osdep.h"
15 #include "hw/i2c/i2c.h"
16 #include "hw/i2c/smbus_master.h"
18 /* Master device commands. */
19 int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
21 if (i2c_start_transfer(bus, addr, read)) {
22 return -1;
24 i2c_end_transfer(bus);
25 return 0;
28 int smbus_receive_byte(I2CBus *bus, uint8_t addr)
30 uint8_t data;
32 if (i2c_start_transfer(bus, addr, 1)) {
33 return -1;
35 data = i2c_recv(bus);
36 i2c_nack(bus);
37 i2c_end_transfer(bus);
38 return data;
41 int smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
43 if (i2c_start_transfer(bus, addr, 0)) {
44 return -1;
46 i2c_send(bus, data);
47 i2c_end_transfer(bus);
48 return 0;
51 int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
53 uint8_t data;
54 if (i2c_start_transfer(bus, addr, 0)) {
55 return -1;
57 i2c_send(bus, command);
58 if (i2c_start_transfer(bus, addr, 1)) {
59 i2c_end_transfer(bus);
60 return -1;
62 data = i2c_recv(bus);
63 i2c_nack(bus);
64 i2c_end_transfer(bus);
65 return data;
68 int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
70 if (i2c_start_transfer(bus, addr, 0)) {
71 return -1;
73 i2c_send(bus, command);
74 i2c_send(bus, data);
75 i2c_end_transfer(bus);
76 return 0;
79 int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
81 uint16_t data;
82 if (i2c_start_transfer(bus, addr, 0)) {
83 return -1;
85 i2c_send(bus, command);
86 if (i2c_start_transfer(bus, addr, 1)) {
87 i2c_end_transfer(bus);
88 return -1;
90 data = i2c_recv(bus);
91 data |= i2c_recv(bus) << 8;
92 i2c_nack(bus);
93 i2c_end_transfer(bus);
94 return data;
97 int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
99 if (i2c_start_transfer(bus, addr, 0)) {
100 return -1;
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;
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)
112 int rlen;
113 int i;
115 if (send_cmd) {
116 if (i2c_start_transfer(bus, addr, 0)) {
117 return -1;
119 i2c_send(bus, command);
121 if (i2c_start_transfer(bus, addr, 1)) {
122 if (send_cmd) {
123 i2c_end_transfer(bus);
125 return -1;
127 if (recv_len) {
128 rlen = i2c_recv(bus);
129 } else {
130 rlen = len;
132 if (rlen > len) {
133 rlen = 0;
135 for (i = 0; i < rlen; i++) {
136 data[i] = i2c_recv(bus);
138 i2c_nack(bus);
139 i2c_end_transfer(bus);
140 return rlen;
143 int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
144 int len, bool send_len)
146 int i;
148 if (len > 32) {
149 len = 32;
152 if (i2c_start_transfer(bus, addr, 0)) {
153 return -1;
155 i2c_send(bus, command);
156 if (send_len) {
157 i2c_send(bus, len);
159 for (i = 0; i < len; i++) {
160 i2c_send(bus, data[i]);
162 i2c_end_transfer(bus);
163 return 0;