4 * Copyright (c) 2004 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 #include "qemu/osdep.h"
26 #include "hw/input/adb.h"
27 #include "hw/qdev-properties.h"
28 #include "migration/vmstate.h"
29 #include "qemu/module.h"
30 #include "qemu/timer.h"
31 #include "adb-internal.h"
34 #define ADB_RET_NOTPRESENT (-2)
36 static void adb_device_reset(ADBDevice
*d
)
38 qdev_reset_all(DEVICE(d
));
41 static int do_adb_request(ADBBusState
*s
, uint8_t *obuf
, const uint8_t *buf
,
46 int devaddr
, cmd
, olen
, i
;
49 if (cmd
== ADB_BUSRESET
) {
50 for (i
= 0; i
< s
->nb_devices
; i
++) {
59 for (i
= 0; i
< s
->nb_devices
; i
++) {
61 adc
= ADB_DEVICE_GET_CLASS(d
);
63 if (adc
->devhasdata(d
)) {
64 s
->pending
|= (1 << d
->devaddr
);
69 devaddr
= buf
[0] >> 4;
70 for (i
= 0; i
< s
->nb_devices
; i
++) {
72 adc
= ADB_DEVICE_GET_CLASS(d
);
74 if (d
->devaddr
== devaddr
) {
75 olen
= adc
->devreq(d
, obuf
, buf
, len
);
77 s
->status
|= ADB_STATUS_BUSTIMEOUT
;
83 s
->status
|= ADB_STATUS_BUSTIMEOUT
;
84 return ADB_RET_NOTPRESENT
;
87 int adb_request(ADBBusState
*s
, uint8_t *obuf
, const uint8_t *buf
, int len
)
89 assert(s
->autopoll_blocked
);
91 return do_adb_request(s
, obuf
, buf
, len
);
94 int adb_poll(ADBBusState
*s
, uint8_t *obuf
, uint16_t poll_mask
)
101 for (i
= 0; i
< s
->nb_devices
; i
++) {
102 if (s
->poll_index
>= s
->nb_devices
) {
105 d
= s
->devices
[s
->poll_index
];
106 if ((1 << d
->devaddr
) & poll_mask
) {
107 buf
[0] = ADB_READREG
| (d
->devaddr
<< 4);
108 olen
= do_adb_request(s
, obuf
+ 1, buf
, 1);
109 /* if there is data, we poll again the same device */
111 s
->status
|= ADB_STATUS_POLLREPLY
;
122 void adb_set_autopoll_enabled(ADBBusState
*s
, bool enabled
)
124 if (s
->autopoll_enabled
!= enabled
) {
125 s
->autopoll_enabled
= enabled
;
126 if (s
->autopoll_enabled
) {
127 timer_mod(s
->autopoll_timer
,
128 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL
) +
129 s
->autopoll_rate_ms
);
131 timer_del(s
->autopoll_timer
);
136 void adb_set_autopoll_rate_ms(ADBBusState
*s
, int rate_ms
)
138 s
->autopoll_rate_ms
= rate_ms
;
140 if (s
->autopoll_enabled
) {
141 timer_mod(s
->autopoll_timer
,
142 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL
) +
143 s
->autopoll_rate_ms
);
147 void adb_set_autopoll_mask(ADBBusState
*s
, uint16_t mask
)
149 if (s
->autopoll_mask
!= mask
) {
150 s
->autopoll_mask
= mask
;
151 if (s
->autopoll_enabled
&& s
->autopoll_mask
) {
152 timer_mod(s
->autopoll_timer
,
153 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL
) +
154 s
->autopoll_rate_ms
);
156 timer_del(s
->autopoll_timer
);
161 void adb_autopoll_block(ADBBusState
*s
)
163 s
->autopoll_blocked
= true;
165 if (s
->autopoll_enabled
) {
166 timer_del(s
->autopoll_timer
);
170 void adb_autopoll_unblock(ADBBusState
*s
)
172 s
->autopoll_blocked
= false;
174 if (s
->autopoll_enabled
) {
175 timer_mod(s
->autopoll_timer
,
176 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL
) +
177 s
->autopoll_rate_ms
);
181 static void adb_autopoll(void *opaque
)
183 ADBBusState
*s
= opaque
;
185 if (!s
->autopoll_blocked
) {
186 s
->autopoll_cb(s
->autopoll_cb_opaque
);
189 timer_mod(s
->autopoll_timer
,
190 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL
) +
191 s
->autopoll_rate_ms
);
194 void adb_register_autopoll_callback(ADBBusState
*s
, void (*cb
)(void *opaque
),
198 s
->autopoll_cb_opaque
= opaque
;
201 static const VMStateDescription vmstate_adb_bus
= {
204 .minimum_version_id
= 0,
205 .fields
= (VMStateField
[]) {
206 VMSTATE_TIMER_PTR(autopoll_timer
, ADBBusState
),
207 VMSTATE_BOOL(autopoll_enabled
, ADBBusState
),
208 VMSTATE_UINT8(autopoll_rate_ms
, ADBBusState
),
209 VMSTATE_UINT16(autopoll_mask
, ADBBusState
),
210 VMSTATE_BOOL(autopoll_blocked
, ADBBusState
),
211 VMSTATE_END_OF_LIST()
215 static void adb_bus_reset(BusState
*qbus
)
217 ADBBusState
*adb_bus
= ADB_BUS(qbus
);
219 adb_bus
->autopoll_enabled
= false;
220 adb_bus
->autopoll_mask
= 0xffff;
221 adb_bus
->autopoll_rate_ms
= 20;
224 static void adb_bus_realize(BusState
*qbus
, Error
**errp
)
226 ADBBusState
*adb_bus
= ADB_BUS(qbus
);
228 adb_bus
->autopoll_timer
= timer_new_ms(QEMU_CLOCK_VIRTUAL
, adb_autopoll
,
231 vmstate_register(NULL
, -1, &vmstate_adb_bus
, adb_bus
);
234 static void adb_bus_unrealize(BusState
*qbus
)
236 ADBBusState
*adb_bus
= ADB_BUS(qbus
);
238 timer_del(adb_bus
->autopoll_timer
);
240 vmstate_unregister(NULL
, &vmstate_adb_bus
, adb_bus
);
243 static void adb_bus_class_init(ObjectClass
*klass
, void *data
)
245 BusClass
*k
= BUS_CLASS(klass
);
247 k
->realize
= adb_bus_realize
;
248 k
->unrealize
= adb_bus_unrealize
;
249 k
->reset
= adb_bus_reset
;
252 static const TypeInfo adb_bus_type_info
= {
253 .name
= TYPE_ADB_BUS
,
255 .instance_size
= sizeof(ADBBusState
),
256 .class_init
= adb_bus_class_init
,
259 const VMStateDescription vmstate_adb_device
= {
260 .name
= "adb_device",
262 .minimum_version_id
= 0,
263 .fields
= (VMStateField
[]) {
264 VMSTATE_INT32(devaddr
, ADBDevice
),
265 VMSTATE_INT32(handler
, ADBDevice
),
266 VMSTATE_END_OF_LIST()
270 static void adb_device_realizefn(DeviceState
*dev
, Error
**errp
)
272 ADBDevice
*d
= ADB_DEVICE(dev
);
273 ADBBusState
*bus
= ADB_BUS(qdev_get_parent_bus(dev
));
275 if (bus
->nb_devices
>= MAX_ADB_DEVICES
) {
279 bus
->devices
[bus
->nb_devices
++] = d
;
282 static void adb_device_class_init(ObjectClass
*oc
, void *data
)
284 DeviceClass
*dc
= DEVICE_CLASS(oc
);
286 dc
->realize
= adb_device_realizefn
;
287 dc
->bus_type
= TYPE_ADB_BUS
;
290 static const TypeInfo adb_device_type_info
= {
291 .name
= TYPE_ADB_DEVICE
,
292 .parent
= TYPE_DEVICE
,
293 .instance_size
= sizeof(ADBDevice
),
295 .class_init
= adb_device_class_init
,
298 static void adb_register_types(void)
300 type_register_static(&adb_bus_type_info
);
301 type_register_static(&adb_device_type_info
);
304 type_init(adb_register_types
)