root / hw / milkymist-ac97.c @ 8294a64d
History | View | Annotate | Download (8.3 kB)
1 | 25a8bb96 | Michael Walle | /*
|
---|---|---|---|
2 | 25a8bb96 | Michael Walle | * QEMU model of the Milkymist System Controller.
|
3 | 25a8bb96 | Michael Walle | *
|
4 | 25a8bb96 | Michael Walle | * Copyright (c) 2010 Michael Walle <michael@walle.cc>
|
5 | 25a8bb96 | Michael Walle | *
|
6 | 25a8bb96 | Michael Walle | * This library is free software; you can redistribute it and/or
|
7 | 25a8bb96 | Michael Walle | * modify it under the terms of the GNU Lesser General Public
|
8 | 25a8bb96 | Michael Walle | * License as published by the Free Software Foundation; either
|
9 | 25a8bb96 | Michael Walle | * version 2 of the License, or (at your option) any later version.
|
10 | 25a8bb96 | Michael Walle | *
|
11 | 25a8bb96 | Michael Walle | * This library is distributed in the hope that it will be useful,
|
12 | 25a8bb96 | Michael Walle | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 25a8bb96 | Michael Walle | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 25a8bb96 | Michael Walle | * Lesser General Public License for more details.
|
15 | 25a8bb96 | Michael Walle | *
|
16 | 25a8bb96 | Michael Walle | * You should have received a copy of the GNU Lesser General Public
|
17 | 25a8bb96 | Michael Walle | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
18 | 25a8bb96 | Michael Walle | *
|
19 | 25a8bb96 | Michael Walle | *
|
20 | 25a8bb96 | Michael Walle | * Specification available at:
|
21 | 25a8bb96 | Michael Walle | * http://www.milkymist.org/socdoc/ac97.pdf
|
22 | 25a8bb96 | Michael Walle | */
|
23 | 25a8bb96 | Michael Walle | |
24 | 25a8bb96 | Michael Walle | #include "hw.h" |
25 | 25a8bb96 | Michael Walle | #include "sysbus.h" |
26 | 25a8bb96 | Michael Walle | #include "trace.h" |
27 | 25a8bb96 | Michael Walle | #include "audio/audio.h" |
28 | 25a8bb96 | Michael Walle | #include "qemu-error.h" |
29 | 25a8bb96 | Michael Walle | |
30 | 25a8bb96 | Michael Walle | enum {
|
31 | 25a8bb96 | Michael Walle | R_AC97_CTRL = 0,
|
32 | 25a8bb96 | Michael Walle | R_AC97_ADDR, |
33 | 25a8bb96 | Michael Walle | R_AC97_DATAOUT, |
34 | 25a8bb96 | Michael Walle | R_AC97_DATAIN, |
35 | 25a8bb96 | Michael Walle | R_D_CTRL, |
36 | 25a8bb96 | Michael Walle | R_D_ADDR, |
37 | 25a8bb96 | Michael Walle | R_D_REMAINING, |
38 | 25a8bb96 | Michael Walle | R_RESERVED, |
39 | 25a8bb96 | Michael Walle | R_U_CTRL, |
40 | 25a8bb96 | Michael Walle | R_U_ADDR, |
41 | 25a8bb96 | Michael Walle | R_U_REMAINING, |
42 | 25a8bb96 | Michael Walle | R_MAX |
43 | 25a8bb96 | Michael Walle | }; |
44 | 25a8bb96 | Michael Walle | |
45 | 25a8bb96 | Michael Walle | enum {
|
46 | 25a8bb96 | Michael Walle | AC97_CTRL_RQEN = (1<<0), |
47 | 25a8bb96 | Michael Walle | AC97_CTRL_WRITE = (1<<1), |
48 | 25a8bb96 | Michael Walle | }; |
49 | 25a8bb96 | Michael Walle | |
50 | 25a8bb96 | Michael Walle | enum {
|
51 | 25a8bb96 | Michael Walle | CTRL_EN = (1<<0), |
52 | 25a8bb96 | Michael Walle | }; |
53 | 25a8bb96 | Michael Walle | |
54 | 25a8bb96 | Michael Walle | struct MilkymistAC97State {
|
55 | 25a8bb96 | Michael Walle | SysBusDevice busdev; |
56 | 9496e1c3 | Michael Walle | MemoryRegion regs_region; |
57 | 25a8bb96 | Michael Walle | |
58 | 25a8bb96 | Michael Walle | QEMUSoundCard card; |
59 | 25a8bb96 | Michael Walle | SWVoiceIn *voice_in; |
60 | 25a8bb96 | Michael Walle | SWVoiceOut *voice_out; |
61 | 25a8bb96 | Michael Walle | |
62 | 25a8bb96 | Michael Walle | uint32_t regs[R_MAX]; |
63 | 25a8bb96 | Michael Walle | |
64 | 25a8bb96 | Michael Walle | qemu_irq crrequest_irq; |
65 | 25a8bb96 | Michael Walle | qemu_irq crreply_irq; |
66 | 25a8bb96 | Michael Walle | qemu_irq dmar_irq; |
67 | 25a8bb96 | Michael Walle | qemu_irq dmaw_irq; |
68 | 25a8bb96 | Michael Walle | }; |
69 | 25a8bb96 | Michael Walle | typedef struct MilkymistAC97State MilkymistAC97State; |
70 | 25a8bb96 | Michael Walle | |
71 | 25a8bb96 | Michael Walle | static void update_voices(MilkymistAC97State *s) |
72 | 25a8bb96 | Michael Walle | { |
73 | 25a8bb96 | Michael Walle | if (s->regs[R_D_CTRL] & CTRL_EN) {
|
74 | 25a8bb96 | Michael Walle | AUD_set_active_out(s->voice_out, 1);
|
75 | 25a8bb96 | Michael Walle | } else {
|
76 | 25a8bb96 | Michael Walle | AUD_set_active_out(s->voice_out, 0);
|
77 | 25a8bb96 | Michael Walle | } |
78 | 25a8bb96 | Michael Walle | |
79 | 25a8bb96 | Michael Walle | if (s->regs[R_U_CTRL] & CTRL_EN) {
|
80 | 25a8bb96 | Michael Walle | AUD_set_active_in(s->voice_in, 1);
|
81 | 25a8bb96 | Michael Walle | } else {
|
82 | 25a8bb96 | Michael Walle | AUD_set_active_in(s->voice_in, 0);
|
83 | 25a8bb96 | Michael Walle | } |
84 | 25a8bb96 | Michael Walle | } |
85 | 25a8bb96 | Michael Walle | |
86 | 9496e1c3 | Michael Walle | static uint64_t ac97_read(void *opaque, target_phys_addr_t addr, |
87 | 9496e1c3 | Michael Walle | unsigned size)
|
88 | 25a8bb96 | Michael Walle | { |
89 | 25a8bb96 | Michael Walle | MilkymistAC97State *s = opaque; |
90 | 25a8bb96 | Michael Walle | uint32_t r = 0;
|
91 | 25a8bb96 | Michael Walle | |
92 | 25a8bb96 | Michael Walle | addr >>= 2;
|
93 | 25a8bb96 | Michael Walle | switch (addr) {
|
94 | 25a8bb96 | Michael Walle | case R_AC97_CTRL:
|
95 | 25a8bb96 | Michael Walle | case R_AC97_ADDR:
|
96 | 25a8bb96 | Michael Walle | case R_AC97_DATAOUT:
|
97 | 25a8bb96 | Michael Walle | case R_AC97_DATAIN:
|
98 | 25a8bb96 | Michael Walle | case R_D_CTRL:
|
99 | 25a8bb96 | Michael Walle | case R_D_ADDR:
|
100 | 25a8bb96 | Michael Walle | case R_D_REMAINING:
|
101 | 25a8bb96 | Michael Walle | case R_U_CTRL:
|
102 | 25a8bb96 | Michael Walle | case R_U_ADDR:
|
103 | 25a8bb96 | Michael Walle | case R_U_REMAINING:
|
104 | 25a8bb96 | Michael Walle | r = s->regs[addr]; |
105 | 25a8bb96 | Michael Walle | break;
|
106 | 25a8bb96 | Michael Walle | |
107 | 25a8bb96 | Michael Walle | default:
|
108 | dd3d6775 | Markus Armbruster | error_report("milkymist_ac97: read access to unknown register 0x"
|
109 | 25a8bb96 | Michael Walle | TARGET_FMT_plx, addr << 2);
|
110 | 25a8bb96 | Michael Walle | break;
|
111 | 25a8bb96 | Michael Walle | } |
112 | 25a8bb96 | Michael Walle | |
113 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_memory_read(addr << 2, r);
|
114 | 25a8bb96 | Michael Walle | |
115 | 25a8bb96 | Michael Walle | return r;
|
116 | 25a8bb96 | Michael Walle | } |
117 | 25a8bb96 | Michael Walle | |
118 | 9496e1c3 | Michael Walle | static void ac97_write(void *opaque, target_phys_addr_t addr, uint64_t value, |
119 | 9496e1c3 | Michael Walle | unsigned size)
|
120 | 25a8bb96 | Michael Walle | { |
121 | 25a8bb96 | Michael Walle | MilkymistAC97State *s = opaque; |
122 | 25a8bb96 | Michael Walle | |
123 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_memory_write(addr, value); |
124 | 25a8bb96 | Michael Walle | |
125 | 25a8bb96 | Michael Walle | addr >>= 2;
|
126 | 25a8bb96 | Michael Walle | switch (addr) {
|
127 | 25a8bb96 | Michael Walle | case R_AC97_CTRL:
|
128 | 25a8bb96 | Michael Walle | /* always raise an IRQ according to the direction */
|
129 | 25a8bb96 | Michael Walle | if (value & AC97_CTRL_RQEN) {
|
130 | 25a8bb96 | Michael Walle | if (value & AC97_CTRL_WRITE) {
|
131 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_pulse_irq_crrequest(); |
132 | 25a8bb96 | Michael Walle | qemu_irq_pulse(s->crrequest_irq); |
133 | 25a8bb96 | Michael Walle | } else {
|
134 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_pulse_irq_crreply(); |
135 | 25a8bb96 | Michael Walle | qemu_irq_pulse(s->crreply_irq); |
136 | 25a8bb96 | Michael Walle | } |
137 | 25a8bb96 | Michael Walle | } |
138 | 25a8bb96 | Michael Walle | |
139 | 25a8bb96 | Michael Walle | /* RQEN is self clearing */
|
140 | 25a8bb96 | Michael Walle | s->regs[addr] = value & ~AC97_CTRL_RQEN; |
141 | 25a8bb96 | Michael Walle | break;
|
142 | 25a8bb96 | Michael Walle | case R_D_CTRL:
|
143 | 25a8bb96 | Michael Walle | case R_U_CTRL:
|
144 | 25a8bb96 | Michael Walle | s->regs[addr] = value; |
145 | 25a8bb96 | Michael Walle | update_voices(s); |
146 | 25a8bb96 | Michael Walle | break;
|
147 | 25a8bb96 | Michael Walle | case R_AC97_ADDR:
|
148 | 25a8bb96 | Michael Walle | case R_AC97_DATAOUT:
|
149 | 25a8bb96 | Michael Walle | case R_AC97_DATAIN:
|
150 | 25a8bb96 | Michael Walle | case R_D_ADDR:
|
151 | 25a8bb96 | Michael Walle | case R_D_REMAINING:
|
152 | 25a8bb96 | Michael Walle | case R_U_ADDR:
|
153 | 25a8bb96 | Michael Walle | case R_U_REMAINING:
|
154 | 25a8bb96 | Michael Walle | s->regs[addr] = value; |
155 | 25a8bb96 | Michael Walle | break;
|
156 | 25a8bb96 | Michael Walle | |
157 | 25a8bb96 | Michael Walle | default:
|
158 | dd3d6775 | Markus Armbruster | error_report("milkymist_ac97: write access to unknown register 0x"
|
159 | 25a8bb96 | Michael Walle | TARGET_FMT_plx, addr); |
160 | 25a8bb96 | Michael Walle | break;
|
161 | 25a8bb96 | Michael Walle | } |
162 | 25a8bb96 | Michael Walle | |
163 | 25a8bb96 | Michael Walle | } |
164 | 25a8bb96 | Michael Walle | |
165 | 9496e1c3 | Michael Walle | static const MemoryRegionOps ac97_mmio_ops = { |
166 | 9496e1c3 | Michael Walle | .read = ac97_read, |
167 | 9496e1c3 | Michael Walle | .write = ac97_write, |
168 | 9496e1c3 | Michael Walle | .valid = { |
169 | 9496e1c3 | Michael Walle | .min_access_size = 4,
|
170 | 9496e1c3 | Michael Walle | .max_access_size = 4,
|
171 | 9496e1c3 | Michael Walle | }, |
172 | 9496e1c3 | Michael Walle | .endianness = DEVICE_NATIVE_ENDIAN, |
173 | 25a8bb96 | Michael Walle | }; |
174 | 25a8bb96 | Michael Walle | |
175 | 25a8bb96 | Michael Walle | static void ac97_in_cb(void *opaque, int avail_b) |
176 | 25a8bb96 | Michael Walle | { |
177 | 25a8bb96 | Michael Walle | MilkymistAC97State *s = opaque; |
178 | 25a8bb96 | Michael Walle | uint8_t buf[4096];
|
179 | 25a8bb96 | Michael Walle | uint32_t remaining = s->regs[R_U_REMAINING]; |
180 | 25a8bb96 | Michael Walle | int temp = audio_MIN(remaining, avail_b);
|
181 | 25a8bb96 | Michael Walle | uint32_t addr = s->regs[R_U_ADDR]; |
182 | 25a8bb96 | Michael Walle | int transferred = 0; |
183 | 25a8bb96 | Michael Walle | |
184 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_in_cb(avail_b, remaining); |
185 | 25a8bb96 | Michael Walle | |
186 | 25a8bb96 | Michael Walle | /* prevent from raising an IRQ */
|
187 | 25a8bb96 | Michael Walle | if (temp == 0) { |
188 | 25a8bb96 | Michael Walle | return;
|
189 | 25a8bb96 | Michael Walle | } |
190 | 25a8bb96 | Michael Walle | |
191 | 25a8bb96 | Michael Walle | while (temp) {
|
192 | 25a8bb96 | Michael Walle | int acquired, to_copy;
|
193 | 25a8bb96 | Michael Walle | |
194 | 25a8bb96 | Michael Walle | to_copy = audio_MIN(temp, sizeof(buf));
|
195 | 25a8bb96 | Michael Walle | acquired = AUD_read(s->voice_in, buf, to_copy); |
196 | 25a8bb96 | Michael Walle | if (!acquired) {
|
197 | 25a8bb96 | Michael Walle | break;
|
198 | 25a8bb96 | Michael Walle | } |
199 | 25a8bb96 | Michael Walle | |
200 | 25a8bb96 | Michael Walle | cpu_physical_memory_write(addr, buf, acquired); |
201 | 25a8bb96 | Michael Walle | |
202 | 25a8bb96 | Michael Walle | temp -= acquired; |
203 | 25a8bb96 | Michael Walle | addr += acquired; |
204 | 25a8bb96 | Michael Walle | transferred += acquired; |
205 | 25a8bb96 | Michael Walle | } |
206 | 25a8bb96 | Michael Walle | |
207 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_in_cb_transferred(transferred); |
208 | 25a8bb96 | Michael Walle | |
209 | 25a8bb96 | Michael Walle | s->regs[R_U_ADDR] = addr; |
210 | 25a8bb96 | Michael Walle | s->regs[R_U_REMAINING] -= transferred; |
211 | 25a8bb96 | Michael Walle | |
212 | 25a8bb96 | Michael Walle | if ((s->regs[R_U_CTRL] & CTRL_EN) && (s->regs[R_U_REMAINING] == 0)) { |
213 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_pulse_irq_dmaw(); |
214 | 25a8bb96 | Michael Walle | qemu_irq_pulse(s->dmaw_irq); |
215 | 25a8bb96 | Michael Walle | } |
216 | 25a8bb96 | Michael Walle | } |
217 | 25a8bb96 | Michael Walle | |
218 | 25a8bb96 | Michael Walle | static void ac97_out_cb(void *opaque, int free_b) |
219 | 25a8bb96 | Michael Walle | { |
220 | 25a8bb96 | Michael Walle | MilkymistAC97State *s = opaque; |
221 | 25a8bb96 | Michael Walle | uint8_t buf[4096];
|
222 | 25a8bb96 | Michael Walle | uint32_t remaining = s->regs[R_D_REMAINING]; |
223 | 25a8bb96 | Michael Walle | int temp = audio_MIN(remaining, free_b);
|
224 | 25a8bb96 | Michael Walle | uint32_t addr = s->regs[R_D_ADDR]; |
225 | 25a8bb96 | Michael Walle | int transferred = 0; |
226 | 25a8bb96 | Michael Walle | |
227 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_out_cb(free_b, remaining); |
228 | 25a8bb96 | Michael Walle | |
229 | 25a8bb96 | Michael Walle | /* prevent from raising an IRQ */
|
230 | 25a8bb96 | Michael Walle | if (temp == 0) { |
231 | 25a8bb96 | Michael Walle | return;
|
232 | 25a8bb96 | Michael Walle | } |
233 | 25a8bb96 | Michael Walle | |
234 | 25a8bb96 | Michael Walle | while (temp) {
|
235 | 25a8bb96 | Michael Walle | int copied, to_copy;
|
236 | 25a8bb96 | Michael Walle | |
237 | 25a8bb96 | Michael Walle | to_copy = audio_MIN(temp, sizeof(buf));
|
238 | 25a8bb96 | Michael Walle | cpu_physical_memory_read(addr, buf, to_copy); |
239 | 25a8bb96 | Michael Walle | copied = AUD_write(s->voice_out, buf, to_copy); |
240 | 25a8bb96 | Michael Walle | if (!copied) {
|
241 | 25a8bb96 | Michael Walle | break;
|
242 | 25a8bb96 | Michael Walle | } |
243 | 25a8bb96 | Michael Walle | temp -= copied; |
244 | 25a8bb96 | Michael Walle | addr += copied; |
245 | 25a8bb96 | Michael Walle | transferred += copied; |
246 | 25a8bb96 | Michael Walle | } |
247 | 25a8bb96 | Michael Walle | |
248 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_out_cb_transferred(transferred); |
249 | 25a8bb96 | Michael Walle | |
250 | 25a8bb96 | Michael Walle | s->regs[R_D_ADDR] = addr; |
251 | 25a8bb96 | Michael Walle | s->regs[R_D_REMAINING] -= transferred; |
252 | 25a8bb96 | Michael Walle | |
253 | 25a8bb96 | Michael Walle | if ((s->regs[R_D_CTRL] & CTRL_EN) && (s->regs[R_D_REMAINING] == 0)) { |
254 | 25a8bb96 | Michael Walle | trace_milkymist_ac97_pulse_irq_dmar(); |
255 | 25a8bb96 | Michael Walle | qemu_irq_pulse(s->dmar_irq); |
256 | 25a8bb96 | Michael Walle | } |
257 | 25a8bb96 | Michael Walle | } |
258 | 25a8bb96 | Michael Walle | |
259 | 25a8bb96 | Michael Walle | static void milkymist_ac97_reset(DeviceState *d) |
260 | 25a8bb96 | Michael Walle | { |
261 | 25a8bb96 | Michael Walle | MilkymistAC97State *s = container_of(d, MilkymistAC97State, busdev.qdev); |
262 | 25a8bb96 | Michael Walle | int i;
|
263 | 25a8bb96 | Michael Walle | |
264 | 25a8bb96 | Michael Walle | for (i = 0; i < R_MAX; i++) { |
265 | 25a8bb96 | Michael Walle | s->regs[i] = 0;
|
266 | 25a8bb96 | Michael Walle | } |
267 | 25a8bb96 | Michael Walle | |
268 | 25a8bb96 | Michael Walle | AUD_set_active_in(s->voice_in, 0);
|
269 | 25a8bb96 | Michael Walle | AUD_set_active_out(s->voice_out, 0);
|
270 | 25a8bb96 | Michael Walle | } |
271 | 25a8bb96 | Michael Walle | |
272 | 25a8bb96 | Michael Walle | static int ac97_post_load(void *opaque, int version_id) |
273 | 25a8bb96 | Michael Walle | { |
274 | 25a8bb96 | Michael Walle | MilkymistAC97State *s = opaque; |
275 | 25a8bb96 | Michael Walle | |
276 | 25a8bb96 | Michael Walle | update_voices(s); |
277 | 25a8bb96 | Michael Walle | |
278 | 25a8bb96 | Michael Walle | return 0; |
279 | 25a8bb96 | Michael Walle | } |
280 | 25a8bb96 | Michael Walle | |
281 | 25a8bb96 | Michael Walle | static int milkymist_ac97_init(SysBusDevice *dev) |
282 | 25a8bb96 | Michael Walle | { |
283 | 25a8bb96 | Michael Walle | MilkymistAC97State *s = FROM_SYSBUS(typeof(*s), dev); |
284 | 25a8bb96 | Michael Walle | |
285 | 25a8bb96 | Michael Walle | struct audsettings as;
|
286 | 25a8bb96 | Michael Walle | sysbus_init_irq(dev, &s->crrequest_irq); |
287 | 25a8bb96 | Michael Walle | sysbus_init_irq(dev, &s->crreply_irq); |
288 | 25a8bb96 | Michael Walle | sysbus_init_irq(dev, &s->dmar_irq); |
289 | 25a8bb96 | Michael Walle | sysbus_init_irq(dev, &s->dmaw_irq); |
290 | 25a8bb96 | Michael Walle | |
291 | 25a8bb96 | Michael Walle | AUD_register_card("Milkymist AC'97", &s->card);
|
292 | 25a8bb96 | Michael Walle | |
293 | 25a8bb96 | Michael Walle | as.freq = 48000;
|
294 | 25a8bb96 | Michael Walle | as.nchannels = 2;
|
295 | 25a8bb96 | Michael Walle | as.fmt = AUD_FMT_S16; |
296 | 25a8bb96 | Michael Walle | as.endianness = 1;
|
297 | 25a8bb96 | Michael Walle | |
298 | 25a8bb96 | Michael Walle | s->voice_in = AUD_open_in(&s->card, s->voice_in, |
299 | 25a8bb96 | Michael Walle | "mm_ac97.in", s, ac97_in_cb, &as);
|
300 | 25a8bb96 | Michael Walle | s->voice_out = AUD_open_out(&s->card, s->voice_out, |
301 | 25a8bb96 | Michael Walle | "mm_ac97.out", s, ac97_out_cb, &as);
|
302 | 25a8bb96 | Michael Walle | |
303 | 9496e1c3 | Michael Walle | memory_region_init_io(&s->regs_region, &ac97_mmio_ops, s, |
304 | 9496e1c3 | Michael Walle | "milkymist-ac97", R_MAX * 4); |
305 | 750ecd44 | Avi Kivity | sysbus_init_mmio(dev, &s->regs_region); |
306 | 25a8bb96 | Michael Walle | |
307 | 25a8bb96 | Michael Walle | return 0; |
308 | 25a8bb96 | Michael Walle | } |
309 | 25a8bb96 | Michael Walle | |
310 | 25a8bb96 | Michael Walle | static const VMStateDescription vmstate_milkymist_ac97 = { |
311 | 25a8bb96 | Michael Walle | .name = "milkymist-ac97",
|
312 | 25a8bb96 | Michael Walle | .version_id = 1,
|
313 | 25a8bb96 | Michael Walle | .minimum_version_id = 1,
|
314 | 25a8bb96 | Michael Walle | .minimum_version_id_old = 1,
|
315 | 25a8bb96 | Michael Walle | .post_load = ac97_post_load, |
316 | 25a8bb96 | Michael Walle | .fields = (VMStateField[]) { |
317 | 25a8bb96 | Michael Walle | VMSTATE_UINT32_ARRAY(regs, MilkymistAC97State, R_MAX), |
318 | 25a8bb96 | Michael Walle | VMSTATE_END_OF_LIST() |
319 | 25a8bb96 | Michael Walle | } |
320 | 25a8bb96 | Michael Walle | }; |
321 | 25a8bb96 | Michael Walle | |
322 | 999e12bb | Anthony Liguori | static void milkymist_ac97_class_init(ObjectClass *klass, void *data) |
323 | 999e12bb | Anthony Liguori | { |
324 | 39bffca2 | Anthony Liguori | DeviceClass *dc = DEVICE_CLASS(klass); |
325 | 999e12bb | Anthony Liguori | SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); |
326 | 999e12bb | Anthony Liguori | |
327 | 999e12bb | Anthony Liguori | k->init = milkymist_ac97_init; |
328 | 39bffca2 | Anthony Liguori | dc->reset = milkymist_ac97_reset; |
329 | 39bffca2 | Anthony Liguori | dc->vmsd = &vmstate_milkymist_ac97; |
330 | 999e12bb | Anthony Liguori | } |
331 | 999e12bb | Anthony Liguori | |
332 | 39bffca2 | Anthony Liguori | static TypeInfo milkymist_ac97_info = {
|
333 | 39bffca2 | Anthony Liguori | .name = "milkymist-ac97",
|
334 | 39bffca2 | Anthony Liguori | .parent = TYPE_SYS_BUS_DEVICE, |
335 | 39bffca2 | Anthony Liguori | .instance_size = sizeof(MilkymistAC97State),
|
336 | 39bffca2 | Anthony Liguori | .class_init = milkymist_ac97_class_init, |
337 | 25a8bb96 | Michael Walle | }; |
338 | 25a8bb96 | Michael Walle | |
339 | 83f7d43a | Andreas Färber | static void milkymist_ac97_register_types(void) |
340 | 25a8bb96 | Michael Walle | { |
341 | 39bffca2 | Anthony Liguori | type_register_static(&milkymist_ac97_info); |
342 | 25a8bb96 | Michael Walle | } |
343 | 25a8bb96 | Michael Walle | |
344 | 83f7d43a | Andreas Färber | type_init(milkymist_ac97_register_types) |