Add PowerPC power-management state check callback.
[qemu] / hw / wm8750.c
1 /*
2  * WM8750 audio CODEC.
3  *
4  * Copyright (c) 2006 Openedhand Ltd.
5  * Written by Andrzej Zaborowski <balrog@zabor.org>
6  *
7  * This file is licensed under GNU GPL.
8  */
9
10 #include "vl.h"
11
12 #define IN_PORT_N       3
13 #define OUT_PORT_N      3
14
15 #define CODEC           "wm8750"
16
17 struct wm_rate_s;
18 struct wm8750_s {
19     i2c_slave i2c;
20     uint8_t i2c_data[2];
21     int i2c_len;
22     QEMUSoundCard card;
23     SWVoiceIn *adc_voice[IN_PORT_N];
24     SWVoiceOut *dac_voice[OUT_PORT_N];
25     int enable;
26     void (*data_req)(void *, int, int);
27     void *opaque;
28     uint8_t data_in[4096];
29     uint8_t data_out[4096];
30     int idx_in, req_in;
31     int idx_out, req_out;
32
33     SWVoiceOut **out[2];
34     uint8_t outvol[7], outmute[2];
35     SWVoiceIn **in[2];
36     uint8_t invol[4], inmute[2];
37
38     uint8_t diff[2], pol, ds, monomix[2], alc, mute;
39     uint8_t path[4], mpath[2], power, format;
40     uint32_t inmask, outmask;
41     const struct wm_rate_s *rate;
42 };
43
44 static inline void wm8750_in_load(struct wm8750_s *s)
45 {
46     int acquired;
47     if (s->idx_in + s->req_in <= sizeof(s->data_in))
48         return;
49     s->idx_in = audio_MAX(0, (int) sizeof(s->data_in) - s->req_in);
50     acquired = AUD_read(*s->in[0], s->data_in + s->idx_in,
51                     sizeof(s->data_in) - s->idx_in);
52 }
53
54 static inline void wm8750_out_flush(struct wm8750_s *s)
55 {
56     int sent;
57     if (!s->idx_out)
58         return;
59     sent = AUD_write(*s->out[0], s->data_out, s->idx_out);
60     s->idx_out = 0;
61 }
62
63 static void wm8750_audio_in_cb(void *opaque, int avail_b)
64 {
65     struct wm8750_s *s = (struct wm8750_s *) opaque;
66     s->req_in = avail_b;
67     s->data_req(s->opaque, s->req_out >> 2, avail_b >> 2);
68
69 #if 0
70     wm8750_in_load(s);
71 #endif
72 }
73
74 static void wm8750_audio_out_cb(void *opaque, int free_b)
75 {
76     struct wm8750_s *s = (struct wm8750_s *) opaque;
77     wm8750_out_flush(s);
78
79     s->req_out = free_b;
80     s->data_req(s->opaque, free_b >> 2, s->req_in >> 2);
81 }
82
83 struct wm_rate_s {
84     int adc;
85     int adc_hz;
86     int dac;
87     int dac_hz;
88 };
89
90 static const struct wm_rate_s wm_rate_table[] = {
91     {  256, 48000,  256, 48000 },       /* SR: 00000 */
92     {  384, 48000,  384, 48000 },       /* SR: 00001 */
93     {  256, 48000, 1536,  8000 },       /* SR: 00010 */
94     {  384, 48000, 2304,  8000 },       /* SR: 00011 */
95     { 1536,  8000,  256, 48000 },       /* SR: 00100 */
96     { 2304,  8000,  384, 48000 },       /* SR: 00101 */
97     { 1536,  8000, 1536,  8000 },       /* SR: 00110 */
98     { 2304,  8000, 2304,  8000 },       /* SR: 00111 */
99     { 1024, 12000, 1024, 12000 },       /* SR: 01000 */
100     { 1526, 12000, 1536, 12000 },       /* SR: 01001 */
101     {  768, 16000,  768, 16000 },       /* SR: 01010 */
102     { 1152, 16000, 1152, 16000 },       /* SR: 01011 */
103     {  384, 32000,  384, 32000 },       /* SR: 01100 */
104     {  576, 32000,  576, 32000 },       /* SR: 01101 */
105     {  128, 96000,  128, 96000 },       /* SR: 01110 */
106     {  192, 96000,  192, 96000 },       /* SR: 01111 */
107     {  256, 44100,  256, 44100 },       /* SR: 10000 */
108     {  384, 44100,  384, 44100 },       /* SR: 10001 */
109     {  256, 44100, 1408,  8018 },       /* SR: 10010 */
110     {  384, 44100, 2112,  8018 },       /* SR: 10011 */
111     { 1408,  8018,  256, 44100 },       /* SR: 10100 */
112     { 2112,  8018,  384, 44100 },       /* SR: 10101 */
113     { 1408,  8018, 1408,  8018 },       /* SR: 10110 */
114     { 2112,  8018, 2112,  8018 },       /* SR: 10111 */
115     { 1024, 11025, 1024, 11025 },       /* SR: 11000 */
116     { 1536, 11025, 1536, 11025 },       /* SR: 11001 */
117     {  512, 22050,  512, 22050 },       /* SR: 11010 */
118     {  768, 22050,  768, 22050 },       /* SR: 11011 */
119     {  512, 24000,  512, 24000 },       /* SR: 11100 */
120     {  768, 24000,  768, 24000 },       /* SR: 11101 */
121     {  128, 88200,  128, 88200 },       /* SR: 11110 */
122     {  192, 88200,  128, 88200 },       /* SR: 11111 */
123 };
124
125 void wm8750_set_format(struct wm8750_s *s)
126 {
127     int i;
128     audsettings_t in_fmt;
129     audsettings_t out_fmt;
130     audsettings_t monoout_fmt;
131
132     wm8750_out_flush(s);
133
134     if (s->in[0] && *s->in[0])
135         AUD_set_active_in(*s->in[0], 0);
136     if (s->out[0] && *s->out[0])
137         AUD_set_active_out(*s->out[0], 0);
138
139     for (i = 0; i < IN_PORT_N; i ++)
140         if (s->adc_voice[i]) {
141             AUD_close_in(&s->card, s->adc_voice[i]);
142             s->adc_voice[i] = 0;
143         }
144     for (i = 0; i < OUT_PORT_N; i ++)
145         if (s->dac_voice[i]) {
146             AUD_close_out(&s->card, s->dac_voice[i]);
147             s->dac_voice[i] = 0;
148         }
149
150     if (!s->enable)
151         return;
152
153     /* Setup input */
154     in_fmt.endianness = 0;
155     in_fmt.nchannels = 2;
156     in_fmt.freq = s->rate->adc_hz;
157     in_fmt.fmt = AUD_FMT_S16;
158
159     s->adc_voice[0] = AUD_open_in(&s->card, s->adc_voice[0],
160                     CODEC ".input1", s, wm8750_audio_in_cb, &in_fmt);
161     s->adc_voice[1] = AUD_open_in(&s->card, s->adc_voice[1],
162                     CODEC ".input2", s, wm8750_audio_in_cb, &in_fmt);
163     s->adc_voice[2] = AUD_open_in(&s->card, s->adc_voice[2],
164                     CODEC ".input3", s, wm8750_audio_in_cb, &in_fmt);
165
166     /* Setup output */
167     out_fmt.endianness = 0;
168     out_fmt.nchannels = 2;
169     out_fmt.freq = s->rate->dac_hz;
170     out_fmt.fmt = AUD_FMT_S16;
171     monoout_fmt.endianness = 0;
172     monoout_fmt.nchannels = 1;
173     monoout_fmt.freq = s->rate->dac_hz;
174     monoout_fmt.fmt = AUD_FMT_S16;
175
176     s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
177                     CODEC ".speaker", s, wm8750_audio_out_cb, &out_fmt);
178     s->dac_voice[1] = AUD_open_out(&s->card, s->dac_voice[1],
179                     CODEC ".headphone", s, wm8750_audio_out_cb, &out_fmt);
180     /* MONOMIX is also in stereo for simplicity */
181     s->dac_voice[2] = AUD_open_out(&s->card, s->dac_voice[2],
182                     CODEC ".monomix", s, wm8750_audio_out_cb, &out_fmt);
183     /* no sense emulating OUT3 which is a mix of other outputs */
184
185     /* We should connect the left and right channels to their
186      * respective inputs/outputs but we have completely no need
187      * for mixing or combining paths to different ports, so we
188      * connect both channels to where the left channel is routed.  */
189     if (s->in[0] && *s->in[0])
190         AUD_set_active_in(*s->in[0], 1);
191     if (s->out[0] && *s->out[0])
192         AUD_set_active_out(*s->out[0], 1);
193 }
194
195 void inline wm8750_mask_update(struct wm8750_s *s)
196 {
197 #define R_ONLY  0x0000ffff
198 #define L_ONLY  0xffff0000
199 #define BOTH    (R_ONLY | L_ONLY)
200 #define NONE    (R_ONLY & L_ONLY)
201     s->inmask =
202             (s->inmute[0] ? R_ONLY : BOTH) &
203             (s->inmute[1] ? L_ONLY : BOTH) &
204             (s->mute ? NONE : BOTH);
205     s->outmask =
206             (s->outmute[0] ? R_ONLY : BOTH) &
207             (s->outmute[1] ? L_ONLY : BOTH) &
208             (s->mute ? NONE : BOTH);
209 }
210
211 void wm8750_reset(i2c_slave *i2c)
212 {
213     struct wm8750_s *s = (struct wm8750_s *) i2c;
214     s->enable = 0;
215     wm8750_set_format(s);
216     s->diff[0] = 0;
217     s->diff[1] = 0;
218     s->ds = 0;
219     s->alc = 0;
220     s->in[0] = &s->adc_voice[0];
221     s->invol[0] = 0x17;
222     s->invol[1] = 0x17;
223     s->invol[2] = 0xc3;
224     s->invol[3] = 0xc3;
225     s->out[0] = &s->dac_voice[0];
226     s->outvol[0] = 0xff;
227     s->outvol[1] = 0xff;
228     s->outvol[2] = 0x79;
229     s->outvol[3] = 0x79;
230     s->outvol[4] = 0x79;
231     s->outvol[5] = 0x79;
232     s->inmute[0] = 0;
233     s->inmute[1] = 0;
234     s->outmute[0] = 0;
235     s->outmute[1] = 0;
236     s->mute = 1;
237     s->path[0] = 0;
238     s->path[1] = 0;
239     s->path[2] = 0;
240     s->path[3] = 0;
241     s->mpath[0] = 0;
242     s->mpath[1] = 0;
243     s->format = 0x0a;
244     s->idx_in = sizeof(s->data_in);
245     s->req_in = 0;
246     s->idx_out = 0;
247     s->req_out = 0;
248     wm8750_mask_update(s);
249     s->i2c_len = 0;
250 }
251
252 static void wm8750_event(i2c_slave *i2c, enum i2c_event event)
253 {
254     struct wm8750_s *s = (struct wm8750_s *) i2c;
255
256     switch (event) {
257     case I2C_START_SEND:
258         s->i2c_len = 0;
259         break;
260     case I2C_FINISH:
261 #ifdef VERBOSE
262         if (s->i2c_len < 2)
263             printf("%s: message too short (%i bytes)\n",
264                             __FUNCTION__, s->i2c_len);
265 #endif
266         break;
267     default:
268         break;
269     }
270 }
271
272 #define WM8750_LINVOL   0x00
273 #define WM8750_RINVOL   0x01
274 #define WM8750_LOUT1V   0x02
275 #define WM8750_ROUT1V   0x03
276 #define WM8750_ADCDAC   0x05
277 #define WM8750_IFACE    0x07
278 #define WM8750_SRATE    0x08
279 #define WM8750_LDAC     0x0a
280 #define WM8750_RDAC     0x0b
281 #define WM8750_BASS     0x0c
282 #define WM8750_TREBLE   0x0d
283 #define WM8750_RESET    0x0f
284 #define WM8750_3D       0x10
285 #define WM8750_ALC1     0x11
286 #define WM8750_ALC2     0x12
287 #define WM8750_ALC3     0x13
288 #define WM8750_NGATE    0x14
289 #define WM8750_LADC     0x15
290 #define WM8750_RADC     0x16
291 #define WM8750_ADCTL1   0x17
292 #define WM8750_ADCTL2   0x18
293 #define WM8750_PWR1     0x19
294 #define WM8750_PWR2     0x1a
295 #define WM8750_ADCTL3   0x1b
296 #define WM8750_ADCIN    0x1f
297 #define WM8750_LADCIN   0x20
298 #define WM8750_RADCIN   0x21
299 #define WM8750_LOUTM1   0x22
300 #define WM8750_LOUTM2   0x23
301 #define WM8750_ROUTM1   0x24
302 #define WM8750_ROUTM2   0x25
303 #define WM8750_MOUTM1   0x26
304 #define WM8750_MOUTM2   0x27
305 #define WM8750_LOUT2V   0x28
306 #define WM8750_ROUT2V   0x29
307 #define WM8750_MOUTV    0x2a
308
309 static int wm8750_tx(i2c_slave *i2c, uint8_t data)
310 {
311     struct wm8750_s *s = (struct wm8750_s *) i2c;
312     uint8_t cmd;
313     uint16_t value;
314
315     if (s->i2c_len >= 2) {
316         printf("%s: long message (%i bytes)\n", __FUNCTION__, s->i2c_len);
317 #ifdef VERBOSE
318         return 1;
319 #endif
320     }
321     s->i2c_data[s->i2c_len ++] = data;
322     if (s->i2c_len != 2)
323         return 0;
324
325     cmd = s->i2c_data[0] >> 1;
326     value = ((s->i2c_data[0] << 8) | s->i2c_data[1]) & 0x1ff;
327
328     switch (cmd) {
329     case WM8750_LADCIN: /* ADC Signal Path Control (Left) */
330         s->diff[0] = (((value >> 6) & 3) == 3); /* LINSEL */
331         if (s->diff[0])
332             s->in[0] = &s->adc_voice[0 + s->ds * 1];
333         else
334             s->in[0] = &s->adc_voice[((value >> 6) & 3) * 1 + 0];
335         break;
336
337     case WM8750_RADCIN: /* ADC Signal Path Control (Right) */
338         s->diff[1] = (((value >> 6) & 3) == 3); /* RINSEL */
339         if (s->diff[1])
340             s->in[1] = &s->adc_voice[0 + s->ds * 1];
341         else
342             s->in[1] = &s->adc_voice[((value >> 6) & 3) * 1 + 0];
343         break;
344
345     case WM8750_ADCIN:  /* ADC Input Mode */
346         s->ds = (value >> 8) & 1;       /* DS */
347         if (s->diff[0])
348             s->in[0] = &s->adc_voice[0 + s->ds * 1];
349         if (s->diff[1])
350             s->in[1] = &s->adc_voice[0 + s->ds * 1];
351         s->monomix[0] = (value >> 6) & 3;       /* MONOMIX */
352         break;
353
354     case WM8750_ADCTL1: /* Additional Control (1) */
355         s->monomix[1] = (value >> 1) & 1;       /* DMONOMIX */
356         break;
357
358     case WM8750_PWR1:   /* Power Management (1) */
359         s->enable = ((value >> 6) & 7) == 3;    /* VMIDSEL, VREF */
360         wm8750_set_format(s);
361         break;
362
363     case WM8750_LINVOL: /* Left Channel PGA */
364         s->invol[0] = value & 0x3f;             /* LINVOL */
365         s->inmute[0] = (value >> 7) & 1;        /* LINMUTE */
366         wm8750_mask_update(s);
367         break;
368
369     case WM8750_RINVOL: /* Right Channel PGA */
370         s->invol[1] = value & 0x3f;             /* RINVOL */
371         s->inmute[1] = (value >> 7) & 1;        /* RINMUTE */
372         wm8750_mask_update(s);
373         break;
374
375     case WM8750_ADCDAC: /* ADC and DAC Control */
376         s->pol = (value >> 5) & 3;              /* ADCPOL */
377         s->mute = (value >> 3) & 1;             /* DACMU */
378         wm8750_mask_update(s);
379         break;
380
381     case WM8750_ADCTL3: /* Additional Control (3) */
382         break;
383
384     case WM8750_LADC:   /* Left ADC Digital Volume */
385         s->invol[2] = value & 0xff;             /* LADCVOL */
386         break;
387
388     case WM8750_RADC:   /* Right ADC Digital Volume */
389         s->invol[3] = value & 0xff;             /* RADCVOL */
390         break;
391
392     case WM8750_ALC1:   /* ALC Control (1) */
393         s->alc = (value >> 7) & 3;              /* ALCSEL */
394         break;
395
396     case WM8750_NGATE:  /* Noise Gate Control */
397     case WM8750_3D:     /* 3D enhance */
398         break;
399
400     case WM8750_LDAC:   /* Left Channel Digital Volume */
401         s->outvol[0] = value & 0xff;            /* LDACVOL */
402         break;
403
404     case WM8750_RDAC:   /* Right Channel Digital Volume */
405         s->outvol[1] = value & 0xff;            /* RDACVOL */
406         break;
407
408     case WM8750_BASS:   /* Bass Control */
409         break;
410
411     case WM8750_LOUTM1: /* Left Mixer Control (1) */
412         s->path[0] = (value >> 8) & 1;          /* LD2LO */
413         break;
414
415     case WM8750_LOUTM2: /* Left Mixer Control (2) */
416         s->path[1] = (value >> 8) & 1;          /* RD2LO */
417         break;
418
419     case WM8750_ROUTM1: /* Right Mixer Control (1) */
420         s->path[2] = (value >> 8) & 1;          /* LD2RO */
421         break;
422
423     case WM8750_ROUTM2: /* Right Mixer Control (2) */
424         s->path[3] = (value >> 8) & 1;          /* RD2RO */
425         break;
426
427     case WM8750_MOUTM1: /* Mono Mixer Control (1) */
428         s->mpath[0] = (value >> 8) & 1;         /* LD2MO */
429         break;
430
431     case WM8750_MOUTM2: /* Mono Mixer Control (2) */
432         s->mpath[1] = (value >> 8) & 1;         /* RD2MO */
433         break;
434
435     case WM8750_LOUT1V: /* LOUT1 Volume */
436         s->outvol[2] = value & 0x7f;            /* LOUT2VOL */
437         break;
438
439     case WM8750_LOUT2V: /* LOUT2 Volume */
440         s->outvol[4] = value & 0x7f;            /* LOUT2VOL */
441         break;
442
443     case WM8750_ROUT1V: /* ROUT1 Volume */
444         s->outvol[3] = value & 0x7f;            /* ROUT2VOL */
445         break;
446
447     case WM8750_ROUT2V: /* ROUT2 Volume */
448         s->outvol[5] = value & 0x7f;            /* ROUT2VOL */
449         break;
450
451     case WM8750_MOUTV:  /* MONOOUT Volume */
452         s->outvol[6] = value & 0x7f;            /* MONOOUTVOL */
453         break;
454
455     case WM8750_ADCTL2: /* Additional Control (2) */
456         break;
457
458     case WM8750_PWR2:   /* Power Management (2) */
459         s->power = value & 0x7e;
460         break;
461
462     case WM8750_IFACE:  /* Digital Audio Interface Format */
463 #ifdef VERBOSE
464         if (value & 0x40)                       /* MS */
465             printf("%s: attempt to enable Master Mode\n", __FUNCTION__);
466 #endif
467         s->format = value;
468         wm8750_set_format(s);
469         break;
470
471     case WM8750_SRATE:  /* Clocking and Sample Rate Control */
472         s->rate = &wm_rate_table[(value >> 1) & 0x1f];
473         wm8750_set_format(s);
474         break;
475
476     case WM8750_RESET:  /* Reset */
477         wm8750_reset(&s->i2c);
478         break;
479
480 #ifdef VERBOSE
481     default:
482         printf("%s: unknown register %02x\n", __FUNCTION__, cmd);
483 #endif
484     }
485
486     return 0;
487 }
488
489 static int wm8750_rx(i2c_slave *i2c)
490 {
491     return 0x00;
492 }
493
494 static void wm8750_save(QEMUFile *f, void *opaque)
495 {
496     struct wm8750_s *s = (struct wm8750_s *) opaque;
497     int i;
498     qemu_put_8s(f, &s->i2c_data[0]);
499     qemu_put_8s(f, &s->i2c_data[1]);
500     qemu_put_be32(f, s->i2c_len);
501     qemu_put_be32(f, s->enable);
502     qemu_put_be32(f, s->idx_in);
503     qemu_put_be32(f, s->req_in);
504     qemu_put_be32(f, s->idx_out);
505     qemu_put_be32(f, s->req_out);
506
507     for (i = 0; i < 7; i ++)
508         qemu_put_8s(f, &s->outvol[i]);
509     for (i = 0; i < 2; i ++)
510         qemu_put_8s(f, &s->outmute[i]);
511     for (i = 0; i < 4; i ++)
512         qemu_put_8s(f, &s->invol[i]);
513     for (i = 0; i < 2; i ++)
514         qemu_put_8s(f, &s->inmute[i]);
515
516     for (i = 0; i < 2; i ++)
517         qemu_put_8s(f, &s->diff[i]);
518     qemu_put_8s(f, &s->pol);
519     qemu_put_8s(f, &s->ds);
520     for (i = 0; i < 2; i ++)
521         qemu_put_8s(f, &s->monomix[i]);
522     qemu_put_8s(f, &s->alc);
523     qemu_put_8s(f, &s->mute);
524     for (i = 0; i < 4; i ++)
525         qemu_put_8s(f, &s->path[i]);
526     for (i = 0; i < 2; i ++)
527         qemu_put_8s(f, &s->mpath[i]);
528     qemu_put_8s(f, &s->format);
529     qemu_put_8s(f, &s->power);
530     qemu_put_be32s(f, &s->inmask);
531     qemu_put_be32s(f, &s->outmask);
532     qemu_put_byte(f, (s->rate - wm_rate_table) / sizeof(*s->rate));
533     i2c_slave_save(f, &s->i2c);
534 }
535
536 static int wm8750_load(QEMUFile *f, void *opaque, int version_id)
537 {
538     struct wm8750_s *s = (struct wm8750_s *) opaque;
539     int i;
540     qemu_get_8s(f, &s->i2c_data[0]);
541     qemu_get_8s(f, &s->i2c_data[1]);
542     s->i2c_len = qemu_get_be32(f);
543     s->enable = qemu_get_be32(f);
544     s->idx_in = qemu_get_be32(f);
545     s->req_in = qemu_get_be32(f);
546     s->idx_out = qemu_get_be32(f);
547     s->req_out = qemu_get_be32(f);
548
549     for (i = 0; i < 7; i ++)
550         qemu_get_8s(f, &s->outvol[i]);
551     for (i = 0; i < 2; i ++)
552         qemu_get_8s(f, &s->outmute[i]);
553     for (i = 0; i < 4; i ++)
554         qemu_get_8s(f, &s->invol[i]);
555     for (i = 0; i < 2; i ++)
556         qemu_get_8s(f, &s->inmute[i]);
557
558     for (i = 0; i < 2; i ++)
559         qemu_get_8s(f, &s->diff[i]);
560     qemu_get_8s(f, &s->pol);
561     qemu_get_8s(f, &s->ds);
562     for (i = 0; i < 2; i ++)
563         qemu_get_8s(f, &s->monomix[i]);
564     qemu_get_8s(f, &s->alc);
565     qemu_get_8s(f, &s->mute);
566     for (i = 0; i < 4; i ++)
567         qemu_get_8s(f, &s->path[i]);
568     for (i = 0; i < 2; i ++)
569         qemu_get_8s(f, &s->mpath[i]);
570     qemu_get_8s(f, &s->format);
571     qemu_get_8s(f, &s->power);
572     qemu_get_be32s(f, &s->inmask);
573     qemu_get_be32s(f, &s->outmask);
574     s->rate = &wm_rate_table[(uint8_t) qemu_get_byte(f) & 0x1f];
575     i2c_slave_load(f, &s->i2c);
576     return 0;
577 }
578
579 static int wm8750_iid = 0;
580
581 i2c_slave *wm8750_init(i2c_bus *bus, AudioState *audio)
582 {
583     struct wm8750_s *s = (struct wm8750_s *)
584             i2c_slave_init(bus, 0, sizeof(struct wm8750_s));
585     s->i2c.event = wm8750_event;
586     s->i2c.recv = wm8750_rx;
587     s->i2c.send = wm8750_tx;
588
589     AUD_register_card(audio, CODEC, &s->card);
590     wm8750_reset(&s->i2c);
591
592     register_savevm(CODEC, wm8750_iid ++, 0, wm8750_save, wm8750_load, s);
593
594     return &s->i2c;
595 }
596
597 void wm8750_fini(i2c_slave *i2c)
598 {
599     struct wm8750_s *s = (struct wm8750_s *) i2c;
600     wm8750_reset(&s->i2c);
601     AUD_remove_card(&s->card);
602     qemu_free(s);
603 }
604
605 void wm8750_data_req_set(i2c_slave *i2c,
606                 void (*data_req)(void *, int, int), void *opaque)
607 {
608     struct wm8750_s *s = (struct wm8750_s *) i2c;
609     s->data_req = data_req;
610     s->opaque = opaque;
611 }
612
613 void wm8750_dac_dat(void *opaque, uint32_t sample)
614 {
615     struct wm8750_s *s = (struct wm8750_s *) opaque;
616     uint32_t *data = (uint32_t *) &s->data_out[s->idx_out];
617     *data = sample & s->outmask;
618     s->req_out -= 4;
619     s->idx_out += 4;
620     if (s->idx_out >= sizeof(s->data_out) || s->req_out <= 0)
621         wm8750_out_flush(s);
622 }
623
624 uint32_t wm8750_adc_dat(void *opaque)
625 {
626     struct wm8750_s *s = (struct wm8750_s *) opaque;
627     uint32_t *data;
628     if (s->idx_in >= sizeof(s->data_in))
629         wm8750_in_load(s);
630     data = (uint32_t *) &s->data_in[s->idx_in];
631     s->req_in -= 4;
632     s->idx_in += 4;
633     return *data & s->inmask;
634 }